Don't require return slots for nodes without projection.
In a lot of nodes the return slot is not required. That can either be because the node doesn't do any projection (say an Append node), or because the node does perform projections but the projection is optimized away because the projection would yield an identical row. Slots aren't that small, especially for wide rows, so it's worthwhile to avoid creating them. It's not possible to just skip creating the slot - it's currently used to determine the tuple descriptor returned by ExecGetResultType(). So separate the determination of the result type from the slot creation. The work previously done internally ExecInitResultTupleSlotTL() can now also be done separately with ExecInitResultTypeTL() and ExecInitResultSlot(). That way nodes that aren't guaranteed to need a result slot, can use ExecInitResultTypeTL() to determine the result type of the node, and ExecAssignScanProjectionInfo() (via ExecConditionalAssignProjectionInfo()) determines that a result slot is needed, it is created with ExecInitResultSlot(). Besides the advantage of avoiding to create slots that then are unused, this is necessary preparation for later patches around tuple table slot abstraction. In particular separating the return descriptor and slot is a prerequisite to allow JITing of tuple deforming with knowledge of the underlying tuple format, and to avoid unnecessarily creating JITed tuple deforming for virtual slots. This commit removes a redundant argument from ExecInitResultTupleSlotTL(). While this commit touches a lot of the relevant lines anyway, it'd normally still not worthwhile to cause breakage, except that aforementioned later commits will touch *all* ExecInitResultTupleSlotTL() callers anyway (but fits worse thematically). Author: Andres Freund Discussion: https://postgr.es/m/20181105210039.hh4vvi4vwoq5ba2q@alap3.anarazel.de
This commit is contained in:
parent
3ce1201894
commit
1ef6bd2954
|
@ -19,18 +19,22 @@
|
||||||
*
|
*
|
||||||
* At ExecutorStart()
|
* At ExecutorStart()
|
||||||
* ----------------
|
* ----------------
|
||||||
* - ExecInitSeqScan() calls ExecInitScanTupleSlot() and
|
|
||||||
* ExecInitResultTupleSlotTL() to construct TupleTableSlots
|
* - ExecInitSeqScan() calls ExecInitScanTupleSlot() to construct a
|
||||||
* for the tuples returned by the access methods and the
|
* TupleTableSlots for the tuples returned by the access method, and
|
||||||
* tuples resulting from performing target list projections.
|
* ExecInitResultTypeTL() to define the node's return
|
||||||
|
* type. ExecAssignScanProjectionInfo() will, if necessary, create
|
||||||
|
* another TupleTableSlot for the tuples resulting from performing
|
||||||
|
* target list projections.
|
||||||
*
|
*
|
||||||
* During ExecutorRun()
|
* During ExecutorRun()
|
||||||
* ----------------
|
* ----------------
|
||||||
* - SeqNext() calls ExecStoreBufferHeapTuple() to place the tuple
|
* - SeqNext() calls ExecStoreBufferHeapTuple() to place the tuple
|
||||||
* returned by the access methods into the scan tuple slot.
|
* returned by the access method into the scan tuple slot.
|
||||||
*
|
*
|
||||||
* - ExecSeqScan() calls ExecStoreHeapTuple() to take the result
|
* - ExecSeqScan() (via ExecScan), if necessary, calls ExecProject(),
|
||||||
* tuple from ExecProject() and place it into the result tuple slot.
|
* putting the result of the projection in the result tuple slot. If
|
||||||
|
* not necessary, it directly returns the slot returned by SeqNext().
|
||||||
*
|
*
|
||||||
* - ExecutePlan() calls the output function.
|
* - ExecutePlan() calls the output function.
|
||||||
*
|
*
|
||||||
|
@ -902,23 +906,14 @@ ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* --------------------------------
|
|
||||||
* ExecInit{Result,Scan,Extra}TupleSlot[TL]
|
|
||||||
*
|
|
||||||
* These are convenience routines to initialize the specified slot
|
|
||||||
* in nodes inheriting the appropriate state. ExecInitExtraTupleSlot
|
|
||||||
* is used for initializing special-purpose slots.
|
|
||||||
* --------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* ExecInitResultTupleSlotTL
|
* ExecInitResultTypeTL
|
||||||
*
|
*
|
||||||
* Initialize result tuple slot, using the plan node's targetlist.
|
* Initialize result type, using the plan node's targetlist.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
|
ExecInitResultTypeTL(PlanState *planstate)
|
||||||
{
|
{
|
||||||
bool hasoid;
|
bool hasoid;
|
||||||
TupleDesc tupDesc;
|
TupleDesc tupDesc;
|
||||||
|
@ -934,8 +929,46 @@ ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
|
tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
|
||||||
|
planstate->ps_ResultTupleDesc = tupDesc;
|
||||||
|
}
|
||||||
|
|
||||||
planstate->ps_ResultTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable, tupDesc);
|
/* --------------------------------
|
||||||
|
* ExecInit{Result,Scan,Extra}TupleSlot[TL]
|
||||||
|
*
|
||||||
|
* These are convenience routines to initialize the specified slot
|
||||||
|
* in nodes inheriting the appropriate state. ExecInitExtraTupleSlot
|
||||||
|
* is used for initializing special-purpose slots.
|
||||||
|
* --------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* ExecInitResultTupleSlotTL
|
||||||
|
*
|
||||||
|
* Initialize result tuple slot, using the tuple descriptor previously
|
||||||
|
* computed with ExecInitResultTypeTL().
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ExecInitResultSlot(PlanState *planstate)
|
||||||
|
{
|
||||||
|
TupleTableSlot *slot;
|
||||||
|
|
||||||
|
slot = ExecAllocTableSlot(&planstate->state->es_tupleTable,
|
||||||
|
planstate->ps_ResultTupleDesc);
|
||||||
|
planstate->ps_ResultTupleSlot = slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* ExecInitResultTupleSlotTL
|
||||||
|
*
|
||||||
|
* Initialize result tuple slot, using the plan node's targetlist.
|
||||||
|
* ----------------
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ExecInitResultTupleSlotTL(PlanState *planstate)
|
||||||
|
{
|
||||||
|
ExecInitResultTypeTL(planstate);
|
||||||
|
ExecInitResultSlot(planstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
|
|
|
@ -451,9 +451,7 @@ ExecAssignExprContext(EState *estate, PlanState *planstate)
|
||||||
TupleDesc
|
TupleDesc
|
||||||
ExecGetResultType(PlanState *planstate)
|
ExecGetResultType(PlanState *planstate)
|
||||||
{
|
{
|
||||||
TupleTableSlot *slot = planstate->ps_ResultTupleSlot;
|
return planstate->ps_ResultTupleDesc;
|
||||||
|
|
||||||
return slot->tts_tupleDescriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -496,8 +494,12 @@ ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc,
|
||||||
inputDesc))
|
inputDesc))
|
||||||
planstate->ps_ProjInfo = NULL;
|
planstate->ps_ProjInfo = NULL;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (!planstate->ps_ResultTupleSlot)
|
||||||
|
ExecInitResultSlot(planstate);
|
||||||
ExecAssignProjectionInfo(planstate, inputDesc);
|
ExecAssignProjectionInfo(planstate, inputDesc);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
|
tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc)
|
||||||
|
|
|
@ -2219,7 +2219,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result type, slot and projection.
|
* Initialize result type, slot and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &aggstate->ss.ps);
|
ExecInitResultTupleSlotTL(&aggstate->ss.ps);
|
||||||
ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
|
ExecAssignProjectionInfo(&aggstate->ss.ps, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -196,7 +196,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result tuple type and slot.
|
* Initialize result tuple type and slot.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &appendstate->ps);
|
ExecInitResultTupleSlotTL(&appendstate->ps);
|
||||||
|
|
||||||
appendplanstates = (PlanState **) palloc(nplans *
|
appendplanstates = (PlanState **) palloc(nplans *
|
||||||
sizeof(PlanState *));
|
sizeof(PlanState *));
|
||||||
|
|
|
@ -800,6 +800,7 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
|
||||||
/*
|
/*
|
||||||
* clear out tuple table slots
|
* clear out tuple table slots
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
@ -916,9 +917,9 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -263,9 +263,9 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags)
|
||||||
ExecGetResultType(scanstate->cteplanstate));
|
ExecGetResultType(scanstate->cteplanstate));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -294,6 +294,7 @@ ExecEndCteScan(CteScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
@ -318,6 +319,7 @@ ExecReScanCteScan(CteScanState *node)
|
||||||
{
|
{
|
||||||
Tuplestorestate *tuplestorestate = node->leader->cte_table;
|
Tuplestorestate *tuplestorestate = node->leader->cte_table;
|
||||||
|
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
|
|
||||||
ExecScanReScan(&node->ss);
|
ExecScanReScan(&node->ss);
|
||||||
|
|
|
@ -87,7 +87,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &css->ss.ps);
|
ExecInitResultTupleSlotTL(&css->ss.ps);
|
||||||
ExecAssignScanProjectionInfoWithVarno(&css->ss, tlistvarno);
|
ExecAssignScanProjectionInfoWithVarno(&css->ss, tlistvarno);
|
||||||
|
|
||||||
/* initialize child expressions */
|
/* initialize child expressions */
|
||||||
|
|
|
@ -198,7 +198,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfoWithVarno(&scanstate->ss, tlistvarno);
|
ExecAssignScanProjectionInfoWithVarno(&scanstate->ss, tlistvarno);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -256,6 +256,7 @@ ExecEndForeignScan(ForeignScanState *node)
|
||||||
ExecFreeExprContext(&node->ss.ps);
|
ExecFreeExprContext(&node->ss.ps);
|
||||||
|
|
||||||
/* clean out the tuple table */
|
/* clean out the tuple table */
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
}
|
}
|
||||||
|
|
|
@ -487,7 +487,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -529,6 +529,7 @@ ExecEndFunctionScan(FunctionScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
@ -563,6 +564,7 @@ ExecReScanFunctionScan(FunctionScanState *node)
|
||||||
int i;
|
int i;
|
||||||
Bitmapset *chgparam = node->ss.ps.chgParam;
|
Bitmapset *chgparam = node->ss.ps.chgParam;
|
||||||
|
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
for (i = 0; i < node->nfuncs; i++)
|
for (i = 0; i < node->nfuncs; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,9 +92,9 @@ ExecInitGather(Gather *node, EState *estate, int eflags)
|
||||||
tupDesc = ExecGetResultType(outerPlanState(gatherstate));
|
tupDesc = ExecGetResultType(outerPlanState(gatherstate));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &gatherstate->ps);
|
ExecInitResultTypeTL(&gatherstate->ps);
|
||||||
ExecConditionalAssignProjectionInfo(&gatherstate->ps, tupDesc, OUTER_VAR);
|
ExecConditionalAssignProjectionInfo(&gatherstate->ps, tupDesc, OUTER_VAR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -231,6 +231,7 @@ ExecEndGather(GatherState *node)
|
||||||
ExecEndNode(outerPlanState(node)); /* let children clean up first */
|
ExecEndNode(outerPlanState(node)); /* let children clean up first */
|
||||||
ExecShutdownGather(node);
|
ExecShutdownGather(node);
|
||||||
ExecFreeExprContext(&node->ps);
|
ExecFreeExprContext(&node->ps);
|
||||||
|
if (node->ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ps.ps_ResultTupleSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,9 +117,9 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
|
||||||
gm_state->tupDesc = tupDesc;
|
gm_state->tupDesc = tupDesc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &gm_state->ps);
|
ExecInitResultTypeTL(&gm_state->ps);
|
||||||
ExecConditionalAssignProjectionInfo(&gm_state->ps, tupDesc, OUTER_VAR);
|
ExecConditionalAssignProjectionInfo(&gm_state->ps, tupDesc, OUTER_VAR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -272,6 +272,7 @@ ExecEndGatherMerge(GatherMergeState *node)
|
||||||
ExecEndNode(outerPlanState(node)); /* let children clean up first */
|
ExecEndNode(outerPlanState(node)); /* let children clean up first */
|
||||||
ExecShutdownGatherMerge(node);
|
ExecShutdownGatherMerge(node);
|
||||||
ExecFreeExprContext(&node->ps);
|
ExecFreeExprContext(&node->ps);
|
||||||
|
if (node->ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ps.ps_ResultTupleSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ ExecInitGroup(Group *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &grpstate->ss.ps);
|
ExecInitResultTupleSlotTL(&grpstate->ss.ps);
|
||||||
ExecAssignProjectionInfo(&grpstate->ss.ps, NULL);
|
ExecAssignProjectionInfo(&grpstate->ss.ps, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -382,7 +382,7 @@ ExecInitHash(Hash *node, EState *estate, int eflags)
|
||||||
* initialize our result slot and type. No need to build projection
|
* initialize our result slot and type. No need to build projection
|
||||||
* because this node doesn't do projections.
|
* because this node doesn't do projections.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &hashstate->ps);
|
ExecInitResultTupleSlotTL(&hashstate->ps);
|
||||||
hashstate->ps.ps_ProjInfo = NULL;
|
hashstate->ps.ps_ProjInfo = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -644,7 +644,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &hjstate->js.ps);
|
ExecInitResultTupleSlotTL(&hjstate->js.ps);
|
||||||
ExecAssignProjectionInfo(&hjstate->js.ps, NULL);
|
ExecAssignProjectionInfo(&hjstate->js.ps, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -399,6 +399,7 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node)
|
||||||
/*
|
/*
|
||||||
* clear out tuple table slots
|
* clear out tuple table slots
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
@ -529,11 +530,10 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
|
||||||
ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc);
|
ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection info. The node's
|
* Initialize result type and projection info. The node's targetlist will
|
||||||
* targetlist will contain Vars with varno = INDEX_VAR, referencing the
|
* contain Vars with varno = INDEX_VAR, referencing the scan tuple.
|
||||||
* scan tuple.
|
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &indexstate->ss.ps);
|
ExecInitResultTypeTL(&indexstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfoWithVarno(&indexstate->ss, INDEX_VAR);
|
ExecAssignScanProjectionInfoWithVarno(&indexstate->ss, INDEX_VAR);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -822,6 +822,7 @@ ExecEndIndexScan(IndexScanState *node)
|
||||||
/*
|
/*
|
||||||
* clear out tuple table slots
|
* clear out tuple table slots
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
@ -947,9 +948,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
|
||||||
RelationGetDescr(currentRelation));
|
RelationGetDescr(currentRelation));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &indexstate->ss.ps);
|
ExecInitResultTypeTL(&indexstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&indexstate->ss);
|
ExecAssignScanProjectionInfo(&indexstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -376,10 +376,9 @@ ExecInitLimit(Limit *node, EState *estate, int eflags)
|
||||||
(PlanState *) limitstate);
|
(PlanState *) limitstate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot and type. (XXX not actually used, but upper
|
* Initialize result type.
|
||||||
* nodes access it to get this node's result tupledesc...)
|
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &limitstate->ps);
|
ExecInitResultTypeTL(&limitstate->ps);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* limit nodes do no projections, so initialize projection info for this
|
* limit nodes do no projections, so initialize projection info for this
|
||||||
|
|
|
@ -381,10 +381,9 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tuple table initialization (XXX not actually used, but upper nodes
|
* Initialize result type.
|
||||||
* access it to get this node's result tupledesc...)
|
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &lrstate->ps);
|
ExecInitResultTypeTL(&lrstate->ps);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* then initialize outer plan
|
* then initialize outer plan
|
||||||
|
|
|
@ -223,7 +223,7 @@ ExecInitMaterial(Material *node, EState *estate, int eflags)
|
||||||
*
|
*
|
||||||
* material nodes only return tuples from their materialized relation.
|
* material nodes only return tuples from their materialized relation.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &matstate->ss.ps);
|
ExecInitResultTupleSlotTL(&matstate->ss.ps);
|
||||||
matstate->ss.ps.ps_ProjInfo = NULL;
|
matstate->ss.ps.ps_ProjInfo = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -165,9 +165,9 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
|
||||||
* Miscellaneous initialization
|
* Miscellaneous initialization
|
||||||
*
|
*
|
||||||
* MergeAppend nodes do have Result slots, which hold pointers to tuples,
|
* MergeAppend nodes do have Result slots, which hold pointers to tuples,
|
||||||
* so we have to initialize them.
|
* so we have to initialize them. FIXME
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &mergestate->ps);
|
ExecInitResultTupleSlotTL(&mergestate->ps);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call ExecInitNode on each of the valid plans to be executed and save
|
* call ExecInitNode on each of the valid plans to be executed and save
|
||||||
|
|
|
@ -1512,7 +1512,7 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &mergestate->js.ps);
|
ExecInitResultTupleSlotTL(&mergestate->js.ps);
|
||||||
ExecAssignProjectionInfo(&mergestate->js.ps, NULL);
|
ExecAssignProjectionInfo(&mergestate->js.ps, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2407,7 +2407,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||||
mtstate->ps.plan->targetlist = (List *) linitial(node->returningLists);
|
mtstate->ps.plan->targetlist = (List *) linitial(node->returningLists);
|
||||||
|
|
||||||
/* Set up a slot for the output of the RETURNING projection(s) */
|
/* Set up a slot for the output of the RETURNING projection(s) */
|
||||||
ExecInitResultTupleSlotTL(estate, &mtstate->ps);
|
ExecInitResultTupleSlotTL(&mtstate->ps);
|
||||||
slot = mtstate->ps.ps_ResultTupleSlot;
|
slot = mtstate->ps.ps_ResultTupleSlot;
|
||||||
|
|
||||||
/* Need an econtext too */
|
/* Need an econtext too */
|
||||||
|
@ -2437,7 +2437,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
||||||
* expects one (maybe should change that?).
|
* expects one (maybe should change that?).
|
||||||
*/
|
*/
|
||||||
mtstate->ps.plan->targetlist = NIL;
|
mtstate->ps.plan->targetlist = NIL;
|
||||||
ExecInitResultTupleSlotTL(estate, &mtstate->ps);
|
ExecInitResultTypeTL(&mtstate->ps);
|
||||||
|
|
||||||
mtstate->ps.ps_ExprContext = NULL;
|
mtstate->ps.ps_ExprContext = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2716,6 +2716,7 @@ ExecEndModifyTable(ModifyTableState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ps.ps_ResultTupleSlot);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -135,23 +135,22 @@ ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflag
|
||||||
ExecAssignExprContext(estate, &scanstate->ss.ps);
|
ExecAssignExprContext(estate, &scanstate->ss.ps);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tuple table and result type initialization. The scan tuple type is
|
* The scan tuple type is specified for the tuplestore.
|
||||||
* specified for the tuplestore.
|
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
|
||||||
ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc);
|
ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize result type and projection.
|
||||||
|
*/
|
||||||
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize child expressions
|
* initialize child expressions
|
||||||
*/
|
*/
|
||||||
scanstate->ss.ps.qual =
|
scanstate->ss.ps.qual =
|
||||||
ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
|
ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate);
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize projection.
|
|
||||||
*/
|
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
|
||||||
|
|
||||||
return scanstate;
|
return scanstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +171,7 @@ ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,7 @@ ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node)
|
||||||
{
|
{
|
||||||
Tuplestorestate *tuplestorestate = node->relation;
|
Tuplestorestate *tuplestorestate = node->relation;
|
||||||
|
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
|
|
||||||
ExecScanReScan(&node->ss);
|
ExecScanReScan(&node->ss);
|
||||||
|
|
|
@ -304,7 +304,7 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &nlstate->js.ps);
|
ExecInitResultTupleSlotTL(&nlstate->js.ps);
|
||||||
ExecAssignProjectionInfo(&nlstate->js.ps, NULL);
|
ExecAssignProjectionInfo(&nlstate->js.ps, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -256,7 +256,7 @@ ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* tuple table and result type initialization
|
* tuple table and result type initialization
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &state->ps);
|
ExecInitResultTupleSlotTL(&state->ps);
|
||||||
|
|
||||||
/* Create workspace for per-tlist-entry expr state & SRF-is-done state */
|
/* Create workspace for per-tlist-entry expr state & SRF-is-done state */
|
||||||
state->nelems = list_length(node->plan.targetlist);
|
state->nelems = list_length(node->plan.targetlist);
|
||||||
|
|
|
@ -229,7 +229,7 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
|
||||||
* RecursiveUnion nodes still have Result slots, which hold pointers to
|
* RecursiveUnion nodes still have Result slots, which hold pointers to
|
||||||
* tuples, so we have to initialize them.
|
* tuples, so we have to initialize them.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &rustate->ps);
|
ExecInitResultTypeTL(&rustate->ps);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result tuple type. (Note: we have to set up the result type
|
* Initialize result tuple type. (Note: we have to set up the result type
|
||||||
|
@ -279,11 +279,6 @@ ExecEndRecursiveUnion(RecursiveUnionState *node)
|
||||||
if (node->tableContext)
|
if (node->tableContext)
|
||||||
MemoryContextDelete(node->tableContext);
|
MemoryContextDelete(node->tableContext);
|
||||||
|
|
||||||
/*
|
|
||||||
* clean out the upper tuple table
|
|
||||||
*/
|
|
||||||
ExecClearTuple(node->ps.ps_ResultTupleSlot);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* close down subplans
|
* close down subplans
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -217,7 +217,7 @@ ExecInitResult(Result *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &resstate->ps);
|
ExecInitResultTupleSlotTL(&resstate->ps);
|
||||||
ExecAssignProjectionInfo(&resstate->ps, NULL);
|
ExecAssignProjectionInfo(&resstate->ps, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -149,10 +149,9 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
|
||||||
RelationGetDescr(scanstate->ss.ss_currentRelation));
|
RelationGetDescr(scanstate->ss.ss_currentRelation));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection. tuple table and result
|
* Initialize result type and projection.
|
||||||
* tuple initialization
|
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -211,6 +210,7 @@ ExecEndSampleScan(SampleScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
|
|
@ -175,9 +175,9 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
|
||||||
RelationGetDescr(scanstate->ss.ss_currentRelation));
|
RelationGetDescr(scanstate->ss.ss_currentRelation));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -213,6 +213,7 @@ ExecEndSeqScan(SeqScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
|
|
@ -532,7 +532,7 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags)
|
||||||
* Initialize result slot and type. Setop nodes do no projections, so
|
* Initialize result slot and type. Setop nodes do no projections, so
|
||||||
* initialize projection info for this node appropriately.
|
* initialize projection info for this node appropriately.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &setopstate->ps);
|
ExecInitResultTupleSlotTL(&setopstate->ps);
|
||||||
setopstate->ps.ps_ProjInfo = NULL;
|
setopstate->ps.ps_ProjInfo = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -217,7 +217,7 @@ ExecInitSort(Sort *node, EState *estate, int eflags)
|
||||||
* Initialize return slot and type. No need to initialize projection info
|
* Initialize return slot and type. No need to initialize projection info
|
||||||
* because this node doesn't do projections.
|
* because this node doesn't do projections.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &sortstate->ss.ps);
|
ExecInitResultTupleSlotTL(&sortstate->ss.ps);
|
||||||
sortstate->ss.ps.ps_ProjInfo = NULL;
|
sortstate->ss.ps.ps_ProjInfo = NULL;
|
||||||
|
|
||||||
SO1_printf("ExecInitSort: %s\n",
|
SO1_printf("ExecInitSort: %s\n",
|
||||||
|
|
|
@ -126,15 +126,15 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
|
||||||
subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
|
subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize scan slot and type (needed by ExecInitResultTupleSlotTL)
|
* Initialize scan slot and type (needed by ExecAssignScanProjectionInfo)
|
||||||
*/
|
*/
|
||||||
ExecInitScanTupleSlot(estate, &subquerystate->ss,
|
ExecInitScanTupleSlot(estate, &subquerystate->ss,
|
||||||
ExecGetResultType(subquerystate->subplan));
|
ExecGetResultType(subquerystate->subplan));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &subquerystate->ss.ps);
|
ExecInitResultTypeTL(&subquerystate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&subquerystate->ss);
|
ExecAssignScanProjectionInfo(&subquerystate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -163,6 +163,7 @@ ExecEndSubqueryScan(SubqueryScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the upper tuple table
|
* clean out the upper tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
|
|
@ -150,9 +150,9 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags)
|
||||||
ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc);
|
ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -221,6 +221,7 @@ ExecEndTableFuncScan(TableFuncScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
|
|
||||||
|
@ -243,6 +244,7 @@ ExecReScanTableFuncScan(TableFuncScanState *node)
|
||||||
{
|
{
|
||||||
Bitmapset *chgparam = node->ss.ps.chgParam;
|
Bitmapset *chgparam = node->ss.ps.chgParam;
|
||||||
|
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecScanReScan(&node->ss);
|
ExecScanReScan(&node->ss);
|
||||||
|
|
||||||
|
|
|
@ -487,6 +487,7 @@ ExecEndTidScan(TidScanState *node)
|
||||||
/*
|
/*
|
||||||
* clear out tuple table slots
|
* clear out tuple table slots
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
}
|
}
|
||||||
|
@ -545,9 +546,9 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags)
|
||||||
RelationGetDescr(currentRelation));
|
RelationGetDescr(currentRelation));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &tidstate->ss.ps);
|
ExecInitResultTypeTL(&tidstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&tidstate->ss);
|
ExecAssignScanProjectionInfo(&tidstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -141,7 +141,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags)
|
||||||
* Initialize result slot and type. Unique nodes do no projections, so
|
* Initialize result slot and type. Unique nodes do no projections, so
|
||||||
* initialize projection info for this node appropriately.
|
* initialize projection info for this node appropriately.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &uniquestate->ps);
|
ExecInitResultTupleSlotTL(&uniquestate->ps);
|
||||||
uniquestate->ps.ps_ProjInfo = NULL;
|
uniquestate->ps.ps_ProjInfo = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -264,9 +264,9 @@ ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
|
||||||
ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc);
|
ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecAssignScanProjectionInfo(&scanstate->ss);
|
ExecAssignScanProjectionInfo(&scanstate->ss);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -312,6 +312,7 @@ ExecEndValuesScan(ValuesScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
}
|
}
|
||||||
|
@ -325,6 +326,7 @@ ExecEndValuesScan(ValuesScanState *node)
|
||||||
void
|
void
|
||||||
ExecReScanValuesScan(ValuesScanState *node)
|
ExecReScanValuesScan(ValuesScanState *node)
|
||||||
{
|
{
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
|
|
||||||
ExecScanReScan(&node->ss);
|
ExecScanReScan(&node->ss);
|
||||||
|
|
|
@ -2349,7 +2349,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* Initialize result slot, type and projection.
|
* Initialize result slot, type and projection.
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &winstate->ss.ps);
|
ExecInitResultTupleSlotTL(&winstate->ss.ps);
|
||||||
ExecAssignProjectionInfo(&winstate->ss.ps, NULL);
|
ExecAssignProjectionInfo(&winstate->ss.ps, NULL);
|
||||||
|
|
||||||
/* Set up data for comparing tuples */
|
/* Set up data for comparing tuples */
|
||||||
|
|
|
@ -159,7 +159,7 @@ ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
|
||||||
/*
|
/*
|
||||||
* tuple table initialization
|
* tuple table initialization
|
||||||
*/
|
*/
|
||||||
ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps);
|
ExecInitResultTypeTL(&scanstate->ss.ps);
|
||||||
ExecInitScanTupleSlot(estate, &scanstate->ss, NULL);
|
ExecInitScanTupleSlot(estate, &scanstate->ss, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -193,6 +193,7 @@ ExecEndWorkTableScan(WorkTableScanState *node)
|
||||||
/*
|
/*
|
||||||
* clean out the tuple table
|
* clean out the tuple table
|
||||||
*/
|
*/
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
ExecClearTuple(node->ss.ss_ScanTupleSlot);
|
||||||
}
|
}
|
||||||
|
@ -206,6 +207,7 @@ ExecEndWorkTableScan(WorkTableScanState *node)
|
||||||
void
|
void
|
||||||
ExecReScanWorkTableScan(WorkTableScanState *node)
|
ExecReScanWorkTableScan(WorkTableScanState *node)
|
||||||
{
|
{
|
||||||
|
if (node->ss.ps.ps_ResultTupleSlot)
|
||||||
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
|
||||||
|
|
||||||
ExecScanReScan(&node->ss);
|
ExecScanReScan(&node->ss);
|
||||||
|
|
|
@ -429,7 +429,9 @@ extern void ExecScanReScan(ScanState *node);
|
||||||
/*
|
/*
|
||||||
* prototypes from functions in execTuples.c
|
* prototypes from functions in execTuples.c
|
||||||
*/
|
*/
|
||||||
extern void ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate);
|
extern void ExecInitResultTypeTL(PlanState *planstate);
|
||||||
|
extern void ExecInitResultSlot(PlanState *planstate);
|
||||||
|
extern void ExecInitResultTupleSlotTL(PlanState *planstate);
|
||||||
extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupleDesc);
|
extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupleDesc);
|
||||||
extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate,
|
extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate,
|
||||||
TupleDesc tupleDesc);
|
TupleDesc tupleDesc);
|
||||||
|
|
|
@ -966,6 +966,7 @@ typedef struct PlanState
|
||||||
/*
|
/*
|
||||||
* Other run-time state needed by most if not all node types.
|
* Other run-time state needed by most if not all node types.
|
||||||
*/
|
*/
|
||||||
|
TupleDesc ps_ResultTupleDesc; /* node's return type */
|
||||||
TupleTableSlot *ps_ResultTupleSlot; /* slot for my result tuples */
|
TupleTableSlot *ps_ResultTupleSlot; /* slot for my result tuples */
|
||||||
ExprContext *ps_ExprContext; /* node's expression-evaluation context */
|
ExprContext *ps_ExprContext; /* node's expression-evaluation context */
|
||||||
ProjectionInfo *ps_ProjInfo; /* info for doing tuple projection */
|
ProjectionInfo *ps_ProjInfo; /* info for doing tuple projection */
|
||||||
|
|
Loading…
Reference in New Issue