Commit cc9f08b6 authored by Andres Freund's avatar Andres Freund

Move ExecProcNode from dispatch to function pointer based model.

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 b8d7f053 - 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
parent d47cfef7
...@@ -17,15 +17,10 @@ ...@@ -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 * NOTES
* This used to be three files. It is now all combined into * This used to be three files. It is now all combined into
* one file so that it is easier to keep ExecInitNode, ExecProcNode, * one file so that it is easier to keep the dispatch routines
* and ExecEndNode in sync when new nodes are added. * in sync when new nodes are added.
* *
* EXAMPLE * EXAMPLE
* Suppose we want the age of the manager of the shoe department and * Suppose we want the age of the manager of the shoe department and
...@@ -122,6 +117,10 @@ ...@@ -122,6 +117,10 @@
#include "miscadmin.h" #include "miscadmin.h"
static TupleTableSlot *ExecProcNodeFirst(PlanState *node);
static TupleTableSlot *ExecProcNodeInstr(PlanState *node);
/* ------------------------------------------------------------------------ /* ------------------------------------------------------------------------
* ExecInitNode * ExecInitNode
* *
...@@ -149,6 +148,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags) ...@@ -149,6 +148,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
if (node == NULL) if (node == NULL)
return 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)) switch (nodeTag(node))
{ {
/* /*
...@@ -364,6 +370,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags) ...@@ -364,6 +370,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
break; 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 * Initialize any initPlans present in this node. The planner put them in
* a separate list for us. * a separate list for us.
...@@ -388,194 +401,50 @@ ExecInitNode(Plan *node, EState *estate, int eflags) ...@@ -388,194 +401,50 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
} }
/* ---------------------------------------------------------------- /*
* ExecProcNode * ExecProcNode wrapper that performs some one-time checks, before calling
* * the relevant node method (possibly via an instrumentation wrapper).
* Execute the given node to return a(nother) tuple.
* ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecProcNode(PlanState *node) ExecProcNodeFirst(PlanState *node)
{ {
TupleTableSlot *result;
if (node->chgParam != NULL) /* something changed */
ExecReScan(node); /* let ReScan handle this */
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 * 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.
*/ */
case T_SeqScanState: check_stack_depth();
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 * 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.
*/ */
case T_NestLoopState: if (node->instrument)
result = ExecNestLoop((NestLoopState *) node); node->ExecProcNode = ExecProcNodeInstr;
break; else
node->ExecProcNode = node->ExecProcNodeReal;
case T_MergeJoinState: return node->ExecProcNode(node);
result = ExecMergeJoin((MergeJoinState *) node); }
break;
case T_HashJoinState:
result = ExecHashJoin((HashJoinState *) node);
break;
/* /*
* materialization nodes * ExecProcNode wrapper that performs instrumentation calls. By keeping
* this a separate function, we avoid overhead in the normal case where
* no instrumentation is wanted.
*/ */
case T_MaterialState: static TupleTableSlot *
result = ExecMaterial((MaterialState *) node); ExecProcNodeInstr(PlanState *node)
break; {
TupleTableSlot *result;
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: InstrStartNode(node->instrument);
result = ExecLockRows((LockRowsState *) node);
break;
case T_LimitState: result = node->ExecProcNodeReal(node);
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; return result;
...@@ -600,6 +469,8 @@ MultiExecProcNode(PlanState *node) ...@@ -600,6 +469,8 @@ MultiExecProcNode(PlanState *node)
{ {
Node *result; Node *result;
check_stack_depth();
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
if (node->chgParam != NULL) /* something changed */ if (node->chgParam != NULL) /* something changed */
...@@ -657,6 +528,13 @@ ExecEndNode(PlanState *node) ...@@ -657,6 +528,13 @@ ExecEndNode(PlanState *node)
if (node == NULL) if (node == NULL)
return; 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) if (node->chgParam != NULL)
{ {
bms_free(node->chgParam); bms_free(node->chgParam);
...@@ -855,6 +733,8 @@ ExecShutdownNode(PlanState *node) ...@@ -855,6 +733,8 @@ ExecShutdownNode(PlanState *node)
if (node == NULL) if (node == NULL)
return false; return false;
check_stack_depth();
planstate_tree_walker(node, ExecShutdownNode, NULL); planstate_tree_walker(node, ExecShutdownNode, NULL);
switch (nodeTag(node)) switch (nodeTag(node))
......
...@@ -2099,9 +2099,10 @@ lookup_hash_entries(AggState *aggstate) ...@@ -2099,9 +2099,10 @@ lookup_hash_entries(AggState *aggstate)
* stored in the expression context to be used when ExecProject evaluates * stored in the expression context to be used when ExecProject evaluates
* the result tuple. * the result tuple.
*/ */
TupleTableSlot * static TupleTableSlot *
ExecAgg(AggState *node) ExecAgg(PlanState *pstate)
{ {
AggState *node = castNode(AggState, pstate);
TupleTableSlot *result = NULL; TupleTableSlot *result = NULL;
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
...@@ -2695,6 +2696,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) ...@@ -2695,6 +2696,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
aggstate = makeNode(AggState); aggstate = makeNode(AggState);
aggstate->ss.ps.plan = (Plan *) node; aggstate->ss.ps.plan = (Plan *) node;
aggstate->ss.ps.state = estate; aggstate->ss.ps.state = estate;
aggstate->ss.ps.ExecProcNode = ExecAgg;
aggstate->aggs = NIL; aggstate->aggs = NIL;
aggstate->numaggs = 0; aggstate->numaggs = 0;
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#include "executor/nodeAppend.h" #include "executor/nodeAppend.h"
#include "miscadmin.h" #include "miscadmin.h"
static TupleTableSlot *ExecAppend(PlanState *pstate);
static bool exec_append_initialize_next(AppendState *appendstate); static bool exec_append_initialize_next(AppendState *appendstate);
...@@ -147,6 +148,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags) ...@@ -147,6 +148,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
*/ */
appendstate->ps.plan = (Plan *) node; appendstate->ps.plan = (Plan *) node;
appendstate->ps.state = estate; appendstate->ps.state = estate;
appendstate->ps.ExecProcNode = ExecAppend;
appendstate->appendplans = appendplanstates; appendstate->appendplans = appendplanstates;
appendstate->as_nplans = nplans; appendstate->as_nplans = nplans;
...@@ -197,9 +199,11 @@ ExecInitAppend(Append *node, EState *estate, int eflags) ...@@ -197,9 +199,11 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
* Handles iteration over multiple subplans. * Handles iteration over multiple subplans.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecAppend(AppendState *node) ExecAppend(PlanState *pstate)
{ {
AppendState *node = castNode(AppendState, pstate);
for (;;) for (;;)
{ {
PlanState *subnode; PlanState *subnode;
......
...@@ -32,6 +32,19 @@ ...@@ -32,6 +32,19 @@
#include "executor/nodeBitmapAnd.h" #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 * ExecInitBitmapAnd
* *
...@@ -63,6 +76,7 @@ ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags) ...@@ -63,6 +76,7 @@ ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags)
*/ */
bitmapandstate->ps.plan = (Plan *) node; bitmapandstate->ps.plan = (Plan *) node;
bitmapandstate->ps.state = estate; bitmapandstate->ps.state = estate;
bitmapandstate->ps.ExecProcNode = ExecBitmapAnd;
bitmapandstate->bitmapplans = bitmapplanstates; bitmapandstate->bitmapplans = bitmapplanstates;
bitmapandstate->nplans = nplans; bitmapandstate->nplans = nplans;
......
...@@ -665,9 +665,11 @@ BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot) ...@@ -665,9 +665,11 @@ BitmapHeapRecheck(BitmapHeapScanState *node, TupleTableSlot *slot)
* ExecBitmapHeapScan(node) * ExecBitmapHeapScan(node)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecBitmapHeapScan(BitmapHeapScanState *node) ExecBitmapHeapScan(PlanState *pstate)
{ {
BitmapHeapScanState *node = castNode(BitmapHeapScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) BitmapHeapNext, (ExecScanAccessMtd) BitmapHeapNext,
(ExecScanRecheckMtd) BitmapHeapRecheck); (ExecScanRecheckMtd) BitmapHeapRecheck);
...@@ -815,6 +817,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) ...@@ -815,6 +817,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
scanstate = makeNode(BitmapHeapScanState); scanstate = makeNode(BitmapHeapScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecBitmapHeapScan;
scanstate->tbm = NULL; scanstate->tbm = NULL;
scanstate->tbmiterator = NULL; scanstate->tbmiterator = NULL;
......
...@@ -28,6 +28,19 @@ ...@@ -28,6 +28,19 @@
#include "utils/memutils.h" #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) * MultiExecBitmapIndexScan(node)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
...@@ -208,6 +221,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) ...@@ -208,6 +221,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
indexstate = makeNode(BitmapIndexScanState); indexstate = makeNode(BitmapIndexScanState);
indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.plan = (Plan *) node;
indexstate->ss.ps.state = estate; indexstate->ss.ps.state = estate;
indexstate->ss.ps.ExecProcNode = ExecBitmapIndexScan;
/* normally we don't make the result bitmap till runtime */ /* normally we don't make the result bitmap till runtime */
indexstate->biss_result = NULL; indexstate->biss_result = NULL;
......
...@@ -33,6 +33,19 @@ ...@@ -33,6 +33,19 @@
#include "miscadmin.h" #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 * ExecInitBitmapOr
* *
...@@ -64,6 +77,7 @@ ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags) ...@@ -64,6 +77,7 @@ ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags)
*/ */
bitmaporstate->ps.plan = (Plan *) node; bitmaporstate->ps.plan = (Plan *) node;
bitmaporstate->ps.state = estate; bitmaporstate->ps.state = estate;
bitmaporstate->ps.ExecProcNode = ExecBitmapOr;
bitmaporstate->bitmapplans = bitmapplanstates; bitmaporstate->bitmapplans = bitmapplanstates;
bitmaporstate->nplans = nplans; bitmaporstate->nplans = nplans;
......
...@@ -149,9 +149,11 @@ CteScanRecheck(CteScanState *node, TupleTableSlot *slot) ...@@ -149,9 +149,11 @@ CteScanRecheck(CteScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecCteScan(CteScanState *node) ExecCteScan(PlanState *pstate)
{ {
CteScanState *node = castNode(CteScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) CteScanNext, (ExecScanAccessMtd) CteScanNext,
(ExecScanRecheckMtd) CteScanRecheck); (ExecScanRecheckMtd) CteScanRecheck);
...@@ -191,6 +193,7 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags) ...@@ -191,6 +193,7 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags)
scanstate = makeNode(CteScanState); scanstate = makeNode(CteScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecCteScan;
scanstate->eflags = eflags; scanstate->eflags = eflags;
scanstate->cte_table = NULL; scanstate->cte_table = NULL;
scanstate->eof_cte = false; scanstate->eof_cte = false;
......
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
#include "utils/memutils.h" #include "utils/memutils.h"
#include "utils/rel.h" #include "utils/rel.h"
static TupleTableSlot *ExecCustomScan(PlanState *pstate);
CustomScanState * CustomScanState *
ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
{ {
...@@ -45,6 +49,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) ...@@ -45,6 +49,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
/* fill up fields of ScanState */ /* fill up fields of ScanState */
css->ss.ps.plan = &cscan->scan.plan; css->ss.ps.plan = &cscan->scan.plan;
css->ss.ps.state = estate; css->ss.ps.state = estate;
css->ss.ps.ExecProcNode = ExecCustomScan;
/* create expression context for node */ /* create expression context for node */
ExecAssignExprContext(estate, &css->ss.ps); ExecAssignExprContext(estate, &css->ss.ps);
...@@ -102,9 +107,11 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) ...@@ -102,9 +107,11 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
return css; return css;
} }
TupleTableSlot * static TupleTableSlot *
ExecCustomScan(CustomScanState *node) ExecCustomScan(PlanState *pstate)
{ {
CustomScanState *node = castNode(CustomScanState, pstate);
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
Assert(node->methods->ExecCustomScan != NULL); Assert(node->methods->ExecCustomScan != NULL);
......
...@@ -113,10 +113,12 @@ ForeignRecheck(ForeignScanState *node, TupleTableSlot *slot) ...@@ -113,10 +113,12 @@ ForeignRecheck(ForeignScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecForeignScan(ForeignScanState *node) ExecForeignScan(PlanState *pstate)
{ {
return ExecScan((ScanState *) node, ForeignScanState *node = castNode(ForeignScanState, pstate);
return ExecScan(&node->ss,
(ExecScanAccessMtd) ForeignNext, (ExecScanAccessMtd) ForeignNext,
(ExecScanRecheckMtd) ForeignRecheck); (ExecScanRecheckMtd) ForeignRecheck);
} }
...@@ -144,6 +146,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) ...@@ -144,6 +146,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
scanstate = makeNode(ForeignScanState); scanstate = makeNode(ForeignScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecForeignScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -262,9 +262,11 @@ FunctionRecheck(FunctionScanState *node, TupleTableSlot *slot) ...@@ -262,9 +262,11 @@ FunctionRecheck(FunctionScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecFunctionScan(FunctionScanState *node) ExecFunctionScan(PlanState *pstate)
{ {
FunctionScanState *node = castNode(FunctionScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) FunctionNext, (ExecScanAccessMtd) FunctionNext,
(ExecScanRecheckMtd) FunctionRecheck); (ExecScanRecheckMtd) FunctionRecheck);
...@@ -299,6 +301,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags) ...@@ -299,6 +301,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
scanstate = makeNode(FunctionScanState); scanstate = makeNode(FunctionScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecFunctionScan;
scanstate->eflags = eflags; scanstate->eflags = eflags;
/* /*
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include "utils/rel.h" #include "utils/rel.h"
static TupleTableSlot *ExecGather(PlanState *pstate);
static TupleTableSlot *gather_getnext(GatherState *gatherstate); static TupleTableSlot *gather_getnext(GatherState *gatherstate);
static HeapTuple gather_readnext(GatherState *gatherstate); static HeapTuple gather_readnext(GatherState *gatherstate);
static void ExecShutdownGatherWorkers(GatherState *node); static void ExecShutdownGatherWorkers(GatherState *node);
...@@ -69,6 +70,7 @@ ExecInitGather(Gather *node, EState *estate, int eflags) ...@@ -69,6 +70,7 @@ ExecInitGather(Gather *node, EState *estate, int eflags)
gatherstate = makeNode(GatherState); gatherstate = makeNode(GatherState);
gatherstate->ps.plan = (Plan *) node; gatherstate->ps.plan = (Plan *) node;
gatherstate->ps.state = estate; gatherstate->ps.state = estate;
gatherstate->ps.ExecProcNode = ExecGather;
gatherstate->need_to_scan_locally = !node->single_copy; gatherstate->need_to_scan_locally = !node->single_copy;
/* /*
...@@ -120,9 +122,10 @@ ExecInitGather(Gather *node, EState *estate, int eflags) ...@@ -120,9 +122,10 @@ ExecInitGather(Gather *node, EState *estate, int eflags)
* the next qualifying tuple. * the next qualifying tuple.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecGather(GatherState *node) ExecGather(PlanState *pstate)
{ {
GatherState *node = castNode(GatherState, pstate);
TupleTableSlot *fslot = node->funnel_slot; TupleTableSlot *fslot = node->funnel_slot;
int i; int i;
TupleTableSlot *slot; TupleTableSlot *slot;
......
...@@ -44,6 +44,7 @@ typedef struct GMReaderTupleBuffer ...@@ -44,6 +44,7 @@ typedef struct GMReaderTupleBuffer
*/ */
#define MAX_TUPLE_STORE 10 #define MAX_TUPLE_STORE 10
static TupleTableSlot *ExecGatherMerge(PlanState *pstate);
static int32 heap_compare_slots(Datum a, Datum b, void *arg); static int32 heap_compare_slots(Datum a, Datum b, void *arg);
static TupleTableSlot *gather_merge_getnext(GatherMergeState *gm_state); static TupleTableSlot *gather_merge_getnext(GatherMergeState *gm_state);
static HeapTuple gm_readnext_tuple(GatherMergeState *gm_state, int nreader, static HeapTuple gm_readnext_tuple(GatherMergeState *gm_state, int nreader,
...@@ -75,6 +76,7 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) ...@@ -75,6 +76,7 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
gm_state = makeNode(GatherMergeState); gm_state = makeNode(GatherMergeState);
gm_state->ps.plan = (Plan *) node; gm_state->ps.plan = (Plan *) node;
gm_state->ps.state = estate; gm_state->ps.state = estate;
gm_state->ps.ExecProcNode = ExecGatherMerge;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
...@@ -157,9 +159,10 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) ...@@ -157,9 +159,10 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
* the next qualifying tuple. * the next qualifying tuple.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecGatherMerge(GatherMergeState *node) ExecGatherMerge(PlanState *pstate)
{ {
GatherMergeState *node = castNode(GatherMergeState, pstate);
TupleTableSlot *slot; TupleTableSlot *slot;
ExprContext *econtext; ExprContext *econtext;
int i; int i;
......
...@@ -32,9 +32,10 @@ ...@@ -32,9 +32,10 @@
* *
* Return one tuple for each group of matching input tuples. * Return one tuple for each group of matching input tuples.
*/ */
TupleTableSlot * static TupleTableSlot *
ExecGroup(GroupState *node) ExecGroup(PlanState *pstate)
{ {
GroupState *node = castNode(GroupState, pstate);
ExprContext *econtext; ExprContext *econtext;
int numCols; int numCols;
AttrNumber *grpColIdx; AttrNumber *grpColIdx;
...@@ -175,6 +176,7 @@ ExecInitGroup(Group *node, EState *estate, int eflags) ...@@ -175,6 +176,7 @@ ExecInitGroup(Group *node, EState *estate, int eflags)
grpstate = makeNode(GroupState); grpstate = makeNode(GroupState);
grpstate->ss.ps.plan = (Plan *) node; grpstate->ss.ps.plan = (Plan *) node;
grpstate->ss.ps.state = estate; grpstate->ss.ps.state = estate;
grpstate->ss.ps.ExecProcNode = ExecGroup;
grpstate->grp_done = FALSE; grpstate->grp_done = FALSE;
/* /*
......
...@@ -56,8 +56,8 @@ static void *dense_alloc(HashJoinTable hashtable, Size size); ...@@ -56,8 +56,8 @@ static void *dense_alloc(HashJoinTable hashtable, Size size);
* stub for pro forma compliance * stub for pro forma compliance
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecHash(HashState *node) ExecHash(PlanState *pstate)
{ {
elog(ERROR, "Hash node does not support ExecProcNode call convention"); elog(ERROR, "Hash node does not support ExecProcNode call convention");
return NULL; return NULL;
...@@ -172,6 +172,7 @@ ExecInitHash(Hash *node, EState *estate, int eflags) ...@@ -172,6 +172,7 @@ ExecInitHash(Hash *node, EState *estate, int eflags)
hashstate = makeNode(HashState); hashstate = makeNode(HashState);
hashstate->ps.plan = (Plan *) node; hashstate->ps.plan = (Plan *) node;
hashstate->ps.state = estate; hashstate->ps.state = estate;
hashstate->ps.ExecProcNode = ExecHash;
hashstate->hashtable = NULL; hashstate->hashtable = NULL;
hashstate->hashkeys = NIL; /* will be set by parent HashJoin */ hashstate->hashkeys = NIL; /* will be set by parent HashJoin */
......
...@@ -58,9 +58,10 @@ static bool ExecHashJoinNewBatch(HashJoinState *hjstate); ...@@ -58,9 +58,10 @@ static bool ExecHashJoinNewBatch(HashJoinState *hjstate);
* the other one is "outer". * the other one is "outer".
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * /* return: a tuple or NULL */ static TupleTableSlot * /* return: a tuple or NULL */
ExecHashJoin(HashJoinState *node) ExecHashJoin(PlanState *pstate)
{ {
HashJoinState *node = castNode(HashJoinState, pstate);
PlanState *outerNode; PlanState *outerNode;
HashState *hashNode; HashState *hashNode;
ExprState *joinqual; ExprState *joinqual;
...@@ -399,6 +400,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) ...@@ -399,6 +400,7 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags)
hjstate = makeNode(HashJoinState); hjstate = makeNode(HashJoinState);
hjstate->js.ps.plan = (Plan *) node; hjstate->js.ps.plan = (Plan *) node;
hjstate->js.ps.state = estate; hjstate->js.ps.state = estate;
hjstate->js.ps.ExecProcNode = ExecHashJoin;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -306,9 +306,11 @@ IndexOnlyRecheck(IndexOnlyScanState *node, TupleTableSlot *slot) ...@@ -306,9 +306,11 @@ IndexOnlyRecheck(IndexOnlyScanState *node, TupleTableSlot *slot)
* ExecIndexOnlyScan(node) * ExecIndexOnlyScan(node)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecIndexOnlyScan(IndexOnlyScanState *node) ExecIndexOnlyScan(PlanState *pstate)
{ {
IndexOnlyScanState *node = castNode(IndexOnlyScanState, pstate);
/* /*
* If we have runtime keys and they've not already been set up, do it now. * 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) ...@@ -476,6 +478,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
indexstate = makeNode(IndexOnlyScanState); indexstate = makeNode(IndexOnlyScanState);
indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.plan = (Plan *) node;
indexstate->ss.ps.state = estate; indexstate->ss.ps.state = estate;
indexstate->ss.ps.ExecProcNode = ExecIndexOnlyScan;
indexstate->ioss_HeapFetches = 0; indexstate->ioss_HeapFetches = 0;
/* /*
......
...@@ -542,9 +542,11 @@ reorderqueue_pop(IndexScanState *node) ...@@ -542,9 +542,11 @@ reorderqueue_pop(IndexScanState *node)
* ExecIndexScan(node) * ExecIndexScan(node)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecIndexScan(IndexScanState *node) ExecIndexScan(PlanState *pstate)
{ {
IndexScanState *node = castNode(IndexScanState, pstate);
/* /*
* If we have runtime keys and they've not already been set up, do it now. * 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) ...@@ -910,6 +912,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
indexstate = makeNode(IndexScanState); indexstate = makeNode(IndexScanState);
indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.plan = (Plan *) node;
indexstate->ss.ps.state = estate; indexstate->ss.ps.state = estate;
indexstate->ss.ps.ExecProcNode = ExecIndexScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -37,9 +37,10 @@ static void pass_down_bound(LimitState *node, PlanState *child_node); ...@@ -37,9 +37,10 @@ static void pass_down_bound(LimitState *node, PlanState *child_node);
* filtering on the stream of tuples returned by a subplan. * filtering on the stream of tuples returned by a subplan.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * /* return: a tuple or NULL */ static TupleTableSlot * /* return: a tuple or NULL */
ExecLimit(LimitState *node) ExecLimit(PlanState *pstate)
{ {
LimitState *node = castNode(LimitState, pstate);
ScanDirection direction; ScanDirection direction;
TupleTableSlot *slot; TupleTableSlot *slot;
PlanState *outerPlan; PlanState *outerPlan;
...@@ -378,6 +379,7 @@ ExecInitLimit(Limit *node, EState *estate, int eflags) ...@@ -378,6 +379,7 @@ ExecInitLimit(Limit *node, EState *estate, int eflags)
limitstate = makeNode(LimitState); limitstate = makeNode(LimitState);
limitstate->ps.plan = (Plan *) node; limitstate->ps.plan = (Plan *) node;
limitstate->ps.state = estate; limitstate->ps.state = estate;
limitstate->ps.ExecProcNode = ExecLimit;
limitstate->lstate = LIMIT_INITIAL; limitstate->lstate = LIMIT_INITIAL;
......
...@@ -36,9 +36,10 @@ ...@@ -36,9 +36,10 @@
* ExecLockRows * ExecLockRows
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * /* return: a tuple or NULL */ static TupleTableSlot * /* return: a tuple or NULL */
ExecLockRows(LockRowsState *node) ExecLockRows(PlanState *pstate)
{ {
LockRowsState *node = castNode(LockRowsState, pstate);
TupleTableSlot *slot; TupleTableSlot *slot;
EState *estate; EState *estate;
PlanState *outerPlan; PlanState *outerPlan;
...@@ -364,6 +365,7 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags) ...@@ -364,6 +365,7 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags)
lrstate = makeNode(LockRowsState); lrstate = makeNode(LockRowsState);
lrstate->ps.plan = (Plan *) node; lrstate->ps.plan = (Plan *) node;
lrstate->ps.state = estate; lrstate->ps.state = estate;
lrstate->ps.ExecProcNode = ExecLockRows;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -35,9 +35,10 @@ ...@@ -35,9 +35,10 @@
* *
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * /* result tuple from subplan */ static TupleTableSlot * /* result tuple from subplan */
ExecMaterial(MaterialState *node) ExecMaterial(PlanState *pstate)
{ {
MaterialState *node = castNode(MaterialState, pstate);
EState *estate; EState *estate;
ScanDirection dir; ScanDirection dir;
bool forward; bool forward;
...@@ -173,6 +174,7 @@ ExecInitMaterial(Material *node, EState *estate, int eflags) ...@@ -173,6 +174,7 @@ ExecInitMaterial(Material *node, EState *estate, int eflags)
matstate = makeNode(MaterialState); matstate = makeNode(MaterialState);
matstate->ss.ps.plan = (Plan *) node; matstate->ss.ps.plan = (Plan *) node;
matstate->ss.ps.state = estate; matstate->ss.ps.state = estate;
matstate->ss.ps.ExecProcNode = ExecMaterial;
/* /*
* We must have a tuplestore buffering the subplan output to do backward * We must have a tuplestore buffering the subplan output to do backward
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
*/ */
typedef int32 SlotNumber; typedef int32 SlotNumber;
static TupleTableSlot *ExecMergeAppend(PlanState *pstate);
static int heap_compare_slots(Datum a, Datum b, void *arg); static int heap_compare_slots(Datum a, Datum b, void *arg);
...@@ -89,6 +90,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) ...@@ -89,6 +90,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
*/ */
mergestate->ps.plan = (Plan *) node; mergestate->ps.plan = (Plan *) node;
mergestate->ps.state = estate; mergestate->ps.state = estate;
mergestate->ps.ExecProcNode = ExecMergeAppend;
mergestate->mergeplans = mergeplanstates; mergestate->mergeplans = mergeplanstates;
mergestate->ms_nplans = nplans; mergestate->ms_nplans = nplans;
...@@ -169,9 +171,10 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) ...@@ -169,9 +171,10 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
* Handles iteration over multiple subplans. * Handles iteration over multiple subplans.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecMergeAppend(MergeAppendState *node) ExecMergeAppend(PlanState *pstate)
{ {
MergeAppendState *node = castNode(MergeAppendState, pstate);
TupleTableSlot *result; TupleTableSlot *result;
SlotNumber i; SlotNumber i;
......
...@@ -596,9 +596,10 @@ ExecMergeTupleDump(MergeJoinState *mergestate) ...@@ -596,9 +596,10 @@ ExecMergeTupleDump(MergeJoinState *mergestate)
* ExecMergeJoin * ExecMergeJoin
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecMergeJoin(MergeJoinState *node) ExecMergeJoin(PlanState *pstate)
{ {
MergeJoinState *node = castNode(MergeJoinState, pstate);
ExprState *joinqual; ExprState *joinqual;
ExprState *otherqual; ExprState *otherqual;
bool qualResult; bool qualResult;
...@@ -1448,6 +1449,7 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) ...@@ -1448,6 +1449,7 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
mergestate = makeNode(MergeJoinState); mergestate = makeNode(MergeJoinState);
mergestate->js.ps.plan = (Plan *) node; mergestate->js.ps.plan = (Plan *) node;
mergestate->js.ps.state = estate; mergestate->js.ps.state = estate;
mergestate->js.ps.ExecProcNode = ExecMergeJoin;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -1535,9 +1535,10 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) ...@@ -1535,9 +1535,10 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate)
* if needed. * if needed.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecModifyTable(ModifyTableState *node) ExecModifyTable(PlanState *pstate)
{ {
ModifyTableState *node = castNode(ModifyTableState, pstate);
EState *estate = node->ps.state; EState *estate = node->ps.state;
CmdType operation = node->operation; CmdType operation = node->operation;
ResultRelInfo *saved_resultRelInfo; ResultRelInfo *saved_resultRelInfo;
...@@ -1806,6 +1807,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) ...@@ -1806,6 +1807,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
mtstate = makeNode(ModifyTableState); mtstate = makeNode(ModifyTableState);
mtstate->ps.plan = (Plan *) node; mtstate->ps.plan = (Plan *) node;
mtstate->ps.state = estate; mtstate->ps.state = estate;
mtstate->ps.ExecProcNode = ExecModifyTable;
mtstate->operation = operation; mtstate->operation = operation;
mtstate->canSetTag = node->canSetTag; mtstate->canSetTag = node->canSetTag;
......
...@@ -63,9 +63,11 @@ NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot) ...@@ -63,9 +63,11 @@ NamedTuplestoreScanRecheck(NamedTuplestoreScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecNamedTuplestoreScan(NamedTuplestoreScanState *node) ExecNamedTuplestoreScan(PlanState *pstate)
{ {
NamedTuplestoreScanState *node = castNode(NamedTuplestoreScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) NamedTuplestoreScanNext, (ExecScanAccessMtd) NamedTuplestoreScanNext,
(ExecScanRecheckMtd) NamedTuplestoreScanRecheck); (ExecScanRecheckMtd) NamedTuplestoreScanRecheck);
...@@ -97,6 +99,7 @@ ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflag ...@@ -97,6 +99,7 @@ ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflag
scanstate = makeNode(NamedTuplestoreScanState); scanstate = makeNode(NamedTuplestoreScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecNamedTuplestoreScan;
enr = get_ENR(estate->es_queryEnv, node->enrname); enr = get_ENR(estate->es_queryEnv, node->enrname);
if (!enr) if (!enr)
......
...@@ -57,9 +57,10 @@ ...@@ -57,9 +57,10 @@
* are prepared to return the first tuple. * are prepared to return the first tuple.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecNestLoop(NestLoopState *node) ExecNestLoop(PlanState *pstate)
{ {
NestLoopState *node = castNode(NestLoopState, pstate);
NestLoop *nl; NestLoop *nl;
PlanState *innerPlan; PlanState *innerPlan;
PlanState *outerPlan; PlanState *outerPlan;
...@@ -275,6 +276,7 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags) ...@@ -275,6 +276,7 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
nlstate = makeNode(NestLoopState); nlstate = makeNode(NestLoopState);
nlstate->js.ps.plan = (Plan *) node; nlstate->js.ps.plan = (Plan *) node;
nlstate->js.ps.state = estate; nlstate->js.ps.state = estate;
nlstate->js.ps.ExecProcNode = ExecNestLoop;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -39,9 +39,10 @@ static TupleTableSlot *ExecProjectSRF(ProjectSetState *node, bool continuing); ...@@ -39,9 +39,10 @@ static TupleTableSlot *ExecProjectSRF(ProjectSetState *node, bool continuing);
* returning functions). * returning functions).
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecProjectSet(ProjectSetState *node) ExecProjectSet(PlanState *pstate)
{ {
ProjectSetState *node = castNode(ProjectSetState, pstate);
TupleTableSlot *outerTupleSlot; TupleTableSlot *outerTupleSlot;
TupleTableSlot *resultSlot; TupleTableSlot *resultSlot;
PlanState *outerPlan; PlanState *outerPlan;
...@@ -215,6 +216,7 @@ ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags) ...@@ -215,6 +216,7 @@ ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags)
state = makeNode(ProjectSetState); state = makeNode(ProjectSetState);
state->ps.plan = (Plan *) node; state->ps.plan = (Plan *) node;
state->ps.state = estate; state->ps.state = estate;
state->ps.ExecProcNode = ExecProjectSet;
state->pending_srf_tuples = false; state->pending_srf_tuples = false;
......
...@@ -66,9 +66,10 @@ build_hash_table(RecursiveUnionState *rustate) ...@@ -66,9 +66,10 @@ build_hash_table(RecursiveUnionState *rustate)
* 2.6 go back to 2.2 * 2.6 go back to 2.2
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecRecursiveUnion(RecursiveUnionState *node) ExecRecursiveUnion(PlanState *pstate)
{ {
RecursiveUnionState *node = castNode(RecursiveUnionState, pstate);
PlanState *outerPlan = outerPlanState(node); PlanState *outerPlan = outerPlanState(node);
PlanState *innerPlan = innerPlanState(node); PlanState *innerPlan = innerPlanState(node);
RecursiveUnion *plan = (RecursiveUnion *) node->ps.plan; RecursiveUnion *plan = (RecursiveUnion *) node->ps.plan;
...@@ -172,6 +173,7 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags) ...@@ -172,6 +173,7 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
rustate = makeNode(RecursiveUnionState); rustate = makeNode(RecursiveUnionState);
rustate->ps.plan = (Plan *) node; rustate->ps.plan = (Plan *) node;
rustate->ps.state = estate; rustate->ps.state = estate;
rustate->ps.ExecProcNode = ExecRecursiveUnion;
rustate->eqfunctions = NULL; rustate->eqfunctions = NULL;
rustate->hashfunctions = NULL; rustate->hashfunctions = NULL;
......
...@@ -64,9 +64,10 @@ ...@@ -64,9 +64,10 @@
* 'nil' if the constant qualification is not satisfied. * 'nil' if the constant qualification is not satisfied.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecResult(ResultState *node) ExecResult(PlanState *pstate)
{ {
ResultState *node = castNode(ResultState, pstate);
TupleTableSlot *outerTupleSlot; TupleTableSlot *outerTupleSlot;
PlanState *outerPlan; PlanState *outerPlan;
ExprContext *econtext; ExprContext *econtext;
...@@ -191,6 +192,7 @@ ExecInitResult(Result *node, EState *estate, int eflags) ...@@ -191,6 +192,7 @@ ExecInitResult(Result *node, EState *estate, int eflags)
resstate = makeNode(ResultState); resstate = makeNode(ResultState);
resstate->ps.plan = (Plan *) node; resstate->ps.plan = (Plan *) node;
resstate->ps.state = estate; resstate->ps.state = estate;
resstate->ps.ExecProcNode = ExecResult;
resstate->rs_done = false; resstate->rs_done = false;
resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true; resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
......
...@@ -96,10 +96,12 @@ SampleRecheck(SampleScanState *node, TupleTableSlot *slot) ...@@ -96,10 +96,12 @@ SampleRecheck(SampleScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecSampleScan(SampleScanState *node) ExecSampleScan(PlanState *pstate)
{ {
return ExecScan((ScanState *) node, SampleScanState *node = castNode(SampleScanState, pstate);
return ExecScan(&node->ss,
(ExecScanAccessMtd) SampleNext, (ExecScanAccessMtd) SampleNext,
(ExecScanRecheckMtd) SampleRecheck); (ExecScanRecheckMtd) SampleRecheck);
} }
...@@ -153,6 +155,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags) ...@@ -153,6 +155,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags)
scanstate = makeNode(SampleScanState); scanstate = makeNode(SampleScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecSampleScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -121,10 +121,12 @@ SeqRecheck(SeqScanState *node, TupleTableSlot *slot) ...@@ -121,10 +121,12 @@ SeqRecheck(SeqScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecSeqScan(SeqScanState *node) ExecSeqScan(PlanState *pstate)
{ {
return ExecScan((ScanState *) node, SeqScanState *node = castNode(SeqScanState, pstate);
return ExecScan(&node->ss,
(ExecScanAccessMtd) SeqNext, (ExecScanAccessMtd) SeqNext,
(ExecScanRecheckMtd) SeqRecheck); (ExecScanRecheckMtd) SeqRecheck);
} }
...@@ -177,6 +179,7 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags) ...@@ -177,6 +179,7 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags)
scanstate = makeNode(SeqScanState); scanstate = makeNode(SeqScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecSeqScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -180,9 +180,10 @@ set_output_count(SetOpState *setopstate, SetOpStatePerGroup pergroup) ...@@ -180,9 +180,10 @@ set_output_count(SetOpState *setopstate, SetOpStatePerGroup pergroup)
* ExecSetOp * ExecSetOp
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * /* return: a tuple or NULL */ static TupleTableSlot * /* return: a tuple or NULL */
ExecSetOp(SetOpState *node) ExecSetOp(PlanState *pstate)
{ {
SetOpState *node = castNode(SetOpState, pstate);
SetOp *plannode = (SetOp *) node->ps.plan; SetOp *plannode = (SetOp *) node->ps.plan;
TupleTableSlot *resultTupleSlot = node->ps.ps_ResultTupleSlot; TupleTableSlot *resultTupleSlot = node->ps.ps_ResultTupleSlot;
...@@ -485,6 +486,7 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags) ...@@ -485,6 +486,7 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags)
setopstate = makeNode(SetOpState); setopstate = makeNode(SetOpState);
setopstate->ps.plan = (Plan *) node; setopstate->ps.plan = (Plan *) node;
setopstate->ps.state = estate; setopstate->ps.state = estate;
setopstate->ps.ExecProcNode = ExecSetOp;
setopstate->eqfunctions = NULL; setopstate->eqfunctions = NULL;
setopstate->hashfunctions = NULL; setopstate->hashfunctions = NULL;
......
...@@ -35,9 +35,10 @@ ...@@ -35,9 +35,10 @@
* -- the outer child is prepared to return the first tuple. * -- the outer child is prepared to return the first tuple.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecSort(SortState *node) ExecSort(PlanState *pstate)
{ {
SortState *node = castNode(SortState, pstate);
EState *estate; EState *estate;
ScanDirection dir; ScanDirection dir;
Tuplesortstate *tuplesortstate; Tuplesortstate *tuplesortstate;
...@@ -165,6 +166,7 @@ ExecInitSort(Sort *node, EState *estate, int eflags) ...@@ -165,6 +166,7 @@ ExecInitSort(Sort *node, EState *estate, int eflags)
sortstate = makeNode(SortState); sortstate = makeNode(SortState);
sortstate->ss.ps.plan = (Plan *) node; sortstate->ss.ps.plan = (Plan *) node;
sortstate->ss.ps.state = estate; sortstate->ss.ps.state = estate;
sortstate->ss.ps.ExecProcNode = ExecSort;
/* /*
* We must have random access to the sort output to do backward scan or * We must have random access to the sort output to do backward scan or
......
...@@ -79,9 +79,11 @@ SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot) ...@@ -79,9 +79,11 @@ SubqueryRecheck(SubqueryScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecSubqueryScan(SubqueryScanState *node) ExecSubqueryScan(PlanState *pstate)
{ {
SubqueryScanState *node = castNode(SubqueryScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) SubqueryNext, (ExecScanAccessMtd) SubqueryNext,
(ExecScanRecheckMtd) SubqueryRecheck); (ExecScanRecheckMtd) SubqueryRecheck);
...@@ -109,6 +111,7 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags) ...@@ -109,6 +111,7 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
subquerystate = makeNode(SubqueryScanState); subquerystate = makeNode(SubqueryScanState);
subquerystate->ss.ps.plan = (Plan *) node; subquerystate->ss.ps.plan = (Plan *) node;
subquerystate->ss.ps.state = estate; subquerystate->ss.ps.state = estate;
subquerystate->ss.ps.ExecProcNode = ExecSubqueryScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -93,9 +93,11 @@ TableFuncRecheck(TableFuncScanState *node, TupleTableSlot *slot) ...@@ -93,9 +93,11 @@ TableFuncRecheck(TableFuncScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecTableFuncScan(TableFuncScanState *node) ExecTableFuncScan(PlanState *pstate)
{ {
TableFuncScanState *node = castNode(TableFuncScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) TableFuncNext, (ExecScanAccessMtd) TableFuncNext,
(ExecScanRecheckMtd) TableFuncRecheck); (ExecScanRecheckMtd) TableFuncRecheck);
...@@ -128,6 +130,7 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags) ...@@ -128,6 +130,7 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags)
scanstate = makeNode(TableFuncScanState); scanstate = makeNode(TableFuncScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecTableFuncScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -445,9 +445,11 @@ TidRecheck(TidScanState *node, TupleTableSlot *slot) ...@@ -445,9 +445,11 @@ TidRecheck(TidScanState *node, TupleTableSlot *slot)
* -- tidPtr is -1. * -- tidPtr is -1.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecTidScan(TidScanState *node) ExecTidScan(PlanState *pstate)
{ {
TidScanState *node = castNode(TidScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) TidNext, (ExecScanAccessMtd) TidNext,
(ExecScanRecheckMtd) TidRecheck); (ExecScanRecheckMtd) TidRecheck);
...@@ -519,6 +521,7 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags) ...@@ -519,6 +521,7 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags)
tidstate = makeNode(TidScanState); tidstate = makeNode(TidScanState);
tidstate->ss.ps.plan = (Plan *) node; tidstate->ss.ps.plan = (Plan *) node;
tidstate->ss.ps.state = estate; tidstate->ss.ps.state = estate;
tidstate->ss.ps.ExecProcNode = ExecTidScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -43,9 +43,10 @@ ...@@ -43,9 +43,10 @@
* ExecUnique * ExecUnique
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * /* return: a tuple or NULL */ static TupleTableSlot * /* return: a tuple or NULL */
ExecUnique(UniqueState *node) ExecUnique(PlanState *pstate)
{ {
UniqueState *node = castNode(UniqueState, pstate);
Unique *plannode = (Unique *) node->ps.plan; Unique *plannode = (Unique *) node->ps.plan;
TupleTableSlot *resultTupleSlot; TupleTableSlot *resultTupleSlot;
TupleTableSlot *slot; TupleTableSlot *slot;
...@@ -125,6 +126,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags) ...@@ -125,6 +126,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags)
uniquestate = makeNode(UniqueState); uniquestate = makeNode(UniqueState);
uniquestate->ps.plan = (Plan *) node; uniquestate->ps.plan = (Plan *) node;
uniquestate->ps.state = estate; uniquestate->ps.state = estate;
uniquestate->ps.ExecProcNode = ExecUnique;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -185,9 +185,11 @@ ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot) ...@@ -185,9 +185,11 @@ ValuesRecheck(ValuesScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecValuesScan(ValuesScanState *node) ExecValuesScan(PlanState *pstate)
{ {
ValuesScanState *node = castNode(ValuesScanState, pstate);
return ExecScan(&node->ss, return ExecScan(&node->ss,
(ExecScanAccessMtd) ValuesNext, (ExecScanAccessMtd) ValuesNext,
(ExecScanRecheckMtd) ValuesRecheck); (ExecScanRecheckMtd) ValuesRecheck);
...@@ -218,6 +220,7 @@ ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags) ...@@ -218,6 +220,7 @@ ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags)
scanstate = makeNode(ValuesScanState); scanstate = makeNode(ValuesScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecValuesScan;
/* /*
* Miscellaneous initialization * Miscellaneous initialization
......
...@@ -1587,9 +1587,10 @@ update_frametailpos(WindowObject winobj, TupleTableSlot *slot) ...@@ -1587,9 +1587,10 @@ update_frametailpos(WindowObject winobj, TupleTableSlot *slot)
* returned rows is exactly the same as its outer subplan's result. * returned rows is exactly the same as its outer subplan's result.
* ----------------- * -----------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecWindowAgg(WindowAggState *winstate) ExecWindowAgg(PlanState *pstate)
{ {
WindowAggState *winstate = castNode(WindowAggState, pstate);
ExprContext *econtext; ExprContext *econtext;
int i; int i;
int numfuncs; int numfuncs;
...@@ -1790,6 +1791,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) ...@@ -1790,6 +1791,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
winstate = makeNode(WindowAggState); winstate = makeNode(WindowAggState);
winstate->ss.ps.plan = (Plan *) node; winstate->ss.ps.plan = (Plan *) node;
winstate->ss.ps.state = estate; winstate->ss.ps.state = estate;
winstate->ss.ps.ExecProcNode = ExecWindowAgg;
/* /*
* Create expression contexts. We need two, one for per-input-tuple * Create expression contexts. We need two, one for per-input-tuple
......
...@@ -77,9 +77,11 @@ WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot) ...@@ -77,9 +77,11 @@ WorkTableScanRecheck(WorkTableScanState *node, TupleTableSlot *slot)
* access method functions. * access method functions.
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
TupleTableSlot * static TupleTableSlot *
ExecWorkTableScan(WorkTableScanState *node) ExecWorkTableScan(PlanState *pstate)
{ {
WorkTableScanState *node = castNode(WorkTableScanState, pstate);
/* /*
* On the first call, find the ancestor RecursiveUnion's state via the * 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 * 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) ...@@ -144,6 +146,7 @@ ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags)
scanstate = makeNode(WorkTableScanState); scanstate = makeNode(WorkTableScanState);
scanstate->ss.ps.plan = (Plan *) node; scanstate->ss.ps.plan = (Plan *) node;
scanstate->ss.ps.state = estate; scanstate->ss.ps.state = estate;
scanstate->ss.ps.ExecProcNode = ExecWorkTableScan;
scanstate->rustate = NULL; /* we'll set this later */ scanstate->rustate = NULL; /* we'll set this later */
/* /*
......
...@@ -225,14 +225,31 @@ extern void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate); ...@@ -225,14 +225,31 @@ extern void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate);
extern void EvalPlanQualEnd(EPQState *epqstate); 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 PlanState *ExecInitNode(Plan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecProcNode(PlanState *node);
extern Node *MultiExecProcNode(PlanState *node); extern Node *MultiExecProcNode(PlanState *node);
extern void ExecEndNode(PlanState *node); extern void ExecEndNode(PlanState *node);
extern bool ExecShutdownNode(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 * prototypes from functions in execExpr.c
*/ */
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags); extern AggState *ExecInitAgg(Agg *node, EState *estate, int eflags);
extern TupleTableSlot *ExecAgg(AggState *node);
extern void ExecEndAgg(AggState *node); extern void ExecEndAgg(AggState *node);
extern void ExecReScanAgg(AggState *node); extern void ExecReScanAgg(AggState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern AppendState *ExecInitAppend(Append *node, EState *estate, int eflags); extern AppendState *ExecInitAppend(Append *node, EState *estate, int eflags);
extern TupleTableSlot *ExecAppend(AppendState *node);
extern void ExecEndAppend(AppendState *node); extern void ExecEndAppend(AppendState *node);
extern void ExecReScanAppend(AppendState *node); extern void ExecReScanAppend(AppendState *node);
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "access/parallel.h" #include "access/parallel.h"
extern BitmapHeapScanState *ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags); extern BitmapHeapScanState *ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecBitmapHeapScan(BitmapHeapScanState *node);
extern void ExecEndBitmapHeapScan(BitmapHeapScanState *node); extern void ExecEndBitmapHeapScan(BitmapHeapScanState *node);
extern void ExecReScanBitmapHeapScan(BitmapHeapScanState *node); extern void ExecReScanBitmapHeapScan(BitmapHeapScanState *node);
extern void ExecBitmapHeapEstimate(BitmapHeapScanState *node, extern void ExecBitmapHeapEstimate(BitmapHeapScanState *node,
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern CteScanState *ExecInitCteScan(CteScan *node, EState *estate, int eflags); extern CteScanState *ExecInitCteScan(CteScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecCteScan(CteScanState *node);
extern void ExecEndCteScan(CteScanState *node); extern void ExecEndCteScan(CteScanState *node);
extern void ExecReScanCteScan(CteScanState *node); extern void ExecReScanCteScan(CteScanState *node);
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
*/ */
extern CustomScanState *ExecInitCustomScan(CustomScan *custom_scan, extern CustomScanState *ExecInitCustomScan(CustomScan *custom_scan,
EState *estate, int eflags); EState *estate, int eflags);
extern TupleTableSlot *ExecCustomScan(CustomScanState *node);
extern void ExecEndCustomScan(CustomScanState *node); extern void ExecEndCustomScan(CustomScanState *node);
extern void ExecReScanCustomScan(CustomScanState *node); extern void ExecReScanCustomScan(CustomScanState *node);
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern ForeignScanState *ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags); extern ForeignScanState *ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecForeignScan(ForeignScanState *node);
extern void ExecEndForeignScan(ForeignScanState *node); extern void ExecEndForeignScan(ForeignScanState *node);
extern void ExecReScanForeignScan(ForeignScanState *node); extern void ExecReScanForeignScan(ForeignScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern FunctionScanState *ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags); extern FunctionScanState *ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecFunctionScan(FunctionScanState *node);
extern void ExecEndFunctionScan(FunctionScanState *node); extern void ExecEndFunctionScan(FunctionScanState *node);
extern void ExecReScanFunctionScan(FunctionScanState *node); extern void ExecReScanFunctionScan(FunctionScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern GatherState *ExecInitGather(Gather *node, EState *estate, int eflags); extern GatherState *ExecInitGather(Gather *node, EState *estate, int eflags);
extern TupleTableSlot *ExecGather(GatherState *node);
extern void ExecEndGather(GatherState *node); extern void ExecEndGather(GatherState *node);
extern void ExecShutdownGather(GatherState *node); extern void ExecShutdownGather(GatherState *node);
extern void ExecReScanGather(GatherState *node); extern void ExecReScanGather(GatherState *node);
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
extern GatherMergeState *ExecInitGatherMerge(GatherMerge *node, extern GatherMergeState *ExecInitGatherMerge(GatherMerge *node,
EState *estate, EState *estate,
int eflags); int eflags);
extern TupleTableSlot *ExecGatherMerge(GatherMergeState *node);
extern void ExecEndGatherMerge(GatherMergeState *node); extern void ExecEndGatherMerge(GatherMergeState *node);
extern void ExecReScanGatherMerge(GatherMergeState *node); extern void ExecReScanGatherMerge(GatherMergeState *node);
extern void ExecShutdownGatherMerge(GatherMergeState *node); extern void ExecShutdownGatherMerge(GatherMergeState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern GroupState *ExecInitGroup(Group *node, EState *estate, int eflags); extern GroupState *ExecInitGroup(Group *node, EState *estate, int eflags);
extern TupleTableSlot *ExecGroup(GroupState *node);
extern void ExecEndGroup(GroupState *node); extern void ExecEndGroup(GroupState *node);
extern void ExecReScanGroup(GroupState *node); extern void ExecReScanGroup(GroupState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern HashState *ExecInitHash(Hash *node, EState *estate, int eflags); extern HashState *ExecInitHash(Hash *node, EState *estate, int eflags);
extern TupleTableSlot *ExecHash(HashState *node);
extern Node *MultiExecHash(HashState *node); extern Node *MultiExecHash(HashState *node);
extern void ExecEndHash(HashState *node); extern void ExecEndHash(HashState *node);
extern void ExecReScanHash(HashState *node); extern void ExecReScanHash(HashState *node);
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "storage/buffile.h" #include "storage/buffile.h"
extern HashJoinState *ExecInitHashJoin(HashJoin *node, EState *estate, int eflags); extern HashJoinState *ExecInitHashJoin(HashJoin *node, EState *estate, int eflags);
extern TupleTableSlot *ExecHashJoin(HashJoinState *node);
extern void ExecEndHashJoin(HashJoinState *node); extern void ExecEndHashJoin(HashJoinState *node);
extern void ExecReScanHashJoin(HashJoinState *node); extern void ExecReScanHashJoin(HashJoinState *node);
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "access/parallel.h" #include "access/parallel.h"
extern IndexOnlyScanState *ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags); extern IndexOnlyScanState *ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecIndexOnlyScan(IndexOnlyScanState *node);
extern void ExecEndIndexOnlyScan(IndexOnlyScanState *node); extern void ExecEndIndexOnlyScan(IndexOnlyScanState *node);
extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node); extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node);
extern void ExecIndexOnlyRestrPos(IndexOnlyScanState *node); extern void ExecIndexOnlyRestrPos(IndexOnlyScanState *node);
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern IndexScanState *ExecInitIndexScan(IndexScan *node, EState *estate, int eflags); extern IndexScanState *ExecInitIndexScan(IndexScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecIndexScan(IndexScanState *node);
extern void ExecEndIndexScan(IndexScanState *node); extern void ExecEndIndexScan(IndexScanState *node);
extern void ExecIndexMarkPos(IndexScanState *node); extern void ExecIndexMarkPos(IndexScanState *node);
extern void ExecIndexRestrPos(IndexScanState *node); extern void ExecIndexRestrPos(IndexScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern LimitState *ExecInitLimit(Limit *node, EState *estate, int eflags); extern LimitState *ExecInitLimit(Limit *node, EState *estate, int eflags);
extern TupleTableSlot *ExecLimit(LimitState *node);
extern void ExecEndLimit(LimitState *node); extern void ExecEndLimit(LimitState *node);
extern void ExecReScanLimit(LimitState *node); extern void ExecReScanLimit(LimitState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern LockRowsState *ExecInitLockRows(LockRows *node, EState *estate, int eflags); extern LockRowsState *ExecInitLockRows(LockRows *node, EState *estate, int eflags);
extern TupleTableSlot *ExecLockRows(LockRowsState *node);
extern void ExecEndLockRows(LockRowsState *node); extern void ExecEndLockRows(LockRowsState *node);
extern void ExecReScanLockRows(LockRowsState *node); extern void ExecReScanLockRows(LockRowsState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern MaterialState *ExecInitMaterial(Material *node, EState *estate, int eflags); extern MaterialState *ExecInitMaterial(Material *node, EState *estate, int eflags);
extern TupleTableSlot *ExecMaterial(MaterialState *node);
extern void ExecEndMaterial(MaterialState *node); extern void ExecEndMaterial(MaterialState *node);
extern void ExecMaterialMarkPos(MaterialState *node); extern void ExecMaterialMarkPos(MaterialState *node);
extern void ExecMaterialRestrPos(MaterialState *node); extern void ExecMaterialRestrPos(MaterialState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern MergeAppendState *ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags); extern MergeAppendState *ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags);
extern TupleTableSlot *ExecMergeAppend(MergeAppendState *node);
extern void ExecEndMergeAppend(MergeAppendState *node); extern void ExecEndMergeAppend(MergeAppendState *node);
extern void ExecReScanMergeAppend(MergeAppendState *node); extern void ExecReScanMergeAppend(MergeAppendState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern MergeJoinState *ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags); extern MergeJoinState *ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags);
extern TupleTableSlot *ExecMergeJoin(MergeJoinState *node);
extern void ExecEndMergeJoin(MergeJoinState *node); extern void ExecEndMergeJoin(MergeJoinState *node);
extern void ExecReScanMergeJoin(MergeJoinState *node); extern void ExecReScanMergeJoin(MergeJoinState *node);
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern ModifyTableState *ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags); extern ModifyTableState *ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags);
extern TupleTableSlot *ExecModifyTable(ModifyTableState *node);
extern void ExecEndModifyTable(ModifyTableState *node); extern void ExecEndModifyTable(ModifyTableState *node);
extern void ExecReScanModifyTable(ModifyTableState *node); extern void ExecReScanModifyTable(ModifyTableState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern NamedTuplestoreScanState *ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags); extern NamedTuplestoreScanState *ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecNamedTuplestoreScan(NamedTuplestoreScanState *node);
extern void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node); extern void ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node);
extern void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node); extern void ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern NestLoopState *ExecInitNestLoop(NestLoop *node, EState *estate, int eflags); extern NestLoopState *ExecInitNestLoop(NestLoop *node, EState *estate, int eflags);
extern TupleTableSlot *ExecNestLoop(NestLoopState *node);
extern void ExecEndNestLoop(NestLoopState *node); extern void ExecEndNestLoop(NestLoopState *node);
extern void ExecReScanNestLoop(NestLoopState *node); extern void ExecReScanNestLoop(NestLoopState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern ProjectSetState *ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags); extern ProjectSetState *ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags);
extern TupleTableSlot *ExecProjectSet(ProjectSetState *node);
extern void ExecEndProjectSet(ProjectSetState *node); extern void ExecEndProjectSet(ProjectSetState *node);
extern void ExecReScanProjectSet(ProjectSetState *node); extern void ExecReScanProjectSet(ProjectSetState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern RecursiveUnionState *ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags); extern RecursiveUnionState *ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags);
extern TupleTableSlot *ExecRecursiveUnion(RecursiveUnionState *node);
extern void ExecEndRecursiveUnion(RecursiveUnionState *node); extern void ExecEndRecursiveUnion(RecursiveUnionState *node);
extern void ExecReScanRecursiveUnion(RecursiveUnionState *node); extern void ExecReScanRecursiveUnion(RecursiveUnionState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern ResultState *ExecInitResult(Result *node, EState *estate, int eflags); extern ResultState *ExecInitResult(Result *node, EState *estate, int eflags);
extern TupleTableSlot *ExecResult(ResultState *node);
extern void ExecEndResult(ResultState *node); extern void ExecEndResult(ResultState *node);
extern void ExecResultMarkPos(ResultState *node); extern void ExecResultMarkPos(ResultState *node);
extern void ExecResultRestrPos(ResultState *node); extern void ExecResultRestrPos(ResultState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern SampleScanState *ExecInitSampleScan(SampleScan *node, EState *estate, int eflags); extern SampleScanState *ExecInitSampleScan(SampleScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecSampleScan(SampleScanState *node);
extern void ExecEndSampleScan(SampleScanState *node); extern void ExecEndSampleScan(SampleScanState *node);
extern void ExecReScanSampleScan(SampleScanState *node); extern void ExecReScanSampleScan(SampleScanState *node);
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern SeqScanState *ExecInitSeqScan(SeqScan *node, EState *estate, int eflags); extern SeqScanState *ExecInitSeqScan(SeqScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecSeqScan(SeqScanState *node);
extern void ExecEndSeqScan(SeqScanState *node); extern void ExecEndSeqScan(SeqScanState *node);
extern void ExecReScanSeqScan(SeqScanState *node); extern void ExecReScanSeqScan(SeqScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern SetOpState *ExecInitSetOp(SetOp *node, EState *estate, int eflags); extern SetOpState *ExecInitSetOp(SetOp *node, EState *estate, int eflags);
extern TupleTableSlot *ExecSetOp(SetOpState *node);
extern void ExecEndSetOp(SetOpState *node); extern void ExecEndSetOp(SetOpState *node);
extern void ExecReScanSetOp(SetOpState *node); extern void ExecReScanSetOp(SetOpState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern SortState *ExecInitSort(Sort *node, EState *estate, int eflags); extern SortState *ExecInitSort(Sort *node, EState *estate, int eflags);
extern TupleTableSlot *ExecSort(SortState *node);
extern void ExecEndSort(SortState *node); extern void ExecEndSort(SortState *node);
extern void ExecSortMarkPos(SortState *node); extern void ExecSortMarkPos(SortState *node);
extern void ExecSortRestrPos(SortState *node); extern void ExecSortRestrPos(SortState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern SubqueryScanState *ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags); extern SubqueryScanState *ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecSubqueryScan(SubqueryScanState *node);
extern void ExecEndSubqueryScan(SubqueryScanState *node); extern void ExecEndSubqueryScan(SubqueryScanState *node);
extern void ExecReScanSubqueryScan(SubqueryScanState *node); extern void ExecReScanSubqueryScan(SubqueryScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern TableFuncScanState *ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags); extern TableFuncScanState *ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecTableFuncScan(TableFuncScanState *node);
extern void ExecEndTableFuncScan(TableFuncScanState *node); extern void ExecEndTableFuncScan(TableFuncScanState *node);
extern void ExecReScanTableFuncScan(TableFuncScanState *node); extern void ExecReScanTableFuncScan(TableFuncScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern TidScanState *ExecInitTidScan(TidScan *node, EState *estate, int eflags); extern TidScanState *ExecInitTidScan(TidScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecTidScan(TidScanState *node);
extern void ExecEndTidScan(TidScanState *node); extern void ExecEndTidScan(TidScanState *node);
extern void ExecReScanTidScan(TidScanState *node); extern void ExecReScanTidScan(TidScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern UniqueState *ExecInitUnique(Unique *node, EState *estate, int eflags); extern UniqueState *ExecInitUnique(Unique *node, EState *estate, int eflags);
extern TupleTableSlot *ExecUnique(UniqueState *node);
extern void ExecEndUnique(UniqueState *node); extern void ExecEndUnique(UniqueState *node);
extern void ExecReScanUnique(UniqueState *node); extern void ExecReScanUnique(UniqueState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern ValuesScanState *ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags); extern ValuesScanState *ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecValuesScan(ValuesScanState *node);
extern void ExecEndValuesScan(ValuesScanState *node); extern void ExecEndValuesScan(ValuesScanState *node);
extern void ExecReScanValuesScan(ValuesScanState *node); extern void ExecReScanValuesScan(ValuesScanState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern WindowAggState *ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags); extern WindowAggState *ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags);
extern TupleTableSlot *ExecWindowAgg(WindowAggState *node);
extern void ExecEndWindowAgg(WindowAggState *node); extern void ExecEndWindowAgg(WindowAggState *node);
extern void ExecReScanWindowAgg(WindowAggState *node); extern void ExecReScanWindowAgg(WindowAggState *node);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "nodes/execnodes.h" #include "nodes/execnodes.h"
extern WorkTableScanState *ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags); extern WorkTableScanState *ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags);
extern TupleTableSlot *ExecWorkTableScan(WorkTableScanState *node);
extern void ExecEndWorkTableScan(WorkTableScanState *node); extern void ExecEndWorkTableScan(WorkTableScanState *node);
extern void ExecReScanWorkTableScan(WorkTableScanState *node); extern void ExecReScanWorkTableScan(WorkTableScanState *node);
......
...@@ -818,6 +818,18 @@ typedef struct DomainConstraintState ...@@ -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 * PlanState node
* *
...@@ -835,6 +847,10 @@ typedef struct PlanState ...@@ -835,6 +847,10 @@ typedef struct PlanState
* nodes point to one EState for the whole * nodes point to one EState for the whole
* top-level plan */ * 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 */ Instrumentation *instrument; /* Optional runtime stats for this node */
WorkerInstrumentation *worker_instrument; /* per-worker instrumentation */ WorkerInstrumentation *worker_instrument; /* per-worker instrumentation */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment