estate->es_range_table = cstate->range_table;
/* Set up a tuple slot too */
- myslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(myslot, tupDesc);
+ myslot = ExecInitExtraTupleSlot(estate, tupDesc);
/* Triggers might need a slot as well */
- estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate);
+ estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate, NULL);
/* Prepare to catch AFTER triggers. */
AfterTriggerBeginQuery();
if (estate->es_trig_oldtup_slot == NULL)
{
oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
- estate->es_trig_oldtup_slot = ExecInitExtraTupleSlot(estate);
+ estate->es_trig_oldtup_slot =
+ ExecInitExtraTupleSlot(estate, NULL);
MemoryContextSwitchTo(oldContext);
}
oldslot = estate->es_trig_oldtup_slot;
if (estate->es_trig_newtup_slot == NULL)
{
oldContext = MemoryContextSwitchTo(estate->es_query_cxt);
- estate->es_trig_newtup_slot = ExecInitExtraTupleSlot(estate);
+ estate->es_trig_newtup_slot =
+ ExecInitExtraTupleSlot(estate, NULL);
MemoryContextSwitchTo(oldContext);
}
newslot = estate->es_trig_newtup_slot;
switch to per-query context to run ExecInitNode
AfterTriggerBeginQuery
ExecInitNode --- recursively scans plan tree
+ ExecInitNode
+ recurse into subsidiary nodes
CreateExprContext
creates per-tuple context
ExecInitExpr
scratch->d.wholerow.junkFilter =
ExecInitJunkFilter(subplan->plan->targetlist,
ExecGetResultType(subplan)->tdhasoid,
- ExecInitExtraTupleSlot(parent->state));
+ ExecInitExtraTupleSlot(parent->state, NULL));
}
}
}
j = ExecInitJunkFilter(planstate->plan->targetlist,
tupType->tdhasoid,
- ExecInitExtraTupleSlot(estate));
+ ExecInitExtraTupleSlot(estate, NULL));
estate->es_junkFilter = j;
/* Want to return the cleaned tuple type */
* We need an additional tuple slot for storing transient tuples that
* are converted to the root table descriptor.
*/
- proute->root_tuple_slot = MakeTupleTableSlot();
+ proute->root_tuple_slot = MakeTupleTableSlot(NULL);
}
else
{
* (such as ModifyTableState) and released when the node finishes
* processing.
*/
- proute->partition_tuple_slot = MakeTupleTableSlot();
+ proute->partition_tuple_slot = MakeTupleTableSlot(NULL);
i = 0;
foreach(cell, leaf_parts)
* the scan node, because the planner will preferentially generate a matching
* tlist.
*
- * ExecAssignScanType must have been called already.
+ * The scan slot's descriptor must have been set already.
*/
void
ExecAssignScanProjectionInfo(ScanState *node)
* At ExecutorStart()
* ----------------
* - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
- * ExecInitResultTupleSlot() to construct TupleTableSlots
+ * ExecInitResultTupleSlotTL() to construct TupleTableSlots
* for the tuples returned by the access methods and the
* tuples resulting from performing target list projections.
*
/* --------------------------------
* MakeTupleTableSlot
*
- * Basic routine to make an empty TupleTableSlot.
+ * Basic routine to make an empty TupleTableSlot. If tupleDesc is
+ * specified the slot's descriptor is fixed for it's lifetime, gaining
+ * some efficiency. If that's undesirable, pass NULL.
* --------------------------------
*/
TupleTableSlot *
-MakeTupleTableSlot(void)
+MakeTupleTableSlot(TupleDesc tupleDesc)
{
- TupleTableSlot *slot = makeNode(TupleTableSlot);
+ Size sz;
+ TupleTableSlot *slot;
+ /*
+ * When a fixed descriptor is specified, we can reduce overhead by
+ * allocating the entire slot in one go.
+ */
+ if (tupleDesc)
+ sz = MAXALIGN(sizeof(TupleTableSlot)) +
+ MAXALIGN(tupleDesc->natts * sizeof(Datum)) +
+ MAXALIGN(tupleDesc->natts * sizeof(bool));
+ else
+ sz = sizeof(TupleTableSlot);
+
+ slot = palloc0(sz);
+ slot->type = T_TupleTableSlot;
slot->tts_isempty = true;
slot->tts_shouldFree = false;
slot->tts_shouldFreeMin = false;
slot->tts_tuple = NULL;
- slot->tts_tupleDescriptor = NULL;
+ slot->tts_fixedTupleDescriptor = tupleDesc != NULL;
+ slot->tts_tupleDescriptor = tupleDesc;
slot->tts_mcxt = CurrentMemoryContext;
slot->tts_buffer = InvalidBuffer;
slot->tts_nvalid = 0;
slot->tts_isnull = NULL;
slot->tts_mintuple = NULL;
+ if (tupleDesc != NULL)
+ {
+ slot->tts_values = (Datum *)
+ (((char *) slot)
+ + MAXALIGN(sizeof(TupleTableSlot)));
+ slot->tts_isnull = (bool *)
+ (((char *) slot)
+ + MAXALIGN(sizeof(TupleTableSlot))
+ + MAXALIGN(tupleDesc->natts * sizeof(Datum)));
+
+ PinTupleDesc(tupleDesc);
+ }
+
return slot;
}
* --------------------------------
*/
TupleTableSlot *
-ExecAllocTableSlot(List **tupleTable)
+ExecAllocTableSlot(List **tupleTable, TupleDesc desc)
{
- TupleTableSlot *slot = MakeTupleTableSlot();
+ TupleTableSlot *slot = MakeTupleTableSlot(desc);
*tupleTable = lappend(*tupleTable, slot);
/* If shouldFree, release memory occupied by the slot itself */
if (shouldFree)
{
- if (slot->tts_values)
- pfree(slot->tts_values);
- if (slot->tts_isnull)
- pfree(slot->tts_isnull);
+ if (!slot->tts_fixedTupleDescriptor)
+ {
+ if (slot->tts_values)
+ pfree(slot->tts_values);
+ if (slot->tts_isnull)
+ pfree(slot->tts_isnull);
+ }
pfree(slot);
}
}
TupleTableSlot *
MakeSingleTupleTableSlot(TupleDesc tupdesc)
{
- TupleTableSlot *slot = MakeTupleTableSlot();
-
- ExecSetSlotDescriptor(slot, tupdesc);
+ TupleTableSlot *slot = MakeTupleTableSlot(tupdesc);
return slot;
}
ExecClearTuple(slot);
if (slot->tts_tupleDescriptor)
ReleaseTupleDesc(slot->tts_tupleDescriptor);
- if (slot->tts_values)
- pfree(slot->tts_values);
- if (slot->tts_isnull)
- pfree(slot->tts_isnull);
+ if (!slot->tts_fixedTupleDescriptor)
+ {
+ if (slot->tts_values)
+ pfree(slot->tts_values);
+ if (slot->tts_isnull)
+ pfree(slot->tts_isnull);
+ }
pfree(slot);
}
ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */
TupleDesc tupdesc) /* new tuple descriptor */
{
+ Assert(!slot->tts_fixedTupleDescriptor);
+
/* For safety, make sure slot is empty before changing it */
ExecClearTuple(slot);
*/
/* --------------------------------
- * ExecInit{Result,Scan,Extra}TupleSlot
+ * ExecInit{Result,Scan,Extra}TupleSlot[TL]
*
* These are convenience routines to initialize the specified slot
* in nodes inheriting the appropriate state. ExecInitExtraTupleSlot
*/
/* ----------------
- * ExecInitResultTupleSlot
+ * ExecInitResultTupleSlotTL
+ *
+ * Initialize result tuple slot, using the plan node's targetlist.
* ----------------
*/
void
-ExecInitResultTupleSlot(EState *estate, PlanState *planstate)
+ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
{
- planstate->ps_ResultTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable);
+ bool hasoid;
+ TupleDesc tupDesc;
+
+ if (ExecContextForcesOids(planstate, &hasoid))
+ {
+ /* context forces OID choice; hasoid is now set correctly */
+ }
+ else
+ {
+ /* given free choice, don't leave space for OIDs in result tuples */
+ hasoid = false;
+ }
+
+ tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
+
+ planstate->ps_ResultTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable, tupDesc);
}
/* ----------------
* ----------------
*/
void
-ExecInitScanTupleSlot(EState *estate, ScanState *scanstate)
+ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc)
{
- scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable);
+ scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable,
+ tupledesc);
}
/* ----------------
* ExecInitExtraTupleSlot
+ *
+ * Return a newly created slot. If tupledesc is non-NULL the slot will have
+ * that as its fixed tupledesc. Otherwise the caller needs to use
+ * ExecSetSlotDescriptor() to set the descriptor before use.
* ----------------
*/
TupleTableSlot *
-ExecInitExtraTupleSlot(EState *estate)
+ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc)
{
- return ExecAllocTableSlot(&estate->es_tupleTable);
+ return ExecAllocTableSlot(&estate->es_tupleTable, tupledesc);
}
/* ----------------
TupleTableSlot *
ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
{
- TupleTableSlot *slot = ExecInitExtraTupleSlot(estate);
-
- ExecSetSlotDescriptor(slot, tupType);
+ TupleTableSlot *slot = ExecInitExtraTupleSlot(estate, tupType);
return ExecStoreAllNullTuple(slot);
}
* ReScanExprContext
*
* ExecAssignExprContext Common code for plan node init routines.
- * ExecAssignResultType
* etc
*
* ExecOpenScanRelation Common code for scan node init routines.
planstate->ps_ExprContext = CreateExprContext(estate);
}
-/* ----------------
- * ExecAssignResultType
- * ----------------
- */
-void
-ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc)
-{
- TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
-
- ExecSetSlotDescriptor(slot, tupDesc);
-}
-
-/* ----------------
- * ExecAssignResultTypeFromTL
- * ----------------
- */
-void
-ExecAssignResultTypeFromTL(PlanState *planstate)
-{
- bool hasoid;
- TupleDesc tupDesc;
-
- if (ExecContextForcesOids(planstate, &hasoid))
- {
- /* context forces OID choice; hasoid is now set correctly */
- }
- else
- {
- /* given free choice, don't leave space for OIDs in result tuples */
- hasoid = false;
- }
-
- /*
- * ExecTypeFromTL needs the parse-time representation of the tlist, not a
- * list of ExprStates. This is good because some plan nodes don't bother
- * to set up planstate->targetlist ...
- */
- tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
- ExecAssignResultType(planstate, tupDesc);
-}
-
/* ----------------
* ExecGetResultType
* ----------------
planstate->ps_ExprContext = NULL;
}
+
/* ----------------------------------------------------------------
- * the following scan type support functions are for
- * those nodes which are stubborn and return tuples in
- * their Scan tuple slot instead of their Result tuple
- * slot.. luck fur us, these nodes do not do projections
- * so we don't have to worry about getting the ProjectionInfo
- * right for them... -cim 6/3/91
+ * Scan node support
* ----------------------------------------------------------------
*/
}
/* ----------------
- * ExecAssignScanTypeFromOuterPlan
+ * ExecCreateSlotFromOuterPlan
* ----------------
*/
void
-ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
+ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate)
{
PlanState *outerPlan;
TupleDesc tupDesc;
outerPlan = outerPlanState(scanstate);
tupDesc = ExecGetResultType(outerPlan);
- ExecAssignScanType(scanstate, tupDesc);
+ ExecInitScanTupleSlot(estate, scanstate, tupDesc);
}
-
-/* ----------------------------------------------------------------
- * Scan node support
- * ----------------------------------------------------------------
- */
-
/* ----------------------------------------------------------------
* ExecRelationIsTargetRelation
*
perhash->aggnode->grpOperators,
&perhash->eqfuncoids,
&perhash->hashfunctions);
- perhash->hashslot = ExecAllocTableSlot(&estate->es_tupleTable);
- ExecSetSlotDescriptor(perhash->hashslot, hashDesc);
+ perhash->hashslot =
+ ExecAllocTableSlot(&estate->es_tupleTable, hashDesc);
list_free(hashTlist);
bms_free(colnos);
ExecAssignExprContext(estate, &aggstate->ss.ps);
- /*
- * tuple table initialization.
- *
- * For hashtables, we create some additional slots below.
- */
- ExecInitScanTupleSlot(estate, &aggstate->ss);
- ExecInitResultTupleSlot(estate, &aggstate->ss.ps);
- aggstate->sort_slot = ExecInitExtraTupleSlot(estate);
-
- /*
- * initialize child expressions
- *
- * We expect the parser to have checked that no aggs contain other agg
- * calls in their arguments (and just to be sure, we verify it again while
- * initializing the plan node). This would make no sense under SQL
- * semantics, and it's forbidden by the spec. Because it is true, we
- * don't need to worry about evaluating the aggs in any particular order.
- *
- * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState
- * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs
- * in the targetlist are found during ExecAssignProjectionInfo, below.
- */
- aggstate->ss.ps.qual =
- ExecInitQual(node->plan.qual, (PlanState *) aggstate);
-
/*
* Initialize child nodes.
*
/*
* initialize source tuple type.
*/
- ExecAssignScanTypeFromOuterPlan(&aggstate->ss);
+ ExecCreateScanSlotFromOuterPlan(estate, &aggstate->ss);
scanDesc = aggstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor;
if (node->chain)
- ExecSetSlotDescriptor(aggstate->sort_slot, scanDesc);
+ aggstate->sort_slot = ExecInitExtraTupleSlot(estate, scanDesc);
/*
- * Initialize result tuple type and projection info.
+ * Initialize result type, slot and projection.
*/
- ExecAssignResultTypeFromTL(&aggstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &aggstate->ss.ps);
ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
+ /*
+ * initialize child expressions
+ *
+ * We expect the parser to have checked that no aggs contain other agg
+ * calls in their arguments (and just to be sure, we verify it again while
+ * initializing the plan node). This would make no sense under SQL
+ * semantics, and it's forbidden by the spec. Because it is true, we
+ * don't need to worry about evaluating the aggs in any particular order.
+ *
+ * Note: execExpr.c finds Aggrefs for us, and adds their AggrefExprState
+ * nodes to aggstate->aggs. Aggrefs in the qual are found here; Aggrefs
+ * in the targetlist are found during ExecAssignProjectionInfo, below.
+ */
+ aggstate->ss.ps.qual =
+ ExecInitQual(node->plan.qual, (PlanState *) aggstate);
+
/*
* We should now have found all Aggrefs in the targetlist and quals.
*/
if (numSortCols > 0 || aggref->aggfilter)
{
pertrans->sortdesc = ExecTypeFromTL(aggref->args, false);
- pertrans->sortslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(pertrans->sortslot, pertrans->sortdesc);
+ pertrans->sortslot =
+ ExecInitExtraTupleSlot(estate, pertrans->sortdesc);
}
if (numSortCols > 0)
else if (numDistinctCols > 0)
{
/* we will need an extra slot to store prior values */
- pertrans->uniqslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(pertrans->uniqslot,
- pertrans->sortdesc);
+ pertrans->uniqslot =
+ ExecInitExtraTupleSlot(estate, pertrans->sortdesc);
}
/* Extract the sort information for use later */
appendstate->as_nplans = nplans;
/*
- * Miscellaneous initialization
- *
- * Append plans don't have expression contexts because they never call
- * ExecQual or ExecProject.
+ * Initialize result tuple type and slot.
*/
-
- /*
- * append nodes still have Result slots, which hold pointers to tuples, so
- * we have to initialize them.
- */
- ExecInitResultTupleSlot(estate, &appendstate->ps);
+ ExecInitResultTupleSlotTL(estate, &appendstate->ps);
/*
* call ExecInitNode on each of the plans to be executed and save the
}
/*
- * initialize output tuple type
+ * Miscellaneous initialization
+ *
+ * Append plans don't have expression contexts because they never call
+ * ExecQual or ExecProject.
*/
- ExecAssignResultTypeFromTL(&appendstate->ps);
appendstate->ps.ps_ProjInfo = NULL;
/*
bitmapandstate->bitmapplans = bitmapplanstates;
bitmapandstate->nplans = nplans;
- /*
- * Miscellaneous initialization
- *
- * BitmapAnd plans don't have expression contexts because they never call
- * ExecQual or ExecProject. They don't need any tuple slots either.
- */
-
/*
* call ExecInitNode on each of the plans to be executed and save the
* results into the array "bitmapplanstates".
i++;
}
+ /*
+ * Miscellaneous initialization
+ *
+ * BitmapAnd plans don't have expression contexts because they never call
+ * ExecQual or ExecProject. They don't need any tuple slots either.
+ */
+
return bitmapandstate;
}
ExecAssignExprContext(estate, &scanstate->ss.ps);
/*
- * initialize child expressions
+ * open the base relation and acquire appropriate lock on it.
*/
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
- scanstate->bitmapqualorig =
- ExecInitQual(node->bitmapqualorig, (PlanState *) scanstate);
+ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
+
+ /*
+ * initialize child nodes
+ *
+ * We do this after ExecOpenScanRelation because the child nodes will open
+ * indexscans on our relation's indexes, and we want to be sure we have
+ * acquired a lock on the relation first.
+ */
+ outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags);
/*
- * tuple table initialization
+ * get the scan type from the relation descriptor.
*/
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
+ ExecInitScanTupleSlot(estate, &scanstate->ss,
+ RelationGetDescr(currentRelation));
+
/*
- * open the base relation and acquire appropriate lock on it.
+ * Initialize result slot, type and projection.
*/
- currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
+ ExecAssignScanProjectionInfo(&scanstate->ss);
+
+ /*
+ * initialize child expressions
+ */
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+ scanstate->bitmapqualorig =
+ ExecInitQual(node->bitmapqualorig, (PlanState *) scanstate);
/*
* Determine the maximum for prefetch_target. If the tablespace has a
0,
NULL);
- /*
- * get the scan type from the relation descriptor.
- */
- ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation));
-
- /*
- * Initialize result tuple type and projection info.
- */
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
- ExecAssignScanProjectionInfo(&scanstate->ss);
-
- /*
- * initialize child nodes
- *
- * We do this last because the child nodes will open indexscans on our
- * relation's indexes, and we want to be sure we have acquired a lock on
- * the relation first.
- */
- outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags);
-
/*
* all done.
*/
/* normally we don't make the result bitmap till runtime */
indexstate->biss_result = NULL;
+ /*
+ * We do not open or lock the base relation here. We assume that an
+ * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on
+ * the heap relation throughout the execution of the plan tree.
+ */
+
+ indexstate->ss.ss_currentRelation = NULL;
+ indexstate->ss.ss_currentScanDesc = NULL;
+
/*
* Miscellaneous initialization
*
* sub-parts corresponding to runtime keys (see below).
*/
- /*
- * We do not open or lock the base relation here. We assume that an
- * ancestor BitmapHeapScan node is holding AccessShareLock (or better) on
- * the heap relation throughout the execution of the plan tree.
- */
-
- indexstate->ss.ss_currentRelation = NULL;
- indexstate->ss.ss_currentScanDesc = NULL;
-
/*
* If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
* here. This allows an index-advisor plugin to EXPLAIN a plan containing
bitmaporstate->bitmapplans = bitmapplanstates;
bitmaporstate->nplans = nplans;
- /*
- * Miscellaneous initialization
- *
- * BitmapOr plans don't have expression contexts because they never call
- * ExecQual or ExecProject. They don't need any tuple slots either.
- */
-
/*
* call ExecInitNode on each of the plans to be executed and save the
* results into the array "bitmapplanstates".
i++;
}
+ /*
+ * Miscellaneous initialization
+ *
+ * BitmapOr plans don't have expression contexts because they never call
+ * ExecQual or ExecProject. They don't need any tuple slots either.
+ */
+
return bitmaporstate;
}
*/
ExecAssignExprContext(estate, &scanstate->ss.ps);
- /*
- * initialize child expressions
- */
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
-
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
-
/*
* The scan tuple type (ie, the rowtype we expect to find in the work
* table) is the same as the result rowtype of the CTE query.
*/
- ExecAssignScanType(&scanstate->ss,
- ExecGetResultType(scanstate->cteplanstate));
+ ExecInitScanTupleSlot(estate, &scanstate->ss,
+ ExecGetResultType(scanstate->cteplanstate));
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
ExecAssignScanProjectionInfo(&scanstate->ss);
+ /*
+ * initialize child expressions
+ */
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+
return scanstate;
}
/* create expression context for node */
ExecAssignExprContext(estate, &css->ss.ps);
- /* initialize child expressions */
- css->ss.ps.qual =
- ExecInitQual(cscan->scan.plan.qual, (PlanState *) css);
-
- /* tuple table initialization */
- ExecInitScanTupleSlot(estate, &css->ss);
- ExecInitResultTupleSlot(estate, &css->ss.ps);
-
/*
* open the base relation, if any, and acquire an appropriate lock on it
*/
TupleDesc scan_tupdesc;
scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist, false);
- ExecAssignScanType(&css->ss, scan_tupdesc);
+ ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc);
/* Node's targetlist will contain Vars with varno = INDEX_VAR */
tlistvarno = INDEX_VAR;
}
else
{
- ExecAssignScanType(&css->ss, RelationGetDescr(scan_rel));
+ ExecInitScanTupleSlot(estate, &css->ss, RelationGetDescr(scan_rel));
/* Node's targetlist will contain Vars with varno = scanrelid */
tlistvarno = scanrelid;
}
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&css->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &css->ss.ps);
ExecAssignScanProjectionInfoWithVarno(&css->ss, tlistvarno);
+ /* initialize child expressions */
+ css->ss.ps.qual =
+ ExecInitQual(cscan->scan.plan.qual, (PlanState *) css);
+
/*
* The callback of custom-scan provider applies the final initialization
* of the custom-scan-state node according to its logic.
*/
ExecAssignExprContext(estate, &scanstate->ss.ps);
- /*
- * initialize child expressions
- */
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
- scanstate->fdw_recheck_quals =
- ExecInitQual(node->fdw_recheck_quals, (PlanState *) scanstate);
-
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
-
/*
* open the base relation, if any, and acquire an appropriate lock on it;
* also acquire function pointers from the FDW's handler
TupleDesc scan_tupdesc;
scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist, false);
- ExecAssignScanType(&scanstate->ss, scan_tupdesc);
+ ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc);
/* Node's targetlist will contain Vars with varno = INDEX_VAR */
tlistvarno = INDEX_VAR;
}
else
{
- ExecAssignScanType(&scanstate->ss, RelationGetDescr(currentRelation));
+ ExecInitScanTupleSlot(estate, &scanstate->ss, RelationGetDescr(currentRelation));
/* Node's targetlist will contain Vars with varno = scanrelid */
tlistvarno = scanrelid;
}
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
ExecAssignScanProjectionInfoWithVarno(&scanstate->ss, tlistvarno);
+ /*
+ * initialize child expressions
+ */
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+ scanstate->fdw_recheck_quals =
+ ExecInitQual(node->fdw_recheck_quals, (PlanState *) scanstate);
+
/*
* Initialize FDW-related state.
*/
*/
ExecAssignExprContext(estate, &scanstate->ss.ps);
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
-
- /*
- * initialize child expressions
- */
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
-
scanstate->funcstates = palloc(nfuncs * sizeof(FunctionScanPerFuncState));
natts = 0;
*/
if (!scanstate->simple)
{
- fs->func_slot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(fs->func_slot, fs->tupdesc);
+ fs->func_slot = ExecInitExtraTupleSlot(estate, fs->tupdesc);
}
else
fs->func_slot = NULL;
Assert(attno == natts);
}
- ExecAssignScanType(&scanstate->ss, scan_tupdesc);
+ /*
+ * Initialize scan slot and type.
+ */
+ ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc);
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
ExecAssignScanProjectionInfo(&scanstate->ss);
+ /*
+ * initialize child expressions
+ */
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+
/*
* Create a memory context that ExecMakeTableFunctionResult can use to
* evaluate function arguments in. We can't use the per-tuple context for
{
GatherState *gatherstate;
Plan *outerNode;
- bool hasoid;
TupleDesc tupDesc;
/* Gather node doesn't have innerPlan node. */
*/
ExecAssignExprContext(estate, &gatherstate->ps);
- /*
- * Gather doesn't support checking a qual (it's always more efficient to
- * do it in the child node).
- */
- Assert(!node->plan.qual);
-
- /*
- * tuple table initialization
- */
- gatherstate->funnel_slot = ExecInitExtraTupleSlot(estate);
- ExecInitResultTupleSlot(estate, &gatherstate->ps);
-
/*
* now initialize outer plan
*/
outerNode = outerPlan(node);
outerPlanState(gatherstate) = ExecInitNode(outerNode, estate, eflags);
+ tupDesc = ExecGetResultType(outerPlanState(gatherstate));
+
+ /*
+ * Initialize result slot, type and projection.
+ */
+ ExecInitResultTupleSlotTL(estate, &gatherstate->ps);
+ ExecConditionalAssignProjectionInfo(&gatherstate->ps, tupDesc, OUTER_VAR);
/*
* Initialize funnel slot to same tuple descriptor as outer plan.
*/
- if (!ExecContextForcesOids(outerPlanState(gatherstate), &hasoid))
- hasoid = false;
- tupDesc = ExecTypeFromTL(outerNode->targetlist, hasoid);
- ExecSetSlotDescriptor(gatherstate->funnel_slot, tupDesc);
+ gatherstate->funnel_slot = ExecInitExtraTupleSlot(estate, tupDesc);
/*
- * Initialize result tuple type and projection info.
+ * Gather doesn't support checking a qual (it's always more efficient to
+ * do it in the child node).
*/
- ExecAssignResultTypeFromTL(&gatherstate->ps);
- ExecConditionalAssignProjectionInfo(&gatherstate->ps, tupDesc, OUTER_VAR);
+ Assert(!node->plan.qual);
return gatherstate;
}
{
GatherMergeState *gm_state;
Plan *outerNode;
- bool hasoid;
TupleDesc tupDesc;
/* Gather merge node doesn't have innerPlan node. */
*/
Assert(!node->plan.qual);
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &gm_state->ps);
-
/*
* now initialize outer plan
*/
* Store the tuple descriptor into gather merge state, so we can use it
* while initializing the gather merge slots.
*/
- if (!ExecContextForcesOids(outerPlanState(gm_state), &hasoid))
- hasoid = false;
- tupDesc = ExecTypeFromTL(outerNode->targetlist, hasoid);
+ tupDesc = ExecGetResultType(outerPlanState(gm_state));
gm_state->tupDesc = tupDesc;
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&gm_state->ps);
+ ExecInitResultTupleSlotTL(estate, &gm_state->ps);
ExecConditionalAssignProjectionInfo(&gm_state->ps, tupDesc, OUTER_VAR);
/*
(HeapTuple *) palloc0(sizeof(HeapTuple) * MAX_TUPLE_STORE);
/* Initialize tuple slot for worker */
- gm_state->gm_slots[i + 1] = ExecInitExtraTupleSlot(gm_state->ps.state);
- ExecSetSlotDescriptor(gm_state->gm_slots[i + 1],
- gm_state->tupDesc);
+ gm_state->gm_slots[i + 1] =
+ ExecInitExtraTupleSlot(gm_state->ps.state, gm_state->tupDesc);
}
/* Allocate the resources for the merge */
*/
ExecAssignExprContext(estate, &grpstate->ss.ps);
- /*
- * tuple table initialization
- */
- ExecInitScanTupleSlot(estate, &grpstate->ss);
- ExecInitResultTupleSlot(estate, &grpstate->ss.ps);
-
- /*
- * initialize child expressions
- */
- grpstate->ss.ps.qual =
- ExecInitQual(node->plan.qual, (PlanState *) grpstate);
-
/*
* initialize child nodes
*/
outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags);
/*
- * initialize tuple type.
+ * Initialize scan slot and type.
*/
- ExecAssignScanTypeFromOuterPlan(&grpstate->ss);
+ ExecCreateScanSlotFromOuterPlan(estate, &grpstate->ss);
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&grpstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &grpstate->ss.ps);
ExecAssignProjectionInfo(&grpstate->ss.ps, NULL);
+ /*
+ * initialize child expressions
+ */
+ grpstate->ss.ps.qual =
+ ExecInitQual(node->plan.qual, (PlanState *) grpstate);
+
/*
* Precompute fmgr lookup data for inner loop
*/
*/
ExecAssignExprContext(estate, &hashstate->ps);
- /*
- * initialize our result slot
- */
- ExecInitResultTupleSlot(estate, &hashstate->ps);
-
- /*
- * initialize child expressions
- */
- hashstate->ps.qual =
- ExecInitQual(node->plan.qual, (PlanState *) hashstate);
-
/*
* initialize child nodes
*/
outerPlanState(hashstate) = ExecInitNode(outerPlan(node), estate, eflags);
/*
- * initialize tuple type. no need to initialize projection info because
- * this node doesn't do projections
+ * initialize our result slot and type. No need to build projection
+ * because this node doesn't do projections.
*/
- ExecAssignResultTypeFromTL(&hashstate->ps);
+ ExecInitResultTupleSlotTL(estate, &hashstate->ps);
hashstate->ps.ps_ProjInfo = NULL;
+ /*
+ * initialize child expressions
+ */
+ hashstate->ps.qual =
+ ExecInitQual(node->plan.qual, (PlanState *) hashstate);
+
return hashstate;
}
List *lclauses;
List *rclauses;
List *hoperators;
+ TupleDesc outerDesc, innerDesc;
ListCell *l;
/* check for unsupported flags */
* managed to launch a parallel query.
*/
hjstate->js.ps.ExecProcNode = ExecHashJoin;
+ hjstate->js.jointype = node->join.jointype;
/*
* Miscellaneous initialization
*/
ExecAssignExprContext(estate, &hjstate->js.ps);
- /*
- * initialize child expressions
- */
- hjstate->js.ps.qual =
- ExecInitQual(node->join.plan.qual, (PlanState *) hjstate);
- hjstate->js.jointype = node->join.jointype;
- hjstate->js.joinqual =
- ExecInitQual(node->join.joinqual, (PlanState *) hjstate);
- hjstate->hashclauses =
- ExecInitQual(node->hashclauses, (PlanState *) hjstate);
-
/*
* initialize child nodes
*
hashNode = (Hash *) innerPlan(node);
outerPlanState(hjstate) = ExecInitNode(outerNode, estate, eflags);
+ outerDesc = ExecGetResultType(outerPlanState(hjstate));
innerPlanState(hjstate) = ExecInitNode((Plan *) hashNode, estate, eflags);
+ innerDesc = ExecGetResultType(innerPlanState(hjstate));
+
+ /*
+ * Initialize result slot, type and projection.
+ */
+ ExecInitResultTupleSlotTL(estate, &hjstate->js.ps);
+ ExecAssignProjectionInfo(&hjstate->js.ps, NULL);
/*
* tuple table initialization
*/
- ExecInitResultTupleSlot(estate, &hjstate->js.ps);
- hjstate->hj_OuterTupleSlot = ExecInitExtraTupleSlot(estate);
+ hjstate->hj_OuterTupleSlot = ExecInitExtraTupleSlot(estate, outerDesc);
/*
* detect whether we need only consider the first matching inner tuple
case JOIN_LEFT:
case JOIN_ANTI:
hjstate->hj_NullInnerTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(innerPlanState(hjstate)));
+ ExecInitNullTupleSlot(estate, innerDesc);
break;
case JOIN_RIGHT:
hjstate->hj_NullOuterTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(outerPlanState(hjstate)));
+ ExecInitNullTupleSlot(estate, outerDesc);
break;
case JOIN_FULL:
hjstate->hj_NullOuterTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(outerPlanState(hjstate)));
+ ExecInitNullTupleSlot(estate, outerDesc);
hjstate->hj_NullInnerTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(innerPlanState(hjstate)));
+ ExecInitNullTupleSlot(estate, innerDesc);
break;
default:
elog(ERROR, "unrecognized join type: %d",
}
/*
- * initialize tuple type and projection info
+ * initialize child expressions
*/
- ExecAssignResultTypeFromTL(&hjstate->js.ps);
- ExecAssignProjectionInfo(&hjstate->js.ps, NULL);
-
- ExecSetSlotDescriptor(hjstate->hj_OuterTupleSlot,
- ExecGetResultType(outerPlanState(hjstate)));
+ hjstate->js.ps.qual =
+ ExecInitQual(node->join.plan.qual, (PlanState *) hjstate);
+ hjstate->js.joinqual =
+ ExecInitQual(node->join.joinqual, (PlanState *) hjstate);
+ hjstate->hashclauses =
+ ExecInitQual(node->hashclauses, (PlanState *) hjstate);
/*
* initialize hash-specific info
*/
ExecAssignExprContext(estate, &indexstate->ss.ps);
- /*
- * initialize child expressions
- *
- * Note: we don't initialize all of the indexorderby expression, only the
- * sub-parts corresponding to runtime keys (see below).
- */
- indexstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) indexstate);
- indexstate->indexqual =
- ExecInitQual(node->indexqual, (PlanState *) indexstate);
-
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &indexstate->ss.ps);
- ExecInitScanTupleSlot(estate, &indexstate->ss);
-
/*
* open the base relation and acquire appropriate lock on it.
*/
* suitable data anyway.)
*/
tupDesc = ExecTypeFromTL(node->indextlist, false);
- ExecAssignScanType(&indexstate->ss, tupDesc);
+ ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc);
/*
- * Initialize result tuple type and projection info. The node's
+ * Initialize result slot, type and projection info. The node's
* targetlist will contain Vars with varno = INDEX_VAR, referencing the
* scan tuple.
*/
- ExecAssignResultTypeFromTL(&indexstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &indexstate->ss.ps);
ExecAssignScanProjectionInfoWithVarno(&indexstate->ss, INDEX_VAR);
+ /*
+ * initialize child expressions
+ *
+ * Note: we don't initialize all of the indexorderby expression, only the
+ * sub-parts corresponding to runtime keys (see below).
+ */
+ indexstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) indexstate);
+ indexstate->indexqual =
+ ExecInitQual(node->indexqual, (PlanState *) indexstate);
+
/*
* If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
* here. This allows an index-advisor plugin to EXPLAIN a plan containing
*/
ExecAssignExprContext(estate, &indexstate->ss.ps);
+ /*
+ * open the base relation and acquire appropriate lock on it.
+ */
+ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
+
+ indexstate->ss.ss_currentRelation = currentRelation;
+ indexstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
+
+ /*
+ * get the scan type from the relation descriptor.
+ */
+ ExecInitScanTupleSlot(estate, &indexstate->ss,
+ RelationGetDescr(currentRelation));
+
+ /*
+ * Initialize result slot, type and projection.
+ */
+ ExecInitResultTupleSlotTL(estate, &indexstate->ss.ps);
+ ExecAssignScanProjectionInfo(&indexstate->ss);
+
/*
* initialize child expressions
*
indexstate->indexorderbyorig =
ExecInitExprList(node->indexorderbyorig, (PlanState *) indexstate);
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &indexstate->ss.ps);
- ExecInitScanTupleSlot(estate, &indexstate->ss);
-
- /*
- * open the base relation and acquire appropriate lock on it.
- */
- currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags);
-
- indexstate->ss.ss_currentRelation = currentRelation;
- indexstate->ss.ss_currentScanDesc = NULL; /* no heap scan here */
-
- /*
- * get the scan type from the relation descriptor.
- */
- ExecAssignScanType(&indexstate->ss, RelationGetDescr(currentRelation));
-
- /*
- * Initialize result tuple type and projection info.
- */
- ExecAssignResultTypeFromTL(&indexstate->ss.ps);
- ExecAssignScanProjectionInfo(&indexstate->ss);
-
/*
* If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
* here. This allows an index-advisor plugin to EXPLAIN a plan containing
*/
ExecAssignExprContext(estate, &limitstate->ps);
+ /*
+ * initialize outer plan
+ */
+ outerPlan = outerPlan(node);
+ outerPlanState(limitstate) = ExecInitNode(outerPlan, estate, eflags);
+
/*
* initialize child expressions
*/
(PlanState *) limitstate);
/*
- * Tuple table initialization (XXX not actually used...)
+ * Initialize result slot and type. (XXX not actually used, but upper
+ * nodes access it to get this node's result tupledesc...)
*/
- ExecInitResultTupleSlot(estate, &limitstate->ps);
-
- /*
- * then initialize outer plan
- */
- outerPlan = outerPlan(node);
- outerPlanState(limitstate) = ExecInitNode(outerPlan, estate, eflags);
+ ExecInitResultTupleSlotTL(estate, &limitstate->ps);
/*
* limit nodes do no projections, so initialize projection info for this
* node appropriately
*/
- ExecAssignResultTypeFromTL(&limitstate->ps);
limitstate->ps.ps_ProjInfo = NULL;
return limitstate;
/*
* Miscellaneous initialization
*
- * LockRows nodes never call ExecQual or ExecProject.
+ * LockRows nodes never call ExecQual or ExecProject, therefore no
+ * ExprContext is needed.
*/
/*
- * Tuple table initialization (XXX not actually used...)
+ * Tuple table initialization (XXX not actually used, but upper nodes
+ * access it to get this node's result tupledesc...)
*/
- ExecInitResultTupleSlot(estate, &lrstate->ps);
+ ExecInitResultTupleSlotTL(estate, &lrstate->ps);
/*
* then initialize outer plan
* LockRows nodes do no projections, so initialize projection info for
* this node appropriately
*/
- ExecAssignResultTypeFromTL(&lrstate->ps);
lrstate->ps.ps_ProjInfo = NULL;
/*
* ExecQual or ExecProject.
*/
- /*
- * tuple table initialization
- *
- * material nodes only return tuples from their materialized relation.
- */
- ExecInitResultTupleSlot(estate, &matstate->ss.ps);
- ExecInitScanTupleSlot(estate, &matstate->ss);
-
/*
* initialize child nodes
*
outerPlanState(matstate) = ExecInitNode(outerPlan, estate, eflags);
/*
- * initialize tuple type. no need to initialize projection info because
- * this node doesn't do projections.
+ * Initialize result type and slot. No need to initialize projection info
+ * because this node doesn't do projections.
+ *
+ * material nodes only return tuples from their materialized relation.
*/
- ExecAssignResultTypeFromTL(&matstate->ss.ps);
- ExecAssignScanTypeFromOuterPlan(&matstate->ss);
+ ExecInitResultTupleSlotTL(estate, &matstate->ss.ps);
matstate->ss.ps.ps_ProjInfo = NULL;
+ /*
+ * initialize tuple type.
+ */
+ ExecCreateScanSlotFromOuterPlan(estate, &matstate->ss);
+
return matstate;
}
* MergeAppend nodes do have Result slots, which hold pointers to tuples,
* so we have to initialize them.
*/
- ExecInitResultTupleSlot(estate, &mergestate->ps);
+ ExecInitResultTupleSlotTL(estate, &mergestate->ps);
/*
* call ExecInitNode on each of the plans to be executed and save the
i++;
}
- /*
- * initialize output tuple type
- */
- ExecAssignResultTypeFromTL(&mergestate->ps);
mergestate->ps.ps_ProjInfo = NULL;
/*
ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
{
MergeJoinState *mergestate;
+ TupleDesc outerDesc, innerDesc;
/* check for unsupported flags */
Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
mergestate->js.ps.plan = (Plan *) node;
mergestate->js.ps.state = estate;
mergestate->js.ps.ExecProcNode = ExecMergeJoin;
+ mergestate->js.jointype = node->join.jointype;
+ mergestate->mj_ConstFalseJoin = false;
/*
* Miscellaneous initialization
mergestate->mj_OuterEContext = CreateExprContext(estate);
mergestate->mj_InnerEContext = CreateExprContext(estate);
- /*
- * initialize child expressions
- */
- mergestate->js.ps.qual =
- ExecInitQual(node->join.plan.qual, (PlanState *) mergestate);
- mergestate->js.jointype = node->join.jointype;
- mergestate->js.joinqual =
- ExecInitQual(node->join.joinqual, (PlanState *) mergestate);
- mergestate->mj_ConstFalseJoin = false;
- /* mergeclauses are handled below */
-
/*
* initialize child nodes
*
mergestate->mj_SkipMarkRestore = node->skip_mark_restore;
outerPlanState(mergestate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerDesc = ExecGetResultType(outerPlanState(mergestate));
innerPlanState(mergestate) = ExecInitNode(innerPlan(node), estate,
mergestate->mj_SkipMarkRestore ?
eflags :
(eflags | EXEC_FLAG_MARK));
+ innerDesc = ExecGetResultType(innerPlanState(mergestate));
/*
* For certain types of inner child nodes, it is advantageous to issue
else
mergestate->mj_ExtraMarks = false;
+ /*
+ * Initialize result slot, type and projection.
+ */
+ ExecInitResultTupleSlotTL(estate, &mergestate->js.ps);
+ ExecAssignProjectionInfo(&mergestate->js.ps, NULL);
+
/*
* tuple table initialization
*/
- ExecInitResultTupleSlot(estate, &mergestate->js.ps);
+ mergestate->mj_MarkedTupleSlot = ExecInitExtraTupleSlot(estate, innerDesc);
- mergestate->mj_MarkedTupleSlot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(mergestate->mj_MarkedTupleSlot,
- ExecGetResultType(innerPlanState(mergestate)));
+ /*
+ * initialize child expressions
+ */
+ mergestate->js.ps.qual =
+ ExecInitQual(node->join.plan.qual, (PlanState *) mergestate);
+ mergestate->js.joinqual =
+ ExecInitQual(node->join.joinqual, (PlanState *) mergestate);
+ /* mergeclauses are handled below */
/*
* detect whether we need only consider the first matching inner tuple
mergestate->mj_FillOuter = true;
mergestate->mj_FillInner = false;
mergestate->mj_NullInnerTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(innerPlanState(mergestate)));
+ ExecInitNullTupleSlot(estate, innerDesc);
break;
case JOIN_RIGHT:
mergestate->mj_FillOuter = false;
mergestate->mj_FillInner = true;
mergestate->mj_NullOuterTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(outerPlanState(mergestate)));
+ ExecInitNullTupleSlot(estate, outerDesc);
/*
* Can't handle right or full join with non-constant extra
mergestate->mj_FillOuter = true;
mergestate->mj_FillInner = true;
mergestate->mj_NullOuterTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(outerPlanState(mergestate)));
+ ExecInitNullTupleSlot(estate, outerDesc);
mergestate->mj_NullInnerTupleSlot =
- ExecInitNullTupleSlot(estate,
- ExecGetResultType(innerPlanState(mergestate)));
+ ExecInitNullTupleSlot(estate, innerDesc);
/*
* Can't handle right or full join with non-constant extra
(int) node->join.jointype);
}
- /*
- * initialize tuple type and projection info
- */
- ExecAssignResultTypeFromTL(&mergestate->js.ps);
- ExecAssignProjectionInfo(&mergestate->js.ps, NULL);
-
/*
* preprocess the merge clauses
*/
mtstate->ps.plan->targetlist = (List *) linitial(node->returningLists);
/* Set up a slot for the output of the RETURNING projection(s) */
- ExecInitResultTupleSlot(estate, &mtstate->ps);
- ExecAssignResultTypeFromTL(&mtstate->ps);
+ ExecInitResultTupleSlotTL(estate, &mtstate->ps);
slot = mtstate->ps.ps_ResultTupleSlot;
/* Need an econtext too */
* expects one (maybe should change that?).
*/
mtstate->ps.plan->targetlist = NIL;
- ExecInitResultTupleSlot(estate, &mtstate->ps);
- ExecAssignResultTypeFromTL(&mtstate->ps);
+ ExecInitResultTupleSlotTL(estate, &mtstate->ps);
mtstate->ps.ps_ExprContext = NULL;
}
if (node->onConflictAction == ONCONFLICT_UPDATE)
{
ExprContext *econtext;
+ TupleDesc relationDesc;
TupleDesc tupDesc;
/* insert may only have one plan, inheritance is not expanded */
ExecAssignExprContext(estate, &mtstate->ps);
econtext = mtstate->ps.ps_ExprContext;
+ relationDesc = resultRelInfo->ri_RelationDesc->rd_att;
/* initialize slot for the existing tuple */
- mtstate->mt_existing = ExecInitExtraTupleSlot(mtstate->ps.state);
- ExecSetSlotDescriptor(mtstate->mt_existing,
- resultRelInfo->ri_RelationDesc->rd_att);
+ mtstate->mt_existing =
+ ExecInitExtraTupleSlot(mtstate->ps.state, relationDesc);
/* carried forward solely for the benefit of explain */
mtstate->mt_excludedtlist = node->exclRelTlist;
/* create target slot for UPDATE SET projection */
tupDesc = ExecTypeFromTL((List *) node->onConflictSet,
- resultRelInfo->ri_RelationDesc->rd_rel->relhasoids);
- mtstate->mt_conflproj = ExecInitExtraTupleSlot(mtstate->ps.state);
- ExecSetSlotDescriptor(mtstate->mt_conflproj, tupDesc);
+ relationDesc->tdhasoid);
+ mtstate->mt_conflproj =
+ ExecInitExtraTupleSlot(mtstate->ps.state, tupDesc);
/* build UPDATE SET projection state */
resultRelInfo->ri_onConflictSetProj =
ExecBuildProjectionInfo(node->onConflictSet, econtext,
mtstate->mt_conflproj, &mtstate->ps,
- resultRelInfo->ri_RelationDesc->rd_att);
+ relationDesc);
/* build DO UPDATE WHERE clause expression */
if (node->onConflictWhere)
j = ExecInitJunkFilter(subplan->targetlist,
resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
- ExecInitExtraTupleSlot(estate));
+ ExecInitExtraTupleSlot(estate, NULL));
if (operation == CMD_UPDATE || operation == CMD_DELETE)
{
* we keep it in the estate.
*/
if (estate->es_trig_tuple_slot == NULL)
- estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate);
+ estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate, NULL);
/*
* Lastly, if this is not the primary (canSetTag) ModifyTable node, add it
ExecAssignExprContext(estate, &scanstate->ss.ps);
/*
- * initialize child expressions
+ * Tuple table and result type initialization. The scan tuple type is
+ * specified for the tuplestore.
*/
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
+ ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc);
/*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
-
- /*
- * The scan tuple type is specified for the tuplestore.
+ * initialize child expressions
*/
- ExecAssignScanType(&scanstate->ss, scanstate->tupdesc);
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
/*
- * Initialize result tuple type and projection info.
+ * Initialize projection.
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
ExecAssignScanProjectionInfo(&scanstate->ss);
return scanstate;
*/
ExecAssignExprContext(estate, &nlstate->js.ps);
- /*
- * initialize child expressions
- */
- nlstate->js.ps.qual =
- ExecInitQual(node->join.plan.qual, (PlanState *) nlstate);
- nlstate->js.jointype = node->join.jointype;
- nlstate->js.joinqual =
- ExecInitQual(node->join.joinqual, (PlanState *) nlstate);
-
/*
* initialize child nodes
*
innerPlanState(nlstate) = ExecInitNode(innerPlan(node), estate, eflags);
/*
- * tuple table initialization
+ * Initialize result slot, type and projection.
*/
- ExecInitResultTupleSlot(estate, &nlstate->js.ps);
+ ExecInitResultTupleSlotTL(estate, &nlstate->js.ps);
+ ExecAssignProjectionInfo(&nlstate->js.ps, NULL);
+
+ /*
+ * initialize child expressions
+ */
+ nlstate->js.ps.qual =
+ ExecInitQual(node->join.plan.qual, (PlanState *) nlstate);
+ nlstate->js.jointype = node->join.jointype;
+ nlstate->js.joinqual =
+ ExecInitQual(node->join.joinqual, (PlanState *) nlstate);
/*
* detect whether we need only consider the first matching inner tuple
(int) node->join.jointype);
}
- /*
- * initialize tuple type and projection info
- */
- ExecAssignResultTypeFromTL(&nlstate->js.ps);
- ExecAssignProjectionInfo(&nlstate->js.ps, NULL);
-
/*
* finally, wipe the current outer tuple clean.
*/
*/
ExecAssignExprContext(estate, &state->ps);
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &state->ps);
-
- /* We don't support any qual on ProjectSet nodes */
- Assert(node->plan.qual == NIL);
-
/*
* initialize child nodes
*/
Assert(innerPlan(node) == NULL);
/*
- * initialize tuple type and projection info
+ * tuple table and result type initialization
*/
- ExecAssignResultTypeFromTL(&state->ps);
+ ExecInitResultTupleSlotTL(estate, &state->ps);
/* Create workspace for per-tlist-entry expr state & SRF-is-done state */
state->nelems = list_length(node->plan.targetlist);
off++;
}
+ /* We don't support any qual on ProjectSet nodes */
+ Assert(node->plan.qual == NIL);
/*
* Create a memory context that ExecMakeFunctionResult can use to evaluate
* RecursiveUnion nodes still have Result slots, which hold pointers to
* tuples, so we have to initialize them.
*/
- ExecInitResultTupleSlot(estate, &rustate->ps);
+ ExecInitResultTupleSlotTL(estate, &rustate->ps);
/*
- * Initialize result tuple type and projection info. (Note: we have to
- * set up the result type before initializing child nodes, because
- * nodeWorktablescan.c expects it to be valid.)
+ * Initialize result tuple type. (Note: we have to set up the result type
+ * before initializing child nodes, because nodeWorktablescan.c expects it
+ * to be valid.)
*/
- ExecAssignResultTypeFromTL(&rustate->ps);
rustate->ps.ps_ProjInfo = NULL;
/*
*/
ExecAssignExprContext(estate, &resstate->ps);
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &resstate->ps);
-
- /*
- * initialize child expressions
- */
- resstate->ps.qual =
- ExecInitQual(node->plan.qual, (PlanState *) resstate);
- resstate->resconstantqual =
- ExecInitQual((List *) node->resconstantqual, (PlanState *) resstate);
-
/*
* initialize child nodes
*/
Assert(innerPlan(node) == NULL);
/*
- * initialize tuple type and projection info
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&resstate->ps);
+ ExecInitResultTupleSlotTL(estate, &resstate->ps);
ExecAssignProjectionInfo(&resstate->ps, NULL);
+ /*
+ * initialize child expressions
+ */
+ resstate->ps.qual =
+ ExecInitQual(node->plan.qual, (PlanState *) resstate);
+ resstate->resconstantqual =
+ ExecInitQual((List *) node->resconstantqual, (PlanState *) resstate);
+
return resstate;
}
#include "utils/rel.h"
#include "utils/tqual.h"
-static void InitScanRelation(SampleScanState *node, EState *estate, int eflags);
static TupleTableSlot *SampleNext(SampleScanState *node);
static void tablesample_init(SampleScanState *scanstate);
static HeapTuple tablesample_getnext(SampleScanState *scanstate);
(ExecScanRecheckMtd) SampleRecheck);
}
-/* ----------------------------------------------------------------
- * InitScanRelation
- *
- * Set up to access the scan relation.
- * ----------------------------------------------------------------
- */
-static void
-InitScanRelation(SampleScanState *node, EState *estate, int eflags)
-{
- Relation currentRelation;
-
- /*
- * get the relation object id from the relid'th entry in the range table,
- * open that relation and acquire appropriate lock on it.
- */
- currentRelation = ExecOpenScanRelation(estate,
- ((SampleScan *) node->ss.ps.plan)->scan.scanrelid,
- eflags);
-
- node->ss.ss_currentRelation = currentRelation;
-
- /* we won't set up the HeapScanDesc till later */
- node->ss.ss_currentScanDesc = NULL;
-
- /* and report the scan tuple slot's rowtype */
- ExecAssignScanType(&node->ss, RelationGetDescr(currentRelation));
-}
-
-
/* ----------------------------------------------------------------
* ExecInitSampleScan
* ----------------------------------------------------------------
ExecAssignExprContext(estate, &scanstate->ss.ps);
/*
- * initialize child expressions
+ * Initialize scan relation.
+ *
+ * Get the relation object id from the relid'th entry in the range table,
+ * open that relation and acquire appropriate lock on it.
*/
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+ scanstate->ss.ss_currentRelation =
+ ExecOpenScanRelation(estate,
+ node->scan.scanrelid,
+ eflags);
- scanstate->args = ExecInitExprList(tsc->args, (PlanState *) scanstate);
- scanstate->repeatable =
- ExecInitExpr(tsc->repeatable, (PlanState *) scanstate);
+ /* we won't set up the HeapScanDesc till later */
+ scanstate->ss.ss_currentScanDesc = NULL;
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
+ /* and create slot with appropriate rowtype */
+ ExecInitScanTupleSlot(estate, &scanstate->ss,
+ RelationGetDescr(scanstate->ss.ss_currentRelation));
/*
- * initialize scan relation
+ * Initialize result slot, type and projection.
+ * tuple table and result tuple initialization
*/
- InitScanRelation(scanstate, estate, eflags);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
+ ExecAssignScanProjectionInfo(&scanstate->ss);
/*
- * Initialize result tuple type and projection info.
+ * initialize child expressions
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
- ExecAssignScanProjectionInfo(&scanstate->ss);
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+
+ scanstate->args = ExecInitExprList(tsc->args, (PlanState *) scanstate);
+ scanstate->repeatable =
+ ExecInitExpr(tsc->repeatable, (PlanState *) scanstate);
/*
* If we don't have a REPEATABLE clause, select a random seed. We want to
#include "executor/nodeSeqscan.h"
#include "utils/rel.h"
-static void InitScanRelation(SeqScanState *node, EState *estate, int eflags);
static TupleTableSlot *SeqNext(SeqScanState *node);
/* ----------------------------------------------------------------
(ExecScanRecheckMtd) SeqRecheck);
}
-/* ----------------------------------------------------------------
- * InitScanRelation
- *
- * Set up to access the scan relation.
- * ----------------------------------------------------------------
- */
-static void
-InitScanRelation(SeqScanState *node, EState *estate, int eflags)
-{
- Relation currentRelation;
-
- /*
- * get the relation object id from the relid'th entry in the range table,
- * open that relation and acquire appropriate lock on it.
- */
- currentRelation = ExecOpenScanRelation(estate,
- ((SeqScan *) node->ss.ps.plan)->scanrelid,
- eflags);
-
- node->ss.ss_currentRelation = currentRelation;
-
- /* and report the scan tuple slot's rowtype */
- ExecAssignScanType(&node->ss, RelationGetDescr(currentRelation));
-}
-
/* ----------------------------------------------------------------
* ExecInitSeqScan
ExecAssignExprContext(estate, &scanstate->ss.ps);
/*
- * initialize child expressions
+ * Initialize scan relation.
+ *
+ * Get the relation object id from the relid'th entry in the range table,
+ * open that relation and acquire appropriate lock on it.
*/
- scanstate->ss.ps.qual =
- ExecInitQual(node->plan.qual, (PlanState *) scanstate);
+ scanstate->ss.ss_currentRelation =
+ ExecOpenScanRelation(estate,
+ node->scanrelid,
+ eflags);
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
+ /* and create slot with the appropriate rowtype */
+ ExecInitScanTupleSlot(estate, &scanstate->ss,
+ RelationGetDescr(scanstate->ss.ss_currentRelation));
/*
- * initialize scan relation
+ * Initialize result slot, type and projection.
*/
- InitScanRelation(scanstate, estate, eflags);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
+ ExecAssignScanProjectionInfo(&scanstate->ss);
/*
- * Initialize result tuple type and projection info.
+ * initialize child expressions
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
- ExecAssignScanProjectionInfo(&scanstate->ss);
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->plan.qual, (PlanState *) scanstate);
return scanstate;
}
"SetOp hash table",
ALLOCSET_DEFAULT_SIZES);
- /*
- * Tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &setopstate->ps);
-
/*
* initialize child nodes
*
outerDesc = ExecGetResultType(outerPlanState(setopstate));
/*
- * setop nodes do no projections, so initialize projection info for this
- * node appropriately
+ * Initialize result slot and type. Setop nodes do no projections, so
+ * initialize projection info for this node appropriately.
*/
- ExecAssignResultTypeFromTL(&setopstate->ps);
+ ExecInitResultTupleSlotTL(estate, &setopstate->ps);
setopstate->ps.ps_ProjInfo = NULL;
/*
* ExecQual or ExecProject.
*/
- /*
- * tuple table initialization
- *
- * sort nodes only return scan tuples from their sorted relation.
- */
- ExecInitResultTupleSlot(estate, &sortstate->ss.ps);
- ExecInitScanTupleSlot(estate, &sortstate->ss);
-
/*
* initialize child nodes
*
outerPlanState(sortstate) = ExecInitNode(outerPlan(node), estate, eflags);
/*
- * initialize tuple type. no need to initialize projection info because
+ * Initialize scan slot and type.
+ */
+ ExecCreateScanSlotFromOuterPlan(estate, &sortstate->ss);
+
+ /*
+ * Initialize return slot and type. No need to initialize projection info because
* this node doesn't do projections.
*/
- ExecAssignResultTypeFromTL(&sortstate->ss.ps);
- ExecAssignScanTypeFromOuterPlan(&sortstate->ss);
+ ExecInitResultTupleSlotTL(estate, &sortstate->ss.ps);
sortstate->ss.ps.ps_ProjInfo = NULL;
SO1_printf("ExecInitSort: %s\n",
* own innerecontext.
*/
tupDescLeft = ExecTypeFromTL(lefttlist, false);
- slot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(slot, tupDescLeft);
+ slot = ExecInitExtraTupleSlot(estate, tupDescLeft);
sstate->projLeft = ExecBuildProjectionInfo(lefttlist,
NULL,
slot,
NULL);
sstate->descRight = tupDescRight = ExecTypeFromTL(righttlist, false);
- slot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(slot, tupDescRight);
+ slot = ExecInitExtraTupleSlot(estate, tupDescRight);
sstate->projRight = ExecBuildProjectionInfo(righttlist,
sstate->innerecontext,
slot,
*/
ExecAssignExprContext(estate, &subquerystate->ss.ps);
- /*
- * initialize child expressions
- */
- subquerystate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) subquerystate);
-
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &subquerystate->ss.ps);
- ExecInitScanTupleSlot(estate, &subquerystate->ss);
-
/*
* initialize subquery
*/
subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
/*
- * Initialize scan tuple type (needed by ExecAssignScanProjectionInfo)
+ * Initialize scan slot and type (needed by ExecInitResultTupleSlotTL)
*/
- ExecAssignScanType(&subquerystate->ss,
- ExecGetResultType(subquerystate->subplan));
+ ExecInitScanTupleSlot(estate, &subquerystate->ss,
+ ExecGetResultType(subquerystate->subplan));
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&subquerystate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &subquerystate->ss.ps);
ExecAssignScanProjectionInfo(&subquerystate->ss);
+ /*
+ * initialize child expressions
+ */
+ subquerystate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) subquerystate);
+
return subquerystate;
}
*/
ExecAssignExprContext(estate, &scanstate->ss.ps);
- /*
- * initialize child expressions
- */
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, &scanstate->ss.ps);
-
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
-
/*
* initialize source tuple type
*/
tf->coltypes,
tf->coltypmods,
tf->colcollations);
-
- ExecAssignScanType(&scanstate->ss, tupdesc);
+ /* and the corresponding scan slot */
+ ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc);
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
ExecAssignScanProjectionInfo(&scanstate->ss);
+ /*
+ * initialize child expressions
+ */
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, &scanstate->ss.ps);
+
/* Only XMLTABLE is supported currently */
scanstate->routine = &XmlTableRoutine;
*/
ExecAssignExprContext(estate, &tidstate->ss.ps);
- /*
- * initialize child expressions
- */
- tidstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) tidstate);
-
- TidExprListCreate(tidstate);
-
- /*
- * tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &tidstate->ss.ps);
- ExecInitScanTupleSlot(estate, &tidstate->ss);
-
/*
* mark tid list as not computed yet
*/
/*
* get the scan type from the relation descriptor.
*/
- ExecAssignScanType(&tidstate->ss, RelationGetDescr(currentRelation));
+ ExecInitScanTupleSlot(estate, &tidstate->ss,
+ RelationGetDescr(currentRelation));
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&tidstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &tidstate->ss.ps);
ExecAssignScanProjectionInfo(&tidstate->ss);
+ /*
+ * initialize child expressions
+ */
+ tidstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) tidstate);
+
+ TidExprListCreate(tidstate);
+
/*
* all done.
*/
*/
ExecAssignExprContext(estate, &uniquestate->ps);
- /*
- * Tuple table initialization
- */
- ExecInitResultTupleSlot(estate, &uniquestate->ps);
-
/*
* then initialize outer plan
*/
outerPlanState(uniquestate) = ExecInitNode(outerPlan(node), estate, eflags);
/*
- * unique nodes do no projections, so initialize projection info for this
- * node appropriately
+ * Initialize result slot and type. Unique nodes do no projections, so
+ * initialize projection info for this node appropriately.
*/
- ExecAssignResultTypeFromTL(&uniquestate->ps);
+ ExecInitResultTupleSlotTL(estate, &uniquestate->ps);
uniquestate->ps.ps_ProjInfo = NULL;
/*
ExecAssignExprContext(estate, planstate);
/*
- * tuple table initialization
+ * Get info about values list, initialize scan slot with it.
*/
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
+ tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
+ ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc);
/*
- * initialize child expressions
+ * Initialize result slot, type and projection.
*/
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
+ ExecAssignScanProjectionInfo(&scanstate->ss);
/*
- * get info about values list
+ * initialize child expressions
*/
- tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists));
-
- ExecAssignScanType(&scanstate->ss, tupdesc);
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
/*
* Other node-specific setup
scanstate->exprlists[i++] = (List *) lfirst(vtl);
}
- /*
- * Initialize result tuple type and projection info.
- */
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
- ExecAssignScanProjectionInfo(&scanstate->ss);
-
return scanstate;
}
"WindowAgg Aggregates",
ALLOCSET_DEFAULT_SIZES);
- /*
- * tuple table initialization
- */
- ExecInitScanTupleSlot(estate, &winstate->ss);
- ExecInitResultTupleSlot(estate, &winstate->ss.ps);
- winstate->first_part_slot = ExecInitExtraTupleSlot(estate);
- winstate->agg_row_slot = ExecInitExtraTupleSlot(estate);
- winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate);
- winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate);
-
- /*
- * create frame head and tail slots only if needed (must match logic in
- * update_frameheadpos and update_frametailpos)
- */
- winstate->framehead_slot = winstate->frametail_slot = NULL;
-
- if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS))
- {
- if (!(frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING))
- winstate->framehead_slot = ExecInitExtraTupleSlot(estate);
- if (!(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING))
- winstate->frametail_slot = ExecInitExtraTupleSlot(estate);
- }
-
/*
* WindowAgg nodes never have quals, since they can only occur at the
* logical top level of a query (ie, after any WHERE or HAVING filters)
* initialize source tuple type (which is also the tuple type that we'll
* store in the tuplestore and use in all our working slots).
*/
- ExecAssignScanTypeFromOuterPlan(&winstate->ss);
+ ExecCreateScanSlotFromOuterPlan(estate, &winstate->ss);
scanDesc = winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor;
- ExecSetSlotDescriptor(winstate->first_part_slot,
- winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor);
- ExecSetSlotDescriptor(winstate->agg_row_slot,
- winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor);
- ExecSetSlotDescriptor(winstate->temp_slot_1,
- winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor);
- ExecSetSlotDescriptor(winstate->temp_slot_2,
- winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor);
- if (winstate->framehead_slot)
- ExecSetSlotDescriptor(winstate->framehead_slot,
- winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor);
- if (winstate->frametail_slot)
- ExecSetSlotDescriptor(winstate->frametail_slot,
- winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor);
+ /*
+ * tuple table initialization
+ */
+ winstate->first_part_slot = ExecInitExtraTupleSlot(estate, scanDesc);
+ winstate->agg_row_slot = ExecInitExtraTupleSlot(estate, scanDesc);
+ winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate, scanDesc);
+ winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc);
+
+ /*
+ * create frame head and tail slots only if needed (must match logic in
+ * update_frameheadpos and update_frametailpos)
+ */
+ winstate->framehead_slot = winstate->frametail_slot = NULL;
+
+ if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS))
+ {
+ if (!(frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING))
+ winstate->framehead_slot = ExecInitExtraTupleSlot(estate, scanDesc);
+ if (!(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING))
+ winstate->frametail_slot = ExecInitExtraTupleSlot(estate, scanDesc);
+ }
/*
- * Initialize result tuple type and projection info.
+ * Initialize result slot, type and projection.
*/
- ExecAssignResultTypeFromTL(&winstate->ss.ps);
+ ExecInitResultTupleSlotTL(estate, &winstate->ss.ps);
ExecAssignProjectionInfo(&winstate->ss.ps, NULL);
/* Set up data for comparing tuples */
ExecAssignExprContext(estate, &scanstate->ss.ps);
/*
- * initialize child expressions
+ * tuple table initialization
*/
- scanstate->ss.ps.qual =
- ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
+ ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
+ ExecInitScanTupleSlot(estate, &scanstate->ss, NULL);
/*
- * tuple table initialization
+ * initialize child expressions
*/
- ExecInitResultTupleSlot(estate, &scanstate->ss.ps);
- ExecInitScanTupleSlot(estate, &scanstate->ss);
+ scanstate->ss.ps.qual =
+ ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
/*
- * Initialize result tuple type, but not yet projection info.
+ * Do not yet initialize projection info, see ExecWorkTableScan() for
+ * details.
*/
- ExecAssignResultTypeFromTL(&scanstate->ss.ps);
return scanstate;
}
/* Triggers might need a slot */
if (resultRelInfo->ri_TrigDesc)
- estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate);
+ estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate, NULL);
/* Prepare to catch AFTER triggers. */
AfterTriggerBeginQuery();
/* Initialize the executor state. */
estate = create_estate_for_relation(rel);
- remoteslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(remoteslot, RelationGetDescr(rel->localrel));
+ remoteslot = ExecInitExtraTupleSlot(estate,
+ RelationGetDescr(rel->localrel));
/* Process and store remote tuple in the slot */
oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
/* Initialize the executor state. */
estate = create_estate_for_relation(rel);
- remoteslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(remoteslot, RelationGetDescr(rel->localrel));
- localslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(localslot, RelationGetDescr(rel->localrel));
+ remoteslot = ExecInitExtraTupleSlot(estate,
+ RelationGetDescr(rel->localrel));
+ localslot = ExecInitExtraTupleSlot(estate,
+ RelationGetDescr(rel->localrel));
EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1);
PushActiveSnapshot(GetTransactionSnapshot());
/* Initialize the executor state. */
estate = create_estate_for_relation(rel);
- remoteslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(remoteslot, RelationGetDescr(rel->localrel));
- localslot = ExecInitExtraTupleSlot(estate);
- ExecSetSlotDescriptor(localslot, RelationGetDescr(rel->localrel));
+ remoteslot = ExecInitExtraTupleSlot(estate,
+ RelationGetDescr(rel->localrel));
+ localslot = ExecInitExtraTupleSlot(estate,
+ RelationGetDescr(rel->localrel));
EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1);
PushActiveSnapshot(GetTransactionSnapshot());
/*
* prototypes from functions in execTuples.c
*/
-extern void ExecInitResultTupleSlot(EState *estate, PlanState *planstate);
-extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate);
-extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate);
+extern void ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate);
+extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupleDesc);
+extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate,
+ TupleDesc tupleDesc);
extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate,
TupleDesc tupType);
extern TupleDesc ExecTypeFromTL(List *targetList, bool hasoid);
} while (0)
extern void ExecAssignExprContext(EState *estate, PlanState *planstate);
-extern void ExecAssignResultType(PlanState *planstate, TupleDesc tupDesc);
-extern void ExecAssignResultTypeFromTL(PlanState *planstate);
extern TupleDesc ExecGetResultType(PlanState *planstate);
extern void ExecAssignProjectionInfo(PlanState *planstate,
TupleDesc inputDesc);
TupleDesc inputDesc, Index varno);
extern void ExecFreeExprContext(PlanState *planstate);
extern void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc);
-extern void ExecAssignScanTypeFromOuterPlan(ScanState *scanstate);
+extern void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate);
extern bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid);
MinimalTuple tts_mintuple; /* minimal tuple, or NULL if none */
HeapTupleData tts_minhdr; /* workspace for minimal-tuple-only case */
long tts_off; /* saved state for slot_deform_tuple */
+ bool tts_fixedTupleDescriptor; /* descriptor can't be changed */
} TupleTableSlot;
#define TTS_HAS_PHYSICAL_TUPLE(slot) \
((slot) == NULL || (slot)->tts_isempty)
/* in executor/execTuples.c */
-extern TupleTableSlot *MakeTupleTableSlot(void);
-extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable);
+extern TupleTableSlot *MakeTupleTableSlot(TupleDesc desc);
+extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc);
extern void ExecResetTupleTable(List *tupleTable, bool shouldFree);
extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc);
extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot);