mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
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 b8d7f053c5
- 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
This commit is contained in:
@ -17,15 +17,10 @@
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
/*
|
||||
* INTERFACE ROUTINES
|
||||
* ExecInitNode - initialize a plan node and its subplans
|
||||
* ExecProcNode - get a tuple by executing the plan node
|
||||
* ExecEndNode - shut down a plan node and its subplans
|
||||
*
|
||||
* NOTES
|
||||
* This used to be three files. It is now all combined into
|
||||
* one file so that it is easier to keep ExecInitNode, ExecProcNode,
|
||||
* and ExecEndNode in sync when new nodes are added.
|
||||
* one file so that it is easier to keep the dispatch routines
|
||||
* in sync when new nodes are added.
|
||||
*
|
||||
* EXAMPLE
|
||||
* Suppose we want the age of the manager of the shoe department and
|
||||
@ -122,6 +117,10 @@
|
||||
#include "miscadmin.h"
|
||||
|
||||
|
||||
static TupleTableSlot *ExecProcNodeFirst(PlanState *node);
|
||||
static TupleTableSlot *ExecProcNodeInstr(PlanState *node);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
* ExecInitNode
|
||||
*
|
||||
@ -149,6 +148,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Make sure there's enough stack available. Need to check here, in
|
||||
* addition to ExecProcNode() (via ExecProcNodeFirst()), to ensure the
|
||||
* stack isn't overrun while initializing the node tree.
|
||||
*/
|
||||
check_stack_depth();
|
||||
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
/*
|
||||
@ -364,6 +370,13 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a wrapper around the ExecProcNode callback that checks stack depth
|
||||
* during the first execution.
|
||||
*/
|
||||
result->ExecProcNodeReal = result->ExecProcNode;
|
||||
result->ExecProcNode = ExecProcNodeFirst;
|
||||
|
||||
/*
|
||||
* Initialize any initPlans present in this node. The planner put them in
|
||||
* a separate list for us.
|
||||
@ -388,195 +401,51 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecProcNode
|
||||
*
|
||||
* Execute the given node to return a(nother) tuple.
|
||||
* ----------------------------------------------------------------
|
||||
/*
|
||||
* ExecProcNode wrapper that performs some one-time checks, before calling
|
||||
* the relevant node method (possibly via an instrumentation wrapper).
|
||||
*/
|
||||
TupleTableSlot *
|
||||
ExecProcNode(PlanState *node)
|
||||
static TupleTableSlot *
|
||||
ExecProcNodeFirst(PlanState *node)
|
||||
{
|
||||
/*
|
||||
* Perform stack depth check during the first execution of the node. We
|
||||
* only do so the first time round because it turns out to not be cheap on
|
||||
* some common architectures (eg. x86). This relies on the assumption that
|
||||
* ExecProcNode calls for a given plan node will always be made at roughly
|
||||
* the same stack depth.
|
||||
*/
|
||||
check_stack_depth();
|
||||
|
||||
/*
|
||||
* If instrumentation is required, change the wrapper to one that just
|
||||
* does instrumentation. Otherwise we can dispense with all wrappers and
|
||||
* have ExecProcNode() directly call the relevant function from now on.
|
||||
*/
|
||||
if (node->instrument)
|
||||
node->ExecProcNode = ExecProcNodeInstr;
|
||||
else
|
||||
node->ExecProcNode = node->ExecProcNodeReal;
|
||||
|
||||
return node->ExecProcNode(node);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ExecProcNode wrapper that performs instrumentation calls. By keeping
|
||||
* this a separate function, we avoid overhead in the normal case where
|
||||
* no instrumentation is wanted.
|
||||
*/
|
||||
static TupleTableSlot *
|
||||
ExecProcNodeInstr(PlanState *node)
|
||||
{
|
||||
TupleTableSlot *result;
|
||||
|
||||
if (node->chgParam != NULL) /* something changed */
|
||||
ExecReScan(node); /* let ReScan handle this */
|
||||
InstrStartNode(node->instrument);
|
||||
|
||||
if (node->instrument)
|
||||
InstrStartNode(node->instrument);
|
||||
result = node->ExecProcNodeReal(node);
|
||||
|
||||
switch (nodeTag(node))
|
||||
{
|
||||
/*
|
||||
* control nodes
|
||||
*/
|
||||
case T_ResultState:
|
||||
result = ExecResult((ResultState *) node);
|
||||
break;
|
||||
|
||||
case T_ProjectSetState:
|
||||
result = ExecProjectSet((ProjectSetState *) node);
|
||||
break;
|
||||
|
||||
case T_ModifyTableState:
|
||||
result = ExecModifyTable((ModifyTableState *) node);
|
||||
break;
|
||||
|
||||
case T_AppendState:
|
||||
result = ExecAppend((AppendState *) node);
|
||||
break;
|
||||
|
||||
case T_MergeAppendState:
|
||||
result = ExecMergeAppend((MergeAppendState *) node);
|
||||
break;
|
||||
|
||||
case T_RecursiveUnionState:
|
||||
result = ExecRecursiveUnion((RecursiveUnionState *) node);
|
||||
break;
|
||||
|
||||
/* BitmapAndState does not yield tuples */
|
||||
|
||||
/* BitmapOrState does not yield tuples */
|
||||
|
||||
/*
|
||||
* scan nodes
|
||||
*/
|
||||
case T_SeqScanState:
|
||||
result = ExecSeqScan((SeqScanState *) node);
|
||||
break;
|
||||
|
||||
case T_SampleScanState:
|
||||
result = ExecSampleScan((SampleScanState *) node);
|
||||
break;
|
||||
|
||||
case T_IndexScanState:
|
||||
result = ExecIndexScan((IndexScanState *) node);
|
||||
break;
|
||||
|
||||
case T_IndexOnlyScanState:
|
||||
result = ExecIndexOnlyScan((IndexOnlyScanState *) node);
|
||||
break;
|
||||
|
||||
/* BitmapIndexScanState does not yield tuples */
|
||||
|
||||
case T_BitmapHeapScanState:
|
||||
result = ExecBitmapHeapScan((BitmapHeapScanState *) node);
|
||||
break;
|
||||
|
||||
case T_TidScanState:
|
||||
result = ExecTidScan((TidScanState *) node);
|
||||
break;
|
||||
|
||||
case T_SubqueryScanState:
|
||||
result = ExecSubqueryScan((SubqueryScanState *) node);
|
||||
break;
|
||||
|
||||
case T_FunctionScanState:
|
||||
result = ExecFunctionScan((FunctionScanState *) node);
|
||||
break;
|
||||
|
||||
case T_TableFuncScanState:
|
||||
result = ExecTableFuncScan((TableFuncScanState *) node);
|
||||
break;
|
||||
|
||||
case T_ValuesScanState:
|
||||
result = ExecValuesScan((ValuesScanState *) node);
|
||||
break;
|
||||
|
||||
case T_CteScanState:
|
||||
result = ExecCteScan((CteScanState *) node);
|
||||
break;
|
||||
|
||||
case T_NamedTuplestoreScanState:
|
||||
result = ExecNamedTuplestoreScan((NamedTuplestoreScanState *) node);
|
||||
break;
|
||||
|
||||
case T_WorkTableScanState:
|
||||
result = ExecWorkTableScan((WorkTableScanState *) node);
|
||||
break;
|
||||
|
||||
case T_ForeignScanState:
|
||||
result = ExecForeignScan((ForeignScanState *) node);
|
||||
break;
|
||||
|
||||
case T_CustomScanState:
|
||||
result = ExecCustomScan((CustomScanState *) node);
|
||||
break;
|
||||
|
||||
/*
|
||||
* join nodes
|
||||
*/
|
||||
case T_NestLoopState:
|
||||
result = ExecNestLoop((NestLoopState *) node);
|
||||
break;
|
||||
|
||||
case T_MergeJoinState:
|
||||
result = ExecMergeJoin((MergeJoinState *) node);
|
||||
break;
|
||||
|
||||
case T_HashJoinState:
|
||||
result = ExecHashJoin((HashJoinState *) node);
|
||||
break;
|
||||
|
||||
/*
|
||||
* materialization nodes
|
||||
*/
|
||||
case T_MaterialState:
|
||||
result = ExecMaterial((MaterialState *) node);
|
||||
break;
|
||||
|
||||
case T_SortState:
|
||||
result = ExecSort((SortState *) node);
|
||||
break;
|
||||
|
||||
case T_GroupState:
|
||||
result = ExecGroup((GroupState *) node);
|
||||
break;
|
||||
|
||||
case T_AggState:
|
||||
result = ExecAgg((AggState *) node);
|
||||
break;
|
||||
|
||||
case T_WindowAggState:
|
||||
result = ExecWindowAgg((WindowAggState *) node);
|
||||
break;
|
||||
|
||||
case T_UniqueState:
|
||||
result = ExecUnique((UniqueState *) node);
|
||||
break;
|
||||
|
||||
case T_GatherState:
|
||||
result = ExecGather((GatherState *) node);
|
||||
break;
|
||||
|
||||
case T_GatherMergeState:
|
||||
result = ExecGatherMerge((GatherMergeState *) node);
|
||||
break;
|
||||
|
||||
case T_HashState:
|
||||
result = ExecHash((HashState *) node);
|
||||
break;
|
||||
|
||||
case T_SetOpState:
|
||||
result = ExecSetOp((SetOpState *) node);
|
||||
break;
|
||||
|
||||
case T_LockRowsState:
|
||||
result = ExecLockRows((LockRowsState *) node);
|
||||
break;
|
||||
|
||||
case T_LimitState:
|
||||
result = ExecLimit((LimitState *) node);
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
|
||||
result = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (node->instrument)
|
||||
InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
|
||||
InstrStopNode(node->instrument, TupIsNull(result) ? 0.0 : 1.0);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -600,6 +469,8 @@ MultiExecProcNode(PlanState *node)
|
||||
{
|
||||
Node *result;
|
||||
|
||||
check_stack_depth();
|
||||
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
if (node->chgParam != NULL) /* something changed */
|
||||
@ -657,6 +528,13 @@ ExecEndNode(PlanState *node)
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Make sure there's enough stack available. Need to check here, in
|
||||
* addition to ExecProcNode() (via ExecProcNodeFirst()), because it's not
|
||||
* guaranteed that ExecProcNode() is reached for all nodes.
|
||||
*/
|
||||
check_stack_depth();
|
||||
|
||||
if (node->chgParam != NULL)
|
||||
{
|
||||
bms_free(node->chgParam);
|
||||
@ -855,6 +733,8 @@ ExecShutdownNode(PlanState *node)
|
||||
if (node == NULL)
|
||||
return false;
|
||||
|
||||
check_stack_depth();
|
||||
|
||||
planstate_tree_walker(node, ExecShutdownNode, NULL);
|
||||
|
||||
switch (nodeTag(node))
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -32,6 +32,19 @@
|
||||
#include "executor/nodeBitmapAnd.h"
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecBitmapAnd
|
||||
*
|
||||
* stub for pro forma compliance
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static TupleTableSlot *
|
||||
ExecBitmapAnd(PlanState *pstate)
|
||||
{
|
||||
elog(ERROR, "BitmapAnd node does not support ExecProcNode call convention");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecInitBitmapAnd
|
||||
*
|
||||
@ -63,6 +76,7 @@ ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags)
|
||||
*/
|
||||
bitmapandstate->ps.plan = (Plan *) node;
|
||||
bitmapandstate->ps.state = estate;
|
||||
bitmapandstate->ps.ExecProcNode = ExecBitmapAnd;
|
||||
bitmapandstate->bitmapplans = bitmapplanstates;
|
||||
bitmapandstate->nplans = nplans;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -28,6 +28,19 @@
|
||||
#include "utils/memutils.h"
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecBitmapIndexScan
|
||||
*
|
||||
* stub for pro forma compliance
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static TupleTableSlot *
|
||||
ExecBitmapIndexScan(PlanState *pstate)
|
||||
{
|
||||
elog(ERROR, "BitmapIndexScan node does not support ExecProcNode call convention");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* MultiExecBitmapIndexScan(node)
|
||||
* ----------------------------------------------------------------
|
||||
@ -208,6 +221,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
|
||||
indexstate = makeNode(BitmapIndexScanState);
|
||||
indexstate->ss.ps.plan = (Plan *) node;
|
||||
indexstate->ss.ps.state = estate;
|
||||
indexstate->ss.ps.ExecProcNode = ExecBitmapIndexScan;
|
||||
|
||||
/* normally we don't make the result bitmap till runtime */
|
||||
indexstate->biss_result = NULL;
|
||||
|
@ -33,6 +33,19 @@
|
||||
#include "miscadmin.h"
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecBitmapOr
|
||||
*
|
||||
* stub for pro forma compliance
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static TupleTableSlot *
|
||||
ExecBitmapOr(PlanState *pstate)
|
||||
{
|
||||
elog(ERROR, "BitmapOr node does not support ExecProcNode call convention");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* ExecInitBitmapOr
|
||||
*
|
||||
@ -64,6 +77,7 @@ ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags)
|
||||
*/
|
||||
bitmaporstate->ps.plan = (Plan *) node;
|
||||
bitmaporstate->ps.state = estate;
|
||||
bitmaporstate->ps.ExecProcNode = ExecBitmapOr;
|
||||
bitmaporstate->bitmapplans = bitmapplanstates;
|
||||
bitmaporstate->nplans = nplans;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
|
||||
static TupleTableSlot *ExecCustomScan(PlanState *pstate);
|
||||
|
||||
|
||||
CustomScanState *
|
||||
ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
|
||||
{
|
||||
@ -45,6 +49,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
|
||||
/* fill up fields of ScanState */
|
||||
css->ss.ps.plan = &cscan->scan.plan;
|
||||
css->ss.ps.state = estate;
|
||||
css->ss.ps.ExecProcNode = ExecCustomScan;
|
||||
|
||||
/* create expression context for node */
|
||||
ExecAssignExprContext(estate, &css->ss.ps);
|
||||
@ -102,9 +107,11 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
|
||||
return css;
|
||||
}
|
||||
|
||||
TupleTableSlot *
|
||||
ExecCustomScan(CustomScanState *node)
|
||||
static TupleTableSlot *
|
||||
ExecCustomScan(PlanState *pstate)
|
||||
{
|
||||
CustomScanState *node = castNode(CustomScanState, pstate);
|
||||
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
Assert(node->methods->ExecCustomScan != NULL);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -32,9 +32,10 @@
|
||||
*
|
||||
* Return one tuple for each group of matching input tuples.
|
||||
*/
|
||||
TupleTableSlot *
|
||||
ExecGroup(GroupState *node)
|
||||
static TupleTableSlot *
|
||||
ExecGroup(PlanState *pstate)
|
||||
{
|
||||
GroupState *node = castNode(GroupState, pstate);
|
||||
ExprContext *econtext;
|
||||
int numCols;
|
||||
AttrNumber *grpColIdx;
|
||||
@ -175,6 +176,7 @@ ExecInitGroup(Group *node, EState *estate, int eflags)
|
||||
grpstate = makeNode(GroupState);
|
||||
grpstate->ss.ps.plan = (Plan *) node;
|
||||
grpstate->ss.ps.state = estate;
|
||||
grpstate->ss.ps.ExecProcNode = ExecGroup;
|
||||
grpstate->grp_done = FALSE;
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -36,9 +36,10 @@
|
||||
* ExecLockRows
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
TupleTableSlot * /* return: a tuple or NULL */
|
||||
ExecLockRows(LockRowsState *node)
|
||||
static TupleTableSlot * /* return: a tuple or NULL */
|
||||
ExecLockRows(PlanState *pstate)
|
||||
{
|
||||
LockRowsState *node = castNode(LockRowsState, pstate);
|
||||
TupleTableSlot *slot;
|
||||
EState *estate;
|
||||
PlanState *outerPlan;
|
||||
@ -364,6 +365,7 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags)
|
||||
lrstate = makeNode(LockRowsState);
|
||||
lrstate->ps.plan = (Plan *) node;
|
||||
lrstate->ps.state = estate;
|
||||
lrstate->ps.ExecProcNode = ExecLockRows;
|
||||
|
||||
/*
|
||||
* Miscellaneous initialization
|
||||
|
@ -35,9 +35,10 @@
|
||||
*
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
TupleTableSlot * /* result tuple from subplan */
|
||||
ExecMaterial(MaterialState *node)
|
||||
static TupleTableSlot * /* result tuple from subplan */
|
||||
ExecMaterial(PlanState *pstate)
|
||||
{
|
||||
MaterialState *node = castNode(MaterialState, pstate);
|
||||
EState *estate;
|
||||
ScanDirection dir;
|
||||
bool forward;
|
||||
@ -173,6 +174,7 @@ ExecInitMaterial(Material *node, EState *estate, int eflags)
|
||||
matstate = makeNode(MaterialState);
|
||||
matstate->ss.ps.plan = (Plan *) node;
|
||||
matstate->ss.ps.state = estate;
|
||||
matstate->ss.ps.ExecProcNode = ExecMaterial;
|
||||
|
||||
/*
|
||||
* We must have a tuplestore buffering the subplan output to do backward
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -57,9 +57,10 @@
|
||||
* are prepared to return the first tuple.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
TupleTableSlot *
|
||||
ExecNestLoop(NestLoopState *node)
|
||||
static TupleTableSlot *
|
||||
ExecNestLoop(PlanState *pstate)
|
||||
{
|
||||
NestLoopState *node = castNode(NestLoopState, pstate);
|
||||
NestLoop *nl;
|
||||
PlanState *innerPlan;
|
||||
PlanState *outerPlan;
|
||||
@ -275,6 +276,7 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
|
||||
nlstate = makeNode(NestLoopState);
|
||||
nlstate->js.ps.plan = (Plan *) node;
|
||||
nlstate->js.ps.state = estate;
|
||||
nlstate->js.ps.ExecProcNode = ExecNestLoop;
|
||||
|
||||
/*
|
||||
* Miscellaneous initialization
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -64,9 +64,10 @@
|
||||
* 'nil' if the constant qualification is not satisfied.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
TupleTableSlot *
|
||||
ExecResult(ResultState *node)
|
||||
static TupleTableSlot *
|
||||
ExecResult(PlanState *pstate)
|
||||
{
|
||||
ResultState *node = castNode(ResultState, pstate);
|
||||
TupleTableSlot *outerTupleSlot;
|
||||
PlanState *outerPlan;
|
||||
ExprContext *econtext;
|
||||
@ -191,6 +192,7 @@ ExecInitResult(Result *node, EState *estate, int eflags)
|
||||
resstate = makeNode(ResultState);
|
||||
resstate->ps.plan = (Plan *) node;
|
||||
resstate->ps.state = estate;
|
||||
resstate->ps.ExecProcNode = ExecResult;
|
||||
|
||||
resstate->rs_done = false;
|
||||
resstate->rs_checkqual = (node->resconstantqual == NULL) ? false : true;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -35,9 +35,10 @@
|
||||
* -- the outer child is prepared to return the first tuple.
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
TupleTableSlot *
|
||||
ExecSort(SortState *node)
|
||||
static TupleTableSlot *
|
||||
ExecSort(PlanState *pstate)
|
||||
{
|
||||
SortState *node = castNode(SortState, pstate);
|
||||
EState *estate;
|
||||
ScanDirection dir;
|
||||
Tuplesortstate *tuplesortstate;
|
||||
@ -165,6 +166,7 @@ ExecInitSort(Sort *node, EState *estate, int eflags)
|
||||
sortstate = makeNode(SortState);
|
||||
sortstate->ss.ps.plan = (Plan *) node;
|
||||
sortstate->ss.ps.state = estate;
|
||||
sortstate->ss.ps.ExecProcNode = ExecSort;
|
||||
|
||||
/*
|
||||
* We must have random access to the sort output to do backward scan or
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -43,9 +43,10 @@
|
||||
* ExecUnique
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
TupleTableSlot * /* return: a tuple or NULL */
|
||||
ExecUnique(UniqueState *node)
|
||||
static TupleTableSlot * /* return: a tuple or NULL */
|
||||
ExecUnique(PlanState *pstate)
|
||||
{
|
||||
UniqueState *node = castNode(UniqueState, pstate);
|
||||
Unique *plannode = (Unique *) node->ps.plan;
|
||||
TupleTableSlot *resultTupleSlot;
|
||||
TupleTableSlot *slot;
|
||||
@ -125,6 +126,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags)
|
||||
uniquestate = makeNode(UniqueState);
|
||||
uniquestate->ps.plan = (Plan *) node;
|
||||
uniquestate->ps.state = estate;
|
||||
uniquestate->ps.ExecProcNode = ExecUnique;
|
||||
|
||||
/*
|
||||
* Miscellaneous initialization
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user