diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execExprInterp.c | 2 | ||||
-rw-r--r-- | src/backend/executor/execMain.c | 13 | ||||
-rw-r--r-- | src/backend/executor/execTuples.c | 28 | ||||
-rw-r--r-- | src/backend/executor/execUtils.c | 2 |
4 files changed, 40 insertions, 5 deletions
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index f7bcf6370b5..e530b262dae 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -2505,7 +2505,7 @@ ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op, /* ignore dropped columns */ if (TupleDescAttr(tupDesc, att - 1)->attisdropped) continue; - if (heap_attisnull(&tmptup, att)) + if (heap_attisnull(&tmptup, att, tupDesc)) { /* null field disproves IS NOT NULL */ if (!checkisnull) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 68f6450ee64..9a107aba561 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -2980,8 +2980,17 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate) false, NULL)) elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck"); - /* successful, copy tuple */ - copyTuple = heap_copytuple(&tuple); + if (HeapTupleHeaderGetNatts(tuple.t_data) < + RelationGetDescr(erm->relation)->natts) + { + copyTuple = heap_expand_tuple(&tuple, + RelationGetDescr(erm->relation)); + } + else + { + /* successful, copy tuple */ + copyTuple = heap_copytuple(&tuple); + } ReleaseBuffer(buffer); } diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index acd1b97b0e6..78cfcadea03 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -625,7 +625,15 @@ ExecCopySlotMinimalTuple(TupleTableSlot *slot) if (slot->tts_mintuple) return heap_copy_minimal_tuple(slot->tts_mintuple); if (slot->tts_tuple) - return minimal_tuple_from_heap_tuple(slot->tts_tuple); + { + if (TTS_HAS_PHYSICAL_TUPLE(slot) && + HeapTupleHeaderGetNatts(slot->tts_tuple->t_data) + < slot->tts_tupleDescriptor->natts) + return minimal_expand_tuple(slot->tts_tuple, + slot->tts_tupleDescriptor); + else + return minimal_tuple_from_heap_tuple(slot->tts_tuple); + } /* * Otherwise we need to build a tuple from the Datum array. @@ -663,7 +671,23 @@ ExecFetchSlotTuple(TupleTableSlot *slot) * If we have a regular physical tuple then just return it. */ if (TTS_HAS_PHYSICAL_TUPLE(slot)) - return slot->tts_tuple; + { + if (HeapTupleHeaderGetNatts(slot->tts_tuple->t_data) < + slot->tts_tupleDescriptor->natts) + { + MemoryContext oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + + slot->tts_tuple = heap_expand_tuple(slot->tts_tuple, + slot->tts_tupleDescriptor); + slot->tts_shouldFree = true; + MemoryContextSwitchTo(oldContext); + return slot->tts_tuple; + } + else + { + return slot->tts_tuple; + } + } /* * Otherwise materialize the slot... diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 14b07b5d449..b963cae730c 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -511,6 +511,8 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc return false; /* out of order */ if (att_tup->attisdropped) return false; /* table contains dropped columns */ + if (att_tup->atthasmissing) + return false; /* table contains cols with missing values */ /* * Note: usually the Var's type should match the tupdesc exactly, but |