diff options
Diffstat (limited to 'src/backend/executor')
40 files changed, 278 insertions, 261 deletions
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 20fd9f822ed..396920c0a23 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -17,15 +17,10 @@ *------------------------------------------------------------------------- */ /* - * INTERFACE ROUTINES - * ExecInitNode - initialize a plan node and its subplans - * ExecProcNode - get a tuple by executing the plan node - * ExecEndNode - shut down a plan node and its subplans - * * NOTES * This used to be three files. It is now all combined into - * one file so that it is easier to keep ExecInitNode, ExecProcNode, - * and ExecEndNode in sync when new nodes are added. + * one file so that it is easier to keep the dispatch routines + * in sync when new nodes are added. * * EXAMPLE * Suppose we want the age of the manager of the shoe department and @@ -122,6 +117,10 @@ #include "miscadmin.h" +static TupleTableSlot *ExecProcNodeFirst(PlanState *node); +static TupleTableSlot *ExecProcNodeInstr(PlanState *node); + + /* ------------------------------------------------------------------------ * ExecInitNode * @@ -149,6 +148,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags) if (node == NULL) return NULL; + /* + * Make sure there's enough stack available. Need to check here, in + * addition to ExecProcNode() (via ExecProcNodeFirst()), to ensure the + * stack isn't overrun while initializing the node tree. + */ + check_stack_depth(); + switch (nodeTag(node)) { /* @@ -365,6 +371,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags) } /* + * Add a wrapper around the ExecProcNode callback that checks stack depth + * during the first execution. + */ + result->ExecProcNodeReal = result->ExecProcNode; + result->ExecProcNode = ExecProcNodeFirst; + + /* * Initialize any initPlans present in this node. The planner put them in * a separate list for us. */ @@ -388,195 +401,51 @@ ExecInitNode(Plan *node, EState *estate, int eflags) } -/* ---------------------------------------------------------------- - * ExecProcNode - * - * Execute the given node to return a(nother) tuple. - * ---------------------------------------------------------------- +/* + * ExecProcNode wrapper that performs some one-time checks, before calling + * the relevant node method (possibly via an instrumentation wrapper). */ -TupleTableSlot * -ExecProcNode(PlanState *node) +static TupleTableSlot * +ExecProcNodeFirst(PlanState *node) { - TupleTableSlot *result; - - if (node->chgParam != NULL) /* something changed */ - ExecReScan(node); /* let ReScan handle this */ + /* + * Perform stack depth check during the first execution of the node. We + * only do so the first time round because it turns out to not be cheap on + * some common architectures (eg. x86). This relies on the assumption that + * ExecProcNode calls for a given plan node will always be made at roughly + * the same stack depth. + */ + check_stack_depth(); + /* + * If instrumentation is required, change the wrapper to one that just + * does instrumentation. Otherwise we can dispense with all wrappers and + * have ExecProcNode() directly call the relevant function from now on. + */ if (node->instrument) - InstrStartNode(node->instrument); - - switch (nodeTag(node)) - { - /* - * control nodes - */ - case T_ResultState: - result = ExecResult((ResultState *) node); - break; - - case T_ProjectSetState: - result = ExecProjectSet((ProjectSetState *) node); - break; - - case T_ModifyTableState: - result = ExecModifyTable((ModifyTableState *) node); - break; - - case T_AppendState: - result = ExecAppend((AppendState *) node); - break; - - case T_MergeAppendState: - result = ExecMergeAppend((MergeAppendState *) node); - break; - - case T_RecursiveUnionState: - result = ExecRecursiveUnion((RecursiveUnionState *) node); - break; - - /* BitmapAndState does not yield tuples */ - - /* BitmapOrState does not yield tuples */ - - /* - * scan nodes - */ - case T_SeqScanState: - result = ExecSeqScan((SeqScanState *) node); - break; - - case T_SampleScanState: - result = ExecSampleScan((SampleScanState *) node); - break; - - case T_IndexScanState: - result = ExecIndexScan((IndexScanState *) node); - break; - - case T_IndexOnlyScanState: - result = ExecIndexOnlyScan((IndexOnlyScanState *) node); - break; - - /* BitmapIndexScanState does not yield tuples */ - - case T_BitmapHeapScanState: - result = ExecBitmapHeapScan((BitmapHeapScanState *) node); - break; - - case T_TidScanState: - result = ExecTidScan((TidScanState *) node); - break; - - case T_SubqueryScanState: - result = ExecSubqueryScan((SubqueryScanState *) node); - break; - - case T_FunctionScanState: - result = ExecFunctionScan((FunctionScanState *) node); - break; - - case T_TableFuncScanState: - result = ExecTableFuncScan((TableFuncScanState *) node); - break; - - case T_ValuesScanState: - result = ExecValuesScan((ValuesScanState *) node); - break; - - case T_CteScanState: - result = ExecCteScan((CteScanState *) node); - break; - - case T_NamedTuplestoreScanState: - result = ExecNamedTuplestoreScan((NamedTuplestoreScanState *) node); - break; - - case T_WorkTableScanState: - result = ExecWorkTableScan((WorkTableScanState *) node); - break; - - case T_ForeignScanState: - result = ExecForeignScan((ForeignScanState *) node); - break; - - case T_CustomScanState: - result = ExecCustomScan((CustomScanState *) node); - break; - - /* - * join nodes - */ - case T_NestLoopState: - result = ExecNestLoop((NestLoopState *) node); - break; - - case T_MergeJoinState: - result = ExecMergeJoin((MergeJoinState *) node); - break; - - case T_HashJoinState: - result = ExecHashJoin((HashJoinState *) node); - break; - - /* - * materialization nodes - */ - case T_MaterialState: - result = ExecMaterial((MaterialState *) node); - break; - - case T_SortState: - result = ExecSort((SortState *) node); - break; - - case T_GroupState: - result = ExecGroup((GroupState *) node); - break; + node->ExecProcNode = ExecProcNodeInstr; + else + node->ExecProcNode = node->ExecProcNodeReal; - case T_AggState: - result = ExecAgg((AggState *) node); - break; - - case T_WindowAggState: - result = ExecWindowAgg((WindowAggState *) node); - break; - - case T_UniqueState: - result = ExecUnique((UniqueState *) node); - break; - - case T_GatherState: - result = ExecGather((GatherState *) node); - break; - - case T_GatherMergeState: - result = ExecGatherMerge((GatherMergeState *) node); - break; - - case T_HashState: - result = ExecHash((HashState *) node); - break; + return node->ExecProcNode(node); +} - case T_SetOpState: - result = ExecSetOp((SetOpState *) node); - break; - case T_LockRowsState: - result = ExecLockRows((LockRowsState *) node); - break; +/* + * ExecProcNode wrapper that performs instrumentation calls. By keeping + * this a separate function, we avoid overhead in the normal case where + * no instrumentation is wanted. + */ +static TupleTableSlot * +ExecProcNodeInstr(PlanState *node) +{ + TupleTableSlot *result; - case T_LimitState: - result = ExecLimit((LimitState *) node); - break; + InstrStartNode(node->instrument); - default: - elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); - result = NULL; - break; - } + result = node->ExecProcNodeReal(node); - if (node->instrument) - InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0); + InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0); return result; } @@ -600,6 +469,8 @@ MultiExecProcNode(PlanState *node) { Node *result; + check_stack_depth(); + CHECK_FOR_INTERRUPTS(); if (node->chgParam != NULL) /* something changed */ @@ -657,6 +528,13 @@ ExecEndNode(PlanState *node) if (node == NULL) return; + /* + * Make sure there's enough stack available. Need to check here, in + * addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not + * guaranteed that ExecProcNode() is reached for all nodes. + */ + check_stack_depth(); + if (node->chgParam != NULL) { bms_free(node->chgParam); @@ -855,6 +733,8 @@ ExecShutdownNode(PlanState *node) if (node == NULL) return false; + check_stack_depth(); + planstate_tree_walker(node, ExecShutdownNode, NULL); switch (nodeTag(node)) diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 377916dae75..6a26773a49f 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -2099,9 +2099,10 @@ lookup_hash_entries(AggState *aggstate) * stored in the expression context to be used when ExecProject evaluates * the result tuple. */ -TupleTableSlot * -ExecAgg(AggState *node) +static TupleTableSlot * +ExecAgg(PlanState *pstate) { + AggState *node = castNode(AggState, pstate); TupleTableSlot *result = NULL; CHECK_FOR_INTERRUPTS(); @@ -2695,6 +2696,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) aggstate = makeNode(AggState); aggstate->ss.ps.plan = (Plan *) node; aggstate->ss.ps.state = estate; + aggstate->ss.ps.ExecProcNode = ExecAgg; aggstate->aggs = NIL; aggstate->numaggs = 0; diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index 58045e05e5d..bed9bb87138 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -61,6 +61,7 @@ #include "executor/nodeAppend.h" #include "miscadmin.h" +static TupleTableSlot *ExecAppend(PlanState *pstate); static bool exec_append_initialize_next(AppendState *appendstate); @@ -147,6 +148,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags) */ appendstate->ps.plan = (Plan *) node; appendstate->ps.state = estate; + appendstate->ps.ExecProcNode = ExecAppend; appendstate->appendplans = appendplanstates; appendstate->as_nplans = nplans; @@ -197,9 +199,11 @@ ExecInitAppend(Append *node, EState *estate, int eflags) * Handles iteration over multiple subplans. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecAppend(AppendState *node) +static TupleTableSlot * +ExecAppend(PlanState *pstate) { + AppendState *node = castNode(AppendState, pstate); + for (;;) { PlanState *subnode; diff --git a/src/backend/executor/nodeBitmapAnd.c b/src/backend/executor/nodeBitmapAnd.c index e4eb028ff9c..1c5c312c954 100644 --- a/src/backend/executor/nodeBitmapAnd.c +++ b/src/backend/executor/nodeBitmapAnd.c @@ -33,6 +33,19 @@ /* ---------------------------------------------------------------- + * ExecBitmapAnd + * + * stub for pro forma compliance + * ---------------------------------------------------------------- + */ +static TupleTableSlot * +ExecBitmapAnd(PlanState *pstate) +{ + elog(ERROR, "BitmapAnd node does not support ExecProcNode call convention"); + return NULL; +} + +/* ---------------------------------------------------------------- * ExecInitBitmapAnd * * Begin all of the subscans of the BitmapAnd node. @@ -63,6 +76,7 @@ ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags) */ bitmapandstate->ps.plan = (Plan *) node; bitmapandstate->ps.state = estate; + bitmapandstate->ps.ExecProcNode = ExecBitmapAnd; bitmapandstate->bitmapplans = bitmapplanstates; bitmapandstate->nplans = nplans; diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index cf109d5049f..79f534e4e92 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -665,9 +665,11 @@ BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot) * ExecBitmapHeapScan(node) * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecBitmapHeapScan(BitmapHeapScanState *node) +static TupleTableSlot * +ExecBitmapHeapScan(PlanState *pstate) { + BitmapHeapScanState *node = castNode(BitmapHeapScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) BitmapHeapNext, (ExecScanRecheckMtd) BitmapHeapRecheck); @@ -815,6 +817,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) scanstate = makeNode(BitmapHeapScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecBitmapHeapScan; scanstate->tbm = NULL; scanstate->tbmiterator = NULL; diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c index 2411a2e5c1a..6feb70f4ae3 100644 --- a/src/backend/executor/nodeBitmapIndexscan.c +++ b/src/backend/executor/nodeBitmapIndexscan.c @@ -29,6 +29,19 @@ /* ---------------------------------------------------------------- + * ExecBitmapIndexScan + * + * stub for pro forma compliance + * ---------------------------------------------------------------- + */ +static TupleTableSlot * +ExecBitmapIndexScan(PlanState *pstate) +{ + elog(ERROR, "BitmapIndexScan node does not support ExecProcNode call convention"); + return NULL; +} + +/* ---------------------------------------------------------------- * MultiExecBitmapIndexScan(node) * ---------------------------------------------------------------- */ @@ -208,6 +221,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) indexstate = makeNode(BitmapIndexScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; + indexstate->ss.ps.ExecProcNode = ExecBitmapIndexScan; /* normally we don't make the result bitmap till runtime */ indexstate->biss_result = NULL; diff --git a/src/backend/executor/nodeBitmapOr.c b/src/backend/executor/nodeBitmapOr.c index 4f0ddc6dffd..66a7a89a8b7 100644 --- a/src/backend/executor/nodeBitmapOr.c +++ b/src/backend/executor/nodeBitmapOr.c @@ -34,6 +34,19 @@ /* ---------------------------------------------------------------- + * ExecBitmapOr + * + * stub for pro forma compliance + * ---------------------------------------------------------------- + */ +static TupleTableSlot * +ExecBitmapOr(PlanState *pstate) +{ + elog(ERROR, "BitmapOr node does not support ExecProcNode call convention"); + return NULL; +} + +/* ---------------------------------------------------------------- * ExecInitBitmapOr * * Begin all of the subscans of the BitmapOr node. @@ -64,6 +77,7 @@ ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags) */ bitmaporstate->ps.plan = (Plan *) node; bitmaporstate->ps.state = estate; + bitmaporstate->ps.ExecProcNode = ExecBitmapOr; bitmaporstate->bitmapplans = bitmapplanstates; bitmaporstate->nplans = nplans; diff --git a/src/backend/executor/nodeCtescan.c b/src/backend/executor/nodeCtescan.c index bed7949c5a0..79676ca9787 100644 --- a/src/backend/executor/nodeCtescan.c +++ b/src/backend/executor/nodeCtescan.c @@ -149,9 +149,11 @@ CteScanRecheck(CteScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecCteScan(CteScanState *node) +static TupleTableSlot * +ExecCteScan(PlanState *pstate) { + CteScanState *node = castNode(CteScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) CteScanNext, (ExecScanRecheckMtd) CteScanRecheck); @@ -191,6 +193,7 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags) scanstate = makeNode(CteScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecCteScan; scanstate->eflags = eflags; scanstate->cte_table = NULL; scanstate->eof_cte = false; diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c index fc15974a2d0..fb7645b1f46 100644 --- a/src/backend/executor/nodeCustom.c +++ b/src/backend/executor/nodeCustom.c @@ -21,6 +21,10 @@ #include "utils/memutils.h" #include "utils/rel.h" + +static TupleTableSlot *ExecCustomScan(PlanState *pstate); + + CustomScanState * ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) { @@ -45,6 +49,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) /* fill up fields of ScanState */ css->ss.ps.plan = &cscan->scan.plan; css->ss.ps.state = estate; + css->ss.ps.ExecProcNode = ExecCustomScan; /* create expression context for node */ ExecAssignExprContext(estate, &css->ss.ps); @@ -102,9 +107,11 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) return css; } -TupleTableSlot * -ExecCustomScan(CustomScanState *node) +static TupleTableSlot * +ExecCustomScan(PlanState *pstate) { + CustomScanState *node = castNode(CustomScanState, pstate); + CHECK_FOR_INTERRUPTS(); Assert(node->methods->ExecCustomScan != NULL); diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index 9cde112554b..140e82ef5e4 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -113,10 +113,12 @@ ForeignRecheck(ForeignScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecForeignScan(ForeignScanState *node) +static TupleTableSlot * +ExecForeignScan(PlanState *pstate) { - return ExecScan((ScanState *) node, + ForeignScanState *node = castNode(ForeignScanState, pstate); + + return ExecScan(&node->ss, (ExecScanAccessMtd) ForeignNext, (ExecScanRecheckMtd) ForeignRecheck); } @@ -144,6 +146,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) scanstate = makeNode(ForeignScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecForeignScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c index 3217d641d76..9f87a7e5cdd 100644 --- a/src/backend/executor/nodeFunctionscan.c +++ b/src/backend/executor/nodeFunctionscan.c @@ -262,9 +262,11 @@ FunctionRecheck(FunctionScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecFunctionScan(FunctionScanState *node) +static TupleTableSlot * +ExecFunctionScan(PlanState *pstate) { + FunctionScanState *node = castNode(FunctionScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) FunctionNext, (ExecScanRecheckMtd) FunctionRecheck); @@ -299,6 +301,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags) scanstate = makeNode(FunctionScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecFunctionScan; scanstate->eflags = eflags; /* diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c index 5dbe19c056d..e8d94ee6f38 100644 --- a/src/backend/executor/nodeGather.c +++ b/src/backend/executor/nodeGather.c @@ -43,6 +43,7 @@ #include "utils/rel.h" +static TupleTableSlot *ExecGather(PlanState *pstate); static TupleTableSlot *gather_getnext(GatherState *gatherstate); static HeapTuple gather_readnext(GatherState *gatherstate); static void ExecShutdownGatherWorkers(GatherState *node); @@ -69,6 +70,7 @@ ExecInitGather(Gather *node, EState *estate, int eflags) gatherstate = makeNode(GatherState); gatherstate->ps.plan = (Plan *) node; gatherstate->ps.state = estate; + gatherstate->ps.ExecProcNode = ExecGather; gatherstate->need_to_scan_locally = !node->single_copy; /* @@ -120,9 +122,10 @@ ExecInitGather(Gather *node, EState *estate, int eflags) * the next qualifying tuple. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecGather(GatherState *node) +static TupleTableSlot * +ExecGather(PlanState *pstate) { + GatherState *node = castNode(GatherState, pstate); TupleTableSlot *fslot = node->funnel_slot; int i; TupleTableSlot *slot; diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c index 0aff3798f75..9a81e225100 100644 --- a/src/backend/executor/nodeGatherMerge.c +++ b/src/backend/executor/nodeGatherMerge.c @@ -44,6 +44,7 @@ typedef struct GMReaderTupleBuffer */ #define MAX_TUPLE_STORE 10 +static TupleTableSlot *ExecGatherMerge(PlanState *pstate); static int32 heap_compare_slots(Datum a, Datum b, void *arg); static TupleTableSlot *gather_merge_getnext(GatherMergeState *gm_state); static HeapTuple gm_readnext_tuple(GatherMergeState *gm_state, int nreader, @@ -75,6 +76,7 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) gm_state = makeNode(GatherMergeState); gm_state->ps.plan = (Plan *) node; gm_state->ps.state = estate; + gm_state->ps.ExecProcNode = ExecGatherMerge; /* * Miscellaneous initialization @@ -157,9 +159,10 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) * the next qualifying tuple. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecGatherMerge(GatherMergeState *node) +static TupleTableSlot * +ExecGatherMerge(PlanState *pstate) { + GatherMergeState *node = castNode(GatherMergeState, pstate); TupleTableSlot *slot; ExprContext *econtext; int i; diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c index fc5e0e59bcc..ab4ae24a6bc 100644 --- a/src/backend/executor/nodeGroup.c +++ b/src/backend/executor/nodeGroup.c @@ -32,9 +32,10 @@ * * Return one tuple for each group of matching input tuples. */ -TupleTableSlot * -ExecGroup(GroupState *node) +static TupleTableSlot * +ExecGroup(PlanState *pstate) { + GroupState *node = castNode(GroupState, pstate); ExprContext *econtext; int numCols; AttrNumber *grpColIdx; @@ -175,6 +176,7 @@ ExecInitGroup(Group *node, EState *estate, int eflags) grpstate = makeNode(GroupState); grpstate->ss.ps.plan = (Plan *) node; grpstate->ss.ps.state = estate; + grpstate->ss.ps.ExecProcNode = ExecGroup; grpstate->grp_done = FALSE; /* diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index fbeb562489c..d10d94ccc26 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -56,8 +56,8 @@ static void *dense_alloc(HashJoinTable hashtable, Size size); * stub for pro forma compliance * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecHash(HashState *node) +static TupleTableSlot * +ExecHash(PlanState *pstate) { elog(ERROR, "Hash node does not support ExecProcNode call convention"); return NULL; @@ -172,6 +172,7 @@ ExecInitHash(Hash *node, EState *estate, int eflags) hashstate = makeNode(HashState); hashstate->ps.plan = (Plan *) node; hashstate->ps.state = estate; + hashstate->ps.ExecProcNode = ExecHash; hashstate->hashtable = NULL; hashstate->hashkeys = NIL; /* will be set by parent HashJoin */ diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 252960c81c5..ab1632cc13d 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -58,9 +58,10 @@ static bool ExecHashJoinNewBatch(HashJoinState *hjstate); * the other one is "outer". * ---------------------------------------------------------------- */ -TupleTableSlot * /* return: a tuple or NULL */ -ExecHashJoin(HashJoinState *node) +static TupleTableSlot * /* return: a tuple or NULL */ +ExecHashJoin(PlanState *pstate) { + HashJoinState *node = castNode(HashJoinState, pstate); PlanState *outerNode; HashState *hashNode; ExprState *joinqual; @@ -399,6 +400,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) hjstate = makeNode(HashJoinState); hjstate->js.ps.plan = (Plan *) node; hjstate->js.ps.state = estate; + hjstate->js.ps.ExecProcNode = ExecHashJoin; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index e2000764a46..fe7ba3f1a4f 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -306,9 +306,11 @@ IndexOnlyRecheck(IndexOnlyScanState *node, TupleTableSlot *slot) * ExecIndexOnlyScan(node) * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecIndexOnlyScan(IndexOnlyScanState *node) +static TupleTableSlot * +ExecIndexOnlyScan(PlanState *pstate) { + IndexOnlyScanState *node = castNode(IndexOnlyScanState, pstate); + /* * If we have runtime keys and they've not already been set up, do it now. */ @@ -476,6 +478,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) indexstate = makeNode(IndexOnlyScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; + indexstate->ss.ps.ExecProcNode = ExecIndexOnlyScan; indexstate->ioss_HeapFetches = 0; /* diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 6704ede9955..404076d5930 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -542,9 +542,11 @@ reorderqueue_pop(IndexScanState *node) * ExecIndexScan(node) * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecIndexScan(IndexScanState *node) +static TupleTableSlot * +ExecIndexScan(PlanState *pstate) { + IndexScanState *node = castNode(IndexScanState, pstate); + /* * If we have runtime keys and they've not already been set up, do it now. */ @@ -910,6 +912,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) indexstate = makeNode(IndexScanState); indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; + indexstate->ss.ps.ExecProcNode = ExecIndexScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c index 2ed3523257f..ac5a2ff0e60 100644 --- a/src/backend/executor/nodeLimit.c +++ b/src/backend/executor/nodeLimit.c @@ -37,9 +37,10 @@ static void pass_down_bound(LimitState *node, PlanState *child_node); * filtering on the stream of tuples returned by a subplan. * ---------------------------------------------------------------- */ -TupleTableSlot * /* return: a tuple or NULL */ -ExecLimit(LimitState *node) +static TupleTableSlot * /* return: a tuple or NULL */ +ExecLimit(PlanState *pstate) { + LimitState *node = castNode(LimitState, pstate); ScanDirection direction; TupleTableSlot *slot; PlanState *outerPlan; @@ -378,6 +379,7 @@ ExecInitLimit(Limit *node, EState *estate, int eflags) limitstate = makeNode(LimitState); limitstate->ps.plan = (Plan *) node; limitstate->ps.state = estate; + limitstate->ps.ExecProcNode = ExecLimit; limitstate->lstate = LIMIT_INITIAL; diff --git a/src/backend/executor/nodeLockRows.c b/src/backend/executor/nodeLockRows.c index dd4e2c5f2f1..93895600a5d 100644 --- a/src/backend/executor/nodeLockRows.c +++ b/src/backend/executor/nodeLockRows.c @@ -36,9 +36,10 @@ * ExecLockRows * ---------------------------------------------------------------- */ -TupleTableSlot * /* return: a tuple or NULL */ -ExecLockRows(LockRowsState *node) +static TupleTableSlot * /* return: a tuple or NULL */ +ExecLockRows(PlanState *pstate) { + LockRowsState *node = castNode(LockRowsState, pstate); TupleTableSlot *slot; EState *estate; PlanState *outerPlan; @@ -364,6 +365,7 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags) lrstate = makeNode(LockRowsState); lrstate->ps.plan = (Plan *) node; lrstate->ps.state = estate; + lrstate->ps.ExecProcNode = ExecLockRows; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c index 33429495909..91178f10198 100644 --- a/src/backend/executor/nodeMaterial.c +++ b/src/backend/executor/nodeMaterial.c @@ -35,9 +35,10 @@ * * ---------------------------------------------------------------- */ -TupleTableSlot * /* result tuple from subplan */ -ExecMaterial(MaterialState *node) +static TupleTableSlot * /* result tuple from subplan */ +ExecMaterial(PlanState *pstate) { + MaterialState *node = castNode(MaterialState, pstate); EState *estate; ScanDirection dir; bool forward; @@ -173,6 +174,7 @@ ExecInitMaterial(Material *node, EState *estate, int eflags) matstate = makeNode(MaterialState); matstate->ss.ps.plan = (Plan *) node; matstate->ss.ps.state = estate; + matstate->ss.ps.ExecProcNode = ExecMaterial; /* * We must have a tuplestore buffering the subplan output to do backward diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index d41def13506..6bf490bd700 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -50,6 +50,7 @@ */ typedef int32 SlotNumber; +static TupleTableSlot *ExecMergeAppend(PlanState *pstate); static int heap_compare_slots(Datum a, Datum b, void *arg); @@ -89,6 +90,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) */ mergestate->ps.plan = (Plan *) node; mergestate->ps.state = estate; + mergestate->ps.ExecProcNode = ExecMergeAppend; mergestate->mergeplans = mergeplanstates; mergestate->ms_nplans = nplans; @@ -169,9 +171,10 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) * Handles iteration over multiple subplans. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecMergeAppend(MergeAppendState *node) +static TupleTableSlot * +ExecMergeAppend(PlanState *pstate) { + MergeAppendState *node = castNode(MergeAppendState, pstate); TupleTableSlot *result; SlotNumber i; diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index 324b61b8c0c..925b4cf5535 100644 --- a/src/backend/executor/nodeMergejoin.c +++ b/src/backend/executor/nodeMergejoin.c @@ -596,9 +596,10 @@ ExecMergeTupleDump(MergeJoinState *mergestate) * ExecMergeJoin * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecMergeJoin(MergeJoinState *node) +static TupleTableSlot * +ExecMergeJoin(PlanState *pstate) { + MergeJoinState *node = castNode(MergeJoinState, pstate); ExprState *joinqual; ExprState *otherqual; bool qualResult; @@ -1448,6 +1449,7 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) mergestate = makeNode(MergeJoinState); mergestate->js.ps.plan = (Plan *) node; mergestate->js.ps.state = estate; + mergestate->js.ps.ExecProcNode = ExecMergeJoin; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 637a582e1cc..0dde0ed6eb2 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1535,9 +1535,10 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) * if needed. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecModifyTable(ModifyTableState *node) +static TupleTableSlot * +ExecModifyTable(PlanState *pstate) { + ModifyTableState *node = castNode(ModifyTableState, pstate); EState *estate = node->ps.state; CmdType operation = node->operation; ResultRelInfo *saved_resultRelInfo; @@ -1806,6 +1807,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate = makeNode(ModifyTableState); mtstate->ps.plan = (Plan *) node; mtstate->ps.state = estate; + mtstate->ps.ExecProcNode = ExecModifyTable; mtstate->operation = operation; mtstate->canSetTag = node->canSetTag; diff --git a/src/backend/executor/nodeNamedtuplestorescan.c b/src/backend/executor/nodeNamedtuplestorescan.c index 62234869abb..3a65b9f5dc9 100644 --- a/src/backend/executor/nodeNamedtuplestorescan.c +++ b/src/backend/executor/nodeNamedtuplestorescan.c @@ -63,9 +63,11 @@ NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecNamedTuplestoreScan(NamedTuplestoreScanState *node) +static TupleTableSlot * +ExecNamedTuplestoreScan(PlanState *pstate) { + NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) NamedTuplestoreScanNext, (ExecScanRecheckMtd) NamedTuplestoreScanRecheck); @@ -97,6 +99,7 @@ ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflag scanstate = makeNode(NamedTuplestoreScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan; enr = get_ENR(estate->es_queryEnv, node->enrname); if (!enr) diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c index bedc374ef05..4447b7c051a 100644 --- a/src/backend/executor/nodeNestloop.c +++ b/src/backend/executor/nodeNestloop.c @@ -57,9 +57,10 @@ * are prepared to return the first tuple. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecNestLoop(NestLoopState *node) +static TupleTableSlot * +ExecNestLoop(PlanState *pstate) { + NestLoopState *node = castNode(NestLoopState, pstate); NestLoop *nl; PlanState *innerPlan; PlanState *outerPlan; @@ -275,6 +276,7 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags) nlstate = makeNode(NestLoopState); nlstate->js.ps.plan = (Plan *) node; nlstate->js.ps.state = estate; + nlstate->js.ps.ExecProcNode = ExecNestLoop; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeProjectSet.c b/src/backend/executor/nodeProjectSet.c index 3b69c7adeea..d93462c5421 100644 --- a/src/backend/executor/nodeProjectSet.c +++ b/src/backend/executor/nodeProjectSet.c @@ -39,9 +39,10 @@ static TupleTableSlot *ExecProjectSRF(ProjectSetState *node, bool continuing); * returning functions). * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecProjectSet(ProjectSetState *node) +static TupleTableSlot * +ExecProjectSet(PlanState *pstate) { + ProjectSetState *node = castNode(ProjectSetState, pstate); TupleTableSlot *outerTupleSlot; TupleTableSlot *resultSlot; PlanState *outerPlan; @@ -215,6 +216,7 @@ ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags) state = makeNode(ProjectSetState); state->ps.plan = (Plan *) node; state->ps.state = estate; + state->ps.ExecProcNode = ExecProjectSet; state->pending_srf_tuples = false; diff --git a/src/backend/executor/nodeRecursiveunion.c b/src/backend/executor/nodeRecursiveunion.c index 2802fffa2b6..a64dd1397a4 100644 --- a/src/backend/executor/nodeRecursiveunion.c +++ b/src/backend/executor/nodeRecursiveunion.c @@ -66,9 +66,10 @@ build_hash_table(RecursiveUnionState *rustate) * 2.6 go back to 2.2 * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecRecursiveUnion(RecursiveUnionState *node) +static TupleTableSlot * +ExecRecursiveUnion(PlanState *pstate) { + RecursiveUnionState *node = castNode(RecursiveUnionState, pstate); PlanState *outerPlan = outerPlanState(node); PlanState *innerPlan = innerPlanState(node); RecursiveUnion *plan = (RecursiveUnion *) node->ps.plan; @@ -172,6 +173,7 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags) rustate = makeNode(RecursiveUnionState); rustate->ps.plan = (Plan *) node; rustate->ps.state = estate; + rustate->ps.ExecProcNode = ExecRecursiveUnion; rustate->eqfunctions = NULL; rustate->hashfunctions = NULL; diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c index f007f46784f..4c879d87655 100644 --- a/src/backend/executor/nodeResult.c +++ b/src/backend/executor/nodeResult.c @@ -64,9 +64,10 @@ * 'nil' if the constant qualification is not satisfied. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecResult(ResultState *node) +static TupleTableSlot * +ExecResult(PlanState *pstate) { + ResultState *node = castNode(ResultState, pstate); TupleTableSlot *outerTupleSlot; PlanState *outerPlan; ExprContext *econtext; @@ -191,6 +192,7 @@ ExecInitResult(Result *node, EState *estate, int eflags) resstate = makeNode(ResultState); resstate->ps.plan = (Plan *) node; resstate->ps.state = estate; + resstate->ps.ExecProcNode = ExecResult; resstate->rs_done = false; resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true; diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c index b710ef7edf2..9c74a836e40 100644 --- a/src/backend/executor/nodeSamplescan.c +++ b/src/backend/executor/nodeSamplescan.c @@ -96,10 +96,12 @@ SampleRecheck(SampleScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecSampleScan(SampleScanState *node) +static TupleTableSlot * +ExecSampleScan(PlanState *pstate) { - return ExecScan((ScanState *) node, + SampleScanState *node = castNode(SampleScanState, pstate); + + return ExecScan(&node->ss, (ExecScanAccessMtd) SampleNext, (ExecScanRecheckMtd) SampleRecheck); } @@ -153,6 +155,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags) scanstate = makeNode(SampleScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecSampleScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index 307df87c82f..5c49d4ca8a9 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -121,10 +121,12 @@ SeqRecheck(SeqScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecSeqScan(SeqScanState *node) +static TupleTableSlot * +ExecSeqScan(PlanState *pstate) { - return ExecScan((ScanState *) node, + SeqScanState *node = castNode(SeqScanState, pstate); + + return ExecScan(&node->ss, (ExecScanAccessMtd) SeqNext, (ExecScanRecheckMtd) SeqRecheck); } @@ -177,6 +179,7 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags) scanstate = makeNode(SeqScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecSeqScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeSetOp.c b/src/backend/executor/nodeSetOp.c index 56c5643f175..571cbf86b1d 100644 --- a/src/backend/executor/nodeSetOp.c +++ b/src/backend/executor/nodeSetOp.c @@ -180,9 +180,10 @@ set_output_count(SetOpState *setopstate, SetOpStatePerGroup pergroup) * ExecSetOp * ---------------------------------------------------------------- */ -TupleTableSlot * /* return: a tuple or NULL */ -ExecSetOp(SetOpState *node) +static TupleTableSlot * /* return: a tuple or NULL */ +ExecSetOp(PlanState *pstate) { + SetOpState *node = castNode(SetOpState, pstate); SetOp *plannode = (SetOp *) node->ps.plan; TupleTableSlot *resultTupleSlot = node->ps.ps_ResultTupleSlot; @@ -485,6 +486,7 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags) setopstate = makeNode(SetOpState); setopstate->ps.plan = (Plan *) node; setopstate->ps.state = estate; + setopstate->ps.ExecProcNode = ExecSetOp; setopstate->eqfunctions = NULL; setopstate->hashfunctions = NULL; diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c index 799a4e92042..aae4150e2c8 100644 --- a/src/backend/executor/nodeSort.c +++ b/src/backend/executor/nodeSort.c @@ -35,9 +35,10 @@ * -- the outer child is prepared to return the first tuple. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecSort(SortState *node) +static TupleTableSlot * +ExecSort(PlanState *pstate) { + SortState *node = castNode(SortState, pstate); EState *estate; ScanDirection dir; Tuplesortstate *tuplesortstate; @@ -165,6 +166,7 @@ ExecInitSort(Sort *node, EState *estate, int eflags) sortstate = makeNode(SortState); sortstate->ss.ps.plan = (Plan *) node; sortstate->ss.ps.state = estate; + sortstate->ss.ps.ExecProcNode = ExecSort; /* * We must have random access to the sort output to do backward scan or diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c index ae184700a67..088c92992ec 100644 --- a/src/backend/executor/nodeSubqueryscan.c +++ b/src/backend/executor/nodeSubqueryscan.c @@ -79,9 +79,11 @@ SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecSubqueryScan(SubqueryScanState *node) +static TupleTableSlot * +ExecSubqueryScan(PlanState *pstate) { + SubqueryScanState *node = castNode(SubqueryScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) SubqueryNext, (ExecScanRecheckMtd) SubqueryRecheck); @@ -109,6 +111,7 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags) subquerystate = makeNode(SubqueryScanState); subquerystate->ss.ps.plan = (Plan *) node; subquerystate->ss.ps.state = estate; + subquerystate->ss.ps.ExecProcNode = ExecSubqueryScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeTableFuncscan.c b/src/backend/executor/nodeTableFuncscan.c index 2859363fe2c..b03d2ef7622 100644 --- a/src/backend/executor/nodeTableFuncscan.c +++ b/src/backend/executor/nodeTableFuncscan.c @@ -93,9 +93,11 @@ TableFuncRecheck(TableFuncScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecTableFuncScan(TableFuncScanState *node) +static TupleTableSlot * +ExecTableFuncScan(PlanState *pstate) { + TableFuncScanState *node = castNode(TableFuncScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) TableFuncNext, (ExecScanRecheckMtd) TableFuncRecheck); @@ -128,6 +130,7 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags) scanstate = makeNode(TableFuncScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecTableFuncScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c index c122473bdf8..0ee76e7d252 100644 --- a/src/backend/executor/nodeTidscan.c +++ b/src/backend/executor/nodeTidscan.c @@ -445,9 +445,11 @@ TidRecheck(TidScanState *node, TupleTableSlot *slot) * -- tidPtr is -1. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecTidScan(TidScanState *node) +static TupleTableSlot * +ExecTidScan(PlanState *pstate) { + TidScanState *node = castNode(TidScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) TidNext, (ExecScanRecheckMtd) TidRecheck); @@ -519,6 +521,7 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags) tidstate = makeNode(TidScanState); tidstate->ss.ps.plan = (Plan *) node; tidstate->ss.ps.state = estate; + tidstate->ss.ps.ExecProcNode = ExecTidScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c index db78c88368b..621fdd9b9c1 100644 --- a/src/backend/executor/nodeUnique.c +++ b/src/backend/executor/nodeUnique.c @@ -43,9 +43,10 @@ * ExecUnique * ---------------------------------------------------------------- */ -TupleTableSlot * /* return: a tuple or NULL */ -ExecUnique(UniqueState *node) +static TupleTableSlot * /* return: a tuple or NULL */ +ExecUnique(PlanState *pstate) { + UniqueState *node = castNode(UniqueState, pstate); Unique *plannode = (Unique *) node->ps.plan; TupleTableSlot *resultTupleSlot; TupleTableSlot *slot; @@ -125,6 +126,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags) uniquestate = makeNode(UniqueState); uniquestate->ps.plan = (Plan *) node; uniquestate->ps.state = estate; + uniquestate->ps.ExecProcNode = ExecUnique; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeValuesscan.c b/src/backend/executor/nodeValuesscan.c index 9ee776c4c32..6eacaed8bb8 100644 --- a/src/backend/executor/nodeValuesscan.c +++ b/src/backend/executor/nodeValuesscan.c @@ -185,9 +185,11 @@ ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecValuesScan(ValuesScanState *node) +static TupleTableSlot * +ExecValuesScan(PlanState *pstate) { + ValuesScanState *node = castNode(ValuesScanState, pstate); + return ExecScan(&node->ss, (ExecScanAccessMtd) ValuesNext, (ExecScanRecheckMtd) ValuesRecheck); @@ -218,6 +220,7 @@ ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags) scanstate = makeNode(ValuesScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecValuesScan; /* * Miscellaneous initialization diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 9da35ac506b..80be46029f4 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -1587,9 +1587,10 @@ update_frametailpos(WindowObject winobj, TupleTableSlot *slot) * returned rows is exactly the same as its outer subplan's result. * ----------------- */ -TupleTableSlot * -ExecWindowAgg(WindowAggState *winstate) +static TupleTableSlot * +ExecWindowAgg(PlanState *pstate) { + WindowAggState *winstate = castNode(WindowAggState, pstate); ExprContext *econtext; int i; int numfuncs; @@ -1790,6 +1791,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) winstate = makeNode(WindowAggState); winstate->ss.ps.plan = (Plan *) node; winstate->ss.ps.state = estate; + winstate->ss.ps.ExecProcNode = ExecWindowAgg; /* * Create expression contexts. We need two, one for per-input-tuple diff --git a/src/backend/executor/nodeWorktablescan.c b/src/backend/executor/nodeWorktablescan.c index d7616be0652..d5ffadda3e8 100644 --- a/src/backend/executor/nodeWorktablescan.c +++ b/src/backend/executor/nodeWorktablescan.c @@ -77,9 +77,11 @@ WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot) * access method functions. * ---------------------------------------------------------------- */ -TupleTableSlot * -ExecWorkTableScan(WorkTableScanState *node) +static TupleTableSlot * +ExecWorkTableScan(PlanState *pstate) { + WorkTableScanState *node = castNode(WorkTableScanState, pstate); + /* * On the first call, find the ancestor RecursiveUnion's state via the * Param slot reserved for it. (We can't do this during node init because @@ -144,6 +146,7 @@ ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags) scanstate = makeNode(WorkTableScanState); scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.state = estate; + scanstate->ss.ps.ExecProcNode = ExecWorkTableScan; scanstate->rustate = NULL; /* we'll set this later */ /* |