In executor context, outerPlanState(node) is the same as
node->ss.ps.lefttree. We follow this in most places except a few. This
patch clean up the outliers and might save us a few instructions by
removing indirection.

Most of changes are trivial. Except I take out an outerPlan nullable
check in grouping iterator - as a it surely has a left child.

I noticed that we mixed use "node" for plan node and plan state. While
changing it can make code clear, but back patching could be terrible.


Regards,
Qingqing
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 9ff0eff..672825a 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -2054,10 +2054,11 @@ ExecReScanAgg(AggState *node)
 {
        ExprContext *econtext = node->ss.ps.ps_ExprContext;
        int                     aggno;
+       PlanState       *outerPlan;
 
        node->agg_done = false;
-
        node->ss.ps.ps_TupFromTlist = false;
+       outerPlan = outerPlanState(node);
 
        if (((Agg *) node->ss.ps.plan)->aggstrategy == AGG_HASHED)
        {
@@ -2075,7 +2076,7 @@ ExecReScanAgg(AggState *node)
                 * parameter changes, then we can just rescan the existing hash 
table;
                 * no need to build it again.
                 */
-               if (node->ss.ps.lefttree->chgParam == NULL)
+               if (outerPlan->chgParam == NULL)
                {
                        ResetTupleHashIterator(node->hashtable, 
&node->hashiter);
                        return;
@@ -2133,8 +2134,8 @@ ExecReScanAgg(AggState *node)
         * if chgParam of subnode is not null then plan will be re-scanned by
         * first ExecProcNode.
         */
-       if (node->ss.ps.lefttree->chgParam == NULL)
-               ExecReScan(node->ss.ps.lefttree);
+       if (outerPlan->chgParam == NULL)
+               ExecReScan(outerPlan);
 }
 
 
diff --git a/src/backend/executor/nodeBitmapHeapscan.c 
b/src/backend/executor/nodeBitmapHeapscan.c
index 8ea8b9f..6502841 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -449,6 +449,8 @@ ExecBitmapHeapScan(BitmapHeapScanState *node)
 void
 ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
 {
+       PlanState       *outerPlan;
+
        /* rescan to release any page pin */
        heap_rescan(node->ss.ss_currentScanDesc, NULL);
 
@@ -469,8 +471,9 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node)
         * if chgParam of subnode is not null then plan will be re-scanned by
         * first ExecProcNode.
         */
-       if (node->ss.ps.lefttree->chgParam == NULL)
-               ExecReScan(node->ss.ps.lefttree);
+       outerPlan = outerPlanState(node);
+       if (outerPlan->chgParam == NULL)
+               ExecReScan(outerPlan);
 }
 
 /* ----------------------------------------------------------------
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index 83d562e..b0d5442 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -280,6 +280,8 @@ ExecEndGroup(GroupState *node)
 void
 ExecReScanGroup(GroupState *node)
 {
+       PlanState       *outerPlan;
+       
        node->grp_done = FALSE;
        node->ss.ps.ps_TupFromTlist = false;
        /* must clear first tuple */
@@ -289,7 +291,7 @@ ExecReScanGroup(GroupState *node)
         * if chgParam of subnode is not null then plan will be re-scanned by
         * first ExecProcNode.
         */
-       if (node->ss.ps.lefttree &&
-               node->ss.ps.lefttree->chgParam == NULL)
-               ExecReScan(node->ss.ps.lefttree);
+       outerPlan = outerPlanState(node);
+       if (outerPlan->chgParam == NULL)
+               ExecReScan(outerPlan);
 }
