RE: speeding up planning with partitions
Imai, Yoshikazu <imai.yoshikazu@jp.fujitsu.com>
Hi, Amit!
On Thu, Sept 13, 2018 at 10:29 PM, Amit Langote wrote:
> Attached is what I have at the moment.
I also do the code review of the patch.
I could only see a v3-0001.patch so far, so below are all about v3-0001.patch.
I am new to inheritance/partitioning codes and code review, so my review below might have some mistakes. If there are mistakes, please point out that kindly :)
v3-0001:
1. Is there any reason inheritance_make_rel_from_joinlist returns "parent" that is passed to it? I think we can refer parent in the caller even if inheritance_make_rel_from_joinlist returns nothing.
+static RelOptInfo *
+inheritance_make_rel_from_joinlist(PlannerInfo *root,
+ RelOptInfo *parent,
+ List *joinlist)
+{
...
+ return parent;
+}
2. Is there the possible case that IS_DUMMY_REL(child_joinrel) is true in inheritance_adjust_scanjoin_target()?
+inheritance_adjust_scanjoin_target(PlannerInfo *root,
...
+{
...
+ foreach(lc, root->inh_target_child_rels)
+ {
...
+ /*
+ * If the child was pruned, its corresponding joinrel will be empty,
+ * which we can ignore safely.
+ */
+ if (IS_DUMMY_REL(child_joinrel))
+ continue;
I think inheritance_make_rel_from_joinlist() doesn't make dummy joinrel for the child that was pruned.
+inheritance_make_rel_from_joinlist(PlannerInfo *root,
...
+{
...
+ foreach(lc, root->append_rel_list)
+ {
+ RelOptInfo *childrel;
...
+ /* Ignore excluded/pruned children. */
+ if (IS_DUMMY_REL(childrel))
+ continue;
...
+ /*
+ * Save child joinrel to be processed later in
+ * inheritance_adjust_scanjoin_target, which adjusts its paths to
+ * be able to emit expressions in query's top-level target list.
+ */
+ root->inh_target_child_rels = lappend(root->inh_target_child_rels,
+ childrel);
+ }
+}
3.
Is the "root->parse->commandType != CMD_INSERT" required in:
@@ -2018,13 +1514,45 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
...
+ /*
+ * For UPDATE/DELETE on an inheritance parent, we must generate and
+ * apply scanjoin target based on targetlist computed using each
+ * of the child relations.
+ */
+ if (parse->commandType != CMD_INSERT &&
+ current_rel->reloptkind == RELOPT_BASEREL &&
+ current_rel->relid == root->parse->resultRelation &&
+ root->simple_rte_array[current_rel->relid]->inh)
...
@@ -2137,92 +1665,123 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
final_rel->fdwroutine = current_rel->fdwroutine;
...
- foreach(lc, current_rel->pathlist)
+ if (current_rel->reloptkind == RELOPT_BASEREL &&
+ current_rel->relid == root->parse->resultRelation &&
+ !IS_DUMMY_REL(current_rel) &&
+ root->simple_rte_array[current_rel->relid]->inh &&
+ parse->commandType != CMD_INSERT)
I think if a condition would be "current_rel->relid == root->parse->resultRelation && parse->commandType != CMD_INSERT" at the above if clause, elog() is called in the query_planner and planner don't reach above if clause.
Of course there is the case that query_planner returns the dummy joinrel and elog is not called, but in that case, current_rel->relid may be 0(current_rel is dummy joinrel) and root->parse->resultRelation may be not 0(a query is INSERT).
4. Can't we use define value(IS_PARTITIONED or something like IS_INHERITANCE?) to identify inheritance and partitioned table in below code? It was little confusing to me that which code is related to inheritance/partitioned when looking codes.
In make_one_rel():
+ if (root->parse->resultRelation &&
+ root->simple_rte_array[root->parse->resultRelation]->inh)
+ {
...
+ rel = inheritance_make_rel_from_joinlist(root, targetrel, joinlist);
In inheritance_make_rel_from_joinlist():
+ if (childrel->part_scheme != NULL)
+ childrel =
+ inheritance_make_rel_from_joinlist(root, childrel,
+ translated_joinlist);
I can't review inheritance_adjust_scanjoin_target() deeply, because it is difficult to me to understand fully codes about join processing.
--
Yoshikazu Imai
Commits
-
Clean up handling of constraint_exclusion and enable_partition_pruning.
- e03ff739695c 12.0 landed
- 11ea45ffec9a 11.3 landed
-
Add test case exercising formerly-unreached code in inheritance_planner.
- 8fba397f0ca7 12.0 landed
-
Speed up planning when partitions can be pruned at plan time.
- 428b260f87e8 12.0 landed
-
Avoid crash in partitionwise join planning under GEQO.
- 7ad6498fd5a6 12.0 landed
- d70c147fa217 11.3 landed
-
Avoid passing query tlist around separately from root->processed_tlist.
- 333ed246c6f3 12.0 landed
-
Build "other rels" of appendrel baserels in a separate step.
- 53bcf5e3dbea 12.0 landed
-
Get rid of duplicate child RTE for a partitioned table.
- e8d5dd6be79e 12.0 landed
-
Rearrange make_partitionedrel_pruneinfo to avoid work when we can't prune.
- 734308a22072 12.0 landed
-
Don't copy PartitionBoundInfo in set_relation_partition_info.
- c8151e642368 12.0 landed
-
Move building of child base quals out into a new function
- 80579f9bb171 12.0 landed
-
Reorganize planner code moved in b60c39759908
- d723f56872a9 12.0 landed
-
Move inheritance expansion code into its own file
- b60c39759908 12.0 landed
-
Fix inherited UPDATE/DELETE with UNION ALL subqueries.
- c03ad5602f52 9.4.0 cited
-
Rearrange planner to save the whole PlannerInfo (subroot) for a subquery.
- b3aaf9081a1a 9.2.0 cited