From ac4a9d92fcb6869e757cc729dca2ca5ccf94b185 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 9 Oct 2016 12:49:37 -0400 Subject: [PATCH] Fix incorrect handling of polymorphic aggregates used as window functions. The transfunction was told that its first argument and result were of the window function output type, not the aggregate state type. This'd only matter if the transfunction consults get_fn_expr_argtype, which typically only polymorphic functions would do. Although we have several regression tests around polymorphic aggs, none of them detected this mistake --- in fact, they still didn't fail when I injected the same mistake into nodeAgg.c. So add some more tests covering both plain agg and window-function-agg cases. Per report from Sebastian Luque. Back-patch to 9.6 where the error was introduced (by sloppy refactoring in commit 804163bc2, looks like). Report: <87int2qkat.fsf@gmail.com> --- src/backend/executor/nodeWindowAgg.c | 2 +- src/test/regress/expected/polymorphism.out | 55 ++++++++++++++++++++++ src/test/regress/sql/polymorphism.sql | 22 +++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 371548ceb3..96c8527eb3 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -2218,7 +2218,7 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc, numArguments, 0, /* no ordered-set window functions yet */ false, /* no variadic window functions yet */ - wfunc->wintype, + aggtranstype, wfunc->inputcollid, transfn_oid, invtransfn_oid, diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out index ddf45cf597..68b88d33a1 100644 --- a/src/test/regress/expected/polymorphism.out +++ b/src/test/regress/expected/polymorphism.out @@ -635,6 +635,61 @@ create aggregate build_group(int8, integer) ( SFUNC = add_group, STYPE = int8[] ); +-- check proper resolution of data types for polymorphic transfn/finalfn +create function first_el(anyarray) returns anyelement as +'select $1[1]' language sql strict immutable; +create aggregate first_el_agg_f8(float8) ( + SFUNC = array_append, + STYPE = float8[], + FINALFUNC = first_el +); +create aggregate first_el_agg_any(anyelement) ( + SFUNC = array_append, + STYPE = anyarray, + FINALFUNC = first_el +); +select first_el_agg_f8(x::float8) from generate_series(1,10) x; + first_el_agg_f8 +----------------- + 1 +(1 row) + +select first_el_agg_any(x) from generate_series(1,10) x; + first_el_agg_any +------------------ + 1 +(1 row) + +select first_el_agg_f8(x::float8) over(order by x) from generate_series(1,10) x; + first_el_agg_f8 +----------------- + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +(10 rows) + +select first_el_agg_any(x) over(order by x) from generate_series(1,10) x; + first_el_agg_any +------------------ + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +(10 rows) + -- check that we can apply functions taking ANYARRAY to pg_stats select distinct array_ndims(histogram_bounds) from pg_stats where histogram_bounds is not null; diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql index 72f6cb5e7c..45ae7a23aa 100644 --- a/src/test/regress/sql/polymorphism.sql +++ b/src/test/regress/sql/polymorphism.sql @@ -443,6 +443,28 @@ create aggregate build_group(int8, integer) ( STYPE = int8[] ); +-- check proper resolution of data types for polymorphic transfn/finalfn + +create function first_el(anyarray) returns anyelement as +'select $1[1]' language sql strict immutable; + +create aggregate first_el_agg_f8(float8) ( + SFUNC = array_append, + STYPE = float8[], + FINALFUNC = first_el +); + +create aggregate first_el_agg_any(anyelement) ( + SFUNC = array_append, + STYPE = anyarray, + FINALFUNC = first_el +); + +select first_el_agg_f8(x::float8) from generate_series(1,10) x; +select first_el_agg_any(x) from generate_series(1,10) x; +select first_el_agg_f8(x::float8) over(order by x) from generate_series(1,10) x; +select first_el_agg_any(x) over(order by x) from generate_series(1,10) x; + -- check that we can apply functions taking ANYARRAY to pg_stats select distinct array_ndims(histogram_bounds) from pg_stats where histogram_bounds is not null;