pg.ddx.io pgsql-bugs@postgresql.org mailing list archive
help / color / mirror / Atom feedBUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
8+ messages / 5 participants
[nested] [flat]
Commits from this thread:
2024-01-15 fe093994db Fix 'negative bitmapset member' error
* BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2023-12-27 09:33 PG Bug reporting form <noreply@postgresql.org>
0 siblings, 2 replies; 8+ messages in thread
From: PG Bug reporting form @ 2023-12-27 09:33 UTC (permalink / raw)
To: pgsql-bugs@lists.postgresql.org; +Cc: zuming.jiang@inf.ethz.ch
The following bug has been logged on the website:
Bug reference: 18260
Logged by: Zuming Jiang
Email address: zuming.jiang@inf.ethz.ch
PostgreSQL version: 16.1
Operating system: Ubuntu 20.04
Description:
My fuzzer finds a bug in Postgres 17devel, which triggers an unexpected
error "ERROR: negative bitmapset member not allowed".
--- Set up database ---
create table t0 (vkey int4, c1 numeric);
create table t1 (vkey int4, c9 text, primary key(vkey));
create view t3 as
select
ref_3.c1 as c_0,
ref_3.c1 as c_2,
null::int4 as c_4,
right(ref_2.c9, ref_2.vkey) as c_6
from
((select ref_0.vkey as c_2 from t1 as ref_0) as subq_0
left outer join (t1 as ref_2
right outer join t0 as ref_3
on (ref_2.vkey = ref_3.vkey))
on (subq_0.c_2 = ref_3.vkey));
The fuzzer generates a test case:
--- Test case ---
with cte_1 as (select
ref_1.c_0 as c_2,
ref_1.c_4 as c_3,
case when (nullif(ref_1.c_2, ref_1.c_0) <> (
select
ref_53.c_2 as c_0
from
(t1 as ref_52 left outer join t3 as ref_53 on true)
where (ref_53.c_6) ~~ (ref_53.c_6)
order by c_0 limit 1)
) then null else null end
as c_4
from
t3 as ref_1)
select 1
from
cte_1 as ref_33
where (ref_33.c_2 > (
select
ref_200.c_2 as c_0
from
t3 as ref_200
window w0 as (partition by ref_33.c_3 order by ref_33.c_4 desc)
order by c_0 limit 1));
--- Expected behavior ---
The test case should not trigger any error.
--- Actual behavior ---
The test case trigger an error:
ERROR: negative bitmapset member not allowed
--- Postgres version ---
Github commit: 0eac3c798c2d223d6557a5440d7534317dbd4fa0
Version: PostgreSQL 17devel on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu
9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit
--- Platform information ---
Platform: Ubuntu 20.04
Kernel: Linux 5.4.0-147-generic
^ permalink raw reply [nested|flat] 8+ messages in thread
* Re: BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2023-12-27 10:31 Zu-Ming Jiang <zuming.jiang@inf.ethz.ch>
parent: PG Bug reporting form <noreply@postgresql.org>
1 sibling, 0 replies; 8+ messages in thread
From: Zu-Ming Jiang @ 2023-12-27 10:31 UTC (permalink / raw)
To: pgsql-bugs@lists.postgresql.org
When I removed "window w0 as (partition by ref_33.c_3 order by
ref_33.c_4 desc)" in the test case query, the query did not trigger
errors any more.
Specifically, this query did not trigger errors:
with cte_1 as (select
ref_1.c_0 as c_2,
ref_1.c_4 as c_3,
case when (nullif(ref_1.c_2, ref_1.c_0) <> (
select
ref_53.c_2 as c_0
from
(t1 as ref_52 left outer join t3 as ref_53 on true)
where (ref_53.c_6) ~~ (ref_53.c_6)
order by c_0 limit 1)
) then null else null end
as c_4
from
t3 as ref_1)
select 1
from
cte_1 as ref_33
where (ref_33.c_2 > (
select
ref_200.c_2 as c_0
from
t3 as ref_200
order by c_0 limit 1));
^ permalink raw reply [nested|flat] 8+ messages in thread
* Re: BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2023-12-27 12:15 Richard Guo <guofenglinux@gmail.com>
parent: PG Bug reporting form <noreply@postgresql.org>
1 sibling, 1 reply; 8+ messages in thread
From: Richard Guo @ 2023-12-27 12:15 UTC (permalink / raw)
To: zuming.jiang@inf.ethz.ch; pgsql-bugs@lists.postgresql.org
On Wed, Dec 27, 2023 at 6:18 PM PG Bug reporting form <
noreply@postgresql.org> wrote:
> My fuzzer finds a bug in Postgres 17devel, which triggers an unexpected
> error "ERROR: negative bitmapset member not allowed".
Thank you for the report. This issue is caused by the way SJE removes
PHVs. I have run out of time today, but I will look into it tomorrow.
Thanks
Richard
^ permalink raw reply [nested|flat] 8+ messages in thread
* Re: BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2023-12-28 03:03 Richard Guo <guofenglinux@gmail.com>
parent: Richard Guo <guofenglinux@gmail.com>
0 siblings, 1 reply; 8+ messages in thread
From: Richard Guo @ 2023-12-28 03:03 UTC (permalink / raw)
To: zuming.jiang@inf.ethz.ch; pgsql-bugs@lists.postgresql.org
On Wed, Dec 27, 2023 at 8:15 PM Richard Guo <guofenglinux@gmail.com> wrote:
> On Wed, Dec 27, 2023 at 6:18 PM PG Bug reporting form <
> noreply@postgresql.org> wrote:
>
>> My fuzzer finds a bug in Postgres 17devel, which triggers an unexpected
>> error "ERROR: negative bitmapset member not allowed".
>
>
> Thank you for the report. This issue is caused by the way SJE removes
> PHVs. I have run out of time today, but I will look into it tomorrow.
>
I've looked into it further. 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 added a check in 9a2dbc614 for
that:
!bms_is_member(ojrelid, phinfo->ph_eval_at)
During that time, join removal was only performed for left joins, so it
was not possible for 'ojrelid' to be negative. However, with the
introduction of the SJE feature, inner joins can also be removed, and
'ojrelid' is set to -1 in the inner join case. That's how we see this
error.
A straightforward way to fix this error is to skip checking ojrelid for
inner joins:
inline patch 1: src/backend/optimizer/plan/analyzejoins.c (+0/-0 lines) download inline-1.patch
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -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)))
Alternatively, we can modify bms_is_member() to return false for
negative numbers instead of emitting an error, as suggested by the
comment there.
inline patch 2: src/backend/nodes/bitmapset.c (+2/-2 lines) download inline-2.patch
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -477,9 +477,9 @@ bms_is_member(int x, const Bitmapset *a)
int wordnum,
bitnum;
- /* XXX better to just return false for x<0 ? */
+ /* negative number cannot be a member of the bitmapset */
if (x < 0)
- elog(ERROR, "negative bitmapset member not allowed");
+ return false;
I prefer the second option, but I'm open to other thoughts.
Attached is a patch for the second option.
FWIW, here is a simplified repro for this error.
create table t (a int primary key, b int);
explain (verbose, costs off)
select 1 from t t1 left join
(lateral (select 1 as x, * from t t2) s1 inner join
(select * from t t3) s2 on s1.a = s2.a)
on true
where s1.x = 1;
ERROR: negative bitmapset member not allowed
Thanks
Richard
Patches and attachments: download all (3 files, .tar.gz)
v1-0001-Fix-negative-bitmapset-member-error.patch (application/octet-stream, 3.3K) download
From 5429590c0a058bc681b450b0130ecb1f848fb740 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Thu, 28 Dec 2023 10:56:17 +0800
Subject: [PATCH v1] 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 an useless inner join, 'ojrelid' is
set to -1, which would trigger the "negative bitmapset member not
allowed" error in bms_is_member().
We can fix it by skipping checking ojrelid for inner joins. But this
patch chooses to modify bms_is_member() to return false for negative
numbers instead of emitting an error.
---
src/backend/nodes/bitmapset.c | 4 ++--
src/test/regress/expected/join.out | 20 ++++++++++++++++++++
src/test/regress/sql/join.sql | 8 ++++++++
3 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index e13ecaa155..2a828ce709 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -477,9 +477,9 @@ bms_is_member(int x, const Bitmapset *a)
int wordnum,
bitnum;
- /* XXX better to just return false for x<0 ? */
+ /* negative number cannot be a member of the bitmapset */
if (x < 0)
- elog(ERROR, "negative bitmapset member not allowed");
+ return false;
if (a == NULL)
return false;
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 1557e17299..dc5d11317f 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -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
+ (lateral (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
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index fed9e83e31..e2ec5c1c12 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -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
+ (lateral (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
--
2.31.0
^ permalink raw reply [nested|flat] 8+ messages in thread
* Re: BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2023-12-28 04:30 Andrei Lepikhov <a.lepikhov@postgrespro.ru>
parent: Richard Guo <guofenglinux@gmail.com>
0 siblings, 1 reply; 8+ messages in thread
From: Andrei Lepikhov @ 2023-12-28 04:30 UTC (permalink / raw)
To: Richard Guo <guofenglinux@gmail.com>; zuming.jiang@inf.ethz.ch; pgsql-bugs@lists.postgresql.org
On 28/12/2023 10:03, Richard Guo wrote:
> During that time, join removal was only performed for left joins, so it
> was not possible for 'ojrelid' to be negative. However, with the
> introduction of the SJE feature, inner joins can also be removed, and
> 'ojrelid' is set to -1 in the inner join case. That's how we see this
> error.
Agreed, I have come to the same conclusion.
> 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)))
It would be better to check "ojrelid >= 0" as a sign. But why do you
think SJE could need to delete PlaceHolderVar at all?
>
> Alternatively, we can modify bms_is_member() to return false for
> negative numbers instead of emitting an error, as suggested by the
> comment there.
> - /* XXX better to just return false for x<0 ? */
> + /* negative number cannot be a member of the bitmapset */
> if (x < 0)
> - elog(ERROR, "negative bitmapset member not allowed");
> + return false;
>
> I prefer the second option, but I'm open to other thoughts.
I don't like this option. It could mask some blunders somewhere like a
current one.
> FWIW, here is a simplified repro for this error.
>
> create table t (a int primary key, b int);
>
> explain (verbose, costs off)
> select 1 from t t1 left join
> (lateral (select 1 as x, * from t t2) s1 inner join
> (select * from t t3) s2 on s1.a = s2.a)
> on true
> where s1.x = 1;
> ERROR: negative bitmapset member not allowed
It can be simplified even more (without LATERAL):
explain (verbose, costs off)
select 1 from t t1 left join
(select 1 as x, * from t t2) s1 inner join
(select * from t t3) using (a)
on true
where s1.x = 1;
--
regards,
Andrei Lepikhov
Postgres Professional
^ permalink raw reply [nested|flat] 8+ messages in thread
* Re: BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2024-01-11 09:08 Richard Guo <guofenglinux@gmail.com>
parent: Andrei Lepikhov <a.lepikhov@postgrespro.ru>
0 siblings, 1 reply; 8+ messages in thread
From: Richard Guo @ 2024-01-11 09:08 UTC (permalink / raw)
To: Andrei Lepikhov <a.lepikhov@postgrespro.ru>; +Cc: zuming.jiang@inf.ethz.ch; pgsql-bugs@lists.postgresql.org
On Thu, Dec 28, 2023 at 12:30 PM Andrei Lepikhov <a.lepikhov@postgrespro.ru>
wrote:
> On 28/12/2023 10:03, Richard Guo wrote:
> > 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)))
>
> > Alternatively, we can modify bms_is_member() to return false for
> > negative numbers instead of emitting an error, as suggested by the
> > comment there.
> > - /* XXX better to just return false for x<0 ? */
> > + /* negative number cannot be a member of the bitmapset */
> > if (x < 0)
> > - elog(ERROR, "negative bitmapset member not allowed");
> > + return false;
> >
> > I prefer the second option, but I'm open to other thoughts.
> I don't like this option. It could mask some blunders somewhere like a
> current one.
After a second thought, I agree that the first option is better. It
maintains consistency with the Assert a few lines ahead, and also
minimizes the potential impact of code changes compared to the second
option.
> > FWIW, here is a simplified repro for this error.
> >
> > create table t (a int primary key, b int);
> >
> > explain (verbose, costs off)
> > select 1 from t t1 left join
> > (lateral (select 1 as x, * from t t2) s1 inner join
> > (select * from t t3) s2 on s1.a = s2.a)
> > on true
> > where s1.x = 1;
> > ERROR: negative bitmapset member not allowed
> It can be simplified even more (without LATERAL):
Indeed. I realized this shortly after v1 patch was sent out, and was
thinking that it wasn't worth the effort to update the patch with a new
version just for this issue.
Thanks
Richard
Attachments:
v2-0001-Fix-negative-bitmapset-member-error.patch (application/octet-stream, 3.4K) download
From 6b575ca1d6cc8025134579c8032faaf3d10f2964 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Thu, 28 Dec 2023 10:56:17 +0800
Subject: [PATCH v2] 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 an 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.
---
src/backend/optimizer/plan/analyzejoins.c | 2 +-
src/test/regress/expected/join.out | 20 ++++++++++++++++++++
src/test/regress/sql/join.sql | 8 ++++++++
3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c
index 8a2ccbb604..7dcb74572a 100644
--- a/src/backend/optimizer/plan/analyzejoins.c
+++ b/src/backend/optimizer/plan/analyzejoins.c
@@ -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);
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 321b6a7147..08ad748f7c 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -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
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index 6d066ef952..385d581fd2 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -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
--
2.31.0
^ permalink raw reply [nested|flat] 8+ messages in thread
* Re: BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2024-01-15 00:20 Andrei Lepikhov <a.lepikhov@postgrespro.ru>
parent: Richard Guo <guofenglinux@gmail.com>
0 siblings, 1 reply; 8+ messages in thread
From: Andrei Lepikhov @ 2024-01-15 00:20 UTC (permalink / raw)
To: Richard Guo <guofenglinux@gmail.com>; Alexander Korotkov <aekorotkov@gmail.com>; +Cc: zuming.jiang@inf.ethz.ch; pgsql-bugs@lists.postgresql.org
On 11/1/2024 16:08, Richard Guo wrote:
>
> On Thu, Dec 28, 2023 at 12:30 PM Andrei Lepikhov
> <a.lepikhov@postgrespro.ru <mailto:a.lepikhov@postgrespro.ru>> wrote:
>
> On 28/12/2023 10:03, Richard Guo wrote:
> > 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)))
>
> > Alternatively, we can modify bms_is_member() to return false for
> > negative numbers instead of emitting an error, as suggested by the
> > comment there.
> > - /* XXX better to just return false for x<0 ? */
> > + /* negative number cannot be a member of the bitmapset */
> > if (x < 0)
> > - elog(ERROR, "negative bitmapset member not allowed");
> > + return false;
> >
> > I prefer the second option, but I'm open to other thoughts.
> I don't like this option. It could mask some blunders somewhere like a
> current one.
>
>
> After a second thought, I agree that the first option is better. It
> maintains consistency with the Assert a few lines ahead, and also
> minimizes the potential impact of code changes compared to the second
> option.
>
> > FWIW, here is a simplified repro for this error.
> >
> > create table t (a int primary key, b int);
> >
> > explain (verbose, costs off)
> > select 1 from t t1 left join
> > (lateral (select 1 as x, * from t t2) s1 inner join
> > (select * from t t3) s2 on s1.a = s2.a)
> > on true
> > where s1.x = 1;
> > ERROR: negative bitmapset member not allowed
> It can be simplified even more (without LATERAL):
>
>
> Indeed. I realized this shortly after v1 patch was sent out, and was
> thinking that it wasn't worth the effort to update the patch with a new
> version just for this issue.
I like it, thanks for your efforts.
--
regards,
Andrei Lepikhov
Postgres Professional
^ permalink raw reply [nested|flat] 8+ messages in thread
* Re: BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN
@ 2024-01-15 00:34 Alexander Korotkov <aekorotkov@gmail.com>
parent: Andrei Lepikhov <a.lepikhov@postgrespro.ru>
0 siblings, 0 replies; 8+ messages in thread
From: Alexander Korotkov @ 2024-01-15 00:34 UTC (permalink / raw)
To: Andrei Lepikhov <a.lepikhov@postgrespro.ru>; +Cc: Richard Guo <guofenglinux@gmail.com>; zuming.jiang@inf.ethz.ch; pgsql-bugs@lists.postgresql.org
On Mon, Jan 15, 2024 at 2:20 AM Andrei Lepikhov
<a.lepikhov@postgrespro.ru> wrote:
> On 11/1/2024 16:08, Richard Guo wrote:
> >
> > On Thu, Dec 28, 2023 at 12:30 PM Andrei Lepikhov
> > <a.lepikhov@postgrespro.ru <mailto:a.lepikhov@postgrespro.ru>> wrote:
> >
> > On 28/12/2023 10:03, Richard Guo wrote:
> > > 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)))
> >
> > > Alternatively, we can modify bms_is_member() to return false for
> > > negative numbers instead of emitting an error, as suggested by the
> > > comment there.
> > > - /* XXX better to just return false for x<0 ? */
> > > + /* negative number cannot be a member of the bitmapset */
> > > if (x < 0)
> > > - elog(ERROR, "negative bitmapset member not allowed");
> > > + return false;
> > >
> > > I prefer the second option, but I'm open to other thoughts.
> > I don't like this option. It could mask some blunders somewhere like a
> > current one.
> >
> >
> > After a second thought, I agree that the first option is better. It
> > maintains consistency with the Assert a few lines ahead, and also
> > minimizes the potential impact of code changes compared to the second
> > option.
> >
> > > FWIW, here is a simplified repro for this error.
> > >
> > > create table t (a int primary key, b int);
> > >
> > > explain (verbose, costs off)
> > > select 1 from t t1 left join
> > > (lateral (select 1 as x, * from t t2) s1 inner join
> > > (select * from t t3) s2 on s1.a = s2.a)
> > > on true
> > > where s1.x = 1;
> > > ERROR: negative bitmapset member not allowed
> > It can be simplified even more (without LATERAL):
> >
> >
> > Indeed. I realized this shortly after v1 patch was sent out, and was
> > thinking that it wasn't worth the effort to update the patch with a new
> > version just for this issue.
> I like it, thanks for your efforts.
+1,
Thank you, Richard, Andrei. I'm going to push this tomorrow.
------
Regards,
Alexander Korotkov
^ permalink raw reply [nested|flat] 8+ messages in thread
end of thread, other threads:[~2024-01-15 00:34 UTC | newest]
Thread overview: 8+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2023-12-27 09:33 BUG #18260: Unexpected error: "negative bitmapset member not allowed" triggered by multiple JOIN PG Bug reporting form <noreply@postgresql.org>
2023-12-27 10:31 ` Zu-Ming Jiang <zuming.jiang@inf.ethz.ch>
2023-12-27 12:15 ` Richard Guo <guofenglinux@gmail.com>
2023-12-28 03:03 ` Richard Guo <guofenglinux@gmail.com>
2023-12-28 04:30 ` Andrei Lepikhov <a.lepikhov@postgrespro.ru>
2024-01-11 09:08 ` Richard Guo <guofenglinux@gmail.com>
2024-01-15 00:20 ` Andrei Lepikhov <a.lepikhov@postgrespro.ru>
2024-01-15 00:34 ` Alexander Korotkov <aekorotkov@gmail.com>
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox