aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/parser/parse_agg.c11
-rw-r--r--src/test/regress/expected/aggregates.out20
-rw-r--r--src/test/regress/sql/aggregates.sql9
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;