]> granicus.if.org Git - postgresql/commitdiff
Move ExecProcNode from dispatch to function pointer based model.
authorAndres Freund <andres@anarazel.de>
Mon, 17 Jul 2017 07:33:49 +0000 (00:33 -0700)
committerAndres Freund <andres@anarazel.de>
Sun, 30 Jul 2017 23:18:21 +0000 (16:18 -0700)
This allows us to add stack-depth checks the first time an executor
node is called, and skip that overhead on following
calls. Additionally it yields a nice speedup.

While it'd probably have been a good idea to have that check all
along, it has become more important after the new expression
evaluation framework in b8d7f053c5c2bf2a7e - there's no stack depth
check in common paths anymore now. We previously relied on
ExecEvalExpr() being executed somewhere.

We should move towards that model for further routines, but as this is
required for v10, it seems better to only do the necessary (which
already is quite large).

Author: Andres Freund, Tom Lane
Reported-By: Julien Rouhaud
Discussion:
    https://postgr.es/m/22833.1490390175@sss.pgh.pa.us
    https://postgr.es/m/b0af9eaa-130c-60d0-9e4e-7a135b1e0c76@dalibo.com

78 files changed:
src/backend/executor/execProcnode.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeAppend.c
src/backend/executor/nodeBitmapAnd.c
src/backend/executor/nodeBitmapHeapscan.c
src/backend/executor/nodeBitmapIndexscan.c
src/backend/executor/nodeBitmapOr.c
src/backend/executor/nodeCtescan.c
src/backend/executor/nodeCustom.c
src/backend/executor/nodeForeignscan.c
src/backend/executor/nodeFunctionscan.c
src/backend/executor/nodeGather.c
src/backend/executor/nodeGatherMerge.c
src/backend/executor/nodeGroup.c
src/backend/executor/nodeHash.c
src/backend/executor/nodeHashjoin.c
src/backend/executor/nodeIndexonlyscan.c
src/backend/executor/nodeIndexscan.c
src/backend/executor/nodeLimit.c
src/backend/executor/nodeLockRows.c
src/backend/executor/nodeMaterial.c
src/backend/executor/nodeMergeAppend.c
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/nodeNamedtuplestorescan.c
src/backend/executor/nodeNestloop.c
src/backend/executor/nodeProjectSet.c
src/backend/executor/nodeRecursiveunion.c
src/backend/executor/nodeResult.c
src/backend/executor/nodeSamplescan.c
src/backend/executor/nodeSeqscan.c
src/backend/executor/nodeSetOp.c
src/backend/executor/nodeSort.c
src/backend/executor/nodeSubqueryscan.c
src/backend/executor/nodeTableFuncscan.c
src/backend/executor/nodeTidscan.c
src/backend/executor/nodeUnique.c
src/backend/executor/nodeValuesscan.c
src/backend/executor/nodeWindowAgg.c
src/backend/executor/nodeWorktablescan.c
src/include/executor/executor.h
src/include/executor/nodeAgg.h
src/include/executor/nodeAppend.h
src/include/executor/nodeBitmapHeapscan.h
src/include/executor/nodeCtescan.h
src/include/executor/nodeCustom.h
src/include/executor/nodeForeignscan.h
src/include/executor/nodeFunctionscan.h
src/include/executor/nodeGather.h
src/include/executor/nodeGatherMerge.h
src/include/executor/nodeGroup.h
src/include/executor/nodeHash.h
src/include/executor/nodeHashjoin.h
src/include/executor/nodeIndexonlyscan.h
src/include/executor/nodeIndexscan.h
src/include/executor/nodeLimit.h
src/include/executor/nodeLockRows.h
src/include/executor/nodeMaterial.h
src/include/executor/nodeMergeAppend.h
src/include/executor/nodeMergejoin.h
src/include/executor/nodeModifyTable.h
src/include/executor/nodeNamedtuplestorescan.h
src/include/executor/nodeNestloop.h
src/include/executor/nodeProjectSet.h
src/include/executor/nodeRecursiveunion.h
src/include/executor/nodeResult.h
src/include/executor/nodeSamplescan.h
src/include/executor/nodeSeqscan.h
src/include/executor/nodeSetOp.h
src/include/executor/nodeSort.h
src/include/executor/nodeSubqueryscan.h
src/include/executor/nodeTableFuncscan.h
src/include/executor/nodeTidscan.h
src/include/executor/nodeUnique.h
src/include/executor/nodeValuesscan.h
src/include/executor/nodeWindowAgg.h
src/include/executor/nodeWorktablescan.h
src/include/nodes/execnodes.h

