From c3ddcc0b39417c0ff6e8085fb2ada73063be767a Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Fri, 7 Jun 2019 14:07:44 +0800 Subject: [PATCH 1/9] add AGGREGATES [Part 3] --- .../inputs/pgSQL/aggregates_part3.sql | 653 ++++++++++++++++++ 1 file changed, 653 insertions(+) create mode 100644 sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql new file mode 100644 index 0000000000000..09b8d982093f0 --- /dev/null +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql @@ -0,0 +1,653 @@ +-- +-- Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group +-- +-- +-- AGGREGATES [Part 3] +-- https://github.com/postgres/postgres/blob/REL_12_BETA1/src/test/regress/sql/aggregates.sql#L352-L990 + +-- try it on an inheritance tree +create table minmaxtest(f1 int); +create table minmaxtest1() inherits (minmaxtest); +create table minmaxtest2() inherits (minmaxtest); +create table minmaxtest3() inherits (minmaxtest); +create index minmaxtesti on minmaxtest(f1); +create index minmaxtest1i on minmaxtest1(f1); +create index minmaxtest2i on minmaxtest2(f1 desc); +create index minmaxtest3i on minmaxtest3(f1) where f1 is not null; + +insert into minmaxtest values(11), (12); +insert into minmaxtest1 values(13), (14); +insert into minmaxtest2 values(15), (16); +insert into minmaxtest3 values(17), (18); + +explain (costs off) + select min(f1), max(f1) from minmaxtest; +select min(f1), max(f1) from minmaxtest; + +-- DISTINCT doesn't do anything useful here, but it shouldn't fail +explain (costs off) + select distinct min(f1), max(f1) from minmaxtest; +select distinct min(f1), max(f1) from minmaxtest; + +drop table minmaxtest cascade; + +-- check for correct detection of nested-aggregate errors +select max(min(unique1)) from tenk1; +select (select max(min(unique1)) from int8_tbl) from tenk1; + +-- +-- Test removal of redundant GROUP BY columns +-- + +create temp table t1 (a int, b int, c int, d int, primary key (a, b)); +create temp table t2 (x int, y int, z int, primary key (x, y)); +create temp table t3 (a int, b int, c int, primary key(a, b) deferrable); + +-- Non-primary-key columns can be removed from GROUP BY +explain (costs off) select * from t1 group by a,b,c,d; + +-- No removal can happen if the complete PK is not present in GROUP BY +explain (costs off) select a,c from t1 group by a,c,d; + +-- Test removal across multiple relations +explain (costs off) select * +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.y,t2.z; + +-- Test case where t1 can be optimized but not t2 +explain (costs off) select t1.*,t2.x,t2.z +from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z; + +-- Cannot optimize when PK is deferrable +explain (costs off) select * from t3 group by a,b,c; + +drop table t1; +drop table t2; +drop table t3; + +-- +-- Test combinations of DISTINCT and/or ORDER BY +-- + +select array_agg(a order by b) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); +select array_agg(a order by a) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); +select array_agg(a order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); +select array_agg(b order by a desc) + from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); + +select array_agg(distinct a) + from (values (1),(2),(1),(3),(null),(2)) v(a); +select array_agg(distinct a order by a) + from (values (1),(2),(1),(3),(null),(2)) v(a); +select array_agg(distinct a order by a desc) + from (values (1),(2),(1),(3),(null),(2)) v(a); +select array_agg(distinct a order by a desc nulls last) + from (values (1),(2),(1),(3),(null),(2)) v(a); + +-- multi-arg aggs, strict/nonstrict, distinct/order by + +select aggfstr(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); +select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select aggfstr(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; +select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select aggfstr(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; +select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +-- test specific code paths + +select aggfns(distinct a,a,c order by c using ~<~,a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; +select aggfns(distinct a,a,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; +select aggfns(distinct a,a,c order by a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; +select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +-- check node I/O via view creation and usage, also deparsing logic + +create view agg_view1 as + select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select * from agg_view1; +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i; + +select * from agg_view1; +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(a,b,c order by b+1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(a,a,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(a,b,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +select * from agg_view1; +select pg_get_viewdef('agg_view1'::regclass); + +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +select * from agg_view1; +select pg_get_viewdef('agg_view1'::regclass); + +drop view agg_view1; + +-- incorrect DISTINCT usage errors + +select aggfns(distinct a,b,c order by i) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +select aggfns(distinct a,b,c order by a,b+1) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +select aggfns(distinct a,b,c order by a,b,i,c) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +select aggfns(distinct a,a,c order by a,b) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; + +-- string_agg tests +select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a); +select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a); +select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a); +select string_agg(a,',') from (values(null),(null)) g(a); + +-- check some implicit casting cases, as per bug #5564 +select string_agg(distinct f1, ',' order by f1) from varchar_tbl; -- ok +select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; -- not ok +select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok +select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok + +-- string_agg bytea tests +create table bytea_test_table(v bytea); + +select string_agg(v, '') from bytea_test_table; + +insert into bytea_test_table values(decode('ff','hex')); + +select string_agg(v, '') from bytea_test_table; + +insert into bytea_test_table values(decode('aa','hex')); + +select string_agg(v, '') from bytea_test_table; +select string_agg(v, NULL) from bytea_test_table; +select string_agg(v, decode('ee', 'hex')) from bytea_test_table; + +drop table bytea_test_table; + +-- FILTER tests + +select min(unique1) filter (where unique1 > 100) from tenk1; + +select sum(1/ten) filter (where ten > 0) from tenk1; + +select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +group by ten; + +select ten, sum(distinct four) filter (where four > 10) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four); + +select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') +from (values ('a', 'b')) AS v(foo,bar); + +-- outer reference in FILTER (PostgreSQL extension) +select (select count(*) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c); -- inner query is aggregation query +select (select count(*) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c); -- outer query is aggregation query +select (select count(inner_c) filter (where outer_c <> 0) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c); -- inner query is aggregation query +select + (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)) + filter (where o.unique1 < 10)) +from tenk1 o; -- outer query is aggregation query + +-- subquery in FILTER clause (PostgreSQL extension) +select sum(unique1) FILTER (WHERE + unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1; + +-- exercise lots of aggregate parts with FILTER +select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i; + +-- ordered-set aggregates + +select p, percentile_cont(p) within group (order by x::float8) +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p; + +select p, percentile_cont(p order by p) within group (order by x) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p; + +select p, sum() within group (order by x::float8) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p; + +select p, percentile_cont(p,p) -- error +from generate_series(1,5) x, + (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) +group by p order by p; + +select percentile_cont(0.5) within group (order by b) from aggtest; +select percentile_cont(0.5) within group (order by b), sum(b) from aggtest; +select percentile_cont(0.5) within group (order by thousand) from tenk1; +select percentile_disc(0.5) within group (order by thousand) from tenk1; +select rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); +select cume_dist(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); +select percent_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4),(5)) v(x); +select dense_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); + +select percentile_disc(array[0,0.1,0.25,0.5,0.75,0.9,1]) within group (order by thousand) +from tenk1; +select percentile_cont(array[0,0.25,0.5,0.75,1]) within group (order by thousand) +from tenk1; +select percentile_disc(array[[null,1,0.5],[0.75,0.25,null]]) within group (order by thousand) +from tenk1; +select percentile_cont(array[0,1,0.25,0.75,0.5,1,0.3,0.32,0.35,0.38,0.4]) within group (order by x) +from generate_series(1,6) x; + +select ten, mode() within group (order by string4) from tenk1 group by ten; + +select percentile_disc(array[0.25,0.5,0.75]) within group (order by x) +from unnest('{fred,jim,fred,jack,jill,fred,jill,jim,jim,sheila,jim,sheila}'::text[]) u(x); + +-- check collation propagates up in suitable cases: +select pg_collation_for(percentile_disc(1) within group (order by x collate "POSIX")) + from (values ('fred'),('jim')) v(x); + +-- ordered-set aggs created with CREATE AGGREGATE +select test_rank(3) within group (order by x) +from (values (1),(1),(2),(2),(3),(3),(4)) v(x); +select test_percentile_disc(0.5) within group (order by thousand) from tenk1; + +-- ordered-set aggs can't use ungrouped vars in direct args: +select rank(x) within group (order by x) from generate_series(1,5) x; + +-- outer-level agg can't use a grouped arg of a lower level, either: +select array(select percentile_disc(a) within group (order by x) + from (values (0.3),(0.7)) v(a) group by a) + from generate_series(1,5) g(x); + +-- agg in the direct args is a grouping violation, too: +select rank(sum(x)) within group (order by x) from generate_series(1,5) x; + +-- hypothetical-set type unification and argument-count failures: +select rank(3) within group (order by x) from (values ('fred'),('jim')) v(x); +select rank(3) within group (order by stringu1,stringu2) from tenk1; +select rank('fred') within group (order by x) from generate_series(1,5) x; +select rank('adam'::text collate "C") within group (order by x collate "POSIX") + from (values ('fred'),('jim')) v(x); +-- hypothetical-set type unification successes: +select rank('adam'::varchar) within group (order by x) from (values ('fred'),('jim')) v(x); +select rank('3') within group (order by x) from generate_series(1,5) x; + +-- divide by zero check +select percent_rank(0) within group (order by x) from generate_series(1,0) x; + +-- deparse and multiple features: +create view aggordview1 as +select ten, + percentile_disc(0.5) within group (order by thousand) as p50, + percentile_disc(0.5) within group (order by thousand) filter (where hundred=1) as px, + rank(5,'AZZZZ',50) within group (order by hundred, string4 desc, hundred) + from tenk1 + group by ten order by ten; + +select pg_get_viewdef('aggordview1'); +select * from aggordview1 order by ten; +drop view aggordview1; + +-- variadic aggregates +select least_agg(q1,q2) from int8_tbl; +select least_agg(variadic array[q1,q2]) from int8_tbl; + + +-- test aggregates with common transition functions share the same states +begin work; + +create type avg_state as (total bigint, count bigint); + +create or replace function avg_transfn(state avg_state, n int) returns avg_state as +$$ +declare new_state avg_state; +begin + raise notice 'avg_transfn called with %', n; + if state is null then + if n is not null then + new_state.total := n; + new_state.count := 1; + return new_state; + end if; + return null; + elsif n is not null then + state.total := state.total + n; + state.count := state.count + 1; + return state; + end if; + + return null; +end +$$ language plpgsql; + +create function avg_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total / state.count; + end if; +end +$$ language plpgsql; + +create function sum_finalfn(state avg_state) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state.total; + end if; +end +$$ language plpgsql; + +create aggregate my_avg(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn +); + +create aggregate my_sum(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn +); + +-- aggregate state should be shared as aggs are the same. +select my_avg(one),my_avg(one) from (values(1),(3)) t(one); + +-- aggregate state should be shared as transfn is the same for both aggs. +select my_avg(one),my_sum(one) from (values(1),(3)) t(one); + +-- same as previous one, but with DISTINCT, which requires sorting the input. +select my_avg(distinct one),my_sum(distinct one) from (values(1),(3),(1)) t(one); + +-- shouldn't share states due to the distinctness not matching. +select my_avg(distinct one),my_sum(one) from (values(1),(3)) t(one); + +-- shouldn't share states due to the filter clause not matching. +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); + +-- exercise cases where OSAs share state +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 + percentile_cont(0.25) within group (order by a), + percentile_disc(0.5) within group (order by a) +from (values(1::float8),(3),(5),(7)) t(a); + +-- these can't share state currently +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) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = sum_finalfn, + initcond = '(10,0)' +); + +create aggregate my_avg_init(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(10,0)' +); + +create aggregate my_avg_init2(int4) +( + stype = avg_state, + sfunc = avg_transfn, + finalfunc = avg_finalfn, + initcond = '(4,0)' +); + +-- state should be shared if INITCONDs are matching +select my_sum_init(one),my_avg_init(one) from (values(1),(3)) t(one); + +-- Varying INITCONDs should cause the states not to be shared. +select my_sum_init(one),my_avg_init2(one) from (values(1),(3)) t(one); + +rollback; + +-- test aggregate state sharing to ensure it works if one aggregate has a +-- finalfn and the other one has none. +begin work; + +create or replace function sum_transfn(state int4, n int4) returns int4 as +$$ +declare new_state int4; +begin + raise notice 'sum_transfn called with %', n; + if state is null then + if n is not null then + new_state := n; + return new_state; + end if; + return null; + elsif n is not null then + state := state + n; + return state; + end if; + + return null; +end +$$ language plpgsql; + +create function halfsum_finalfn(state int4) returns int4 as +$$ +begin + if state is null then + return NULL; + else + return state / 2; + end if; +end +$$ language plpgsql; + +create aggregate my_sum(int4) +( + stype = int4, + sfunc = sum_transfn +); + +create aggregate my_half_sum(int4) +( + stype = int4, + sfunc = sum_transfn, + finalfunc = halfsum_finalfn +); + +-- Agg state should be shared even though my_sum has no finalfn +select my_sum(one),my_half_sum(one) from (values(1),(2),(3),(4)) t(one); + +rollback; + + +-- test that the aggregate transition logic correctly handles +-- transition / combine functions returning NULL + +-- First test the case of a normal transition function returning NULL +BEGIN; +CREATE FUNCTION balkifnull(int8, int4) +RETURNS int8 +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$; + +CREATE AGGREGATE balk(int4) +( + SFUNC = balkifnull(int8, int4), + STYPE = int8, + PARALLEL = SAFE, + INITCOND = '0' +); + +SELECT balk(hundred) FROM tenk1; + +ROLLBACK; + +-- Secondly test the case of a parallel aggregate combiner function +-- returning NULL. For that use normal transition function, but a +-- combiner function returning NULL. +BEGIN ISOLATION LEVEL REPEATABLE READ; +CREATE FUNCTION balkifnull(int8, int8) +RETURNS int8 +PARALLEL SAFE +STRICT +LANGUAGE plpgsql AS $$ +BEGIN + IF $1 IS NULL THEN + RAISE 'erroneously called with NULL argument'; + END IF; + RETURN NULL; +END$$; + +CREATE AGGREGATE balk(int4) +( + SFUNC = int4_sum(int8, int4), + STYPE = int8, + COMBINEFUNC = balkifnull(int8, int8), + PARALLEL = SAFE, + INITCOND = '0' +); + +-- force use of parallelism +ALTER TABLE tenk1 set (parallel_workers = 4); +SET LOCAL parallel_setup_cost=0; +SET LOCAL max_parallel_workers_per_gather=4; + +EXPLAIN (COSTS OFF) SELECT balk(hundred) FROM tenk1; +SELECT balk(hundred) FROM tenk1; + +ROLLBACK; + +-- test coverage for aggregate combine/serial/deserial functions +BEGIN ISOLATION LEVEL REPEATABLE READ; + +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 4; +SET enable_indexonlyscan = off; + +-- variance(int4) covers numeric_poly_combine +-- sum(int8) covers int8_avg_combine +-- regr_count(float8, float8) covers int8inc_float8_float8 and aggregates with > 1 arg +EXPLAIN (COSTS OFF, VERBOSE) + SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; + +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; + +ROLLBACK; + +-- test coverage for dense_rank +SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (1),(1),(2),(2),(3),(3)) v(x) GROUP BY (x) ORDER BY 1; + + +-- Ensure that the STRICT checks for aggregates does not take NULLness +-- of ORDER BY columns into account. See bug report around +-- 2a505161-2727-2473-7c46-591ed108ac52@email.cz +SELECT min(x ORDER BY y) FROM (VALUES(1, NULL)) AS d(x,y); +SELECT min(x ORDER BY y) FROM (VALUES(1, 2)) AS d(x,y); + +-- check collation-sensitive matching between grouping expressions +select v||'a', case v||'a' when 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; +select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; + +-- Make sure that generation of HashAggregate for uniqification purposes +-- does not lead to array overflow due to unexpected duplicate hash keys +-- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com +explain (costs off) + select 1 from tenk1 + where (hundred, thousand) in (select twothousand, twothousand from onek); From baaf0c5156f8065a66c060d7fdeaedb4e06823d2 Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Mon, 10 Jun 2019 12:51:41 +0800 Subject: [PATCH 2/9] add result --- .../inputs/pgSQL/aggregates_part3.sql | 601 ++++------------- .../results/pgSQL/aggregates_part3.sql.out | 632 ++++++++++++++++++ 2 files changed, 748 insertions(+), 485 deletions(-) create mode 100644 sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql index 09b8d982093f0..84ea367bfb2bb 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql @@ -3,90 +3,105 @@ -- -- -- AGGREGATES [Part 3] --- https://github.com/postgres/postgres/blob/REL_12_BETA1/src/test/regress/sql/aggregates.sql#L352-L990 - +-- https://github.com/postgres/postgres/blob/REL_12_BETA1/src/test/regress/sql/aggregates.sql#L352-L605 + +create temporary view varchar_tbl as select * from values + ('a'), + ('A'), + ('1'), + ('2'), + ('3'), + (''), + -- ('cd'), + ('c') + as varchar_tbl(f1); + +-- We do not support inheritance tree, skip related tests. -- try it on an inheritance tree -create table minmaxtest(f1 int); -create table minmaxtest1() inherits (minmaxtest); -create table minmaxtest2() inherits (minmaxtest); -create table minmaxtest3() inherits (minmaxtest); -create index minmaxtesti on minmaxtest(f1); -create index minmaxtest1i on minmaxtest1(f1); -create index minmaxtest2i on minmaxtest2(f1 desc); -create index minmaxtest3i on minmaxtest3(f1) where f1 is not null; - -insert into minmaxtest values(11), (12); -insert into minmaxtest1 values(13), (14); -insert into minmaxtest2 values(15), (16); -insert into minmaxtest3 values(17), (18); - -explain (costs off) - select min(f1), max(f1) from minmaxtest; -select min(f1), max(f1) from minmaxtest; +-- create table minmaxtest(f1 int); +-- create table minmaxtest1() inherits (minmaxtest); +-- create table minmaxtest2() inherits (minmaxtest); +-- create table minmaxtest3() inherits (minmaxtest); +-- create index minmaxtesti on minmaxtest(f1); +-- create index minmaxtest1i on minmaxtest1(f1); +-- create index minmaxtest2i on minmaxtest2(f1 desc); +-- create index minmaxtest3i on minmaxtest3(f1) where f1 is not null; + +-- insert into minmaxtest values(11), (12); +-- insert into minmaxtest1 values(13), (14); +-- insert into minmaxtest2 values(15), (16); +-- insert into minmaxtest3 values(17), (18); + +-- explain (costs off) +-- select min(f1), max(f1) from minmaxtest; +-- select min(f1), max(f1) from minmaxtest; -- DISTINCT doesn't do anything useful here, but it shouldn't fail -explain (costs off) - select distinct min(f1), max(f1) from minmaxtest; -select distinct min(f1), max(f1) from minmaxtest; +-- explain (costs off) +-- select distinct min(f1), max(f1) from minmaxtest; +-- select distinct min(f1), max(f1) from minmaxtest; -drop table minmaxtest cascade; +-- drop table minmaxtest cascade; +-- [SPARK-9830] It is not allowed to use an aggregate function in the argument of another aggregate function -- check for correct detection of nested-aggregate errors -select max(min(unique1)) from tenk1; -select (select max(min(unique1)) from int8_tbl) from tenk1; +-- select max(min(unique1)) from tenk1; +-- select (select max(min(unique1)) from int8_tbl) from tenk1; +-- These tests only test the explain. Skip these tests. -- -- Test removal of redundant GROUP BY columns -- -create temp table t1 (a int, b int, c int, d int, primary key (a, b)); -create temp table t2 (x int, y int, z int, primary key (x, y)); -create temp table t3 (a int, b int, c int, primary key(a, b) deferrable); +-- create temp table t1 (a int, b int, c int, d int, primary key (a, b)); +-- create temp table t2 (x int, y int, z int, primary key (x, y)); +-- create temp table t3 (a int, b int, c int, primary key(a, b) deferrable); -- Non-primary-key columns can be removed from GROUP BY -explain (costs off) select * from t1 group by a,b,c,d; +-- explain (costs off) select * from t1 group by a,b,c,d; -- No removal can happen if the complete PK is not present in GROUP BY -explain (costs off) select a,c from t1 group by a,c,d; +-- explain (costs off) select a,c from t1 group by a,c,d; -- Test removal across multiple relations -explain (costs off) select * -from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y -group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.y,t2.z; +-- explain (costs off) select * +-- from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +-- group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.y,t2.z; -- Test case where t1 can be optimized but not t2 -explain (costs off) select t1.*,t2.x,t2.z -from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y -group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z; +-- explain (costs off) select t1.*,t2.x,t2.z +-- from t1 inner join t2 on t1.a = t2.x and t1.b = t2.y +-- group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z; -- Cannot optimize when PK is deferrable -explain (costs off) select * from t3 group by a,b,c; +-- explain (costs off) select * from t3 group by a,b,c; -drop table t1; -drop table t2; -drop table t3; +-- drop table t1; +-- drop table t2; +-- drop table t3; +-- [SPARK-27974] Add built-in Aggregate Function: array_agg -- -- Test combinations of DISTINCT and/or ORDER BY -- -select array_agg(a order by b) - from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); -select array_agg(a order by a) - from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); -select array_agg(a order by a desc) - from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); -select array_agg(b order by a desc) - from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); - -select array_agg(distinct a) - from (values (1),(2),(1),(3),(null),(2)) v(a); -select array_agg(distinct a order by a) - from (values (1),(2),(1),(3),(null),(2)) v(a); -select array_agg(distinct a order by a desc) - from (values (1),(2),(1),(3),(null),(2)) v(a); -select array_agg(distinct a order by a desc nulls last) - from (values (1),(2),(1),(3),(null),(2)) v(a); +-- select array_agg(a order by b) +-- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); +-- select array_agg(a order by a) +-- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); +-- select array_agg(a order by a desc) +-- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); +-- select array_agg(b order by a desc) +-- from (values (1,4),(2,3),(3,1),(4,2)) v(a,b); + +-- select array_agg(distinct a) +-- from (values (1),(2),(1),(3),(null),(2)) v(a); +-- select array_agg(distinct a order by a) +-- from (values (1),(2),(1),(3),(null),(2)) v(a); +-- select array_agg(distinct a order by a desc) +-- from (values (1),(2),(1),(3),(null),(2)) v(a); +-- select array_agg(distinct a order by a desc nulls last) +-- from (values (1),(2),(1),(3),(null),(2)) v(a); -- multi-arg aggs, strict/nonstrict, distinct/order by @@ -191,463 +206,79 @@ select aggfns(distinct a,b,c order by a,b,i,c) select aggfns(distinct a,a,c order by a,b) from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +-- [SPARK-27978] We use concat_ws(delimiter, collect_list(expression)) to rewrite string_agg -- string_agg tests -select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a); -select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a); -select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a); -select string_agg(a,',') from (values(null),(null)) g(a); +select concat_ws(',', collect_list(a)) from (values('aaaa'),('bbbb'),('cccc')) g(a); +select concat_ws(',', collect_list(a)) from (values('aaaa'),(null),('bbbb'),('cccc')) g(a); +select concat_ws('AB', collect_list(a)) from (values(null),(null),('bbbb'),('cccc')) g(a); +-- The result is different: collect_list returns an empty list, but string_agg results NULL +select concat_ws(',', collect_list(a)) from (values(null),(null)) g(a); -- check some implicit casting cases, as per bug #5564 -select string_agg(distinct f1, ',' order by f1) from varchar_tbl; -- ok -select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; -- not ok -select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok -select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok +select concat_ws(',', sort_array(array_distinct(collect_list(f1)))) from varchar_tbl; +-- select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; -- not ok +-- select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok +-- select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok +-- Skip these tests because we do not have a bytea type -- string_agg bytea tests -create table bytea_test_table(v bytea); +-- create table bytea_test_table(v bytea); -select string_agg(v, '') from bytea_test_table; +-- select string_agg(v, '') from bytea_test_table; -insert into bytea_test_table values(decode('ff','hex')); +-- insert into bytea_test_table values(decode('ff','hex')); -select string_agg(v, '') from bytea_test_table; +-- select string_agg(v, '') from bytea_test_table; -insert into bytea_test_table values(decode('aa','hex')); +-- insert into bytea_test_table values(decode('aa','hex')); -select string_agg(v, '') from bytea_test_table; -select string_agg(v, NULL) from bytea_test_table; -select string_agg(v, decode('ee', 'hex')) from bytea_test_table; +-- select string_agg(v, '') from bytea_test_table; +-- select string_agg(v, NULL) from bytea_test_table; +-- select string_agg(v, decode('ee', 'hex')) from bytea_test_table; -drop table bytea_test_table; +-- drop table bytea_test_table; +-- [SPARK-27986] Support Aggregate Expressions -- FILTER tests -select min(unique1) filter (where unique1 > 100) from tenk1; +select min(CASE WHEN unique1> 100 THEN unique1 END) from tenk1; -select sum(1/ten) filter (where ten > 0) from tenk1; +select sum(CASE WHEN ten > 0 THEN cast(1/ten as integer) END) from tenk1; -select ten, sum(distinct four) filter (where four::text ~ '123') from onek a -group by ten; +-- [SPARK-27987] Support POSIX Regular Expressions +-- select ten, sum(distinct four) filter (where four::text ~ '123') from onek a +-- group by ten; -select ten, sum(distinct four) filter (where four > 10) from onek a +select ten, sum(distinct CASE WHEN four > 10 THEN four END) from onek a group by ten having exists (select 1 from onek b where sum(distinct a.four) = b.four); -select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') +select max(CASE WHEN bar > '0' THEN foo END) from (values ('a', 'b')) AS v(foo,bar); -- outer reference in FILTER (PostgreSQL extension) select (select count(*) from (values (1)) t0(inner_c)) from (values (2),(3)) t1(outer_c); -- inner query is aggregation query -select (select count(*) filter (where outer_c <> 0) - from (values (1)) t0(inner_c)) -from (values (2),(3)) t1(outer_c); -- outer query is aggregation query -select (select count(inner_c) filter (where outer_c <> 0) - from (values (1)) t0(inner_c)) -from (values (2),(3)) t1(outer_c); -- inner query is aggregation query -select - (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)) - filter (where o.unique1 < 10)) -from tenk1 o; -- outer query is aggregation query - +-- Rewriting to CASE WHEN will hit: Expressions referencing the outer query are not supported outside of WHERE/HAVING clauses +-- select (select count(*) filter (where outer_c <> 0) +-- from (values (1)) t0(inner_c)) +-- from (values (2),(3)) t1(outer_c); +-- Rewriting to CASE WHEN will hit: Found an aggregate expression in a correlated predicate that has both outer and local references +-- select (select count(inner_c) filter (where outer_c <> 0) +-- from (values (1)) t0(inner_c)) +-- from (values (2),(3)) t1(outer_c); -- inner query is aggregation query +-- Can not rewrite this pattern: aggregate_name(sub-query) filter() +-- select +-- (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)) +-- filter (where o.unique1 < 10)) +-- from tenk1 o; -- outer query is aggregation query -- subquery in FILTER clause (PostgreSQL extension) -select sum(unique1) FILTER (WHERE - unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1; +-- Rewriting to CASE WHEN will hit: IN/EXISTS predicate sub-queries can only be used in a Filter +-- select sum(unique1) FILTER (WHERE +-- unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1; -- exercise lots of aggregate parts with FILTER select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), generate_series(1,2) i; - --- ordered-set aggregates - -select p, percentile_cont(p) within group (order by x::float8) -from generate_series(1,5) x, - (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) -group by p order by p; - -select p, percentile_cont(p order by p) within group (order by x) -- error -from generate_series(1,5) x, - (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) -group by p order by p; - -select p, sum() within group (order by x::float8) -- error -from generate_series(1,5) x, - (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) -group by p order by p; - -select p, percentile_cont(p,p) -- error -from generate_series(1,5) x, - (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p) -group by p order by p; - -select percentile_cont(0.5) within group (order by b) from aggtest; -select percentile_cont(0.5) within group (order by b), sum(b) from aggtest; -select percentile_cont(0.5) within group (order by thousand) from tenk1; -select percentile_disc(0.5) within group (order by thousand) from tenk1; -select rank(3) within group (order by x) -from (values (1),(1),(2),(2),(3),(3),(4)) v(x); -select cume_dist(3) within group (order by x) -from (values (1),(1),(2),(2),(3),(3),(4)) v(x); -select percent_rank(3) within group (order by x) -from (values (1),(1),(2),(2),(3),(3),(4),(5)) v(x); -select dense_rank(3) within group (order by x) -from (values (1),(1),(2),(2),(3),(3),(4)) v(x); - -select percentile_disc(array[0,0.1,0.25,0.5,0.75,0.9,1]) within group (order by thousand) -from tenk1; -select percentile_cont(array[0,0.25,0.5,0.75,1]) within group (order by thousand) -from tenk1; -select percentile_disc(array[[null,1,0.5],[0.75,0.25,null]]) within group (order by thousand) -from tenk1; -select percentile_cont(array[0,1,0.25,0.75,0.5,1,0.3,0.32,0.35,0.38,0.4]) within group (order by x) -from generate_series(1,6) x; - -select ten, mode() within group (order by string4) from tenk1 group by ten; - -select percentile_disc(array[0.25,0.5,0.75]) within group (order by x) -from unnest('{fred,jim,fred,jack,jill,fred,jill,jim,jim,sheila,jim,sheila}'::text[]) u(x); - --- check collation propagates up in suitable cases: -select pg_collation_for(percentile_disc(1) within group (order by x collate "POSIX")) - from (values ('fred'),('jim')) v(x); - --- ordered-set aggs created with CREATE AGGREGATE -select test_rank(3) within group (order by x) -from (values (1),(1),(2),(2),(3),(3),(4)) v(x); -select test_percentile_disc(0.5) within group (order by thousand) from tenk1; - --- ordered-set aggs can't use ungrouped vars in direct args: -select rank(x) within group (order by x) from generate_series(1,5) x; - --- outer-level agg can't use a grouped arg of a lower level, either: -select array(select percentile_disc(a) within group (order by x) - from (values (0.3),(0.7)) v(a) group by a) - from generate_series(1,5) g(x); - --- agg in the direct args is a grouping violation, too: -select rank(sum(x)) within group (order by x) from generate_series(1,5) x; - --- hypothetical-set type unification and argument-count failures: -select rank(3) within group (order by x) from (values ('fred'),('jim')) v(x); -select rank(3) within group (order by stringu1,stringu2) from tenk1; -select rank('fred') within group (order by x) from generate_series(1,5) x; -select rank('adam'::text collate "C") within group (order by x collate "POSIX") - from (values ('fred'),('jim')) v(x); --- hypothetical-set type unification successes: -select rank('adam'::varchar) within group (order by x) from (values ('fred'),('jim')) v(x); -select rank('3') within group (order by x) from generate_series(1,5) x; - --- divide by zero check -select percent_rank(0) within group (order by x) from generate_series(1,0) x; - --- deparse and multiple features: -create view aggordview1 as -select ten, - percentile_disc(0.5) within group (order by thousand) as p50, - percentile_disc(0.5) within group (order by thousand) filter (where hundred=1) as px, - rank(5,'AZZZZ',50) within group (order by hundred, string4 desc, hundred) - from tenk1 - group by ten order by ten; - -select pg_get_viewdef('aggordview1'); -select * from aggordview1 order by ten; -drop view aggordview1; - --- variadic aggregates -select least_agg(q1,q2) from int8_tbl; -select least_agg(variadic array[q1,q2]) from int8_tbl; - - --- test aggregates with common transition functions share the same states -begin work; - -create type avg_state as (total bigint, count bigint); - -create or replace function avg_transfn(state avg_state, n int) returns avg_state as -$$ -declare new_state avg_state; -begin - raise notice 'avg_transfn called with %', n; - if state is null then - if n is not null then - new_state.total := n; - new_state.count := 1; - return new_state; - end if; - return null; - elsif n is not null then - state.total := state.total + n; - state.count := state.count + 1; - return state; - end if; - - return null; -end -$$ language plpgsql; - -create function avg_finalfn(state avg_state) returns int4 as -$$ -begin - if state is null then - return NULL; - else - return state.total / state.count; - end if; -end -$$ language plpgsql; - -create function sum_finalfn(state avg_state) returns int4 as -$$ -begin - if state is null then - return NULL; - else - return state.total; - end if; -end -$$ language plpgsql; - -create aggregate my_avg(int4) -( - stype = avg_state, - sfunc = avg_transfn, - finalfunc = avg_finalfn -); - -create aggregate my_sum(int4) -( - stype = avg_state, - sfunc = avg_transfn, - finalfunc = sum_finalfn -); - --- aggregate state should be shared as aggs are the same. -select my_avg(one),my_avg(one) from (values(1),(3)) t(one); - --- aggregate state should be shared as transfn is the same for both aggs. -select my_avg(one),my_sum(one) from (values(1),(3)) t(one); - --- same as previous one, but with DISTINCT, which requires sorting the input. -select my_avg(distinct one),my_sum(distinct one) from (values(1),(3),(1)) t(one); - --- shouldn't share states due to the distinctness not matching. -select my_avg(distinct one),my_sum(one) from (values(1),(3)) t(one); - --- shouldn't share states due to the filter clause not matching. -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); - --- exercise cases where OSAs share state -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 - percentile_cont(0.25) within group (order by a), - percentile_disc(0.5) within group (order by a) -from (values(1::float8),(3),(5),(7)) t(a); - --- these can't share state currently -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) -( - stype = avg_state, - sfunc = avg_transfn, - finalfunc = sum_finalfn, - initcond = '(10,0)' -); - -create aggregate my_avg_init(int4) -( - stype = avg_state, - sfunc = avg_transfn, - finalfunc = avg_finalfn, - initcond = '(10,0)' -); - -create aggregate my_avg_init2(int4) -( - stype = avg_state, - sfunc = avg_transfn, - finalfunc = avg_finalfn, - initcond = '(4,0)' -); - --- state should be shared if INITCONDs are matching -select my_sum_init(one),my_avg_init(one) from (values(1),(3)) t(one); - --- Varying INITCONDs should cause the states not to be shared. -select my_sum_init(one),my_avg_init2(one) from (values(1),(3)) t(one); - -rollback; - --- test aggregate state sharing to ensure it works if one aggregate has a --- finalfn and the other one has none. -begin work; - -create or replace function sum_transfn(state int4, n int4) returns int4 as -$$ -declare new_state int4; -begin - raise notice 'sum_transfn called with %', n; - if state is null then - if n is not null then - new_state := n; - return new_state; - end if; - return null; - elsif n is not null then - state := state + n; - return state; - end if; - - return null; -end -$$ language plpgsql; - -create function halfsum_finalfn(state int4) returns int4 as -$$ -begin - if state is null then - return NULL; - else - return state / 2; - end if; -end -$$ language plpgsql; - -create aggregate my_sum(int4) -( - stype = int4, - sfunc = sum_transfn -); - -create aggregate my_half_sum(int4) -( - stype = int4, - sfunc = sum_transfn, - finalfunc = halfsum_finalfn -); - --- Agg state should be shared even though my_sum has no finalfn -select my_sum(one),my_half_sum(one) from (values(1),(2),(3),(4)) t(one); - -rollback; - - --- test that the aggregate transition logic correctly handles --- transition / combine functions returning NULL - --- First test the case of a normal transition function returning NULL -BEGIN; -CREATE FUNCTION balkifnull(int8, int4) -RETURNS int8 -STRICT -LANGUAGE plpgsql AS $$ -BEGIN - IF $1 IS NULL THEN - RAISE 'erroneously called with NULL argument'; - END IF; - RETURN NULL; -END$$; - -CREATE AGGREGATE balk(int4) -( - SFUNC = balkifnull(int8, int4), - STYPE = int8, - PARALLEL = SAFE, - INITCOND = '0' -); - -SELECT balk(hundred) FROM tenk1; - -ROLLBACK; - --- Secondly test the case of a parallel aggregate combiner function --- returning NULL. For that use normal transition function, but a --- combiner function returning NULL. -BEGIN ISOLATION LEVEL REPEATABLE READ; -CREATE FUNCTION balkifnull(int8, int8) -RETURNS int8 -PARALLEL SAFE -STRICT -LANGUAGE plpgsql AS $$ -BEGIN - IF $1 IS NULL THEN - RAISE 'erroneously called with NULL argument'; - END IF; - RETURN NULL; -END$$; - -CREATE AGGREGATE balk(int4) -( - SFUNC = int4_sum(int8, int4), - STYPE = int8, - COMBINEFUNC = balkifnull(int8, int8), - PARALLEL = SAFE, - INITCOND = '0' -); - --- force use of parallelism -ALTER TABLE tenk1 set (parallel_workers = 4); -SET LOCAL parallel_setup_cost=0; -SET LOCAL max_parallel_workers_per_gather=4; - -EXPLAIN (COSTS OFF) SELECT balk(hundred) FROM tenk1; -SELECT balk(hundred) FROM tenk1; - -ROLLBACK; - --- test coverage for aggregate combine/serial/deserial functions -BEGIN ISOLATION LEVEL REPEATABLE READ; - -SET parallel_setup_cost = 0; -SET parallel_tuple_cost = 0; -SET min_parallel_table_scan_size = 0; -SET max_parallel_workers_per_gather = 4; -SET enable_indexonlyscan = off; - --- variance(int4) covers numeric_poly_combine --- sum(int8) covers int8_avg_combine --- regr_count(float8, float8) covers int8inc_float8_float8 and aggregates with > 1 arg -EXPLAIN (COSTS OFF, VERBOSE) - SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; - -SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; - -ROLLBACK; - --- test coverage for dense_rank -SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (1),(1),(2),(2),(3),(3)) v(x) GROUP BY (x) ORDER BY 1; - - --- Ensure that the STRICT checks for aggregates does not take NULLness --- of ORDER BY columns into account. See bug report around --- 2a505161-2727-2473-7c46-591ed108ac52@email.cz -SELECT min(x ORDER BY y) FROM (VALUES(1, NULL)) AS d(x,y); -SELECT min(x ORDER BY y) FROM (VALUES(1, 2)) AS d(x,y); - --- check collation-sensitive matching between grouping expressions -select v||'a', case v||'a' when 'aa' then 1 else 0 end, count(*) - from unnest(array['a','b']) u(v) - group by v||'a' order by 1; -select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) - from unnest(array['a','b']) u(v) - group by v||'a' order by 1; - --- Make sure that generation of HashAggregate for uniqification purposes --- does not lead to array overflow due to unexpected duplicate hash keys --- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com -explain (costs off) - select 1 from tenk1 - where (hundred, thousand) in (select twothousand, twothousand from onek); diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out new file mode 100644 index 0000000000000..5204251f50a48 --- /dev/null +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out @@ -0,0 +1,632 @@ +-- Automatically generated by SQLQueryTestSuite +-- Number of queries: 48 + + +-- !query 0 +create temporary view varchar_tbl as select * from values + ('a'), + ('A'), + ('1'), + ('2'), + ('3'), + (''), + -- ('cd'), + ('c') + as varchar_tbl(f1) +-- !query 0 schema +struct<> +-- !query 0 output + + + +-- !query 1 +select aggfstr(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- !query 1 schema +struct<> +-- !query 1 output +org.apache.spark.sql.AnalysisException +Undefined function: 'aggfstr'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 + + +-- !query 2 +select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- !query 2 schema +struct<> +-- !query 2 output +org.apache.spark.sql.AnalysisException +Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 + + +-- !query 3 +select aggfstr(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- !query 3 schema +struct<> +-- !query 3 output +org.apache.spark.sql.AnalysisException +Undefined function: 'aggfstr'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 + + +-- !query 4 +select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- !query 4 schema +struct<> +-- !query 4 output +org.apache.spark.sql.AnalysisException +Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 + + +-- !query 5 +select aggfstr(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- !query 5 schema +struct<> +-- !query 5 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 30) + +== SQL == +select aggfstr(distinct a,b,c order by b) +------------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i + + +-- !query 6 +select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- !query 6 schema +struct<> +-- !query 6 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,b,c order by b) +-----------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i + + +-- !query 7 +select aggfns(distinct a,a,c order by c using ~<~,a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- !query 7 schema +struct<> +-- !query 7 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,a,c order by c using ~<~,a) +-----------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i + + +-- !query 8 +select aggfns(distinct a,a,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- !query 8 schema +struct<> +-- !query 8 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,a,c order by c using ~<~) +-----------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i + + +-- !query 9 +select aggfns(distinct a,a,c order by a) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- !query 9 schema +struct<> +-- !query 9 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,a,c order by a) +-----------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i + + +-- !query 10 +select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- !query 10 schema +struct<> +-- !query 10 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,b,c order by a,c using ~<~,b) +-----------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i + + +-- !query 11 +create view agg_view1 as + select aggfns(a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- !query 11 schema +struct<> +-- !query 11 output +org.apache.spark.sql.AnalysisException +Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 2 pos 9 + + +-- !query 12 +select * from agg_view1 +-- !query 12 schema +struct<> +-- !query 12 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; line 1 pos 14 + + +-- !query 13 +select pg_get_viewdef('agg_view1'::regclass) +-- !query 13 schema +struct<> +-- !query 13 output +org.apache.spark.sql.catalyst.parser.ParseException + +mismatched input ':' expecting {')', ','}(line 1, pos 33) + +== SQL == +select pg_get_viewdef('agg_view1'::regclass) +---------------------------------^^^ + + +-- !query 14 +create or replace view agg_view1 as + select aggfns(distinct a,b,c) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- !query 14 schema +struct<> +-- !query 14 output +org.apache.spark.sql.AnalysisException +Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 2 pos 9 + + +-- !query 15 +select * from agg_view1 +-- !query 15 schema +struct<> +-- !query 15 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; line 1 pos 14 + + +-- !query 16 +select pg_get_viewdef('agg_view1'::regclass) +-- !query 16 schema +struct<> +-- !query 16 output +org.apache.spark.sql.catalyst.parser.ParseException + +mismatched input ':' expecting {')', ','}(line 1, pos 33) + +== SQL == +select pg_get_viewdef('agg_view1'::regclass) +---------------------------------^^^ + + +-- !query 17 +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i +-- !query 17 schema +struct<> +-- !query 17 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 2, pos 31) + +== SQL == +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by b) +-------------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,3) i + + +-- !query 18 +select * from agg_view1 +-- !query 18 schema +struct<> +-- !query 18 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; line 1 pos 14 + + +-- !query 19 +select pg_get_viewdef('agg_view1'::regclass) +-- !query 19 schema +struct<> +-- !query 19 output +org.apache.spark.sql.catalyst.parser.ParseException + +mismatched input ':' expecting {')', ','}(line 1, pos 33) + +== SQL == +select pg_get_viewdef('agg_view1'::regclass) +---------------------------------^^^ + + +-- !query 20 +create or replace view agg_view1 as + select aggfns(a,b,c order by b+1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- !query 20 schema +struct<> +-- !query 20 output +org.apache.spark.sql.catalyst.parser.ParseException + +missing ')' at 'order'(line 2, pos 22) + +== SQL == +create or replace view agg_view1 as + select aggfns(a,b,c order by b+1) +----------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) + + +-- !query 21 +select * from agg_view1 +-- !query 21 schema +struct<> +-- !query 21 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; line 1 pos 14 + + +-- !query 22 +select pg_get_viewdef('agg_view1'::regclass) +-- !query 22 schema +struct<> +-- !query 22 output +org.apache.spark.sql.catalyst.parser.ParseException + +mismatched input ':' expecting {')', ','}(line 1, pos 33) + +== SQL == +select pg_get_viewdef('agg_view1'::regclass) +---------------------------------^^^ + + +-- !query 23 +create or replace view agg_view1 as + select aggfns(a,a,c order by b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- !query 23 schema +struct<> +-- !query 23 output +org.apache.spark.sql.catalyst.parser.ParseException + +missing ')' at 'order'(line 2, pos 22) + +== SQL == +create or replace view agg_view1 as + select aggfns(a,a,c order by b) +----------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) + + +-- !query 24 +select * from agg_view1 +-- !query 24 schema +struct<> +-- !query 24 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; line 1 pos 14 + + +-- !query 25 +select pg_get_viewdef('agg_view1'::regclass) +-- !query 25 schema +struct<> +-- !query 25 output +org.apache.spark.sql.catalyst.parser.ParseException + +mismatched input ':' expecting {')', ','}(line 1, pos 33) + +== SQL == +select pg_get_viewdef('agg_view1'::regclass) +---------------------------------^^^ + + +-- !query 26 +create or replace view agg_view1 as + select aggfns(a,b,c order by c using ~<~) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) +-- !query 26 schema +struct<> +-- !query 26 output +org.apache.spark.sql.catalyst.parser.ParseException + +missing ')' at 'order'(line 2, pos 22) + +== SQL == +create or replace view agg_view1 as + select aggfns(a,b,c order by c using ~<~) +----------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) + + +-- !query 27 +select * from agg_view1 +-- !query 27 schema +struct<> +-- !query 27 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; line 1 pos 14 + + +-- !query 28 +select pg_get_viewdef('agg_view1'::regclass) +-- !query 28 schema +struct<> +-- !query 28 output +org.apache.spark.sql.catalyst.parser.ParseException + +mismatched input ':' expecting {')', ','}(line 1, pos 33) + +== SQL == +select pg_get_viewdef('agg_view1'::regclass) +---------------------------------^^^ + + +-- !query 29 +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by a,c using ~<~,b) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- !query 29 schema +struct<> +-- !query 29 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 2, pos 31) + +== SQL == +create or replace view agg_view1 as + select aggfns(distinct a,b,c order by a,c using ~<~,b) +-------------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i + + +-- !query 30 +select * from agg_view1 +-- !query 30 schema +struct<> +-- !query 30 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; line 1 pos 14 + + +-- !query 31 +select pg_get_viewdef('agg_view1'::regclass) +-- !query 31 schema +struct<> +-- !query 31 output +org.apache.spark.sql.catalyst.parser.ParseException + +mismatched input ':' expecting {')', ','}(line 1, pos 33) + +== SQL == +select pg_get_viewdef('agg_view1'::regclass) +---------------------------------^^^ + + +-- !query 32 +drop view agg_view1 +-- !query 32 schema +struct<> +-- !query 32 output +org.apache.spark.sql.AnalysisException +Table or view not found: agg_view1; + + +-- !query 33 +select aggfns(distinct a,b,c order by i) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- !query 33 schema +struct<> +-- !query 33 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,b,c order by i) +-----------------------------^^^ + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i + + +-- !query 34 +select aggfns(distinct a,b,c order by a,b+1) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- !query 34 schema +struct<> +-- !query 34 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,b,c order by a,b+1) +-----------------------------^^^ + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i + + +-- !query 35 +select aggfns(distinct a,b,c order by a,b,i,c) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- !query 35 schema +struct<> +-- !query 35 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,b,c order by a,b,i,c) +-----------------------------^^^ + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i + + +-- !query 36 +select aggfns(distinct a,a,c order by a,b) + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i +-- !query 36 schema +struct<> +-- !query 36 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 1, pos 29) + +== SQL == +select aggfns(distinct a,a,c order by a,b) +-----------------------------^^^ + from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i + + +-- !query 37 +select concat_ws(',', collect_list(a)) from (values('aaaa'),('bbbb'),('cccc')) g(a) +-- !query 37 schema +struct +-- !query 37 output +aaaa,bbbb,cccc + + +-- !query 38 +select concat_ws(',', collect_list(a)) from (values('aaaa'),(null),('bbbb'),('cccc')) g(a) +-- !query 38 schema +struct +-- !query 38 output +aaaa,bbbb,cccc + + +-- !query 39 +select concat_ws('AB', collect_list(a)) from (values(null),(null),('bbbb'),('cccc')) g(a) +-- !query 39 schema +struct +-- !query 39 output +bbbbABcccc + + +-- !query 40 +select concat_ws(',', collect_list(a)) from (values(null),(null)) g(a) +-- !query 40 schema +struct +-- !query 40 output + + + +-- !query 41 +select concat_ws(',', sort_array(array_distinct(collect_list(f1)))) from varchar_tbl +-- !query 41 schema +struct +-- !query 41 output +,1,2,3,A,a,c + + +-- !query 42 +select min(CASE WHEN unique1> 100 THEN unique1 END) from tenk1 +-- !query 42 schema +struct 100) THEN unique1 END):int> +-- !query 42 output +101 + + +-- !query 43 +select sum(CASE WHEN ten > 0 THEN cast(1/ten as integer) END) from tenk1 +-- !query 43 schema +struct 0) THEN CAST((CAST(1 AS DOUBLE) / CAST(ten AS DOUBLE)) AS INT) END):bigint> +-- !query 43 output +1000 + + +-- !query 44 +select ten, sum(distinct CASE WHEN four > 10 THEN four END) from onek a +group by ten +having exists (select 1 from onek b where sum(distinct a.four) = b.four) +-- !query 44 schema +struct 10) THEN four END):bigint> +-- !query 44 output +0 NULL +2 NULL +4 NULL +6 NULL +8 NULL + + +-- !query 45 +select max(CASE WHEN bar > '0' THEN foo END) +from (values ('a', 'b')) AS v(foo,bar) +-- !query 45 schema +struct 0) THEN foo END):string> +-- !query 45 output +a + + +-- !query 46 +select (select count(*) + from (values (1)) t0(inner_c)) +from (values (2),(3)) t1(outer_c) +-- !query 46 schema +struct +-- !query 46 output +1 +1 + + +-- !query 47 +-- inner query is aggregation query + +select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i +-- !query 47 schema +struct<> +-- !query 47 output +org.apache.spark.sql.catalyst.parser.ParseException + +extraneous input 'order' expecting {')', ','}(line 3, pos 29) + +== SQL == +-- inner query is aggregation query + +select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) +-----------------------------^^^ + from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), + generate_series(1,2) i From 0a425c41b26225512cb9d0e8cb58986d76513f6c Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Wed, 12 Jun 2019 13:14:29 +0800 Subject: [PATCH 3/9] Skip some test because it requires 4 UDFs: aggf_trans, aggfns_trans, aggfstr, and aggfns --- .../inputs/pgSQL/aggregates_part3.sql | 165 ++--- .../results/pgSQL/aggregates_part3.sql.out | 583 +----------------- 2 files changed, 114 insertions(+), 634 deletions(-) diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql index 84ea367bfb2bb..da5dd059b06f6 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql @@ -103,108 +103,109 @@ create temporary view varchar_tbl as select * from values -- select array_agg(distinct a order by a desc nulls last) -- from (values (1),(2),(1),(3),(null),(2)) v(a); +-- Skip the test below because it requires 4 UDFs: aggf_trans, aggfns_trans, aggfstr, and aggfns -- multi-arg aggs, strict/nonstrict, distinct/order by -select aggfstr(a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); -select aggfns(a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); - -select aggfstr(distinct a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i; -select aggfns(distinct a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i; - -select aggfstr(distinct a,b,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i; -select aggfns(distinct a,b,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i; +-- select aggfstr(a,b,c) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); +-- select aggfns(a,b,c) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); + +-- select aggfstr(distinct a,b,c) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,3) i; +-- select aggfns(distinct a,b,c) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,3) i; + +-- select aggfstr(distinct a,b,c order by b) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,3) i; +-- select aggfns(distinct a,b,c order by b) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,3) i; -- test specific code paths -select aggfns(distinct a,a,c order by c using ~<~,a) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i; -select aggfns(distinct a,a,c order by c using ~<~) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i; -select aggfns(distinct a,a,c order by a) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i; -select aggfns(distinct a,b,c order by a,c using ~<~,b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i; +-- select aggfns(distinct a,a,c order by c using ~<~,a) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,2) i; +-- select aggfns(distinct a,a,c order by c using ~<~) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,2) i; +-- select aggfns(distinct a,a,c order by a) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,2) i; +-- select aggfns(distinct a,b,c order by a,c using ~<~,b) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,2) i; -- check node I/O via view creation and usage, also deparsing logic -create view agg_view1 as - select aggfns(a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); +-- create view agg_view1 as +-- select aggfns(a,b,c) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); -select * from agg_view1; -select pg_get_viewdef('agg_view1'::regclass); +-- select * from agg_view1; +-- select pg_get_viewdef('agg_view1'::regclass); -create or replace view agg_view1 as - select aggfns(distinct a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i; +-- create or replace view agg_view1 as +-- select aggfns(distinct a,b,c) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,3) i; -select * from agg_view1; -select pg_get_viewdef('agg_view1'::regclass); +-- select * from agg_view1; +-- select pg_get_viewdef('agg_view1'::regclass); -create or replace view agg_view1 as - select aggfns(distinct a,b,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i; +-- create or replace view agg_view1 as +-- select aggfns(distinct a,b,c order by b) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,3) i; -select * from agg_view1; -select pg_get_viewdef('agg_view1'::regclass); +-- select * from agg_view1; +-- select pg_get_viewdef('agg_view1'::regclass); -create or replace view agg_view1 as - select aggfns(a,b,c order by b+1) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); +-- create or replace view agg_view1 as +-- select aggfns(a,b,c order by b+1) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); -select * from agg_view1; -select pg_get_viewdef('agg_view1'::regclass); +-- select * from agg_view1; +-- select pg_get_viewdef('agg_view1'::regclass); -create or replace view agg_view1 as - select aggfns(a,a,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); +-- create or replace view agg_view1 as +-- select aggfns(a,a,c order by b) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); -select * from agg_view1; -select pg_get_viewdef('agg_view1'::regclass); +-- select * from agg_view1; +-- select pg_get_viewdef('agg_view1'::regclass); -create or replace view agg_view1 as - select aggfns(a,b,c order by c using ~<~) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); +-- create or replace view agg_view1 as +-- select aggfns(a,b,c order by c using ~<~) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c); -select * from agg_view1; -select pg_get_viewdef('agg_view1'::regclass); +-- select * from agg_view1; +-- select pg_get_viewdef('agg_view1'::regclass); -create or replace view agg_view1 as - select aggfns(distinct a,b,c order by a,c using ~<~,b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i; +-- create or replace view agg_view1 as +-- select aggfns(distinct a,b,c order by a,c using ~<~,b) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,2) i; -select * from agg_view1; -select pg_get_viewdef('agg_view1'::regclass); +-- select * from agg_view1; +-- select pg_get_viewdef('agg_view1'::regclass); -drop view agg_view1; +-- drop view agg_view1; -- incorrect DISTINCT usage errors -select aggfns(distinct a,b,c order by i) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; -select aggfns(distinct a,b,c order by a,b+1) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; -select aggfns(distinct a,b,c order by a,b,i,c) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; -select aggfns(distinct a,a,c order by a,b) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +-- select aggfns(distinct a,b,c order by i) +-- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +-- select aggfns(distinct a,b,c order by a,b+1) +-- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +-- select aggfns(distinct a,b,c order by a,b,i,c) +-- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; +-- select aggfns(distinct a,a,c order by a,b) +-- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; -- [SPARK-27978] We use concat_ws(delimiter, collect_list(expression)) to rewrite string_agg -- string_agg tests @@ -243,6 +244,7 @@ select concat_ws(',', sort_array(array_distinct(collect_list(f1)))) from varchar select min(CASE WHEN unique1> 100 THEN unique1 END) from tenk1; +-- The result is different: we added cast here because [SPARK-2659] select sum(CASE WHEN ten > 0 THEN cast(1/ten as integer) END) from tenk1; -- [SPARK-27987] Support POSIX Regular Expressions @@ -253,13 +255,14 @@ select ten, sum(distinct CASE WHEN four > 10 THEN four END) from onek a group by ten having exists (select 1 from onek b where sum(distinct a.four) = b.four); +-- Rewrite this SQL by removing COLLATE select max(CASE WHEN bar > '0' THEN foo END) from (values ('a', 'b')) AS v(foo,bar); -- outer reference in FILTER (PostgreSQL extension) select (select count(*) from (values (1)) t0(inner_c)) -from (values (2),(3)) t1(outer_c); -- inner query is aggregation query +from (values (2),(3)) t1(outer_c); -- Rewriting to CASE WHEN will hit: Expressions referencing the outer query are not supported outside of WHERE/HAVING clauses -- select (select count(*) filter (where outer_c <> 0) -- from (values (1)) t0(inner_c)) @@ -279,6 +282,6 @@ from (values (2),(3)) t1(outer_c); -- inner query is aggregation query -- unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1; -- exercise lots of aggregate parts with FILTER -select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i; +-- select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) +-- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), +-- generate_series(1,2) i; diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out index 5204251f50a48..9a9ae8c073a23 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out @@ -1,5 +1,5 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 48 +-- Number of queries: 11 -- !query 0 @@ -20,569 +20,68 @@ struct<> -- !query 1 -select aggfstr(a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) --- !query 1 schema -struct<> --- !query 1 output -org.apache.spark.sql.AnalysisException -Undefined function: 'aggfstr'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 - - --- !query 2 -select aggfns(a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) --- !query 2 schema -struct<> --- !query 2 output -org.apache.spark.sql.AnalysisException -Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 - - --- !query 3 -select aggfstr(distinct a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i --- !query 3 schema -struct<> --- !query 3 output -org.apache.spark.sql.AnalysisException -Undefined function: 'aggfstr'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 - - --- !query 4 -select aggfns(distinct a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i --- !query 4 schema -struct<> --- !query 4 output -org.apache.spark.sql.AnalysisException -Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 1 pos 7 - - --- !query 5 -select aggfstr(distinct a,b,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i --- !query 5 schema -struct<> --- !query 5 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 30) - -== SQL == -select aggfstr(distinct a,b,c order by b) -------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i - - --- !query 6 -select aggfns(distinct a,b,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i --- !query 6 schema -struct<> --- !query 6 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,b,c order by b) ------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i - - --- !query 7 -select aggfns(distinct a,a,c order by c using ~<~,a) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i --- !query 7 schema -struct<> --- !query 7 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,a,c order by c using ~<~,a) ------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i - - --- !query 8 -select aggfns(distinct a,a,c order by c using ~<~) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i --- !query 8 schema -struct<> --- !query 8 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,a,c order by c using ~<~) ------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i - - --- !query 9 -select aggfns(distinct a,a,c order by a) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i --- !query 9 schema -struct<> --- !query 9 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,a,c order by a) ------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i - - --- !query 10 -select aggfns(distinct a,b,c order by a,c using ~<~,b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i --- !query 10 schema -struct<> --- !query 10 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,b,c order by a,c using ~<~,b) ------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i - - --- !query 11 -create view agg_view1 as - select aggfns(a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) --- !query 11 schema -struct<> --- !query 11 output -org.apache.spark.sql.AnalysisException -Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 2 pos 9 - - --- !query 12 -select * from agg_view1 --- !query 12 schema -struct<> --- !query 12 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; line 1 pos 14 - - --- !query 13 -select pg_get_viewdef('agg_view1'::regclass) --- !query 13 schema -struct<> --- !query 13 output -org.apache.spark.sql.catalyst.parser.ParseException - -mismatched input ':' expecting {')', ','}(line 1, pos 33) - -== SQL == -select pg_get_viewdef('agg_view1'::regclass) ----------------------------------^^^ - - --- !query 14 -create or replace view agg_view1 as - select aggfns(distinct a,b,c) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i --- !query 14 schema -struct<> --- !query 14 output -org.apache.spark.sql.AnalysisException -Undefined function: 'aggfns'. This function is neither a registered temporary function nor a permanent function registered in the database 'default'.; line 2 pos 9 - - --- !query 15 -select * from agg_view1 --- !query 15 schema -struct<> --- !query 15 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; line 1 pos 14 - - --- !query 16 -select pg_get_viewdef('agg_view1'::regclass) --- !query 16 schema -struct<> --- !query 16 output -org.apache.spark.sql.catalyst.parser.ParseException - -mismatched input ':' expecting {')', ','}(line 1, pos 33) - -== SQL == -select pg_get_viewdef('agg_view1'::regclass) ----------------------------------^^^ - - --- !query 17 -create or replace view agg_view1 as - select aggfns(distinct a,b,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i --- !query 17 schema -struct<> --- !query 17 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 2, pos 31) - -== SQL == -create or replace view agg_view1 as - select aggfns(distinct a,b,c order by b) --------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,3) i - - --- !query 18 -select * from agg_view1 --- !query 18 schema -struct<> --- !query 18 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; line 1 pos 14 - - --- !query 19 -select pg_get_viewdef('agg_view1'::regclass) --- !query 19 schema -struct<> --- !query 19 output -org.apache.spark.sql.catalyst.parser.ParseException - -mismatched input ':' expecting {')', ','}(line 1, pos 33) - -== SQL == -select pg_get_viewdef('agg_view1'::regclass) ----------------------------------^^^ - - --- !query 20 -create or replace view agg_view1 as - select aggfns(a,b,c order by b+1) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) --- !query 20 schema -struct<> --- !query 20 output -org.apache.spark.sql.catalyst.parser.ParseException - -missing ')' at 'order'(line 2, pos 22) - -== SQL == -create or replace view agg_view1 as - select aggfns(a,b,c order by b+1) -----------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) - - --- !query 21 -select * from agg_view1 --- !query 21 schema -struct<> --- !query 21 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; line 1 pos 14 - - --- !query 22 -select pg_get_viewdef('agg_view1'::regclass) --- !query 22 schema -struct<> --- !query 22 output -org.apache.spark.sql.catalyst.parser.ParseException - -mismatched input ':' expecting {')', ','}(line 1, pos 33) - -== SQL == -select pg_get_viewdef('agg_view1'::regclass) ----------------------------------^^^ - - --- !query 23 -create or replace view agg_view1 as - select aggfns(a,a,c order by b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) --- !query 23 schema -struct<> --- !query 23 output -org.apache.spark.sql.catalyst.parser.ParseException - -missing ')' at 'order'(line 2, pos 22) - -== SQL == -create or replace view agg_view1 as - select aggfns(a,a,c order by b) -----------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) - - --- !query 24 -select * from agg_view1 --- !query 24 schema -struct<> --- !query 24 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; line 1 pos 14 - - --- !query 25 -select pg_get_viewdef('agg_view1'::regclass) --- !query 25 schema -struct<> --- !query 25 output -org.apache.spark.sql.catalyst.parser.ParseException - -mismatched input ':' expecting {')', ','}(line 1, pos 33) - -== SQL == -select pg_get_viewdef('agg_view1'::regclass) ----------------------------------^^^ - - --- !query 26 -create or replace view agg_view1 as - select aggfns(a,b,c order by c using ~<~) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) --- !query 26 schema -struct<> --- !query 26 output -org.apache.spark.sql.catalyst.parser.ParseException - -missing ')' at 'order'(line 2, pos 22) - -== SQL == -create or replace view agg_view1 as - select aggfns(a,b,c order by c using ~<~) -----------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c) - - --- !query 27 -select * from agg_view1 --- !query 27 schema -struct<> --- !query 27 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; line 1 pos 14 - - --- !query 28 -select pg_get_viewdef('agg_view1'::regclass) --- !query 28 schema -struct<> --- !query 28 output -org.apache.spark.sql.catalyst.parser.ParseException - -mismatched input ':' expecting {')', ','}(line 1, pos 33) - -== SQL == -select pg_get_viewdef('agg_view1'::regclass) ----------------------------------^^^ - - --- !query 29 -create or replace view agg_view1 as - select aggfns(distinct a,b,c order by a,c using ~<~,b) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i --- !query 29 schema -struct<> --- !query 29 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 2, pos 31) - -== SQL == -create or replace view agg_view1 as - select aggfns(distinct a,b,c order by a,c using ~<~,b) --------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i - - --- !query 30 -select * from agg_view1 --- !query 30 schema -struct<> --- !query 30 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; line 1 pos 14 - - --- !query 31 -select pg_get_viewdef('agg_view1'::regclass) --- !query 31 schema -struct<> --- !query 31 output -org.apache.spark.sql.catalyst.parser.ParseException - -mismatched input ':' expecting {')', ','}(line 1, pos 33) - -== SQL == -select pg_get_viewdef('agg_view1'::regclass) ----------------------------------^^^ - - --- !query 32 -drop view agg_view1 --- !query 32 schema -struct<> --- !query 32 output -org.apache.spark.sql.AnalysisException -Table or view not found: agg_view1; - - --- !query 33 -select aggfns(distinct a,b,c order by i) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i --- !query 33 schema -struct<> --- !query 33 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,b,c order by i) ------------------------------^^^ - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i - - --- !query 34 -select aggfns(distinct a,b,c order by a,b+1) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i --- !query 34 schema -struct<> --- !query 34 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,b,c order by a,b+1) ------------------------------^^^ - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i - - --- !query 35 -select aggfns(distinct a,b,c order by a,b,i,c) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i --- !query 35 schema -struct<> --- !query 35 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,b,c order by a,b,i,c) ------------------------------^^^ - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i - - --- !query 36 -select aggfns(distinct a,a,c order by a,b) - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i --- !query 36 schema -struct<> --- !query 36 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 1, pos 29) - -== SQL == -select aggfns(distinct a,a,c order by a,b) ------------------------------^^^ - from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i - - --- !query 37 select concat_ws(',', collect_list(a)) from (values('aaaa'),('bbbb'),('cccc')) g(a) --- !query 37 schema +-- !query 1 schema struct --- !query 37 output +-- !query 1 output aaaa,bbbb,cccc --- !query 38 +-- !query 2 select concat_ws(',', collect_list(a)) from (values('aaaa'),(null),('bbbb'),('cccc')) g(a) --- !query 38 schema +-- !query 2 schema struct --- !query 38 output +-- !query 2 output aaaa,bbbb,cccc --- !query 39 +-- !query 3 select concat_ws('AB', collect_list(a)) from (values(null),(null),('bbbb'),('cccc')) g(a) --- !query 39 schema +-- !query 3 schema struct --- !query 39 output +-- !query 3 output bbbbABcccc --- !query 40 +-- !query 4 select concat_ws(',', collect_list(a)) from (values(null),(null)) g(a) --- !query 40 schema +-- !query 4 schema struct --- !query 40 output +-- !query 4 output --- !query 41 +-- !query 5 select concat_ws(',', sort_array(array_distinct(collect_list(f1)))) from varchar_tbl --- !query 41 schema +-- !query 5 schema struct --- !query 41 output +-- !query 5 output ,1,2,3,A,a,c --- !query 42 +-- !query 6 select min(CASE WHEN unique1> 100 THEN unique1 END) from tenk1 --- !query 42 schema +-- !query 6 schema struct 100) THEN unique1 END):int> --- !query 42 output +-- !query 6 output 101 --- !query 43 +-- !query 7 select sum(CASE WHEN ten > 0 THEN cast(1/ten as integer) END) from tenk1 --- !query 43 schema +-- !query 7 schema struct 0) THEN CAST((CAST(1 AS DOUBLE) / CAST(ten AS DOUBLE)) AS INT) END):bigint> --- !query 43 output +-- !query 7 output 1000 --- !query 44 +-- !query 8 select ten, sum(distinct CASE WHEN four > 10 THEN four END) from onek a group by ten having exists (select 1 from onek b where sum(distinct a.four) = b.four) --- !query 44 schema +-- !query 8 schema struct 10) THEN four END):bigint> --- !query 44 output +-- !query 8 output 0 NULL 2 NULL 4 NULL @@ -590,43 +89,21 @@ struct 10) THEN four END):bigint> 8 NULL --- !query 45 +-- !query 9 select max(CASE WHEN bar > '0' THEN foo END) from (values ('a', 'b')) AS v(foo,bar) --- !query 45 schema +-- !query 9 schema struct 0) THEN foo END):string> --- !query 45 output +-- !query 9 output a --- !query 46 +-- !query 10 select (select count(*) from (values (1)) t0(inner_c)) from (values (2),(3)) t1(outer_c) --- !query 46 schema +-- !query 10 schema struct --- !query 46 output +-- !query 10 output 1 1 - - --- !query 47 --- inner query is aggregation query - -select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i --- !query 47 schema -struct<> --- !query 47 output -org.apache.spark.sql.catalyst.parser.ParseException - -extraneous input 'order' expecting {')', ','}(line 3, pos 29) - -== SQL == --- inner query is aggregation query - -select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) ------------------------------^^^ - from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), - generate_series(1,2) i From 7c8b1edf7d7c61b0f4653a4f9ab6349d88947535 Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Thu, 1 Aug 2019 21:59:26 +0800 Subject: [PATCH 4/9] Merge master --- .../resources/sql-tests/results/pgSQL/aggregates_part3.sql.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out index 9a9ae8c073a23..76ffae10abc02 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out @@ -70,7 +70,7 @@ struct 100) THEN unique1 END):int> -- !query 7 select sum(CASE WHEN ten > 0 THEN cast(1/ten as integer) END) from tenk1 -- !query 7 schema -struct 0) THEN CAST((CAST(1 AS DOUBLE) / CAST(ten AS DOUBLE)) AS INT) END):bigint> +struct 0) THEN CAST((1 div ten) AS INT) END):bigint> -- !query 7 output 1000 From 55b233ee78d059c17f7c552cd65bf4335977f229 Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Fri, 9 Aug 2019 12:43:40 +0800 Subject: [PATCH 5/9] Merge master --- .../resources/sql-tests/results/pgSQL/aggregates_part3.sql.out | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out index 76ffae10abc02..b2b1306bc4033 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out @@ -10,7 +10,6 @@ create temporary view varchar_tbl as select * from values ('2'), ('3'), (''), - -- ('cd'), ('c') as varchar_tbl(f1) -- !query 0 schema From 7fe3507ed16ead5ad92cf6caf86088afd14ec344 Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Sat, 10 Aug 2019 13:17:43 +0800 Subject: [PATCH 6/9] revert some change --- .../inputs/pgSQL/aggregates_part3.sql | 44 +++----- .../results/pgSQL/aggregates_part3.sql.out | 101 +----------------- 2 files changed, 18 insertions(+), 127 deletions(-) diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql index da5dd059b06f6..7cebbcd65f964 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql @@ -5,17 +5,6 @@ -- AGGREGATES [Part 3] -- https://github.com/postgres/postgres/blob/REL_12_BETA1/src/test/regress/sql/aggregates.sql#L352-L605 -create temporary view varchar_tbl as select * from values - ('a'), - ('A'), - ('1'), - ('2'), - ('3'), - (''), - -- ('cd'), - ('c') - as varchar_tbl(f1); - -- We do not support inheritance tree, skip related tests. -- try it on an inheritance tree -- create table minmaxtest(f1 int); @@ -207,16 +196,15 @@ create temporary view varchar_tbl as select * from values -- select aggfns(distinct a,a,c order by a,b) -- from (values (1,1,'foo')) v(a,b,c), generate_series(1,2) i; --- [SPARK-27978] We use concat_ws(delimiter, collect_list(expression)) to rewrite string_agg +-- [SPARK-27978] Add built-in Aggregate Functions: string_agg -- string_agg tests -select concat_ws(',', collect_list(a)) from (values('aaaa'),('bbbb'),('cccc')) g(a); -select concat_ws(',', collect_list(a)) from (values('aaaa'),(null),('bbbb'),('cccc')) g(a); -select concat_ws('AB', collect_list(a)) from (values(null),(null),('bbbb'),('cccc')) g(a); --- The result is different: collect_list returns an empty list, but string_agg results NULL -select concat_ws(',', collect_list(a)) from (values(null),(null)) g(a); +-- select string_agg(a,',') from (values('aaaa'),('bbbb'),('cccc')) g(a); +-- select string_agg(a,',') from (values('aaaa'),(null),('bbbb'),('cccc')) g(a); +-- select string_agg(a,'AB') from (values(null),(null),('bbbb'),('cccc')) g(a); +-- select string_agg(a,',') from (values(null),(null)) g(a); -- check some implicit casting cases, as per bug #5564 -select concat_ws(',', sort_array(array_distinct(collect_list(f1)))) from varchar_tbl; +-- select string_agg(distinct f1, ',' order by f1) from varchar_tbl; -- ok -- select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; -- not ok -- select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok -- select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok @@ -239,25 +227,23 @@ select concat_ws(',', sort_array(array_distinct(collect_list(f1)))) from varchar -- drop table bytea_test_table; --- [SPARK-27986] Support Aggregate Expressions +-- [SPARK-27986] Support Aggregate Expressions with filter -- FILTER tests -select min(CASE WHEN unique1> 100 THEN unique1 END) from tenk1; +-- select min(unique1) filter (where unique1 > 100) from tenk1; --- The result is different: we added cast here because [SPARK-2659] -select sum(CASE WHEN ten > 0 THEN cast(1/ten as integer) END) from tenk1; +-- select sum(1/ten) filter (where ten > 0) from tenk1; --- [SPARK-27987] Support POSIX Regular Expressions -- select ten, sum(distinct four) filter (where four::text ~ '123') from onek a -- group by ten; -select ten, sum(distinct CASE WHEN four > 10 THEN four END) from onek a -group by ten -having exists (select 1 from onek b where sum(distinct a.four) = b.four); +-- select ten, sum(distinct four) filter (where four > 10) from onek a +-- group by ten +-- having exists (select 1 from onek b where sum(distinct a.four) = b.four); --- Rewrite this SQL by removing COLLATE -select max(CASE WHEN bar > '0' THEN foo END) -from (values ('a', 'b')) AS v(foo,bar); +-- [SPARK-28682] ANSI SQL: Collation Support +-- select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') +-- from (values ('a', 'b')) AS v(foo,bar); -- outer reference in FILTER (PostgreSQL extension) select (select count(*) diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out index b2b1306bc4033..3ac1f5f848a4b 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out @@ -1,108 +1,13 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 11 +-- Number of queries: 1 -- !query 0 -create temporary view varchar_tbl as select * from values - ('a'), - ('A'), - ('1'), - ('2'), - ('3'), - (''), - ('c') - as varchar_tbl(f1) --- !query 0 schema -struct<> --- !query 0 output - - - --- !query 1 -select concat_ws(',', collect_list(a)) from (values('aaaa'),('bbbb'),('cccc')) g(a) --- !query 1 schema -struct --- !query 1 output -aaaa,bbbb,cccc - - --- !query 2 -select concat_ws(',', collect_list(a)) from (values('aaaa'),(null),('bbbb'),('cccc')) g(a) --- !query 2 schema -struct --- !query 2 output -aaaa,bbbb,cccc - - --- !query 3 -select concat_ws('AB', collect_list(a)) from (values(null),(null),('bbbb'),('cccc')) g(a) --- !query 3 schema -struct --- !query 3 output -bbbbABcccc - - --- !query 4 -select concat_ws(',', collect_list(a)) from (values(null),(null)) g(a) --- !query 4 schema -struct --- !query 4 output - - - --- !query 5 -select concat_ws(',', sort_array(array_distinct(collect_list(f1)))) from varchar_tbl --- !query 5 schema -struct --- !query 5 output -,1,2,3,A,a,c - - --- !query 6 -select min(CASE WHEN unique1> 100 THEN unique1 END) from tenk1 --- !query 6 schema -struct 100) THEN unique1 END):int> --- !query 6 output -101 - - --- !query 7 -select sum(CASE WHEN ten > 0 THEN cast(1/ten as integer) END) from tenk1 --- !query 7 schema -struct 0) THEN CAST((1 div ten) AS INT) END):bigint> --- !query 7 output -1000 - - --- !query 8 -select ten, sum(distinct CASE WHEN four > 10 THEN four END) from onek a -group by ten -having exists (select 1 from onek b where sum(distinct a.four) = b.four) --- !query 8 schema -struct 10) THEN four END):bigint> --- !query 8 output -0 NULL -2 NULL -4 NULL -6 NULL -8 NULL - - --- !query 9 -select max(CASE WHEN bar > '0' THEN foo END) -from (values ('a', 'b')) AS v(foo,bar) --- !query 9 schema -struct 0) THEN foo END):string> --- !query 9 output -a - - --- !query 10 select (select count(*) from (values (1)) t0(inner_c)) from (values (2),(3)) t1(outer_c) --- !query 10 schema +-- !query 0 schema struct --- !query 10 output +-- !query 0 output 1 1 From a2e9e5749cadd658950f33d8c8606f3800bb70f8 Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Sat, 17 Aug 2019 11:18:28 +0800 Subject: [PATCH 7/9] Address comment --- .../inputs/pgSQL/aggregates_part3.sql | 18 ++++++--------- .../results/pgSQL/aggregates_part3.sql.out | 23 ++++++++++++++++--- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql index 7cebbcd65f964..ed8671c6b3587 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql @@ -3,7 +3,7 @@ -- -- -- AGGREGATES [Part 3] --- https://github.com/postgres/postgres/blob/REL_12_BETA1/src/test/regress/sql/aggregates.sql#L352-L605 +-- https://github.com/postgres/postgres/blob/REL_12_BETA2/src/test/regress/sql/aggregates.sql#L352-L605 -- We do not support inheritance tree, skip related tests. -- try it on an inheritance tree @@ -32,9 +32,8 @@ -- drop table minmaxtest cascade; --- [SPARK-9830] It is not allowed to use an aggregate function in the argument of another aggregate function -- check for correct detection of nested-aggregate errors --- select max(min(unique1)) from tenk1; +select max(min(unique1)) from tenk1; -- select (select max(min(unique1)) from int8_tbl) from tenk1; -- These tests only test the explain. Skip these tests. @@ -211,10 +210,10 @@ -- Skip these tests because we do not have a bytea type -- string_agg bytea tests --- create table bytea_test_table(v bytea); +CREATE TABLE bytea_test_table(v BINARY) USING parquet; -- select string_agg(v, '') from bytea_test_table; - +-- [SPARK-28121] decode can not accept 'hex' as charset -- insert into bytea_test_table values(decode('ff','hex')); -- select string_agg(v, '') from bytea_test_table; @@ -248,22 +247,19 @@ -- outer reference in FILTER (PostgreSQL extension) select (select count(*) from (values (1)) t0(inner_c)) -from (values (2),(3)) t1(outer_c); --- Rewriting to CASE WHEN will hit: Expressions referencing the outer query are not supported outside of WHERE/HAVING clauses +from (values (2),(3)) t1(outer_c); -- inner query is aggregation query -- select (select count(*) filter (where outer_c <> 0) -- from (values (1)) t0(inner_c)) --- from (values (2),(3)) t1(outer_c); --- Rewriting to CASE WHEN will hit: Found an aggregate expression in a correlated predicate that has both outer and local references +-- from (values (2),(3)) t1(outer_c); -- outer query is aggregation query -- select (select count(inner_c) filter (where outer_c <> 0) -- from (values (1)) t0(inner_c)) -- from (values (2),(3)) t1(outer_c); -- inner query is aggregation query --- Can not rewrite this pattern: aggregate_name(sub-query) filter() -- select -- (select max((select i.unique2 from tenk1 i where i.unique1 = o.unique1)) -- filter (where o.unique1 < 10)) -- from tenk1 o; -- outer query is aggregation query + -- subquery in FILTER clause (PostgreSQL extension) --- Rewriting to CASE WHEN will hit: IN/EXISTS predicate sub-queries can only be used in a Filter -- select sum(unique1) FILTER (WHERE -- unique1 IN (SELECT unique1 FROM onek where unique1 < 100)) FROM tenk1; diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out index 3ac1f5f848a4b..d05b08ffda212 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out @@ -1,13 +1,30 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 1 +-- Number of queries: 3 -- !query 0 +select max(min(unique1)) from tenk1 +-- !query 0 schema +struct<> +-- !query 0 output +org.apache.spark.sql.AnalysisException +It is not allowed to use an aggregate function in the argument of another aggregate function. Please use the inner aggregate function in a sub-query.; + + +-- !query 1 +CREATE TABLE bytea_test_table(v BINARY) USING parquet +-- !query 1 schema +struct<> +-- !query 1 output + + + +-- !query 2 select (select count(*) from (values (1)) t0(inner_c)) from (values (2),(3)) t1(outer_c) --- !query 0 schema +-- !query 2 schema struct --- !query 0 output +-- !query 2 output 1 1 From ad5363b0f02ff7bce73a7bbff31f171bb3bb2192 Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Sun, 18 Aug 2019 20:21:41 +0800 Subject: [PATCH 8/9] fix --- .../sql-tests/inputs/pgSQL/aggregates_part3.sql | 7 ++++--- .../results/pgSQL/aggregates_part3.sql.out | 14 +++----------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql index ed8671c6b3587..5798f91576b5c 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql @@ -115,6 +115,7 @@ select max(min(unique1)) from tenk1; -- test specific code paths +-- [SPARK-28768] Implement more text pattern operators -- select aggfns(distinct a,a,c order by c using ~<~,a) -- from (values (1,3,'foo'),(0,null,null),(2,2,'bar'),(3,1,'baz')) v(a,b,c), -- generate_series(1,2) i; @@ -208,12 +209,12 @@ select max(min(unique1)) from tenk1; -- select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok -- select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok --- Skip these tests because we do not have a bytea type +-- [SPARK-28121] decode can not accept 'hex' as charset -- string_agg bytea tests -CREATE TABLE bytea_test_table(v BINARY) USING parquet; +-- CREATE TABLE bytea_test_table(v BINARY) USING parquet; -- select string_agg(v, '') from bytea_test_table; --- [SPARK-28121] decode can not accept 'hex' as charset + -- insert into bytea_test_table values(decode('ff','hex')); -- select string_agg(v, '') from bytea_test_table; diff --git a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out index d05b08ffda212..f102383cb4d8f 100644 --- a/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out +++ b/sql/core/src/test/resources/sql-tests/results/pgSQL/aggregates_part3.sql.out @@ -1,5 +1,5 @@ -- Automatically generated by SQLQueryTestSuite --- Number of queries: 3 +-- Number of queries: 2 -- !query 0 @@ -12,19 +12,11 @@ It is not allowed to use an aggregate function in the argument of another aggreg -- !query 1 -CREATE TABLE bytea_test_table(v BINARY) USING parquet --- !query 1 schema -struct<> --- !query 1 output - - - --- !query 2 select (select count(*) from (values (1)) t0(inner_c)) from (values (2),(3)) t1(outer_c) --- !query 2 schema +-- !query 1 schema struct --- !query 2 output +-- !query 1 output 1 1 From 33650461aa18b66f5d69c032113efd264ebb4bea Mon Sep 17 00:00:00 2001 From: Yuming Wang Date: Sun, 25 Aug 2019 17:59:58 +0800 Subject: [PATCH 9/9] fix --- .../resources/sql-tests/inputs/pgSQL/aggregates_part3.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql index 5798f91576b5c..78fdbf6ae6cd2 100644 --- a/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql +++ b/sql/core/src/test/resources/sql-tests/inputs/pgSQL/aggregates_part3.sql @@ -5,7 +5,7 @@ -- AGGREGATES [Part 3] -- https://github.com/postgres/postgres/blob/REL_12_BETA2/src/test/regress/sql/aggregates.sql#L352-L605 --- We do not support inheritance tree, skip related tests. +-- [SPARK-28865] Table inheritance -- try it on an inheritance tree -- create table minmaxtest(f1 int); -- create table minmaxtest1() inherits (minmaxtest); @@ -91,7 +91,7 @@ select max(min(unique1)) from tenk1; -- select array_agg(distinct a order by a desc nulls last) -- from (values (1),(2),(1),(3),(null),(2)) v(a); --- Skip the test below because it requires 4 UDFs: aggf_trans, aggfns_trans, aggfstr, and aggfns +-- Skip the test below because it requires 4 UDAFs: aggf_trans, aggfns_trans, aggfstr, and aggfns -- multi-arg aggs, strict/nonstrict, distinct/order by -- select aggfstr(a,b,c)