pg.ddx.io pgsql-bugs@postgresql.org mailing list archive
help / color / mirror / Atom feedError from array_agg when table has many rows
5+ messages / 4 participants
[nested] [flat]
Commits from this thread:
2025-03-09 fedfcf6650 43847dd5e9 a7aa9f21f2 Don't try to parallelize array_agg() on an anonymous record type.
* Error from array_agg when table has many rows
@ 2025-03-07 20:07 Kirill Zdornyy <kirill@dineserve.com>
0 siblings, 1 reply; 5+ messages in thread
From: Kirill Zdornyy @ 2025-03-07 20:07 UTC (permalink / raw)
To: pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
Hello,
After upgrading from PostgreSQL 12.19 to PostgreSQL 16.3 the function "array_agg" gives me the following error under certain conditions.
ERROR: input of anonymous composite types is not implemented
I was also able reproduce the issue on PostgreSQL 17.4 via the latest currently available Docker image.
Please see the following SQL script for the minimum reproduction.
```
drop table if exists my_table;
create table my_table
(
my_text text
);
-- Insert a minimum of 200,000 rows.
do
$$
declare
counter integer := 0;
begin
while counter < 200000
loop
INSERT INTO my_table (my_text) VALUES ('A simple sentence.');
counter := counter + 1;
end loop;
end;
$$;
select array_agg(t)
from (select my_text from my_table WHERE my_text != '') t;
```
On my machine the issue appears if 200,000 or more rows exist. I used EXPLAIN and noticed that the query plan is different if this condition is met.
This is the query plan if fewer than 200,000 rows exist.
```
Aggregate (cost=1935.40..1935.41 rows=1 width=32)
-> Seq Scan on my_table (cost=0.00..1719.90 rows=86199 width=32)
Filter: (my_text <> ''::text)
```
This is the query plan if more than 200,000 rows exist.
```
Finalize Aggregate (cost=3801.65..3801.66 rows=1 width=32)
-> Gather (cost=3801.53..3801.64 rows=1 width=32)
Workers Planned: 1
-> Partial Aggregate (cost=2801.53..2801.54 rows=1 width=32)
-> Parallel Seq Scan on my_table (cost=0.00..2548.00 rows=101411 width=32)
Filter: (my_text <> ''::text)
```
I am also able to reproduce the issue on AWS RDS PostgreSQL 16.3.
Thank you!
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: Error from array_agg when table has many rows
@ 2025-03-08 09:38 Richard Guo <guofenglinux@gmail.com>
parent: Kirill Zdornyy <kirill@dineserve.com>
0 siblings, 1 reply; 5+ messages in thread
From: Richard Guo @ 2025-03-08 09:38 UTC (permalink / raw)
To: Kirill Zdornyy <kirill@dineserve.com>; +Cc: pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
On Sat, Mar 8, 2025 at 8:10 AM Kirill Zdornyy <kirill@dineserve.com> wrote:
> After upgrading from PostgreSQL 12.19 to PostgreSQL 16.3 the function "array_agg" gives me the following error under certain conditions.
>
> ERROR: input of anonymous composite types is not implemented
>
> I was also able reproduce the issue on PostgreSQL 17.4 via the latest currently available Docker image.
Thanks for the report! I can reproduce it on master with the query
below.
create table t (a int);
insert into t values (1);
set parallel_setup_cost=0;
set parallel_tuple_cost=0;
set min_parallel_table_scan_size=0;
# select array_agg(s) from (select * from t) s;
ERROR: input of anonymous composite types is not implemented
And the plan for this query is:
explain (verbose, costs off)
select array_agg(s) from (select * from t) s;
QUERY PLAN
---------------------------------------------------
Finalize Aggregate
Output: array_agg(ROW(t.a))
-> Gather
Output: (PARTIAL array_agg(ROW(t.a)))
Workers Planned: 2
-> Partial Aggregate
Output: PARTIAL array_agg(ROW(t.a))
-> Parallel Seq Scan on public.t
Output: t.a
(9 rows)
We are performing deserialization during the final phase of the
aggregation on data of type RECORD but we fail to provide a valid
typmod (array_agg_deserialize() uses -1 as the typmod when calling the
receiveproc).
I haven't verified it, but I suspect it's related to 16fd03e95.
Thanks
Richard
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: Error from array_agg when table has many rows
@ 2025-03-08 15:50 Tom Lane <tgl@sss.pgh.pa.us>
parent: Richard Guo <guofenglinux@gmail.com>
0 siblings, 1 reply; 5+ messages in thread
From: Tom Lane @ 2025-03-08 15:50 UTC (permalink / raw)
To: Richard Guo <guofenglinux@gmail.com>; +Cc: David Rowley <dgrowleyml@gmail.com>; Kirill Zdornyy <kirill@dineserve.com>; pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
Richard Guo <guofenglinux@gmail.com> writes:
> We are performing deserialization during the final phase of the
> aggregation on data of type RECORD but we fail to provide a valid
> typmod (array_agg_deserialize() uses -1 as the typmod when calling the
> receiveproc).
> I haven't verified it, but I suspect it's related to 16fd03e95.
Yeah. I don't think there is any way for array_agg_deserialize to
know the correct typmod, so what we have to do is disable using
partial aggregation in this case. Fortunately there's a
policy-setting function that can be taught that, as attached.
regards, tom lane
Attachments:
disable_partial_aggregation_on_RECORD.patch (text/x-diff, 1.1K) download
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 9e567f3cc45..0ac8966e30f 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -2052,7 +2052,7 @@ resolve_aggregate_transtype(Oid aggfuncid,
/*
* agg_args_support_sendreceive
- * Returns true if all non-byval of aggref's arg types have send and
+ * Returns true if all non-byval types of aggref's args have send and
* receive functions.
*/
bool
@@ -2067,6 +2067,15 @@ agg_args_support_sendreceive(Aggref *aggref)
TargetEntry *tle = (TargetEntry *) lfirst(lc);
Oid type = exprType((Node *) tle->expr);
+ /*
+ * RECORD is a special case: it has typsend/typreceive functions, but
+ * record_recv only works if passed the correct typmod to identify the
+ * specific anonymous record type. array_agg_deserialize cannot do
+ * that, so we have to disclaim support for the case.
+ */
+ if (type == RECORDOID)
+ return false;
+
typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
if (!HeapTupleIsValid(typeTuple))
elog(ERROR, "cache lookup failed for type %u", type);
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: Error from array_agg when table has many rows
@ 2025-03-09 07:22 David Rowley <dgrowleyml@gmail.com>
parent: Tom Lane <tgl@sss.pgh.pa.us>
0 siblings, 1 reply; 5+ messages in thread
From: David Rowley @ 2025-03-09 07:22 UTC (permalink / raw)
To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: Richard Guo <guofenglinux@gmail.com>; Kirill Zdornyy <kirill@dineserve.com>; pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
On Sun, 9 Mar 2025 at 04:50, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> Richard Guo <guofenglinux@gmail.com> writes:
> > We are performing deserialization during the final phase of the
> > aggregation on data of type RECORD but we fail to provide a valid
> > typmod (array_agg_deserialize() uses -1 as the typmod when calling the
> > receiveproc).
>
> > I haven't verified it, but I suspect it's related to 16fd03e95.
>
> Yeah. I don't think there is any way for array_agg_deserialize to
> know the correct typmod, so what we have to do is disable using
> partial aggregation in this case. Fortunately there's a
> policy-setting function that can be taught that, as attached.
The only way I can think of to get that would be to special-case
array_agg_serialize() to have it serialize the typmod when the send
function is record_send(), then add a similar special-case to
array_agg_deserialize() to check for a record_recv() and deserialize
the typmod there. That doesn't seem very pretty, so I'm happy to go
with your fix to disable parallel aggregates for this case.
David
^ permalink raw reply [nested|flat] 5+ messages in thread
* Re: Error from array_agg when table has many rows
@ 2025-03-09 17:14 Tom Lane <tgl@sss.pgh.pa.us>
parent: David Rowley <dgrowleyml@gmail.com>
0 siblings, 0 replies; 5+ messages in thread
From: Tom Lane @ 2025-03-09 17:14 UTC (permalink / raw)
To: David Rowley <dgrowleyml@gmail.com>; +Cc: Richard Guo <guofenglinux@gmail.com>; Kirill Zdornyy <kirill@dineserve.com>; pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
David Rowley <dgrowleyml@gmail.com> writes:
> On Sun, 9 Mar 2025 at 04:50, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Yeah. I don't think there is any way for array_agg_deserialize to
>> know the correct typmod, so what we have to do is disable using
>> partial aggregation in this case. Fortunately there's a
>> policy-setting function that can be taught that, as attached.
> The only way I can think of to get that would be to special-case
> array_agg_serialize() to have it serialize the typmod when the send
> function is record_send(), then add a similar special-case to
> array_agg_deserialize() to check for a record_recv() and deserialize
> the typmod there. That doesn't seem very pretty, so I'm happy to go
> with your fix to disable parallel aggregates for this case.
Yeah ... we could probably make that work if we had to, but the
ugliness would likely metastasize outside array_agg_[de]serialize.
Since it took more than a year to get a field report, I'm content
to just disable the optimization instead. Pushed that way.
regards, tom lane
^ permalink raw reply [nested|flat] 5+ messages in thread
end of thread, other threads:[~2025-03-09 17:14 UTC | newest]
Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2025-03-07 20:07 Error from array_agg when table has many rows Kirill Zdornyy <kirill@dineserve.com>
2025-03-08 09:38 ` Richard Guo <guofenglinux@gmail.com>
2025-03-08 15:50 ` Tom Lane <tgl@sss.pgh.pa.us>
2025-03-09 07:22 ` David Rowley <dgrowleyml@gmail.com>
2025-03-09 17:14 ` Tom Lane <tgl@sss.pgh.pa.us>
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