get_rid_of_find_appinfos_by_relids_incomplete_mess.patch
application/octet-stream
Filename: get_rid_of_find_appinfos_by_relids_incomplete_mess.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/allpaths.c | 3 | 3 |
| src/backend/optimizer/path/equivclass.c | 1 | 1 |
| src/backend/optimizer/path/joinrels.c | 1 | 5 |
| src/backend/optimizer/plan/planner.c | 9 | 17 |
| src/backend/optimizer/prep/prepunion.c | 67 | 130 |
| src/backend/optimizer/util/placeholder.c | 1 | 7 |
| src/backend/optimizer/util/relnode.c | 23 | 6 |
| src/include/nodes/relation.h | 5 | 0 |
| src/include/optimizer/prep.h | 1 | 4 |
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 477b9f7fb8..7f76d0ab9d 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1019,7 +1019,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
childrel->reltarget->exprs = (List *)
adjust_appendrel_attrs(root,
(Node *) rel->reltarget->exprs,
- 1, &appinfo);
+ bms_make_singleton(appinfo->child_relid));
/*
* We have to make child entries in the EquivalenceClass data
@@ -1061,7 +1061,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
Assert(IsA(rinfo, RestrictInfo));
childqual = adjust_appendrel_attrs(root,
(Node *) rinfo->clause,
- 1, &appinfo);
+ bms_make_singleton(appinfo->child_relid));
childqual = eval_const_expressions(root, childqual);
/* check for flat-out constant */
if (childqual && IsA(childqual, Const))
@@ -1178,7 +1178,7 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
childrel->joininfo = (List *)
adjust_appendrel_attrs(root,
(Node *) rel->joininfo,
- 1, &appinfo);
+ bms_make_singleton(appinfo->child_relid));
/*
* If parallelism is allowable for this query in general, see whether
diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index b22b36ec0e..2be3caa56f 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -2152,7 +2152,7 @@ add_child_rel_equivalences(PlannerInfo *root,
child_expr = (Expr *)
adjust_appendrel_attrs(root,
(Node *) cur_em->em_expr,
- 1, &appinfo);
+ bms_make_singleton(appinfo->child_relid));
/*
* Transform em_relids to match. Note we do *not* do
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 7008e1318e..ce1efd403e 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -1366,13 +1366,10 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
List *child_restrictlist;
RelOptInfo *child_joinrel;
Relids child_joinrelids;
- AppendRelInfo **appinfos;
- int nappinfos;
/* We should never try to join two overlapping sets of rels. */
Assert(!bms_overlap(child_rel1->relids, child_rel2->relids));
child_joinrelids = bms_union(child_rel1->relids, child_rel2->relids);
- appinfos = find_appinfos_by_relids(root, child_joinrelids, &nappinfos);
/*
* Construct SpecialJoinInfo from parent join relations's
@@ -1389,8 +1386,7 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
child_restrictlist =
(List *) adjust_appendrel_attrs(root,
(Node *) parent_restrictlist,
- nappinfos, appinfos);
- pfree(appinfos);
+ child_joinrelids);
child_joinrel = joinrel->part_rels[cnt_parts];
if (!child_joinrel)
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 67a2c7a581..a0b3123a2e 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -1163,6 +1163,7 @@ inheritance_planner(PlannerInfo *root)
List *final_rtable = NIL;
int save_rel_array_size = 0;
RelOptInfo **save_rel_array = NULL;
+ AppendRelInfo **save_append_rel_array = NULL;
List *subpaths = NIL;
List *subroots = NIL;
List *resultRelations = NIL;
@@ -1311,7 +1312,7 @@ inheritance_planner(PlannerInfo *root)
subroot->parse = (Query *)
adjust_appendrel_attrs(parent_root,
(Node *) parent_parse,
- 1, &appinfo);
+ bms_make_singleton(appinfo->child_relid));
/*
* If there are securityQuals attached to the parent, move them to the
@@ -1529,6 +1530,7 @@ inheritance_planner(PlannerInfo *root)
}
save_rel_array_size = subroot->simple_rel_array_size;
save_rel_array = subroot->simple_rel_array;
+ save_append_rel_array = subroot->append_rel_array;
/* Make sure any initplans from this rel get into the outer list */
root->init_plans = subroot->init_plans;
@@ -1579,6 +1581,8 @@ inheritance_planner(PlannerInfo *root)
parse->rtable = final_rtable;
root->simple_rel_array_size = save_rel_array_size;
root->simple_rel_array = save_rel_array;
+ root->append_rel_array = save_append_rel_array;
+
/* Must reconstruct master's simple_rte_array, too */
root->simple_rte_array = (RangeTblEntry **)
palloc0((list_length(final_rtable) + 1) * sizeof(RangeTblEntry *));
@@ -6924,13 +6928,9 @@ apply_scanjoin_target_to_paths(PlannerInfo *root,
{
RelOptInfo *child_rel = rel->part_rels[partition_idx];
ListCell *lc;
- AppendRelInfo **appinfos;
- int nappinfos;
List *child_scanjoin_targets = NIL;
/* Translate scan/join targets for this child. */
- appinfos = find_appinfos_by_relids(root, child_rel->relids,
- &nappinfos);
foreach(lc, scanjoin_targets)
{
PathTarget *target = lfirst_node(PathTarget, lc);
@@ -6939,11 +6939,10 @@ apply_scanjoin_target_to_paths(PlannerInfo *root,
target->exprs = (List *)
adjust_appendrel_attrs(root,
(Node *) target->exprs,
- nappinfos, appinfos);
+ child_rel->relids);
child_scanjoin_targets = lappend(child_scanjoin_targets,
target);
}
- pfree(appinfos);
/* Recursion does the real work. */
apply_scanjoin_target_to_paths(root, child_rel,
@@ -7022,8 +7021,6 @@ create_partitionwise_grouping_paths(PlannerInfo *root,
{
RelOptInfo *child_input_rel = input_rel->part_rels[cnt_parts];
PathTarget *child_target = copy_pathtarget(target);
- AppendRelInfo **appinfos;
- int nappinfos;
GroupPathExtraData child_extra;
RelOptInfo *child_grouped_rel;
RelOptInfo *child_partially_grouped_rel;
@@ -7037,23 +7034,20 @@ create_partitionwise_grouping_paths(PlannerInfo *root,
*/
memcpy(&child_extra, extra, sizeof(child_extra));
- appinfos = find_appinfos_by_relids(root, child_input_rel->relids,
- &nappinfos);
-
child_target->exprs = (List *)
adjust_appendrel_attrs(root,
(Node *) target->exprs,
- nappinfos, appinfos);
+ child_input_rel->relids);
/* Translate havingQual and targetList. */
child_extra.havingQual = (Node *)
adjust_appendrel_attrs(root,
extra->havingQual,
- nappinfos, appinfos);
+ child_input_rel->relids);
child_extra.targetList = (List *)
adjust_appendrel_attrs(root,
(Node *) extra->targetList,
- nappinfos, appinfos);
+ child_input_rel->relids);
/*
* extra->patype was the value computed for our parent rel; patype is
@@ -7098,8 +7092,6 @@ create_partitionwise_grouping_paths(PlannerInfo *root,
grouped_live_children = lappend(grouped_live_children,
child_grouped_rel);
}
-
- pfree(appinfos);
}
/*
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 0ab4014be6..630b07d902 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -56,8 +56,7 @@
typedef struct
{
PlannerInfo *root;
- int nappinfos;
- AppendRelInfo **appinfos;
+ Relids childrelids;
} adjust_appendrel_attrs_context;
static RelOptInfo *recurse_set_operations(Node *setOp, PlannerInfo *root,
@@ -119,8 +118,8 @@ static Bitmapset *translate_col_privs(const Bitmapset *parent_privs,
List *translated_vars);
static Node *adjust_appendrel_attrs_mutator(Node *node,
adjust_appendrel_attrs_context *context);
-static Relids adjust_child_relids(Relids relids, int nappinfos,
- AppendRelInfo **appinfos);
+static Relids adjust_child_relids(PlannerInfo *root, Relids relids,
+ Relids childrelids);
static List *adjust_inherited_tlist(List *tlist,
AppendRelInfo *context);
@@ -2044,18 +2043,16 @@ translate_col_privs(const Bitmapset *parent_privs,
* maybe we should try to fold the two routines together.
*/
Node *
-adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos,
- AppendRelInfo **appinfos)
+adjust_appendrel_attrs(PlannerInfo *root, Node *node, Relids childrelids)
{
Node *result;
adjust_appendrel_attrs_context context;
context.root = root;
- context.nappinfos = nappinfos;
- context.appinfos = appinfos;
+ context.childrelids = childrelids;
/* If there's nothing to adjust, don't call this function. */
- Assert(nappinfos >= 1 && appinfos != NULL);
+ Assert(!bms_is_empty(childrelids));
/*
* Must be prepared to start with a Query or a bare expression tree.
@@ -2063,15 +2060,16 @@ adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos,
if (node && IsA(node, Query))
{
Query *newnode;
- int cnt;
+ int i;
newnode = query_tree_mutator((Query *) node,
adjust_appendrel_attrs_mutator,
(void *) &context,
QTW_IGNORE_RC_SUBQUERIES);
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(childrelids, i)) >= 0)
{
- AppendRelInfo *appinfo = appinfos[cnt];
+ AppendRelInfo *appinfo = root->append_rel_array[i];
if (newnode->resultRelation == appinfo->parent_relid)
{
@@ -2097,9 +2095,9 @@ static Node *
adjust_appendrel_attrs_mutator(Node *node,
adjust_appendrel_attrs_context *context)
{
- AppendRelInfo **appinfos = context->appinfos;
- int nappinfos = context->nappinfos;
- int cnt;
+ PlannerInfo *root = context->root;
+ Relids childrelids = context->childrelids;
+ int i;
if (node == NULL)
return NULL;
@@ -2108,11 +2106,14 @@ adjust_appendrel_attrs_mutator(Node *node,
Var *var = (Var *) copyObject(node);
AppendRelInfo *appinfo = NULL;
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(childrelids, i)) >= 0)
{
- if (var->varno == appinfos[cnt]->parent_relid)
+ AppendRelInfo *ainfo = root->append_rel_array[i];
+
+ if (var->varno == ainfo->parent_relid)
{
- appinfo = appinfos[cnt];
+ appinfo = ainfo;
break;
}
}
@@ -2197,9 +2198,10 @@ adjust_appendrel_attrs_mutator(Node *node,
{
CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node);
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(childrelids, i)) >= 0)
{
- AppendRelInfo *appinfo = appinfos[cnt];
+ AppendRelInfo *appinfo = root->append_rel_array[i];
if (cexpr->cvarno == appinfo->parent_relid)
{
@@ -2213,9 +2215,10 @@ adjust_appendrel_attrs_mutator(Node *node,
{
RangeTblRef *rtr = (RangeTblRef *) copyObject(node);
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(childrelids, i)) >= 0)
{
- AppendRelInfo *appinfo = appinfos[cnt];
+ AppendRelInfo *appinfo = root->append_rel_array[i];
if (rtr->rtindex == appinfo->parent_relid)
{
@@ -2229,15 +2232,15 @@ adjust_appendrel_attrs_mutator(Node *node,
{
/* Copy the JoinExpr node with correct mutation of subnodes */
JoinExpr *j;
- AppendRelInfo *appinfo;
j = (JoinExpr *) expression_tree_mutator(node,
adjust_appendrel_attrs_mutator,
(void *) context);
/* now fix JoinExpr's rtindex (probably never happens) */
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(childrelids, i)) >= 0)
{
- appinfo = appinfos[cnt];
+ AppendRelInfo *appinfo = root->append_rel_array[i];
if (j->rtindex == appinfo->parent_relid)
{
@@ -2257,9 +2260,8 @@ adjust_appendrel_attrs_mutator(Node *node,
(void *) context);
/* now fix PlaceHolderVar's relid sets */
if (phv->phlevelsup == 0)
- phv->phrels = adjust_child_relids(phv->phrels, context->nappinfos,
- context->appinfos);
- return (Node *) phv;
+ phv->phrels = adjust_child_relids(root, phv->phrels,
+ context->childrelids);
}
/* Shouldn't need to handle planner auxiliary nodes here */
Assert(!IsA(node, SpecialJoinInfo));
@@ -2289,24 +2291,18 @@ adjust_appendrel_attrs_mutator(Node *node,
adjust_appendrel_attrs_mutator((Node *) oldinfo->orclause, context);
/* adjust relid sets too */
- newinfo->clause_relids = adjust_child_relids(oldinfo->clause_relids,
- context->nappinfos,
- context->appinfos);
- newinfo->required_relids = adjust_child_relids(oldinfo->required_relids,
- context->nappinfos,
- context->appinfos);
- newinfo->outer_relids = adjust_child_relids(oldinfo->outer_relids,
- context->nappinfos,
- context->appinfos);
- newinfo->nullable_relids = adjust_child_relids(oldinfo->nullable_relids,
- context->nappinfos,
- context->appinfos);
- newinfo->left_relids = adjust_child_relids(oldinfo->left_relids,
- context->nappinfos,
- context->appinfos);
- newinfo->right_relids = adjust_child_relids(oldinfo->right_relids,
- context->nappinfos,
- context->appinfos);
+ newinfo->clause_relids = adjust_child_relids(root, oldinfo->clause_relids,
+ context->childrelids);
+ newinfo->required_relids = adjust_child_relids(root, oldinfo->required_relids,
+ context->childrelids);
+ newinfo->outer_relids = adjust_child_relids(root, oldinfo->outer_relids,
+ context->childrelids);
+ newinfo->nullable_relids = adjust_child_relids(root, oldinfo->nullable_relids,
+ context->childrelids);
+ newinfo->left_relids = adjust_child_relids(root, oldinfo->left_relids,
+ context->childrelids);
+ newinfo->right_relids = adjust_child_relids(root, oldinfo->right_relids,
+ context->childrelids);
/*
* Reset cached derivative fields, since these might need to have
@@ -2344,14 +2340,15 @@ adjust_appendrel_attrs_mutator(Node *node,
* appinfos specifies the substitutions to be performed.
*/
static Relids
-adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos)
+adjust_child_relids(PlannerInfo *root, Relids relids, Relids childrelids)
{
Bitmapset *result = NULL;
- int cnt;
+ int i;
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(childrelids, i)) >= 0)
{
- AppendRelInfo *appinfo = appinfos[cnt];
+ AppendRelInfo *appinfo = root->append_rel_array[i];
/* Remove parent, add child */
if (bms_is_member(appinfo->parent_relid, relids))
@@ -2382,12 +2379,10 @@ Relids
adjust_child_relids_multilevel(PlannerInfo *root, Relids relids,
Relids child_relids, Relids top_parent_relids)
{
- AppendRelInfo **appinfos;
- int nappinfos;
Relids parent_relids = NULL;
Relids result;
Relids tmp_result = NULL;
- int cnt;
+ int i;
/*
* If the given relids set doesn't contain any of the top parent relids,
@@ -2396,12 +2391,11 @@ adjust_child_relids_multilevel(PlannerInfo *root, Relids relids,
if (!bms_overlap(relids, top_parent_relids))
return relids;
- appinfos = find_appinfos_by_relids(root, child_relids, &nappinfos);
-
/* Construct relids set for the immediate parent of the given child. */
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(child_relids, i)) >= 0)
{
- AppendRelInfo *appinfo = appinfos[cnt];
+ AppendRelInfo *appinfo = root->append_rel_array[i];
parent_relids = bms_add_member(parent_relids, appinfo->parent_relid);
}
@@ -2415,13 +2409,12 @@ adjust_child_relids_multilevel(PlannerInfo *root, Relids relids,
relids = tmp_result;
}
- result = adjust_child_relids(relids, nappinfos, appinfos);
+ result = adjust_child_relids(root, relids, child_relids);
/* Free memory consumed by any intermediate result. */
if (tmp_result)
bms_free(tmp_result);
bms_free(parent_relids);
- pfree(appinfos);
return result;
}
@@ -2535,19 +2528,16 @@ adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node,
Relids child_relids,
Relids top_parent_relids)
{
- AppendRelInfo **appinfos;
Bitmapset *parent_relids = NULL;
- int nappinfos;
- int cnt;
+ int i;
Assert(bms_num_members(child_relids) == bms_num_members(top_parent_relids));
- appinfos = find_appinfos_by_relids(root, child_relids, &nappinfos);
-
/* Construct relids set for the immediate parent of given child. */
- for (cnt = 0; cnt < nappinfos; cnt++)
+ i = -1;
+ while ((i = bms_next_member(child_relids, i)) >= 0)
{
- AppendRelInfo *appinfo = appinfos[cnt];
+ AppendRelInfo *appinfo = root->append_rel_array[i];
parent_relids = bms_add_member(parent_relids, appinfo->parent_relid);
}
@@ -2558,9 +2548,7 @@ adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node,
top_parent_relids);
/* Now translate for this child */
- node = adjust_appendrel_attrs(root, node, nappinfos, appinfos);
-
- pfree(appinfos);
+ node = adjust_appendrel_attrs(root, node, child_relids);
return node;
}
@@ -2575,71 +2563,20 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
Relids left_relids, Relids right_relids)
{
SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo);
- AppendRelInfo **left_appinfos;
- int left_nappinfos;
- AppendRelInfo **right_appinfos;
- int right_nappinfos;
memcpy(sjinfo, parent_sjinfo, sizeof(SpecialJoinInfo));
- left_appinfos = find_appinfos_by_relids(root, left_relids,
- &left_nappinfos);
- right_appinfos = find_appinfos_by_relids(root, right_relids,
- &right_nappinfos);
-
- sjinfo->min_lefthand = adjust_child_relids(sjinfo->min_lefthand,
- left_nappinfos, left_appinfos);
- sjinfo->min_righthand = adjust_child_relids(sjinfo->min_righthand,
- right_nappinfos,
- right_appinfos);
- sjinfo->syn_lefthand = adjust_child_relids(sjinfo->syn_lefthand,
- left_nappinfos, left_appinfos);
- sjinfo->syn_righthand = adjust_child_relids(sjinfo->syn_righthand,
- right_nappinfos,
- right_appinfos);
+
+ sjinfo->min_lefthand = adjust_child_relids(root, sjinfo->min_lefthand,
+ left_relids);
+ sjinfo->min_righthand = adjust_child_relids(root, sjinfo->min_righthand,
+ right_relids);
+ sjinfo->syn_lefthand = adjust_child_relids(root, sjinfo->syn_lefthand,
+ left_relids);
+ sjinfo->syn_righthand = adjust_child_relids(root, sjinfo->syn_righthand,
+ right_relids);
sjinfo->semi_rhs_exprs = (List *) adjust_appendrel_attrs(root,
(Node *) sjinfo->semi_rhs_exprs,
- right_nappinfos,
- right_appinfos);
-
- pfree(left_appinfos);
- pfree(right_appinfos);
+ right_relids);
return sjinfo;
}
-
-/*
- * find_appinfos_by_relids
- * Find AppendRelInfo structures for all relations specified by relids.
- *
- * The AppendRelInfos are returned in an array, which can be pfree'd by the
- * caller. *nappinfos is set to the number of entries in the array.
- */
-AppendRelInfo **
-find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)
-{
- ListCell *lc;
- AppendRelInfo **appinfos;
- int cnt = 0;
-
- *nappinfos = bms_num_members(relids);
- appinfos = (AppendRelInfo **) palloc(sizeof(AppendRelInfo *) * *nappinfos);
-
- foreach(lc, root->append_rel_list)
- {
- AppendRelInfo *appinfo = lfirst(lc);
-
- if (bms_is_member(appinfo->child_relid, relids))
- {
- appinfos[cnt] = appinfo;
- cnt++;
-
- /* Stop when we have gathered all the AppendRelInfos. */
- if (cnt == *nappinfos)
- return appinfos;
- }
- }
-
- /* Should have found the entries ... */
- elog(ERROR, "did not find all requested child rels in append_rel_list");
- return NULL; /* not reached */
-}
diff --git a/src/backend/optimizer/util/placeholder.c b/src/backend/optimizer/util/placeholder.c
index c79d0f25d4..2ccf39658f 100644
--- a/src/backend/optimizer/util/placeholder.c
+++ b/src/backend/optimizer/util/placeholder.c
@@ -475,8 +475,6 @@ add_placeholders_to_child_joinrel(PlannerInfo *root, RelOptInfo *childrel,
RelOptInfo *parentrel)
{
ListCell *lc;
- AppendRelInfo **appinfos;
- int nappinfos;
Assert(IS_JOIN_REL(childrel) && IS_JOIN_REL(parentrel));
Assert(IS_OTHER_REL(childrel));
@@ -485,7 +483,6 @@ add_placeholders_to_child_joinrel(PlannerInfo *root, RelOptInfo *childrel,
if (root->placeholder_list == NIL)
return;
- appinfos = find_appinfos_by_relids(root, childrel->relids, &nappinfos);
foreach(lc, parentrel->reltarget->exprs)
{
PlaceHolderVar *phv = lfirst(lc);
@@ -501,8 +498,7 @@ add_placeholders_to_child_joinrel(PlannerInfo *root, RelOptInfo *childrel,
{
phv = (PlaceHolderVar *) adjust_appendrel_attrs(root,
(Node *) phv,
- nappinfos,
- appinfos);
+ childrel->relids);
}
childrel->reltarget->exprs = lappend(childrel->reltarget->exprs,
@@ -514,6 +510,4 @@ add_placeholders_to_child_joinrel(PlannerInfo *root, RelOptInfo *childrel,
childrel->reltarget->cost.startup = parentrel->reltarget->cost.startup;
childrel->reltarget->cost.per_tuple = parentrel->reltarget->cost.per_tuple;
childrel->reltarget->width = parentrel->reltarget->width;
-
- pfree(appinfos);
}
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 82b78420e7..28edd995cf 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -86,6 +86,28 @@ setup_simple_rel_arrays(PlannerInfo *root)
root->simple_rte_array[rti++] = rte;
}
+
+ if (root->append_rel_list != NIL)
+ {
+ root->append_rel_array = (AppendRelInfo **)
+ palloc0(root->simple_rel_array_size * sizeof(AppendRelInfo *));
+
+ foreach(lc, root->append_rel_list)
+ {
+ AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc);
+ int child_relid = appinfo->child_relid;
+
+ /* Sanity check */
+ Assert(child_relid < root->simple_rel_array_size);
+
+ if (root->append_rel_array[child_relid])
+ elog(ERROR, "child relation already exists");
+
+ root->append_rel_array[child_relid] = appinfo;
+ }
+ }
+ else
+ root->append_rel_array = NULL;
}
/*
@@ -689,8 +711,6 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
JoinType jointype)
{
RelOptInfo *joinrel = makeNode(RelOptInfo);
- AppendRelInfo **appinfos;
- int nappinfos;
/* Only joins between "other" relations land here. */
Assert(IS_OTHER_REL(outer_rel) && IS_OTHER_REL(inner_rel));
@@ -759,12 +779,9 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
add_placeholders_to_child_joinrel(root, joinrel, parent_joinrel);
/* Construct joininfo list. */
- appinfos = find_appinfos_by_relids(root, joinrel->relids, &nappinfos);
joinrel->joininfo = (List *) adjust_appendrel_attrs(root,
(Node *) parent_joinrel->joininfo,
- nappinfos,
- appinfos);
- pfree(appinfos);
+ joinrel->relids);
/*
* Lateral relids referred in child join will be same as that referred in
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 3b28d1994f..9045a90f97 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -151,6 +151,7 @@ typedef struct PlannerGlobal
#define planner_subplan_get_plan(root, subplan) \
((Plan *) list_nth((root)->glob->subplans, (subplan)->plan_id - 1))
+struct AppendRelInfo;
/*----------
* PlannerInfo
@@ -201,6 +202,10 @@ typedef struct PlannerInfo
*/
RangeTblEntry **simple_rte_array; /* rangetable as an array */
+ struct AppendRelInfo **append_rel_array; /* append_rel_list indexed by
+ * child_relid, or NULL if
+ * append_rel_list is empty */
+
/*
* all_baserels is a Relids set of all base relids (but not "other"
* relids) in the query; that is, the Relids identifier of the final join
diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h
index 38608770a2..acf0740ec6 100644
--- a/src/include/optimizer/prep.h
+++ b/src/include/optimizer/prep.h
@@ -50,15 +50,12 @@ extern RelOptInfo *plan_set_operations(PlannerInfo *root);
extern void expand_inherited_tables(PlannerInfo *root);
extern Node *adjust_appendrel_attrs(PlannerInfo *root, Node *node,
- int nappinfos, AppendRelInfo **appinfos);
+ Relids childrelids);
extern Node *adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node,
Relids child_relids,
Relids top_parent_relids);
-extern AppendRelInfo **find_appinfos_by_relids(PlannerInfo *root,
- Relids relids, int *nappinfos);
-
extern SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root,
SpecialJoinInfo *parent_sjinfo,
Relids left_relids, Relids right_relids);