]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Arrange to free planning memory (or most of it, anyway) at completion
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 Jul 2000 04:51:04 +0000 (04:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 27 Jul 2000 04:51:04 +0000 (04:51 +0000)
of planning.  This should reduce memory requirements for large joins.

src/backend/optimizer/plan/planmain.c

index a33d068a385ef01ab1546d33b8e16926f705c371..6b6bc15bda7b5e2dd70705f52e2611cbe31f5ea0 100644 (file)
@@ -14,7 +14,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.56 2000/07/24 03:11:01 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.57 2000/07/27 04:51:04 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,6 +28,7 @@
 #include "optimizer/paths.h"
 #include "optimizer/planmain.h"
 #include "optimizer/tlist.h"
+#include "utils/memutils.h"
 
 
 static Plan *subplanner(Query *root, List *flat_tlist, List *qual,
@@ -176,6 +177,9 @@ subplanner(Query *root,
                   double tuple_fraction)
 {
        RelOptInfo *final_rel;
+       Plan       *resultplan;
+       MemoryContext mycontext;
+       MemoryContext oldcxt;
        Path       *cheapestpath;
        Path       *presortedpath;
 
@@ -212,6 +216,24 @@ subplanner(Query *root,
         */
        root->query_pathkeys = canonicalize_pathkeys(root, root->query_pathkeys);
 
+       /*
+        * We might allocate quite a lot of storage during planning (due to
+        * constructing lots of Paths), but all of it can be reclaimed after
+        * we generate the finished Plan tree.  Work in a temporary context
+        * to let that happen.  We make the context a child of
+        * TransactionCommandContext so it will be freed if error abort.
+        *
+        * Note: beware of trying to move this up to the start of this routine.
+        * Some of the data structures built above --- notably the pathkey
+        * equivalence sets --- will still be needed after this routine exits.
+        */
+       mycontext = AllocSetContextCreate(TransactionCommandContext,
+                                                                         "Planner",
+                                                                         ALLOCSET_DEFAULT_MINSIZE,
+                                                                         ALLOCSET_DEFAULT_INITSIZE,
+                                                                         ALLOCSET_DEFAULT_MAXSIZE);
+       oldcxt = MemoryContextSwitchTo(mycontext);
+
        /*
         * Ready to do the primary planning.
         */
@@ -235,7 +257,9 @@ subplanner(Query *root,
                root->query_pathkeys = NIL;             /* signal unordered result */
 
                /* Make childless Result node to evaluate given tlist. */
-               return (Plan *) make_result(flat_tlist, (Node *) qual, (Plan *) NULL);
+               resultplan = (Plan *) make_result(flat_tlist, (Node *) qual,
+                                                                                 (Plan *) NULL);
+               goto plan_built;
        }
 
 #ifdef NOT_USED                                        /* fix xfunc */
@@ -295,7 +319,8 @@ subplanner(Query *root,
                                                          cheapestpath->pathkeys))
        {
                root->query_pathkeys = cheapestpath->pathkeys;
-               return create_plan(root, cheapestpath);
+               resultplan = create_plan(root, cheapestpath);
+               goto plan_built;
        }
 
        /*
@@ -321,7 +346,8 @@ subplanner(Query *root,
                {
                        /* Presorted path is cheaper, use it */
                        root->query_pathkeys = presortedpath->pathkeys;
-                       return create_plan(root, presortedpath);
+                       resultplan = create_plan(root, presortedpath);
+                       goto plan_built;
                }
                /* otherwise, doing it the hard way is still cheaper */
        }
@@ -334,5 +360,24 @@ subplanner(Query *root,
         * as an aggregate function...)
         */
        root->query_pathkeys = cheapestpath->pathkeys;
-       return create_plan(root, cheapestpath);
+       resultplan = create_plan(root, cheapestpath);
+
+plan_built:
+
+       /*
+        * Must copy the completed plan tree and its pathkeys out of temporary
+        * context.
+        */
+       MemoryContextSwitchTo(oldcxt);
+
+       resultplan = copyObject(resultplan);
+
+       root->query_pathkeys = copyObject(root->query_pathkeys);
+
+       /*
+        * Now we can release the Path storage.
+        */
+       MemoryContextDelete(mycontext);
+
+       return resultplan;
 }