mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Fix thinko in join removal.
In commit 9df8f903e
I (tgl) switched join_is_removable() from
using the min relid sets of the join under consideration to
using its full syntactic relid sets. This was a mistake,
as it allowed join removal in cases where a reference to the
join output would survive in some syntactically-lower join
condition. Revert to the former coding.
Richard Guo
Discussion: https://postgr.es/m/CAMbWs4-EU9uBGSP7G-iTwLBhRQ=rnZKvFDhD+n+xhajokyPCKg@mail.gmail.com
This commit is contained in:
parent
70b42f2790
commit
d0f952691f
@ -88,11 +88,8 @@ restart:
|
|||||||
*/
|
*/
|
||||||
innerrelid = bms_singleton_member(sjinfo->min_righthand);
|
innerrelid = bms_singleton_member(sjinfo->min_righthand);
|
||||||
|
|
||||||
/*
|
/* Compute the relid set for the join we are considering */
|
||||||
* Compute the relid set for the join we are considering. We can
|
joinrelids = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand);
|
||||||
* assume things are done in syntactic order.
|
|
||||||
*/
|
|
||||||
joinrelids = bms_union(sjinfo->syn_lefthand, sjinfo->syn_righthand);
|
|
||||||
if (sjinfo->ojrelid != 0)
|
if (sjinfo->ojrelid != 0)
|
||||||
joinrelids = bms_add_member(joinrelids, sjinfo->ojrelid);
|
joinrelids = bms_add_member(joinrelids, sjinfo->ojrelid);
|
||||||
|
|
||||||
@ -204,8 +201,8 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)
|
|||||||
if (!rel_supports_distinctness(root, innerrel))
|
if (!rel_supports_distinctness(root, innerrel))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Compute the syntactic relid set for the join we are considering */
|
/* Compute the relid set for the join we are considering */
|
||||||
inputrelids = bms_union(sjinfo->syn_lefthand, sjinfo->syn_righthand);
|
inputrelids = bms_union(sjinfo->min_lefthand, sjinfo->min_righthand);
|
||||||
Assert(sjinfo->ojrelid != 0);
|
Assert(sjinfo->ojrelid != 0);
|
||||||
joinrelids = bms_copy(inputrelids);
|
joinrelids = bms_copy(inputrelids);
|
||||||
joinrelids = bms_add_member(joinrelids, sjinfo->ojrelid);
|
joinrelids = bms_add_member(joinrelids, sjinfo->ojrelid);
|
||||||
|
@ -5432,6 +5432,22 @@ select d.* from d left join (select distinct * from b) s
|
|||||||
-> Seq Scan on d
|
-> Seq Scan on d
|
||||||
(9 rows)
|
(9 rows)
|
||||||
|
|
||||||
|
-- join removal is not possible here
|
||||||
|
explain (costs off)
|
||||||
|
select 1 from a t1
|
||||||
|
left join (a t2 left join a t3 on t2.id = 1) on t2.id = 1;
|
||||||
|
QUERY PLAN
|
||||||
|
--------------------------------------------------------
|
||||||
|
Nested Loop Left Join
|
||||||
|
-> Seq Scan on a t1
|
||||||
|
-> Materialize
|
||||||
|
-> Nested Loop Left Join
|
||||||
|
Join Filter: (t2.id = 1)
|
||||||
|
-> Index Only Scan using a_pkey on a t2
|
||||||
|
Index Cond: (id = 1)
|
||||||
|
-> Seq Scan on a t3
|
||||||
|
(8 rows)
|
||||||
|
|
||||||
-- check join removal works when uniqueness of the join condition is enforced
|
-- check join removal works when uniqueness of the join condition is enforced
|
||||||
-- by a UNION
|
-- by a UNION
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
|
@ -1958,6 +1958,11 @@ explain (costs off)
|
|||||||
select d.* from d left join (select distinct * from b) s
|
select d.* from d left join (select distinct * from b) s
|
||||||
on d.a = s.id;
|
on d.a = s.id;
|
||||||
|
|
||||||
|
-- join removal is not possible here
|
||||||
|
explain (costs off)
|
||||||
|
select 1 from a t1
|
||||||
|
left join (a t2 left join a t3 on t2.id = 1) on t2.id = 1;
|
||||||
|
|
||||||
-- check join removal works when uniqueness of the join condition is enforced
|
-- check join removal works when uniqueness of the join condition is enforced
|
||||||
-- by a UNION
|
-- by a UNION
|
||||||
explain (costs off)
|
explain (costs off)
|
||||||
|
Loading…
Reference in New Issue
Block a user