mirror of
https://github.com/postgres/postgres.git
synced 2025-05-21 15:54:08 +03:00
Don't try to parallelize array_agg() on an anonymous record type.
This doesn't work because record_recv requires the typmod that identifies the specific record type (in our session) and array_agg_deserialize has no convenient way to get that information. The result is an "input of anonymous composite types is not implemented" error. We could probably make this work if we had to, but it does not seem worth the trouble, given that it took this long to get a field report. Just shut off parallelization, as though record_recv didn't exist. Oversight in commit 16fd03e95. Back-patch to v16 where that came in. Reported-by: Kirill Zdornyy <kirill@dineserve.com> Diagnosed-by: Richard Guo <guofenglinux@gmail.com> Author: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: David Rowley <dgrowleyml@gmail.com> Discussion: https://postgr.es/m/atLI5Kce2ie1zcYjU0w_kjtVaxiYbYGTihrkLDmGZQnRDD4pnXukIATaABbnIj9pUnelC4ESvCXMm4HAyHg-v61XABaKpERj0A2IXzJZM7g=@dineserve.com Backpatch-through: 16
This commit is contained in:
parent
99c01aadf9
commit
43847dd5e9
@ -1961,7 +1961,7 @@ resolve_aggregate_transtype(Oid aggfuncid,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* agg_args_support_sendreceive
|
* 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.
|
* receive functions.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@ -1976,6 +1976,15 @@ agg_args_support_sendreceive(Aggref *aggref)
|
|||||||
TargetEntry *tle = (TargetEntry *) lfirst(lc);
|
TargetEntry *tle = (TargetEntry *) lfirst(lc);
|
||||||
Oid type = exprType((Node *) tle->expr);
|
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));
|
typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
|
||||||
if (!HeapTupleIsValid(typeTuple))
|
if (!HeapTupleIsValid(typeTuple))
|
||||||
elog(ERROR, "cache lookup failed for type %u", type);
|
elog(ERROR, "cache lookup failed for type %u", type);
|
||||||
|
@ -2033,8 +2033,8 @@ explain (costs off) select * from v_pagg_test order by y;
|
|||||||
-> Parallel Seq Scan on pagg_test
|
-> Parallel Seq Scan on pagg_test
|
||||||
(13 rows)
|
(13 rows)
|
||||||
|
|
||||||
set max_parallel_workers_per_gather = 0;
|
|
||||||
-- Ensure results are the same without parallel aggregation.
|
-- Ensure results are the same without parallel aggregation.
|
||||||
|
set max_parallel_workers_per_gather = 0;
|
||||||
select * from v_pagg_test order by y;
|
select * from v_pagg_test order by y;
|
||||||
y | tmin | tmax | tndistinct | bmin | bmax | bndistinct | amin | amax | andistinct | aamin | aamax | aandistinct
|
y | tmin | tmax | tndistinct | bmin | bmax | bndistinct | amin | amax | andistinct | aamin | aamax | aandistinct
|
||||||
---+------+------+------------+------+------+------------+------+------+------------+-------+-------+-------------
|
---+------+------+------------+------+------+------------+------+------+------------+-------+-------+-------------
|
||||||
@ -2050,6 +2050,24 @@ select * from v_pagg_test order by y;
|
|||||||
9 | 19 | 4999 | 250 | 1019 | 999 | 250 | 19 | 4999 | 250 | 19 | 4999 | 250
|
9 | 19 | 4999 | 250 | 1019 | 999 | 250 | 19 | 4999 | 250 | 19 | 4999 | 250
|
||||||
(10 rows)
|
(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
|
-- Clean up
|
||||||
reset max_parallel_workers_per_gather;
|
reset max_parallel_workers_per_gather;
|
||||||
reset bytea_output;
|
reset bytea_output;
|
||||||
|
@ -805,11 +805,16 @@ select * from v_pagg_test order by y;
|
|||||||
-- Ensure parallel aggregation is actually being used.
|
-- Ensure parallel aggregation is actually being used.
|
||||||
explain (costs off) select * from v_pagg_test order by y;
|
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.
|
-- Ensure results are the same without parallel aggregation.
|
||||||
|
set max_parallel_workers_per_gather = 0;
|
||||||
select * from v_pagg_test order by y;
|
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
|
-- Clean up
|
||||||
reset max_parallel_workers_per_gather;
|
reset max_parallel_workers_per_gather;
|
||||||
reset bytea_output;
|
reset bytea_output;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user