index 20fd9f822ed29277b169e48d8ab0450b1848d8db..396920c0a23951e02f0dc11da4f004ed9e280f1b 100644 (file)
  *-------------------------------------------------------------------------
  */
 /*
- *      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
 #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)
 {
-       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))
index 377916dae75e27b2d099048c5b0a74dfb4f17c1e..6a26773a49f248e4c37f8cfa8e8f6545da773025 100644 (file)
@@ -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;
index 58045e05e5d28aac5a758d3c8c3f2980f0123da9..bed9bb8713820c76270a08f4ff273c8e80e21978 100644 (file)
@@ -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;
index e4eb028ff9ccf44b9d1d2d9e2ddfdcc3cc59b0dc..1c5c312c95486f2cb6c42a1b2175f05a9bb8e1c2 100644 (file)
 #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;
 
index cf109d5049f95d437aec944da0c41a29e147c2f8..79f534e4e92b7be2ccc19127700fe0462406953e 100644 (file)
@@ -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;
index 2411a2e5c1a75af3803fd3f3baf0ed7662944995..6feb70f4ae3ed7293675ae56fbcc3f185fa0aeb1 100644 (file)
 #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;
index 4f0ddc6dffda46ecb19ad6f56a1986725efa441b..66a7a89a8b79fdce256ff33dc965b1f519563fd4 100644 (file)
 #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;
 
index bed7949c5a0c0c54a369118955f586b770806ca6..79676ca97875ba46e3a3fef58613255f3c64fccd 100644 (file)
@@ -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;
index fc15974a2d0d98b120375b88f4dd127bdafcfccf..fb7645b1f46da351c574708686be07e1965aeca1 100644 (file)
 #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);
index 9cde112554b2e1801328182b8802d19fb9b3fd27..140e82ef5e4d071381fb716b34a72f912e243363 100644 (file)
@@ -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
index 3217d641d76db026a28980efb21a4d08db202e78..9f87a7e5cdd8a6199c9892871836257fcbcd00af 100644 (file)
@@ -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;
 
        /*
index 5dbe19c056d30737ba0c3ea4866daedb37275384..e8d94ee6f38d062522706aa6832c9d4a89241745 100644 (file)
@@ -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;
index 0aff3798f75ccfb7d4aea28b9c7bd4297d32e8c8..9a81e225100cb673b183ba8e7c9d78b544e9ee9d 100644 (file)
@@ -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;
index fc5e0e59bcc1a9dcd1a6f3e38f1736555f74aed5..ab4ae24a6bc0f9f13eae36cd53c6253dd1f1a0b6 100644 (file)
  *
  *             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;
 
        /*
index fbeb562489cc1a906e134622096fc15b56842951..d10d94ccc264a2ef6d037265796a69abb37aa101 100644 (file)
@@ -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 */
 
index 252960c81c5990f116e34ea8d33bb136efad4f9b..ab1632cc13df46273b9e8a98778d3d198ba029ec 100644 (file)
@@ -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
index e2000764a4646dee16e8d9e3ca979b7f9c0f5678..fe7ba3f1a4f155de068b9c2d934c99e64cc8c6ea 100644 (file)
@@ -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;
 
        /*
index 6704ede9955dd981e9974f1bab0a3cc572725686..404076d5930d6e729acdf6f28e9a52955bc88d10 100644 (file)
@@ -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
index 2ed3523257ff7eca13fe2abdff06531ff7a346ef..ac5a2ff0e601274a1f2868b93527660caef79321 100644 (file)
@@ -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;
 
index dd4e2c5f2f118f0b30e930b31ab5a41f8085b27a..93895600a5dcc8b8d399f11b4213ee42345ef1cf 100644 (file)
  *             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
index 3342949590920af44aff777b55927e8567de2cde..91178f1019868af95df400a33d275943b040a379 100644 (file)
  *
  * ----------------------------------------------------------------
  */
-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
index d41def13506caaf0a7a32544bc942e967e2c2698..6bf490bd700a11ab078ffaa60a2d6a56afbe79df 100644 (file)
@@ -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;
 
index 324b61b8c0c2645fb51284483f5c33ca36bf68ef..925b4cf5535cd6067244e2331d224680e1ce3539 100644 (file)
@@ -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
index 637a582e1ccd5042f6f5d0815b50e6c43013adbf..0dde0ed6eb2bdb91cd34ef28e283c589c9d16336 100644 (file)
@@ -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;
index 62234869abb75e9fe549eadf17d829348e9063af..3a65b9f5dc9d7556da71b35582e42d335093da23 100644 (file)
@@ -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)
index bedc374ef05ed1fad914a4d26aab6d439b38ba75..4447b7c051a04e3809ee150c3f407c361cd8aad8 100644 (file)
  *                        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
