diff options
Diffstat (limited to 'src/backend/optimizer/path/allpaths.c')
-rw-r--r-- | src/backend/optimizer/path/allpaths.c | 78 |
1 files changed, 30 insertions, 48 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 0e80aeb65cd..5db1688bf04 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -910,6 +910,17 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, } /* + * If this is a partitioned baserel, set the consider_partitionwise_join + * flag; currently, we only consider partitionwise joins with the baserel + * if its targetlist doesn't contain a whole-row Var. + */ + if (enable_partitionwise_join && + rel->reloptkind == RELOPT_BASEREL && + rte->relkind == RELKIND_PARTITIONED_TABLE && + rel->attr_needed[InvalidAttrNumber - rel->min_attr] == NULL) + rel->consider_partitionwise_join = true; + + /* * Initialize to compute size estimates for whole append relation. * * We handle width estimates by weighting the widths of different child @@ -956,54 +967,6 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, childrel = find_base_rel(root, childRTindex); Assert(childrel->reloptkind == RELOPT_OTHER_MEMBER_REL); - if (rel->part_scheme) - { - AttrNumber attno; - - /* - * We need attr_needed data for building targetlist of a join - * relation representing join between matching partitions for - * partitionwise join. A given attribute of a child will be needed - * in the same highest joinrel where the corresponding attribute - * of parent is needed. Hence it suffices to use the same Relids - * set for parent and child. - */ - for (attno = rel->min_attr; attno <= rel->max_attr; attno++) - { - int index = attno - rel->min_attr; - Relids attr_needed = rel->attr_needed[index]; - - /* System attributes do not need translation. */ - if (attno <= 0) - { - Assert(rel->min_attr == childrel->min_attr); - childrel->attr_needed[index] = attr_needed; - } - else - { - Var *var = list_nth_node(Var, - appinfo->translated_vars, - attno - 1); - int child_index; - - /* - * Ignore any column dropped from the parent. - * Corresponding Var won't have any translation. It won't - * have attr_needed information, since it can not be - * referenced in the query. - */ - if (var == NULL) - { - Assert(attr_needed == NULL); - continue; - } - - child_index = var->varattno - childrel->min_attr; - childrel->attr_needed[child_index] = attr_needed; - } - } - } - /* * Copy/Modify targetlist. Even if this child is deemed empty, we need * its targetlist in case it falls on nullable side in a child-join @@ -1181,6 +1144,22 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, 1, &appinfo); /* + * Note: we could compute appropriate attr_needed data for the child's + * variables, by transforming the parent's attr_needed through the + * translated_vars mapping. However, currently there's no need + * because attr_needed is only examined for base relations not + * otherrels. So we just leave the child's attr_needed empty. + */ + + /* + * If we consider partitionwise joins with the parent rel, do the same + * for partitioned child rels. + */ + if (rel->consider_partitionwise_join && + childRTE->relkind == RELKIND_PARTITIONED_TABLE) + childrel->consider_partitionwise_join = true; + + /* * If parallelism is allowable for this query in general, see whether * it's allowable for this childrel in particular. But if we've * already decided the appendrel is not parallel-safe as a whole, @@ -3538,6 +3517,9 @@ generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel) if (!IS_PARTITIONED_REL(rel)) return; + /* The relation should have consider_partitionwise_join set. */ + Assert(rel->consider_partitionwise_join); + /* Guard against stack overflow due to overly deep partition hierarchy. */ check_stack_depth(); |