Re: BUG #19106: Potential regression with CTE materialization planning in Postgres 18

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Vik Fearing <vik(at)postgresfriends(dot)org>, Kamil Monicz <kamil(at)monicz(dot)dev>, pgsql-bugs(at)lists(dot)postgresql(dot)org, Peter Eisentraut <peter(at)eisentraut(dot)org>
Subject: Re: BUG #19106: Potential regression with CTE materialization planning in Postgres 18
Date: 2025-11-12 07:04:05
Message-ID: CAMbWs48G6Fk+5YOhz-4u0+R1+sQZhC_bVTZBY7cqbG6wFWcKDA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Wed, Nov 12, 2025 at 5:28 AM Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Thanks for doing that research. It's not at all surprising if back
> in the early 90's nobody had tried to make it work for sub-selects
> (or at least had not succeeded), so they just wrote the spec to not
> require it.

I played with this patch, but I couldn't quite wrap my head around the
expected behavior of using subqueries as arguments to aggregate
functions. The outputs of the following queries are confusing to me.

create table t (a int);
insert into t values (1), (2);

Query 1:
select (select sum((select a from t t1 limit 1))) from t t2;
sum
-----
1
1
(2 rows)

As I understand it, a query of the form:

SELECT <scalar_expression> FROM table;

... produces one output row for each row in the table, with the value
of <scalar_expression> evaluated for that row. Thus, the output of
Query 1 makes sense to me.

Query 2:
select (select sum((select a from t t1 where a = t2.a or true limit
1))) from t t2;
sum
-----
2
(1 row)

I don't quite understand the output of Query 2. The subquery is now
correlated with the outer table t2, but I believe it's still in the
same form as Query 1, so I would expect it to also produce one output
row per table row. Moreover, IIUC, the "or true" clause should make
the two queries semantically equivalent.

Query 3:
with t as (select a from (values (1), (2)) as v(a))
select (select sum((select a from t t1 where a = t2.a or true limit
1))) from t t2;
sum
-----
1
1
(2 rows)

Query 3 replaces the physical table with a CTE that produces the same
logical table content, so I would expect the query's output to remain
unchanged. So the differing outputs of Query 2 and Query 3 are also
confusing to me.

- Richard

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Daniel Gustafsson 2025-11-12 08:13:09 Re: BUG #19095: Test if function exit() is used fail when linked static
Previous Message Tom Lane 2025-11-12 06:38:47 Re: BUG #19095: Test if function exit() is used fail when linked static