From 77fa061f1d3d89efc8abb0ec91bfd7611a39641b Mon Sep 17 00:00:00 2001 From: erthalion <9erthalion6@gmail.com> Date: Tue, 11 Sep 2018 21:09:44 +0200 Subject: [PATCH 2/5] Targetlist of a child-join is produced by translating that of parent join The next patch adds more general partition matching algorithm for partition-wise join. With that change, the first pair of joining relations for the parent joinrel may not produce a partition-wise join because of the restrictions in partition_bounds_merge(), to be added in the next patch. Hence the first pair of joining relations, which is used to build the child join and presented to build_child_join_rel(), for the child joinrel does not correspond to the first pair of joining relations for the parent joinrel. The targetlist built using different pairs have the targetlist entries arranged in different order. An appendrel expects that all its children have their targetlists ordered in the same fashion. Hence translate the parent's targetlist so that parent and child joinrels have their targetlists in sync. Basic partition-wise join commit f49842d1ee31b976c681322f76025d7732e860f3 modified build_joinrel_tlist() to build targetlist for child-join. With the above changes we don't need it anymore. Similarly, the same commit added code to set_append_rel_size() to compute attr_needed for a child-join relation. That change too is not needed with the above change. This commit reverts those two changes. Ashutosh Bapat, reviewed by Dmitry Dolgov --- src/backend/optimizer/util/relnode.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 39f5729b91..2f1137c13d 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -802,6 +802,19 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, appinfos = find_appinfos_by_relids(root, joinrel->relids, &nappinfos); + /* + * The first pair of joining relations for the parent joinrel may not + * produce a partition-wise join because of the restrictions in + * partition_bounds_merge(). Hence the first pair of joining relations, + * which is used to build the child join and presented here, for the child + * joinrel does not correspond to the first pair of joining relations for + * the parent joinrel. The targetlist built using different pairs have the + * targetlist nodes arranged in different order. An appendrel expects that + * all its children have their targetlists ordered in the same fashion. + * Hence translate the parent's targetlist so that parent and child + * joinrels have their targetlists in sync. + */ + joinrel->reltarget = copy_pathtarget(parent_joinrel->reltarget); /* Set up reltarget struct */ build_child_join_reltarget(root, parent_joinrel, joinrel, nappinfos, appinfos); @@ -907,6 +920,12 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, Relids relids = joinrel->relids; ListCell *vars; + /* + * We only see parent joins. Targetlist of a child-join is computed by + * translating corresponding parent join's targetlist. + */ + Assert(joinrel->reloptkind == RELOPT_JOINREL); + foreach(vars, input_rel->reltarget->exprs) { Var *var = (Var *) lfirst(vars); @@ -934,6 +953,7 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, /* Is it still needed above this joinrel? */ ndx = var->varattno - baserel->min_attr; + if (bms_nonempty_difference(baserel->attr_needed[ndx], relids)) { /* Yup, add it to the output */ -- 2.16.4