index 3b69c7adeea64bf3d69cdc2ee39eab08d8220fd5..d93462c5421cbfc79ba001486738498e11078372 100644 (file)
@@ -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;
 
index 2802fffa2b6ab36c97be8dcc6e3761484b8c8852..a64dd1397a4940506b13300ba414b1a4a18a3924 100644 (file)
@@ -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;
index f007f46784fe0ca39e14a506f0360cabc32a9bb5..4c879d8765564ecd65351484d9b8649fe06cd6e4 100644 (file)
  *             '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;
index b710ef7edf242114bd0275babacb8307e7ab54c9..9c74a836e4071403f18291c671ab8c3e7ea08d13 100644 (file)
@@ -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
index 307df87c82f5c56ad3c38f20ab093f23b6e9206a..5c49d4ca8a9f75fc0d09aa69b903479be7f63c55 100644 (file)
@@ -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
index 56c5643f175d6125671a5023ae84dd460599bece..571cbf86b1d0e8e0b86d673de78a4706194c4c08 100644 (file)
@@ -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;
index 799a4e92042f35cf943a5f2d802181055936e18e..aae4150e2c80c157741ace53428489d07aeeb7a9 100644 (file)
  *               -- 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
index ae184700a671a8d6bc0c90011831402088062bb8..088c92992ece430e926438fe9d80587784a9c60d 100644 (file)
@@ -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
index 2859363fe2c95fbfabe4923fc72901b2a8b1c127..b03d2ef76224d2f4258be3d9e77231f0b110f148 100644 (file)
@@ -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
index c122473bdf882df598c7deb8609a66f0d912c328..0ee76e7d252200aff938708db55511c399b0762a 100644 (file)
@@ -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
index db78c88368b70b959dbf0b157b05b03897b89313..621fdd9b9c132d11eda19201168c037a0ede154f 100644 (file)
  *             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
index 9ee776c4c320c72aad2a1c63ceec9c5eab47f5ed..6eacaed8bb8cf46c7863428f03331ea7e15a85f3 100644 (file)
@@ -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
index 9da35ac506bd2e0fcfcdc5af2292dd545e585ad7..80be46029f4cf0c169c808d238753f1b0dfbbf74 100644 (file)
@@ -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
index d7616be06527534d62537a882e381848eadcbd1e..d5ffadda3e81ad793f507aa2d0ef03659b6302ec 100644 (file)
@@ -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 */
 
        /*
index 59c28b709e665cb95cfa7658e286ca1a2bbc8c90..60326f9d0372425fc8865f3e20cedfa685ea75cd 100644 (file)
@@ -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
  */
index fa11ba93a6bcb0df48a12cb522e4dd6ee0c7b7b6..eff5af9c2a4dfe9acf10135fb08a771049b33dc3 100644 (file)
@@ -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);
 
index ee0b6ad23ddf63dd753b01f35ee2b5ea160666c7..4e38a1380e2507f7af0cba5a8ebdafbd3bc3c0e9 100644 (file)
@@ -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);
 
index f477d1c7720bcf034fd21228e8cccef63e21cd27..c77694cf22ffd1f4b84adb29d6f855f5d3494809 100644 (file)
@@ -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,
index 397bdfdd1ce8d0d5e510049ba39ff4a4025f1c1d..d2fbcbd5868a2f62bf318bce30cdb420f6b147e6 100644 (file)
@@ -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);
 
index e81bcf7f21c523693f991e50c7db8d21b3a92354..a1cc63ae1f35ff89fb9b9f9b66547395cef97cd2 100644 (file)
@@ -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);
index 3ff4ecd8c939485f89b8141df2373f5440e7e340..0b662597d8f449b3b345dc496f3fc88c9d232a45 100644 (file)
@@ -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);
 
index 5e830ebdeae17dff2684e5b85053f5f12dd5a9b8..aaa9d8c31666b228d4abd991001aa4904eea9760 100644 (file)
@@ -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);
 
index b0006934d4ddbc80af60048f2a797e955f233380..189bd70041f9d08b3b818fd6a8ac4071bd92db57 100644 (file)
@@ -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);
index 14b31a086c38d9439609ba015fa20bfccbcfc94f..0154d733129e3f4b4eabb00025ce279a768a8d68 100644 (file)
@@ -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);
index 7358b61707ceff46f8e0ed8fb647bd22c8980c8a..b0d7e312c986820121f6b37b669fe61905699676 100644 (file)
@@ -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);
 
index 8052f27d0b16d2304cb34b81974def7f8fce09c9..3ae556fb6c5cc5355df8327906cd58029008e6da 100644 (file)
@@ -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);
index 541c81edc71474961800951b438092bda39490f6..7469bfbf60ce24ecc47391de095fcc7e0f3b37f4 100644 (file)
@@ -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);
 
