v25-0005-Add-only-unpruned-partitioned-child-rels-to-part.patch
text/plain
Filename: v25-0005-Add-only-unpruned-partitioned-child-rels-to-part.patch
Type: text/plain
Part: 4
Patch
Format: format-patch
Series: patch v25-0005
Subject: Add only unpruned partitioned child rels to partitioned_rels
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/allpaths.c | 31 | 38 |
| src/backend/optimizer/plan/planner.c | 14 | 5 |
| src/backend/optimizer/util/relnode.c | 3 | 0 |
| src/include/nodes/relation.h | 8 | 0 |
From 44471a8e2f8cfafef08cd578cece517c547b5af0 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Wed, 13 Sep 2017 18:24:55 +0900
Subject: [PATCH v25 5/5] Add only unpruned partitioned child rels to
partitioned_rels
---
src/backend/optimizer/path/allpaths.c | 69 ++++++++++++++++-------------------
src/backend/optimizer/plan/planner.c | 19 +++++++---
src/backend/optimizer/util/relnode.c | 3 ++
src/include/nodes/relation.h | 8 ++++
4 files changed, 56 insertions(+), 43 deletions(-)
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 98d7a19dad..0adcfad958 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -878,7 +878,10 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
Assert(IS_SIMPLE_REL(rel));
if (rte->relkind == RELKIND_PARTITIONED_TABLE)
+ {
live_children = prune_append_rel_partitions(root, rel);
+ rel->live_partitioned_rels = list_make1_int(rti);
+ }
/*
* Initialize to compute size estimates for whole append relation.
@@ -1358,44 +1361,39 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
ListCell *l;
List *partitioned_rels = NIL;
RangeTblEntry *rte;
- bool build_partitioned_rels = false;
double partial_rows = -1;
+ /*
+ * AppendPath generated for partitioned tables must record the RT indexes
+ * of partitioned tables that are direct or indirect children of this
+ * Append rel. We can find them in rel->live_partitioned_rels. However,
+ * it contains only the immediate children, so collect those of the
+ * children that are partitioned themselves in loop below and concatenate
+ * all into one list to be passed to the path creation function.
+ *
+ * AppendPath may be for a sub-query RTE (UNION ALL), whose child sub-
+ * queries may contain references to partitioned tables. The loop below
+ * will look for such children and collect them in a list to be passed to
+ * the path creation function. (This assumes that we don't need to look
+ * through multiple levels of subquery RTEs; if we ever do, we could
+ * consider stuffing the list we generate here into sub-query RTE's
+ * RelOptInfo, just like we do for partitioned rels, which would be used
+ * when populating our parent rel with paths. For the present, that
+ * appears to be unnecessary.)
+ */
if (IS_SIMPLE_REL(rel))
{
- /*
- * A root partition will already have a PartitionedChildRelInfo, and a
- * non-root partitioned table doesn't need one, because its Append
- * paths will get flattened into the parent anyway. For a subquery
- * RTE, no PartitionedChildRelInfo exists; we collect all
- * partitioned_rels associated with any child. (This assumes that we
- * don't need to look through multiple levels of subquery RTEs; if we
- * ever do, we could create a PartitionedChildRelInfo with the
- * accumulated list of partitioned_rels which would then be found when
- * populated our parent rel with paths. For the present, that appears
- * to be unnecessary.)
- */
rte = planner_rt_fetch(rel->relid, root);
- switch (rte->rtekind)
- {
- case RTE_RELATION:
- if (rte->relkind == RELKIND_PARTITIONED_TABLE)
- partitioned_rels =
- get_partitioned_child_rels(root, rel->relid, NULL);
- break;
- case RTE_SUBQUERY:
- build_partitioned_rels = true;
- break;
- default:
- elog(ERROR, "unexpected rtekind: %d", (int) rte->rtekind);
- }
+ if (rte->rtekind == RTE_RELATION &&
+ rte->relkind == RELKIND_PARTITIONED_TABLE)
+ partitioned_rels = rel->live_partitioned_rels;
}
else if (rel->reloptkind == RELOPT_JOINREL && rel->part_scheme)
{
/*
- * Associate PartitionedChildRelInfo of the root partitioned tables
- * being joined with the root partitioned join (indicated by
- * RELOPT_JOINREL).
+ * For joinrel consisting of partitioned tables, construct the list
+ * list by combining live_partitioned_rels of the component
+ * partitioned tables, which is what the following does.
*/
partitioned_rels = get_partitioned_child_rels_for_join(root,
rel->relids);
@@ -1413,17 +1411,12 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
Path *cheapest_partial_path = NULL;
/*
- * If we need to build partitioned_rels, accumulate the partitioned
- * rels for this child.
+ * Accumulate the live partitioned children of this child, if it's
+ * itself partitioned rel.
*/
- if (build_partitioned_rels)
- {
- List *cprels;
-
- cprels = get_partitioned_child_rels(root, childrel->relid, NULL);
+ if (childrel->part_scheme)
partitioned_rels = list_concat(partitioned_rels,
- list_copy(cprels));
- }
+ list_copy(childrel->live_partitioned_rels));
/*
* If child has an unparameterized cheapest-total path, add that to
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 740de4957d..3b26bab37b 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -5975,14 +5975,23 @@ List *
get_partitioned_child_rels_for_join(PlannerInfo *root, Relids join_relids)
{
List *result = NIL;
- ListCell *l;
+ int relid;
- foreach(l, root->pcinfo_list)
+ relid = -1;
+ while ((relid = bms_next_member(join_relids, relid)) >= 0)
{
- PartitionedChildRelInfo *pc = lfirst(l);
+ RelOptInfo *rel;
- if (bms_is_member(pc->parent_relid, join_relids))
- result = list_concat(result, list_copy(pc->child_rels));
+ /* Paranoia: ignore bogus relid indexes */
+ if (relid >= root->simple_rel_array_size)
+ continue;
+ rel = root->simple_rel_array[relid];
+ if (rel == NULL)
+ continue;
+ Assert(rel->relid == relid); /* sanity check on array */
+ Assert(rel->part_scheme != NULL);
+ Assert(list_length(rel->live_partitioned_rels) >= 1);
+ result = list_concat(result, list_copy(rel->live_partitioned_rels));
}
return result;
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 5b5be8fe16..ad40ac7f8b 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -159,6 +159,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
rel->part_rels = NULL;
rel->partexprs = NULL;
rel->nullable_partexprs = NULL;
+ rel->live_partitioned_rels = NIL;
/*
* Pass top parent's relids down the inheritance hierarchy. If the parent
@@ -574,6 +575,7 @@ build_join_rel(PlannerInfo *root,
joinrel->part_rels = NULL;
joinrel->partexprs = NULL;
joinrel->nullable_partexprs = NULL;
+ joinrel->live_partitioned_rels = NIL;
/* Compute information relevant to the foreign relations. */
set_foreign_rel_properties(joinrel, outer_rel, inner_rel);
@@ -745,6 +747,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
joinrel->part_rels = NULL;
joinrel->partexprs = NULL;
joinrel->nullable_partexprs = NULL;
+ joinrel->live_partitioned_rels = NIL;
joinrel->top_parent_relids = bms_union(outer_rel->top_parent_relids,
inner_rel->top_parent_relids);
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 5ee23a5bb5..6454954e3b 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -542,6 +542,8 @@ typedef struct PartitionSchemeData *PartitionScheme;
* partition_qual - Partition constraint if not the root
* part_rels - RelOptInfos for each partition
* partexprs, nullable_partexprs - Partition key expressions
+ * live_partitioned_rels - RT indexes of unpruned partitions that are
+ * partitioned tables themselves
*
* Note: A base relation always has only one set of partition keys, but a join
* relation may have as many sets of partition keys as the number of relations
@@ -674,6 +676,12 @@ typedef struct RelOptInfo
* stored in the same order of bounds */
List **partexprs; /* Non-nullable partition key expressions. */
List **nullable_partexprs; /* Nullable partition key expressions. */
+
+ /*
+ * RT indexes of live partitions that are partitioned tables themselves.
+ * This includes the RT index of the table itself.
+ */
+ List *live_partitioned_rels;
} RelOptInfo;
/*
--
2.11.0