commit 7c586f16d4a720325c1b9fc86b12b94f531956be Author: Ashutosh Bapat Date: Thu Apr 6 13:57:47 2017 +0530 No-op tuple conversion in ExecEvalConvertRowtype() ExecEvalConvertRowtype() returns the tuple as is when no conversion is required i.e. no conversion map exists. While doing so it does not change the type of the tuple to be the type of the output expected. The tuple could be an on disk tuple and thus scribbling on it may lead to data corruption. I am not sure about this. Hence used heap_copy_tuple_as_datum(). I do not know whether that's the correct solution. But it fixes the problem. diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 4fbb5c1..c889905 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -2818,16 +2818,21 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext } /* - * No-op if no conversion needed (not clear this can happen here). + * Following functions needs a HeapTuple not a bare HeapTupleHeader. */ - if (op->d.convert_rowtype.map == NULL) - return; + tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple); + tmptup.t_data = tuple; /* - * do_convert_tuple needs a HeapTuple not a bare HeapTupleHeader. + * No-op if no conversion needed, but we need to change the type of tuple. + * Since the tuple might come from disk, it's better to copy it and change + * its type. */ - tmptup.t_len = HeapTupleHeaderGetDatumLength(tuple); - tmptup.t_data = tuple; + if (op->d.convert_rowtype.map == NULL) + { + *op->resvalue = heap_copy_tuple_as_datum(&tmptup, outdesc); + return; + } result = do_convert_tuple(&tmptup, op->d.convert_rowtype.map);