aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/path/joinrels.c14
-rw-r--r--src/backend/optimizer/util/relnode.c18
-rw-r--r--src/test/regress/expected/partition_join.out46
-rw-r--r--src/test/regress/sql/partition_join.sql9
4 files changed, 75 insertions, 12 deletions
diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c
index 2feab2184f4..a3f94be1d64 100644
--- a/src/backend/optimizer/path/joinrels.c
+++ b/src/backend/optimizer/path/joinrels.c
@@ -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
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
index 15e3910b79a..76dad17e336 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -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);
diff --git a/src/test/regress/expected/partition_join.out b/src/test/regress/expected/partition_join.out
index 762cc8e53b0..6560fe2416f 100644
--- a/src/test/regress/expected/partition_join.out
+++ b/src/test/regress/expected/partition_join.out
@@ -62,6 +62,52 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b =
450 | 0450 | 450 | 0450
(4 rows)
+-- left outer join, 3-way
+EXPLAIN (COSTS OFF)
+SELECT COUNT(*) FROM prt1 t1
+ LEFT JOIN prt1 t2 ON t1.a = t2.a
+ LEFT JOIN prt1 t3 ON t2.a = t3.a;
+ QUERY PLAN
+--------------------------------------------------------
+ Aggregate
+ -> Append
+ -> Hash Left Join
+ Hash Cond: (t2_1.a = t3_1.a)
+ -> Hash Left Join
+ Hash Cond: (t1_1.a = t2_1.a)
+ -> Seq Scan on prt1_p1 t1_1
+ -> Hash
+ -> Seq Scan on prt1_p1 t2_1
+ -> Hash
+ -> Seq Scan on prt1_p1 t3_1
+ -> Hash Left Join
+ Hash Cond: (t2_2.a = t3_2.a)
+ -> Hash Left Join
+ Hash Cond: (t1_2.a = t2_2.a)
+ -> Seq Scan on prt1_p2 t1_2
+ -> Hash
+ -> Seq Scan on prt1_p2 t2_2
+ -> Hash
+ -> Seq Scan on prt1_p2 t3_2
+ -> Hash Left Join
+ Hash Cond: (t2_3.a = t3_3.a)
+ -> Hash Left Join
+ Hash Cond: (t1_3.a = t2_3.a)
+ -> Seq Scan on prt1_p3 t1_3
+ -> Hash
+ -> Seq Scan on prt1_p3 t2_3
+ -> Hash
+ -> Seq Scan on prt1_p3 t3_3
+(29 rows)
+
+SELECT COUNT(*) FROM prt1 t1
+ LEFT JOIN prt1 t2 ON t1.a = t2.a
+ LEFT JOIN prt1 t3 ON t2.a = t3.a;
+ count
+-------
+ 300
+(1 row)
+
-- left outer join, with whole-row reference; partitionwise join does not apply
EXPLAIN (COSTS OFF)
SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b;
diff --git a/src/test/regress/sql/partition_join.sql b/src/test/regress/sql/partition_join.sql
index 9e16f1ca550..48daf3aee39 100644
--- a/src/test/regress/sql/partition_join.sql
+++ b/src/test/regress/sql/partition_join.sql
@@ -34,6 +34,15 @@ EXPLAIN (COSTS OFF)
SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b;
SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b;
+-- left outer join, 3-way
+EXPLAIN (COSTS OFF)
+SELECT COUNT(*) FROM prt1 t1
+ LEFT JOIN prt1 t2 ON t1.a = t2.a
+ LEFT JOIN prt1 t3 ON t2.a = t3.a;
+SELECT COUNT(*) FROM prt1 t1
+ LEFT JOIN prt1 t2 ON t1.a = t2.a
+ LEFT JOIN prt1 t3 ON t2.a = t3.a;
+
-- left outer join, with whole-row reference; partitionwise join does not apply
EXPLAIN (COSTS OFF)
SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b;