1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-24 09:27:52 +03:00

Fix calculation of relid sets for partitionwise child joins.

Applying add_outer_joins_to_relids() to a child join doesn't actually
work, even if we've built a SpecialJoinInfo specialized to the child,
because that function will also compare the join's relids to elements
of the main join_info_list, which only deal in regular relids not
child relids.  This mistake escaped detection by the existing
partitionwise join tests because they didn't test any cases where
add_outer_joins_to_relids() needs to add additional OJ relids (that
is, any cases where join reordering per identity 3 is possible).

Instead, let's apply adjust_child_relids() to the relids of the parent
join.  This requires minor code reordering to collect the relevant
AppendRelInfo structures first, but that's work we'd do shortly anyway.

Report and fix by Richard Guo; cosmetic changes by me

Discussion: https://postgr.es/m/CAMbWs49NCNbyubZWgci3o=_OTY=snCfAPtMnM-32f3mm-K-Ckw@mail.gmail.com
This commit is contained in:
Tom Lane
2023-07-21 12:00:14 -04:00
parent 66a9003e2e
commit f75595cd80
4 changed files with 75 additions and 12 deletions

View File

@@ -1640,13 +1640,15 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
child_rel1->relids,
child_rel2->relids);
/* Build correct join relids for child join */
child_joinrelids = bms_union(child_rel1->relids, child_rel2->relids);
child_joinrelids = add_outer_joins_to_relids(root, child_joinrelids,
child_sjinfo, NULL);
/* Find the AppendRelInfo structures */
appinfos = find_appinfos_by_relids(root, child_joinrelids, &nappinfos);
appinfos = find_appinfos_by_relids(root,
bms_union(child_rel1->relids,
child_rel2->relids),
&nappinfos);
/* Build correct join relids for child join */
child_joinrelids = adjust_child_relids(joinrel->relids,
nappinfos, appinfos);
/*
* Construct restrictions applicable to the child join from those

View File

@@ -871,10 +871,19 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
/* The parent joinrel should have consider_partitionwise_join set. */
Assert(parent_joinrel->consider_partitionwise_join);
/*
* Find the AppendRelInfo structures for the child baserels. We'll need
* these for computing the child join's relid set, and later for mapping
* Vars to the child rel.
*/
appinfos = find_appinfos_by_relids(root,
bms_union(outer_rel->relids,
inner_rel->relids),
&nappinfos);
joinrel->reloptkind = RELOPT_OTHER_JOINREL;
joinrel->relids = bms_union(outer_rel->relids, inner_rel->relids);
joinrel->relids = add_outer_joins_to_relids(root, joinrel->relids, sjinfo,
NULL);
joinrel->relids = adjust_child_relids(parent_joinrel->relids,
nappinfos, appinfos);
joinrel->rows = 0;
/* cheap startup cost is interesting iff not all tuples to be retrieved */
joinrel->consider_startup = (root->tuple_fraction > 0);
@@ -935,9 +944,6 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
/* Compute information relevant to foreign relations. */
set_foreign_rel_properties(joinrel, outer_rel, inner_rel);
/* Compute information needed for mapping Vars to the child rel */
appinfos = find_appinfos_by_relids(root, joinrel->relids, &nappinfos);
/* Set up reltarget struct */
build_child_join_reltarget(root, parent_joinrel, joinrel,
nappinfos, appinfos);