Modify PlanState to include a pointer to the parent PlanState.
authorRobert Haas <rhaas@postgresql.org>
Wed, 4 May 2016 16:19:03 +0000 (12:19 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 20 Sep 2016 16:39:56 +0000 (12:39 -0400)
29 files changed:
src/backend/executor/execMain.c
src/backend/executor/execProcnode.c
src/backend/executor/nodeAgg.c
src/backend/executor/nodeAppend.c
src/backend/executor/nodeBitmapAnd.c
src/backend/executor/nodeBitmapHeapscan.c
src/backend/executor/nodeBitmapOr.c
src/backend/executor/nodeForeignscan.c
src/backend/executor/nodeGather.c
src/backend/executor/nodeGroup.c
src/backend/executor/nodeHash.c
src/backend/executor/nodeHashjoin.c
src/backend/executor/nodeLimit.c
src/backend/executor/nodeLockRows.c
src/backend/executor/nodeMaterial.c
src/backend/executor/nodeMergeAppend.c
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeModifyTable.c
src/backend/executor/nodeNestloop.c
src/backend/executor/nodeRecursiveunion.c
src/backend/executor/nodeResult.c
src/backend/executor/nodeSetOp.c
src/backend/executor/nodeSort.c
src/backend/executor/nodeSubplan.c
src/backend/executor/nodeSubqueryscan.c
src/backend/executor/nodeUnique.c
src/backend/executor/nodeWindowAgg.c
src/include/executor/executor.h
src/include/nodes/execnodes.h

index 32bb3f9205491e5467cc2cc297fcb9387ac48a9c..ac6d62c3b57f4a7afe582cd66fb7cf73de1c7683 100644 (file)
@@ -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.
@@ -2849,7 +2852,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)
@@ -2857,7 +2862,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);
        }
@@ -2865,9 +2870,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);
 }
index 554244ff71f89e49b7543d8a7849b9b7ed069d82..680ca4b4ed6b2cc8bc42600568d74d61c50b0671 100644 (file)
  * ------------------------------------------------------------------------
  */
 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.
index ce2fc281a43bb445d6d592921bf885e136303b62..d6aa99c76cadb16d7a071d93ccb6dbe69c21bc3b 100644 (file)
@@ -2427,7 +2427,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.
index a26bd6354c1183ebe71408412cb35f67e9b8f898..beb4ab883de1ff79d8d215be6f972f1d2b7e67fd 100644 (file)
@@ -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++;
        }
 
index c39d790f82d2afe6a9b262973eaf573b24acf3a4..6405fa476b4e6560115ecae818d58a6cb57ef6c2 100644 (file)
@@ -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++;
        }
 
index 449aacb6e740a75fa9c85356eeaef0aa080f0115..2ba5cd0514afe3d538a05b8445134632d9805d30 100644 (file)
@@ -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.
index 7e928eb618ce9ae7815cf71b84c70827b82375a1..faa3a37fc57783942cdc718dcd03fb9b5df65770 100644 (file)
@@ -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++;
        }
 
index d886aaf64d6776252020622ddd454633791f1f25..7d9160df95ba96bb334f3eb938c3c93fb0eee96b 100644 (file)
@@ -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.
index 438d1b24fc2e4be8d1b56206a337269e23c0a8bf..1bf5a31dc59fa93a33ea8a18049743f1e87294b9 100644 (file)
@@ -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;
 
index dcf5175d9be0abca524c22fb77ebab75779de152..3c066fc55e8b72067bd56212123fac7aea0baf25 100644 (file)
@@ -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.
index 6375d9bfda7ee2818fe59540d1c24be21e49be40..8333e5c861adc880bba8b90fd0b54629fe2bb673 100644 (file)
@@ -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
index 369e666f8850df141b17ece36d172cc98c975bd4..a7a908a903dc5cb77e1c369207d7c4c144f90654 100644 (file)
@@ -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
index faf32e1aeedd4554e4df31cf6d8e9caf53aee151..97267c587c6caebf57ef806212ba5fccd96ac87a 100644 (file)
@@ -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
index 4ebcaffe699a40d99b66b05331ffa17e9756da7d..c4b533354b998d9f44aed3d0bb94cb6e2f826570 100644 (file)
@@ -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
index 9ab03f3f152bc82983589bdf086f9ba24a46f10f..82e31c123d2f2e233563815dd2c3a4b669685047 100644 (file)
@@ -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
index e271927077b8bec79d7ad71eb0384f74f770fe8d..ae0e8dce68609599d3fe86405a55a9c0ee187ee2 100644 (file)
@@ -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++;
        }
 
index 6db09b836a113358a4bb055f079aaeafdc20dc85..cd8d6c68c1d2a5374c085c476c6514423b95f06e 100644 (file)
@@ -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);
 
        /*
index af7b26c0ef01ae5db18394db8740cef7e06afe1f..95cc2c63a56bc87d2eecd70d8cd4130b77146963 100644 (file)
@@ -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 &&
index 555fa0967900e0c59be65c265351470cf0151789..1895b60459d13c0bb5d9e297d35d2b006b609ba5 100644 (file)
@@ -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
index 39be191c45b0459b0f7ddb3e2360fb0f32804a67..627370f56c54ebc99c1c056b167344168335db53 100644 (file)
@@ -241,8 +241,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
index 4007b765bf8fcce9e3dd23827d1452ccd6c7890f..0d2de14f87459d57545717d35ed6f43360a200ad 100644 (file)
@@ -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
index 633580b4362af9b9dd9efd01510b2cc1f94dbca2..8b05795dfd6727967ccf6d41571b88cb15c823bd 100644 (file)
@@ -533,7 +533,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
index a34dcc513582e1dd5fe7f7d32c0cdc6e31117f50..0286a7fdf37fe322995267c31da6f3c9b91a3a01 100644 (file)
@@ -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
index 2cf169f956620c5720c8d0a29c6f1f7b205b309e..db198872b400091c17a0f903d18c21055276089c 100644 (file)
@@ -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);
index 9bafc62677259d8f2c1a69b74a51a137ffc54131..cb007a578cba023e1fde9a170fc7b8d9acb15e2b 100644 (file)
@@ -136,7 +136,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;
 
index f45c79232dfa6f15a02ad68ff0a00bceac85ea85..3b89e846672cda9084c1d4d650a0a27f039643e6 100644 (file)
@@ -143,7 +143,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
index 371548ceb39079af2a082b78bd33fa8b6b6edea3..f12fe2689242a1a6a50175950b1a780cc87a2b2e 100644 (file)
@@ -1840,7 +1840,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
index 39521ed08e36c1b893934db6de20c53d9ab0664c..28c0c2e1bb1dc5bf06f47e3ffd9e40acf42c27a6 100644 (file)
@@ -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);
index 4fa366178f5ee14f4fa3aef56454c54eae731218..e8bebef5df049abeb17469b58b497e165d96e169 100644 (file)
@@ -1031,6 +1031,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 */