diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 20fd9f822e..396920c0a2 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)) { /* @@ -364,6 +370,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags) break; } + /* + * 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) +{ + /* + * 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) + node->ExecProcNode = ExecProcNodeInstr; + else + node->ExecProcNode = node->ExecProcNodeReal; + + return node->ExecProcNode(node); +} + + +/* + * 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; - if (node->chgParam != NULL) /* something changed */ - ExecReScan(node); /* let ReScan handle this */ + InstrStartNode(node->instrument); - if (node->instrument) - InstrStartNode(node->instrument); + result = node->ExecProcNodeReal(node); - 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; - - 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; - - case T_SetOpState: - result = ExecSetOp((SetOpState *) node); - break; - - case T_LockRowsState: - result = ExecLockRows((LockRowsState *) node); - break; - - case T_LimitState: - result = ExecLimit((LimitState *) node); - break; - - default: - elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); - result = NULL; - break; - } - - 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 377916dae7..6a26773a49 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 58045e05e5..bed9bb8713 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 e4eb028ff9..1c5c312c95 100644 --- a/src/backend/executor/nodeBitmapAnd.c +++ b/src/backend/executor/nodeBitmapAnd.c @@ -32,6 +32,19 @@ #include "executor/nodeBitmapAnd.h" +/* ---------------------------------------------------------------- + * ExecBitmapAnd + * + * stub for pro forma compliance + * ---------------------------------------------------------------- + */ +static TupleTableSlot * +ExecBitmapAnd(PlanState *pstate) +{ + elog(ERROR, "BitmapAnd node does not support ExecProcNode call convention"); + return NULL; +} + /* ---------------------------------------------------------------- * ExecInitBitmapAnd * @@ -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 cf109d5049..79f534e4e9 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 2411a2e5c1..6feb70f4ae 100644 --- a/src/backend/executor/nodeBitmapIndexscan.c +++ b/src/backend/executor/nodeBitmapIndexscan.c @@ -28,6 +28,19 @@ #include "utils/memutils.h" +/* ---------------------------------------------------------------- + * 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 4f0ddc6dff..66a7a89a8b 100644 --- a/src/backend/executor/nodeBitmapOr.c +++ b/src/backend/executor/nodeBitmapOr.c @@ -33,6 +33,19 @@ #include "miscadmin.h" +/* ---------------------------------------------------------------- + * ExecBitmapOr + * + * stub for pro forma compliance + * ---------------------------------------------------------------- + */ +static TupleTableSlot * +ExecBitmapOr(PlanState *pstate) +{ + elog(ERROR, "BitmapOr node does not support ExecProcNode call convention"); + return NULL; +} + /* ---------------------------------------------------------------- * ExecInitBitmapOr * @@ -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 bed7949c5a..79676ca978 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 fc15974a2d..fb7645b1f4 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 9cde112554..140e82ef5e 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 3217d641d7..9f87a7e5cd 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 5dbe19c056..e8d94ee6f3 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 0aff3798f7..9a81e22510 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 fc5e0e59bc..ab4ae24a6b 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 fbeb562489..d10d94ccc2 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 252960c81c..ab1632cc13 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 e2000764a4..fe7ba3f1a4 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 6704ede995..404076d593 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 2ed3523257..ac5a2ff0e6 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 dd4e2c5f2f..93895600a5 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 3342949590..91178f1019 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 d41def1350..6bf490bd70 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 324b61b8c0..925b4cf553 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 637a582e1c..0dde0ed6eb 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 62234869ab..3a65b9f5dc 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 bedc374ef0..4447b7c051 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 3b69c7adee..d93462c542 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 2802fffa2b..a64dd1397a 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 f007f46784..4c879d8765 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 b710ef7edf..9c74a836e4 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 307df87c82..5c49d4ca8a 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 56c5643f17..571cbf86b1 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 799a4e9204..aae4150e2c 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 ae184700a6..088c92992e 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 2859363fe2..b03d2ef762 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 c122473bdf..0ee76e7d25 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 db78c88368..621fdd9b9c 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 9ee776c4c3..6eacaed8bb 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 9da35ac506..80be46029f 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 d7616be065..d5ffadda3e 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 */ /* diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 59c28b709e..60326f9d03 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -225,14 +225,31 @@ extern void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate); extern void EvalPlanQualEnd(EPQState *epqstate); /* - * prototypes from functions in execProcnode.c + * functions in execProcnode.c */ extern PlanState *ExecInitNode(Plan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecProcNode(PlanState *node); extern Node *MultiExecProcNode(PlanState *node); extern void ExecEndNode(PlanState *node); extern bool ExecShutdownNode(PlanState *node); + +/* ---------------------------------------------------------------- + * ExecProcNode + * + * Execute the given node to return a(nother) tuple. + * ---------------------------------------------------------------- + */ +#ifndef FRONTEND +static inline TupleTableSlot * +ExecProcNode(PlanState *node) +{ + if (node->chgParam != NULL) /* something changed? */ + ExecReScan(node); /* let ReScan handle this */ + + return node->ExecProcNode(node); +} +#endif + /* * prototypes from functions in execExpr.c */ diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h index fa11ba93a6..eff5af9c2a 100644 --- a/src/include/executor/nodeAgg.h +++ b/src/include/executor/nodeAgg.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags); -extern TupleTableSlot *ExecAgg(AggState *node); extern void ExecEndAgg(AggState *node); extern void ExecReScanAgg(AggState *node); diff --git a/src/include/executor/nodeAppend.h b/src/include/executor/nodeAppend.h index ee0b6ad23d..4e38a1380e 100644 --- a/src/include/executor/nodeAppend.h +++ b/src/include/executor/nodeAppend.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern AppendState *ExecInitAppend(Append *node, EState *estate, int eflags); -extern TupleTableSlot *ExecAppend(AppendState *node); extern void ExecEndAppend(AppendState *node); extern void ExecReScanAppend(AppendState *node); diff --git a/src/include/executor/nodeBitmapHeapscan.h b/src/include/executor/nodeBitmapHeapscan.h index f477d1c772..c77694cf22 100644 --- a/src/include/executor/nodeBitmapHeapscan.h +++ b/src/include/executor/nodeBitmapHeapscan.h @@ -18,7 +18,6 @@ #include "access/parallel.h" extern BitmapHeapScanState *ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecBitmapHeapScan(BitmapHeapScanState *node); extern void ExecEndBitmapHeapScan(BitmapHeapScanState *node); extern void ExecReScanBitmapHeapScan(BitmapHeapScanState *node); extern void ExecBitmapHeapEstimate(BitmapHeapScanState *node, diff --git a/src/include/executor/nodeCtescan.h b/src/include/executor/nodeCtescan.h index 397bdfdd1c..d2fbcbd586 100644 --- a/src/include/executor/nodeCtescan.h +++ b/src/include/executor/nodeCtescan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern CteScanState *ExecInitCteScan(CteScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecCteScan(CteScanState *node); extern void ExecEndCteScan(CteScanState *node); extern void ExecReScanCteScan(CteScanState *node); diff --git a/src/include/executor/nodeCustom.h b/src/include/executor/nodeCustom.h index e81bcf7f21..a1cc63ae1f 100644 --- a/src/include/executor/nodeCustom.h +++ b/src/include/executor/nodeCustom.h @@ -21,7 +21,6 @@ */ extern CustomScanState *ExecInitCustomScan(CustomScan *custom_scan, EState *estate, int eflags); -extern TupleTableSlot *ExecCustomScan(CustomScanState *node); extern void ExecEndCustomScan(CustomScanState *node); extern void ExecReScanCustomScan(CustomScanState *node); diff --git a/src/include/executor/nodeForeignscan.h b/src/include/executor/nodeForeignscan.h index 3ff4ecd8c9..0b662597d8 100644 --- a/src/include/executor/nodeForeignscan.h +++ b/src/include/executor/nodeForeignscan.h @@ -18,7 +18,6 @@ #include "nodes/execnodes.h" extern ForeignScanState *ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecForeignScan(ForeignScanState *node); extern void ExecEndForeignScan(ForeignScanState *node); extern void ExecReScanForeignScan(ForeignScanState *node); diff --git a/src/include/executor/nodeFunctionscan.h b/src/include/executor/nodeFunctionscan.h index 5e830ebdea..aaa9d8c316 100644 --- a/src/include/executor/nodeFunctionscan.h +++ b/src/include/executor/nodeFunctionscan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern FunctionScanState *ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecFunctionScan(FunctionScanState *node); extern void ExecEndFunctionScan(FunctionScanState *node); extern void ExecReScanFunctionScan(FunctionScanState *node); diff --git a/src/include/executor/nodeGather.h b/src/include/executor/nodeGather.h index b0006934d4..189bd70041 100644 --- a/src/include/executor/nodeGather.h +++ b/src/include/executor/nodeGather.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern GatherState *ExecInitGather(Gather *node, EState *estate, int eflags); -extern TupleTableSlot *ExecGather(GatherState *node); extern void ExecEndGather(GatherState *node); extern void ExecShutdownGather(GatherState *node); extern void ExecReScanGather(GatherState *node); diff --git a/src/include/executor/nodeGatherMerge.h b/src/include/executor/nodeGatherMerge.h index 14b31a086c..0154d73312 100644 --- a/src/include/executor/nodeGatherMerge.h +++ b/src/include/executor/nodeGatherMerge.h @@ -19,7 +19,6 @@ extern GatherMergeState *ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags); -extern TupleTableSlot *ExecGatherMerge(GatherMergeState *node); extern void ExecEndGatherMerge(GatherMergeState *node); extern void ExecReScanGatherMerge(GatherMergeState *node); extern void ExecShutdownGatherMerge(GatherMergeState *node); diff --git a/src/include/executor/nodeGroup.h b/src/include/executor/nodeGroup.h index 7358b61707..b0d7e312c9 100644 --- a/src/include/executor/nodeGroup.h +++ b/src/include/executor/nodeGroup.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern GroupState *ExecInitGroup(Group *node, EState *estate, int eflags); -extern TupleTableSlot *ExecGroup(GroupState *node); extern void ExecEndGroup(GroupState *node); extern void ExecReScanGroup(GroupState *node); diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h index 8052f27d0b..3ae556fb6c 100644 --- a/src/include/executor/nodeHash.h +++ b/src/include/executor/nodeHash.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern HashState *ExecInitHash(Hash *node, EState *estate, int eflags); -extern TupleTableSlot *ExecHash(HashState *node); extern Node *MultiExecHash(HashState *node); extern void ExecEndHash(HashState *node); extern void ExecReScanHash(HashState *node); diff --git a/src/include/executor/nodeHashjoin.h b/src/include/executor/nodeHashjoin.h index 541c81edc7..7469bfbf60 100644 --- a/src/include/executor/nodeHashjoin.h +++ b/src/include/executor/nodeHashjoin.h @@ -18,7 +18,6 @@ #include "storage/buffile.h" extern HashJoinState *ExecInitHashJoin(HashJoin *node, EState *estate, int eflags); -extern TupleTableSlot *ExecHashJoin(HashJoinState *node); extern void ExecEndHashJoin(HashJoinState *node); extern void ExecReScanHashJoin(HashJoinState *node); diff --git a/src/include/executor/nodeIndexonlyscan.h b/src/include/executor/nodeIndexonlyscan.h index cf227daae0..c8a709c26e 100644 --- a/src/include/executor/nodeIndexonlyscan.h +++ b/src/include/executor/nodeIndexonlyscan.h @@ -18,7 +18,6 @@ #include "access/parallel.h" extern IndexOnlyScanState *ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecIndexOnlyScan(IndexOnlyScanState *node); extern void ExecEndIndexOnlyScan(IndexOnlyScanState *node); extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node); extern void ExecIndexOnlyRestrPos(IndexOnlyScanState *node); diff --git a/src/include/executor/nodeIndexscan.h b/src/include/executor/nodeIndexscan.h index 0118234eca..1668e347ee 100644 --- a/src/include/executor/nodeIndexscan.h +++ b/src/include/executor/nodeIndexscan.h @@ -18,7 +18,6 @@ #include "nodes/execnodes.h" extern IndexScanState *ExecInitIndexScan(IndexScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecIndexScan(IndexScanState *node); extern void ExecEndIndexScan(IndexScanState *node); extern void ExecIndexMarkPos(IndexScanState *node); extern void ExecIndexRestrPos(IndexScanState *node); diff --git a/src/include/executor/nodeLimit.h b/src/include/executor/nodeLimit.h index 7bb20d9978..db65b5524c 100644 --- a/src/include/executor/nodeLimit.h +++ b/src/include/executor/nodeLimit.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern LimitState *ExecInitLimit(Limit *node, EState *estate, int eflags); -extern TupleTableSlot *ExecLimit(LimitState *node); extern void ExecEndLimit(LimitState *node); extern void ExecReScanLimit(LimitState *node); diff --git a/src/include/executor/nodeLockRows.h b/src/include/executor/nodeLockRows.h index 6b90756e4c..c9d05b87f1 100644 --- a/src/include/executor/nodeLockRows.h +++ b/src/include/executor/nodeLockRows.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern LockRowsState *ExecInitLockRows(LockRows *node, EState *estate, int eflags); -extern TupleTableSlot *ExecLockRows(LockRowsState *node); extern void ExecEndLockRows(LockRowsState *node); extern void ExecReScanLockRows(LockRowsState *node); diff --git a/src/include/executor/nodeMaterial.h b/src/include/executor/nodeMaterial.h index f69abbca82..4b3c2578c9 100644 --- a/src/include/executor/nodeMaterial.h +++ b/src/include/executor/nodeMaterial.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern MaterialState *ExecInitMaterial(Material *node, EState *estate, int eflags); -extern TupleTableSlot *ExecMaterial(MaterialState *node); extern void ExecEndMaterial(MaterialState *node); extern void ExecMaterialMarkPos(MaterialState *node); extern void ExecMaterialRestrPos(MaterialState *node); diff --git a/src/include/executor/nodeMergeAppend.h b/src/include/executor/nodeMergeAppend.h index 3cc6ef549b..a0ccbae965 100644 --- a/src/include/executor/nodeMergeAppend.h +++ b/src/include/executor/nodeMergeAppend.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern MergeAppendState *ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags); -extern TupleTableSlot *ExecMergeAppend(MergeAppendState *node); extern void ExecEndMergeAppend(MergeAppendState *node); extern void ExecReScanMergeAppend(MergeAppendState *node); diff --git a/src/include/executor/nodeMergejoin.h b/src/include/executor/nodeMergejoin.h index 32df25ae8b..d20e41505d 100644 --- a/src/include/executor/nodeMergejoin.h +++ b/src/include/executor/nodeMergejoin.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern MergeJoinState *ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags); -extern TupleTableSlot *ExecMergeJoin(MergeJoinState *node); extern void ExecEndMergeJoin(MergeJoinState *node); extern void ExecReScanMergeJoin(MergeJoinState *node); diff --git a/src/include/executor/nodeModifyTable.h b/src/include/executor/nodeModifyTable.h index 5a406f236d..a2e7af98de 100644 --- a/src/include/executor/nodeModifyTable.h +++ b/src/include/executor/nodeModifyTable.h @@ -16,7 +16,6 @@ #include "nodes/execnodes.h" extern ModifyTableState *ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags); -extern TupleTableSlot *ExecModifyTable(ModifyTableState *node); extern void ExecEndModifyTable(ModifyTableState *node); extern void ExecReScanModifyTable(ModifyTableState *node); diff --git a/src/include/executor/nodeNamedtuplestorescan.h b/src/include/executor/nodeNamedtuplestorescan.h index 7f72fbe98a..395d978f62 100644 --- a/src/include/executor/nodeNamedtuplestorescan.h +++ b/src/include/executor/nodeNamedtuplestorescan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern NamedTuplestoreScanState *ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecNamedTuplestoreScan(NamedTuplestoreScanState *node); extern void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node); extern void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node); diff --git a/src/include/executor/nodeNestloop.h b/src/include/executor/nodeNestloop.h index 8e0fcc1922..0d6486cc57 100644 --- a/src/include/executor/nodeNestloop.h +++ b/src/include/executor/nodeNestloop.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern NestLoopState *ExecInitNestLoop(NestLoop *node, EState *estate, int eflags); -extern TupleTableSlot *ExecNestLoop(NestLoopState *node); extern void ExecEndNestLoop(NestLoopState *node); extern void ExecReScanNestLoop(NestLoopState *node); diff --git a/src/include/executor/nodeProjectSet.h b/src/include/executor/nodeProjectSet.h index 2f6999e8db..a0b0521f8d 100644 --- a/src/include/executor/nodeProjectSet.h +++ b/src/include/executor/nodeProjectSet.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern ProjectSetState *ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags); -extern TupleTableSlot *ExecProjectSet(ProjectSetState *node); extern void ExecEndProjectSet(ProjectSetState *node); extern void ExecReScanProjectSet(ProjectSetState *node); diff --git a/src/include/executor/nodeRecursiveunion.h b/src/include/executor/nodeRecursiveunion.h index f0eba05bee..e6ce1b4783 100644 --- a/src/include/executor/nodeRecursiveunion.h +++ b/src/include/executor/nodeRecursiveunion.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern RecursiveUnionState *ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags); -extern TupleTableSlot *ExecRecursiveUnion(RecursiveUnionState *node); extern void ExecEndRecursiveUnion(RecursiveUnionState *node); extern void ExecReScanRecursiveUnion(RecursiveUnionState *node); diff --git a/src/include/executor/nodeResult.h b/src/include/executor/nodeResult.h index 61d3cb2cc2..20e0063410 100644 --- a/src/include/executor/nodeResult.h +++ b/src/include/executor/nodeResult.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern ResultState *ExecInitResult(Result *node, EState *estate, int eflags); -extern TupleTableSlot *ExecResult(ResultState *node); extern void ExecEndResult(ResultState *node); extern void ExecResultMarkPos(ResultState *node); extern void ExecResultRestrPos(ResultState *node); diff --git a/src/include/executor/nodeSamplescan.h b/src/include/executor/nodeSamplescan.h index ed06e77e4e..607bbd9412 100644 --- a/src/include/executor/nodeSamplescan.h +++ b/src/include/executor/nodeSamplescan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern SampleScanState *ExecInitSampleScan(SampleScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecSampleScan(SampleScanState *node); extern void ExecEndSampleScan(SampleScanState *node); extern void ExecReScanSampleScan(SampleScanState *node); diff --git a/src/include/executor/nodeSeqscan.h b/src/include/executor/nodeSeqscan.h index 06e0686b0b..0fba79f8de 100644 --- a/src/include/executor/nodeSeqscan.h +++ b/src/include/executor/nodeSeqscan.h @@ -18,7 +18,6 @@ #include "nodes/execnodes.h" extern SeqScanState *ExecInitSeqScan(SeqScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecSeqScan(SeqScanState *node); extern void ExecEndSeqScan(SeqScanState *node); extern void ExecReScanSeqScan(SeqScanState *node); diff --git a/src/include/executor/nodeSetOp.h b/src/include/executor/nodeSetOp.h index af85977183..c15f945046 100644 --- a/src/include/executor/nodeSetOp.h +++ b/src/include/executor/nodeSetOp.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern SetOpState *ExecInitSetOp(SetOp *node, EState *estate, int eflags); -extern TupleTableSlot *ExecSetOp(SetOpState *node); extern void ExecEndSetOp(SetOpState *node); extern void ExecReScanSetOp(SetOpState *node); diff --git a/src/include/executor/nodeSort.h b/src/include/executor/nodeSort.h index 1d2b7130b3..ed0e9dbb53 100644 --- a/src/include/executor/nodeSort.h +++ b/src/include/executor/nodeSort.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern SortState *ExecInitSort(Sort *node, EState *estate, int eflags); -extern TupleTableSlot *ExecSort(SortState *node); extern void ExecEndSort(SortState *node); extern void ExecSortMarkPos(SortState *node); extern void ExecSortRestrPos(SortState *node); diff --git a/src/include/executor/nodeSubqueryscan.h b/src/include/executor/nodeSubqueryscan.h index c852e2947f..710e050285 100644 --- a/src/include/executor/nodeSubqueryscan.h +++ b/src/include/executor/nodeSubqueryscan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern SubqueryScanState *ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecSubqueryScan(SubqueryScanState *node); extern void ExecEndSubqueryScan(SubqueryScanState *node); extern void ExecReScanSubqueryScan(SubqueryScanState *node); diff --git a/src/include/executor/nodeTableFuncscan.h b/src/include/executor/nodeTableFuncscan.h index c58156e99c..c4672c0ac0 100644 --- a/src/include/executor/nodeTableFuncscan.h +++ b/src/include/executor/nodeTableFuncscan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern TableFuncScanState *ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecTableFuncScan(TableFuncScanState *node); extern void ExecEndTableFuncScan(TableFuncScanState *node); extern void ExecReScanTableFuncScan(TableFuncScanState *node); diff --git a/src/include/executor/nodeTidscan.h b/src/include/executor/nodeTidscan.h index d07ed7c864..e68aaf3829 100644 --- a/src/include/executor/nodeTidscan.h +++ b/src/include/executor/nodeTidscan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern TidScanState *ExecInitTidScan(TidScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecTidScan(TidScanState *node); extern void ExecEndTidScan(TidScanState *node); extern void ExecReScanTidScan(TidScanState *node); diff --git a/src/include/executor/nodeUnique.h b/src/include/executor/nodeUnique.h index 3d0ac9dde1..008774ae0f 100644 --- a/src/include/executor/nodeUnique.h +++ b/src/include/executor/nodeUnique.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern UniqueState *ExecInitUnique(Unique *node, EState *estate, int eflags); -extern TupleTableSlot *ExecUnique(UniqueState *node); extern void ExecEndUnique(UniqueState *node); extern void ExecReScanUnique(UniqueState *node); diff --git a/src/include/executor/nodeValuesscan.h b/src/include/executor/nodeValuesscan.h index c28bb1acce..772a5e9705 100644 --- a/src/include/executor/nodeValuesscan.h +++ b/src/include/executor/nodeValuesscan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern ValuesScanState *ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecValuesScan(ValuesScanState *node); extern void ExecEndValuesScan(ValuesScanState *node); extern void ExecReScanValuesScan(ValuesScanState *node); diff --git a/src/include/executor/nodeWindowAgg.h b/src/include/executor/nodeWindowAgg.h index db1ad60677..1c177309ae 100644 --- a/src/include/executor/nodeWindowAgg.h +++ b/src/include/executor/nodeWindowAgg.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern WindowAggState *ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags); -extern TupleTableSlot *ExecWindowAgg(WindowAggState *node); extern void ExecEndWindowAgg(WindowAggState *node); extern void ExecReScanWindowAgg(WindowAggState *node); diff --git a/src/include/executor/nodeWorktablescan.h b/src/include/executor/nodeWorktablescan.h index c222d9f6b4..df05e75111 100644 --- a/src/include/executor/nodeWorktablescan.h +++ b/src/include/executor/nodeWorktablescan.h @@ -17,7 +17,6 @@ #include "nodes/execnodes.h" extern WorkTableScanState *ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags); -extern TupleTableSlot *ExecWorkTableScan(WorkTableScanState *node); extern void ExecEndWorkTableScan(WorkTableScanState *node); extern void ExecReScanWorkTableScan(WorkTableScanState *node); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 85fac8ab91..35c28a6143 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -818,6 +818,18 @@ typedef struct DomainConstraintState * ---------------------------------------------------------------- */ +struct PlanState; + +/* ---------------- + * ExecProcNodeMtd + * + * This is the method called by ExecProcNode to return the next tuple + * from an executor node. It returns NULL, or an empty TupleTableSlot, + * if no more tuples are available. + * ---------------- + */ +typedef TupleTableSlot *(*ExecProcNodeMtd) (struct PlanState *pstate); + /* ---------------- * PlanState node * @@ -835,6 +847,10 @@ typedef struct PlanState * nodes point to one EState for the whole * top-level plan */ + ExecProcNodeMtd ExecProcNode; /* function to return next tuple */ + ExecProcNodeMtd ExecProcNodeReal; /* actual function, if above is a + * wrapper */ + Instrumentation *instrument; /* Optional runtime stats for this node */ WorkerInstrumentation *worker_instrument; /* per-worker instrumentation */