Re: BUG #19752: GROUP BY on a constant and a cast to a length-limited array type crashes the server while planning

From: Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: mertkul669(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org, Richard Guo <guofenglinux(at)gmail(dot)com>
Subject: Re: BUG #19752: GROUP BY on a constant and a cast to a length-limited array type crashes the server while planning
Date: 2026-10-08 19:48:05
Message-ID: CAB8bMiuw5ytFDC9eXANQBCybdUWVX5vWYZ6hVHUZbcqo4kHsuw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

пт, 9 окт. 2026 г. в 00:32, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>:

> PG Bug reporting form <noreply(at)postgresql(dot)org> writes:
> > I found a planner crash (SIGSEGV) in PostgreSQL 18 with the following
> > query:
>
> > SELECT ARRAY[]::varchar(500)[]
> > GROUP BY CAST('true' AS boolean);
>
> > Cause
> > For ARRAY[]::varchar(500)[], the parser builds an ArrayCoerceExpr whose
> > elemexpr is a per-element template:
> > varchar(CaseTestExpr, 500, true)
> > where the final "true" is the internal isExplicit flag.
> > substitute_grouped_columns_mutator() in parse_agg.c replaces any
> > subexpression that equal()s a GROUP BY expression with a Var referencing
> > the RTE_GROUP RTE. It also descends into elemexpr. The GROUP BY
> > expression is Const(bool, true), and the internal isExplicit flag is also
> > Const(bool, true), so the flag is wrongly replaced by a Var. (Dumping
> > elemexpr at the point of failure on 18.4 shows the third argument is a
> > VAR rather than a CONST.)
>
> Yeah, that's nasty, and what's nastier is that even non-crash cases
> might result in seriously wrong answers. We shouldn't be replacing
> constant subexpressions by group Vars ever. I'm inclined to think
> that GROUP BY items should not be candidates for this
> search-and-replace unless they contain at least one level-zero Var.
> But maybe that's too simplistic?
>
> regards, tom lane
>
>
>
Hi, Tom!

If I analyzed the code correctly, the conclusions are as follows:

We should still replace the grouped constant itself. Bisect puts the
crash at f5050f795ae ("Mark expressions nullable by grouping sets"),
whose parent 247dea89f76 does not crash. 247dea89f76 returns on Const
before equal(). f5050f795ae moves that return to after equal(), and
the comment says why. A GROUP BY constant is no longer constant after
the grouping step. The regress query added in that commit is

select 1 as one group by rollup(one) order by one nulls first;

and the expected result is a null row followed by 1.

Skipping every GROUP BY item that contains no level-zero Var is too
broad. The item in that query is a Const, so it contains no Var, and
the commit exists to keep it a candidate. The constants that must not
be replaced are the other Const nodes that happen to compare equal.

--
Regards,
Rachitskiy Andrey

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tom Lane 2026-10-08 20:10:39 Re: BUG #19752: GROUP BY on a constant and a cast to a length-limited array type crashes the server while planning
Previous Message Tom Lane 2026-10-08 19:31:48 Re: BUG #19752: GROUP BY on a constant and a cast to a length-limited array type crashes the server while planning