mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Fix another oversight in checking if a join with LATERAL refs is legal.
It was possible for the planner to decide to join a LATERAL subquery to the outer side of an outer join before the outer join itself is completed. Normally that's fine because of the associativity rules, but it doesn't work if the subquery contains a lateral reference to the inner side of the outer join. In such a situation the outer join *must* be done first. join_is_legal() missed this consideration and would allow the join to be attempted, but the actual path-building code correctly decided that no valid join path could be made, sometimes leading to planner errors such as "failed to build any N-way joins". Per report from Andreas Seltenreich. Back-patch to 9.3 where LATERAL support was added.
This commit is contained in:
@ -3579,6 +3579,47 @@ select * from
|
||||
doh! | 123 | 456 | hi de ho neighbor |
|
||||
(2 rows)
|
||||
|
||||
--
|
||||
-- test for appropriate join order in the presence of lateral references
|
||||
--
|
||||
explain (verbose, costs off)
|
||||
select * from
|
||||
text_tbl t1
|
||||
left join int8_tbl i8
|
||||
on i8.q2 = 123,
|
||||
lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss
|
||||
where t1.f1 = ss.f1;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------
|
||||
Nested Loop
|
||||
Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1
|
||||
Join Filter: (t1.f1 = t2.f1)
|
||||
-> Nested Loop Left Join
|
||||
Output: t1.f1, i8.q1, i8.q2
|
||||
-> Seq Scan on public.text_tbl t1
|
||||
Output: t1.f1
|
||||
-> Materialize
|
||||
Output: i8.q1, i8.q2
|
||||
-> Seq Scan on public.int8_tbl i8
|
||||
Output: i8.q1, i8.q2
|
||||
Filter: (i8.q2 = 123)
|
||||
-> Limit
|
||||
Output: (i8.q1), t2.f1
|
||||
-> Seq Scan on public.text_tbl t2
|
||||
Output: i8.q1, t2.f1
|
||||
(16 rows)
|
||||
|
||||
select * from
|
||||
text_tbl t1
|
||||
left join int8_tbl i8
|
||||
on i8.q2 = 123,
|
||||
lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss
|
||||
where t1.f1 = ss.f1;
|
||||
f1 | q1 | q2 | q1 | f1
|
||||
------+------------------+-----+------------------+------
|
||||
doh! | 4567890123456789 | 123 | 4567890123456789 | doh!
|
||||
(1 row)
|
||||
|
||||
--
|
||||
-- test ability to push constants through outer join clauses
|
||||
--
|
||||
|
@ -1115,6 +1115,25 @@ select * from
|
||||
left join int4_tbl i4
|
||||
on i8.q1 = i4.f1;
|
||||
|
||||
--
|
||||
-- test for appropriate join order in the presence of lateral references
|
||||
--
|
||||
|
||||
explain (verbose, costs off)
|
||||
select * from
|
||||
text_tbl t1
|
||||
left join int8_tbl i8
|
||||
on i8.q2 = 123,
|
||||
lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss
|
||||
where t1.f1 = ss.f1;
|
||||
|
||||
select * from
|
||||
text_tbl t1
|
||||
left join int8_tbl i8
|
||||
on i8.q2 = 123,
|
||||
lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss
|
||||
where t1.f1 = ss.f1;
|
||||
|
||||
--
|
||||
-- test ability to push constants through outer join clauses
|
||||
--
|
||||
|
Reference in New Issue
Block a user