Cosmetic improvements in setup of planner's per-RTE arrays.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 9 Aug 2019 16:33:43 +0000 (12:33 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 9 Aug 2019 16:33:43 +0000 (12:33 -0400)
Merge setup_append_rel_array into setup_simple_rel_arrays.  There's no
particularly good reason to keep them separate, and it's inconsistent
with the lack of separation in expand_planner_arrays.  The only apparent
benefit was that the fast path for trivial queries in query_planner()
doesn't need to set up the append_rel_array; but all we're saving there
is an if-test and NULL assignment, which surely ought to be negligible.

Also improve some obsolete comments.

Discussion: https://postgr.es/m/17220.1565301350@sss.pgh.pa.us

src/backend/optimizer/plan/planmain.c
src/backend/optimizer/prep/prepunion.c
src/backend/optimizer/util/relnode.c
src/include/nodes/pathnodes.h
src/include/optimizer/pathnode.h

index df3f8c25440f02a6b62dc33308d3012b9f804e01..f0c1b52a2e50b22bab1f9ff528565cf6a2a8bdd2 100644 (file)
@@ -79,9 +79,7 @@ query_planner(PlannerInfo *root,
    root->initial_rels = NIL;
 
    /*
-    * Make a flattened version of the rangetable for faster access (this is
-    * OK because the rangetable won't change any more), and set up an empty
-    * array for indexing base relations.
+    * Set up arrays for accessing base relations and AppendRelInfos.
     */
    setup_simple_rel_arrays(root);
 
@@ -156,12 +154,6 @@ query_planner(PlannerInfo *root,
        }
    }
 
-   /*
-    * Populate append_rel_array with each AppendRelInfo to allow direct
-    * lookups by child relid.
-    */
-   setup_append_rel_array(root);
-
    /*
     * Construct RelOptInfo nodes for all base relations used in the query.
     * Appendrel member relations ("other rels") will be added later.
index 5a11c1235c395987f3d6c45db2d3c897f715048b..b01c9bbae7d8347ea82908a8047d3fb19ce41001 100644 (file)
@@ -132,16 +132,10 @@ plan_set_operations(PlannerInfo *root)
    /*
     * We'll need to build RelOptInfos for each of the leaf subqueries, which
     * are RTE_SUBQUERY rangetable entries in this Query.  Prepare the index
-    * arrays for that.
+    * arrays for those, and for AppendRelInfos in case they're needed.
     */
    setup_simple_rel_arrays(root);
 
