pcinfo-for-subquery.patch
application/octet-stream
Filename: pcinfo-for-subquery.patch
Type: application/octet-stream
Part: 1
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/allpaths.c | 48 | 4 |
| src/backend/optimizer/plan/planner.c | 2 | 4 |
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 2d7e1d84d0..9c85302321 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -1287,13 +1287,29 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
ListCell *l;
List *partitioned_rels = NIL;
RangeTblEntry *rte;
+ bool build_partitioned_rels = false;
+ /*
+ * A plain relation will alread have a PartitionedChildRelInfo if it is
+ * partitioned. For a subquery RTE, no PartitionedChildRelInfo exists
+ * yet; we must build one if it is required.
+ */
rte = planner_rt_fetch(rel->relid, root);
- if (rte->relkind == RELKIND_PARTITIONED_TABLE)
+ switch (rte->rtekind)
{
- partitioned_rels = get_partitioned_child_rels(root, rel->relid);
- /* The root partitioned table is included as a child rel */
- Assert(list_length(partitioned_rels) >= 1);
+ case RTE_RELATION:
+ if (rte->relkind == RELKIND_PARTITIONED_TABLE)
+ {
+ partitioned_rels =
+ get_partitioned_child_rels(root, rel->relid);
+ Assert(list_length(partitioned_rels) >= 1);
+ }
+ break;
+ case RTE_SUBQUERY:
+ build_partitioned_rels = true;
+ break;
+ default:
+ elog(ERROR, "unexpcted rtekind: %d", (int) rte->rtekind);
}
/*
@@ -1307,6 +1323,19 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
ListCell *lcp;
/*
+ * If we need to build partitioned_rels, accumulate the partitioned
+ * rels for this child.
+ */
+ if (build_partitioned_rels)
+ {
+ List *cprels;
+
+ cprels = get_partitioned_child_rels(root, childrel->relid);
+ partitioned_rels = list_concat(partitioned_rels,
+ list_copy(cprels));
+ }
+
+ /*
* If child has an unparameterized cheapest-total path, add that to
* the unparameterized Append path we are constructing for the parent.
* If not, there's no workable unparameterized path.
@@ -1390,6 +1419,21 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
}
/*
+ * If our parent is also an appendrel, it will need to build an
+ * appropriate partitioned_rels list in turn, and that requires that we
+ * have a PartitionedChildRelInfo.
+ */
+ if (build_partitioned_rels && partitioned_rels != NIL)
+ {
+ PartitionedChildRelInfo *pcinfo;
+
+ pcinfo = makeNode(PartitionedChildRelInfo);
+ pcinfo->parent_relid = rel->relid;
+ pcinfo->child_rels = partitioned_rels;
+ root->pcinfo_list = lappend(root->pcinfo_list, pcinfo);
+ }
+
+ /*
* If we found unparameterized paths for all children, build an unordered,
* unparameterized Append path for the rel. (Note: this is correct even
* if we have zero or one live subpath due to constraint exclusion.)
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 6b79b3ad99..907622eadb 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -6076,7 +6076,8 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid)
* Returns a list of the RT indexes of the partitioned child relations
* with rti as the root parent RT index.
*
- * Note: Only call this function on RTEs known to be partitioned tables.
+ * Note: This function might get called even for range table entries that
+ * are not partitioned tables; in such a case, it will simply return NIL.
*/
List *
get_partitioned_child_rels(PlannerInfo *root, Index rti)
@@ -6095,8 +6096,5 @@ get_partitioned_child_rels(PlannerInfo *root, Index rti)
}
}
- /* The root partitioned table is included as a child rel */
- Assert(list_length(result) >= 1);
-
return result;
}