/*
* Initialize private state information for each SubPlan. We must do this
* before running ExecInitNode on the main query tree, since
- * ExecInitSubPlan expects to be able to find these entries.
+ * ExecInitSubPlan expects to be able to find these entries. Since the
+ * main plan tree hasn't been initialized yet, we have to pass NULL as the
+ * parent node to ExecInitNode; ExecInitSubPlan also takes responsibility
+ * for fixing up subplanstate->parent.
*/
Assert(estate->es_subplanstates == NIL);
i = 1; /* subplan indices count from 1 */
if (bms_is_member(i, plannedstmt->rewindPlanIDs))
sp_eflags |= EXEC_FLAG_REWIND;
- subplanstate = ExecInitNode(subplan, estate, sp_eflags);
+ subplanstate = ExecInitNode(subplan, estate, NULL, sp_eflags);
estate->es_subplanstates = lappend(estate->es_subplanstates,
subplanstate);
/*
* Initialize the private state information for all the nodes in the query
* tree. This opens files, allocates storage and leaves us ready to start
- * processing tuples.
+ * processing tuples. This is the root planstate node; it has no parent.
*/
- planstate = ExecInitNode(plan, estate, eflags);
+ planstate = ExecInitNode(plan, estate, NULL, eflags);
/*
* Get the tuple descriptor describing the type of tuples to return.
* ExecInitSubPlan expects to be able to find these entries. Some of the
* SubPlans might not be used in the part of the plan tree we intend to
* run, but since it's not easy to tell which, we just initialize them
- * all.
+ * all. Since the main plan tree hasn't been initialized yet, we have to
+ * pass NULL as the parent node to ExecInitNode; ExecInitSubPlan also
+ * takes responsibility for fixing up subplanstate->parent.
*/
Assert(estate->es_subplanstates == NIL);
foreach(l, parentestate->es_plannedstmt->subplans)
Plan *subplan = (Plan *) lfirst(l);
PlanState *subplanstate;
- subplanstate = ExecInitNode(subplan, estate, 0);
+ subplanstate = ExecInitNode(subplan, estate, NULL, 0);
estate->es_subplanstates = lappend(estate->es_subplanstates,
subplanstate);
}
/*
* Initialize the private state information for all the nodes in the part
* of the plan tree we need to run. This opens files, allocates storage
- * and leaves us ready to start processing tuples.
+ * and leaves us ready to start processing tuples. This is the root plan
+ * node; it has no parent.
*/
- epqstate->planstate = ExecInitNode(planTree, estate, 0);
+ epqstate->planstate = ExecInitNode(planTree, estate, NULL, 0);
MemoryContextSwitchTo(oldcontext);
}
* ------------------------------------------------------------------------
*/
PlanState *
-ExecInitNode(Plan *node, EState *estate, int eflags)
+ExecInitNode(Plan *node, EState *estate, PlanState *parent, int eflags)
{
PlanState *result;
List *subps;
break;
}
+ /* Set parent pointer. */
+ result->parent = parent;
+
/*
* Initialize any initPlans present in this node. The planner put them in
* a separate list for us.
if (node->aggstrategy == AGG_HASHED)
eflags &= ~EXEC_FLAG_REWIND;
outerPlan = outerPlan(node);
- outerPlanState(aggstate) = ExecInitNode(outerPlan, estate, eflags);
+ outerPlanState(aggstate) =
+ ExecInitNode(outerPlan, estate, &aggstate->ss.ps, eflags);
/*
* initialize source tuple type.
{
Plan *initNode = (Plan *) lfirst(lc);
- appendplanstates[i] = ExecInitNode(initNode, estate, eflags);
+ appendplanstates[i] = ExecInitNode(initNode, estate, &appendstate->ps,
+ eflags);
i++;
}
foreach(l, node->bitmapplans)
{
initNode = (Plan *) lfirst(l);
- bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags);
+ bitmapplanstates[i] = ExecInitNode(initNode, estate,
+ &bitmapandstate->ps, eflags);
i++;
}
* relation's indexes, and we want to be sure we have acquired a lock on
* the relation first.
*/
- outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate,
+ &scanstate->ss.ps, eflags);
/*
* all done.
foreach(l, node->bitmapplans)
{
initNode = (Plan *) lfirst(l);
- bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags);
+ bitmapplanstates[i] = ExecInitNode(initNode, estate,
+ &bitmaporstate->ps, eflags);
i++;
}
/* Initialize any outer plan. */
if (outerPlan(node))
outerPlanState(scanstate) =
- ExecInitNode(outerPlan(node), estate, eflags);
+ ExecInitNode(outerPlan(node), estate, &scanstate->ss.ps, eflags);
/*
* Tell the FDW to initialize the scan.
* now initialize outer plan
*/
outerNode = outerPlan(node);
- outerPlanState(gatherstate) = ExecInitNode(outerNode, estate, eflags);
+ outerPlanState(gatherstate) =
+ ExecInitNode(outerNode, estate, &gatherstate->ps, eflags);
gatherstate->ps.ps_TupFromTlist = false;
/*
* initialize child nodes
*/
- outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(grpstate) =
+ ExecInitNode(outerPlan(node), estate, &grpstate->ss.ps, eflags);
/*
* initialize tuple type.
/*
* initialize child nodes
*/
- outerPlanState(hashstate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(hashstate) =
+ ExecInitNode(outerPlan(node), estate, &hashstate->ps, eflags);
/*
* initialize tuple type. no need to initialize projection info because
outerNode = outerPlan(node);
hashNode = (Hash *) innerPlan(node);
- outerPlanState(hjstate) = ExecInitNode(outerNode, estate, eflags);
- innerPlanState(hjstate) = ExecInitNode((Plan *) hashNode, estate, eflags);
+ outerPlanState(hjstate) =
+ ExecInitNode(outerNode, estate, &hjstate->js.ps, eflags);
+ innerPlanState(hjstate) =
+ ExecInitNode((Plan *) hashNode, estate, &hjstate->js.ps, eflags);
/*
* tuple table initialization
* then initialize outer plan
*/
outerPlan = outerPlan(node);
- outerPlanState(limitstate) = ExecInitNode(outerPlan, estate, eflags);
+ outerPlanState(limitstate) =
+ ExecInitNode(outerPlan, estate, &limitstate->ps, eflags);
/*
* limit nodes do no projections, so initialize projection info for this
/*
* then initialize outer plan
*/
- outerPlanState(lrstate) = ExecInitNode(outerPlan, estate, eflags);
+ outerPlanState(lrstate) =
+ ExecInitNode(outerPlan, estate, &lrstate->ps, eflags);
/*
* LockRows nodes do no projections, so initialize projection info for
eflags &= ~(EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK);
outerPlan = outerPlan(node);
- outerPlanState(matstate) = ExecInitNode(outerPlan, estate, eflags);
+ outerPlanState(matstate) =
+ ExecInitNode(outerPlan, estate, &matstate->ss.ps, eflags);
/*
* initialize tuple type. no need to initialize projection info because
{
Plan *initNode = (Plan *) lfirst(lc);
- mergeplanstates[i] = ExecInitNode(initNode, estate, eflags);
+ mergeplanstates[i] =
+ ExecInitNode(initNode, estate, &mergestate->ps, eflags);
i++;
}
*
* inner child must support MARK/RESTORE.
*/
- outerPlanState(mergestate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(mergestate) =
+ ExecInitNode(outerPlan(node), estate, &mergestate->js.ps, eflags);
innerPlanState(mergestate) = ExecInitNode(innerPlan(node), estate,
+ &mergestate->js.ps,
eflags | EXEC_FLAG_MARK);
/*
/* Now init the plan for this result rel */
estate->es_result_relation_info = resultRelInfo;
- mtstate->mt_plans[i] = ExecInitNode(subplan, estate, eflags);
+ mtstate->mt_plans[i] =
+ ExecInitNode(subplan, estate, &mtstate->ps, eflags);
/* Also let FDWs init themselves for foreign-table result rels */
if (!resultRelInfo->ri_usesFdwDirectModify &&
* inner child, because it will always be rescanned with fresh parameter
* values.
*/
- outerPlanState(nlstate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(nlstate) =
+ ExecInitNode(outerPlan(node), estate, &nlstate->js.ps, eflags);
if (node->nestParams == NIL)
eflags |= EXEC_FLAG_REWIND;
else
eflags &= ~EXEC_FLAG_REWIND;
- innerPlanState(nlstate) = ExecInitNode(innerPlan(node), estate, eflags);
+ innerPlanState(nlstate) =
+ ExecInitNode(innerPlan(node), estate, &nlstate->js.ps, eflags);
/*
* tuple table initialization
/*
* initialize child nodes
*/
- outerPlanState(rustate) = ExecInitNode(outerPlan(node), estate, eflags);
- innerPlanState(rustate) = ExecInitNode(innerPlan(node), estate, eflags);
+ outerPlanState(rustate) =
+ ExecInitNode(outerPlan(node), estate, &rustate->ps, eflags);
+ innerPlanState(rustate) =
+ ExecInitNode(innerPlan(node), estate, &rustate->ps, eflags);
/*
* If hashing, precompute fmgr lookup data for inner loop, and create the
/*
* initialize child nodes
*/
- outerPlanState(resstate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(resstate) =
+ ExecInitNode(outerPlan(node), estate, &resstate->ps, eflags);
/*
* we don't use inner plan
*/
if (node->strategy == SETOP_HASHED)
eflags &= ~EXEC_FLAG_REWIND;
- outerPlanState(setopstate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(setopstate) =
+ ExecInitNode(outerPlan(node), estate, &setopstate->ps, eflags);
/*
* setop nodes do no projections, so initialize projection info for this
*/
eflags &= ~(EXEC_FLAG_REWIND | EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK);
- outerPlanState(sortstate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(sortstate) =
+ ExecInitNode(outerPlan(node), estate, &sortstate->ss.ps, eflags);
/*
* initialize tuple type. no need to initialize projection info because
/* ... and to its parent's state */
sstate->parent = parent;
+ sstate->planstate->parent = parent;
/* Initialize subexpressions */
sstate->testexpr = ExecInitExpr((Expr *) subplan->testexpr, parent);
/*
* initialize subquery
*/
- subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
+ subquerystate->subplan =
+ ExecInitNode(node->subplan, estate, &subquerystate->ss.ps, eflags);
subquerystate->ss.ps.ps_TupFromTlist = false;
/*
* then initialize outer plan
*/
- outerPlanState(uniquestate) = ExecInitNode(outerPlan(node), estate, eflags);
+ outerPlanState(uniquestate) =
+ ExecInitNode(outerPlan(node), estate, &uniquestate->ps, eflags);
/*
* unique nodes do no projections, so initialize projection info for this
* initialize child nodes
*/
outerPlan = outerPlan(node);
- outerPlanState(winstate) = ExecInitNode(outerPlan, estate, eflags);
+ outerPlanState(winstate) =
+ ExecInitNode(outerPlan, estate, &winstate->ss.ps, eflags);
/*
* initialize source tuple type (which is also the tuple type that we'll
/*
* prototypes from functions in execProcnode.c
*/
-extern PlanState *ExecInitNode(Plan *node, EState *estate, int eflags);
+extern PlanState *ExecInitNode(Plan *node, EState *estate, PlanState *parent,
+ int eflags);
extern TupleTableSlot *ExecProcNode(PlanState *node);
extern Node *MultiExecProcNode(PlanState *node);
extern void ExecEndNode(PlanState *node);
* nodes point to one EState for the whole
* top-level plan */
+ struct PlanState *parent; /* node which will receive tuples from us */
+
Instrumentation *instrument; /* Optional runtime stats for this node */
WorkerInstrumentation *worker_instrument; /* per-worker instrumentation */