aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execScan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execScan.c')
-rw-r--r--src/backend/executor/execScan.c75
1 files changed, 4 insertions, 71 deletions
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index 5dfc49deb95..837abc0f017 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -23,8 +23,6 @@
#include "utils/memutils.h"
-static bool tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc);
-
/*
* ExecScanFetch -- check interrupts & fetch next potential tuple
@@ -237,8 +235,9 @@ void
ExecAssignScanProjectionInfo(ScanState *node)
{
Scan *scan = (Scan *) node->ps.plan;
+ TupleDesc tupdesc = node->ss_ScanTupleSlot->tts_tupleDescriptor;
- ExecAssignScanProjectionInfoWithVarno(node, scan->scanrelid);
+ ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, scan->scanrelid);
}
/*
@@ -248,75 +247,9 @@ ExecAssignScanProjectionInfo(ScanState *node)
void
ExecAssignScanProjectionInfoWithVarno(ScanState *node, Index varno)
{
- Scan *scan = (Scan *) node->ps.plan;
-
- if (tlist_matches_tupdesc(&node->ps,
- scan->plan.targetlist,
- varno,
- node->ss_ScanTupleSlot->tts_tupleDescriptor))
- node->ps.ps_ProjInfo = NULL;
- else
- ExecAssignProjectionInfo(&node->ps,
- node->ss_ScanTupleSlot->tts_tupleDescriptor);
-}
-
-static bool
-tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
-{
- int numattrs = tupdesc->natts;
- int attrno;
- bool hasoid;
- ListCell *tlist_item = list_head(tlist);
-
- /* Check the tlist attributes */
- for (attrno = 1; attrno <= numattrs; attrno++)
- {
- Form_pg_attribute att_tup = TupleDescAttr(tupdesc, attrno - 1);
- Var *var;
-
- if (tlist_item == NULL)
- return false; /* tlist too short */
- var = (Var *) ((TargetEntry *) lfirst(tlist_item))->expr;
- if (!var || !IsA(var, Var))
- return false; /* tlist item not a Var */
- /* if these Asserts fail, planner messed up */
- Assert(var->varno == varno);
- Assert(var->varlevelsup == 0);
- if (var->varattno != attrno)
- return false; /* out of order */
- if (att_tup->attisdropped)
- return false; /* table contains dropped columns */
-
- /*
- * Note: usually the Var's type should match the tupdesc exactly, but
- * in situations involving unions of columns that have different
- * typmods, the Var may have come from above the union and hence have
- * typmod -1. This is a legitimate situation since the Var still
- * describes the column, just not as exactly as the tupdesc does. We
- * could change the planner to prevent it, but it'd then insert
- * projection steps just to convert from specific typmod to typmod -1,
- * which is pretty silly.
- */
- if (var->vartype != att_tup->atttypid ||
- (var->vartypmod != att_tup->atttypmod &&
- var->vartypmod != -1))
- return false; /* type mismatch */
-
- tlist_item = lnext(tlist_item);
- }
-
- if (tlist_item)
- return false; /* tlist too long */
-
- /*
- * If the plan context requires a particular hasoid setting, then that has
- * to match, too.
- */
- if (ExecContextForcesOids(ps, &hasoid) &&
- hasoid != tupdesc->tdhasoid)
- return false;
+ TupleDesc tupdesc = node->ss_ScanTupleSlot->tts_tupleDescriptor;
- return true;
+ ExecConditionalAssignProjectionInfo(&node->ps, tupdesc, varno);
}
/*