Cosmetic improvements in setup of planner's per-RTE arrays.

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
This commit is contained in:
Tom Lane 2019-08-09 12:33:43 -04:00
parent b8f2da0ac5
commit 1661a40505
5 changed files with 34 additions and 47 deletions

View File

@ -79,9 +79,7 @@ query_planner(PlannerInfo *root,
root->initial_rels = NIL; root->initial_rels = NIL;
/* /*
* Make a flattened version of the rangetable for faster access (this is * Set up arrays for accessing base relations and AppendRelInfos.
* OK because the rangetable won't change any more), and set up an empty
* array for indexing base relations.
*/ */
setup_simple_rel_arrays(root); 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. * Construct RelOptInfo nodes for all base relations used in the query.
* Appendrel member relations ("other rels") will be added later. * Appendrel member relations ("other rels") will be added later.

View File

@ -132,16 +132,10 @@ plan_set_operations(PlannerInfo *root)
/* /*
* We'll need to build RelOptInfos for each of the leaf subqueries, which * We'll need to build RelOptInfos for each of the leaf subqueries, which
* are RTE_SUBQUERY rangetable entries in this Query. Prepare the index * 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); 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 * Find the leftmost component Query. We need to use its column names for
* all generated tlists (else SELECT INTO won't work right). * all generated tlists (else SELECT INTO won't work right).

View File

@ -67,24 +67,30 @@ static void build_child_join_reltarget(PlannerInfo *root,
/* /*
* setup_simple_rel_arrays * 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 void
setup_simple_rel_arrays(PlannerInfo *root) setup_simple_rel_arrays(PlannerInfo *root)
{ {
int size;
Index rti; Index rti;
ListCell *lc; ListCell *lc;
/* Arrays are accessed using RT indexes (1..N) */ /* 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 **) 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 */ /* simple_rte_array is an array equivalent of the rtable list */
root->simple_rte_array = (RangeTblEntry **) root->simple_rte_array = (RangeTblEntry **)
palloc0(root->simple_rel_array_size * sizeof(RangeTblEntry *)); palloc0(size * sizeof(RangeTblEntry *));
rti = 1; rti = 1;
foreach(lc, root->parse->rtable) foreach(lc, root->parse->rtable)
{ {
@ -92,21 +98,8 @@ setup_simple_rel_arrays(PlannerInfo *root)
root->simple_rte_array[rti++] = rte; 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) if (root->append_rel_list == NIL)
{ {
root->append_rel_array = NULL; root->append_rel_array = NULL;
@ -116,6 +109,12 @@ setup_append_rel_array(PlannerInfo *root)
root->append_rel_array = (AppendRelInfo **) root->append_rel_array = (AppendRelInfo **)
palloc0(size * sizeof(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) foreach(lc, root->append_rel_list)
{ {
AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc); AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc);
@ -135,6 +134,10 @@ setup_append_rel_array(PlannerInfo *root)
* expand_planner_arrays * expand_planner_arrays
* Expand the PlannerInfo's per-RTE arrays by add_size members * Expand the PlannerInfo's per-RTE arrays by add_size members
* and initialize the newly added entries to NULLs * 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 void
expand_planner_arrays(PlannerInfo *root, int add_size) 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; 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 **) root->simple_rel_array = (RelOptInfo **)
repalloc(root->simple_rel_array, repalloc(root->simple_rel_array,
sizeof(RelOptInfo *) * new_size); sizeof(RelOptInfo *) * new_size);
MemSet(root->simple_rel_array + root->simple_rel_array_size, MemSet(root->simple_rel_array + root->simple_rel_array_size,
0, sizeof(RelOptInfo *) * add_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) if (root->append_rel_array)
{ {
root->append_rel_array = (AppendRelInfo **) root->append_rel_array = (AppendRelInfo **)

View File

@ -204,17 +204,16 @@ struct PlannerInfo
/* /*
* simple_rte_array is the same length as simple_rel_array and holds * simple_rte_array is the same length as simple_rel_array and holds
* pointers to the associated rangetable entries. This lets us avoid * pointers to the associated rangetable entries. Using this is a shade
* rt_fetch(), which can be a bit slow once large inheritance sets have * faster than using rt_fetch(), mostly due to fewer indirections.
* been expanded.
*/ */
RangeTblEntry **simple_rte_array; /* rangetable as an array */ RangeTblEntry **simple_rte_array; /* rangetable as an array */
/* /*
* append_rel_array is the same length as the above arrays, and holds * append_rel_array is the same length as the above arrays, and holds
* pointers to the corresponding AppendRelInfo entry indexed by * pointers to the corresponding AppendRelInfo entry indexed by
* child_relid, or NULL if none. The array itself is not allocated if * child_relid, or NULL if the rel is not an appendrel child. The array
* append_rel_list is empty. * itself is not allocated if append_rel_list is empty.
*/ */
struct AppendRelInfo **append_rel_array; struct AppendRelInfo **append_rel_array;

View File

@ -277,7 +277,6 @@ extern Path *reparameterize_path_by_child(PlannerInfo *root, Path *path,
* prototypes for relnode.c * prototypes for relnode.c
*/ */
extern void setup_simple_rel_arrays(PlannerInfo *root); 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 void expand_planner_arrays(PlannerInfo *root, int add_size);
extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid, extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid,
RelOptInfo *parent); RelOptInfo *parent);