RestrictInfo *rinfo,
Relids eval_relids)
{
- Relids clause_relids = rinfo->clause_relids;
+ Relids clause_relids;
ListCell *lc;
/* Nothing to do if no outer joins have been performed yet. */
if (!bms_overlap(eval_relids, root->outer_join_rels))
return true;
+ /*
+ * For an ordinary qual clause, we consider the actual clause_relids as
+ * explained above. However, it's possible for multiple members of a
+ * group of clone quals to have the same clause_relids, so for clones use
+ * the required_relids instead to ensure we select just one of them.
+ */
+ if (rinfo->has_clone || rinfo->is_clone)
+ clause_relids = rinfo->required_relids;
+ else
+ clause_relids = rinfo->clause_relids;
+
foreach(lc, root->join_info_list)
{
SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
-> Seq Scan on int4_tbl t4
(12 rows)
+explain (costs off)
+select * from int4_tbl t1
+ left join (int4_tbl t2 left join int4_tbl t3 on t2.f1 > 0) on t2.f1 > 1
+ left join int4_tbl t4 on t2.f1 > 2 and t3.f1 > 3
+where t1.f1 = coalesce(t2.f1, 1);
+ QUERY PLAN
+----------------------------------------------------
+ Nested Loop Left Join
+ Join Filter: ((t2.f1 > 2) AND (t3.f1 > 3))
+ -> Nested Loop Left Join
+ Join Filter: (t2.f1 > 0)
+ -> Nested Loop Left Join
+ Filter: (t1.f1 = COALESCE(t2.f1, 1))
+ -> Seq Scan on int4_tbl t1
+ -> Materialize
+ -> Seq Scan on int4_tbl t2
+ Filter: (f1 > 1)
+ -> Seq Scan on int4_tbl t3
+ -> Materialize
+ -> Seq Scan on int4_tbl t4
+(13 rows)
+
+explain (costs off)
+select * from int4_tbl t1
+ left join ((select t2.f1 from int4_tbl t2
+ left join int4_tbl t3 on t2.f1 > 0
+ where t3.f1 is null) s
+ left join tenk1 t4 on s.f1 > 1)
+ on s.f1 = t1.f1;
+ QUERY PLAN
+-------------------------------------------------
+ Nested Loop Left Join
+ Join Filter: (t2.f1 > 1)
+ -> Hash Right Join
+ Hash Cond: (t2.f1 = t1.f1)
+ -> Nested Loop Left Join
+ Join Filter: (t2.f1 > 0)
+ Filter: (t3.f1 IS NULL)
+ -> Seq Scan on int4_tbl t2
+ -> Materialize
+ -> Seq Scan on int4_tbl t3
+ -> Hash
+ -> Seq Scan on int4_tbl t1
+ -> Seq Scan on tenk1 t4
+(13 rows)
+
+explain (costs off)
+select * from onek t1
+ left join onek t2 on t1.unique1 = t2.unique1
+ left join onek t3 on t2.unique1 = t3.unique1
+ left join onek t4 on t3.unique1 = t4.unique1 and t2.unique2 = t4.unique2;
+ QUERY PLAN
+------------------------------------------------------------------------
+ Hash Left Join
+ Hash Cond: ((t3.unique1 = t4.unique1) AND (t2.unique2 = t4.unique2))
+ -> Hash Left Join
+ Hash Cond: (t2.unique1 = t3.unique1)
+ -> Hash Left Join
+ Hash Cond: (t1.unique1 = t2.unique1)
+ -> Seq Scan on onek t1
+ -> Hash
+ -> Seq Scan on onek t2
+ -> Hash
+ -> Seq Scan on onek t3
+ -> Hash
+ -> Seq Scan on onek t4
+(13 rows)
+
--
-- check a case where we formerly got confused by conflicting sort orders
-- in redundant merge join path keys
left join int4_tbl t3 on t2.f1 = t3.f1
left join int4_tbl t4 on t3.f1 != t4.f1;
+explain (costs off)
+select * from int4_tbl t1
+ left join (int4_tbl t2 left join int4_tbl t3 on t2.f1 > 0) on t2.f1 > 1
+ left join int4_tbl t4 on t2.f1 > 2 and t3.f1 > 3
+where t1.f1 = coalesce(t2.f1, 1);
+
+explain (costs off)
+select * from int4_tbl t1
+ left join ((select t2.f1 from int4_tbl t2
+ left join int4_tbl t3 on t2.f1 > 0
+ where t3.f1 is null) s
+ left join tenk1 t4 on s.f1 > 1)
+ on s.f1 = t1.f1;
+
+explain (costs off)
+select * from onek t1
+ left join onek t2 on t1.unique1 = t2.unique1
+ left join onek t3 on t2.unique1 = t3.unique1
+ left join onek t4 on t3.unique1 = t4.unique1 and t2.unique2 = t4.unique2;
+
--
-- check a case where we formerly got confused by conflicting sort orders
-- in redundant merge join path keys