in src/backend/executor/execProcnode.c [152:570]
static CdbVisitOpt planstate_walk_node_extended(PlanState *planstate,
CdbVisitOpt (*walker) (PlanState *planstate, void *context),
void *context,
int flags);
static CdbVisitOpt planstate_walk_array(PlanState **planstates,
int nplanstate,
CdbVisitOpt (*walker) (PlanState *planstate, void *context),
void *context,
int flags);
static CdbVisitOpt planstate_walk_kids(PlanState *planstate,
CdbVisitOpt (*walker) (PlanState *planstate, void *context),
void *context,
int flags);
static TupleTableSlot *ExecProcNodeFirst(PlanState *node);
#if 0
static TupleTableSlot *ExecProcNodeInstr(PlanState *node);
#endif
static TupleTableSlot *ExecProcNodeGPDB(PlanState *node);
/* ------------------------------------------------------------------------
* ExecInitNode
*
* Recursively initializes all the nodes in the plan tree rooted
* at 'node'.
*
* Inputs:
* 'node' is the current node of the plan produced by the query planner
* 'estate' is the shared execution state for the plan tree
* 'eflags' is a bitwise OR of flag bits described in executor.h
*
* Returns a PlanState node corresponding to the given Plan node.
* ------------------------------------------------------------------------
*/
PlanState *
ExecInitNode(Plan *node, EState *estate, int eflags)
{
PlanState *result;
List *subps;
ListCell *l;
MemoryContext nodecxt = NULL;
MemoryContext oldcxt = NULL;
/*
* do nothing when we get to the end of a leaf on tree.
*/
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();
/*
* If per-node memory usage was requested
* (explain_memory_verbosity=detail), create a separate memory context
* for every node, so that we can attribute memory usage to each node.
* Otherwise, everything is allocated in the per-query ExecutorState
* context. The extra memory contexts consume some memory on their
* own, and prevent reusing memory allocated in one node in another
* node, so we only want to do this if the level of detail is needed.
*/
if ((estate->es_instrument & INSTRUMENT_MEMORY_DETAIL) != 0)
{
nodecxt = AllocSetContextCreate(CurrentMemoryContext,
"executor node",
ALLOCSET_SMALL_SIZES);
MemoryContextDeclareAccountingRoot(nodecxt);
oldcxt = MemoryContextSwitchTo(nodecxt);
}
switch (nodeTag(node))
{
/*
* control nodes
*/
case T_Result:
result = (PlanState *) ExecInitResult((Result *) node,
estate, eflags);
break;
case T_ProjectSet:
result = (PlanState *) ExecInitProjectSet((ProjectSet *) node,
estate, eflags);
break;
case T_ModifyTable:
result = (PlanState *) ExecInitModifyTable((ModifyTable *) node,
estate, eflags);
break;
case T_Append:
result = (PlanState *) ExecInitAppend((Append *) node,
estate, eflags);
break;
case T_Sequence:
result = (PlanState *) ExecInitSequence((Sequence *) node,
estate, eflags);
break;
case T_MergeAppend:
result = (PlanState *) ExecInitMergeAppend((MergeAppend *) node,
estate, eflags);
break;
case T_RecursiveUnion:
result = (PlanState *) ExecInitRecursiveUnion((RecursiveUnion *) node,
estate, eflags);
break;
case T_BitmapAnd:
result = (PlanState *) ExecInitBitmapAnd((BitmapAnd *) node,
estate, eflags);
break;
case T_BitmapOr:
result = (PlanState *) ExecInitBitmapOr((BitmapOr *) node,
estate, eflags);
break;
/*
* scan nodes
*/
case T_SeqScan:
result = (PlanState *) ExecInitSeqScan((SeqScan *) node,
estate, eflags);
break;
case T_DynamicSeqScan:
result = (PlanState *) ExecInitDynamicSeqScan((DynamicSeqScan *) node,
estate, eflags);
break;
case T_SampleScan:
result = (PlanState *) ExecInitSampleScan((SampleScan *) node,
estate, eflags);
break;
case T_IndexScan:
result = (PlanState *) ExecInitIndexScan((IndexScan *) node,
estate, eflags);
break;
case T_DynamicIndexScan:
result = (PlanState *) ExecInitDynamicIndexScan((DynamicIndexScan *) node,
estate, eflags);
break;
case T_DynamicIndexOnlyScan:
result = (PlanState *) ExecInitDynamicIndexOnlyScan((DynamicIndexOnlyScan *) node,
estate, eflags);
break;
case T_IndexOnlyScan:
result = (PlanState *) ExecInitIndexOnlyScan((IndexOnlyScan *) node,
estate, eflags);
break;
case T_BitmapIndexScan:
result = (PlanState *) ExecInitBitmapIndexScan((BitmapIndexScan *) node,
estate, eflags);
break;
case T_DynamicBitmapIndexScan:
result = (PlanState *) ExecInitDynamicBitmapIndexScan((DynamicBitmapIndexScan *) node,
estate, eflags);
break;
case T_BitmapHeapScan:
result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
estate, eflags);
break;
case T_DynamicBitmapHeapScan:
result = (PlanState *) ExecInitDynamicBitmapHeapScan((DynamicBitmapHeapScan *) node,
estate, eflags);
break;
case T_TidScan:
result = (PlanState *) ExecInitTidScan((TidScan *) node,
estate, eflags);
break;
case T_TidRangeScan:
result = (PlanState *) ExecInitTidRangeScan((TidRangeScan *) node,
estate, eflags);
break;
case T_SubqueryScan:
result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node,
estate, eflags);
break;
case T_FunctionScan:
result = (PlanState *) ExecInitFunctionScan((FunctionScan *) node,
estate, eflags);
break;
case T_TableFunctionScan:
result = (PlanState *) ExecInitTableFunction((TableFunctionScan *) node,
estate, eflags);
break;
case T_TableFuncScan:
result = (PlanState *) ExecInitTableFuncScan((TableFuncScan *) node,
estate, eflags);
break;
case T_ValuesScan:
result = (PlanState *) ExecInitValuesScan((ValuesScan *) node,
estate, eflags);
break;
case T_CteScan:
result = (PlanState *) ExecInitCteScan((CteScan *) node,
estate, eflags);
break;
case T_NamedTuplestoreScan:
result = (PlanState *) ExecInitNamedTuplestoreScan((NamedTuplestoreScan *) node,
estate, eflags);
break;
case T_WorkTableScan:
result = (PlanState *) ExecInitWorkTableScan((WorkTableScan *) node,
estate, eflags);
break;
case T_ForeignScan:
result = (PlanState *) ExecInitForeignScan((ForeignScan *) node,
estate, eflags);
break;
case T_DynamicForeignScan:
result = (PlanState *) ExecInitDynamicForeignScan((DynamicForeignScan *) node,
estate, eflags);
break;
case T_CustomScan:
result = (PlanState *) ExecInitCustomScan((CustomScan *) node,
estate, eflags);
break;
/*
* join nodes
*/
case T_NestLoop:
result = (PlanState *) ExecInitNestLoop((NestLoop *) node,
estate, eflags);
break;
case T_MergeJoin:
result = (PlanState *) ExecInitMergeJoin((MergeJoin *) node,
estate, eflags);
break;
case T_HashJoin:
result = (PlanState *) ExecInitHashJoin((HashJoin *) node,
estate, eflags);
break;
/*
* materialization nodes
*/
case T_Material:
result = (PlanState *) ExecInitMaterial((Material *) node,
estate, eflags);
break;
case T_Sort:
result = (PlanState *) ExecInitSort((Sort *) node,
estate, eflags);
break;
case T_IncrementalSort:
result = (PlanState *) ExecInitIncrementalSort((IncrementalSort *) node,
estate, eflags);
break;
case T_Memoize:
result = (PlanState *) ExecInitMemoize((Memoize *) node, estate,
eflags);
break;
case T_Group:
result = (PlanState *) ExecInitGroup((Group *) node,
estate, eflags);
break;
case T_Agg:
result = (PlanState *) ExecInitAgg((Agg *) node,
estate, eflags);
break;
case T_WindowAgg:
result = (PlanState *) ExecInitWindowAgg((WindowAgg *) node,
estate, eflags);
break;
case T_Unique:
result = (PlanState *) ExecInitUnique((Unique *) node,
estate, eflags);
break;
case T_Gather:
result = (PlanState *) ExecInitGather((Gather *) node,
estate, eflags);
break;
case T_GatherMerge:
result = (PlanState *) ExecInitGatherMerge((GatherMerge *) node,
estate, eflags);
break;
case T_Hash:
result = (PlanState *) ExecInitHash((Hash *) node,
estate, eflags);
break;
case T_SetOp:
result = (PlanState *) ExecInitSetOp((SetOp *) node,
estate, eflags);
break;
case T_LockRows:
result = (PlanState *) ExecInitLockRows((LockRows *) node,
estate, eflags);
break;
case T_RuntimeFilter:
result = (PlanState *) ExecInitRuntimeFilter((RuntimeFilter *) node,
estate, eflags);
break;
case T_Limit:
result = (PlanState *) ExecInitLimit((Limit *) node,
estate, eflags);
break;
case T_Motion:
result = (PlanState *) ExecInitMotion((Motion *) node,
estate, eflags);
break;
/*
* share input nodes
*/
case T_ShareInputScan:
result = (PlanState *) ExecInitShareInputScan((ShareInputScan *) node, estate, eflags);
break;
case T_SplitUpdate:
result = (PlanState *) ExecInitSplitUpdate((SplitUpdate *) node,
estate, eflags);
break;
case T_AssertOp:
result = (PlanState *) ExecInitAssertOp((AssertOp *) node,
estate, eflags);
break;
case T_PartitionSelector:
result = (PlanState *) ExecInitPartitionSelector((PartitionSelector *) node,
estate, eflags);
break;
case T_TupleSplit:
result = (PlanState *) ExecInitTupleSplit((TupleSplit *) node,
estate, eflags);
break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
result = NULL; /* keep compiler quiet */
break;
}
ExecSetExecProcNode(result, result->ExecProcNode);
if ((estate->es_instrument & INSTRUMENT_MEMORY_DETAIL) != 0)
{
Assert(CurrentMemoryContext == nodecxt);
result->node_context = nodecxt;
MemoryContextSwitchTo(oldcxt);
}
/*
* Initialize any initPlans present in this node. The planner put them in
* a separate list for us.
*/
subps = NIL;
foreach(l, node->initPlan)
{
SubPlan *subplan = (SubPlan *) lfirst(l);
SubPlanState *sstate;
int origSliceId = estate->currentSliceId;
Assert(IsA(subplan, SubPlan));
estate->currentSliceId = estate->es_plannedstmt->subplan_sliceIds[subplan->plan_id - 1];
sstate = ExecInitSubPlan(subplan, result);
subps = lappend(subps, sstate);
estate->currentSliceId = origSliceId;
}
if (result != NULL)
result->initPlan = subps;
/* Set up instrumentation for this node if requested */
if (estate->es_instrument && result != NULL)
result->instrument = GpInstrAlloc(node, estate->es_instrument,
result->async_capable);
return result;
}