mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
Fix 'negative bitmapset member' error
When removing a useless join, we'd remove PHVs that are not used at join partner rels or above the join. A PHV that references the join's relid in ph_eval_at is logically "above" the join and thus should not be removed. We have the following check for that: !bms_is_member(ojrelid, phinfo->ph_eval_at) However, in the case of SJE removing a useless inner join, 'ojrelid' is set to -1, which would trigger the "negative bitmapset member not allowed" error in bms_is_member(). Fix it by skipping examining ojrelid for inner joins in this check. Reported-by: Zuming Jiang Bug: #18260 Discussion: https://postgr.es/m/18260-1b6a0c4ae311b837%40postgresql.org Author: Richard Guo Reviewed-by: Andrei Lepikhov
This commit is contained in:
parent
aa817c7496
commit
fe093994db
@ -456,7 +456,7 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
|
||||
Assert(sjinfo == NULL || !bms_is_member(relid, phinfo->ph_lateral));
|
||||
if (bms_is_subset(phinfo->ph_needed, joinrelids) &&
|
||||
bms_is_member(relid, phinfo->ph_eval_at) &&
|
||||
!bms_is_member(ojrelid, phinfo->ph_eval_at))
|
||||
(sjinfo == NULL || !bms_is_member(ojrelid, phinfo->ph_eval_at)))
|
||||
{
|
||||
root->placeholder_list = foreach_delete_current(root->placeholder_list,
|
||||
l);
|
||||
|
@ -6821,6 +6821,26 @@ on true;
|
||||
Filter: (id IS NOT NULL)
|
||||
(8 rows)
|
||||
|
||||
-- Check that SJE removes the whole PHVs correctly
|
||||
explain (verbose, costs off)
|
||||
select 1 from emp1 t1 left join
|
||||
((select 1 as x, * from emp1 t2) s1 inner join
|
||||
(select * from emp1 t3) s2 on s1.id = s2.id)
|
||||
on true
|
||||
where s1.x = 1;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------
|
||||
Nested Loop
|
||||
Output: 1
|
||||
-> Seq Scan on public.emp1 t1
|
||||
Output: t1.id, t1.code
|
||||
-> Materialize
|
||||
Output: t3.id
|
||||
-> Seq Scan on public.emp1 t3
|
||||
Output: t3.id
|
||||
Filter: ((t3.id IS NOT NULL) AND (1 = 1))
|
||||
(9 rows)
|
||||
|
||||
-- Check that PHVs do not impose any constraints on removing self joins
|
||||
explain (verbose, costs off)
|
||||
select * from emp1 t1 join emp1 t2 on t1.id = t2.id left join
|
||||
|
@ -2600,6 +2600,14 @@ select * from emp1 t1 left join
|
||||
on true)
|
||||
on true;
|
||||
|
||||
-- Check that SJE removes the whole PHVs correctly
|
||||
explain (verbose, costs off)
|
||||
select 1 from emp1 t1 left join
|
||||
((select 1 as x, * from emp1 t2) s1 inner join
|
||||
(select * from emp1 t3) s2 on s1.id = s2.id)
|
||||
on true
|
||||
where s1.x = 1;
|
||||
|
||||
-- Check that PHVs do not impose any constraints on removing self joins
|
||||
explain (verbose, costs off)
|
||||
select * from emp1 t1 join emp1 t2 on t1.id = t2.id left join
|
||||
|
Loading…
x
Reference in New Issue
Block a user