diff --git a/src/backend/executor/nodeMaterial.c 
b/src/backend/executor/nodeMaterial.c
index 1158825..41859e0 100644
--- a/src/backend/executor/nodeMaterial.c
+++ b/src/backend/executor/nodeMaterial.c
@@ -317,6 +317,9 @@ ExecMaterialRestrPos(MaterialState *node)
 void
 ExecReScanMaterial(MaterialState *node)
 {
+       PlanState       *outerPlan;
+
+       outerPlan = outerPlanState(node);
        ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
 
        if (node->eflags != 0)
@@ -339,13 +342,13 @@ ExecReScanMaterial(MaterialState *node)
                 * Otherwise we can just rewind and rescan the stored output. 
The
                 * state of the subnode does not change.
                 */
-               if (node->ss.ps.lefttree->chgParam != NULL ||
+               if (outerPlan->chgParam != NULL ||
                        (node->eflags & EXEC_FLAG_REWIND) == 0)
                {
                        tuplestore_end(node->tuplestorestate);
                        node->tuplestorestate = NULL;
-                       if (node->ss.ps.lefttree->chgParam == NULL)
-                               ExecReScan(node->ss.ps.lefttree);
+                       if (outerPlan->chgParam == NULL)
+                               ExecReScan(outerPlan);
                        node->eof_underlying = false;
                }
                else
@@ -359,8 +362,8 @@ ExecReScanMaterial(MaterialState *node)
                 * if chgParam of subnode is not null then plan will be 
re-scanned by
                 * first ExecProcNode.
                 */
-               if (node->ss.ps.lefttree->chgParam == NULL)
-                       ExecReScan(node->ss.ps.lefttree);
+               if (outerPlan->chgParam == NULL)
+                       ExecReScan(outerPlan);
                node->eof_underlying = false;
        }
 }
diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c
index a815cde..32e064e 100644
--- a/src/backend/executor/nodeSort.c
+++ b/src/backend/executor/nodeSort.c
@@ -290,6 +290,8 @@ ExecSortRestrPos(SortState *node)
 void
 ExecReScanSort(SortState *node)
 {
+       PlanState       *outerPlan;
+       
        /*
         * If we haven't sorted yet, just return. If outerplan's chgParam is not
         * NULL then it will be re-scanned by ExecProcNode, else no reason to
@@ -299,6 +301,7 @@ ExecReScanSort(SortState *node)
                return;
 
        /* must drop pointer to sort result tuple */
+       outerPlan = outerPlanState(node);
        ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
 
        /*
@@ -308,7 +311,7 @@ ExecReScanSort(SortState *node)
         *
         * Otherwise we can just rewind and rescan the sorted output.
         */
-       if (node->ss.ps.lefttree->chgParam != NULL ||
+       if (outerPlan->chgParam != NULL ||
                node->bounded != node->bounded_Done ||
                node->bound != node->bound_Done ||
                !node->randomAccess)
@@ -321,8 +324,8 @@ ExecReScanSort(SortState *node)
                 * if chgParam of subnode is not null then plan will be 
re-scanned by
                 * first ExecProcNode.
                 */
-               if (node->ss.ps.lefttree->chgParam == NULL)
-                       ExecReScan(node->ss.ps.lefttree);
+               if (outerPlan->chgParam == NULL)
+                       ExecReScan(outerPlan);
        }
        else
                tuplesort_rescan((Tuplesortstate *) node->tuplesortstate);
diff --git a/src/backend/executor/nodeWindowAgg.c 
b/src/backend/executor/nodeWindowAgg.c
index a06790d..520be66 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -2057,6 +2057,7 @@ ExecEndWindowAgg(WindowAggState *node)
 void
 ExecReScanWindowAgg(WindowAggState *node)
 {
+       PlanState       *outerPlan;
        ExprContext *econtext = node->ss.ps.ps_ExprContext;
 
        node->all_done = false;
@@ -2082,8 +2083,9 @@ ExecReScanWindowAgg(WindowAggState *node)
         * if chgParam of subnode is not null then plan will be re-scanned by
         * first ExecProcNode.
         */
-       if (node->ss.ps.lefttree->chgParam == NULL)
-               ExecReScan(node->ss.ps.lefttree);
+       outerPlan = outerPlanState(node);
+       if (outerPlan->chgParam == NULL)
+               ExecReScan(outerPlan);
 }
 
 /*
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to