diff options
-rw-r--r-- | src/backend/parser/parse_agg.c | 11 | ||||
-rw-r--r-- | src/test/regress/expected/aggregates.out | 20 | ||||
-rw-r--r-- | src/test/regress/sql/aggregates.sql | 9 |
3 files changed, 36 insertions, 4 deletions
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); diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index 8c4f8ce27ed..6b6371c3e74 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -2151,8 +2151,8 @@ explain (costs off) select * from v_pagg_test order by y; -> Parallel Seq Scan on pagg_test (13 rows) -set max_parallel_workers_per_gather = 0; -- Ensure results are the same without parallel aggregation. +set max_parallel_workers_per_gather = 0; select * from v_pagg_test order by y; y | tmin | tmax | tndistinct | bmin | bmax | bndistinct | amin | amax | andistinct | aamin | aamax | aandistinct ---+------+------+------------+------+------+------------+------+------+------------+-------+-------+------------- @@ -2168,6 +2168,24 @@ select * from v_pagg_test order by y; 9 | 19 | 4999 | 250 | 1019 | 999 | 250 | 19 | 4999 | 250 | 19 | 4999 | 250 (10 rows) +-- Check that we don't fail on anonymous record types. +set max_parallel_workers_per_gather = 2; +explain (costs off) +select array_dims(array_agg(s)) from (select * from pagg_test) s; + QUERY PLAN +-------------------------------------------- + Aggregate + -> Gather + Workers Planned: 2 + -> Parallel Seq Scan on pagg_test +(4 rows) + +select array_dims(array_agg(s)) from (select * from pagg_test) s; + array_dims +------------ + [1:5000] +(1 row) + -- Clean up reset max_parallel_workers_per_gather; reset bytea_output; diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql index a1dc94bff57..2c47a462b7e 100644 --- a/src/test/regress/sql/aggregates.sql +++ b/src/test/regress/sql/aggregates.sql @@ -852,11 +852,16 @@ select * from v_pagg_test order by y; -- Ensure parallel aggregation is actually being used. explain (costs off) select * from v_pagg_test order by y; -set max_parallel_workers_per_gather = 0; - -- Ensure results are the same without parallel aggregation. +set max_parallel_workers_per_gather = 0; select * from v_pagg_test order by y; +-- Check that we don't fail on anonymous record types. +set max_parallel_workers_per_gather = 2; +explain (costs off) +select array_dims(array_agg(s)) from (select * from pagg_test) s; +select array_dims(array_agg(s)) from (select * from pagg_test) s; + -- Clean up reset max_parallel_workers_per_gather; reset bytea_output; |