aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/plan/planmain.c10
-rw-r--r--src/backend/optimizer/prep/prepunion.c8
-rw-r--r--src/backend/optimizer/util/relnode.c53
-rw-r--r--src/include/nodes/pathnodes.h9
-rw-r--r--src/include/optimizer/pathnode.h1
5 files changed, 34 insertions, 47 deletions
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c
index df3f8c25440..f0c1b52a2e5 100644
--- a/src/backend/optimizer/plan/planmain.c
+++ b/src/backend/optimizer/plan/planmain.c
@@ -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);
@@ -157,12 +155,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.
*
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 5a11c1235c3..b01c9bbae7d 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -132,17 +132,11 @@ 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).
*/
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 37d228ce5d0..582c5dd979b 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -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 **)
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index e3c579ee443..13b147d85d5 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -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;
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index 182ffeef4b4..a12af54971b 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -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);