Re: BUG #18877: PostgreSQL triggers assertion failure - Mailing list pgsql-bugs

From Tender Wang
Subject Re: BUG #18877: PostgreSQL triggers assertion failure
Date
Msg-id CAHewXN=NHxdEE2BVFOzNdN=DBW7dBm3geLyA1bwCd1Eq-1xf0w@mail.gmail.com
Whole thread Raw
In response to Re: BUG #18877: PostgreSQL triggers assertion failure  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-bugs


Tom Lane <tgl@sss.pgh.pa.us> 于2025年4月5日周六 11:54写道:
PG Bug reporting form <noreply@postgresql.org> writes:
> In the debug build of PostgreSQL 17.4, compiled with `configure
> --enable-debug --prefix=$(pwd) --exec-prefix=$(pwd) --enable-cassert`,
> triggered Assertion Failure when executing the following statement:

> ```sql
> SELECT ALL GROUP BY ALL ( ), CUBE ( CASE WHEN FALSE THEN TRUE END )
> INTERSECT ALL SELECT ALL FROM JSON_ARRAY ( WITH any_cte_name AS ( ( TABLE
> v00 ) ) VALUES ( FALSE ) ), any_table_name GROUP BY CUBE ( CASE WHEN TRUE
> THEN FALSE END );
> ```

Minimized a bit, that's

regression=# SELECT 1 FROM JSON_ARRAY ( WITH any_cte_name AS ( ( select 1 ) ) VALUES ( FALSE ) );
server closed the connection unexpectedly

This is another case of "don't let the parser process the same
querytree twice".  I can make it go away with

Yes, indeed.
 

diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 9caf1e481a2..bc602f00ae3 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -3772,7 +3772,7 @@ transformJsonArrayQueryConstructor(ParseState *pstate,
        /* Transform query only for counting target list entries. */
        qpstate = make_parsestate(pstate);

-       query = transformStmt(qpstate, ctor->query);
+       query = transformStmt(qpstate, copyObject(ctor->query));

        if (count_nonjunk_tlist_entries(query->targetList) != 1)
                ereport(ERROR,

However ... it's possible that this isn't the stupidest, most
brute-force code in Postgres, but I'll wager it's in the top ten.
Is it really necessary to transform the subquery twice just to
produce this error?  It seems like the constructed EXPR_SUBLINK
should produce the same error all by itself.  I tried nuking this
whole stanza to see whether that would happen, and then there are a
couple of regression test cases that don't produce the same results.
But I feel like it could be made to work with a bit more thought.

If we use the constructed EXPR_SUBLINK, the following query
SELECT JSON_ARRAY(SELECT i, i FROM (VALUES (1)) foo(I));
will not produce the same results.

If we want to get the same error "subquery must return only one column",
the ResTarget of EXPR_SUBLINK should not be "a". But if not using "a",
we should create a new TargetEntry to replace the targetList of the transformed sublink's subselect.


--
Thanks, Tender Wang

pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #18877: PostgreSQL triggers assertion failure
Next
From: Alvaro Herrera
Date:
Subject: Re: BUG #18877: PostgreSQL triggers assertion failure