From e2bfb13eab7e06dd6691ccdfba54166a7bf3ba8c Mon Sep 17 00:00:00 2001
From: Arseny Sher <sher-ars@ispras.ru>
Date: Fri, 10 Mar 2017 15:02:37 +0300
Subject: [PATCH 1/8] parent param added to ExecInitNode, parent field added to
 PlanState

---
 src/backend/executor/execMain.c           | 8 ++++----
 src/backend/executor/execProcnode.c       | 3 ++-
 src/backend/executor/nodeAgg.c            | 2 +-
 src/backend/executor/nodeAppend.c         | 2 +-
 src/backend/executor/nodeBitmapAnd.c      | 2 +-
 src/backend/executor/nodeBitmapHeapscan.c | 2 +-
 src/backend/executor/nodeBitmapOr.c       | 2 +-
 src/backend/executor/nodeForeignscan.c    | 2 +-
 src/backend/executor/nodeGather.c         | 2 +-
 src/backend/executor/nodeGatherMerge.c    | 2 +-
 src/backend/executor/nodeGroup.c          | 2 +-
 src/backend/executor/nodeHash.c           | 3 ++-
 src/backend/executor/nodeHashjoin.c       | 6 ++++--
 src/backend/executor/nodeLimit.c          | 2 +-
 src/backend/executor/nodeLockRows.c       | 2 +-
 src/backend/executor/nodeMaterial.c       | 2 +-
 src/backend/executor/nodeMergeAppend.c    | 2 +-
 src/backend/executor/nodeMergejoin.c      | 5 +++--
 src/backend/executor/nodeModifyTable.c    | 2 +-
 src/backend/executor/nodeNestloop.c       | 4 ++--
 src/backend/executor/nodeProjectSet.c     | 2 +-
 src/backend/executor/nodeRecursiveunion.c | 4 ++--
 src/backend/executor/nodeResult.c         | 2 +-
 src/backend/executor/nodeSetOp.c          | 2 +-
 src/backend/executor/nodeSort.c           | 2 +-
 src/backend/executor/nodeSubqueryscan.c   | 2 +-
 src/backend/executor/nodeUnique.c         | 2 +-
 src/backend/executor/nodeWindowAgg.c      | 2 +-
 src/include/executor/executor.h           | 3 ++-
 src/include/nodes/execnodes.h             | 1 +
 30 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index f5cd65d8a0..efb3f30dd0 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -955,7 +955,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, sp_eflags, NULL);
 
 		estate->es_subplanstates = lappend(estate->es_subplanstates,
 										   subplanstate);
@@ -968,7 +968,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
 	 * tree.  This opens files, allocates storage and leaves us ready to start
 	 * processing tuples.
 	 */
-	planstate = ExecInitNode(plan, estate, eflags);
+	planstate = ExecInitNode(plan, estate, eflags, NULL);
 
 	/*
 	 * Get the tuple descriptor describing the type of tuples to return.
@@ -3006,7 +3006,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
 		Plan	   *subplan = (Plan *) lfirst(l);
 		PlanState  *subplanstate;
 
-		subplanstate = ExecInitNode(subplan, estate, 0);
+		subplanstate = ExecInitNode(subplan, estate, 0, NULL);
 		estate->es_subplanstates = lappend(estate->es_subplanstates,
 										   subplanstate);
 	}
@@ -3016,7 +3016,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
 	 * of the plan tree we need to run.  This opens files, allocates storage
 	 * and leaves us ready to start processing tuples.
 	 */
-	epqstate->planstate = ExecInitNode(planTree, estate, 0);
+	epqstate->planstate = ExecInitNode(planTree, estate, 0, NULL);
 
 	MemoryContextSwitchTo(oldcontext);
 }
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 80c77addb8..c1c4cecd6c 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -131,12 +131,13 @@
  *		  '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
+ *        'parent' is parent of the node
  *
  *		Returns a PlanState node corresponding to the given Plan node.
  * ------------------------------------------------------------------------
  */
 PlanState *
-ExecInitNode(Plan *node, EState *estate, int eflags)
+ExecInitNode(Plan *node, EState *estate, int eflags, PlanState *parent)
 {
 	PlanState  *result;
 	List	   *subps;
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 3207ee460c..fa19358d19 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -2523,7 +2523,7 @@ 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, eflags, NULL);
 
 	/*
 	 * initialize source tuple type.
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index 6986caee6b..752b22d219 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -165,7 +165,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
 	{
 		Plan	   *initNode = (Plan *) lfirst(lc);
 
-		appendplanstates[i] = ExecInitNode(initNode, estate, eflags);
+		appendplanstates[i] = ExecInitNode(initNode, estate, eflags, NULL);
 		i++;
 	}
 
diff --git a/src/backend/executor/nodeBitmapAnd.c b/src/backend/executor/nodeBitmapAnd.c
index e4eb028ff9..c2a2f7d30a 100644
--- a/src/backend/executor/nodeBitmapAnd.c
+++ b/src/backend/executor/nodeBitmapAnd.c
@@ -81,7 +81,7 @@ 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, eflags, NULL);
 		i++;
 	}
 
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 2e9ff7d1b9..c0bcfb5d98 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -903,7 +903,7 @@ 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, eflags, NULL);
 
 	/*
 	 * all done.
diff --git a/src/backend/executor/nodeBitmapOr.c b/src/backend/executor/nodeBitmapOr.c
index c0f261407b..c834e29abb 100644
--- a/src/backend/executor/nodeBitmapOr.c
+++ b/src/backend/executor/nodeBitmapOr.c
@@ -82,7 +82,7 @@ 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, eflags, NULL);
 		i++;
 	}
 
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c
index 3b6d1390eb..2e6ceb8b34 100644
--- a/src/backend/executor/nodeForeignscan.c
+++ b/src/backend/executor/nodeForeignscan.c
@@ -222,7 +222,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, eflags, NULL);
 
 	/*
 	 * Tell the FDW to initialize the scan.
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index 32c97d390e..0031898acf 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -98,7 +98,7 @@ 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, eflags, NULL);
 
 	/*
 	 * Initialize result tuple type and projection info.
diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c
index 72f30ab4e6..7ed0c5bc0c 100644
--- a/src/backend/executor/nodeGatherMerge.c
+++ b/src/backend/executor/nodeGatherMerge.c
@@ -102,7 +102,7 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags)
 	 * now initialize outer plan
 	 */
 	outerNode = outerPlan(node);
-	outerPlanState(gm_state) = ExecInitNode(outerNode, estate, eflags);
+	outerPlanState(gm_state) = ExecInitNode(outerNode, estate, eflags, NULL);
 
 	/*
 	 * Initialize result tuple type and projection info.
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index 66c095bc72..5338e29187 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -198,7 +198,7 @@ ExecInitGroup(Group *node, EState *estate, int eflags)
 	/*
 	 * initialize child nodes
 	 */
-	outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags);
+	outerPlanState(grpstate) = ExecInitNode(outerPlan(node), estate, eflags, NULL);
 
 	/*
 	 * initialize tuple type.
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index e695d8834b..43e65ca04e 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, eflags,
+											 (PlanState*) hashstate);
 
 	/*
 	 * 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 c50d93f43d..b48863f90b 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -435,8 +435,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, eflags,
+										   (PlanState *) hjstate);
+	innerPlanState(hjstate) = ExecInitNode((Plan *) hashNode, estate, eflags,
+										   (PlanState *) hjstate);
 
 	/*
 	 * tuple table initialization
diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c
index aaec132218..bcacbfc13b 100644
--- a/src/backend/executor/nodeLimit.c
+++ b/src/backend/executor/nodeLimit.c
@@ -403,7 +403,7 @@ 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, eflags, NULL);
 
 	/*
 	 * 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 b098034337..446a5e6fb3 100644
--- a/src/backend/executor/nodeLockRows.c
+++ b/src/backend/executor/nodeLockRows.c
@@ -376,7 +376,7 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags)
 	/*
 	 * then initialize outer plan
 	 */
-	outerPlanState(lrstate) = ExecInitNode(outerPlan, estate, eflags);
+	outerPlanState(lrstate) = ExecInitNode(outerPlan, estate, eflags, NULL);
 
 	/*
 	 * 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 aa5d2529f4..97d025977f 100644
--- a/src/backend/executor/nodeMaterial.c
+++ b/src/backend/executor/nodeMaterial.c
@@ -219,7 +219,7 @@ 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, eflags, NULL);
 
 	/*
 	 * 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 7a20bf07a4..0327cf9a2a 100644
--- a/src/backend/executor/nodeMergeAppend.c
+++ b/src/backend/executor/nodeMergeAppend.c
@@ -112,7 +112,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
 	{
 		Plan	   *initNode = (Plan *) lfirst(lc);
 
-		mergeplanstates[i] = ExecInitNode(initNode, estate, eflags);
+		mergeplanstates[i] = ExecInitNode(initNode, estate, eflags, NULL);
 		i++;
 	}
 
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index 105e2dcedb..68c53ba1fe 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -1473,9 +1473,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, eflags, NULL);
 	innerPlanState(mergestate) = ExecInitNode(innerPlan(node), estate,
-											  eflags | EXEC_FLAG_MARK);
+											  eflags | EXEC_FLAG_MARK,
+											  NULL);
 
 	/*
 	 * For certain types of inner child nodes, it is advantageous to issue
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 95e158970c..ee6e4e7946 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -1703,7 +1703,7 @@ 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, eflags, NULL);
 
 		/* 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 cac7ba1b9b..697f5d48a2 100644
--- a/src/backend/executor/nodeNestloop.c
+++ b/src/backend/executor/nodeNestloop.c
@@ -302,12 +302,12 @@ 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, eflags, NULL);
 	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, eflags, NULL);
 
 	/*
 	 * tuple table initialization
diff --git a/src/backend/executor/nodeProjectSet.c b/src/backend/executor/nodeProjectSet.c
index eae0f1dad9..0c61685430 100644
--- a/src/backend/executor/nodeProjectSet.c
+++ b/src/backend/executor/nodeProjectSet.c
@@ -240,7 +240,7 @@ ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags)
 	/*
 	 * initialize child nodes
 	 */
-	outerPlanState(state) = ExecInitNode(outerPlan(node), estate, eflags);
+	outerPlanState(state) = ExecInitNode(outerPlan(node), estate, eflags, NULL);
 
 	/*
 	 * we don't use inner plan
diff --git a/src/backend/executor/nodeRecursiveunion.c b/src/backend/executor/nodeRecursiveunion.c
index fc1c00d68f..4b91f155c9 100644
--- a/src/backend/executor/nodeRecursiveunion.c
+++ b/src/backend/executor/nodeRecursiveunion.c
@@ -235,8 +235,8 @@ 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, eflags, NULL);
+	innerPlanState(rustate) = ExecInitNode(innerPlan(node), estate, eflags, NULL);
 
 	/*
 	 * 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 b5b50b21e9..bbc0c82c3f 100644
--- a/src/backend/executor/nodeResult.c
+++ b/src/backend/executor/nodeResult.c
@@ -221,7 +221,7 @@ ExecInitResult(Result *node, EState *estate, int eflags)
 	/*
 	 * initialize child nodes
 	 */
-	outerPlanState(resstate) = ExecInitNode(outerPlan(node), estate, eflags);
+	outerPlanState(resstate) = ExecInitNode(outerPlan(node), estate, eflags, NULL);
 
 	/*
 	 * we don't use inner plan
diff --git a/src/backend/executor/nodeSetOp.c b/src/backend/executor/nodeSetOp.c
index 85b3f67b33..f437ec1044 100644
--- a/src/backend/executor/nodeSetOp.c
+++ b/src/backend/executor/nodeSetOp.c
@@ -526,7 +526,7 @@ 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, eflags, NULL);
 
 	/*
 	 * 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 591a31aa6a..0028912509 100644
--- a/src/backend/executor/nodeSort.c
+++ b/src/backend/executor/nodeSort.c
@@ -199,7 +199,7 @@ 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, eflags, NULL);
 
 	/*
 	 * initialize tuple type.  no need to initialize projection info because
diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c
index 230a96f9d2..b3cbe266dc 100644
--- a/src/backend/executor/nodeSubqueryscan.c
+++ b/src/backend/executor/nodeSubqueryscan.c
@@ -136,7 +136,7 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags)
 	/*
 	 * initialize subquery
 	 */
-	subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags);
+	subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags, NULL);
 
 	/*
 	 * Initialize scan tuple type (needed by ExecAssignScanProjectionInfo)
diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c
index 28cc1e90f8..244c49f2dc 100644
--- a/src/backend/executor/nodeUnique.c
+++ b/src/backend/executor/nodeUnique.c
@@ -143,7 +143,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags)
 	/*
 	 * then initialize outer plan
 	 */
-	outerPlanState(uniquestate) = ExecInitNode(outerPlan(node), estate, eflags);
+	outerPlanState(uniquestate) = ExecInitNode(outerPlan(node), estate, eflags, NULL);
 
 	/*
 	 * 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 2a123e8452..39971458d1 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -1841,7 +1841,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags)
 	 * initialize child nodes
 	 */
 	outerPlan = outerPlan(node);
-	outerPlanState(winstate) = ExecInitNode(outerPlan, estate, eflags);
+	outerPlanState(winstate) = ExecInitNode(outerPlan, estate, eflags, NULL);
 
 	/*
 	 * 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 02dbe7b228..716362970f 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -234,7 +234,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, int eflags,
+	PlanState *parent);
 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 f856f6036f..738f098b00 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -1062,6 +1062,7 @@ typedef struct PlanState
 	 */
 	List	   *targetlist;		/* target list to be computed at this node */
 	List	   *qual;			/* implicitly-ANDed qual conditions */
+	struct PlanState *parent;   /* parent node, NULL if root */
 	struct PlanState *lefttree; /* input plan tree(s) */
 	struct PlanState *righttree;
 	List	   *initPlan;		/* Init SubPlanState nodes (un-correlated expr
-- 
2.11.0