index cf227daae041e68ccf77d36ae7087a5f2e05244f..c8a709c26ed472e4ed9be93ace32317ae6a2c5c4 100644 (file)
@@ -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);
index 0118234eca792d852ed1000be9336ec2a6578e0c..1668e347eef58c85b24a93618e1bcb51886e5d80 100644 (file)
@@ -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);
index 7bb20d99786cd7c8832d6eeea53b2a3a225aaa5a..db65b5524cd48ee74d19544c414e1d581b878987 100644 (file)
@@ -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);
 
index 6b90756e4c06f6b2e1288e510c16df761dffa401..c9d05b87f1a973b3e2d5835527a78e8b22ec3a3a 100644 (file)
@@ -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);
 
index f69abbca82b9c15e6e13012de69d0062317c0a34..4b3c2578c9c84b00f1eaab37e30ab46759ebfe43 100644 (file)
@@ -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);
index 3cc6ef549b34f0de53b3fcb1e826ed3132c3ed13..a0ccbae96518a8e332198fd9ea86a65aa8b7fa03 100644 (file)
@@ -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);
 
index 32df25ae8b3636c9bc5336a65374efe3a1b34173..d20e41505db0e277b392497550a4245d34baebed 100644 (file)
@@ -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);
 
index 5a406f236d4dd34918ba4f81a409047edfbb7d89..a2e7af98de8310ccdb9b1994f4380d61cc7b0970 100644 (file)
@@ -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);
 
index 7f72fbe98af5cb8d1bb3e11c78098e8f948ebf3f..395d978f624d6cbee6061aebc201e04f90f2ebbd 100644 (file)
@@ -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);
 
index 8e0fcc1922c9f4d4fadca5e9eb536918dd6034f7..0d6486cc57ac9dfe17080ce4658b341ace35221a 100644 (file)
@@ -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);
 
index 2f6999e8db3a1060b03e9c75ff1e85961ed61376..a0b0521f8d2119609ea60cd14cca601df7bec5e9 100644 (file)
@@ -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);
 
index f0eba05bee969e384b8821ccf490dacce515f64b..e6ce1b47831c676c00fb361984268756aedaaaac 100644 (file)
@@ -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);
 
index 61d3cb2cc2e20a93f79d76c57e4665ec0f76784b..20e0063410eb12d61174e27f9487722f62eec29f 100644 (file)
@@ -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);
index ed06e77e4eebec553392fe7fc9469f8d6fe530e6..607bbd94125a219aa489fdfb6e09a83817230033 100644 (file)
@@ -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);
 
index 06e0686b0b7e96e11064d8de525b2f882c59397f..0fba79f8de6a164f6d11f16f5e9b997d7d481ee1 100644 (file)
@@ -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);
 
index af8597718380bdbb76ff5723026dbf177fcce9d3..c15f94504684b97f15482d12d2a0612c94f5fdd6 100644 (file)
@@ -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);
 
index 1d2b7130b3246775221e75330ad7bb228b811b7d..ed0e9dbb53e21ff33b22faf6f0a1faacaea15fab 100644 (file)
@@ -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);
index c852e2947f96741b7476fc9e22fc2acd2928d830..710e050285ca7ced8efd99603992ad488a3c24c2 100644 (file)
@@ -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);
 
index c58156e99c2e85e986a7043cff16c5564f14143a..c4672c0ac0499d7adb67ce1cdb04d1fb13535f74 100644 (file)
@@ -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);
 
index d07ed7c864122676dbcef654d3685c8d540929cc..e68aaf38290eb6ce4ac5f23ec51e883b5a2f7488 100644 (file)
@@ -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);
 
index 3d0ac9dde16cce8f2f36e23a12c790b4e87a4033..008774ae0f07cd4e7eff356bd889be6626be20c0 100644 (file)
@@ -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);
 
index c28bb1acce657d2613e0e2c0543a290796ed9fca..772a5e9705d634e73d713c40ad79b13fb42ff68e 100644 (file)
@@ -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);
 
index db1ad60677a90c17808db645749212403ca3e428..1c177309ae606be06d629ea836562281dd1421b3 100644 (file)
@@ -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);
 
index c222d9f6b4d2a0991cd388e50f48d5624a638093..df05e75111b1199ba44a7b14188b842f6edb1c5e 100644 (file)
@@ -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);
 
index 85fac8ab91b6f1f22d65f6c5e268af1d9acf38a9..35c28a61431742e365ea3d578324db5424b55d12 100644 (file)
@@ -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 */