phv->phrels = replace_relid(phv->phrels, ojrelid, subst);
Assert(!bms_is_empty(phv->phrels));
replace_varno((Node *) phv->phexpr, relid, subst);
- phinfo->ph_lateral = replace_relid(phinfo->ph_lateral, relid, subst);
Assert(phv->phnullingrels == NULL); /* no need to adjust */
}
}
/* there isn't any other place to eval PHV */
if (bms_is_subset(phinfo->ph_eval_at, joinrelids) ||
- bms_is_subset(phinfo->ph_needed, joinrelids))
+ bms_is_subset(phinfo->ph_needed, joinrelids) ||
+ bms_is_member(r, phinfo->ph_lateral))
break;
}
if (lc)
Filter: (id IS NOT NULL)
(8 rows)
+-- Check that SJE does not remove self joins if a PHV references the removed
+-- rel laterally.
+explain (costs off)
+select * from emp1 t1 join emp1 t2 on t1.id = t2.id left join
+ lateral (select t1.id as t1id, * from generate_series(1,1) t3) s on true;
+ QUERY PLAN
+---------------------------------------------------
+ Nested Loop Left Join
+ -> Nested Loop
+ -> Seq Scan on emp1 t1
+ -> Index Scan using emp1_pkey on emp1 t2
+ Index Cond: (id = t1.id)
+ -> Function Scan on generate_series t3
+(6 rows)
+
-- We can remove the join even if we find the join can't duplicate rows and
-- the base quals of each side are different. In the following case we end up
-- moving quals over to s1 to make it so it can't match any rows.
on true)
on true;
+-- Check that SJE does not remove self joins if a PHV references the removed
+-- rel laterally.
+explain (costs off)
+select * from emp1 t1 join emp1 t2 on t1.id = t2.id left join
+ lateral (select t1.id as t1id, * from generate_series(1,1) t3) s on true;
+
-- We can remove the join even if we find the join can't duplicate rows and
-- the base quals of each side are different. In the following case we end up
-- moving quals over to s1 to make it so it can't match any rows.