-   /*
-    * Populate append_rel_array with each AppendRelInfo to allow direct
-    * lookups by child relid.
-    */
-   setup_append_rel_array(root);
-
    /*
     * Find the leftmost component Query.  We need to use its column names for
     * all generated tlists (else SELECT INTO won't work right).
index 37d228ce5d0048217dc9a3697bcc16bcb23baf1d..582c5dd979be24a7d7a141c8ca6c8efd792cd7b0 100644 (file)
@@ -67,24 +67,30 @@ static void build_child_join_reltarget(PlannerInfo *root,
 
 /*
  * setup_simple_rel_arrays
- *   Prepare the arrays we use for quickly accessing base relations.
+ *   Prepare the arrays we use for quickly accessing base relations
+ *   and AppendRelInfos.
  */
 void
 setup_simple_rel_arrays(PlannerInfo *root)
 {
+   int         size;
    Index       rti;
    ListCell   *lc;
 
    /* Arrays are accessed using RT indexes (1..N) */
-   root->simple_rel_array_size = list_length(root->parse->rtable) + 1;
+   size = list_length(root->parse->rtable) + 1;
+   root->simple_rel_array_size = size;
 
-   /* simple_rel_array is initialized to all NULLs */
+   /*
+    * simple_rel_array is initialized to all NULLs, since no RelOptInfos
+    * exist yet.  It'll be filled by later calls to build_simple_rel().
+    */
    root->simple_rel_array = (RelOptInfo **)
-       palloc0(root->simple_rel_array_size * sizeof(RelOptInfo *));
+       palloc0(size * sizeof(RelOptInfo *));
 
    /* simple_rte_array is an array equivalent of the rtable list */
    root->simple_rte_array = (RangeTblEntry **)
-       palloc0(root->simple_rel_array_size * sizeof(RangeTblEntry *));
+       palloc0(size * sizeof(RangeTblEntry *));
    rti = 1;
    foreach(lc, root->parse->rtable)
    {
@@ -92,21 +98,8 @@ setup_simple_rel_arrays(PlannerInfo *root)
 
        root->simple_rte_array[rti++] = rte;
    }
-}
-
-/*
- * setup_append_rel_array
- *     Populate the append_rel_array to allow direct lookups of
- *     AppendRelInfos by child relid.
- *
- * The array remains unallocated if there are no AppendRelInfos.
- */
-void
-setup_append_rel_array(PlannerInfo *root)
-{
-   ListCell   *lc;
-   int         size = list_length(root->parse->rtable) + 1;
 
+   /* append_rel_array is not needed if there are no AppendRelInfos */
    if (root->append_rel_list == NIL)
    {
        root->append_rel_array = NULL;
@@ -116,6 +109,12 @@ setup_append_rel_array(PlannerInfo *root)
    root->append_rel_array = (AppendRelInfo **)
        palloc0(size * sizeof(AppendRelInfo *));
 
+   /*
+    * append_rel_array is filled with any already-existing AppendRelInfos,
+    * which currently could only come from UNION ALL flattening.  We might
+    * add more later during inheritance expansion, but it's the
+    * responsibility of the expansion code to update the array properly.
+    */
    foreach(lc, root->append_rel_list)
    {
        AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc);
@@ -135,6 +134,10 @@ setup_append_rel_array(PlannerInfo *root)
  * expand_planner_arrays
  *     Expand the PlannerInfo's per-RTE arrays by add_size members
  *     and initialize the newly added entries to NULLs
+ *
+ * Note: this causes the append_rel_array to become allocated even if
+ * it was not before.  This is okay for current uses, because we only call
+ * this when adding child relations, which always have AppendRelInfos.
  */
 void
 expand_planner_arrays(PlannerInfo *root, int add_size)
@@ -145,18 +148,18 @@ expand_planner_arrays(PlannerInfo *root, int add_size)
 
    new_size = root->simple_rel_array_size + add_size;
 
-   root->simple_rte_array = (RangeTblEntry **)
-       repalloc(root->simple_rte_array,
-                sizeof(RangeTblEntry *) * new_size);
-   MemSet(root->simple_rte_array + root->simple_rel_array_size,
-          0, sizeof(RangeTblEntry *) * add_size);
-
    root->simple_rel_array = (RelOptInfo **)
        repalloc(root->simple_rel_array,
                 sizeof(RelOptInfo *) * new_size);
    MemSet(root->simple_rel_array + root->simple_rel_array_size,
           0, sizeof(RelOptInfo *) * add_size);
 
+   root->simple_rte_array = (RangeTblEntry **)
+       repalloc(root->simple_rte_array,
+                sizeof(RangeTblEntry *) * new_size);
+   MemSet(root->simple_rte_array + root->simple_rel_array_size,
+          0, sizeof(RangeTblEntry *) * add_size);
+
    if (root->append_rel_array)
    {
        root->append_rel_array = (AppendRelInfo **)
index e3c579ee4437505d305274e5423a77a04439e8ad..13b147d85d5ceb9ee3e7f712ef7a168ce5620acc 100644 (file)
@@ -204,17 +204,16 @@ struct PlannerInfo
 
    /*
     * simple_rte_array is the same length as simple_rel_array and holds
-    * pointers to the associated rangetable entries.  This lets us avoid
-    * rt_fetch(), which can be a bit slow once large inheritance sets have
-    * been expanded.
+    * pointers to the associated rangetable entries.  Using this is a shade
+    * faster than using rt_fetch(), mostly due to fewer indirections.
     */
    RangeTblEntry **simple_rte_array;   /* rangetable as an array */
 
    /*
     * append_rel_array is the same length as the above arrays, and holds
     * pointers to the corresponding AppendRelInfo entry indexed by
-    * child_relid, or NULL if none.  The array itself is not allocated if
-    * append_rel_list is empty.
+    * child_relid, or NULL if the rel is not an appendrel child.  The array
+    * itself is not allocated if append_rel_list is empty.
     */
    struct AppendRelInfo **append_rel_array;
 
index 182ffeef4b42a6416e1fbecabeef8901865c501c..a12af54971bfc9b3359e47c0ca0502a4f80c355a 100644 (file)
@@ -277,7 +277,6 @@ extern Path *reparameterize_path_by_child(PlannerInfo *root, Path *path,
  * prototypes for relnode.c
  */
 extern void setup_simple_rel_arrays(PlannerInfo *root);
-extern void setup_append_rel_array(PlannerInfo *root);
 extern void expand_planner_arrays(PlannerInfo *root, int add_size);
 extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid,
                                    RelOptInfo *parent);