Skip to content

Commit fe09399

Browse files
committed
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
1 parent aa817c7 commit fe09399

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

src/backend/optimizer/plan/analyzejoins.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel,
456456
Assert(sjinfo == NULL || !bms_is_member(relid, phinfo->ph_lateral));
457457
if (bms_is_subset(phinfo->ph_needed, joinrelids) &&
458458
bms_is_member(relid, phinfo->ph_eval_at) &&
459-
!bms_is_member(ojrelid, phinfo->ph_eval_at))
459+
(sjinfo == NULL || !bms_is_member(ojrelid, phinfo->ph_eval_at)))
460460
{
461461
root->placeholder_list = foreach_delete_current(root->placeholder_list,
462462
l);

src/test/regress/expected/join.out

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6821,6 +6821,26 @@ on true;
68216821
Filter: (id IS NOT NULL)
68226822
(8 rows)
68236823

6824+
-- Check that SJE removes the whole PHVs correctly
6825+
explain (verbose, costs off)
6826+
select 1 from emp1 t1 left join
6827+
((select 1 as x, * from emp1 t2) s1 inner join
6828+
(select * from emp1 t3) s2 on s1.id = s2.id)
6829+
on true
6830+
where s1.x = 1;
6831+
QUERY PLAN
6832+
---------------------------------------------------------
6833+
Nested Loop
6834+
Output: 1
6835+
-> Seq Scan on public.emp1 t1
6836+
Output: t1.id, t1.code
6837+
-> Materialize
6838+
Output: t3.id
6839+
-> Seq Scan on public.emp1 t3
6840+
Output: t3.id
6841+
Filter: ((t3.id IS NOT NULL) AND (1 = 1))
6842+
(9 rows)
6843+
68246844
-- Check that PHVs do not impose any constraints on removing self joins
68256845
explain (verbose, costs off)
68266846
select * from emp1 t1 join emp1 t2 on t1.id = t2.id left join

src/test/regress/sql/join.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2600,6 +2600,14 @@ select * from emp1 t1 left join
26002600
on true)
26012601
on true;
26022602

2603+
-- Check that SJE removes the whole PHVs correctly
2604+
explain (verbose, costs off)
2605+
select 1 from emp1 t1 left join
2606+
((select 1 as x, * from emp1 t2) s1 inner join
2607+
(select * from emp1 t3) s2 on s1.id = s2.id)
2608+
on true
2609+
where s1.x = 1;
2610+
26032611
-- Check that PHVs do not impose any constraints on removing self joins
26042612
explain (verbose, costs off)
26052613
select * from emp1 t1 join emp1 t2 on t1.id = t2.id left join

0 commit comments

Comments
 (0)