Skip to content

Commit

Permalink
Cosmetic improvements in setup of planner's per-RTE arrays.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tglsfdc committed Aug 9, 2019
1 parent b8f2da0 commit 1661a40
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 47 deletions.
10 changes: 1 addition & 9 deletions src/backend/optimizer/plan/planmain.c
Expand Up @@ -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);

Expand Down Expand Up @@ -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.
Expand Down
8 changes: 1 addition & 7 deletions src/backend/optimizer/prep/prepunion.c
Expand Up @@ -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).
Expand Down
53 changes: 28 additions & 25 deletions src/backend/optimizer/util/relnode.c
Expand Up @@ -67,46 +67,39 @@ 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)
{
RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);

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;
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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 **)
Expand Down
9 changes: 4 additions & 5 deletions src/include/nodes/pathnodes.h
Expand Up @@ -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;

Expand Down
1 change: 0 additions & 1 deletion src/include/optimizer/pathnode.h
Expand Up @@ -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);
Expand Down

0 comments on commit 1661a40

Please sign in to comment.