]> granicus.if.org Git - postgresql/commitdiff
Fix incorrect handling of polymorphic aggregates used as window functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 9 Oct 2016 16:49:37 +0000 (12:49 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 9 Oct 2016 16:49:37 +0000 (12:49 -0400)
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
src/test/regress/expected/polymorphism.out
src/test/regress/sql/polymorphism.sql

index 371548ceb39079af2a082b78bd33fa8b6b6edea3..96c8527eb321084592412bc2d66abdfc28060a98 100644 (file)
@@ -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,
index ddf45cf59734d8b5a1ee08d1c97bcd01a78106a3..68b88d33a16b2a909f7476972a1549598e22d572 100644 (file)
@@ -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;
index 72f6cb5e7cb16a4c162e6e38b9126fc17647bd9f..45ae7a23aa7e1b9a126c42ec32e445e861b5c2d6 100644 (file)
@@ -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;