mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Undo mistaken tightening in join_is_legal().
One of the changes I made in commit8703059c6b
turns out not to have been such a good idea: we still need the exception in join_is_legal() that allows a join if both inputs already overlap the RHS of the special join we're checking. Otherwise we can miss valid plans, and might indeed fail to find a plan at all, as in recent report from Andreas Seltenreich. That code was added way back in commitc17117649b
, but I failed to include a regression test case then; my bad. Put it back with a better explanation, and a test this time. The logic does end up a bit different than before though: I now believe it's appropriate to make this check first, thereby allowing such a case whether or not we'd consider the previous SJ(s) to commute with this one. (Presumably, we already decided they did; but it was confusing to have this consideration in the middle of the code that was handling the other case.) Back-patch to all active branches, like the previous patch.
This commit is contained in:
@ -3563,6 +3563,52 @@ select t1.* from
|
||||
hi de ho neighbor
|
||||
(2 rows)
|
||||
|
||||
explain (verbose, costs off)
|
||||
select * from
|
||||
text_tbl t1
|
||||
inner join int8_tbl i8
|
||||
on i8.q2 = 456
|
||||
right join text_tbl t2
|
||||
on t1.f1 = 'doh!'
|
||||
left join int4_tbl i4
|
||||
on i8.q1 = i4.f1;
|
||||
QUERY PLAN
|
||||
--------------------------------------------------------
|
||||
Nested Loop Left Join
|
||||
Output: t1.f1, i8.q1, i8.q2, t2.f1, i4.f1
|
||||
-> Seq Scan on public.text_tbl t2
|
||||
Output: t2.f1
|
||||
-> Materialize
|
||||
Output: i8.q1, i8.q2, i4.f1, t1.f1
|
||||
-> Nested Loop
|
||||
Output: i8.q1, i8.q2, i4.f1, t1.f1
|
||||
-> Nested Loop Left Join
|
||||
Output: i8.q1, i8.q2, i4.f1
|
||||
Join Filter: (i8.q1 = i4.f1)
|
||||
-> Seq Scan on public.int8_tbl i8
|
||||
Output: i8.q1, i8.q2
|
||||
Filter: (i8.q2 = 456)
|
||||
-> Seq Scan on public.int4_tbl i4
|
||||
Output: i4.f1
|
||||
-> Seq Scan on public.text_tbl t1
|
||||
Output: t1.f1
|
||||
Filter: (t1.f1 = 'doh!'::text)
|
||||
(19 rows)
|
||||
|
||||
select * from
|
||||
text_tbl t1
|
||||
inner join int8_tbl i8
|
||||
on i8.q2 = 456
|
||||
right join text_tbl t2
|
||||
on t1.f1 = 'doh!'
|
||||
left join int4_tbl i4
|
||||
on i8.q1 = i4.f1;
|
||||
f1 | q1 | q2 | f1 | f1
|
||||
------+-----+-----+-------------------+----
|
||||
doh! | 123 | 456 | doh! |
|
||||
doh! | 123 | 456 | hi de ho neighbor |
|
||||
(2 rows)
|
||||
|
||||
--
|
||||
-- test ability to push constants through outer join clauses
|
||||
--
|
||||
|
@ -1108,6 +1108,25 @@ select t1.* from
|
||||
left join int4_tbl i4
|
||||
on (i8.q2 = i4.f1);
|
||||
|
||||
explain (verbose, costs off)
|
||||
select * from
|
||||
text_tbl t1
|
||||
inner join int8_tbl i8
|
||||
on i8.q2 = 456
|
||||
right join text_tbl t2
|
||||
on t1.f1 = 'doh!'
|
||||
left join int4_tbl i4
|
||||
on i8.q1 = i4.f1;
|
||||
|
||||
select * from
|
||||
text_tbl t1
|
||||
inner join int8_tbl i8
|
||||
on i8.q2 = 456
|
||||
right join text_tbl t2
|
||||
on t1.f1 = 'doh!'
|
||||
left join int4_tbl i4
|
||||
on i8.q1 = i4.f1;
|
||||
|
||||
--
|
||||
-- test ability to push constants through outer join clauses
|
||||
--
|
||||
|
Reference in New Issue
Block a user