diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 0ae5873868..1a1aebe7b0 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -3808,6 +3808,16 @@ find_compatible_pertrans(AggState *aggstate, Aggref *newagg, { ListCell *lc; + /* + * For the moment, never try to share transition states between different + * ordered-set aggregates. This is necessary because the finalfns of the + * built-in OSAs (see orderedsetaggs.c) are destructive of their + * transition states. We should fix them so we can allow this, but not + * losing performance in the normal non-shared case will take some work. + */ + if (AGGKIND_IS_ORDERED_SET(newagg->aggkind)) + return -1; + foreach(lc, transnos) { int transno = lfirst_int(lc); diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index ce6b841a33..82ede655aa 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -1860,6 +1860,25 @@ NOTICE: avg_transfn called with 3 2 | 6 (1 row) +-- ideally these would share state, but we have to fix the OSAs first. +select + percentile_cont(0.5) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a); + percentile_cont | percentile_disc +-----------------+----------------- + 4 | 3 +(1 row) + +select + rank(4) within group (order by a), + dense_rank(4) within group (order by a) +from (values(1),(3),(5),(7)) t(a); + rank | dense_rank +------+------------ + 3 | 3 +(1 row) + -- test that aggs with the same sfunc and initcond share the same agg state create aggregate my_sum_init(int4) ( diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql index 2eeb3eedbd..77314522eb 100644 --- a/src/test/regress/sql/aggregates.sql +++ b/src/test/regress/sql/aggregates.sql @@ -739,6 +739,17 @@ select my_avg(one) filter (where one > 1),my_sum(one) from (values(1),(3)) t(one -- this should not share the state due to different input columns. select my_avg(one),my_sum(two) from (values(1,2),(3,4)) t(one,two); +-- ideally these would share state, but we have to fix the OSAs first. +select + percentile_cont(0.5) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a); + +select + rank(4) within group (order by a), + dense_rank(4) within group (order by a) +from (values(1),(3),(5),(7)) t(a); + -- test that aggs with the same sfunc and initcond share the same agg state create aggregate my_sum_init(int4) (