diff options
Diffstat (limited to 'src/backend/optimizer/util/relnode.c')
-rw-r--r-- | src/backend/optimizer/util/relnode.c | 51 |
1 files changed, 22 insertions, 29 deletions
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 7912df0baaa..3aa701fd843 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -88,7 +88,7 @@ setup_simple_rel_arrays(PlannerInfo *root) * Construct a new RelOptInfo for a base relation or 'other' relation. */ RelOptInfo * -build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind) +build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) { RelOptInfo *rel; RangeTblEntry *rte; @@ -103,7 +103,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind) Assert(rte != NULL); rel = makeNode(RelOptInfo); - rel->reloptkind = reloptkind; + rel->reloptkind = parent ? RELOPT_OTHER_MEMBER_REL : RELOPT_BASEREL; rel->relids = bms_make_singleton(relid); rel->rows = 0; /* cheap startup cost is interesting iff not all tuples to be retrieved */ @@ -144,6 +144,22 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind) rel->joininfo = NIL; rel->has_eclass_joins = false; + /* + * Pass top parent's relids down the inheritance hierarchy. If the parent + * has top_parent_relids set, it's a direct or an indirect child of the top + * parent indicated by top_parent_relids. By extention this child is also + * an indirect child of that parent. + */ + if (parent) + { + if (parent->top_parent_relids) + rel->top_parent_relids = parent->top_parent_relids; + else + rel->top_parent_relids = bms_copy(parent->relids); + } + else + rel->top_parent_relids = NULL; + /* Check type of rtable entry */ switch (rte->rtekind) { @@ -209,7 +225,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind) continue; (void) build_simple_rel(root, appinfo->child_relid, - RELOPT_OTHER_MEMBER_REL); + rel); } } @@ -504,6 +520,7 @@ build_join_rel(PlannerInfo *root, joinrel->baserestrict_min_security = UINT_MAX; joinrel->joininfo = NIL; joinrel->has_eclass_joins = false; + joinrel->top_parent_relids = NULL; /* Compute information relevant to the foreign relations. */ set_foreign_rel_properties(joinrel, outer_rel, inner_rel); @@ -966,32 +983,6 @@ find_childrel_appendrelinfo(PlannerInfo *root, RelOptInfo *rel) /* - * find_childrel_top_parent - * Fetch the topmost appendrel parent rel of an appendrel child rel. - * - * Since appendrels can be nested, a child could have multiple levels of - * appendrel ancestors. This function locates the topmost ancestor, - * which will be a regular baserel not an otherrel. - */ -RelOptInfo * -find_childrel_top_parent(PlannerInfo *root, RelOptInfo *rel) -{ - do - { - AppendRelInfo *appinfo = find_childrel_appendrelinfo(root, rel); - Index prelid = appinfo->parent_relid; - - /* traverse up to the parent rel, loop if it's also a child rel */ - rel = find_base_rel(root, prelid); - } while (rel->reloptkind == RELOPT_OTHER_MEMBER_REL); - - Assert(rel->reloptkind == RELOPT_BASEREL); - - return rel; -} - - -/* * find_childrel_parents * Compute the set of parent relids of an appendrel child rel. * @@ -1004,6 +995,8 @@ find_childrel_parents(PlannerInfo *root, RelOptInfo *rel) { Relids result = NULL; + Assert(rel->reloptkind == RELOPT_OTHER_MEMBER_REL); + do { AppendRelInfo *appinfo = find_childrel_appendrelinfo(root, rel); |