]> granicus.if.org Git - postgresql/commitdiff
Revert incorrect memory-conservation hack in inheritance_planner().
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 13 Jan 2011 19:33:19 +0000 (14:33 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 13 Jan 2011 19:33:19 +0000 (14:33 -0500)
This reverts commit d1001a78ce612a16ea622b558f5fc2b68c45ab4c of 2010-12-05,
which was broken as reported by Jeff Davis.  The problem is that the
individual planning steps may have side-effects on substructures of
PlannerGlobal, not only the current PlannerInfo root.  Arranging to keep
all such side effects in the main planning context is probably possible,
but it would change this from a quick local hack into a wide-ranging and
rather fragile endeavor.  Which it's not worth.

src/backend/optimizer/plan/planner.c

index d52ebd0ea1998be2725df9984710039931fdf3f7..b52eebe2aac590dee553784a15114a61cf839853 100644 (file)
@@ -41,7 +41,6 @@
 #include "parser/parse_oper.h"
 #include "parser/parsetree.h"
 #include "utils/lsyscache.h"
-#include "utils/memutils.h"
 #include "utils/syscache.h"
 
 
@@ -742,52 +741,19 @@ inheritance_planner(PlannerInfo *root)
        List       *rowMarks;
        List       *tlist;
        PlannerInfo subroot;
-       MemoryContext childcxt;
        ListCell   *l;
 
-       /*
-        * Memory management here is a bit messy, because the planning process can
-        * scribble on both the query parsetree and the rangetable.  We need to
-        * ensure that each call of grouping_planner gets an un-scribbled-on copy
-        * to start with, so we start by copying the given query tree each time
-        * (as a byproduct of adjust_appendrel_attrs).  However, we also want to
-        * make sure that the modified rangetable ultimately gets propagated back
-        * to the master copy, to pick up any changes of the Query structures
-        * inside subquery RTEs.  We do that by copying back the rangetable from
-        * the first successful child planning step.  (We are effectively assuming
-        * that sub-Queries will get planned identically each time, or at least
-        * that the impacts on their rangetables will be the same each time.)
-        *
-        * Another consideration is that when there are a lot of child tables, we
-        * can eat a lot of memory this way.  To fix that, we create a child
-        * memory context that can be reset between steps to recover memory, at
-        * the cost of having to copy the completed plan trees out to the parent
-        * context.
-        */
-       childcxt = AllocSetContextCreate(CurrentMemoryContext,
-                                                                        "Inheritance child planning context",
-                                                                        ALLOCSET_DEFAULT_MINSIZE,
-                                                                        ALLOCSET_DEFAULT_INITSIZE,
-                                                                        ALLOCSET_DEFAULT_MAXSIZE);
-
        foreach(l, root->append_rel_list)
        {
                AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
                Plan       *subplan;
-               MemoryContext oldcxt;
 
                /* append_rel_list contains all append rels; ignore others */
                if (appinfo->parent_relid != parentRTindex)
                        continue;
 
                /*
-                * Discard any cruft generated in previous loop iterations.
-                */
-               MemoryContextReset(childcxt);
-               oldcxt = MemoryContextSwitchTo(childcxt);
-
-               /*
-                * Generate modified query (in childcxt) with this rel as target.
+                * Generate modified query with this rel as target.
                 */
                memcpy(&subroot, root, sizeof(PlannerInfo));
                subroot.parse = (Query *)
@@ -801,11 +767,9 @@ inheritance_planner(PlannerInfo *root)
                /* and we haven't created PlaceHolderInfos, either */
                Assert(subroot.placeholder_list == NIL);
 
-               /* Generate plan (also in childcxt) */
+               /* Generate plan */
                subplan = grouping_planner(&subroot, 0.0 /* retrieve all tuples */ );
 
-               MemoryContextSwitchTo(oldcxt);
-
                /*
                 * If this child rel was excluded by constraint exclusion, exclude it
                 * from the plan.
@@ -813,20 +777,14 @@ inheritance_planner(PlannerInfo *root)
                if (is_dummy_plan(subplan))
                        continue;
 
-               /*
-                * Be sure to copy what we need out of the child context.
-                */
-               subplan = copyObject(subplan);
-
-               /* Save rtable from first child to install in parent after the loop */
+               /* Save rtable from first rel for use below */
                if (subplans == NIL)
-                       rtable = copyObject(subroot.parse->rtable);
+                       rtable = subroot.parse->rtable;
 
                subplans = lappend(subplans, subplan);
 
                /* Make sure any initplans from this rel get into the outer list */
-               root->init_plans = list_concat(root->init_plans,
-                                                                          copyObject(subroot.init_plans));
+               root->init_plans = list_concat(root->init_plans, subroot.init_plans);
 
                /* Build target-relations list for the executor */
                resultRelations = lappend_int(resultRelations, appinfo->child_relid);
@@ -836,18 +794,14 @@ inheritance_planner(PlannerInfo *root)
                {
                        List       *rlist;
 
-                       rlist = copyObject(subroot.parse->returningList);
                        rlist = set_returning_clause_references(root->glob,
-                                                                                                       rlist,
+                                                                                               subroot.parse->returningList,
                                                                                                        subplan,
                                                                                                        appinfo->child_relid);
                        returningLists = lappend(returningLists, rlist);
                }
        }
 
-       /* Done with child context */
-       MemoryContextDelete(childcxt);
-
        root->resultRelations = resultRelations;
 
        /* Mark result as unordered (probably unnecessary) */
@@ -870,7 +824,15 @@ inheritance_planner(PlannerInfo *root)
        }
 
        /*
-        * Install modified rangetable from first child into parent parsetree.
+        * Planning might have modified the rangetable, due to changes of the
+        * Query structures inside subquery RTEs.  We have to ensure that this
+        * gets propagated back to the master copy.  But can't do this until we
+        * are done planning, because all the calls to grouping_planner need
+        * virgin sub-Queries to work from.  (We are effectively assuming that
+        * sub-Queries will get planned identically each time, or at least that
+        * the impacts on their rangetables will be the same each time.)
+        *
+        * XXX should clean this up someday
         */
        parse->rtable = rtable;