aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execExprInterp.c2
-rw-r--r--src/backend/executor/execMain.c13
-rw-r--r--src/backend/executor/execTuples.c28
-rw-r--r--src/backend/executor/execUtils.c2
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