From 905bb2c9a9e025f7cd0b5bd75e735f6e8f69f3cf Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Wed, 4 May 2016 12:19:03 -0400 Subject: [PATCH 1/3] Modify PlanState to include a pointer to the parent PlanState. --- src/backend/executor/execMain.c | 22 ++++++++++++++-------- src/backend/executor/execProcnode.c | 5 ++++- src/backend/executor/nodeAgg.c | 3 ++- src/backend/executor/nodeAppend.c | 3 ++- src/backend/executor/nodeBitmapAnd.c | 3 ++- src/backend/executor/nodeBitmapHeapscan.c | 3 ++- src/backend/executor/nodeBitmapOr.c | 3 ++- src/backend/executor/nodeForeignscan.c | 2 +- src/backend/executor/nodeGather.c | 3 ++- src/backend/executor/nodeGroup.c | 3 ++- src/backend/executor/nodeHash.c | 3 ++- src/backend/executor/nodeHashjoin.c | 6 ++++-- src/backend/executor/nodeLimit.c | 3 ++- src/backend/executor/nodeLockRows.c | 3 ++- src/backend/executor/nodeMaterial.c | 3 ++- src/backend/executor/nodeMergeAppend.c | 3 ++- src/backend/executor/nodeMergejoin.c | 4 +++- src/backend/executor/nodeModifyTable.c | 3 ++- src/backend/executor/nodeNestloop.c | 6 ++++-- src/backend/executor/nodeRecursiveunion.c | 6 ++++-- src/backend/executor/nodeResult.c | 3 ++- src/backend/executor/nodeSetOp.c | 3 ++- src/backend/executor/nodeSort.c | 3 ++- src/backend/executor/nodeSubplan.c | 1 + src/backend/executor/nodeSubqueryscan.c | 3 ++- src/backend/executor/nodeUnique.c | 3 ++- src/backend/executor/nodeWindowAgg.c | 3 ++- src/include/executor/executor.h | 3 ++- src/include/nodes/execnodes.h | 2 ++ 29 files changed, 77 insertions(+), 37 deletions(-) diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index ac02304..e0d0296 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -923,7 +923,10 @@ InitPlan(QueryDesc *queryDesc, int eflags) /* * 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 */ @@ -943,7 +946,7 @@ InitPlan(QueryDesc *queryDesc, int eflags) 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); @@ -954,9 +957,9 @@ InitPlan(QueryDesc *queryDesc, int eflags) /* * 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. @@ -2841,7 +2844,9 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) * 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) @@ -2849,7 +2854,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) 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); } @@ -2857,9 +2862,10 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) /* * 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); } diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index 554244f..680ca4b 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -133,7 +133,7 @@ * ------------------------------------------------------------------------ */ PlanState * -ExecInitNode(Plan *node, EState *estate, int eflags) +ExecInitNode(Plan *node, EState *estate, PlanState *parent, int eflags) { PlanState *result; List *subps; @@ -340,6 +340,9 @@ ExecInitNode(Plan *node, EState *estate, int eflags) break; } + /* Set parent pointer. */ + result->parent = parent; + /* * Initialize any initPlans present in this node. The planner put them in * a separate list for us. diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 0c1e4a3..e37551e 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -2448,7 +2448,8 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) 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. diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index a26bd63..beb4ab8 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -165,7 +165,8 @@ ExecInitAppend(Append *node, EState *estate, int eflags) { Plan *initNode = (Plan *) lfirst(lc); - appendplanstates[i] = ExecInitNode(initNode, estate, eflags); + appendplanstates[i] = ExecInitNode(initNode, estate, &appendstate->ps, + eflags); i++; } diff --git a/src/backend/executor/nodeBitmapAnd.c b/src/backend/executor/nodeBitmapAnd.c index c39d790..6405fa4 100644 --- a/src/backend/executor/nodeBitmapAnd.c +++ b/src/backend/executor/nodeBitmapAnd.c @@ -81,7 +81,8 @@ ExecInitBitmapAnd(BitmapAnd *node, EState *estate, int eflags) foreach(l, node->bitmapplans) { initNode = (Plan *) lfirst(l); - bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags); + bitmapplanstates[i] = ExecInitNode(initNode, estate, + &bitmapandstate->ps, eflags); i++; } diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 449aacb..2ba5cd0 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -646,7 +646,8 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) * 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. diff --git a/src/backend/executor/nodeBitmapOr.c b/src/backend/executor/nodeBitmapOr.c index 7e928eb..faa3a37 100644 --- a/src/backend/executor/nodeBitmapOr.c +++ b/src/backend/executor/nodeBitmapOr.c @@ -82,7 +82,8 @@ ExecInitBitmapOr(BitmapOr *node, EState *estate, int eflags) foreach(l, node->bitmapplans) { initNode = (Plan *) lfirst(l); - bitmapplanstates[i] = ExecInitNode(initNode, estate, eflags); + bitmapplanstates[i] = ExecInitNode(initNode, estate, + &bitmaporstate->ps, eflags); i++; } diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index 300f947..8418c5a 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -224,7 +224,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) /* 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. diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c index 3834ed6..2ac0c8d 100644 --- a/src/backend/executor/nodeGather.c +++ b/src/backend/executor/nodeGather.c @@ -97,7 +97,8 @@ ExecInitGather(Gather *node, EState *estate, int eflags) * 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; diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c index dcf5175..3c066fc 100644 --- a/src/backend/executor/nodeGroup.c +++ b/src/backend/executor/nodeGroup.c @@ -233,7 +233,8 @@ ExecInitGroup(Group *node, EState *estate, int eflags) /* * initialize child nodes */ - outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags); + outerPlanState(grpstate) = + ExecInitNode(outerPlan(node), estate, &grpstate->ss.ps, eflags); /* * initialize tuple type. diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index 9ed09a7..5e78de0 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -200,7 +200,8 @@ ExecInitHash(Hash *node, EState *estate, int eflags) /* * 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 diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 369e666..a7a908a 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -486,8 +486,10 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) 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 diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c index faf32e1..97267c5 100644 --- a/src/backend/executor/nodeLimit.c +++ b/src/backend/executor/nodeLimit.c @@ -412,7 +412,8 @@ ExecInitLimit(Limit *node, EState *estate, int eflags) * 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 diff --git a/src/backend/executor/nodeLockRows.c b/src/backend/executor/nodeLockRows.c index 4ebcaff..c4b5333 100644 --- a/src/backend/executor/nodeLockRows.c +++ b/src/backend/executor/nodeLockRows.c @@ -376,7 +376,8 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags) /* * 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 diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c index 9ab03f3..82e31c1 100644 --- a/src/backend/executor/nodeMaterial.c +++ b/src/backend/executor/nodeMaterial.c @@ -219,7 +219,8 @@ ExecInitMaterial(Material *node, EState *estate, int eflags) 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 diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index e271927..ae0e8dc 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -112,7 +112,8 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) { Plan *initNode = (Plan *) lfirst(lc); - mergeplanstates[i] = ExecInitNode(initNode, estate, eflags); + mergeplanstates[i] = + ExecInitNode(initNode, estate, &mergestate->ps, eflags); i++; } diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index 6db09b8..cd8d6c6 100644 --- a/src/backend/executor/nodeMergejoin.c +++ b/src/backend/executor/nodeMergejoin.c @@ -1522,8 +1522,10 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) * * 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); /* diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index e62c8aa..7bb318a 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -1618,7 +1618,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) /* 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 && diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c index 555fa09..1895b60 100644 --- a/src/backend/executor/nodeNestloop.c +++ b/src/backend/executor/nodeNestloop.c @@ -340,12 +340,14 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags) * 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 diff --git a/src/backend/executor/nodeRecursiveunion.c b/src/backend/executor/nodeRecursiveunion.c index e76405a..2328ef3 100644 --- a/src/backend/executor/nodeRecursiveunion.c +++ b/src/backend/executor/nodeRecursiveunion.c @@ -245,8 +245,10 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags) /* * 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 diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c index 4007b76..0d2de14 100644 --- a/src/backend/executor/nodeResult.c +++ b/src/backend/executor/nodeResult.c @@ -250,7 +250,8 @@ ExecInitResult(Result *node, EState *estate, int eflags) /* * 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 diff --git a/src/backend/executor/nodeSetOp.c b/src/backend/executor/nodeSetOp.c index 2d81d46..7a3b67c 100644 --- a/src/backend/executor/nodeSetOp.c +++ b/src/backend/executor/nodeSetOp.c @@ -537,7 +537,8 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags) */ 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 diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c index a34dcc5..0286a7f 100644 --- a/src/backend/executor/nodeSort.c +++ b/src/backend/executor/nodeSort.c @@ -199,7 +199,8 @@ ExecInitSort(Sort *node, EState *estate, int eflags) */ 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 diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index e503494..458e254 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -707,6 +707,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) /* ... and to its parent's state */ sstate->parent = parent; + sstate->planstate->parent = parent; /* Initialize subexpressions */ sstate->testexpr = ExecInitExpr((Expr *) subplan->testexpr, parent); diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c index 0304b15..75a28fd 100644 --- a/src/backend/executor/nodeSubqueryscan.c +++ b/src/backend/executor/nodeSubqueryscan.c @@ -144,7 +144,8 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags) /* * 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; diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c index 4caae34..5d13a89 100644 --- a/src/backend/executor/nodeUnique.c +++ b/src/backend/executor/nodeUnique.c @@ -145,7 +145,8 @@ ExecInitUnique(Unique *node, EState *estate, int eflags) /* * 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 diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index f06eebe..3dc6757 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -1844,7 +1844,8 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) * 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 diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 44fac27..f1be8fa 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -221,7 +221,8 @@ extern void EvalPlanQualEnd(EPQState *epqstate); /* * 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); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index ee4e189..7d33b6d 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -1030,6 +1030,8 @@ typedef struct PlanState * 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 */ -- 2.5.4 (Apple Git-61)