should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,115 @@
# name: test/sql/function/list/aggregates/any_value.test
# description: Test the list_any_value aggregate function
# group: [aggregates]
query I
SELECT list_aggr([NULL, 1, 2], 'any_value')
----
1
# incorrect usage
statement error
SELECT list_any_value()
----
# different types
# numerics
foreach type <numeric>
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_any_value(i) FROM five
----
1
NULL
NULL
NULL
1
statement ok
DROP TABLE five
endloop
# temporal
statement ok
CREATE TABLE five_dates AS
SELECT
LIST(NULLIF(i,0)::integer) AS i,
LIST('2021-08-20'::DATE + NULLIF(i,0)::INTEGER) AS d,
LIST('2021-08-20'::TIMESTAMP + INTERVAL (NULLIF(i,0)) HOUR) AS dt,
LIST('14:59:37'::TIME + INTERVAL (NULLIF(i,0)) MINUTE) AS t,
LIST(INTERVAL (NULLIF(i,0)) SECOND) AS s
FROM range(0, 6, 1) t1(i)
query IIII
SELECT list_any_value(d), list_any_value(dt), list_any_value(t), list_any_value(s) FROM five_dates
----
2021-08-21 2021-08-20 01:00:00 15:00:37 00:00:01
statement ok
DROP TABLE five_dates
# with time zone
statement ok
CREATE TABLE five_dates_tz AS
SELECT
LIST(('2021-08-20'::TIMESTAMP + INTERVAL (NULLIF(i,0)) HOUR)::TIMESTAMPTZ) AS dt,
LIST(('14:59:37'::TIME + INTERVAL (NULLIF(i,0)) MINUTE)::TIMETZ) AS t,
FROM range(0, 6, 1) t1(i)
query II
SELECT list_any_value(dt), list_any_value(t) FROM five_dates_tz
----
2021-08-20 01:00:00+00 15:00:37+00
statement ok
DROP TABLE five_dates_tz
# complex types
statement ok
CREATE TABLE five_complex AS
SELECT
LIST(NULLIF(i,0)::integer) AS i,
LIST(NULLIF(i,0)::VARCHAR) AS s,
LIST([NULLIF(i,0)]) AS l,
LIST({'a': NULLIF(i,0)}) AS r
FROM range(0, 6, 1) t1(i)
query III
SELECT list_any_value(s), list_any_value(l), list_any_value(r)
FROM five_complex
----
1 [NULL] {'a': NULL}
statement ok
DROP TABLE five_complex
# decimals
foreach type decimal(4,1) decimal(8,1) decimal(12,1) decimal(18,1)
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_any_value(i) FROM five
----
1.0
NULL
NULL
NULL
1.0
statement ok
DROP TABLE five
endloop

View File

@@ -0,0 +1,98 @@
# name: test/sql/function/list/aggregates/approx_count_distinct.test
# description: Test the list_approx_count_distinct aggregate function
# group: [aggregates]
statement ok
CREATE TABLE list_ints (l INTEGER[]);
statement ok
INSERT INTO list_ints SELECT LIST(i) FROM range(100) tbl(i);
query II
select list_approx_count_distinct([10]), list_approx_count_distinct(['hello']) from list_ints;
----
1 1
query II
select list_approx_count_distinct(l), list_approx_count_distinct(['hello']) from list_ints;
----
98 1
query I
select list_approx_count_distinct([]) from list_ints;
----
0
statement ok
INSERT INTO list_ints VALUES ([]), (NULL), ([NULL]);
query I
select list_approx_count_distinct(l) from list_ints;
----
98
0
NULL
0
# dates
statement ok
CREATE TABLE IF NOT EXISTS dates (t date[]);
statement ok
INSERT INTO dates VALUES (['2008-01-01', NULL, '2007-01-01', '2008-02-01', '2008-01-02', '2008-01-01', '2008-01-01', '2008-01-01'])
query II
SELECT list_count(t), list_approx_count_distinct(t) from dates
----
7 4
# timestamps
statement ok
CREATE TABLE IF NOT EXISTS timestamp (t TIMESTAMP[]);
statement ok
INSERT INTO timestamp VALUES (['2008-01-01 00:00:01', NULL, '2007-01-01 00:00:01', '2008-02-01 00:00:01', '2008-01-02 00:00:01', '2008-01-01 10:00:00', '2008-01-01 00:10:00', '2008-01-01 00:00:10'])
query II
SELECT list_count(t), list_approx_count_distinct(t) from timestamp
----
7 6
# strings
statement ok
CREATE TABLE IF NOT EXISTS names (t string[]);
statement ok
INSERT INTO names VALUES (['Pedro', NULL, 'Pedro', 'Pedro', 'Mark', 'Mark', 'Mark', 'Hannes-Muehleisen', 'Hannes-Muehleisen'])
query II
SELECT list_count(t), list_approx_count_distinct(t) from names
----
8 3
# test approximate count on different (long) lists
statement ok
CREATE TABLE list_ints_2 (a INTEGER[], b INTEGER[]);
statement ok
INSERT INTO list_ints_2 SELECT LIST(a), LIST(mod(a, 10)) FROM range(2000) tbl(a);
query III
SELECT list_count(a), list_approx_count_distinct(a), list_approx_count_distinct(b) from list_ints_2
----
2000 2322 11
statement ok
DELETE FROM list_ints_2
statement ok
INSERT INTO list_ints_2 SELECT LIST(a), NULL FROM range(2000) tbl(a, b) WHERE a % 2 = 0;
statement ok
INSERT INTO list_ints_2 SELECT LIST(a), NULL FROM range(2000) tbl(a, b) WHERE a % 2 = 1;
query I
SELECT list_approx_count_distinct(a) from list_ints_2;
----
1006
1230

View File

@@ -0,0 +1,81 @@
# name: test/sql/function/list/aggregates/avg.test
# description: Test the list_avg aggregate function
# group: [aggregates]
# list_avg on a sequence
statement ok
CREATE SEQUENCE seq;
query I
SELECT list_avg([nextval('seq')]);
----
1
query I
SELECT list_avg([nextval('seq')]);
----
2
# multiple list entries
statement ok
CREATE TABLE integers(i INTEGER[]);
statement ok
INSERT INTO integers VALUES ([1, 2, 3]), ([6, 3, 2, 5]), ([]), ([NULL]), (NULL), ([1, NULL, 2, 3]);
query I
SELECT list_avg(i) FROM integers;
----
2
4
NULL
NULL
NULL
2
# incorrect use
statement error
SELECT list_avg()
----
# NULL average
statement ok
CREATE TABLE vals(i INTEGER[], j HUGEINT[]);
statement ok
INSERT INTO vals VALUES ([NULL, NULL], [NULL, NULL, NULL])
query II
SELECT list_avg(i), list_avg(j) FROM vals;
----
NULL NULL
# test list_avg on integers with no exact float64 representation
statement ok
CREATE TABLE bigints(n HUGEINT[]);
statement ok
INSERT INTO bigints (n) VALUES (['9007199254740992'::HUGEINT, 1::HUGEINT, 0::HUGEINT]);
# this would give the wrong result with 'double' precision
require longdouble
query R
SELECT list_avg(n)::DOUBLE - '3002399751580331'::DOUBLE FROM bigints;
----
0
# test list_avg in which the intermediate sums are not exact (favg)
statement ok
CREATE TABLE doubles(n DOUBLE[]);
statement ok
INSERT INTO doubles (n) VALUES (['9007199254740992'::DOUBLE, 1::DOUBLE, 1::DOUBLE, 0::DOUBLE]);
# this would give the wrong result with a simple sum-and-divide
query R
SELECT list_aggr(n, 'favg') - '2251799813685248.5'::DOUBLE FROM doubles;
----
0

View File

@@ -0,0 +1,117 @@
# name: test/sql/function/list/aggregates/bigints_sum_avg.test
# description: Test list_sum and list_avg with bigints
# group: [aggregates]
statement ok
CREATE TABLE bigints (i BIGINT[]);
statement ok
INSERT INTO bigints VALUES ([1, 2, 3]);
# sum
query I
SELECT list_sum(i) FROM bigints;
----
6
# avg
query I
SELECT list_avg(i) FROM bigints;
----
2
statement ok
DELETE FROM bigints;
# sum no longer fits in int64
statement ok
INSERT INTO bigints VALUES ([1, 2, 3, 9223372036854775806]);
# sum
query I
SELECT list_sum(i) FROM bigints;
----
9223372036854775812
# avg
query I
SELECT list_avg(i) FROM bigints;
----
2305843009213693952
statement ok
DELETE FROM bigints;
statement ok
INSERT INTO bigints VALUES ([-1, -2, -3]);
# sum
query I
SELECT list_sum(i) FROM bigints;
----
-6
# avg
query I
SELECT list_avg(i) FROM bigints;
----
-2
statement ok
DELETE FROM bigints;
# sum no longer fits in int64 [negative]
statement ok
INSERT INTO bigints VALUES ([-1, -2, -3, -9223372036854775806]);
# sum
query I
SELECT list_sum(i) FROM bigints;
----
-9223372036854775812
# avg
query I
SELECT list_avg(i) FROM bigints;
----
-2305843009213693952
# now with decimals
statement ok
CREATE TABLE decimals (i DECIMAL(18,1)[]);
statement ok
INSERT INTO decimals VALUES ([1, 2, 3]);
# sum
query I
SELECT list_sum(i) FROM decimals;
----
6.0
# avg
query I
SELECT list_avg(i) FROM decimals;
----
2.0
statement ok
DELETE FROM decimals;
# sum no longer fits in int64
statement ok
INSERT INTO decimals VALUES ([99999999999999999.9, 99999999999999999.9, 99999999999999999.9,
99999999999999999.9, 99999999999999999.9, 99999999999999999.9, 99999999999999999.9,
99999999999999999.9, 99999999999999999.9, 99999999999999999.9, 1.0, 2.0, 3.0]);
# sum
query I
SELECT list_sum(i) FROM decimals;
----
1000000000000000005.0
query I
SELECT list_avg(i) FROM decimals;
----
76923076923076923

View File

@@ -0,0 +1,48 @@
# name: test/sql/function/list/aggregates/bit_and.test
# description: Test the list_bit_and aggregate function
# group: [aggregates]
# bit_and on a sequence
statement ok
CREATE SEQUENCE seq;
query I
SELECT list_bit_and([nextval('seq')])
----
1
query I
SELECT list_bit_and([nextval('seq')])
----
2
# list of integers
statement ok
CREATE TABLE integers(i INTEGER[]);
statement ok
INSERT INTO integers VALUES ([3, 7, 15, 31, 3, 15]);
# empty list
query I
SELECT list_bit_and([]) FROM integers
----
NULL
statement ok
INSERT INTO integers VALUES ([]), (NULL), ([NULL]), ([3, 7, NULL, 15, 31, 3, 15, NULL]);
query III
SELECT list_bit_and(i), list_bit_and([1, 1, 1, 1, 1, 1]), list_bit_and(NULL) FROM integers
----
3 1 NULL
NULL 1 NULL
NULL 1 NULL
NULL 1 NULL
3 1 NULL
# incorrect usage
statement error
SELECT list_bit_and()
----
<REGEX>:.*Binder Error.*does not support the supplied arguments.*

View File

@@ -0,0 +1,48 @@
# name: test/sql/function/list/aggregates/bit_or.test
# description: Test the list_bit_or aggregate function
# group: [aggregates]
# bit_or on a sequence
statement ok
CREATE SEQUENCE seq;
query I
SELECT list_bit_or([nextval('seq')])
----
1
query I
SELECT list_bit_or([nextval('seq')])
----
2
# list of integers
statement ok
CREATE TABLE integers(i INTEGER[]);
statement ok
INSERT INTO integers VALUES ([3, 7, 15, 31, 3, 15])
# empty list
query I
SELECT list_bit_or([]) FROM integers
----
NULL
statement ok
INSERT INTO integers VALUES ([]), (NULL), ([NULL]), ([3, 7, NULL, 15, 31, 3, 15, NULL]);
query III
SELECT list_bit_or(i), list_bit_or([1, 1, 1, 1, 1, 1]), list_bit_or(NULL) FROM integers
----
31 1 NULL
NULL 1 NULL
NULL 1 NULL
NULL 1 NULL
31 1 NULL
# incorrect usage
statement error
SELECT list_bit_or()
----
<REGEX>:.*Binder Error.*does not support the supplied arguments.*

View File

@@ -0,0 +1,48 @@
# name: test/sql/function/list/aggregates/bit_xor.test
# description: Test the list_bit_xor aggregate function
# group: [aggregates]
# bit_xor on a sequence
statement ok
CREATE SEQUENCE seq;
query I
SELECT list_bit_xor([nextval('seq')])
----
1
query I
SELECT list_bit_xor([nextval('seq')])
----
2
# list of integers
statement ok
CREATE TABLE integers (i INTEGER[]);
statement ok
INSERT INTO integers VALUES ([3, 7, 15, 31, 3, 15]);
# empty list
query I
SELECT list_bit_xor([]) FROM integers
----
NULL
statement ok
INSERT INTO integers VALUES ([]), (NULL), ([NULL]), ([3, 7, NULL, 15, 31, 3, 15, NULL]);
query III
SELECT list_bit_xor(i), list_bit_xor([1, 1, 1, 1, 1, 1]), list_bit_xor(NULL) FROM integers
----
24 0 NULL
NULL 0 NULL
NULL 0 NULL
NULL 0 NULL
24 0 NULL
# incorrect usage
statement error
SELECT list_bit_xor()
----
<REGEX>:.*Binder Error.*does not support the supplied arguments.*

View File

@@ -0,0 +1,50 @@
# name: test/sql/function/list/aggregates/bool_and_or.test
# description: Test the list_bool_and, list_bool_or aggregate functions
# group: [aggregates]
# incorrect usage
statement error
select list_bool_or()
----
statement error
select list_bool_and()
----
# list of booleans
statement ok
CREATE TABLE bools (l BOOLEAN[]);
statement ok
INSERT INTO bools SELECT LIST(True) FROM range(100) tbl(i);
statement ok
INSERT INTO bools SELECT LIST(False) FROM range(100) tbl(i);
statement ok
INSERT INTO bools VALUES ([True, False]);
statement ok
INSERT INTO bools VALUES ([]), ([NULL]), (NULL), ([NULL, True, False, NULL]);
query I
SELECT list_bool_or(l) FROM bools;
----
1
0
1
NULL
NULL
NULL
1
query I
SELECT list_bool_and(l) FROM bools;
----
1
0
0
NULL
NULL
NULL
0

View File

@@ -0,0 +1,37 @@
# name: test/sql/function/list/aggregates/count.test
# description: Test the list_count aggregate function
# group: [aggregates]
query I
SELECT list_count([1, 2, 3])
----
3
query I
SELECT list_count([1]) FROM range(3)
----
1
1
1
statement ok
CREATE TABLE lists (l INTEGER[]);
statement ok
INSERT INTO lists VALUES ([1, 2]), ([NULL]), (NULL), ([]), ([3, 4, 5, 6, 7]), ([1, 2, NULL, 1, NULL]);
query I
SELECT list_count(l) FROM lists
----
2
0
NULL
0
5
3
# incorrect usage
statement error
select list_count()
----
<REGEX>:.*Binder Error.*does not support the supplied arguments.*

View File

@@ -0,0 +1,68 @@
# name: test/sql/function/list/aggregates/entropy.test
# description: Test the list_entropy aggregate function
# group: [aggregates]
# incorrect usage
statement error
select list_entropy()
----
query I
select list_entropy([1])
----
0
statement ok
create table aggr(k int[]);
statement ok
insert into aggr values ([0, 1, 1, 1, 4, 0, 3, 3, 2, 2, 4, 4, 2, 4, 0, 0, 0, 1, 2, 3, 4, 2, 3, 3, 1]);
statement ok
insert into aggr values ([]), ([NULL]), (NULL), ([0, 1, 1, 1, 4, NULL, 0, 3, 3, 2, NULL, 2, 4, 4, 2, 4, 0, 0, 0, 1, NULL, 2, 3, 4, 2, 3, 3, 1]);
query I
select list_entropy(k) from aggr;
----
2.321928
0
0
NULL
2.321928
statement ok
CREATE TABLE entr (l INTEGER[]);
statement ok
INSERT INTO entr SELECT LIST(2) FROM range(100) tbl(i);
query I
SELECT list_entropy(l) FROM entr;
----
0
statement ok
create table aggr2 (k int[]);
statement ok
INSERT INTO aggr2 VALUES ([0, 4, 0, 2, 2, 4, 4, 2, 4, 0, 0, 0, 2, 4, 2]);
statement ok
INSERT INTO aggr2 VALUES ([1, 1, 1, 3, 3, 1, 3, 3, 3, 1]);
query I
select list_entropy(k) from aggr2
----
1.584963
1.000000
statement ok
create table names (name string[])
statement ok
insert into names values (['pedro', 'pedro', 'pedro', 'hannes', 'hannes', 'mark', null]);
query I
select list_entropy(name) from names;
----
1.459148

View File

@@ -0,0 +1,115 @@
# name: test/sql/function/list/aggregates/first.test
# description: Test the list_first aggregate function
# group: [aggregates]
query I
SELECT list_aggr([1, 2], 'arbitrary')
----
1
# incorrect usage
statement error
SELECT list_first()
----
# different types
# numerics
foreach type <numeric>
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_first(i) FROM five
----
1
NULL
NULL
NULL
NULL
statement ok
DROP TABLE five
endloop
# temporal
statement ok
CREATE TABLE five_dates AS
SELECT
LIST(i::integer) AS i,
LIST('2021-08-20'::DATE + i::INTEGER) AS d,
LIST('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR) AS dt,
LIST('14:59:37'::TIME + INTERVAL (i) MINUTE) AS t,
LIST(INTERVAL (i) SECOND) AS s
FROM range(1, 6, 1) t1(i)
query IIII
SELECT list_first(d), list_first(dt), list_first(t), list_first(s) FROM five_dates
----
2021-08-21 2021-08-20 01:00:00 15:00:37 00:00:01
statement ok
DROP TABLE five_dates
# with time zone
statement ok
CREATE TABLE five_dates_tz AS
SELECT
LIST(('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR)::TIMESTAMPTZ) AS dt,
LIST(('14:59:37'::TIME + INTERVAL (i) MINUTE)::TIMETZ) AS t,
FROM range(1, 6, 1) t1(i)
query II
SELECT list_first(dt), list_first(t) FROM five_dates_tz
----
2021-08-20 01:00:00+00 15:00:37+00
statement ok
DROP TABLE five_dates_tz
# complex types
statement ok
CREATE TABLE five_complex AS
SELECT
LIST(i::integer) AS i,
LIST(i::VARCHAR) AS s,
LIST([i]) AS l,
LIST({'a': i}) AS r
FROM range(1, 6, 1) t1(i)
query III
SELECT list_first(s), list_first(l), list_first(r)
FROM five_complex
----
1 [1] {'a': 1}
statement ok
DROP TABLE five_complex
# decimals
foreach type decimal(4,1) decimal(8,1) decimal(12,1) decimal(18,1)
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_first(i) FROM five
----
1.0
NULL
NULL
NULL
NULL
statement ok
DROP TABLE five
endloop

View File

@@ -0,0 +1,105 @@
# name: test/sql/function/list/aggregates/histogram.test
# description: Test list_histogram aggregate function
# group: [aggregates]
statement ok
CREATE TABLE const AS SELECT LIST(2) AS i FROM range(200) t1(i)
query I
SELECT list_histogram(i) FROM const
----
{2=200}
query I
select list_histogram([1])
----
{1=1}
# integers
statement ok
CREATE TABLE hist_data (g INTEGER[])
statement ok
INSERT INTO hist_data VALUES ([1, 1, 2, 2, 2, 3, 5]), ([1, 2, 3, 4, 5, 6, NULL]), ([]), (NULL), ([NULL]);
query T
SELECT list_histogram(g) from hist_data
----
{1=2, 2=3, 3=1, 5=1}
{1=1, 2=1, 3=1, 4=1, 5=1, 6=1}
NULL
NULL
NULL
# strings
statement ok
create table names (name string[])
statement ok
insert into names values (['pedro', 'pedro', 'pedro', 'hannes', 'hannes', 'mark', NULL, 'Hubert Blaine Wolfeschlegelsteinhausenbergerdorff Sr.']);
query I
select list_histogram(name) from names;
----
{Hubert Blaine Wolfeschlegelsteinhausenbergerdorff Sr.=1, hannes=2, mark=1, pedro=3}
# incorrect usage
statement error
select list_histogram()
----
# temporal types
# timestamp
query I
SELECT list_histogram(['2021-08-20'::TIMESTAMP])
----
{'2021-08-20 00:00:00'=1}
# timestamp_s
query I
SELECT list_histogram(['2021-08-20'::TIMESTAMP_S])
----
{'2021-08-20 00:00:00'=1}
# timestamp_ms
query I
SELECT list_histogram(['2021-08-20'::TIMESTAMP_MS])
----
{'2021-08-20 00:00:00'=1}
# timestamp_ns
query I
SELECT list_histogram(['2021-08-20'::TIMESTAMP_NS])
----
{'2021-08-20 00:00:00'=1}
# timestamp with time zone
query I
SELECT list_histogram(['2021-08-20'::TIMESTAMPTZ])
----
{'2021-08-20 00:00:00+00'=1}
# date
query I
SELECT list_histogram(['2022-01-02'::DATE])
----
{2022-01-02=1}
# time
query I
SELECT list_histogram(['15:00:07'::TIME])
----
{'15:00:07'=1}
# timetz
query I
SELECT list_histogram(['15:00:07'::TIMETZ])
----
{'15:00:07+00'=1}
# interval
query I
SELECT list_histogram([INTERVAL 1 YEAR])
----
{1 year=1}

View File

@@ -0,0 +1,20 @@
# name: test/sql/function/list/aggregates/histogram_decimal.test
# description: Test histogram for decimals
# group: [aggregates]
statement ok
PRAGMA enable_verification
query II
WITH cte AS (FROM (VALUES (0.0), (9.9)) df(l_orderkey)) SELECT * FROM histogram_values(cte, l_orderkey)
----
1.0 1
2.0 0
3.0 0
4.0 0
5.0 0
6.0 0
7.0 0
8.0 0
9.0 0
10.0 1

View File

@@ -0,0 +1,29 @@
# name: test/sql/function/list/aggregates/hugeint.test
# description: Test hugeint aggregates
# group: [aggregates]
statement ok
CREATE TABLE hugeints(h HUGEINT[])
statement ok
INSERT INTO hugeints VALUES ([NULL, 1, 2]), (NULL), ([]), ([NULL]), ([1, 2, 3])
query III
SELECT list_first(h), list_last(h), list_sum(h) FROM hugeints
----
NULL 2 3
NULL NULL NULL
NULL NULL NULL
NULL NULL NULL
1 3 6
statement ok
DELETE FROM hugeints
statement ok
INSERT INTO hugeints VALUES ([42.0, 1267650600228229401496703205376, -439847238974238975238975, '-12']);
query IIIII
SELECT list_min(h), list_max(h), list_sum(h), list_first(h), list_last(h) FROM hugeints;
----
-439847238974238975238975 1267650600228229401496703205376 1267650160380990427257727966431 42 -12

View File

@@ -0,0 +1,143 @@
# name: test/sql/function/list/aggregates/incorrect.test
# description: Test incorrect and incompatible aggregate functions for lists
# group: [aggregates]
# incorrect syntax
statement error
SELECT list_aggr([1], 2)
----
statement error
SELECT list_aggr([1], True)
----
statement error
SELECT list_aggr([1], NULL)
----
foreach func_name approx_count_distinct avg favg bit_and bit_or bit_xor bool_and bool_or count entropy first arbitrary histogram kurtosis last mad max median min mode array_agg list product sem skewness string_agg group_concat sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
statement error
SELECT list_aggr('${func_name}')
----
statement error
SELECT list_aggr(*, '${func_name}')
----
statement error
SELECT list_aggr('hello', '${func_name}')
----
statement error
SELECT list_aggr(1, 2, '${func_name}')
----
foreach type boolean varchar tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint uhugeint float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10) date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz interval blob
statement error
SELECT list_aggr(NULL::${type}, '${func_name}')
----
endloop
endloop
# incompatible aggregate functions (more than one column)
statement error
SELECT list_aggr([1, 2, NULL], 'count_star');
----
statement error
SELECT list_aggr([1, 2, NULL], 'corr');
----
statement error
SELECT list_aggr([1, 2, NULL], 'covar_pop');
----
statement error
SELECT list_aggr([1, 2, NULL], 'covar_samp');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_intercept');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_sxy');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_sxx');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_syy');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_r2');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_slope');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_count');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_avgy');
----
statement error
SELECT list_aggr([1, 2, NULL], 'regr_avgx');
----
statement error
SELECT list_aggr([1, 2, NULL], 'reservoir_quantile');
----
statement error
SELECT list_aggr([1, 2, NULL], 'approx_quantile');
----
statement error
SELECT list_aggr([1, 2, NULL], 'quantile');
----
statement error
SELECT list_aggr([1, 2, NULL], 'quantile_cont');
----
statement error
SELECT list_aggr([1, 2, NULL], 'quantile_disc');
----
statement error
SELECT list_aggr([1, 2, NULL], 'arg_max');
----
statement error
SELECT list_aggr([1, 2, NULL], 'max_by');
----
statement error
SELECT list_aggr([1, 2, NULL], 'argmax');
----
statement error
SELECT list_aggr([1, 2, NULL], 'arg_min');
----
statement error
SELECT list_aggr([1, 2, NULL], 'min_by');
----
statement error
SELECT list_aggr([1, 2, NULL], 'argmin');
----

View File

@@ -0,0 +1,54 @@
# name: test/sql/function/list/aggregates/kurtosis.test
# description: Test the list_kurtosis aggregate function
# group: [aggregates]
query I
select list_kurtosis([1])
----
NULL
query I
select list_kurtosis([0, 0, 0, 0, 0, 0])
----
NULL
# out of range
statement error
select list_kurtosis([2e304, 2e305, 2e306, 2e307])
----
<REGEX>:.*Out of Range Error.*out of range.*
statement ok
create table aggr(k int[]);
statement ok
insert into aggr values ([1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]),
([10, 10, 10, 10, 20, 20, 25, 30, 30, 30, 30]),
([NULL, 11, 15, 18, 22, 25, NULL, 35, 40, 50, 51]),
(NULL), ([]), ([NULL]);
query I
select list_kurtosis(k) from aggr;
----
11.000000
-1.961428
-1.445120
NULL
NULL
NULL
query I
select list_kurtosis_pop(k) from aggr;
----
6.100000
-1.676857
-1.358688
NULL
NULL
NULL
# incorrect usage
statement error
select list_kurtosis()
----
<REGEX>:.*Binder Error.*does not support the supplied arguments.*

View File

@@ -0,0 +1,110 @@
# name: test/sql/function/list/aggregates/last.test
# description: Test the list_last aggregate function
# group: [aggregates]
# incorrect usage
statement error
SELECT list_last()
----
# different types
# numerics
foreach type <numeric>
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([1, 2, NULL])
query I
SELECT list_last(i) FROM five
----
5
NULL
NULL
NULL
NULL
statement ok
DROP TABLE five
endloop
# temporal
statement ok
CREATE TABLE five_dates AS
SELECT
LIST(i::integer) AS i,
LIST('2021-08-20'::DATE + i::INTEGER) AS d,
LIST('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR) AS dt,
LIST('14:59:37'::TIME + INTERVAL (i) MINUTE) AS t,
LIST(INTERVAL (i) SECOND) AS s
FROM range(1, 6, 1) t1(i)
query IIII
SELECT list_last(d), list_last(dt), list_last(t), list_last(s) FROM five_dates
----
2021-08-25 2021-08-20 05:00:00 15:04:37 00:00:05
statement ok
DROP TABLE five_dates
# with time zone
statement ok
CREATE TABLE five_dates_tz AS
SELECT
LIST(('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR)::TIMESTAMPTZ) AS dt,
LIST(('14:59:37'::TIME + INTERVAL (i) MINUTE)::TIMETZ) AS t,
FROM range(1, 6, 1) t1(i)
query II
SELECT list_last(dt), list_last(t) FROM five_dates_tz
----
2021-08-20 05:00:00+00 15:04:37+00
statement ok
DROP TABLE five_dates_tz
# complex types
statement ok
CREATE TABLE five_complex AS
SELECT
LIST(i::integer) AS i,
LIST(i::VARCHAR) AS s,
LIST([i]) AS l,
LIST({'a': i}) AS r
FROM range(1, 6, 1) t1(i)
query III
SELECT list_last(s), list_last(l), list_last(r)
FROM five_complex
----
5 [5] {'a': 5}
statement ok
DROP TABLE five_complex
# decimals
foreach type decimal(4,1) decimal(8,1) decimal(12,1) decimal(18,1)
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([1, 2, NULL])
query I
SELECT list_last(i) FROM five
----
5.0
NULL
NULL
NULL
NULL
statement ok
DROP TABLE five
endloop

View File

@@ -0,0 +1,130 @@
# name: test/sql/function/list/aggregates/mad.test
# description: Test list_mad (Moving Absolute Deviation) aggregate
# group: [aggregates]
# scalar value
query I
SELECT list_mad([1])
----
0
# constant list_mad is zero
statement ok
CREATE TABLE const AS SELECT LIST(1) AS i FROM range(2000) t1(i)
query I
SELECT list_mad(i) FROM const
----
0
# small numerics
foreach type tinyint decimal(4,1)
statement ok
create table tinys as select list(r::${type}) as r from range(100) tbl(r);
query I
SELECT list_mad(r) FROM tinys
----
25
statement ok
drop table tinys;
endloop
# large numerics
foreach type smallint integer bigint hugeint float double decimal(8,1) decimal(12,1) decimal(18,1) decimal(24,1)
statement ok
create table numerics as select list(r::${type}) as r from range(10000) tbl(r);
query I
SELECT list_mad(r) FROM numerics
----
2500
statement ok
drop table numerics
endloop
# temporal types
statement ok
create table date as select list(('2018-01-01'::DATE + INTERVAL (r) DAY)::DATE) as r from range(10000) tbl(r);
query I
SELECT list_mad(r) FROM date
----
2500 days
statement ok
create table hour as select list('2018-01-01'::TIMESTAMP + INTERVAL (r) HOUR) as r from range(10000) tbl(r);
query I
SELECT list_mad(r) FROM hour
----
104 days 04:00:00
statement ok
create table second as select list('00:00:00'::TIME + INTERVAL (r) SECOND) as r from range(10000) tbl(r);
query I
SELECT list_mad(r) FROM second
----
00:41:40
query I
select list_mad(x) from (values (['294247-01-10'::date, '290309-12-22 (BC)'::date])) tbl(x);
----
106751991 days
query I
select list_mad(x) from (values (['294247-01-10 04:00:54.775806'::timestamp,
'290309-12-22 (BC) 00:00:00'::timestamp])) tbl(x);
----
106751991 days 02:00:27.387903
query I
select list_mad(x) from (values (['23:59:59.999999'::time, '00:00:00'::time])) tbl(x);
----
12:00:00
foreach type date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz
statement ok
SELECT list_mad(['2021-08-20'::${type}])
statement ok
SELECT list_mad([NULL::${type}])
endloop
statement error
SELECT list_mad([INTERVAL 1 YEAR])
----
statement error
SELECT list_mad([NULL::INTERVAL])
----
# extreme values
query I
select list_mad(x) from (values (['127'::DECIMAL(3,0), '-128'::DECIMAL(3,0)])) tbl(x);
----
127
query I
select list_mad(x) from (values (['32767'::DECIMAL(5,0), '-32768'::DECIMAL(5,0)])) tbl(x);
----
32767
query I
select list_mad(x) from (values (['2147483647'::DECIMAL(10,0), '-2147483648'::DECIMAL(10,0)])) tbl(x);
----
2147483647
statement ok
select list_mad(x) from (values ([-1e308, 1e308])) tbl(x);

View File

@@ -0,0 +1,110 @@
# name: test/sql/function/list/aggregates/max.test
# description: Test the list_max aggregate function
# group: [aggregates]
# incorrect usage
statement error
SELECT list_max()
----
# test different types
# numerics
foreach type <numeric>
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_max(i) FROM five
----
5
NULL
NULL
NULL
2
statement ok
DROP TABLE five
endloop
# temporal
statement ok
CREATE TABLE five_dates AS
SELECT
LIST(i::integer) AS i,
LIST('2021-08-20'::DATE + i::INTEGER) AS d,
LIST('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR) AS dt,
LIST('14:59:37'::TIME + INTERVAL (i) MINUTE) AS t,
LIST(INTERVAL (i) SECOND) AS s
FROM range(1, 6, 1) t1(i)
query IIII
SELECT list_max(d), list_max(dt), list_max(t), list_max(s) FROM five_dates
----
2021-08-25 2021-08-20 05:00:00 15:04:37 00:00:05
statement ok
DROP TABLE five_dates
# with time zone
statement ok
CREATE TABLE five_dates_tz AS
SELECT
LIST(('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR)::TIMESTAMPTZ) AS dt,
LIST(('14:59:37'::TIME + INTERVAL (i) MINUTE)::TIMETZ) AS t,
FROM range(1, 6, 1) t1(i)
query II
SELECT list_max(dt), list_max(t) FROM five_dates_tz
----
2021-08-20 05:00:00+00 15:04:37+00
statement ok
DROP TABLE five_dates_tz
# complex types
statement ok
CREATE TABLE five_complex AS
SELECT
LIST(i::integer) AS i,
LIST(i::VARCHAR) AS s,
LIST([i]) AS l,
LIST({'a': i}) AS r
FROM range(1, 6, 1) t1(i)
query III
SELECT list_max(s), list_max(l), list_max(r)
FROM five_complex
----
5 [5] {'a': 5}
statement ok
DROP TABLE five_complex
# decimals
foreach type decimal(4,1) decimal(8,1) decimal(12,1) decimal(18,1)
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_max(i) FROM five
----
5.0
NULL
NULL
NULL
2.0
statement ok
DROP TABLE five
endloop

View File

@@ -0,0 +1,44 @@
# name: test/sql/function/list/aggregates/median.test
# description: Test the list_median aggregate function
# group: [aggregates]
# types
foreach type integer float double smallint bigint hugeint decimal(10,2)
statement ok
CREATE TABLE quantile AS SELECT LIST(r::${type}) AS r FROM range(10000) t1(r);
query I
SELECT list_median(r) FROM quantile
----
4999.5
statement ok
DROP TABLE quantile
endloop
statement ok
CREATE TABLE quantile AS SELECT LIST(r::tinyint) AS r FROM range(100) t1(r);
query I
SELECT list_median(r) FROM quantile
----
49.500000
# scalar quantiles
statement ok
CREATE TABLE range AS SELECT LIST(1) AS i FROM range(2000) t1(i)
statement ok
INSERT INTO range VALUES (NULL), ([]), ([NULL]);
query I
SELECT list_median(i) FROM range
----
1
NULL
NULL
NULL

View File

@@ -0,0 +1,110 @@
# name: test/sql/function/list/aggregates/min.test
# description: Test the list_min aggregate function
# group: [aggregates]
# incorrect usage
statement error
SELECT list_min()
----
# test different types
# numerics
foreach type <numeric>
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_min(i) FROM five
----
1
NULL
NULL
NULL
1
statement ok
DROP TABLE five
endloop
# temporal
statement ok
CREATE TABLE five_dates AS
SELECT
LIST(i::integer) AS i,
LIST('2021-08-20'::DATE + i::INTEGER) AS d,
LIST('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR) AS dt,
LIST('14:59:37'::TIME + INTERVAL (i) MINUTE) AS t,
LIST(INTERVAL (i) SECOND) AS s
FROM range(1, 6, 1) t1(i)
query IIII
SELECT list_min(d), list_min(dt), list_min(t), list_min(s) FROM five_dates
----
2021-08-21 2021-08-20 01:00:00 15:00:37 00:00:01
statement ok
DROP TABLE five_dates
# with time zone
statement ok
CREATE TABLE five_dates_tz AS
SELECT
LIST(('2021-08-20'::TIMESTAMP + INTERVAL (i) HOUR)::TIMESTAMPTZ) AS dt,
LIST(('14:59:37'::TIME + INTERVAL (i) MINUTE)::TIMETZ) AS t,
FROM range(1, 6, 1) t1(i)
query II
SELECT list_min(dt), list_min(t) FROM five_dates_tz
----
2021-08-20 01:00:00+00 15:00:37+00
statement ok
DROP TABLE five_dates_tz
# complex types
statement ok
CREATE TABLE five_complex AS
SELECT
LIST(i::integer) AS i,
LIST(i::VARCHAR) AS s,
LIST([i]) AS l,
LIST({'a': i}) AS r
FROM range(1, 6, 1) t1(i)
query III
SELECT list_min(s), list_min(l), list_min(r)
FROM five_complex
----
1 [1] {'a': 1}
statement ok
DROP TABLE five_complex
# decimals
foreach type decimal(4,1) decimal(8,1) decimal(12,1) decimal(18,1)
statement ok
CREATE TABLE five AS SELECT LIST(i::${type}) AS i FROM range(1, 6, 1) t1(i)
statement ok
INSERT INTO five VALUES (NULL), ([NULL]), ([]), ([NULL, 1, 2])
query I
SELECT list_min(i) FROM five
----
1.0
NULL
NULL
NULL
1.0
statement ok
DROP TABLE five
endloop

View File

@@ -0,0 +1,24 @@
# name: test/sql/function/list/aggregates/minmax_all_types.test_slow
# description: Test the min/max functions on all types
# group: [aggregates]
statement ok
pragma enable_verification
# verify that min/max produces the same results as ORDER BY .. LIMIT 1 for all types
statement ok
CREATE TABLE all_types AS FROM test_all_types();
foreach col <all_types_columns>
query I
SELECT MIN({'val': "${col}"}).val IS NOT DISTINCT FROM (SELECT "${col}" FROM all_types ORDER BY "${col}" LIMIT 1) FROM all_types WHERE bool IS NOT NULL
----
true
query I
SELECT MAX({'val': "${col}"}).val IS NOT DISTINCT FROM (SELECT "${col}" FROM all_types ORDER BY "${col}" DESC LIMIT 1) FROM all_types WHERE bool IS NOT NULL
----
true
endloop

View File

@@ -0,0 +1,227 @@
# name: test/sql/function/list/aggregates/minmax_nested.test
# description: Test the min/max functions on complex nested types aggregate function
# group: [aggregates]
statement ok
pragma enable_verification
# structs
statement ok
CREATE TABLE structs AS SELECT {'i': i} s FROM range(1000) t(i);
query II
SELECT MIN(s), MAX(s) FROM structs;
----
{'i': 0} {'i': 999}
# larger values
statement ok
INSERT INTO structs VALUES ({'i': 99999999});
query II
SELECT MIN(s), MAX(s) FROM structs;
----
{'i': 0} {'i': 99999999}
# limits
statement ok
INSERT INTO structs VALUES ({'i': -9223372036854775808}), ({'i': 9223372036854775807});
query II
SELECT MIN(s), MAX(s) FROM structs;
----
{'i': -9223372036854775808} {'i': 9223372036854775807}
# null values
statement ok
INSERT INTO structs VALUES ({'i': NULL}), (NULL)
query II
SELECT MIN(s), MAX(s) FROM structs;
----
{'i': -9223372036854775808} {'i': NULL}
# structs with varchars
statement ok
CREATE TABLE varchar_structs AS SELECT {'i': concat('long_prefix_', i)} s FROM range(1000) t(i);
query II
SELECT MIN(s), MAX(s) FROM varchar_structs;
----
{'i': long_prefix_0} {'i': long_prefix_999}
# null bytes
statement ok
INSERT INTO varchar_structs VALUES ({'i': chr(0)}), ({'i': 'zzzzz' || chr(0)})
query II
SELECT MIN(s), MAX(s) FROM varchar_structs;
----
{'i': \0} {'i': zzzzz\0}
# structs with blobs
statement ok
CREATE TABLE blob_structs AS SELECT {'i': concat('long_prefix_', '\x', 16+i%239)::blob} s FROM range(1000) t(i);
query II
SELECT MIN(s), MAX(s) FROM blob_structs;
----
{'i': long_prefix_\x100} {'i': long_prefix_\x99}
# null bytes
statement ok
INSERT INTO blob_structs VALUES ({'i': '\x00z\x00\x00z\x00zzzz\x00'::blob}), ({'i': 'zzzzzz\x01\x01\x01\x00\x01\x01\x00'::blob})
query II
SELECT MIN(s), MAX(s) FROM blob_structs;
----
{'i': \x00z\x00\x00z\x00zzzz\x00} {'i': zzzzzz\x01\x01\x01\x00\x01\x01\x00}
# multi-member structs
statement ok
CREATE TABLE multi_member_struct AS SELECT {'i': (1000-i)//5, 'j': i} s FROM range(1000) t(i);
query II
SELECT MIN(s), MAX(s) FROM multi_member_struct;
----
{'i': 0, 'j': 996} {'i': 200, 'j': 0}
# lists
statement ok
CREATE TABLE lists AS SELECT case when i<500 then [i, i + 1, i + 2] else [i, 0] end AS l FROM range(1000) t(i);
query II
SELECT MIN(l), MAX(l) FROM lists;
----
[0, 1, 2] [999, 0]
# empty list and null entries
statement ok
INSERT INTO lists VALUES ([]), (NULL), ([NULL, NULL, NULL]);
query II
SELECT MIN(l), MAX(l) FROM lists;
----
[] [NULL, NULL, NULL]
# lists with structs
statement ok
CREATE TABLE list_with_structs AS SELECT case when i<500 then [{'i': i}, {'i': i + 1}, {'i': i + 2}] else [{'i': i}, {'i': 0}] end AS l FROM range(1000) t(i);
query II
SELECT MIN(l), MAX(l) FROM list_with_structs;
----
[{'i': 0}, {'i': 1}, {'i': 2}] [{'i': 999}, {'i': 0}]
# null within a struct
statement ok
INSERT INTO list_with_structs VALUES ([{'i': NULL}, {'i': 100}, NULL, {'i': NULL}]);
query II
SELECT MIN(l), MAX(l) FROM list_with_structs;
----
[{'i': 0}, {'i': 1}, {'i': 2}] [{'i': NULL}, {'i': 100}, NULL, {'i': NULL}]
# empty list and null entries
statement ok
INSERT INTO list_with_structs VALUES ([]), (NULL), ([NULL, NULL, NULL]);
query II
SELECT MIN(l), MAX(l) FROM list_with_structs;
----
[] [NULL, NULL, NULL]
# list with multi member struct
statement ok
CREATE TABLE list_multi_member_struct AS SELECT [NULL, {'i': (1000-i)//5, 'j': i}, NULL] l FROM range(1000) t(i);
query II
SELECT MIN(l), MAX(l) FROM list_multi_member_struct;
----
[NULL, {'i': 0, 'j': 996}, NULL] [NULL, {'i': 200, 'j': 0}, NULL]
# nulls at different levels
statement ok
INSERT INTO list_multi_member_struct VALUES ([{'i': NULL, 'j': 42}]), ([NULL, NULL, {'i': 84, 'j': NULL}])
query II
SELECT MIN(l), MAX(l) FROM list_multi_member_struct;
----
[{'i': NULL, 'j': 42}] [NULL, NULL, {'i': 84, 'j': NULL}]
# struct with lists
statement ok
CREATE TABLE struct_with_lists AS SELECT {'i': case when i<500 then [i, i + 1, i + 2] else [i, 0] end} AS s FROM range(1000) t(i);
query II
SELECT MIN(s), MAX(s) FROM struct_with_lists;
----
{'i': [0, 1, 2]} {'i': [999, 0]}
# empty list and null entries
statement ok
INSERT INTO struct_with_lists VALUES ({'i': []}), (NULL), ({'i': [NULL, NULL, NULL]})
query II
SELECT MIN(s), MAX(s) FROM struct_with_lists;
----
{'i': []} {'i': [NULL, NULL, NULL]}
statement ok
INSERT INTO struct_with_lists VALUES ({'i': NULL})
query I
SELECT MAX(s) FROM struct_with_lists;
----
{'i': NULL}
# arrays
statement ok
CREATE TABLE arrays AS SELECT (case when i<500 then [i, i + 1, i + 2] else [i, 0, 0] end)::BIGINT[3] AS l FROM range(1000) t(i);
query II
SELECT MIN(l), MAX(l) FROM arrays;
----
[0, 1, 2] [999, 0, 0]
# null entries
statement ok
INSERT INTO arrays VALUES (NULL), ([NULL, NULL, NULL]);
query II
SELECT MIN(l), MAX(l) FROM arrays;
----
[0, 1, 2] [NULL, NULL, NULL]
# floats
statement ok
CREATE TABLE float_values(f FLOAT);
statement ok
INSERT INTO float_values VALUES ('0'), ('-3.4e38'), ('3.4e38'), ('nan'), ('inf'), ('-inf')
query II
SELECT f, (SELECT MIN({'v': x}) FROM (VALUES (f)) t(x)) FROM float_values;
----
0.0 {'v': 0.0}
-3.4e+38 {'v': -3.4e+38}
3.4e+38 {'v': 3.4e+38}
nan {'v': nan}
inf {'v': inf}
-inf {'v': -inf}
statement ok
CREATE TABLE double_values(d DOUBLE);
statement ok
INSERT INTO double_values VALUES ('0'), ('-1e308'), ('1e308'), ('nan'), ('inf'), ('-inf')
query II
SELECT d, (SELECT MIN({'v': x}) FROM (VALUES (d)) t(x)) FROM double_values;
----
0.0 {'v': 0.0}
-1e+308 {'v': -1e+308}
1e+308 {'v': 1e+308}
nan {'v': nan}
inf {'v': inf}
-inf {'v': -inf}

View File

@@ -0,0 +1,115 @@
# name: test/sql/function/list/aggregates/mode.test
# description: Test the list_mode aggregate function
# group: [aggregates]
# incorrect usage
statement error
select list_mode()
----
# integers
statement ok
CREATE TABLE range AS SELECT LIST(2) AS i FROM range(100) t1(i)
query I
SELECT list_mode(i) FROM range;
----
2
# strings
statement ok
create table names (name string[])
statement ok
insert into names values (['pedro', 'pedro', 'pedro', 'hannes', 'hannes', 'mark', NULL]);
query I
select list_mode(name) from names;
----
pedro
# temporal types
# date
statement ok
create table dates (v date[])
statement ok
insert into dates values (['2021-05-02', '2021-05-02', '2021-05-02', '2020-02-29', '2020-02-29', '2004-09-01', NULL]);
query I
select list_mode(v) from dates;
----
2021-05-02
# time
statement ok
create table times (v time[])
statement ok
insert into times values (['12:11:49.5', '12:11:49.5', '12:11:49.5', '06:30:00', '06:30:00', '21:15:22', NULL]);
query I
select list_mode(v) from times;
----
12:11:49.5
# timestamp
statement ok
create table timestamps (v timestamp[])
statement ok
insert into timestamps values (['2021-05-02 12:11:49.5', '2021-05-02 12:11:49.5', '2021-05-02 12:11:49.5',
'2020-02-29 06:30:00', '2020-02-29 06:30:00', '2004-09-01 21:15:22', NULL]);
query I
select list_mode(v) from timestamps;
----
2021-05-02 12:11:49.5
# interval
statement ok
create table intervals (v interval[])
statement ok
insert into intervals values
([INTERVAL '5 months 2 days 12 hours 11 minutes 49 seconds',
INTERVAL '5 months 2 days 12 hours 11 minutes 49 seconds',
INTERVAL '5 months 2 days 12 hours 11 minutes 49 seconds',
INTERVAL '2 months 29 days 6 hours 30 minutes',
INTERVAL '2 months 29 days 6 hours 30 minutes',
INTERVAL '9 months 1 day 21 hours 15 minutes 22 seconds',
NULL]);
query I
select list_mode(v) from intervals;
----
5 months 2 days 12:11:49
# huge integers
statement ok
create table hugeints (v hugeint[])
statement ok
insert into hugeints values ([5, 5, 5, 2, 2, 1, NULL]);
query I
select list_mode(v) from hugeints;
----
5
# decimals
statement ok
create table aggr (v decimal(10,2)[]);
statement ok
insert into aggr values ([10, 10, 20, 21]), ([20, 20, 25, 30]), ([NULL]), ([]), (NULL);
query I
select list_mode(v) from aggr;
----
10
20
NULL
NULL
NULL

View File

@@ -0,0 +1,49 @@
# name: test/sql/function/list/aggregates/nested.test
# description: Test nested list functions
# group: [aggregates]
query I
SELECT list_min(list_concat([1, 2], [-1]))
----
-1
query I
SELECT list_min(list_aggr([1, 2], 'list'))
----
1
statement ok
CREATE TABLE lists (l1 INTEGER[], l2 INTEGER[])
statement ok
INSERT INTO lists VALUES ([1, 2, 3], [4]), ([NULL, 1, -4, NULL], [NULL]), (NULL, NULL), ([NULL], [-4]), ([], [])
query I
SELECT list_last(list_concat(l1, l2)) FROM lists
----
4
NULL
NULL
-4
NULL
query I
SELECT list_concat(list(list_last(l1)), list(list_first(l2))) FROM lists
----
[3, NULL, NULL, NULL, NULL, 4, NULL, NULL, -4, NULL]
# aliases
query I
SELECT array_aggregate([1, 2], 'min')
----
1
query I
SELECT array_aggr([1, 2], 'min')
----
1
query I
SELECT list_aggregate([1, 2], 'min')
----
1

View File

@@ -0,0 +1,82 @@
# name: test/sql/function/list/aggregates/null_or_empty.test
# description: Test the list_aggr function for NULL, [NULL], [] and zero rows
# group: [aggregates]
# NULL list
foreach func_name avg favg approx_count_distinct bit_and bit_or bit_xor bool_or bool_and count entropy first arbitrary histogram kurtosis last mad max median min mode array_agg list product sem skewness string_agg group_concat sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
query I
SELECT list_aggr(NULL, '${func_name}')
----
NULL
endloop
# [NULL] list with NULL result
foreach func_name avg favg bit_and bit_or bit_xor bool_or bool_and first arbitrary histogram kurtosis last mad max median min mode product sem string_agg group_concat sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
query I
SELECT list_aggr([NULL], '${func_name}')
----
NULL
endloop
# [NULL] list with 0 result
foreach func_name approx_count_distinct count entropy
query I
SELECT list_aggr([NULL], '${func_name}')
----
0
endloop
# [NULL] list with [NULL] result
foreach func_name array_agg list
query I
SELECT list_aggr([NULL], '${func_name}')
----
[NULL]
endloop
# empty list with NULL result
foreach func_name avg favg bit_and bit_or bit_xor bool_or bool_and first arbitrary histogram kurtosis last mad max median min mode array_agg list product sem skewness string_agg group_concat sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
query I
SELECT list_aggr([], '${func_name}')
----
NULL
endloop
# select * from NULL list
foreach func_name avg favg approx_count_distinct bit_and bit_or bit_xor bool_or bool_and count entropy first arbitrary histogram kurtosis last mad max median min mode array_agg list product sem skewness string_agg group_concat sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
query I
select * from (SELECT list_aggr(NULL, '${func_name}'))
----
NULL
endloop
# empty list with 0 result
foreach func_name approx_count_distinct count entropy
query I
SELECT list_aggr([], '${func_name}')
----
0
endloop
# zero rows
foreach func_name approx_count_distinct avg favg bit_and bit_or bit_xor bool_and bool_or count entropy first arbitrary histogram kurtosis last mad max median min mode array_agg list product sem skewness string_agg group_concat sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
query I
SELECT list_aggr([], '${func_name}') WHERE 1 = 0
----
endloop

View File

@@ -0,0 +1,42 @@
# name: test/sql/function/list/aggregates/product.test
# description: Test the list_product aggregate function
# group: [aggregates]
# incorrect usage
statement error
select list_product()
----
statement ok
CREATE TABLE integers(i INTEGER[]);
statement ok
INSERT INTO integers VALUES ([1, 2, 4]), (NULL), ([]), ([NULL]), ([1, 2, NULL, 4, NULL])
query I
SELECT list_product(i) FROM integers
----
8
NULL
NULL
NULL
8
statement ok
CREATE TABLE prods AS SELECT LIST(2) AS i FROM range(100) t1(i)
query I
SELECT list_product(i) FROM prods;
----
1267650600228229401496703205376
statement ok
drop table prods
statement ok
CREATE TABLE prods AS SELECT LIST(2) AS i FROM range(100 // 2) t1(i)
query I
SELECT list_product(i) FROM prods;
----
1125899906842624

View File

@@ -0,0 +1,39 @@
# name: test/sql/function/list/aggregates/sem.test
# description: Test the list_sem aggregate function
# group: [aggregates]
# incorrect usage
statement error
select list_sem()
----
query I
select list_sem([1])
----
0.000000
statement ok
create table aggr(k int[], v decimal(10,2)[], v2 decimal(10, 2)[]);
statement ok
insert into aggr values ([1, 2, 2, 2, 2], [10, 10, 20, 25, 30], [NULL, 11, 22, NULL, 35]);
query III
select list_sem(k), list_sem(v), list_sem(v2) from aggr;
----
0.178885 3.577709 5.663398
statement ok
create table sems (l int[]);
statement ok
insert into sems values ([1, 2, 2, 2, 2]), ([1, 2, NULL, 2, 2, NULL, 2]), ([]), ([NULL]), (NULL);
query I
select list_sem(l) from sems;
----
0.178885
0.178885
NULL
NULL
NULL

View File

@@ -0,0 +1,61 @@
# name: test/sql/function/list/aggregates/skewness.test
# description: Test the list_skewness aggregate function
# group: [aggregates]
# incorrect usage
statement error
select list_skewness()
----
query I
select list_skewness([1])
----
NULL
statement ok
CREATE TABLE skew AS SELECT LIST(10) AS i FROM range(5) t1(i)
# constant value
query I
select list_skewness (i) from skew
----
NAN
query I
select list_skewness ([1,2])
----
NULL
# out of range
statement error
select list_skewness([-2e307, 0, 2e307])
----
statement ok
create table aggr(k int[], v decimal(10,2)[], v2 decimal(10, 2)[]);
statement ok
insert into aggr values ([1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[10, 10, 10, 10, 20, 20, 25, 30, 30, 30, 30],
[NULL, 11, 15, 18, 22, 25, NULL, 35, 40, 50, 51]),
([], NULL, [NULL]);
query III
select list_skewness(k), list_skewness(v), list_skewness(v2) from aggr
----
-3.316625 -0.163444 0.365401
NULL NULL NULL
statement ok
create table aggr2(v2 decimal(10, 2)[]);
statement ok
insert into aggr2 values ([NULL, 11, 15, 18]), ([22, 25]), ([NULL]), ([35, 40, 50, 51]);
query I
select list_skewness(v2) from aggr2
----
-0.423273
NULL
NULL
-0.330141

View File

@@ -0,0 +1,83 @@
# name: test/sql/function/list/aggregates/string_agg.test
# description: Test the list_string_agg aggregate function
# group: [aggregates]
# incorrect usage
statement error
SELECT list_string_agg()
----
# scalar values
query T
SELECT list_string_agg(['a', ','])
----
a,,
query T
SELECT list_string_agg(['a'])
----
a
statement ok
CREATE TABLE str_aggs (str varchar[]);
statement ok
INSERT INTO str_aggs VALUES (['a', ',']), ([NULL, ',']), (['a', NULL]), ([NULL, NULL]), (NULL), ([]), ([NULL]);
query T
SELECT list_string_agg(str) from str_aggs;
----
a,,
,
a
NULL
NULL
NULL
NULL
# test string aggregation on lists of values
statement ok
CREATE TABLE strings(g INTEGER[], x VARCHAR[], y VARCHAR[]);
statement ok
INSERT INTO strings VALUES ([1, 1, 2, 2, 2, 3, 4, 4, 4], ['a', 'b', 'i', NULL, 'j', 'p', 'x', 'y', 'z'],
['/', '-', '/', '-', '+', '/', '/', '-', '+']);
query TTT
SELECT list_string_agg(x), list_string_agg(y), list_string_agg(g::varchar[]) FROM strings
----
a,b,i,j,p,x,y,z /,-,/,-,+,/,/,-,+ 1,1,2,2,2,3,4,4,4
query T
SELECT list_string_agg(x) FROM strings WHERE g > [100]
----
# numerics are auto cast to strings for string agg
query I
SELECT list_string_agg([1, 2])
----
1,2
query T
SELECT list_string_agg([1, 2]::varchar[])
----
1,2
# group concat is an alias for list_string_agg
query T
SELECT list_aggr(['a'], 'group_concat')
----
a
statement ok
CREATE TABLE long AS SELECT LIST('a') g FROM range(0, 10, 1) t1(c), range(0, 10, 1) t2(e);
query II
SELECT list_count(g), list_count(g) FROM long;
----
100 100
query I
SELECT list_string_agg(g) FROM long
----
a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a

View File

@@ -0,0 +1,73 @@
# name: test/sql/function/list/aggregates/sum.test
# description: Test the list_sum aggregate function
# group: [aggregates]
query I
SELECT list_sum([2, 2])
----
4
statement ok
CREATE TABLE integers(i INTEGER[]);
# positive numbers
statement ok
INSERT INTO integers SELECT LIST(i) FROM range(0, 1000, 1) tbl(i);
# negative numbers
statement ok
INSERT INTO integers SELECT LIST(i) FROM range(-999, 1000, 1) tbl(i);
# more negative numbers
statement ok
INSERT INTO integers SELECT LIST(i) FROM range(0, -1000, -1) tbl(i);
# empty/NULLs
statement ok
INSERT INTO integers VALUES (NULL), ([NULL]), ([]);
query I
SELECT list_sum(i) FROM integers;
----
499500
0
-499500
NULL
NULL
NULL
statement ok
CREATE TABLE doubles(n DOUBLE[]);
statement ok
INSERT INTO doubles (n) VALUES (['9007199254740992'::DOUBLE, 1::DOUBLE, 1::DOUBLE, 0::DOUBLE]);
# this would give the wrong result with a simple sum
query I
SELECT list_aggr(n, 'fsum') FROM doubles;
----
9007199254740994
query I
SELECT list_aggr(n, 'sumKahan') FROM doubles;
----
9007199254740994
query I
SELECT list_aggr(n, 'kahan_sum') FROM doubles;
----
9007199254740994
# bigint sum
statement ok
CREATE TABLE bigints(i BIGINT[]);
# a bunch of huge values
statement ok
INSERT INTO bigints SELECT LIST(i) FROM range(4611686018427387904, 4611686018427388904, 1) tbl(i);
# sum them up
query I
SELECT list_sum(i) FROM bigints
----
4611686018427388403500

View File

@@ -0,0 +1,22 @@
# name: test/sql/function/list/aggregates/sum_bool.test
# description: Test the SUM(bool)
# group: [aggregates]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers(i INTEGER);
statement ok
INSERT INTO integers SELECT CASE WHEN i%3=0 THEN NULL ELSE i END i FROM range(10000) t(i);
query III
SELECT SUM(i > 500), SUM(i=1), SUM(i IS NULL) FROM integers
----
6332 1 3334
query III
SELECT COUNTIF(i > 500), COUNT_IF(i=1), COUNTIF(i IS NULL) FROM integers
----
6332 1 3334

View File

@@ -0,0 +1,16 @@
# name: test/sql/function/list/aggregates/sum_no_overflow.test
# description: Test the sum_no_overflow aggregate function
# group: [aggregates]
statement ok
PRAGMA enable_verification
statement error
SELECT sum_no_overflow(42)
----
internal use only
statement error
SELECT sum_no_overflow(42.5)
----
internal use only

View File

@@ -0,0 +1,430 @@
# name: test/sql/function/list/aggregates/types.test_slow
# description: Test the list_aggr function for all types
# group: [aggregates]
# This file specifically tests the functionality for each type,
# it does not necessarily test the correctness (statement ok suffices for some tests)
statement ok
PRAGMA enable_verification
# BOOLEAN
# result False
#foreach func_name bool_and bool_or first arbitrary last max median min mode string_agg group_concat
foreach func_name median
query I
SELECT list_aggr([False], '${func_name}')
----
false
query I
SELECT list_aggr([NULL::BOOLEAN], '${func_name}')
----
NULL
endloop
# any other result
foreach func_name approx_count_distinct count entropy array_agg list histogram sum
statement ok
SELECT list_aggr([False], '${func_name}')
statement ok
SELECT list_aggr([NULL::BOOLEAN], '${func_name}')
endloop
# statement error for BOOLEAN
foreach func_name avg favg bit_and bit_or bit_xor kurtosis mad product sem skewness fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
statement error
SELECT list_aggr([False], '${func_name}')
----
endloop
# VARCHAR
# result hello
foreach func_name first arbitrary last max median min mode string_agg group_concat
query I
SELECT list_aggr(['hello'], '${func_name}')
----
hello
query I
SELECT list_aggr([NULL::VARCHAR], '${func_name}')
----
NULL
endloop
# any other result
foreach func_name approx_count_distinct count entropy histogram array_agg list
statement ok
SELECT list_aggr(['hello'], '${func_name}')
statement ok
SELECT list_aggr([NULL::VARCHAR], '${func_name}')
endloop
# statement error for VARCHAR
foreach func_name avg favg bit_and bit_or bit_xor bool_and bool_or kurtosis mad product sem skewness sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
statement error
SELECT list_aggr(['hello'], '${func_name}')
----
endloop
# INTEGER types
foreach func_name avg favg bit_and bit_or bit_xor first arbitrary last max median min mode product sum fsum sumKahan kahan_sum
foreach type tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint uhugeint
query I
SELECT list_aggr([1::${type}], '${func_name}')
----
1
query I
SELECT list_aggr([NULL::${type}], '${func_name}')
----
NULL
endloop
endloop
# any other result
foreach func_name approx_count_distinct count entropy histogram kurtosis mad array_agg list sem skewness var_samp var_pop stddev stddev_pop variance stddev_samp
foreach type tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint uhugeint
statement ok
SELECT list_aggr([1::${type}], '${func_name}')
statement ok
SELECT list_aggr([NULL::${type}], '${func_name}')
endloop
endloop
# statement error for INTEGER types
foreach func_name bool_and bool_or
foreach type tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint uhugeint
statement error
SELECT list_aggr([1::${type}], '${func_name}')
----
endloop
endloop
# FLOAT, DOUBLE and DECIMAL types
foreach func_name avg favg first arbitrary last max median min mode product sum fsum sumKahan kahan_sum
foreach type float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10)
query I
SELECT list_aggr([1::${type}], '${func_name}')
----
1
query I
SELECT list_aggr([NULL::${type}], '${func_name}')
----
NULL
endloop
endloop
# any other result
foreach func_name approx_count_distinct count entropy histogram kurtosis mad array_agg list sem skewness var_samp var_pop stddev stddev_pop variance stddev_samp
foreach type float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10)
statement ok
SELECT list_aggr([1::${type}], '${func_name}')
statement ok
SELECT list_aggr([NULL::${type}], '${func_name}')
endloop
endloop
# statement error for FLOAT, DOUBLE and DECIMAL types
foreach func_name bit_and bit_or bit_xor bool_and bool_or
foreach type float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10)
statement error
SELECT list_aggr([1::${type}], '${func_name}')
----
endloop
endloop
# TEMPORAL types
# exceptions:
# mad (works with everything except interval)
# specific result
foreach func_name first arbitrary last max min mode
# date
query I
SELECT list_aggr(['2021-08-20'::DATE], '${func_name}')
----
2021-08-20
# time
query I
SELECT list_aggr(['14:59:37'::TIME], '${func_name}')
----
14:59:37
# timestamp
query I
SELECT list_aggr(['2021-08-20'::TIMESTAMP], '${func_name}')
----
2021-08-20 00:00:00
# timestamp s
query I
SELECT list_aggr(['2021-08-20'::TIMESTAMP_S], '${func_name}')
----
2021-08-20 00:00:00
# timestamp ms
query I
SELECT list_aggr(['2021-08-20 00:00:00.123'::TIMESTAMP_MS], '${func_name}')
----
2021-08-20 00:00:00.123
# timestamp ns
query I
SELECT list_aggr(['2021-08-20 00:00:00.123456'::TIMESTAMP_NS], '${func_name}')
----
2021-08-20 00:00:00.123456
# time with time zone
query I
SELECT list_aggr(['14:59:37'::TIMETZ], '${func_name}')
----
14:59:37+00
# timestamp with time zone
query I
SELECT list_aggr(['2021-08-20'::TIMESTAMPTZ], '${func_name}')
----
2021-08-20 00:00:00+00
# interval
query I
SELECT list_aggr([INTERVAL 1 YEAR], '${func_name}')
----
1 year
endloop
foreach func_name first arbitrary last max min mode
foreach type date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz interval
query I
SELECT list_aggr([NULL::${type}], '${func_name}')
----
NULL
endloop
endloop
# any other result
foreach func_name approx_count_distinct count entropy median array_agg list histogram
foreach type date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz
statement ok
SELECT list_aggr(['2021-08-20'::${type}], '${func_name}')
statement ok
SELECT list_aggr([NULL::${type}], '${func_name}')
endloop
statement ok
SELECT list_aggr([INTERVAL 1 YEAR], '${func_name}')
statement ok
SELECT list_aggr([NULL::INTERVAL], '${func_name}')
endloop
# statement ok for TEMPORAL types
foreach func_name avg
foreach type date timestamp timestamp_s timestamp_ms timestamp_ns timestamptz timetz
statement ok
SELECT list_aggr(['2021-08-20'::${type}], '${func_name}')
endloop
endloop
# statement error for TEMPORAL types
foreach func_name favg bit_and bit_or bit_xor bool_and bool_or kurtosis product sem skewness sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
foreach type date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz
statement error
SELECT list_aggr(['2021-08-20'::${type}], '${func_name}')
----
endloop
statement error
SELECT list_aggr([INTERVAL 1 YEAR], '${func_name}')
----
endloop
# any other result
foreach func_name approx_count_distinct count entropy histogram array_agg list
endloop
# BLOB
# result {a: 1}
foreach func_name first arbitrary last max min
query I
SELECT list_aggr(['{a: 1}'::BLOB], '${func_name}')
----
{a: 1}
query I
SELECT list_aggr([NULL::BLOB], '${func_name}')
----
NULL
endloop
# any other result
foreach func_name count array_agg list entropy histogram median mode string_agg group_concat
statement ok
SELECT list_aggr(['{a: 1}'::BLOB], '${func_name}')
statement ok
SELECT list_aggr([NULL::BLOB], '${func_name}')
endloop
# statement error for BLOB
foreach func_name avg favg bit_and bit_or bit_xor bool_and bool_or kurtosis mad product sem skewness sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
statement error
SELECT list_aggr(['{a: 1}'::BLOB], '${func_name}')
----
endloop
# ENUMS
statement ok
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')
statement ok
CREATE TABLE enums (e mood[])
statement ok
INSERT INTO enums VALUES (['happy'])
# result happy
foreach func_name first arbitrary last max median min mode string_agg group_concat
query I
SELECT list_aggr(e, '${func_name}') FROM enums
----
happy
endloop
# any other result
foreach func_name approx_count_distinct count entropy array_agg list histogram
statement ok
SELECT list_aggr(e, '${func_name}') FROM enums
endloop
# statement error for ENUMS
foreach func_name avg favg bit_and bit_or bit_xor bool_and bool_or kurtosis mad product sem skewness sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
statement error
SELECT list_aggr(e, '${func_name}') FROM enums
----
endloop
# NESTED types
# list, struct, result is [1] or {'a': 1}
foreach func_name first arbitrary last max median min mode
query I
SELECT list_aggr([[1]], '${func_name}')
----
[1]
query I
SELECT list_aggr([{'a': 1}], '${func_name}')
----
{'a': 1}
endloop
# list, struct, any other result
foreach func_name approx_count_distinct count entropy array_agg list string_agg group_concat histogram
statement ok
SELECT list_aggr([[1]], '${func_name}')
statement ok
SELECT list_aggr([{'a': 1}], '${func_name}')
endloop
# statement error for NESTED types
# list, struct
foreach func_name avg favg bit_and bit_or bit_xor bool_and bool_or kurtosis mad product sem skewness sum fsum sumKahan kahan_sum var_samp var_pop stddev stddev_pop variance stddev_samp
statement error
SELECT list_aggr([[1]], '${func_name}')
----
statement error
SELECT list_aggr([{'a': 1}], '${func_name}')
----
endloop

View File

@@ -0,0 +1,30 @@
# name: test/sql/function/list/aggregates/uhugeint.test
# description: Test uhugeint aggregates
# group: [aggregates]
statement ok
CREATE TABLE uhugeints(h UHUGEINT[])
statement ok
INSERT INTO uhugeints VALUES ([NULL, 1, 2]), (NULL), ([]), ([NULL]), ([1, 2, 3])
query III
SELECT list_first(h), list_last(h), list_sum(h) FROM uhugeints
----
NULL 2 3
NULL NULL NULL
NULL NULL NULL
NULL NULL NULL
1 3 6
statement ok
DELETE FROM uhugeints
statement ok
INSERT INTO uhugeints VALUES ([42.0, 1267650600228229401496703205376, 0, '1']);
query IIIII
SELECT list_min(h), list_max(h), list_sum(h), list_first(h), list_last(h) FROM uhugeints;
----
0 1267650600228229401496703205376 1267650160380990427257727966431 42 1

View File

@@ -0,0 +1,157 @@
# name: test/sql/function/list/aggregates/var_stddev.test
# description: Test the list_var_samp, list_var_pop, list_stddev_pop, list_stddev_samp aggregate functions
# group: [aggregates]
statement ok
create table stddev_test(val integer[])
statement ok
insert into stddev_test values ([42, 43, 42, 1000, NULL, NULL]), ([1, 1, 2, 2, 1, 3]), ([]), ([NULL]), (NULL)
query I
SELECT list_stddev_samp([1])
----
NULL
query I
SELECT list_var_samp([1])
----
NULL
# stddev_samp
query I
select round(list_stddev_samp(val), 1) from stddev_test
----
478.8
0.8
NULL
NULL
NULL
query III
select list_sum(val), round(list_stddev_samp(val), 1), list_min(val) from stddev_test
----
1127 478.8 42
10 0.8 1
NULL NULL NULL
NULL NULL NULL
NULL NULL NULL
# stddev_pop
query I
select round(list_stddev_pop(val), 1) from stddev_test
----
414.7
0.7
NULL
NULL
NULL
query III
select list_sum(val), round(list_stddev_pop(val), 1), list_min(val) from stddev_test
----
1127 414.7 42
10 0.7 1
NULL NULL NULL
NULL NULL NULL
NULL NULL NULL
# var_samp
query I
select round(list_var_samp(val), 1) from stddev_test
----
229281.6
0.7
NULL
NULL
NULL
query I
select round(list_aggr(val, 'variance'), 1) from stddev_test
----
229281.6
0.7
NULL
NULL
NULL
query III
select list_sum(val), round(list_var_samp(val), 1), list_min(val) from stddev_test
----
1127 229281.6 42
10 0.7 1
NULL NULL NULL
NULL NULL NULL
NULL NULL NULL
# var_pop
query I
select round(list_var_pop(val), 1) from stddev_test
----
171961.2
0.6
NULL
NULL
NULL
query III
select list_sum(val), round(list_var_pop(val), 1), list_min(val) from stddev_test
----
1127 171961.2 42
10 0.6 1
NULL NULL NULL
NULL NULL NULL
NULL NULL NULL
# stddev_samp
query I
select round(list_aggr(val, 'stddev'), 1) from stddev_test
----
478.8
0.8
NULL
NULL
NULL
query I
select list_aggr([0], 'stddev')
----
NULL
query I
select list_aggr([0, 0], 'stddev')
----
0
statement error
select list_aggr([1e301, -1e301], 'stddev')
----
<REGEX>:.*Out of Range Error.*out of range.*
statement error
select list_var_samp([1e301, -1e301])
----
<REGEX>:.*Out of Range Error.*out of range.*
statement error
select list_var_pop([1e301, -1e301])
----
<REGEX>:.*Out of Range Error.*out of range.*
# incorrect usage
statement error
SELECT list_stddev_samp()
----
<REGEX>:.*Binder Error.*does not support the supplied arguments.*
# stddev_pop unexpectedly does not fetch any rows, test for list_stddev_pop
statement ok
CREATE TABLE t0 (c0 DOUBLE[]);
statement ok
INSERT INTO t0 VALUES([1E200, 0]);
statement error
SELECT list_stddev_pop(c0) FROM t0;
----
<REGEX>:.*Out of Range Error.*out of range.*

View File

@@ -0,0 +1,50 @@
# name: test/sql/function/list/array_length.test
# description: Test array_length function
# group: [list]
query I
SELECT length([1,2,3])
----
3
query I
SELECT length([])
----
0
query I
SELECT len(NULL)
----
NULL
query I
SELECT array_length(ARRAY[1, 2, 3], 1)
----
3
statement error
SELECT array_length(ARRAY[1, 2, 3], 2)
----
statement error
SELECT array_length(ARRAY[1, 2, 3], 0)
----
query I
SELECT len([1]) FROM range(3)
----
1
1
1
statement ok
CREATE TABLE lists AS SELECT * FROM (VALUES ([1, 2]), ([NULL]), (NULL), ([]), ([3, 4, 5, 6, 7])) tbl(l)
query I
SELECT len(l) FROM lists
----
2
1
NULL
0
5

View File

@@ -0,0 +1,45 @@
# name: test/sql/function/list/array_to_string.test
# description: Test array_to_string function
# group: [list]
statement ok
PRAGMA enable_verification
query I
SELECT array_to_string([1,2,3], '')
----
123
query I
SELECT array_to_string([1,2,3], '-')
----
1-2-3
query I
SELECT array_to_string(NULL, '-')
----
NULL
query I
SELECT array_to_string([1, 2, 3], NULL)
----
1,2,3
query I
SELECT array_to_string([], '-')
----
NULL
query I
SELECT array_to_string([i, i + 1], '-') FROM range(6) t(i) WHERE i<=2 OR i>4
----
0-1
1-2
2-3
5-6
statement error
SELECT array_to_string([1, 2, 3], k) FROM repeat(',', 5) t(k)
----
Separator argument to StringAgg must be a constant

View File

@@ -0,0 +1,52 @@
# name: test/sql/function/list/array_to_string_comma_default.test
# description: Test array_to_string_comma_default function
# group: [list]
query I
SELECT array_to_string_comma_default([1,2,3])
----
1,2,3
query I
SELECT array_to_string_comma_default([1,2,3], sep:=',')
----
1,2,3
query I
SELECT array_to_string_comma_default([1,2,3], sep:='')
----
123
query I
SELECT array_to_string_comma_default([1,2,3], sep:='-')
----
1-2-3
query I
SELECT array_to_string_comma_default(NULL, sep:='-')
----
NULL
query I
SELECT array_to_string_comma_default([1, 2, 3], sep:=NULL)
----
1,2,3
query I
SELECT array_to_string_comma_default([], sep:='-')
----
NULL
query I
SELECT array_to_string_comma_default([i, i + 1], sep:='-') FROM range(6) t(i) WHERE i<=2 OR i>4
----
0-1
1-2
2-3
5-6
statement error
SELECT array_to_string_comma_default([1, 2, 3], sep:=k) FROM repeat(',', 5) t(k)
----
Separator argument to StringAgg must be a constant

View File

@@ -0,0 +1,158 @@
# name: test/sql/function/list/flatten.test
# description: Test flatten function
# group: [list]
# basic functionality
query T
SELECT flatten([[1, 2, 3, 4]])
----
[1, 2, 3, 4]
query T
SELECT flatten([[1, 2], [3, 4]])
----
[1, 2, 3, 4]
statement error
SELECT flatten(1)
----
# empty nested list
query T
SELECT flatten([[], []])
----
[]
# empty child list
query T
SELECT flatten([[1, 2], [], [3, 4]])
----
[1, 2, 3, 4]
query T
SELECT flatten([[1, 2], []])
----
[1, 2]
query T
SELECT flatten([[], [1, 2]])
----
[1, 2]
# NULL
query T
SELECT flatten(NULL)
----
NULL
query T
SELECT flatten([NULL])
----
[]
query T
SELECT flatten([[NULL]])
----
[NULL]
query T
SELECT flatten([NULL, [1], [2, 3], NULL, [4, NULL], [NULL, NULL]])
----
[1, 2, 3, 4, NULL, NULL, NULL]
# multiple-layered nested list
query T
SELECT flatten([[[1, 2], [3, 4]], [[5,6], [7, 8]]])
----
[[1, 2], [3, 4], [5, 6], [7, 8]]
query T
SELECT flatten(flatten(flatten([[[[1], [2]], [[3], [4]]], [[[5], [6]], [[7], [8]]]])))
----
[1, 2, 3, 4, 5, 6, 7, 8]
query T
SELECT flatten([[[1, 2], [3, 4]], [], [[5, 6], [7, 8]]]);
----
[[1, 2], [3, 4], [5, 6], [7, 8]]
query T
SELECT flatten([[[1, 2], [3, 4]], [[]], [[5, 6], [7, 8]]]);
----
[[1, 2], [3, 4], [], [5, 6], [7, 8]]
query T
SELECT flatten([[[]], [[]]])
----
[[], []]
query T
SELECT flatten(flatten([[[]], [[]]]))
----
[]
# flat vector
statement ok
CREATE TABLE nums AS SELECT range % 8 i, range j FROM range(16)
statement ok
CREATE TABLE lists AS SELECT i % 4 i, list(j ORDER BY rowid) j FROM nums GROUP BY i
statement ok
CREATE TABLE nested_lists AS SELECT i, list_sort(list(j ORDER BY rowid)) j FROM lists GROUP BY i ORDER BY i
query II
FROM nested_lists
----
0 [[0, 8], [4, 12]]
1 [[1, 9], [5, 13]]
2 [[2, 10], [6, 14]]
3 [[3, 11], [7, 15]]
query II rowsort
SELECT i, flatten(j) FROM nested_lists
----
0 [0, 8, 4, 12]
1 [1, 9, 5, 13]
2 [2, 10, 6, 14]
3 [3, 11, 7, 15]
query II
SELECT i, flatten(j) FROM nested_lists WHERE i % 2 != 0
----
1 [1, 9, 5, 13]
3 [3, 11, 7, 15]
query II
SELECT i, flatten([[1, 2], [3, 4]]) FROM nested_lists
----
0 [1, 2, 3, 4]
1 [1, 2, 3, 4]
2 [1, 2, 3, 4]
3 [1, 2, 3, 4]
# Issue #6856 - flatten() segfaults when called on bad input
statement error
select flatten(42);
----
No function matches the given name and argument types
statement error
select flatten([1, 2]);
----
No function matches the given name and argument types
query I
select flatten(NULL);
----
NULL
query IIII rowsort
with v_data (col, list) as ( select * FROM (VALUES ('a', [1,2,3]), ('b', [4,5]), ('a', [2,6])) ),
v_list_of_lists ( col, list, list_of_lists ) as ( select v.*, array_agg(v.list) over (partition by v.col order by v.list) from v_data v )
select v.*, flatten(v.list_of_lists) from v_list_of_lists v;
----
a [1, 2, 3] [[1, 2, 3]] [1, 2, 3]
a [2, 6] [[1, 2, 3], [2, 6]] [1, 2, 3, 2, 6]
b [4, 5] [[4, 5]] [4, 5]

View File

@@ -0,0 +1,264 @@
# name: test/sql/function/list/generate_series.test
# description: Test generate_series/range function
# group: [list]
# range with a single parameter
query I
SELECT range(3)
----
[0, 1, 2]
query I
SELECT generate_series(3)
----
[0, 1, 2, 3]
query I
SELECT range(3) FROM range(3)
----
[0, 1, 2]
[0, 1, 2]
[0, 1, 2]
query I
SELECT range(i) FROM range(3) tbl(i)
----
[]
[0]
[0, 1]
query I
SELECT range(NULL) FROM range(3) tbl(i)
----
NULL
NULL
NULL
query I
SELECT range(CASE WHEN i%2=0 THEN NULL ELSE i END) FROM range(6) tbl(i)
----
NULL
[0]
NULL
[0, 1, 2]
NULL
[0, 1, 2, 3, 4]
query I
SELECT range(0)
----
[]
query I
SELECT range(-1)
----
[]
query I
SELECT range(NULL)
----
NULL
# range with two parameters
query I
SELECT range(1, 3)
----
[1, 2]
query I
SELECT generate_series(1, 3)
----
[1, 2, 3]
query I
SELECT range(1, 1)
----
[]
query I
SELECT range(-10, -5)
----
[-10, -9, -8, -7, -6]
query I
SELECT generate_series(1, 1)
----
[1]
query I
SELECT range(3, 1)
----
[]
query I
SELECT range(NULL, 1)
----
NULL
query I
SELECT range(1, NULL)
----
NULL
query I
SELECT range(NULL, NULL)
----
NULL
query I
SELECT range(i, 5) FROM range(5) tbl(i)
----
[0, 1, 2, 3, 4]
[1, 2, 3, 4]
[2, 3, 4]
[3, 4]
[4]
query I
SELECT range(0, i) FROM range(5) tbl(i)
----
[]
[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]
# range with 3 parameters
query I
SELECT range(1, 6, 2)
----
[1, 3, 5]
query I
SELECT generate_series(1, 6, 2)
----
[1, 3, 5]
query I
SELECT generate_series(1, 7, 2)
----
[1, 3, 5, 7]
query I
SELECT range(1, 10, 100)
----
[1]
query I
SELECT range(1, 10, 0)
----
[]
query I
SELECT range(3, 1, -1)
----
[3, 2]
query I
SELECT generate_series(3, 1, -1)
----
[3, 2, 1]
query I
SELECT range(3, 1, 1)
----
[]
query I
SELECT range(1, 3, -1)
----
[]
query I
SELECT range(4, 1, -1)
----
[4, 3, 2]
query I
SELECT range(50, 1, -20)
----
[50, 30, 10]
query I
SELECT generate_series(50, 1, -20)
----
[50, 30, 10]
query I
SELECT generate_series(50, -10, -20)
----
[50, 30, 10, -10]
query I
SELECT range(NULL, 1, 1)
----
NULL
query I
SELECT range(1, NULL, 1)
----
NULL
query I
SELECT range(1, 1, NULL)
----
NULL
query I
SELECT range(NULL, NULL, NULL)
----
NULL
query II
SELECT * FROM (SELECT 1 UNION ALL SELECT 0 UNION ALL SELECT 2) AS _(x), generate_series(1, x) AS __(y) ORDER BY x, y
----
1 1
2 1
2 2
# Check that explain cardinalities are correct
query II
EXPLAIN FROM range(0);
----
physical_plan <REGEX>:.*~0 rows.*
query II
EXPLAIN FROM range(-1);
----
physical_plan <REGEX>:.*~0 rows.*
query II
EXPLAIN FROM range(-5, -20, -1);
----
physical_plan <REGEX>:.*~15 rows.*
query II
EXPLAIN FROM range(1, 4, 2);
----
physical_plan <REGEX>:.*~2 rows.*
query II
EXPLAIN FROM range(1, 5, 2);
----
physical_plan <REGEX>:.*~2 rows.*
query II
EXPLAIN FROM generate_series(0);
----
physical_plan <REGEX>:.*~1 row.*
query II
EXPLAIN FROM generate_series(1);
----
physical_plan <REGEX>:.*~2 rows.*
query II
EXPLAIN FROM generate_series(1, 4, 2);
----
physical_plan <REGEX>:.*~2 rows.*
query II
EXPLAIN FROM generate_series(1, 5, 2);
----
physical_plan <REGEX>:.*~3 rows.*

View File

@@ -0,0 +1,93 @@
# name: test/sql/function/list/generate_series_timestamp.test
# description: Test generate_series/range function
# group: [list]
# standard generate_series (inclusive bound)
query I
SELECT generate_series(timestamp '2020-01-01', timestamp '2020-07-01', interval '3' month);
----
['2020-01-01 00:00:00', '2020-04-01 00:00:00', '2020-07-01 00:00:00']
# exclusive bound
query I
SELECT range(timestamp '2020-01-01', timestamp '2020-07-01', interval '3' month);
----
['2020-01-01 00:00:00', '2020-04-01 00:00:00']
# negative interval
query I
SELECT generate_series(timestamp '2020-06-01', timestamp '2020-01-01', -interval '3' month);
----
['2020-06-01 00:00:00', '2020-03-01 00:00:00']
# start = end
query I
SELECT generate_series(timestamp '2020-01-01', timestamp '2020-01-01', interval '1' day);
----
['2020-01-01 00:00:00']
query I
SELECT range(timestamp '2020-01-01', timestamp '2020-01-01', interval '1' day);
----
[]
# positive interval but start > end
query I
SELECT generate_series(timestamp '2020-06-01', timestamp '2020-01-01', interval '3' month);
----
[]
# negative interval but start < end
query I
SELECT generate_series(timestamp '2020-01-01', timestamp '2020-06-01', -interval '3' month);
----
[]
# null values
query I
SELECT generate_series(NULL, timestamp '2020-06-01', -interval '3' month);
----
NULL
query I
SELECT generate_series(timestamp '2020-01-01', NULL, -interval '3' month);
----
NULL
query I
SELECT generate_series(timestamp '2020-01-01', timestamp '2020-06-01', NULL);
----
NULL
# mixed sign interval not supported
statement error
SELECT generate_series(timestamp '2020-01-01', timestamp '2020-06-01', interval '3' month - interval '3' day);
----
# Infinities will overflow or cause infinite loops so we ban them
statement error
SELECT generate_series('294247-01-10'::TIMESTAMP, 'infinity'::TIMESTAMP, INTERVAL '1 DAY');
----
statement error
SELECT range('294247-01-10'::TIMESTAMP, 'infinity'::TIMESTAMP, INTERVAL '1 DAY');
----
statement error
SELECT generate_series('-infinity'::TIMESTAMP, '290309-12-22 (BC) 00:00:00'::TIMESTAMP, INTERVAL '1 DAY');
----
statement error
SELECT range('-infinity'::TIMESTAMP, '290309-12-22 (BC) 00:00:00'::TIMESTAMP, INTERVAL '1 DAY');
----
statement ok
PRAGMA disable_verification
# > vector size
query I
SELECT count(*) FROM (
SELECT unnest(generate_series(timestamp '2000-01-01', timestamp '2020-06-01', interval '1' day))
);
----
7458

View File

@@ -0,0 +1,23 @@
# name: test/sql/function/list/generate_subscripts.test
# description: Test generate_subscripts function
# group: [list]
query I
SELECT generate_subscripts([4,5,6], 1)
----
1
2
3
query I
SELECT generate_subscripts([], 1)
----
query I
SELECT generate_subscripts(NULL, 1)
----
statement error
SELECT generate_subscripts([[1,2],[3,4],[5,6]], 2)
----
<REGEX>:.*Not implemented Error.*not implemented.*

View File

@@ -0,0 +1,125 @@
# name: test/sql/function/list/icu_generate_series_timestamptz.test
# description: Test generate_series/range function for TIMESTAMPTZ
# group: [list]
require icu
statement ok
SET Calendar = 'gregorian';
statement ok
SET TimeZone = 'America/Los_Angeles';
# standard generate_series (inclusive bound)
query I
SELECT generate_series(timestamptz '2020-01-01', timestamptz '2020-07-01', interval '3' month);
----
['2020-01-01 00:00:00-08', '2020-04-01 00:00:00-07', '2020-07-01 00:00:00-07']
# exclusive bound
query I
SELECT range(timestamptz '2020-01-01', timestamptz '2020-07-01', interval '3' month);
----
['2020-01-01 00:00:00-08', '2020-04-01 00:00:00-07']
# negative interval
query I
SELECT generate_series(timestamptz '2020-06-01', timestamptz '2020-01-01', -interval '3' month);
----
['2020-06-01 00:00:00-07', '2020-03-01 00:00:00-08']
# start = end
query I
SELECT generate_series(timestamptz '2020-01-01', timestamptz '2020-01-01', interval '1' day);
----
['2020-01-01 00:00:00-08']
query I
SELECT range(timestamptz '2020-01-01', timestamptz '2020-01-01', interval '1' day);
----
[]
# positive interval but start > end
query I
SELECT generate_series(timestamptz '2020-06-01', timestamptz '2020-01-01', interval '3' month);
----
[]
# negative interval but start < end
query I
SELECT generate_series(timestamptz '2020-01-01', timestamptz '2020-06-01', -interval '3' month);
----
[]
# null values
query I
SELECT generate_series(NULL, timestamp '2020-06-01', -interval '3' month);
----
NULL
query I
SELECT generate_series(timestamp '2020-01-01', NULL, -interval '3' month);
----
NULL
query I
SELECT generate_series(timestamp '2020-01-01', timestamp '2020-06-01', NULL);
----
NULL
# > vector size
query I
SELECT count(*) FROM (
SELECT unnest(generate_series(timestamptz '2000-01-01', timestamptz '2020-06-01', interval '1' day))
);
----
7458
query I
SELECT generate_series(start, stop, step) FROM (VALUES
(timestamptz '2020-01-01', timestamptz '2020-07-01', interval '3' month),
(timestamptz '2020-12-04', timestamptz '2020-09-01', interval '-1 month -1 day'),
(timestamptz '2020-03-08', timestamptz '2020-03-09', interval '6' hour),
(timestamptz '2020-11-02', timestamptz '2020-11-01', interval '-43200' second),
) AS _(start, stop, step);
----
['2020-01-01 00:00:00-08', '2020-04-01 00:00:00-07', '2020-07-01 00:00:00-07']
['2020-12-04 00:00:00-08', '2020-11-03 00:00:00-08', '2020-10-02 00:00:00-07', '2020-09-01 00:00:00-07']
['2020-03-08 00:00:00-08', '2020-03-08 07:00:00-07', '2020-03-08 13:00:00-07', '2020-03-08 19:00:00-07']
['2020-11-02 00:00:00-08', '2020-11-01 12:00:00-08', '2020-11-01 01:00:00-07']
query I
SELECT range(start, stop, step) FROM (VALUES
(timestamptz '2020-01-01', timestamptz '2020-07-01', interval '3' month),
(timestamptz '2020-12-04', timestamptz '2020-09-01', interval '-1 month -1 day'),
(timestamptz '2020-03-08', timestamptz '2020-03-09', interval '6' hour),
(timestamptz '2020-11-02', timestamptz '2020-11-01', interval '-43200' second),
) AS _(start, stop, step);
----
['2020-01-01 00:00:00-08', '2020-04-01 00:00:00-07']
['2020-12-04 00:00:00-08', '2020-11-03 00:00:00-08', '2020-10-02 00:00:00-07']
['2020-03-08 00:00:00-08', '2020-03-08 07:00:00-07', '2020-03-08 13:00:00-07', '2020-03-08 19:00:00-07']
['2020-11-02 00:00:00-08', '2020-11-01 12:00:00-08', '2020-11-01 01:00:00-07']
# mixed sign interval not supported
statement error
SELECT generate_series(timestamptz '2020-01-01', timestamptz '2020-06-01', interval '3' month - interval '3' day);
----
# Infinities will overflow or cause infinite loops so we ban them
statement error
SELECT generate_series('294247-01-10'::TIMESTAMPTZ, 'infinity'::TIMESTAMPTZ, INTERVAL '1 DAY');
----
statement error
SELECT range('294247-01-10'::TIMESTAMPTZ, 'infinity'::TIMESTAMPTZ, INTERVAL '1 DAY');
----
statement error
SELECT generate_series('-infinity'::TIMESTAMPTZ, '290309-12-22 (BC) 00:00:00'::TIMESTAMPTZ, INTERVAL '1 DAY');
----
statement error
SELECT range('-infinity'::TIMESTAMPTZ, '290309-12-22 (BC) 00:00:00'::TIMESTAMPTZ, INTERVAL '1 DAY');
----

View File

@@ -0,0 +1,8 @@
# name: test/sql/function/list/lambda_constant_null.test
# description: Test constant NULL values in lambdas
# group: [list]
statement error
SELECT quantile(NULL, filter(NULL, (lambda c103: 'babea54a-2261-4b0c-b14b-1d0e9b794e1a')));
----
QUANTILE argument must not be NULL

View File

@@ -0,0 +1,158 @@
# name: test/sql/function/list/lambdas/arrow/expression_iterator_cases_deprecated.test
# description: Test the different possible cases of the expression iterator
# group: [arrow]
# these tests check the different cases of the expression iterator
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# this BOUND_AGGREGATE is a constant, so we can allow it inside lambda functions
query I
SELECT list_transform([10], x -> sum(1) + x)
----
[11]
query I
SELECT list_filter([10], x -> sum(1) > 0)
----
[10]
# BOUND_BETWEEN
query I
SELECT list_transform([NULL, DATE '1992-09-20', DATE '2021-09-20'], elem -> extract('year' FROM elem) BETWEEN 2000 AND 2022)
----
[NULL, false, true]
query I
SELECT list_filter([NULL, DATE '1992-09-20', DATE '2021-09-20'], elem -> extract('year' FROM elem) BETWEEN 2000 AND 2022)
----
[2021-09-20]
# BOUND_CASE
query I
SELECT list_transform(['hello', 'duck', 'sunshine'], str -> CASE WHEN str LIKE '%e%' THEN 'e' ELSE 'other' END)
----
[e, other, e]
query I
SELECT list_filter(['hello', 'duck', 'sunshine'], str -> (CASE WHEN str LIKE '%e%' THEN 'e' ELSE 'other' END) LIKE 'e')
----
[hello, sunshine]
# BOUND_CAST
query I
SELECT list_transform([2.0::DOUBLE], x -> x::INTEGER)
----
[2]
query I
SELECT list_filter([2], x -> x::DOUBLE == 2)
----
[2]
# BOUND_COMPARISON
query I
SELECT list_transform([2.4, NULL, -4.7], x -> x != 10.4)
----
[true, NULL, true]
query I
SELECT list_filter([2.4, NULL, -4.7], x -> x != -4.7)
----
[2.4]
# BOUND_CONJUNCTION
query I
SELECT list_transform([True, False, NULL], x -> x AND true)
----
[true, false, NULL]
query I
SELECT list_filter([True, False, NULL], x -> x AND true)
----
[true]
# BOUND_FUNCTION
query I
SELECT list_transform([TIMESTAMP '1992-03-22', TIMESTAMP '209-03-22', TIMESTAMP '1700-03-22'], x -> century(x))
----
[20, 3, 17]
query I
SELECT list_filter([TIMESTAMP '1992-03-22', TIMESTAMP '209-03-22', TIMESTAMP '1700-03-22'], x -> century(x) > 16)
----
['1992-03-22 00:00:00', '1700-03-22 00:00:00']
# BOUND_OPERATOR
query I
SELECT list_transform([2], x -> x + x)
----
[4]
query I
SELECT list_filter([2], x -> x + x = 4)
----
[2]
# BOUND_SUBQUERY
statement error
SELECT list_transform([2], x -> (SELECT 1 - x) * x)
----
<REGEX>:Binder Error.*subqueries in lambda expressions are not supported.*
statement error
SELECT list_filter([2], x -> (SELECT 1 - x) * x > 2)
----
<REGEX>:Binder Error.*subqueries in lambda expressions are not supported.*
statement ok
CREATE MACRO list_contains_macro(x, y) AS (SELECT list_contains(x, y))
statement error
SELECT list_filter([[1, 2, 1], [1, 2, 3], [1, 1, 1]], x -> list_contains_macro(x, 3))
----
<REGEX>:Binder Error.*subqueries in lambda expressions are not supported.*
# BOUND_UNNEST
statement error
SELECT list_transform([1], x -> x = UNNEST([1]));
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
statement error
SELECT list_filter([1], x -> x = UNNEST([1]));
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
# BOUND_WINDOW
statement ok
CREATE TABLE my_window (l integer[], g integer, o integer)
statement ok
INSERT INTO my_window VALUES ([1], 1, 1), ([1, NULL, 2], 1, 2), ([], 2, 3), (NULL, NULL, NULL), ([1, 2], 2, 4)
query I
SELECT list(list_transform(l, e -> e + 1)) OVER (PARTITION BY g ORDER BY o)
FROM my_window
ORDER BY ALL
----
[[]]
[[], [2, 3]]
[[2]]
[[2], [2, NULL, 3]]
[NULL]

View File

@@ -0,0 +1,244 @@
# name: test/sql/function/list/lambdas/arrow/filter_deprecated.test
# description: Test list_filter function
# group: [arrow]
# NOTE: some of these tests are directly taken from the Presto Array Function examples
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# test NULLs and simple cases
query II
SELECT [1] AS l, list_filter([1], l -> l > 1)
----
[1] []
query I
SELECT list_filter(NULL, x -> x > 1)
----
NULL
query I
SELECT list_filter([True], x -> x)
----
[true]
query I
SELECT list_filter(['duck', 'a', 'ö'], duck -> contains(concat(duck, 'DB'), 'duck'))
----
[duck]
query I
SELECT list_filter([1, 2, 3], x -> x % 2 = 0)
----
[2]
query I
SELECT list_filter([], x -> x > 1)
----
[]
query I
SELECT list_filter([1, NULL, -2, NULL], x -> x % 2 != 0)
----
[1]
query I
SELECT list_filter([5, -6, NULL, 7], x -> x > 0)
----
[5, 7]
query I
SELECT list_filter([5, NULL, 7, NULL], x -> x IS NOT NULL)
----
[5, 7]
# test on table with rows
statement ok
CREATE TABLE lists (n integer, l integer[])
statement ok
INSERT INTO lists VALUES (1, [1]), (2, [1, 2, 3]), (3, NULL), (4, [-1, NULL, 2])
query I
SELECT list_filter(l, x -> x + 1 <= 2) FROM lists
----
[1]
[1]
NULL
[-1]
query I
SELECT list_filter(l, x -> x <= n) FROM lists
----
[1]
[1, 2]
NULL
[-1, 2]
query I
SELECT list_filter(l, x -> x IS NOT NULL) FROM lists
----
[1]
[1, 2, 3]
NULL
[-1, 2]
# test other operators and more complex/nested functions
query I
SELECT list_filter(['x', 'abc', 'z'], x -> contains(x || '0', 'a'))
----
[abc]
query I
SELECT list_transform([[1, 3], [2, 3, 1], [2, 4, 2]], x -> list_filter(x, y -> y <= 2))
----
[[1], [2, 1], [2, 2]]
query I
SELECT list_concat(list_filter([42, -42, 8, -5, 2], elem -> elem > 0)::varchar[], list_filter(['enjoy', 'life', 'to', 'the', 'fullest'], str -> str ILIKE '%e%'))
----
[42, 8, 2, enjoy, life, the, fullest]
# test aliases
query I
SELECT array_filter([1, NULL], arr_elem -> arr_elem < 4)
----
[1]
# test many empty lists
statement ok
CREATE TABLE empty_lists (l integer[])
statement ok
INSERT INTO empty_lists VALUES ([]), ([]), ([]), ([1, NULL, -1]), ([]), (NULL), (NULL), ([]), ([1, 2, 3]), ([]), ([]), ([]);
query I
SELECT list_filter(l, x -> x > 0) FROM empty_lists
----
[]
[]
[]
[1]
[]
NULL
NULL
[]
[1, 2, 3]
[]
[]
[]
# very large lists
statement ok
CREATE TABLE large_lists AS SELECT range % 4 g, list(range) l FROM range(10000) GROUP BY range % 4;
query II
SELECT g, list_count(list_filter(l, x -> x % 2 = 0)) FROM large_lists ORDER BY g
----
0 2500
1 0
2 2500
3 0
# test correlated subqueries
statement ok
CREATE TABLE corr_test (n integer, l varchar[], g integer)
statement ok
INSERT INTO corr_test VALUES (1, ['a', '11', '23'], 1), (3, [NULL, '2', 'hello', 'wie gehts'], 1), (NULL, NULL, 1), (0, [], 1)
query I
SELECT n FROM corr_test WHERE list_count(list_filter(l, elem -> length(elem) >= n)) >= n
----
1
0
query I
SELECT ct.n FROM corr_test ct
WHERE list_count(ct.l) < (SELECT list_count(list_filter(list_concat(list(c.n)::varchar[], ct.l), a -> length(a) >= 1)) FROM corr_test c GROUP BY c.g)
ORDER BY ct.n
----
0
1
3
query I
SELECT (SELECT list_filter(l, elem -> length(elem) >= 1)) FROM corr_test
----
[a, 11, 23]
[2, hello, wie gehts]
NULL
[]
query I
SELECT (SELECT list_filter(l, elem -> length(elem) >= n)) FROM corr_test
----
[a, 11, 23]
[hello, wie gehts]
NULL
[]
query I
SELECT (SELECT (SELECT (SELECT list_filter(l, elem -> length(elem) >= 1)))) FROM corr_test
----
[a, 11, 23]
[2, hello, wie gehts]
NULL
[]
# positional references in lambda functions
query I
SELECT list_filter([1, 2, 3, 4, 5, 6, 7, 8, 9], x -> x > #1) FROM range(10)
----
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 3, 4, 5, 6, 7, 8, 9]
[3, 4, 5, 6, 7, 8, 9]
[4, 5, 6, 7, 8, 9]
[5, 6, 7, 8, 9]
[6, 7, 8, 9]
[7, 8, 9]
[8, 9]
[9]
[]
# fixes 5816
# auto casting in list_filter, or exception if not possible (casting is strict)
statement ok
create table lambdas AS SELECT [5,6] AS col1, [4,8] AS col2;
query I
SELECT list_apply(col1, x -> list_filter(col2, y -> y)) from lambdas;
----
[[4, 8], [4, 8]]
query I
SELECT list_apply([5,6], x -> list_filter([4,8], y -> y));
----
[[4, 8], [4, 8]]
query I
SELECT list_apply([[5,6]], x -> list_filter(x, y -> y));
----
[[5, 6]]
statement error
SELECT list_transform([['abc']], x -> list_filter(x, y -> y));
----
Conversion Error: Could not convert string 'abc' to BOOL
query II
select [[y] for y in range(5)] as c, [x for x in c if x IS NOT NULL];
----
[[0], [1], [2], [3], [4]] [[0], [1], [2], [3], [4]]

View File

@@ -0,0 +1,171 @@
# name: test/sql/function/list/lambdas/arrow/lambda_scope_deprecated.test
# description: Test the scoping of lambda variables.
# group: [arrow]
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# Lambda parameters have precedence over columns.
statement ok
CREATE TABLE t1 AS SELECT [1, 2, 3] AS x;
query I
SELECT list_apply(['hello'], x -> x) FROM t1;
----
[hello]
statement ok
CREATE TABLE t2 AS SELECT [[1], [2], [3]] AS x;
query I
SELECT list_transform([[1], [2], [3]], x -> x[1]) FROM t2;
----
[1, 2, 3]
statement ok
CREATE TABLE l_test (l integer[]);
statement ok
INSERT INTO l_test VALUES ([1, 2, 3]);
query II
SELECT l, list_transform(l, l -> l + 1) FROM l_test;
----
[1, 2, 3] [2, 3, 4]
statement ok
CREATE TABLE l_filter_test (l integer[]);
statement ok
INSERT INTO l_filter_test VALUES ([1, 2]);
query II
SELECT l, list_filter(l, l -> l > 1) FROM l_filter_test;
----
[1, 2] [2]
# don't allow qualified lambda parameters (LHS parameters)
statement error
SELECT list_apply(i, a.x -> a.x + 1) FROM (VALUES (list_value(1, 2, 3))) tbl(i);
----
Invalid lambda parameters
statement ok
CREATE TABLE qualified_tbl (x INTEGER[]);
statement ok
INSERT INTO qualified_tbl VALUES ([1, 2]);
query I
SELECT list_transform(qualified_tbl.x, x -> (qualified_tbl.x)[1] + 1 + x) FROM qualified_tbl;
----
[3, 4]
statement error
SELECT list_transform(qualified_tbl.x, qualified_tbl.x -> qualified_tbl.x + 1) FROM qualified_tbl;
----
Invalid lambda parameters
# previously ambiguous lambda parameters
# issue #9970
query I
SELECT list_transform([1, 2], x -> list_transform([3, 4], x -> x));
----
[[3, 4], [3, 4]]
query I
SELECT list_has_all([variable_has_all FOR variable_has_all IN ['a']], ['b']) AS list_comp_result;
----
false
query I
SELECT list_has_all(list_transform(['a'], variable_has_all -> variable_has_all), ['b']) AS list_transform_result;
----
false
query I
SELECT list_has_any(['b'], list_transform(['a'], variable_has_any -> variable_has_any)) AS list_transform_result;
----
false
query I
SELECT list_intersect(list_intersect([1], [1]), [1])
----
[1]
query I
SELECT list_intersect([1], list_intersect([1], [1]))
----
[1]
query I
SELECT list_has_any(LIST_VALUE(list_has_any([1], [1])), [1])
----
true
query I
SELECT list_has_any([1], LIST_VALUE(list_has_any([1], [1])))
----
true
query I
SELECT list_has_all(LIST_VALUE(list_has_all([1], [1])), [1])
----
true
query I
SELECT list_has_all([1], LIST_VALUE(list_has_all([1], [1])))
----
true
query I
SELECT list_has_any(LIST_VALUE(list_has_all(list_intersect([1], [1]), [1])), [1]);
----
true
query I
SELECT list_has_all(LIST_VALUE(list_has_any(list_intersect([1], [1]), [1])), [1]);
----
true
query I
SELECT list_intersect(LIST_VALUE(list_has_all(LIST_VALUE(list_has_any([1], [1])), [1])), [1])
----
[true]
query I
SELECT list_intersect(list_intersect([1, 2, 3, 4], [4, 5, 6, 7]), list_intersect([4, 5, 6, 7], [1, 2, 3, 4]));
----
[4]
# more tests for qualifying column names
statement ok
CREATE TABLE tbl_qualified AS SELECT 42 AS x;
query II
SELECT x, list_transform([1], x -> x) FROM tbl_qualified;
----
42 [1]
statement error
SELECT list_transform([1,2,3], sqrt(xxx.z) -> xxx.z + 1) AS l ;
----
Invalid lambda parameters
query I
SELECT list_transform([1, 2, 3], "x.y" -> "x.y" + x.y) AS l FROM (VALUES (42), (84)) x(y);
----
[43, 44, 45]
[85, 86, 87]
statement error
SELECT list_reduce([1, 2, 3, 4], x *++++++++* y -> x - y) AS l;
----
Binder Error: Invalid lambda parameters!

View File

@@ -0,0 +1,38 @@
# name: test/sql/function/list/lambdas/arrow/lambdas_and_functions_deprecated.test
# description: Test mixing lambdas and functions
# group: [arrow]
require json
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
statement ok
CREATE OR REPLACE function demo(n, z) AS TABLE (
SELECT list_transform(range(0, n), x -> z) AS row
);
query I
FROM demo(3, 0);
----
[0, 0, 0]
statement ok
CREATE OR REPLACE function demo(n, z) AS TABLE (
SELECT list_transform(range(0, n), x -> 0 + z) AS row
);
query I
FROM demo(3, 0);
----
[0, 0, 0]
statement ok
CREATE OR REPLACE function demo(n, z) AS TABLE (
SELECT list_transform(range(0, n), x -> (z -> 'a')) AS row
);
query I
FROM demo(3, {'a': 2});
----
[2, 2, 2]

View File

@@ -0,0 +1,54 @@
# name: test/sql/function/list/lambdas/arrow/lambdas_and_group_by_deprecated.test
# description: Test lambdas with aggregations
# group: [arrow]
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
statement ok
CREATE TABLE tbl (tag_product VARCHAR);
statement ok
INSERT INTO tbl VALUES ('milk chickpeas apples'), ('chocolate pepper');
query II
SELECT tag_product, list_aggr(list_transform(
string_split(tag_product, ' '), word -> lower(word)),
'string_agg', ',') AS tag_material,
FROM tbl GROUP BY tag_product
ORDER BY ALL;
----
chocolate pepper chocolate,pepper
milk chickpeas apples milk,chickpeas,apples
query II
SELECT 1, list_transform([5, 4, 3], x -> x + 1) AS lst GROUP BY 1;
----
1 [6, 5, 4]
statement ok
CREATE TABLE uniform_purchase_forecast AS
SELECT 'gold' AS color, 10 AS forecast
UNION ALL SELECT 'blue', 15
UNION ALL SELECT 'red', 300;
query I
FROM uniform_purchase_forecast SELECT list(forecast).list_transform(x -> x + 10);
----
[20, 25, 310]
# HAVING binder issues.
query I
FROM (SELECT 1) GROUP BY ALL HAVING list_filter(NULL, x -> x);
----
statement ok
FROM test_all_types() GROUP BY ALL HAVING array_intersect(NULL, NULL);
query I
SELECT x FROM (VALUES (42)) t(x) GROUP BY x HAVING list_filter(NULL, lambda_param -> lambda_param = 1);
----

View File

@@ -0,0 +1,74 @@
# name: test/sql/function/list/lambdas/arrow/lambdas_and_macros_deprecated.test
# description: Test mixing lambdas and macros
# group: [arrow]
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# conflicting column names
statement ok
create table test as select range i from range(3);
statement error
create macro my_macro(i) as (select i in (select i from test));
----
Binder Error: Conflicting column names for column i!
statement ok
CREATE MACRO list_contains_macro(x, y) AS (list_contains(x, y))
query I
SELECT list_filter([[1, 2, 1], [1, 2, 3], [1, 1, 1]], x -> list_contains_macro(x, 3))
----
[[1, 2, 3]]
statement ok
CREATE MACRO macro_with_lambda(list, num) AS (list_transform(list, x -> x + num))
query I
SELECT list_filter([[1, 2], NULL, [3], [4, NULL]], f -> list_count(macro_with_lambda(f, 2)) > 1)
----
[[1, 2]]
# this is a bit more tricky, because the operator mismatch is only detected when using the macro
statement ok
CREATE MACRO some_macro(x, y, z) AS (SELECT list_transform(x, a -> x + y + z))
statement error
SELECT some_macro([1, 2], 3, 4);
----
statement ok
CREATE MACRO reduce_macro(list, num) AS (list_reduce(list, (x, y) -> x + y + num))
query I
SELECT reduce_macro([1, 2, 3, 4], 5);
----
25
statement ok
CREATE MACRO other_reduce_macro(list, num, bla) AS (SELECT list_reduce(list, (x, y) -> list + x + y + num + bla))
statement error
SELECT other_reduce_macro([1, 2, 3, 4], 5, 6);
----
# lambda scoping
statement ok
CREATE MACRO scoping_macro(x, y, z) AS (SELECT list_transform(x, x -> x + y + z));
query I
SELECT scoping_macro([11, 22], 3, 4);
----
[18, 29]
statement ok
CREATE OR REPLACE MACRO foo(bar) AS (SELECT apply([bar], x -> 0));
statement ok
SELECT foo(v) FROM (SELECT 0 AS v);

View File

@@ -0,0 +1,99 @@
# name: test/sql/function/list/lambdas/arrow/list_comprehension_deprecated.test
# description: Test different examples that can be found when searching for python list comprehension examples
# group: [arrow]
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# even squares
query I
SELECT list_transform(list_filter([0, 1, 2, 3, 4, 5], x -> x % 2 = 0), y -> y * y)
----
[0, 4, 16]
query I
SELECT [x * x for x in [0, 1, 2, 3, 4, 5] if x%2=0]
----
[0, 4, 16]
# divisible by 2 and 5
query I
SELECT list_filter(list_filter([2, 4, 3, 1, 20, 10, 3, 30], x -> x % 2 == 0), y -> y % 5 == 0)
----
[20, 10, 30]
query I
SELECT [x for x in [x for x in [2, 4, 3, 1, 20, 10, 3, 30] if x % 2 == 0] if x % 5 == 0]
----
[20, 10, 30]
query I
SELECT list_filter(['apple', 'banana', 'cherry', 'kiwi', 'mango'], fruit -> contains(fruit, 'a'))
----
[apple, banana, mango]
query I
SELECT [fruit for fruit in ['apple', 'banana', 'cherry', 'kiwi', 'mango'] if contains(fruit, 'a')]
----
[apple, banana, mango]
statement ok
CREATE TABLE fruit_tbl AS SELECT ['apple', 'banana', 'cherry', 'kiwi', 'mango'] fruits
query I
SELECT [fruit for fruit in fruits if contains(fruit, 'a')] FROM fruit_tbl
----
[apple, banana, mango]
query I
SELECT list_transform([[1, NULL, 2], [3, NULL]], a -> list_filter(a, x -> x IS NOT NULL))
----
[[1, 2], [3]]
query I
SELECT [len(x) for x in ['goodbye', 'cruel', 'world']]
----
[7, 5, 5]
statement ok
CREATE TABLE word_tbl AS SELECT ['goodbye', 'cruel', 'world'] words
query I
SELECT [len(x) for x in words] from word_tbl
----
[7, 5, 5]
query I
with base as (
select [4,5,6] as l
)
select [x for x,i in l if i != 2] as filtered from base;
----
[4, 6]
query I
select [x+i for x, i in [10, 9, 8, 7, 6]]
----
[11, 11, 11, 11, 11]
query I
with base as (
select [4,5,6] as l
)
select [x + 5 for x in l] as filtered from base;
----
[9, 10, 11]
statement error
select [a for a, b, c in [1,2,3]];
----
This lambda function only supports up to two lambda parameters!
statement error
select [a for a[1], b[2] in [1,2,3,4]];
----
Parser Error: syntax error at or near "["

View File

@@ -0,0 +1,418 @@
# name: test/sql/function/list/lambdas/arrow/reduce_deprecated.test
# description: Test list_reduce function
# group: [arrow]
statement ok
pragma enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
query I
SELECT list_reduce([1, 2, 3], (x, y) -> x + y);
----
6
query I
SELECT list_reduce([1, 2, 3], (x, y) -> x * y);
----
6
query I
SELECT list_reduce([100, 10, 1], (x, y, i) -> x - y - i);
----
84
query I
SELECT list_reduce([1, 2, 3], (x, y) -> y - x);
----
2
query I
SELECT list_reduce([1, 2, 3], (x, y) -> x - y);
----
-4
query I
SELECT list_reduce([1, 2, 3], (x, y, i) -> x + y + i);
----
11
query I
SELECT list_reduce([NULL], (x, y, i) -> x + y + i);
----
NULL
query I
SELECT list_reduce(NULL, (x, y, i) -> x + y + i);
----
NULL
query I
SELECT list_reduce(['Once', 'upon', 'a', 'time'], (x, y) -> x || ' ' || y);
----
Once upon a time
query I
SELECT list_reduce(['a', 'b', 'c', 'd'], (x, y, i) -> x || ' - ' || CAST(i AS VARCHAR) || ' - ' || y);
----
a - 2 - b - 3 - c - 4 - d
#errors on simple reduce
statement error
SELECT list_reduce([], (x, y, i) -> x + y + i);
----
Cannot perform list_reduce on an empty input list
statement error
SELECT list_reduce([1, 2, 3], (x, y) -> (x * y)::VARCHAR || 'please work');
----
Could not convert
statement error
SELECT list_reduce([1, 2], (x) -> x);
----
list_reduce expects a function with 2 or 3 arguments
statement error
SELECT list_reduce([1, 2], NULL);
----
Invalid lambda expression!
statement error
SELECt list_reduce([1, 2], (len('abc') AS x, y) - > x + y)
----
Parser Error: syntax error at or near "AS"
# simple reduce on a table
statement ok
CREATE table t1(a int[]);
statement ok
INSERT INTO t1 VALUES ([1, 2, 3]);
statement ok
INSERT INTO t1 VALUES ([666]);
statement ok
INSERT INTO t1 VALUES (NULL);
statement ok
INSERT INTO t1 VALUES ([44, 55]);
statement ok
INSERT INTO t1 VALUES ([-1, NULL, -2]);
query I
SELECT list_reduce(a, (x, y) -> x + y) FROM t1;
----
6
666
NULL
99
NULL
query I
SELECT list_reduce(a, (x, y, i) -> x + y + i) FROM t1;
----
11
666
NULL
101
NULL
statement ok
INSERT INTO t1 VALUES ([]);
statement error
SELECT list_reduce(a, (x, y) -> x + y) FROM t1;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE t1;
# reduce on a table with a list of strings
statement ok
CREATE TABLE t1 (a varchar[]);
statement ok
INSERT INTO t1 VALUES (['Once', 'upon', 'a', 'time']), (NULL), (['there', 'was', 'a', 'table']), (['with', 'a', 'list', 'of', 'strings']), (['and', 'it', 'was', NULL]);
query I
SELECT list_reduce(a, (x, y) -> x || ' ' || y) FROM t1;
----
Once upon a time
NULL
there was a table
with a list of strings
NULL
statement ok
INSERT INTO t1 VALUES ([]);
statement error
SELECT list_reduce(a, (x, y) -> x || ' ' || y) FROM t1;
----
Cannot perform list_reduce on an empty input list
# reduce on a string only using the RHS
statement ok
CREATE TABLE right_only (v varchar[], i int);
statement ok
INSERT INTO right_only VALUES (['blue', 'babbling', 'brook'], 1), (['dogs', 'doing', 'dishes'], 2), (['she', 'sells', 'seashells'], 3);
query I
SELECT list_reduce(v, (x, y) -> y[i]) FROM right_only;
----
b
i
a
# nested functions with ints
query I
SELECT list_reduce([1, 2, 3], (x, y) -> list_reduce([4, 5, 6], (a, b) -> x + y + a + b));
----
63
statement error
SELECT list_reduce([1, 2, 3], (x, y) -> list_reduce([], (a, b) -> x + y + a + b));
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([1, 2, 3], (x, y, x_i) -> list_reduce([4, 5, 6], (a, b, a_i) -> x + y + a + b + x_i + a_i));
----
92
statement error
SELECT list_reduce([1, 2, 3], (x, y, x_i) -> list_reduce([], (a, b, a_i) -> x + y + a + b + x_i + a_i));
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([[10, 20], [30, 40], [50, 60]], (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (n, o) -> n + o)));
----
[210]
query I
SELECT list_reduce([[1,2,3], [4,5,6], [7,8,9]], (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (n, o) -> n + o)));
----
[45]
query I
SELECT list_reduce([[10, 20], [30, 40], NULL, [NULL, 60], NULL], (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (n, o) -> n + o)));
----
[NULL]
# nested functions with strings
query I
SELECT list_reduce(['a', 'b', 'c', 'd'], (x, y) -> list_reduce(['1', '2', '3', '4'], (a, b) -> x || y || a || b));
----
ababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234d1234
query I
SELECT list_reduce([['a', 'b'], ['c', 'd'], ['e', 'f']], (x, y) -> list_pack(list_reduce(x, (a, b) -> a || b) || list_reduce(y, (c, d) -> c || d)));
----
[abcdef]
# nested functions in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[])
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6]), (NULL, NULL), (NULL, [110, 111, 112]), ([77, 88, 99], [55, 66, NULL]);
query I
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> x + y + a + b)) FROM nested;
----
63
NULL
NULL
NULL
query I
SELECT list_reduce(n, (x, y, x_i) -> list_reduce(l, (a, b, a_i) -> x + y + a + b + x_i + a_i)) FROM nested;
----
92
NULL
NULL
NULL
query I
SELECT list_reduce(n, (x, y, x_i) -> list_reduce(l, (a, b, a_i) -> x + y + x_i < a + b + a_i)) FROM nested;
----
1
NULL
NULL
NULL
statement ok
INSERT INTO nested VALUES ([4, 5, 6], []);
statement error
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> x + y + a + b)) FROM nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][])
statement ok
INSERT INTO nested VALUES ([[10, 20], [30, 40], [50, 60]]), ([[1,2,3], [4,5,6], [7,8,9]]), (NULL), ([[NULL, 60], [70, NULL], [NULL, NULL]]);
query I
SELECT list_reduce(n, (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (j, k) -> j + k))) from nested;
----
[210]
[45]
NULL
[NULL]
statement ok
INSERT INTO nested VALUES ([[4, 5, 6], []]);
statement error
SELECT list_reduce(n, (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (j, k) -> j + k))) from nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
# nested functions in a table with strings
statement ok
CREATE TABLE nested (n varchar[], l varchar[])
statement ok
INSERT INTO nested VALUES (['a', 'b', 'c', 'd'], ['1', '2', '3', '4']), (NULL, NULL), (NULL, ['110', '111', '112']), (['77', '88', '99'], ['55', '66', NULL]);
query I
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> x || y || a || b)) FROM nested;
----
ababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234d1234
NULL
NULL
NULL
statement ok
DROP TABLE nested;
# three level nested functions with ints
query I
SELECT list_reduce([1, 2, 3], (x, y) -> list_reduce([4, 5, 6], (a, b) -> list_reduce([7, 8, 9], (c, d) -> x + y + a + b + c + d)));
----
966
query I
SELECT list_reduce([1, 2, 3], (x, y, x_i) -> list_reduce([4, 5, 6], (a, b, a_i) -> list_reduce([7, 8, 9], (c, d, c_i) -> x + y + a + b + c + d + x_i + a_i + c_i)));
----
1259
query I
SELECT list_reduce([[[10, 20], [100, 200]], [[30, 40], [300, 400]], [[50, 60], [500, 600]]], (x, y) -> list_pack(list_reduce(x, (l, m) -> list_pack(list_reduce(l, (a, b) -> a + b) + list_reduce(m, (c, d) -> c + d))) + list_reduce(y, (n, o) -> list_pack(list_reduce(n, (a, b) -> a + b) + list_reduce(o, (c, d) -> c + d)))));
----
[[330, 770, 1210]]
# three level nested in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[], m integer[])
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6], [7, 8, 9]), (NULL, NULL, NULL), (NULL, [110, 111, 112], [113, 114, 115]), ([77, 88, 99], [55, 66, NULL], [44, 33, 22]);
query I
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> list_reduce(m, (c, d) -> x + y + a + b + c + d))) FROM nested;
----
966
NULL
NULL
NULL
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][][])
statement ok
INSERT INTO nested VALUES ([[[10, 20], [100, 200]], [[30, 40], [300, 400]], [[50, 60], [500, 600]]]), ([[[1,2,3], [4,5,6], [7,8,9]]]), (NULL), ([[[NULL, 60], [70, NULL], [NULL, NULL]]]);
query I
SELECT list_reduce(n, (x, y) -> list_pack(list_reduce(x, (l, m) -> list_pack(list_reduce(l, (a, b) -> a + b) + list_reduce(m, (c, d) -> c + d))) + list_reduce(y, (e, f) -> list_pack(list_reduce(e, (a, b) -> a + b) + list_reduce(f, (c, d) -> c + d))))) from nested;
----
[[330, 770, 1210]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
NULL
[[NULL, 60], [70, NULL], [NULL, NULL]]
# list_reduce in where clause
statement ok
CREATE table where_clause (a int[]);
statement ok
INSERT INTO where_clause VALUES ([10, 2, 1]), ([1, 2, 3]), ([15, 4, 3]), ([3, 4, 5]), ([11, 2, 3, 4, 5]), ([5, 4, 3, 2, 1]), ([100, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
query I
SELECT a FROM where_clause WHERE list_reduce(a, (x, y) -> x - y) > 0;
----
[10, 2, 1]
[15, 4, 3]
[100, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# tests on structs
statement ok
CREATE TABLE t_struct (s STRUCT(v VARCHAR, i INTEGER)[]);
statement ok
INSERT INTO t_struct VALUES ([row('a', 1), row('b', 2)]), ([row('c', 3), row('d', 4)]), ([row('e', 5), row('f', 6)]), ([row('g', 7), row('h', 8)]), ([row('i', 9), row('j', 10)]);
query I
SELECT list_reduce(s, (a, b) -> row(a.v || b.v, a.i + b.i)) FROM t_struct;
----
{'v': ab, 'i': 3}
{'v': cd, 'i': 7}
{'v': ef, 'i': 11}
{'v': gh, 'i': 15}
{'v': ij, 'i': 19}
# issue #11142
statement ok
CREATE OR REPLACE TABLE df(s STRUCT(a INT, b INT)[]);
statement ok
INSERT INTO df VALUES ([row(0, 0), row(0, 1), row(0, 2)]);
query I
SELECT
list_reduce(
s, (curr, next) -> struct_pack(a:=curr.a + (next.b - curr.b), b:=next.b)
)
FROM df
----
{'a': 2, 'b': 2}
query I
SELECT
list_reduce(
[struct_pack(a:=0, b:=0), struct_pack(a:=0, b:=1), struct_pack(a:=0, b:=2)],
(curr, next) -> struct_pack(a:=curr.a + (next.b - curr.b), b:=next.b)
)
----
{'a': 2, 'b': 2}

View File

@@ -0,0 +1,470 @@
# name: test/sql/function/list/lambdas/arrow/reduce_initial_deprecated.test
# description: Test list_reduce function with an intial value
# group: [arrow]
statement ok
pragma enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
query I
SELECT list_reduce([1, 2, 3], (x, y) -> x + y, 100);
----
106
query I
SELECT list_reduce([1, 2, 3], (x, y) -> x * y, -1);
----
-6
query I
SELECT list_reduce([100, 10, 1], (x, y, i) -> x - y - i, 1000);
----
883
query I
SELECT list_reduce([1, 2, 3], (x, y) -> y - x, -1);
----
3
query I
SELECT list_reduce([1, 2, 3], (x, y) -> x - y, 10);
----
4
query I
SELECT list_reduce([1, 2, 3], (x, y, i) -> x + y + i, -1);
----
11
query I
SELECT list_reduce([1, 2, 3], (x, y) -> x + y, NULL);
----
NULL
query I
SELECT list_reduce([NULL], (x, y, i) -> x + y + i, 100);
----
NULL
query I
SELECT list_reduce(NULL, (x, y, i) -> x + y + i, 100);
----
NULL
query I
SELECT list_reduce(['Once', 'upon', 'a', 'time'], (x, y) -> x || ' ' || y, '-->');
----
--> Once upon a time
query I
SELECT list_reduce([], (x, y) -> x + y, 100);
----
100
query I
SELECT list_reduce(['a', 'b', 'c'], (x, y) -> x || y, NULL);
----
NULL
#errors on simple reduce with initial value
statement error
SELECT list_reduce([1, 2, 3], (x, y) -> (x * y), 'i dare you to cast me');
----
Binder Error
statement error
SELECT list_reduce([1, 2], (x) -> x, 100);
----
list_reduce expects a function with 2 or 3 arguments
statement error
SELECT list_reduce([1, 2], NULL, 100);
----
Invalid lambda expression!
statement error
SELECt list_reduce([1, 2], (len('abc') AS x, y) - > x + y, 100)
----
Parser Error: syntax error at or near "AS"
# simple reduce on a table
statement ok
CREATE table t1(l int[], initial int);
statement ok
INSERT INTO t1 VALUES ([1, 2, 3], 100);
statement ok
INSERT INTO t1 VALUES ([666], 1000);
statement ok
INSERT INTO t1 VALUES ([1, 2, 3], NULL);
statement ok
INSERT INTO t1 VALUES (NULL, 2);
statement ok
INSERT INTO t1 VALUES ([44, 55], 3);
statement ok
INSERT INTO t1 VALUES ([-1, NULL, -2], 4);
query I
SELECT list_reduce(l, (x, y) -> x + y, initial) FROM t1;
----
106
1666
NULL
NULL
102
NULL
query I
SELECT list_reduce(l, (x, y, i) -> x + y + i, initial) FROM t1;
----
112
1667
NULL
NULL
105
NULL
statement ok
INSERT INTO t1 VALUES ([], 100);
statement error
SELECT list_reduce(l, (x, y) -> x + y) FROM t1;
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce(l, (x, y) -> x + y, initial) FROM t1;
----
106
1666
NULL
NULL
102
NULL
100
statement ok
DROP TABLE t1;
# reduce on a table with a list of strings
statement ok
CREATE TABLE t1 (l varchar[], initial varchar);
statement ok
INSERT INTO t1 VALUES (['a', 'b'], '1:'), (NULL, '2:'), (['e', 'f'], '3:');
query I
SELECT list_reduce(l, (x, y) -> x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
statement ok
INSERT INTO t1 values (['h', NULL], '4:'), (['i', 'j'], '5:');
query I
SELECT list_reduce(l, (x, y) -> x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
NULL
5: i j
statement ok
INSERT INTO t1 values (['x', 'y'], NULL);
query I
SELECT list_reduce(l, (x, y) -> x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
NULL
5: i j
NULL
statement ok
INSERT INTO t1 VALUES ([], '7:');
statement error
SELECT list_reduce(l, (x, y) -> x || ' ' || y) FROM t1;
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce(l, (x, y) -> x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
NULL
5: i j
NULL
7:
# reduce on a string only using the RHS
statement ok
CREATE TABLE right_only (v varchar[], i int);
statement ok
INSERT INTO right_only VALUES (['blue', 'babbling', 'brook'], 1), (['dogs', 'doing', 'dishes'], 2), (['she', 'sells', 'seashells'], 3);
query I
SELECT list_reduce(v, (x, y) -> y[i]) FROM right_only;
----
b
i
a
# nested functions with ints
query I
SELECT list_reduce([1, 2, 3], (x, y) -> list_reduce([4, 5, 6], (a, b) -> x + y + a + b, 100), 1000);
----
28549
statement error
SELECT list_reduce([1, 2, 3], (x, y) -> list_reduce([], (a, b) -> x + y + a + b), 1000);
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([1, 2, 3], (x, y, x_i) -> list_reduce([4, 5, 6], (a, b, a_i) -> x + y + a + b + x_i + a_i, 100), 1000);
----
28681
statement error
SELECT list_reduce([1, 2, 3], (x, y, x_i) -> list_reduce([], (a, b, a_i) -> x + y + a + b + x_i + a_i), 1000);
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([[10, 20], [30, 40], [50, 60]], (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (n, o) -> n + o)), [100, 200]);
----
[510]
query I
SELECT list_reduce([[1,2,3], [4,5,6], [7,8,9]], (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (n, o) -> n + o)), [100]);
----
[145]
query I
SELECT list_reduce([[10, 20], [30, 40], NULL, [NULL, 60], NULL], (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (n, o) -> n + o)), [100]);
----
[NULL]
# nested functions with strings
query I
SELECT list_reduce(['a', 'b'], (x, y) -> list_reduce(['1', '2'], (a, b) -> x || y || a || b, 'B'), 'A');
----
AaAaB12bAaAaB12bB12
query I
SELECT list_reduce([['a', 'b'], ['c', 'd'], ['e', 'f']], (x, y) -> list_pack(list_reduce(x, (a, b) -> a || b) || list_reduce(y, (c, d) -> c || d)), ['->']);
----
[->abcdef]
# nested functions in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[], initial integer);
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6], 100), (NULL, NULL, 100), (NULL, [110, 111, 112], 44), ([77, 88, 99], [55, 66, NULL], 1);
query I
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> x + y + a + b), initial) FROM nested;
----
927
NULL
NULL
NULL
query I
SELECT list_reduce(n, (x, y, x_i) -> list_reduce(l, (a, b, a_i) -> x + y + a + b + x_i + a_i), initial) FROM nested;
----
984
NULL
NULL
NULL
query I
SELECT list_reduce(n, (x, y, x_i) -> list_reduce(l, (a, b, a_i) -> x + y + x_i < a + b + a_i), initial) FROM nested;
----
1
NULL
NULL
NULL
statement ok
INSERT INTO nested VALUES ([4, 5, 6], [], -1);
statement error
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> x + y + a + b), initial) FROM nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][], initial integer[]);
statement ok
INSERT INTO nested VALUES ([[10, 20], [30, 40], [50, 60]], [100]), ([[1,2,3], [4,5,6], [7,8,9]], [1000]), (NULL, [-1]), ([[NULL, 60], [70, NULL], [NULL, NULL]], [NULL]);
query I
SELECT list_reduce(n, (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (j, k) -> j + k)), initial) from nested;
----
[310]
[1045]
NULL
[NULL]
statement ok
INSERT INTO nested VALUES ([[4, 5, 6], []], [9]);
statement error
SELECT list_reduce(n, (x, y) -> list_pack(list_reduce(x, (l, m) -> l + m) + list_reduce(y, (j, k) -> j + k)), initial) from nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
# nested functions in a table with strings
statement ok
CREATE TABLE nested (n varchar[], l varchar[], initialN varchar, initialL varchar);
statement ok
INSERT INTO nested VALUES (['a', 'b'], ['1', '2'], 'A', 'B'), (NULL, NULL, 'C', 'D'), (NULL, ['110', '111', '112'], 'X', 'Y'), (['77', '88', '99'], ['55', '66', NULL], 'E', 'F');
query I
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> x || y || a || b, initialL), initialN) FROM nested;
----
AaAaB12bAaAaB12bB12
NULL
NULL
NULL
statement ok
DROP TABLE nested;
# three level nested functions with ints
query I
SELECT list_reduce([1, 2, 3], (x, y) -> list_reduce([4, 5, 6], (a, b) -> list_reduce([7, 8, 9], (c, d) -> x + y + a + b + c + d, 1000), 100), 10);
----
25917331
query I
SELECT list_reduce([1, 2, 3], (x, y, x_i) -> list_reduce([4, 5, 6], (a, b, a_i) -> list_reduce([7, 8, 9], (c, d, c_i) -> x + y + a + b + c + d + x_i + a_i + c_i, 1000), 100), 10);
----
26185861
# three level nested in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[], m integer[], initial integer);
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6], [7, 8, 9], 100), (NULL, NULL, NULL, NULL), (NULL, [110, 111, 112], [113, 114, 115], NULL), ([77, 88, 99], [55, 66, NULL], [44, 33, 22], 1);
query I
SELECT list_reduce(n, (x, y) -> list_reduce(l, (a, b) -> list_reduce(m, (c, d) -> x + y + a + b + c + d, initial), initial), initial) FROM nested;
----
12992341
NULL
NULL
NULL
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][][], initial integer[][]);
statement ok
INSERT INTO nested VALUES ([[[10, 20], [100, 200]], [[30, 40], [300, 400]], [[50, 60], [500, 600]]], [[1]]), ([[[1,2,3], [4,5,6], [7,8,9]]], [[2]]), (NULL, [[3]]), ([[[NULL, 60], [70, NULL], [NULL, NULL]]], [[4]]);
query I
SELECT list_reduce(n, (x, y) -> list_pack(list_reduce(x, (l, m) -> list_pack(list_reduce(l, (a, b) -> a + b) + list_reduce(m, (c, d) -> c + d))) + list_reduce(y, (e, f) -> list_pack(list_reduce(e, (a, b) -> a + b) + list_reduce(f, (c, d) -> c + d))))) from nested;
----
[[330, 770, 1210]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
NULL
[[NULL, 60], [70, NULL], [NULL, NULL]]
# tests on structs
statement ok
CREATE TABLE t_struct (s STRUCT(v VARCHAR, i INTEGER)[], initial STRUCT(v VARCHAR, i INTEGER));
statement ok
INSERT INTO t_struct VALUES ([row('a', 1), row('b', 2)], row('->', 1)), ([row('c', 3), row('d', 4)], row('-->', 2)), ([row('e', 5), row('f', 6)], row('--->', 3)), ([row('g', 7), row('h', 8)], row('---->', 4)), ([row('i', 9), row('j', 10)], row('----->', 5));
query I
SELECT list_reduce(s, (a, b) -> row(a.v || b.v, a.i + b.i), initial) FROM t_struct;
----
{'v': ->ab, 'i': 4}
{'v': -->cd, 'i': 9}
{'v': --->ef, 'i': 14}
{'v': ---->gh, 'i': 19}
{'v': ----->ij, 'i': 24}
# issue #11142
statement ok
CREATE OR REPLACE TABLE df(s STRUCT(a INT, b INT)[], initial STRUCT(a INT, b INT));
statement ok
INSERT INTO df VALUES ([row(0, 0), row(0, 1), row(0, 2)], row(-2, -3));
query I
SELECT
list_reduce(
s, (curr, next) -> struct_pack(a:=curr.a + (next.b - curr.b), b:=next.b), initial
)
FROM df
----
{'a': 3, 'b': 2}
query I
SELECT
list_reduce(
[struct_pack(a:=0, b:=0), struct_pack(a:=0, b:=1), struct_pack(a:=0, b:=2)],
(curr, next) -> struct_pack(a:=curr.a + (next.b - curr.b), b:=next.b),
struct_pack(a:=-2, b:=-3)
)
----
{'a': 3, 'b': 2}
# list_reduce in where clause
statement ok
CREATE table where_clause (a int[], initial integer);
statement ok
INSERT INTO where_clause VALUES ([10, 2, 1], 10), ([1, 2, 3], 20), ([15, 4, 3], 30), ([3, 4, 5], 40), ([11, 2, 3, 4, 5], 50), ([5, 4, 3, 2, 1], 60), ([100, 2, 3, 4, 5, 6, 7, 8, 9, 10], 70);
query I
SELECT a FROM where_clause WHERE list_reduce(a, (x, y) -> x - y, initial) > 0;
----
[1, 2, 3]
[15, 4, 3]
[3, 4, 5]
[11, 2, 3, 4, 5]
[5, 4, 3, 2, 1]

View File

@@ -0,0 +1,93 @@
# name: test/sql/function/list/lambdas/arrow/rhs_parameters_deprecated.test
# description: Test nested lambda parameters in the rhs of lambda expressions
# group: [arrow]
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# issue #5795
query I
SELECT list_apply([1,2], x -> list_apply([3,4], y -> {'x': x, 'y': y})) AS bug;
----
[[{'x': 1, 'y': 3}, {'x': 1, 'y': 4}], [{'x': 2, 'y': 3}, {'x': 2, 'y': 4}]]
# arbitrary other nested lambdas
query I
select list_transform([1,2], x -> list_transform([3,4], y -> x + y));
----
[[4, 5], [5, 6]]
query I
select list_transform([1,2], x -> list_transform([3,4], y -> list_transform([5,6], z -> z + y + x)));
----
[[[9, 10], [10, 11]], [[10, 11], [11, 12]]]
query I
select list_transform([1,2,3,4], x -> list_filter([4,5,1,2,3,3,3,5,1,4], y -> y != x))
----
[[4, 5, 2, 3, 3, 3, 5, 4], [4, 5, 1, 3, 3, 3, 5, 1, 4], [4, 5, 1, 2, 5, 1, 4], [5, 1, 2, 3, 3, 3, 5, 1]]
query I
select list_transform([[2, 4, 6]], x -> list_transform(x, y -> list_sum([y] || x)))
----
[[14, 16, 18]]
query I
SELECT list_apply(range(5), x -> {x:x, w:list_filter(range(5), y -> abs(y-x) < 2)});
----
[{'x': 0, 'w': [0, 1]}, {'x': 1, 'w': [0, 1, 2]}, {'x': 2, 'w': [1, 2, 3]}, {'x': 3, 'w': [2, 3, 4]}, {'x': 4, 'w': [3, 4]}]
query I
SELECT list_apply(range(8), x -> list_aggr(list_apply(range(8),
y -> list_element('▁▂▃▄▅▆▇█', 1+abs(y-x))), 'string_agg', ''));
----
[, , , , , , , ]
statement ok
CREATE TABLE lists (i integer, v varchar[])
statement ok
INSERT INTO lists VALUES (1, ['a', 'b', 'c']), (8, NULL), (3, ['duck', 'db', 'tests']), (NULL, NULL), (NULL, ['lambdas!'])
query I
SELECT list_transform(v, x -> list_transform(v, y -> x || y)) FROM lists
----
[[aa, ab, ac], [ba, bb, bc], [ca, cb, cc]]
NULL
[[duckduck, duckdb, ducktests], [dbduck, dbdb, dbtests], [testsduck, testsdb, teststests]]
NULL
[[lambdas!lambdas!]]
query I
SELECT list_transform(v, x -> list_transform(v, y -> list_transform(v, z -> x || y || z))) FROM lists
----
[[[aaa, aab, aac], [aba, abb, abc], [aca, acb, acc]], [[baa, bab, bac], [bba, bbb, bbc], [bca, bcb, bcc]], [[caa, cab, cac], [cba, cbb, cbc], [cca, ccb, ccc]]]
NULL
[[[duckduckduck, duckduckdb, duckducktests], [duckdbduck, duckdbdb, duckdbtests], [ducktestsduck, ducktestsdb, duckteststests]], [[dbduckduck, dbduckdb, dbducktests], [dbdbduck, dbdbdb, dbdbtests], [dbtestsduck, dbtestsdb, dbteststests]], [[testsduckduck, testsduckdb, testsducktests], [testsdbduck, testsdbdb, testsdbtests], [teststestsduck, teststestsdb, teststeststests]]]
NULL
[[[lambdas!lambdas!lambdas!]]]
query I
SELECT list_transform(v, x -> [list_transform([':-)'], y -> x || y || '-#lambdaLove')]
|| list_filter(list_transform(['B-)'], k -> [k] || [x]), j -> list_contains(j, 'a') or list_contains(j, 'duck')))
FROM lists
----
[[['a:-)-#lambdaLove'], ['B-)', a]], [['b:-)-#lambdaLove']], [['c:-)-#lambdaLove']]]
NULL
[[['duck:-)-#lambdaLove'], ['B-)', duck]], [['db:-)-#lambdaLove']], [['tests:-)-#lambdaLove']]]
NULL
[[['lambdas!:-)-#lambdaLove']]]
statement ok
create table no_overwrite as select [range, range + 1] l from range(3);
query II
select l, [[{'x+y': x + y, 'x': x, 'y': y, 'l': l} for y in [42, 43]] for x in l] from no_overwrite;
----
[0, 1] [[{'x+y': 42, 'x': 0, 'y': 42, 'l': [0, 1]}, {'x+y': 43, 'x': 0, 'y': 43, 'l': [0, 1]}], [{'x+y': 43, 'x': 1, 'y': 42, 'l': [0, 1]}, {'x+y': 44, 'x': 1, 'y': 43, 'l': [0, 1]}]]
[1, 2] [[{'x+y': 43, 'x': 1, 'y': 42, 'l': [1, 2]}, {'x+y': 44, 'x': 1, 'y': 43, 'l': [1, 2]}], [{'x+y': 44, 'x': 2, 'y': 42, 'l': [1, 2]}, {'x+y': 45, 'x': 2, 'y': 43, 'l': [1, 2]}]]
[2, 3] [[{'x+y': 44, 'x': 2, 'y': 42, 'l': [2, 3]}, {'x+y': 45, 'x': 2, 'y': 43, 'l': [2, 3]}], [{'x+y': 45, 'x': 3, 'y': 42, 'l': [2, 3]}, {'x+y': 46, 'x': 3, 'y': 43, 'l': [2, 3]}]]

View File

@@ -0,0 +1,68 @@
# name: test/sql/function/list/lambdas/arrow/storage_deprecated.test
# description: Test storing lambda functions
# group: [arrow]
load __TEST_DIR__/lambda_storage.db
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# create macros containing a lambda functions
statement ok
CREATE MACRO my_transform(list) AS list_transform(list, x -> x * x)
statement ok
CREATE MACRO my_filter(list) AS list_filter(list, x -> x > 42)
statement ok
CREATE MACRO my_reduce(list) AS list_reduce(list, (x, y) -> x + y)
statement ok
CREATE MACRO my_nested_lambdas(nested_list) AS list_filter(nested_list, elem -> list_reduce(list_transform(elem, x -> x + 1), (x, y) -> x + y) > 42)
query I
SELECT my_transform([1, 2, 3])
----
[1, 4, 9]
query I
SELECT my_filter([41, 42, NULL, 43, 44])
----
[43, 44]
query I
SELECT my_reduce([1, 2, 3])
----
6
query I
SELECT my_nested_lambdas([[40, NULL], [20, 21], [10, 10, 20]])
----
[[20, 21], [10, 10, 20]]
# restart the system
restart
query I
SELECT my_transform([1, 2, 3])
----
[1, 4, 9]
query I
SELECT my_filter([41, 42, NULL, 43, 44])
----
[43, 44]
query I
SELECT my_reduce([1, 2, 3])
----
6
query I
SELECT my_nested_lambdas([[40, NULL], [20, 21], [10, 10, 20]])
----
[[20, 21], [10, 10, 20]]

View File

@@ -0,0 +1,93 @@
# name: test/sql/function/list/lambdas/arrow/table_functions_deprecated.test
# description: Test list lambdas in table functions
# group: [arrow]
require parquet
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
statement ok
CREATE TABLE tmp AS SELECT range AS id FROM range(10);
# create a parquet file
query I
COPY tmp TO '__TEST_DIR__/my_file_cba.parquet' (FORMAT PARQUET);
----
10
# now test different table functions
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(['C', 'B', 'A'], s -> lower(s)), 'string_agg', '') || '.parquet');
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(list_sort(['a', 'b', 'c'], 'DESC'), s -> lower(s)), 'string_agg', '') || '.parquet');
----
10
# nested lambdas
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(list_filter(['s', 'c', 'b', NULL, 'a'], x -> x IS NOT NULL AND x != 's'),
s -> lower(s)), 'string_agg', '') || '.parquet');
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(list_filter(
list_filter(['s', 'c', 'b', NULL, 'a'], y -> y != 's'), x -> x IS NOT NULL),
s -> lower(s)), 'string_agg', '') || '.parquet');
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_reduce([['c', 'b', NULL, 'a']], (x, y) -> coalesce(x,y)), 'string_agg', '') || '.parquet');
----
10
# lambda parameters in rhs
query I
COPY tmp TO '__TEST_DIR__/my_file_ac.parquet' (FORMAT PARQUET);
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(['a'], x -> list_transform(['a', 'c'], y -> x || y)[2]), 'string_agg', '') || '.parquet');
----
10
# issue 5821 (without httpfs)
query I
COPY tmp TO '__TEST_DIR__/my_file_a=1,b=2,c=3.parquet' (FORMAT PARQUET);
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_string_agg([lower(s) for s in ['a=1', 'b=2', 'c=3']]) || '.parquet');
----
10
# lambdas in ALTER TABLE statements
statement ok
CREATE TABLE cities AS
SELECT * FROM (VALUES ('Amsterdam', [90, 10]), ('London', [89, 102])) cities (name, prices);
statement ok
ALTER TABLE cities
ALTER COLUMN prices SET DATA TYPE INTEGER[] USING
list_filter(cities.prices, price -> price < 100);
query II
SELECT name, prices AS cheap_options FROM cities;
----
Amsterdam [90, 10]
London [89]

View File

@@ -0,0 +1,27 @@
# name: test/sql/function/list/lambdas/arrow/test_deprecated_lambda.test
# description: Test deprecating the arrow operator for lambda functions.
# group: [arrow]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
statement ok
CREATE TABLE varchars(v VARCHAR);
statement ok
INSERT INTO varchars VALUES ('>>%Test<<'), ('%FUNCTION%'), ('Chaining')
statement ok
DELETE FROM varchars
statement ok
INSERT INTO varchars VALUES ('Test Function Chaining Alias');
statement error
SELECT v.split(' ') strings,
strings.apply(x -> x.lower()).filter(x -> x[1] == 't') lower,
strings.apply(x -> x.upper()).filter(x -> x[1] == 'T') upper,
lower + upper AS mix_case_srings
FROM varchars
----
<REGEX>:Binder Error.*Deprecated lambda arrow.*

View File

@@ -0,0 +1,27 @@
# name: test/sql/function/list/lambdas/arrow/test_lambda_arrow_storage_deprecated.test
# description: Test creating a macro with the lambda arrow and loading that from storage.
# group: [arrow]
statement ok
PRAGMA enable_verification;
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
statement ok
ATTACH '__TEST_DIR__/deprecated_syntax.db';
statement ok
CREATE OR REPLACE FUNCTION deprecated_syntax.transpose(lst) AS (
SELECT list_transform(range(1, 1 + length(lst[1])),
j -> list_transform(range(1, length(lst) + 1),
i -> lst[i][j]
)
)
);
statement ok
DETACH deprecated_syntax;
statement ok
ATTACH '__TEST_DIR__/deprecated_syntax.db';

View File

@@ -0,0 +1,317 @@
# name: test/sql/function/list/lambdas/arrow/transform_deprecated.test
# description: Test list_transform function
# group: [arrow]
# NOTE: some of these tests are directly taken from the Presto Array Function examples
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
# test NULLs and simple cases
query II
SELECT [1] AS l, list_transform([1], l -> l + 1)
----
[1] [2]
query I
SELECT list_transform(NULL, x -> x + 1)
----
NULL
query I
SELECT list_transform([1], x -> x)
----
[1]
query I
SELECT list_transform(['duck', 'a', 'ö'], duck -> concat(duck, 'DB'))
----
[duckDB, aDB, öDB]
query I
SELECT list_transform([1, 2, 3], x -> 1)
----
[1, 1, 1]
query I
SELECT list_transform([], x -> x + 1)
----
[]
query I
SELECT list_transform([1, 2, 3], x -> x + 1)
----
[2, 3, 4]
query I
SELECT list_transform([1, NULL, -2, NULL], x -> x + 1)
----
[2, NULL, -1, NULL]
# test on table with rows
statement ok
CREATE TABLE lists (n integer, l integer[])
statement ok
INSERT INTO lists VALUES (1, [1]), (2, [1, 2, 3]), (3, NULL), (4, [-1, NULL, 2])
query I
SELECT list_transform(l, x -> x) FROM lists
----
[1]
[1, 2, 3]
NULL
[-1, NULL, 2]
query I
SELECT list_transform(l, x -> x + n) FROM lists
----
[2]
[3, 4, 5]
NULL
[3, NULL, 6]
query I
SELECT list_transform(l, x -> x < 2) FROM lists
----
[true]
[true, false, false]
NULL
[true, NULL, false]
# test other operators and more complex/nested functions
query I
SELECT list_transform(['x', 'abc', 'z'], x -> x || '0')
----
[x0, abc0, z0]
query I
SELECT list_transform([[1], [2, 3], [NULL], NULL], x -> list_transform(x, y -> y + 1))
----
[[2], [3, 4], [NULL], NULL]
query I
SELECT list_transform([[1], [2], [3]], x -> list_concat(x, x))
----
[[1, 1], [2, 2], [3, 3]]
query I
SELECT list_transform([5, NULL, 6], x -> POW(x, 2)::INTEGER)
----
[25, NULL, 36]
query I
SELECT list_transform([5, NULL, 6], x -> COALESCE(x, 0) + 1)
----
[6, 1, 7]
query I
SELECT list_transform(list_value(list_unique(list_concat([1,2],[2,2]))), x -> (x + 1)::INTEGER);
----
[3]
query I
SELECT list_sort(list_transform(list_distinct(list_concat([1,2],[2,2])), x -> x + 1));
----
[2, 3]
query I
SELECT list_transform([[1], [2], [3]], x -> list_concat(list_transform(x, y -> y + 1), list_transform(x, z -> z - 1)))
----
[[2, 0], [3, 1], [4, 2]]
statement error
SELECT list_transform([[1], [4], NULL, [1], [8]], x -> list_concat(list_transform(x, y -> CASE WHEN y > 1 THEN 'yay' ELSE 'nay' END), x))
----
an explicit cast is required
query I
SELECT list_transform([[1], [4], NULL, [1], [8]], x -> list_concat(list_transform(x, y -> CASE WHEN y > 1 THEN 'yay' ELSE 'nay' END), x::VARCHAR[]))
----
[[nay, 1], [yay, 4], [], [nay, 1], [yay, 8]]
# test aliases
query I
SELECT array_transform([1, NULL], arr_elem -> arr_elem - 4)
----
[-3, NULL]
query I
SELECT array_apply([1, NULL], arr_elem -> arr_elem - 4)
----
[-3, NULL]
query I
SELECT list_apply([1, NULL], arr_elem -> arr_elem - 4)
----
[-3, NULL]
# more tests on precedence
query I
select list_apply(i, x -> (6 + 2 * 12) // x) from (values (list_value(1, 2, 3))) tbl(i);
----
[30, 15, 10]
query I
select list_apply(i, x -> x + 1 AND x + 1) from (values (list_value(1, 2, 3))) tbl(i);
----
[true, true, true]
# very large lists
statement ok
CREATE TABLE large_lists AS SELECT range % 4 g, list(range) l FROM range(10000) GROUP BY range % 4;
statement ok
CREATE TABLE transformed_lists (g integer, l integer[]);
statement ok
INSERT INTO transformed_lists (SELECT g + 1, list_transform(l, x -> x + 1) FROM large_lists WHERE g != 3)
statement ok
INSERT INTO transformed_lists (SELECT g - 3, list_transform(l, x -> x - 3) FROM large_lists WHERE g = 3)
query I
SELECT ll.l = tl.l FROM large_lists ll, transformed_lists tl WHERE ll.g = tl.g
----
True
True
True
True
# test structs (issue #5005)
query I
SELECT list_transform([{'a': 1}], x -> x.a);
----
[1]
query I
SELECT list_transform([{'a': [1, 2, 3]}], x -> x.a[2]);
----
[2]
query I
SELECT list_transform([{'b' : {'a': 1}}], x -> x.b.a);
----
[1]
query I
SELECT list_transform([{'b' : {'a': 42, 'b': 43}}], x -> x.b.b);
----
[43]
query I
SELECT list_transform([{'b' : {'a': [{'c': 77}], 'b': 43}}], x -> x.b.a[1].c);
----
[77]
# test correlated subqueries
statement ok
CREATE TABLE corr_test (n integer, l integer[], g integer)
statement ok
INSERT INTO corr_test VALUES (1, [2, 1, 1], 1), (3, [NULL, 2, 4, 4], 1), (NULL, NULL, 1), (0, [], 1)
query I
SELECT n FROM corr_test WHERE list_sum(list_transform(l, elem -> elem - n)) >= n
----
1
query I
SELECT ct.n FROM corr_test ct
WHERE list_count(ct.l) < (SELECT list_count(list_transform(list_concat(list(c.n), ct.l), a -> a)) FROM corr_test c GROUP BY c.g)
ORDER BY ct.n
----
0
1
3
query I
SELECT (SELECT list_transform(l, elem -> elem + 1)) FROM corr_test
----
[3, 2, 2]
[NULL, 3, 5, 5]
NULL
[]
query I
SELECT (SELECT list_transform(l, elem -> elem + n)) FROM corr_test
----
[3, 2, 2]
[NULL, 5, 7, 7]
NULL
[]
query I
SELECT (SELECT (SELECT (SELECT list_transform(l, elem -> elem + 1)))) FROM corr_test
----
[3, 2, 2]
[NULL, 3, 5, 5]
NULL
[]
# positional references in lambda functions
query I
SELECT list_transform([1, 2, 3], x -> x + #1) FROM range(10)
----
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 10]
[9, 10, 11]
[10, 11, 12]
# test for issue 4855
statement ok
create table test(a int, b int);
statement ok
insert into test values (1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4);
query III
select list_transform(bb, x->[x,b]), bb, b
from (select list(b) over wind as bb, first(b) over wind as b
from test window wind as
(order by a asc, b asc rows between 4 preceding and current row)
qualify row_number() over wind >4);
----
[[2, 2], [3, 2], [4, 2], [2, 2], [3, 2]] [2, 3, 4, 2, 3] 2
[[3, 3], [4, 3], [2, 3], [3, 3], [4, 3]] [3, 4, 2, 3, 4] 3
[[4, 4], [2, 4], [3, 4], [4, 4], [2, 4]] [4, 2, 3, 4, 2] 4
[[2, 2], [3, 2], [4, 2], [2, 2], [3, 2]] [2, 3, 4, 2, 3] 2
[[3, 3], [4, 3], [2, 3], [3, 3], [4, 3]] [3, 4, 2, 3, 4] 3
query I
SELECT list_transform([[2, 3], [4]], x -> list_transform([42], y -> y + 1))
----
[[43], [43]]
query I
SELECT list_transform([[2, 3], [4]], x -> list_transform(x, y -> y + 1))
----
[[3, 4], [5]]
query I
SELECT list_transform([[2, 3], [4]], x -> list_transform([1], y -> x || [y]))
----
[[[2, 3, 1]], [[4, 1]]]
query I
SELECT list_transform([[2, 3], [4]], x -> list_transform(x, y -> x || [y]))
----
[[[2, 3, 2], [2, 3, 3]], [[4, 4]]]

View File

@@ -0,0 +1,127 @@
# name: test/sql/function/list/lambdas/arrow/transform_with_index_deprecated.test
# description: Test the list_transform function with an index parameter
# group: [arrow]
statement ok
PRAGMA enable_verification
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
query I
SELECT list_transform([1, 2, 3], x -> list_transform([4, 5, 6], (y, y_i) -> x + y + y_i));
----
[[6, 8, 10], [7, 9, 11], [8, 10, 12]]
query I
SELECT list_transform(['abc'], (x, i) -> x[i + 1]);
----
[b]
query I
SELECT list_filter([1, 2, 1], (x, y) -> x >= y);
----
[1, 2]
query I
SELECT list_transform([1, 2, 3], x -> list_transform([4, 5, 6], y -> list_transform([7, 8, 9], (z, i) -> x + y + z + i)));
----
[[[13, 15, 17], [14, 16, 18], [15, 17, 19]], [[14, 16, 18], [15, 17, 19], [16, 18, 20]], [[15, 17, 19], [16, 18, 20], [17, 19, 21]]]
query I
SELECT list_transform([10, 20, 30], (x, i) -> x + i);
----
[11, 22, 33]
query I
SELECT list_transform([1, 2, 3, 4, 5, 6], (x, i) -> x * i);
----
[1, 4, 9, 16, 25, 36]
query I
SELECT list_transform([6, 5, 4, 3, 2, 1], (x, i) -> x * i);
----
[6, 10, 12, 12, 10, 6]
query I
SELECT list_transform([1, NULL, 3, 4, 5, 6], (x, i) -> x + i);
----
[2, NULL, 6, 8, 10, 12]
query I
SELECT list_transform(NULL, (x, i) -> x + i);
----
NULL
query I
SELECT list_transform(['1', '2', '3', '4'], (x, i) -> (x || ' + ' || CAST(i AS string)));
----
[1 + 1, 2 + 2, 3 + 3, 4 + 4]
query I
SELECT list_transform([1,2,3,4,5], (x, i) -> (x * 10 / i));
----
[10.0, 10.0, 10.0, 10.0, 10.0]
# tests with column references
statement ok
CREATE TABLE tbl(a int[]);
statement ok
INSERT INTO tbl VALUES ([5, 4, 3]), ([1, 2, 3]), (NULL), ([NULL, 101, 12]);
query I
SELECT list_transform(a, (x, i) -> x + i) FROM tbl;
----
[6, 6, 6]
[2, 4, 6]
NULL
[NULL, 103, 15]
query I
SELECT list_transform(a, (x, i) -> x + i + list_any_value(a)) FROM tbl;
----
[11, 11, 11]
[3, 5, 7]
NULL
[NULL, 204, 116]
statement ok
DROP TABLE tbl;
statement ok
CREATE TABLE tbl(a int[], b int, c int);
statement ok
INSERT INTO tbl VALUES ([5,4,3], 5, 10), ([1,2,3], 7, 14), (NULL, 9, 18), ([10,NULL,12], 11, 22);
query I
SELECT list_transform(a, (x, i) -> (c / b ) * (x + i)) FROM tbl;
----
[12.0, 12.0, 12.0]
[4.0, 8.0, 12.0]
NULL
[22.0, NULL, 30.0]
query I
SELECT list_transform([1, 2, 3], (x, x_i) -> list_transform([4, 5, 6], y -> x + y + x_i));
----
[[6, 7, 8], [8, 9, 10], [10, 11, 12]]
query I
SELECT list_transform([1, 2, 3], (x, x_i) -> list_transform([4, 5, 6], (y, y_i) -> x + y + x_i + y_i));
----
[[7, 9, 11], [9, 11, 13], [11, 13, 15]]
query I
SELECT list_transform([1, 2, 3], (x, i) -> list_transform([4, 5, 6], y -> list_transform([7, 8, 9], z -> x + y + z + i)));
----
[[[13, 14, 15], [14, 15, 16], [15, 16, 17]], [[15, 16, 17], [16, 17, 18], [17, 18, 19]], [[17, 18, 19], [18, 19, 20], [19, 20, 21]]]
query I
SELECT list_transform([1, 2, 3], x -> list_transform([4, 5, 6], (y, i) -> list_transform([7, 8, 9], z -> x + y + z + i)));
----
[[[13, 14, 15], [15, 16, 17], [17, 18, 19]], [[14, 15, 16], [16, 17, 18], [18, 19, 20]], [[15, 16, 17], [17, 18, 19], [19, 20, 21]]]

View File

@@ -0,0 +1,155 @@
# name: test/sql/function/list/lambdas/expression_iterator_cases.test
# description: Test the different possible cases of the expression iterator
# group: [lambdas]
# these tests check the different cases of the expression iterator
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# this BOUND_AGGREGATE is a constant, so we can allow it inside lambda functions
query I
SELECT list_transform([10], lambda x: sum(1) + x)
----
[11]
query I
SELECT list_filter([10], lambda x: sum(1) > 0)
----
[10]
# BOUND_BETWEEN
query I
SELECT list_transform([NULL, DATE '1992-09-20', DATE '2021-09-20'], lambda elem: extract('year' FROM elem) BETWEEN 2000 AND 2022)
----
[NULL, false, true]
query I
SELECT list_filter([NULL, DATE '1992-09-20', DATE '2021-09-20'], lambda elem: extract('year' FROM elem) BETWEEN 2000 AND 2022)
----
[2021-09-20]
# BOUND_CASE
query I
SELECT list_transform(['hello', 'duck', 'sunshine'], lambda str: CASE WHEN str LIKE '%e%' THEN 'e' ELSE 'other' END)
----
[e, other, e]
query I
SELECT list_filter(['hello', 'duck', 'sunshine'], lambda str: (CASE WHEN str LIKE '%e%' THEN 'e' ELSE 'other' END) LIKE 'e')
----
[hello, sunshine]
# BOUND_CAST
query I
SELECT list_transform([2.0::DOUBLE], lambda x: x::INTEGER)
----
[2]
query I
SELECT list_filter([2], lambda x: x::DOUBLE == 2)
----
[2]
# BOUND_COMPARISON
query I
SELECT list_transform([2.4, NULL, -4.7], lambda x: x != 10.4)
----
[true, NULL, true]
query I
SELECT list_filter([2.4, NULL, -4.7], lambda x: x != -4.7)
----
[2.4]
# BOUND_CONJUNCTION
query I
SELECT list_transform([True, False, NULL], lambda x: x AND true)
----
[true, false, NULL]
query I
SELECT list_filter([True, False, NULL], lambda x: x AND true)
----
[true]
# BOUND_FUNCTION
query I
SELECT list_transform([TIMESTAMP '1992-03-22', TIMESTAMP '209-03-22', TIMESTAMP '1700-03-22'], lambda x: century(x))
----
[20, 3, 17]
query I
SELECT list_filter([TIMESTAMP '1992-03-22', TIMESTAMP '209-03-22', TIMESTAMP '1700-03-22'], lambda x: century(x) > 16)
----
['1992-03-22 00:00:00', '1700-03-22 00:00:00']
# BOUND_OPERATOR
query I
SELECT list_transform([2], lambda x: x + x)
----
[4]
query I
SELECT list_filter([2], lambda x: x + x = 4)
----
[2]
# BOUND_SUBQUERY
statement error
SELECT list_transform([2], lambda x: (SELECT 1 - x) * x)
----
<REGEX>:Binder Error.*subqueries in lambda expressions are not supported.*
statement error
SELECT list_filter([2], lambda x: (SELECT 1 - x) * x > 2)
----
<REGEX>:Binder Error.*subqueries in lambda expressions are not supported.*
statement ok
CREATE MACRO list_contains_macro(x, y) AS (SELECT list_contains(x, y))
statement error
SELECT list_filter([[1, 2, 1], [1, 2, 3], [1, 1, 1]], lambda x: list_contains_macro(x, 3))
----
<REGEX>:Binder Error.*subqueries in lambda expressions are not supported.*
# BOUND_UNNEST
statement error
SELECT list_transform([1], lambda x: x = UNNEST([1]));
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
statement error
SELECT list_filter([1], lambda x: x = UNNEST([1]));
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
# BOUND_WINDOW
statement ok
CREATE TABLE my_window (l integer[], g integer, o integer)
statement ok
INSERT INTO my_window VALUES ([1], 1, 1), ([1, NULL, 2], 1, 2), ([], 2, 3), (NULL, NULL, NULL), ([1, 2], 2, 4)
query I
SELECT list(list_transform(l, lambda e: e + 1)) OVER (PARTITION BY g ORDER BY o)
FROM my_window
ORDER BY ALL
----
[[]]
[[], [2, 3]]
[[2]]
[[2], [2, NULL, 3]]
[NULL]

View File

@@ -0,0 +1,245 @@
# name: test/sql/function/list/lambdas/filter.test
# description: Test list_filter function
# group: [lambdas]
# NOTE: some of these tests are directly taken from the Presto Array Function examples
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# test NULLs and simple cases
query II
SELECT [1] AS l, list_filter([1], lambda l: l > 1)
----
[1] []
query I
SELECT list_filter(NULL, lambda x: x > 1)
----
NULL
query I
SELECT list_filter([True], lambda x: x)
----
[true]
query I
SELECT list_filter(['duck', 'a', 'ö'], lambda duck: contains(concat(duck, 'DB'), 'duck'))
----
[duck]
query I
SELECT list_filter([1, 2, 3], lambda x: x % 2 = 0)
----
[2]
query I
SELECT list_filter([], lambda x: x > 1)
----
[]
query I
SELECT list_filter([1, NULL, -2, NULL], lambda x: x % 2 != 0)
----
[1]
query I
SELECT list_filter([5, -6, NULL, 7], lambda x: x > 0)
----
[5, 7]
query I
SELECT list_filter([5, NULL, 7, NULL], lambda x: x IS NOT NULL)
----
[5, 7]
# test on table with rows
statement ok
CREATE TABLE lists (n integer, l integer[])
statement ok
INSERT INTO lists VALUES (1, [1]), (2, [1, 2, 3]), (3, NULL), (4, [-1, NULL, 2])
query I
SELECT list_filter(l, lambda x: x + 1 <= 2) FROM lists
----
[1]
[1]
NULL
[-1]
query I
SELECT list_filter(l, lambda x: x <= n) FROM lists
----
[1]
[1, 2]
NULL
[-1, 2]
query I
SELECT list_filter(l, lambda x: x IS NOT NULL) FROM lists
----
[1]
[1, 2, 3]
NULL
[-1, 2]
# test other operators and more complex/nested functions
query I
SELECT list_filter(['x', 'abc', 'z'], lambda x: contains(x || '0', 'a'))
----
[abc]
query I
SELECT list_transform([[1, 3], [2, 3, 1], [2, 4, 2]], lambda x: list_filter(x, lambda y: y <= 2))
----
[[1], [2, 1], [2, 2]]
query I
SELECT list_concat(list_filter([42, -42, 8, -5, 2], lambda elem: elem > 0)::varchar[],
list_filter(['enjoy', 'life', 'to', 'the', 'fullest'], lambda str: str ILIKE '%e%'))
----
[42, 8, 2, enjoy, life, the, fullest]
# test aliases
query I
SELECT array_filter([1, NULL], lambda arr_elem: arr_elem < 4)
----
[1]
# test many empty lists
statement ok
CREATE TABLE empty_lists (l integer[])
statement ok
INSERT INTO empty_lists VALUES ([]), ([]), ([]), ([1, NULL, -1]), ([]), (NULL), (NULL), ([]), ([1, 2, 3]), ([]), ([]), ([]);
query I
SELECT list_filter(l, lambda x: x > 0) FROM empty_lists
----
[]
[]
[]
[1]
[]
NULL
NULL
[]
[1, 2, 3]
[]
[]
[]
# very large lists
statement ok
CREATE TABLE large_lists AS SELECT range % 4 g, list(range) l FROM range(10000) GROUP BY range % 4;
query II
SELECT g, list_count(list_filter(l, lambda x: x % 2 = 0)) FROM large_lists ORDER BY g
----
0 2500
1 0
2 2500
3 0
# test correlated subqueries
statement ok
CREATE TABLE corr_test (n integer, l varchar[], g integer)
statement ok
INSERT INTO corr_test VALUES (1, ['a', '11', '23'], 1), (3, [NULL, '2', 'hello', 'wie gehts'], 1), (NULL, NULL, 1), (0, [], 1)
query I
SELECT n FROM corr_test WHERE list_count(list_filter(l, lambda elem: length(elem) >= n)) >= n
----
1
0
query I
SELECT ct.n FROM corr_test ct
WHERE list_count(ct.l) < (
SELECT list_count(list_filter(list_concat(list(c.n)::varchar[], ct.l), lambda a: length(a) >= 1))
FROM corr_test c GROUP BY c.g
)
ORDER BY ct.n
----
0
1
3
query I
SELECT (SELECT list_filter(l, lambda elem: length(elem) >= 1)) FROM corr_test
----
[a, 11, 23]
[2, hello, wie gehts]
NULL
[]
query I
SELECT (SELECT list_filter(l, lambda elem: length(elem) >= n)) FROM corr_test
----
[a, 11, 23]
[hello, wie gehts]
NULL
[]
query I
SELECT (SELECT (SELECT (SELECT list_filter(l, lambda elem: length(elem) >= 1)))) FROM corr_test
----
[a, 11, 23]
[2, hello, wie gehts]
NULL
[]
# positional references in lambda functions
query I
SELECT list_filter([1, 2, 3, 4, 5, 6, 7, 8, 9], lambda x: x > #1) FROM range(10)
----
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 3, 4, 5, 6, 7, 8, 9]
[3, 4, 5, 6, 7, 8, 9]
[4, 5, 6, 7, 8, 9]
[5, 6, 7, 8, 9]
[6, 7, 8, 9]
[7, 8, 9]
[8, 9]
[9]
[]
# fixes 5816
# auto casting in list_filter, or exception if not possible (casting is strict)
statement ok
CREATE TABLE lambdas AS SELECT [5, 6] AS col1, [4, 8] AS col2;
query I
SELECT list_apply(col1, lambda x: list_filter(col2, lambda y: y)) FROM lambdas;
----
[[4, 8], [4, 8]]
query I
SELECT list_apply([5,6], lambda x: list_filter([4,8], lambda y: y));
----
[[4, 8], [4, 8]]
query I
SELECT list_apply([[5,6]], lambda x: list_filter(x, lambda y: y));
----
[[5, 6]]
statement error
SELECT list_transform([['abc']], lambda x: list_filter(x, lambda y: y));
----
Conversion Error: Could not convert string 'abc' to BOOL
query II
select [[y] for y in range(5)] as c, [x for x in c if x IS NOT NULL];
----
[[0], [1], [2], [3], [4]] [[0], [1], [2], [3], [4]]

View File

@@ -0,0 +1,291 @@
# name: test/sql/function/list/lambdas/incorrect.test
# description: Test incorrect usage of the lambda functions
# group: [lambdas]
require no_extension_autoloading "EXPECTED: This tests is not compatible with JSON extension, that will otherwise be autoloaded"
statement ok
CREATE TABLE incorrect_test (i INTEGER);
foreach func_name list_transform list_filter list_reduce
statement error
SELECT ${func_name}();
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}([]);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}(1, 2, 3);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}(NULL, NULL);
----
<REGEX>:Binder Error.*Invalid lambda expression!.*
statement error
SELECT ${func_name}(NULL, x);
----
<REGEX>:Binder Error.*Referenced column.*not found in FROM clause!.*
statement error
SELECT ${func_name}([1, 2], (SELECT 1) -> x + 1);
----
<REGEX>:Binder Error.*Invalid lambda parameters!.*
statement error
SELECT ${func_name}(NULL, i) FROM incorrect_test;
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}(NULL, x -> y);
----
<REGEX>:Binder Error.*Referenced column.*not found in FROM clause!.*
statement error
SELECT ${func_name}([1]);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}([1], NULL);
----
<REGEX>:Binder Error.*Invalid lambda expression!.*
statement error
SELECT ${func_name}([[1]], x -> x + 1);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}(1, 1);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}(1, x -> x + 1);
----
Invalid LIST argument during lambda function binding!
endloop
# list_reduce accepts a third parameter, so shows a different error message
foreach func_name list_transform list_filter
statement error
SELECT ${func_name}([1], x -> x, 3);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
statement error
SELECT ${func_name}([True], x -> x, x -> x);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
endloop
statement error
SELECT list_reduce([1], x -> x, 3);
----
<REGEX>:Binder Error.*list_reduce expects a function with 2 or 3 arguments.*
statement error
SELECT list_reduce([True], x -> x, x -> x);
----
<REGEX>:Binder Error.*No function matches the given name and argument types.*You might need to add explicit type casts.*
# list_transform specific tests
statement error
SELECT [split('01:08:22', ':'), x -> CAST (x AS INTEGER)];
----
<REGEX>:Binder Error.*failed to bind function, either.*This scalar function does not support lambdas!.*Referenced column.*not found in FROM clause!.*
statement error
select list_apply(i, x -> x * 3 + 2 / zz) from (values (list_value(1, 2, 3))) tbl(i);
----
<REGEX>:Binder Error.*Referenced column.*not found in FROM clause!.*
# lambda cannot be the root of a plan
statement error
select x -> x + 1 from (values (list_value(1, 2, 3))) tbl(i);
----
<REGEX>:Binder Error.*Referenced column.*not found in FROM clause!.*
statement error
select list_apply(i, y + 1 -> x + 1) from (values (list_value(1, 2, 3))) tbl(i);
----
<REGEX>:Binder Error.*Invalid lambda parameters!.*
statement error
SELECT list_apply(i, a.x -> x + 1) FROM (VALUES (list_value(1, 2, 3))) tbl(i);
----
<REGEX>:Binder Error.*Invalid lambda parameters!.*
statement error
select list_apply(i, x -> x + 1 AND y + 1) from (values (list_value(1, 2, 3))) tbl(i);
----
<REGEX>:Binder Error.*Referenced column.*not found in FROM clause!.*
statement ok
CREATE TABLE l_filter_test (l integer[]);
statement error
SELECT list_transform([1, 2], (x, y, z) -> x + y + z);
----
<REGEX>:Binder Error.*This lambda function only supports up to two lambda parameters!.*
statement error
SELECT list_filter([1, 2], (x, y, z) -> x >= y AND y >= z);
----
<REGEX>:Binder Error.*This lambda function only supports up to two lambda parameters!.*
# using lambdas in functions that do not support them
statement error
SELECT cos(x -> x + 1);
----
<REGEX>:Binder Error.*failed to bind function, either.*This scalar function does not support lambdas!.*Referenced column.*not found in FROM clause!.*
statement error
SELECT cos([1], x -> x + 1);
----
<REGEX>:Binder Error.*failed to bind function, either.*This scalar function does not support lambdas!.*Referenced column.*not found in FROM clause!.*
# FIXME: support lambdas in CHECK constraints
statement error
CREATE TABLE lambda_check (i BIGINT[],
CHECK (list_filter(i, x -> x % 2 = 0) == []));
----
<REGEX>:Not implemented Error.*Lambda functions are currently not supported in CHECK constraints.*
statement error
CREATE TABLE lambda_check (i BIGINT[],
CHECK (list_transform(i, x -> x % 2) == []));
----
<REGEX>:Not implemented Error.*Lambda functions are currently not supported in CHECK constraints.*
statement error
CREATE TABLE lambda_check (i BIGINT[],
CHECK ([x + 1 FOR x IN i IF x > 0] == []));
----
<REGEX>:Not implemented Error.*Lambda functions are currently not supported in CHECK constraints.*
statement error
CREATE TABLE lambda_check (
i BIGINT[],
j BIGINT[],
CHECK ((list_apply(i, x -> list_count(list_filter(j, y -> y%2=0)) + x)) == []));
----
<REGEX>:Not implemented Error.*Lambda functions are currently not supported in CHECK constraints.*
# FIXME: allow lambdas in generated columns
statement error
CREATE TABLE unit2(
price INTEGER[],
total_price INTEGER GENERATED ALWAYS AS (list_transform(price, x -> x + 1)) VIRTUAL
);
----
<REGEX>:Not implemented Error.*Lambda functions are currently not supported in generated columns.*
# Issue 9732
statement ok
CREATE TABLE tbl AS SELECT {'a': 10} AS s;
statement error
SELECT list_transform(UNNEST(s), x -> UNNEST(x)) FROM tbl;
----
<REGEX>:Binder Error.*failed to bind function, either.*struct column can only be applied as the root element of a SELECT expression.*
# UNNEST in lambdas is not supported
statement ok
CREATE TABLE nested_list(i INT[][], other INT[]);
statement ok
INSERT INTO nested_list VALUES ([[1, 2]], [3, 4]);
statement error
SELECT list_transform(i, x -> UNNEST(x)) FROM nested_list;
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
statement error
SELECT list_transform(i, x -> UNNEST(other)) FROM nested_list;
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
statement ok
CREATE TABLE map_tbl(m MAP(INTEGER, INTEGER));
statement error
SELECT [UNNEST([x.key FOR y IN range(x.value)]) FOR x IN map_entries(m)] FROM map_tbl;
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
statement error
SELECT list_transform(map_entries(m), x -> UNNEST(range(x.value))) FROM map_tbl;
----
<REGEX>:Binder Error.*UNNEST in lambda expressions is not supported.*
statement ok
CREATE TABLE dummy_tbl (y INT);
statement error
SELECT list_transform([1], lambda x: lambda y: x + y) FROM dummy_tbl;
----
<REGEX>:Binder Error.*invalid lambda expression.*
statement error
SELECT list_transform([1], lambda x: 1 : hello) FROM dummy_tbl;
----
<REGEX>:Parser Error.*syntax error.*
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
statement error
CREATE OR REPLACE function transpose(lst) AS (
SELECT list_transform(range(1, 1 + length(lst[1])),
j -> list_transform(range(1, length(lst) + 1),
lambda i: lst[i][j]
)
)
);
----
<REGEX>:Binder Error.*Deprecated lambda arrow.*
statement error
CREATE OR REPLACE FUNCTION transpose(lst) AS (
SELECT list_transform(range(1, 1 + length(lst[1])),
j -> list_transform(range(1, length(lst) + 1),
i -> lst[i][j]
)
)
);
----
<REGEX>:Binder Error.*Deprecated lambda arrow.*
statement ok
SET lambda_syntax='ENABLE_SINGLE_ARROW'
statement ok
CREATE OR REPLACE FUNCTION transpose(lst) AS (
SELECT list_transform(range(1, 1 + length(lst[1])),
j -> list_transform(range(1, length(lst) + 1),
i -> lst[i][j]
)
)
);

View File

@@ -0,0 +1,169 @@
# name: test/sql/function/list/lambdas/lambda_scope.test
# description: Test the scoping of lambda variables.
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# Lambda parameters have precedence over columns.
statement ok
CREATE TABLE t1 AS SELECT [1, 2, 3] AS x;
query I
SELECT list_apply(['hello'], lambda x: x) FROM t1;
----
[hello]
statement ok
CREATE TABLE t2 AS SELECT [[1], [2], [3]] AS x;
query I
SELECT list_transform([[1], [2], [3]], lambda x: x[1]) FROM t2;
----
[1, 2, 3]
statement ok
CREATE TABLE l_test (l integer[]);
statement ok
INSERT INTO l_test VALUES ([1, 2, 3]);
query II
SELECT l, list_transform(l, lambda l: l + 1) FROM l_test;
----
[1, 2, 3] [2, 3, 4]
statement ok
CREATE TABLE l_filter_test (l integer[]);
statement ok
INSERT INTO l_filter_test VALUES ([1, 2]);
query II
SELECT l, list_filter(l, lambda l: l > 1) FROM l_filter_test;
----
[1, 2] [2]
# don't allow qualified lambda parameters (LHS parameters)
statement error
SELECT list_apply(i, lambda a.x: a.x + 1) FROM (VALUES (list_value(1, 2, 3))) tbl(i);
----
<REGEX>:Parser Error.*syntax error at or near.*
statement ok
CREATE TABLE qualified_tbl (x INTEGER[]);
statement ok
INSERT INTO qualified_tbl VALUES ([1, 2]);
query I
SELECT list_transform(qualified_tbl.x, lambda x: (qualified_tbl.x)[1] + 1 + x) FROM qualified_tbl;
----
[3, 4]
statement error
SELECT list_transform(qualified_tbl.x, lambda qualified_tbl.x: qualified_tbl.x + 1) FROM qualified_tbl;
----
<REGEX>:Parser Error.*syntax error at or near.*
# previously ambiguous lambda parameters
# issue #9970
query I
SELECT list_transform([1, 2], lambda x: list_transform([3, 4], lambda x: x));
----
[[3, 4], [3, 4]]
query I
SELECT list_has_all([variable_has_all FOR variable_has_all IN ['a']], ['b']) AS list_comp_result;
----
false
query I
SELECT list_has_all(list_transform(['a'], lambda variable_has_all: variable_has_all), ['b']) AS list_transform_result;
----
false
query I
SELECT list_has_any(['b'], list_transform(['a'], lambda variable_has_any: variable_has_any)) AS list_transform_result;
----
false
query I
SELECT list_intersect(list_intersect([1], [1]), [1])
----
[1]
query I
SELECT list_intersect([1], list_intersect([1], [1]))
----
[1]
query I
SELECT list_has_any(LIST_VALUE(list_has_any([1], [1])), [1])
----
true
query I
SELECT list_has_any([1], LIST_VALUE(list_has_any([1], [1])))
----
true
query I
SELECT list_has_all(LIST_VALUE(list_has_all([1], [1])), [1])
----
true
query I
SELECT list_has_all([1], LIST_VALUE(list_has_all([1], [1])))
----
true
query I
SELECT list_has_any(LIST_VALUE(list_has_all(list_intersect([1], [1]), [1])), [1]);
----
true
query I
SELECT list_has_all(LIST_VALUE(list_has_any(list_intersect([1], [1]), [1])), [1]);
----
true
query I
SELECT list_intersect(LIST_VALUE(list_has_all(LIST_VALUE(list_has_any([1], [1])), [1])), [1])
----
[true]
query I
SELECT list_intersect(list_intersect([1, 2, 3, 4], [4, 5, 6, 7]), list_intersect([4, 5, 6, 7], [1, 2, 3, 4]));
----
[4]
# more tests for qualifying column names
statement ok
CREATE TABLE tbl_qualified AS SELECT 42 AS x;
query II
SELECT x, list_transform([1], lambda x: x) FROM tbl_qualified;
----
42 [1]
statement error
SELECT list_transform([1,2,3], lambda sqrt(xxx.z): xxx.z + 1) AS l ;
----
<REGEX>:Parser Error.*syntax error at or near.*
query I
SELECT list_transform([1, 2, 3], lambda "x.y" : "x.y" + x.y) AS l FROM (VALUES (42), (84)) x(y);
----
[43, 44, 45]
[85, 86, 87]
statement error
SELECT list_reduce([1, 2, 3, 4], lambda x *++++++++* y: x - y) AS l;
----
<REGEX>:Parser Error.*syntax error at or near.*

View File

@@ -0,0 +1,38 @@
# name: test/sql/function/list/lambdas/lambdas_and_functions.test
# description: Test mixing lambdas and functions
# group: [lambdas]
require json
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
statement ok
CREATE OR REPLACE function demo(n, z) AS TABLE (
SELECT list_transform(range(0, n), lambda x: z) AS row
);
query I
FROM demo(3, 0);
----
[0, 0, 0]
statement ok
CREATE OR REPLACE function demo(n, z) AS TABLE (
SELECT list_transform(range(0, n), lambda x: 0 + z) AS row
);
query I
FROM demo(3, 0);
----
[0, 0, 0]
statement ok
CREATE OR REPLACE function demo(n, z) AS TABLE (
SELECT list_transform(range(0, n), lambda x: (z -> 'a')) AS row
);
query I
FROM demo(3, {'a': 2});
----
[2, 2, 2]

View File

@@ -0,0 +1,51 @@
# name: test/sql/function/list/lambdas/lambdas_and_group_by.test
# description: Test lambdas with aggregations
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
statement ok
CREATE TABLE tbl (tag_product VARCHAR);
statement ok
INSERT INTO tbl VALUES ('milk chickpeas apples'), ('chocolate pepper');
query II
SELECT tag_product, list_aggr(list_transform(
string_split(tag_product, ' '), lambda word: lower(word)),
'string_agg', ',') AS tag_material,
FROM tbl GROUP BY tag_product
ORDER BY ALL;
----
chocolate pepper chocolate,pepper
milk chickpeas apples milk,chickpeas,apples
query II
SELECT 1, list_transform([5, 4, 3], lambda x: x + 1) AS lst GROUP BY 1;
----
1 [6, 5, 4]
statement ok
CREATE TABLE uniform_purchase_forecast AS
SELECT 'gold' AS color, 10 AS forecast
UNION ALL SELECT 'blue', 15
UNION ALL SELECT 'red', 300;
query I
FROM uniform_purchase_forecast SELECT list(forecast).list_transform(lambda x: x + 10);
----
[20, 25, 310]
# HAVING binder issues.
query I
FROM (SELECT 1) GROUP BY ALL HAVING list_filter(NULL, lambda x: x);
----
statement ok
FROM test_all_types() GROUP BY ALL HAVING array_intersect(NULL, NULL);
query I
SELECT x FROM (VALUES (42)) t(x) GROUP BY x HAVING list_filter(NULL, lambda lambda_param: lambda_param = 1);
----

View File

@@ -0,0 +1,73 @@
# name: test/sql/function/list/lambdas/lambdas_and_macros.test
# description: Test mixing lambdas and macros
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# Test conflicting column names.
statement ok
CREATE TABLE test AS SELECT range i FROM range(3);
statement error
CREATE MACRO my_macro(i) AS (SELECT i IN (SELECT i FROM test));
----
Binder Error: Conflicting column names for column i!
statement ok
CREATE MACRO list_contains_macro(x, y) AS (list_contains(x, y))
query I
SELECT list_filter([[1, 2, 1], [1, 2, 3], [1, 1, 1]], lambda x: list_contains_macro(x, 3))
----
[[1, 2, 3]]
statement ok
CREATE MACRO macro_with_lambda(list, num) AS (list_transform(list, lambda x: x + num))
query I
SELECT list_filter([[1, 2], NULL, [3], [4, NULL]], lambda f: list_count(macro_with_lambda(f, 2)) > 1)
----
[[1, 2]]
# Test a case where the operator mismatch is only detected when using the macro.
statement ok
CREATE MACRO some_macro(x, y, z) AS (SELECT list_transform(x, lambda a: x + y + z))
statement error
SELECT some_macro([1, 2], 3, 4);
----
statement ok
CREATE MACRO reduce_macro(list, num) AS (list_reduce(list, lambda x, y: x + y + num))
query I
SELECT reduce_macro([1, 2, 3, 4], 5);
----
25
statement ok
CREATE MACRO other_reduce_macro(list, num, bla) AS (SELECT list_reduce(list, lambda x, y: list + x + y + num + bla))
statement error
SELECT other_reduce_macro([1, 2, 3, 4], 5, 6);
----
# Test lambda scoping.
statement ok
CREATE MACRO scoping_macro(x, y, z) AS (SELECT list_transform(x, lambda x: x + y + z));
query I
SELECT scoping_macro([11, 22], 3, 4);
----
[18, 29]
statement ok
CREATE OR REPLACE MACRO foo(bar) AS (SELECT apply([bar], lambda x: 0));
statement ok
SELECT foo(v) FROM (SELECT 0 AS v);

View File

@@ -0,0 +1,89 @@
# name: test/sql/function/list/lambdas/list_comprehension.test
# description: Test different examples that can be found when searching for python list comprehension examples
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
query I
SELECT list_transform(list_filter([0, 1, 2, 3, 4, 5], lambda x: x % 2 = 0), lambda y: y * y)
----
[0, 4, 16]
query I
SELECT [x * x for x in [0, 1, 2, 3, 4, 5] if x%2=0]
----
[0, 4, 16]
query I
SELECT list_filter(list_filter([2, 4, 3, 1, 20, 10, 3, 30], lambda x: x % 2 == 0), lambda y: y % 5 == 0)
----
[20, 10, 30]
query I
SELECT [x for x in [x for x in [2, 4, 3, 1, 20, 10, 3, 30] if x % 2 == 0] if x % 5 == 0]
----
[20, 10, 30]
query I
SELECT list_filter(['apple', 'banana', 'cherry', 'kiwi', 'mango'], lambda fruit: contains(fruit, 'a'))
----
[apple, banana, mango]
query I
SELECT [fruit for fruit in ['apple', 'banana', 'cherry', 'kiwi', 'mango'] if contains(fruit, 'a')]
----
[apple, banana, mango]
statement ok
CREATE TABLE fruit_tbl AS SELECT ['apple', 'banana', 'cherry', 'kiwi', 'mango'] fruits
query I
SELECT [fruit for fruit in fruits if contains(fruit, 'a')] FROM fruit_tbl
----
[apple, banana, mango]
query I
SELECT list_transform([[1, NULL, 2], [3, NULL]], lambda a: list_filter(a, lambda x: x IS NOT NULL))
----
[[1, 2], [3]]
query I
SELECT [len(x) for x in ['goodbye', 'cruel', 'world']]
----
[7, 5, 5]
statement ok
CREATE TABLE word_tbl AS SELECT ['goodbye', 'cruel', 'world'] words
query I
SELECT [len(x) for x in words] FROM word_tbl
----
[7, 5, 5]
query I
WITH BASE AS (SELECT [4, 5, 6] AS l)
SELECT [x for x, i in l if i != 2] AS filtered FROM base;
----
[4, 6]
query I
SELECT [x + i for x, i in [10, 9, 8, 7, 6]]
----
[11, 11, 11, 11, 11]
query I
WITH BASE AS (SELECT [4, 5, 6] AS l)
SELECT [x + 5 for x in l] AS filtered FROM base;
----
[9, 10, 11]
statement error
SELECT [a for a, b, c in [1, 2, 3]];
----
This lambda function only supports up to two lambda parameters!
statement error
SELECT [a for a[1], b[2] in [1, 2, 3, 4]];
----
Parser Error: syntax error at or near "["

View File

@@ -0,0 +1,443 @@
# name: test/sql/function/list/lambdas/reduce.test
# description: Test list_reduce function
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x + y);
----
6
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x * y);
----
6
query I
SELECT list_reduce([100, 10, 1], lambda x, y, i: x - y - i);
----
84
query I
SELECT list_reduce([1, 2, 3], lambda x, y: y - x);
----
2
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x - y);
----
-4
query I
SELECT list_reduce([1, 2, 3], lambda x, y, i: x + y + i);
----
11
query I
SELECT list_reduce([NULL], lambda x, y, i: x + y + i);
----
NULL
query I
SELECT list_reduce(NULL, lambda x, y, i: x + y + i);
----
NULL
query I
SELECT list_reduce(['Once', 'upon', 'a', 'time'], lambda x, y: x || ' ' || y);
----
Once upon a time
query I
SELECT list_reduce(['a', 'b', 'c', 'd'], lambda x, y, i: x || ' - ' || CAST(i AS VARCHAR) || ' - ' || y);
----
a - 2 - b - 3 - c - 4 - d
#errors on simple reduce
statement error
SELECT list_reduce([], lambda x, y, i: x + y + i);
----
Cannot perform list_reduce on an empty input list
statement error
SELECT list_reduce([1, 2, 3], lambda x, y: (x * y)::VARCHAR || 'please work');
----
Could not convert
statement error
SELECT list_reduce([1, 2], lambda x: x);
----
list_reduce expects a function with 2 or 3 arguments
statement error
SELECT list_reduce([1, 2], NULL);
----
Invalid lambda expression!
statement error
SELECt list_reduce([1, 2], (len('abc') AS x, y) - > x + y)
----
Parser Error: syntax error at or near "AS"
# simple reduce on a table
statement ok
CREATE table t1(a int[]);
statement ok
INSERT INTO t1 VALUES ([1, 2, 3]);
statement ok
INSERT INTO t1 VALUES ([666]);
statement ok
INSERT INTO t1 VALUES (NULL);
statement ok
INSERT INTO t1 VALUES ([44, 55]);
statement ok
INSERT INTO t1 VALUES ([-1, NULL, -2]);
query I
SELECT list_reduce(a, lambda x, y: x + y) FROM t1;
----
6
666
NULL
99
NULL
query I
SELECT list_reduce(a, lambda x, y, i: x + y + i) FROM t1;
----
11
666
NULL
101
NULL
statement ok
INSERT INTO t1 VALUES ([]);
statement error
SELECT list_reduce(a, lambda x, y: x + y) FROM t1;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE t1;
# reduce on a table with a list of strings
statement ok
CREATE TABLE t1 (a varchar[]);
statement ok
INSERT INTO t1 VALUES (['Once', 'upon', 'a', 'time']), (NULL), (['there', 'was', 'a', 'table']), (['with', 'a', 'list', 'of', 'strings']), (['and', 'it', 'was', NULL]);
query I
SELECT list_reduce(a, lambda x, y: x || ' ' || y) FROM t1;
----
Once upon a time
NULL
there was a table
with a list of strings
NULL
statement ok
INSERT INTO t1 VALUES ([]);
statement error
SELECT list_reduce(a, lambda x, y: x || ' ' || y) FROM t1;
----
Cannot perform list_reduce on an empty input list
# reduce on a string only using the RHS
statement ok
CREATE TABLE right_only (v varchar[], i int);
statement ok
INSERT INTO right_only VALUES (['blue', 'babbling', 'brook'], 1), (['dogs', 'doing', 'dishes'], 2), (['she', 'sells', 'seashells'], 3);
query I
SELECT list_reduce(v, lambda x, y: y[i]) FROM right_only;
----
b
i
a
# nested functions with ints
query I
SELECT list_reduce([1, 2, 3], lambda x, y: list_reduce([4, 5, 6], lambda a, b: x + y + a + b));
----
63
statement error
SELECT list_reduce([1, 2, 3], lambda x, y: list_reduce([], lambda a, b: x + y + a + b));
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([1, 2, 3], lambda x, y, x_i: list_reduce([4, 5, 6], lambda a, b, a_i: x + y + a + b + x_i + a_i));
----
92
statement error
SELECT list_reduce([1, 2, 3], lambda x, y, x_i: list_reduce([], lambda a, b, a_i: x + y + a + b + x_i + a_i));
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([[10, 20], [30, 40], [50, 60]], lambda x, y: list_pack(
list_reduce(x, lambda l, m: l + m) +
list_reduce(y, lambda n, o: n + o)));
----
[210]
query I
SELECT list_reduce([[1, 2, 3], [4, 5, 6], [7, 8, 9]], lambda x, y: list_pack(
list_reduce(x, lambda l, m: l + m) +
list_reduce(y, lambda n, o: n + o)));
----
[45]
query I
SELECT list_reduce([[10, 20], [30, 40], NULL, [NULL, 60], NULL], lambda x, y: list_pack(
list_reduce(x, lambda l, m: l + m) +
list_reduce(y, lambda n, o: n + o)));
----
[NULL]
# nested functions with strings
query I
SELECT list_reduce(['a', 'b', 'c', 'd'], lambda x, y: list_reduce(['1', '2', '3', '4'], lambda a, b: x || y || a || b));
----
ababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234d1234
query I
SELECT list_reduce([['a', 'b'], ['c', 'd'], ['e', 'f']], lambda x, y: list_pack(list_reduce(x, lambda a, b: a || b) || list_reduce(y, lambda c, d: c || d)));
----
[abcdef]
# nested functions in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[])
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6]), (NULL, NULL), (NULL, [110, 111, 112]), ([77, 88, 99], [55, 66, NULL]);
query I
SELECT list_reduce(n, lambda x, y: list_reduce(l, lambda a, b: x + y + a + b)) FROM nested;
----
63
NULL
NULL
NULL
query I
SELECT list_reduce(n, lambda x, y, x_i: list_reduce(l, lambda a, b, a_i: x + y + a + b + x_i + a_i)) FROM nested;
----
92
NULL
NULL
NULL
query I
SELECT list_reduce(n, lambda x, y, x_i: list_reduce(l, lambda a, b, a_i: x + y + x_i < a + b + a_i)) FROM nested;
----
1
NULL
NULL
NULL
statement ok
INSERT INTO nested VALUES ([4, 5, 6], []);
statement error
SELECT list_reduce(n, lambda x, y: list_reduce(l, lambda a, b: x + y + a + b)) FROM nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][])
statement ok
INSERT INTO nested VALUES ([[10, 20], [30, 40], [50, 60]]), ([[1,2,3], [4,5,6], [7,8,9]]), (NULL), ([[NULL, 60], [70, NULL], [NULL, NULL]]);
query I
SELECT list_reduce(n, lambda x, y: list_pack(list_reduce(x, lambda l, m: l + m) + list_reduce(y, lambda j, k: j + k))) from nested;
----
[210]
[45]
NULL
[NULL]
statement ok
INSERT INTO nested VALUES ([[4, 5, 6], []]);
statement error
SELECT list_reduce(n, lambda x, y: list_pack(list_reduce(x, lambda l, m: l + m) + list_reduce(y, lambda j, k: j + k))) from nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
# nested functions in a table with strings
statement ok
CREATE TABLE nested (n varchar[], l varchar[])
statement ok
INSERT INTO nested VALUES (['a', 'b', 'c', 'd'], ['1', '2', '3', '4']), (NULL, NULL), (NULL, ['110', '111', '112']), (['77', '88', '99'], ['55', '66', NULL]);
query I
SELECT list_reduce(n, lambda x, y: list_reduce(l, lambda a, b: x || y || a || b)) FROM nested;
----
ababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234dababab1234cababab1234cababab1234c1234d1234
NULL
NULL
NULL
statement ok
DROP TABLE nested;
# three level nested functions with ints
query I
SELECT
list_reduce([1, 2, 3], lambda x, y:
list_reduce([4, 5, 6], lambda a, b:
list_reduce([7, 8, 9], lambda c, d: x + y + a + b + c + d)));
----
966
query I
SELECT
list_reduce([1, 2, 3], lambda x, y, x_i:
list_reduce([4, 5, 6], lambda a, b, a_i:
list_reduce([7, 8, 9], lambda c, d, c_i: x + y + a + b + c + d + x_i + a_i + c_i)));
----
1259
query I
SELECT
list_reduce([[[10, 20], [100, 200]], [[30, 40], [300, 400]], [[50, 60], [500, 600]]], lambda x, y: list_pack(
list_reduce(x, lambda l, m: list_pack(
list_reduce(l, lambda a, b: a + b) +
list_reduce(m, lambda c, d: c + d))) +
list_reduce(y, lambda n, o: list_pack(
list_reduce(n, lambda a, b: a + b) +
list_reduce(o, lambda c, d: c + d)))));
----
[[330, 770, 1210]]
# three level nested in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[], m integer[])
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6], [7, 8, 9]), (NULL, NULL, NULL), (NULL, [110, 111, 112], [113, 114, 115]), ([77, 88, 99], [55, 66, NULL], [44, 33, 22]);
query I
SELECT
list_reduce(n, lambda x, y:
list_reduce(l, lambda a, b:
list_reduce(m, lambda c, d: x + y + a + b + c + d)))
FROM nested;
----
966
NULL
NULL
NULL
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][][])
statement ok
INSERT INTO nested VALUES ([[[10, 20], [100, 200]], [[30, 40], [300, 400]], [[50, 60], [500, 600]]]), ([[[1,2,3], [4,5,6], [7,8,9]]]), (NULL), ([[[NULL, 60], [70, NULL], [NULL, NULL]]]);
query I
SELECT
list_reduce(n, lambda x, y:
list_pack(list_reduce(x, lambda l, m:
list_pack(list_reduce(l, lambda a, b: a + b) +
list_reduce(m, lambda c, d: c + d))) +
list_reduce(y, lambda e, f: list_pack(
list_reduce(e, lambda a, b: a + b) +
list_reduce(f, lambda c, d: c + d)))))
FROM nested;
----
[[330, 770, 1210]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
NULL
[[NULL, 60], [70, NULL], [NULL, NULL]]
# list_reduce in where clause
statement ok
CREATE table where_clause (a int[]);
statement ok
INSERT INTO where_clause VALUES ([10, 2, 1]), ([1, 2, 3]), ([15, 4, 3]), ([3, 4, 5]), ([11, 2, 3, 4, 5]), ([5, 4, 3, 2, 1]), ([100, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
query I
SELECT a FROM where_clause WHERE list_reduce(a, lambda x, y: x - y) > 0;
----
[10, 2, 1]
[15, 4, 3]
[100, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# tests on structs
statement ok
CREATE TABLE t_struct (s STRUCT(v VARCHAR, i INTEGER)[]);
statement ok
INSERT INTO t_struct VALUES ([row('a', 1), row('b', 2)]), ([row('c', 3), row('d', 4)]), ([row('e', 5), row('f', 6)]), ([row('g', 7), row('h', 8)]), ([row('i', 9), row('j', 10)]);
query I
SELECT list_reduce(s, lambda a, b: row(a.v || b.v, a.i + b.i)) FROM t_struct;
----
{'v': ab, 'i': 3}
{'v': cd, 'i': 7}
{'v': ef, 'i': 11}
{'v': gh, 'i': 15}
{'v': ij, 'i': 19}
# issue #11142
statement ok
CREATE OR REPLACE TABLE df(s STRUCT(a INT, b INT)[]);
statement ok
INSERT INTO df VALUES ([row(0, 0), row(0, 1), row(0, 2)]);
query I
SELECT list_reduce(s, lambda curr, next: struct_pack(a:=curr.a + (next.b - curr.b), b:=next.b))
FROM df
----
{'a': 2, 'b': 2}
query I
SELECT
list_reduce(
[struct_pack(a := 0, b := 0), struct_pack(a := 0, b := 1), struct_pack(a := 0, b := 2)],
lambda curr, next: struct_pack(a := curr.a + (next.b - curr.b), b := next.b)
)
----
{'a': 2, 'b': 2}

View File

@@ -0,0 +1,550 @@
# name: test/sql/function/list/lambdas/reduce_initial.test
# description: Test list_reduce function with an intial value
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x + y, 100);
----
106
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x * y, -1);
----
-6
query I
SELECT list_reduce([100, 10, 1], lambda x, y, i: x - y - i, 1000);
----
883
query I
SELECT list_reduce([1, 2, 3], lambda x, y: y - x, -1);
----
3
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x - y, 10);
----
4
query I
SELECT list_reduce([1, 2, 3], lambda x, y, i: x + y + i, -1);
----
11
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x + y, NULL);
----
NULL
query I
SELECT list_reduce([NULL], lambda x, y, i: x + y + i, 100);
----
NULL
query I
SELECT list_reduce(NULL, lambda x, y, i: x + y + i, 100);
----
NULL
query I
SELECT list_reduce(['Once', 'upon', 'a', 'time'], lambda x, y: x || ' ' || y, '-->');
----
--> Once upon a time
query I
SELECT list_reduce([], lambda x, y: x + y, 100);
----
100
query I
SELECT list_reduce(['a', 'b', 'c'], lambda x, y: x || y, NULL);
----
NULL
#errors on simple reduce with initial value
statement error
SELECT list_reduce([1, 2, 3], lambda x, y: (x * y), 'i dare you to cast me');
----
Binder Error
statement error
SELECT list_reduce([1, 2], lambda x: x, 100);
----
list_reduce expects a function with 2 or 3 arguments
statement error
SELECT list_reduce([1, 2], NULL, 100);
----
Invalid lambda expression!
statement error
SELECt list_reduce([1, 2], (len('abc') AS x, y) - > x + y, 100)
----
Parser Error: syntax error at or near "AS"
# simple reduce on a table
statement ok
CREATE table t1(l int[], initial int);
statement ok
INSERT INTO t1 VALUES ([1, 2, 3], 100);
statement ok
INSERT INTO t1 VALUES ([666], 1000);
statement ok
INSERT INTO t1 VALUES ([1, 2, 3], NULL);
statement ok
INSERT INTO t1 VALUES (NULL, 2);
statement ok
INSERT INTO t1 VALUES ([44, 55], 3);
statement ok
INSERT INTO t1 VALUES ([-1, NULL, -2], 4);
query I
SELECT list_reduce(l, lambda x, y: x + y, initial) FROM t1;
----
106
1666
NULL
NULL
102
NULL
query I
SELECT list_reduce(l, lambda x, y, i: x + y + i, initial) FROM t1;
----
112
1667
NULL
NULL
105
NULL
statement ok
INSERT INTO t1 VALUES ([], 100);
statement error
SELECT list_reduce(l, lambda x, y: x + y) FROM t1;
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce(l, lambda x, y: x + y, initial) FROM t1;
----
106
1666
NULL
NULL
102
NULL
100
statement ok
DROP TABLE t1;
# reduce on a table with a list of strings
statement ok
CREATE TABLE t1 (l varchar[], initial varchar);
statement ok
INSERT INTO t1 VALUES (['a', 'b'], '1:'), (NULL, '2:'), (['e', 'f'], '3:');
query I
SELECT list_reduce(l, lambda x, y: x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
statement ok
INSERT INTO t1 values (['h', NULL], '4:'), (['i', 'j'], '5:');
query I
SELECT list_reduce(l, lambda x, y: x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
NULL
5: i j
statement ok
INSERT INTO t1 values (['x', 'y'], NULL);
query I
SELECT list_reduce(l, lambda x, y: x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
NULL
5: i j
NULL
statement ok
INSERT INTO t1 VALUES ([], '7:');
statement error
SELECT list_reduce(l, lambda x, y: x || ' ' || y) FROM t1;
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce(l, lambda x, y: x || ' ' || y, initial) FROM t1;
----
1: a b
NULL
3: e f
NULL
5: i j
NULL
7:
# reduce on a string only using the RHS
statement ok
CREATE TABLE right_only (v varchar[], i int);
statement ok
INSERT INTO right_only VALUES (['blue', 'babbling', 'brook'], 1), (['dogs', 'doing', 'dishes'], 2), (['she', 'sells', 'seashells'], 3);
query I
SELECT list_reduce(v, lambda x, y: y[i]) FROM right_only;
----
b
i
a
# nested functions with ints
query I
SELECT list_reduce([1, 2, 3], lambda x, y: list_reduce([4, 5, 6], lambda a, b: x + y + a + b, 100), 1000);
----
28549
statement error
SELECT list_reduce([1, 2, 3], lambda x, y: list_reduce([], lambda a, b: x + y + a + b), 1000);
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([1, 2, 3], lambda x, y, x_i: list_reduce([4, 5, 6], lambda a, b, a_i: x + y + a + b + x_i + a_i, 100), 1000);
----
28681
statement error
SELECT list_reduce([1, 2, 3], lambda x, y, x_i: list_reduce([], lambda a, b, a_i: x + y + a + b + x_i + a_i), 1000);
----
Cannot perform list_reduce on an empty input list
query I
SELECT list_reduce([[10, 20], [30, 40], [50, 60]], lambda x, y: list_pack(list_reduce(x, lambda l, m: l + m) + list_reduce(y, lambda n, o: n + o)), [100, 200]);
----
[510]
query I
SELECT list_reduce([[1,2,3], [4,5,6], [7,8,9]], lambda x, y: list_pack(list_reduce(x, lambda l, m: l + m) + list_reduce(y, lambda n, o: n + o)), [100]);
----
[145]
query I
SELECT list_reduce([[10, 20], [30, 40], NULL, [NULL, 60], NULL], lambda x, y: list_pack(list_reduce(x, lambda l, m: l + m) + list_reduce(y, lambda n, o: n + o)), [100]);
----
[NULL]
# nested functions with strings
query I
SELECT list_reduce(['a', 'b'], lambda x, y: list_reduce(['1', '2'], lambda a, b: x || y || a || b, 'B'), 'A');
----
AaAaB12bAaAaB12bB12
query I
SELECT list_reduce([['a', 'b'], ['c', 'd'], ['e', 'f']], lambda x, y: list_pack(list_reduce(x, lambda a, b: a || b) || list_reduce(y, lambda c, d: c || d)), ['->']);
----
[->abcdef]
# nested functions in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[], initial integer);
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6], 100), (NULL, NULL, 100), (NULL, [110, 111, 112], 44), ([77, 88, 99], [55, 66, NULL], 1);
query I
SELECT list_reduce(n, lambda x, y: list_reduce(l, lambda a, b: x + y + a + b), initial) FROM nested;
----
927
NULL
NULL
NULL
query I
SELECT list_reduce(n, lambda x, y, x_i: list_reduce(l, lambda a, b, a_i: x + y + a + b + x_i + a_i), initial) FROM nested;
----
984
NULL
NULL
NULL
query I
SELECT list_reduce(n, lambda x, y, x_i: list_reduce(l, lambda a, b, a_i: x + y + x_i < a + b + a_i), initial) FROM nested;
----
1
NULL
NULL
NULL
statement ok
INSERT INTO nested VALUES ([4, 5, 6], [], -1);
statement error
SELECT list_reduce(n, lambda x, y: list_reduce(l, lambda a, b: x + y + a + b), initial) FROM nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][], initial integer[]);
statement ok
INSERT INTO nested VALUES ([[10, 20], [30, 40], [50, 60]], [100]), ([[1,2,3], [4,5,6], [7,8,9]], [1000]), (NULL, [-1]), ([[NULL, 60], [70, NULL], [NULL, NULL]], [NULL]);
query I
SELECT list_reduce(n, lambda x, y: list_pack(list_reduce(x, lambda l, m: l + m) + list_reduce(y, lambda j, k: j + k)), initial) from nested;
----
[310]
[1045]
NULL
[NULL]
statement ok
INSERT INTO nested VALUES ([[4, 5, 6], []], [9]);
statement error
SELECT list_reduce(n, lambda x, y: list_pack(list_reduce(x, lambda l, m: l + m) + list_reduce(y, lambda j, k: j + k)), initial) from nested;
----
Cannot perform list_reduce on an empty input list
statement ok
DROP TABLE nested;
# nested functions in a table with strings
statement ok
CREATE TABLE nested (n varchar[], l varchar[], initialN varchar, initialL varchar);
statement ok
INSERT INTO nested VALUES (['a', 'b'], ['1', '2'], 'A', 'B'), (NULL, NULL, 'C', 'D'), (NULL, ['110', '111', '112'], 'X', 'Y'), (['77', '88', '99'], ['55', '66', NULL], 'E', 'F');
query I
SELECT list_reduce(n, lambda x, y: list_reduce(l, lambda a, b: x || y || a || b, initialL), initialN) FROM nested;
----
AaAaB12bAaAaB12bB12
NULL
NULL
NULL
statement ok
DROP TABLE nested;
# three level nested functions with ints
query I
SELECT list_reduce([1, 2, 3], lambda x, y: list_reduce([4, 5, 6], lambda a, b: list_reduce([7, 8, 9], lambda c, d: x + y + a + b + c + d, 1000), 100), 10);
----
25917331
query I
SELECT list_reduce([1, 2, 3], lambda x, y, x_i: list_reduce([4, 5, 6], lambda a, b, a_i: list_reduce([7, 8, 9], lambda c, d, c_i: x + y + a + b + c + d + x_i + a_i + c_i, 1000), 100), 10);
----
26185861
# three level nested in a table with ints
statement ok
CREATE TABLE nested (n integer[], l integer[], m integer[], initial integer);
statement ok
INSERT INTO nested VALUES ([1, 2, 3], [4, 5, 6], [7, 8, 9], 100), (NULL, NULL, NULL, NULL), (NULL, [110, 111, 112], [113, 114, 115], NULL), ([77, 88, 99], [55, 66, NULL], [44, 33, 22], 1);
query I
SELECT list_reduce(n, lambda x, y: list_reduce(l, lambda a, b: list_reduce(m, lambda c, d: x + y + a + b + c + d, initial), initial), initial) FROM nested;
----
12992341
NULL
NULL
NULL
statement ok
DROP TABLE nested;
statement ok
CREATE TABLE nested (n integer[][][], initial integer[][]);
statement ok
INSERT INTO nested VALUES ([[[10, 20], [100, 200]], [[30, 40], [300, 400]], [[50, 60], [500, 600]]], [[1]]), ([[[1,2,3], [4,5,6], [7,8,9]]], [[2]]), (NULL, [[3]]), ([[[NULL, 60], [70, NULL], [NULL, NULL]]], [[4]]);
query I
SELECT
list_reduce(n, lambda x, y: list_pack(
list_reduce(x, lambda l, m: list_pack(
list_reduce(l, lambda a, b: a + b) +
list_reduce(m, lambda c, d: c + d))) +
list_reduce(y, lambda e, f: list_pack(
list_reduce(e, lambda a, b: a + b) +
list_reduce(f, lambda c, d: c + d)))))
FROM nested;
----
[[330, 770, 1210]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
NULL
[[NULL, 60], [70, NULL], [NULL, NULL]]
# tests on structs
statement ok
CREATE TABLE t_struct (s STRUCT(v VARCHAR, i INTEGER)[], initial STRUCT(v VARCHAR, i INTEGER));
statement ok
INSERT INTO t_struct VALUES ([row('a', 1), row('b', 2)], row('->', 1)), ([row('c', 3), row('d', 4)], row('-->', 2)), ([row('e', 5), row('f', 6)], row('--->', 3)), ([row('g', 7), row('h', 8)], row('---->', 4)), ([row('i', 9), row('j', 10)], row('----->', 5));
query I
SELECT list_reduce(s, lambda a, b: row(a.v || b.v, a.i + b.i), initial) FROM t_struct;
----
{'v': ->ab, 'i': 4}
{'v': -->cd, 'i': 9}
{'v': --->ef, 'i': 14}
{'v': ---->gh, 'i': 19}
{'v': ----->ij, 'i': 24}
# issue #11142
statement ok
CREATE OR REPLACE TABLE df(s STRUCT(a INT, b INT)[], initial STRUCT(a INT, b INT));
statement ok
INSERT INTO df VALUES ([row(0, 0), row(0, 1), row(0, 2)], row(-2, -3));
query I
SELECT list_reduce(s, lambda curr, next: struct_pack(a:=curr.a + (next.b - curr.b), b:=next.b), initial)
FROM df
----
{'a': 3, 'b': 2}
query I
SELECT
list_reduce(
[struct_pack(a := 0, b := 0), struct_pack(a := 0, b := 1), struct_pack(a := 0, b := 2)],
lambda curr, next: struct_pack(a := curr.a + (next.b - curr.b), b := next.b), struct_pack(a := -2, b := -3)
)
----
{'a': 3, 'b': 2}
# list_reduce in where clause
statement ok
CREATE table where_clause (a int[], initial integer);
statement ok
INSERT INTO where_clause VALUES ([10, 2, 1], 10), ([1, 2, 3], 20), ([15, 4, 3], 30), ([3, 4, 5], 40), ([11, 2, 3, 4, 5], 50), ([5, 4, 3, 2, 1], 60), ([100, 2, 3, 4, 5, 6, 7, 8, 9, 10], 70);
query I
SELECT a FROM where_clause WHERE list_reduce(a, lambda x, y: x - y, initial) > 0;
----
[1, 2, 3]
[15, 4, 3]
[3, 4, 5]
[11, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
# where the initial value has a different type of the list
query I
SELECT list_reduce([0], lambda x, y: x > 3, 3.1);
----
1.0
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x + y, 10.5);
----
16.5
query I
SELECT list_reduce([1, 2, 3], lambda x, y: x * y, 2.5);
----
15.0
statement ok
CREATE TABLE cast_test (l int[], initial float);
statement ok
INSERT INTO cast_test VALUES ([1, 2, 3], 100.0), ([0], 3.1), ([3, 2, 1], 10.5);
query I
SELECT list_reduce(l, lambda x, y: x > 3, initial) FROM cast_test;
----
0.0
1.0
0.0
query I
SELECT list_reduce(l, lambda x, y: x + y, initial) FROM cast_test;
----
106.0
3.1
16.5
query I
SELECT list_reduce(l, lambda x, y: x * y, initial) FROM cast_test;
----
600.0
0.0
63.0
# Test errors with incompatible types
statement error
SELECT list_reduce([1, 2, 3], lambda x, y: x + y, [1, 2]);
----
The initial value type must be the same as the list child type or a common super type
statement error
SELECT list_reduce([BLOB 'hello'], lambda x, y: x, 'text');
----
The initial value type must be the same as the list child type or a common super type
query I
SELECT list_reduce([NULL, NULL]::INTEGER[], lambda x, y: x + y, 3.14);
----
NULL
# Test using ENUM types
statement ok
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
query I
SELECT list_reduce(['sad', 'happy']::mood[], lambda x, y: y::text, 'Mood:');
----
happy
query I
SELECT list_reduce([[1, 2], [3, 4]], lambda x, y: array_append(x, list_aggregate(y, 'sum')), [0]);
----
[0, 3, 7]
query I
SELECT list_reduce([5, 10, 15], lambda x, y: x * y, 1 + 1);
----
1500

View File

@@ -0,0 +1,38 @@
# name: test/sql/function/list/lambdas/reduce_initial.test_slow
# description: Test list_reduce function with an intial value on a larger data set
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# Large lists.
statement ok
CREATE TABLE large_lists AS SELECT range % 4 g, list(range) l, 100 AS initial FROM range(10000) GROUP BY range % 4;
query I
SELECT list_reduce(l, lambda x, y: least(x, y), initial) FROM large_lists ORDER BY g;
----
0
1
2
3
query I
SELECT list_reduce(l, lambda x, y: x + y, initial) FROM large_lists ORDER BY g;
----
12495100
12497600
12500100
12502600
# Large table.
statement ok
CREATE TABLE large_table AS
SELECT list_reduce(range(5000), lambda x, y: x + y, 1) AS l FROM range(1000);
query I
SELECT COUNT(*) FROM large_table WHERE l = 12497501;
----
1000

View File

@@ -0,0 +1,38 @@
# name: test/sql/function/list/lambdas/reduce_on_larger_data.test_slow
# description: Test list_reduce function on larger data
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# Large lists.
statement ok
CREATE TABLE large_lists AS SELECT range % 4 g, list(range) l FROM range(10000) GROUP BY range % 4;
query I
SELECT list_reduce(l, lambda x, y: least(x, y)) FROM large_lists ORDER BY g;
----
0
1
2
3
query I
SELECT list_reduce(l, lambda x, y: x + y) FROM large_lists ORDER BY g;
----
12495000
12497500
12500000
12502500
# Large table.
statement ok
CREATE TABLE large_table AS
SELECT list_reduce(range(5000), lambda x, y: x + y) AS l FROM range(1000);
query I
SELECT COUNT(*) FROM large_table WHERE l = 12497500;
----
1000

View File

@@ -0,0 +1,93 @@
# name: test/sql/function/list/lambdas/rhs_parameters.test
# description: Test nested lambda parameters in the rhs of lambda expressions
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# Issue 5795.
query I
SELECT list_apply([1,2], lambda x: list_apply([3,4], lambda y: {'x': x, 'y': y})) AS bug;
----
[[{'x': 1, 'y': 3}, {'x': 1, 'y': 4}], [{'x': 2, 'y': 3}, {'x': 2, 'y': 4}]]
# Test arbitrary other nested lambdas.
query I
SELECT list_transform([1,2], lambda x: list_transform([3,4], lambda y: x + y));
----
[[4, 5], [5, 6]]
query I
SELECT list_transform([1,2], lambda x:
list_transform([3,4], lambda y:
list_transform([5,6], lambda z: z + y + x)));
----
[[[9, 10], [10, 11]], [[10, 11], [11, 12]]]
query I
SELECT list_transform([1,2,3,4], lambda x: list_filter([4,5,1,2,3,3,3,5,1,4], lambda y: y != x))
----
[[4, 5, 2, 3, 3, 3, 5, 4], [4, 5, 1, 3, 3, 3, 5, 1, 4], [4, 5, 1, 2, 5, 1, 4], [5, 1, 2, 3, 3, 3, 5, 1]]
query I
SELECT list_transform([[2, 4, 6]], lambda x: list_transform(x, lambda y: list_sum([y] || x)))
----
[[14, 16, 18]]
query I
SELECT list_apply(range(5), lambda x: {x:x, w:list_filter(range(5), lambda y: abs(y-x) < 2)});
----
[{'x': 0, 'w': [0, 1]}, {'x': 1, 'w': [0, 1, 2]}, {'x': 2, 'w': [1, 2, 3]}, {'x': 3, 'w': [2, 3, 4]}, {'x': 4, 'w': [3, 4]}]
query I
SELECT list_apply(range(8), lambda x: list_aggr(list_apply(range(8),
lambda y: list_element('▁▂▃▄▅▆▇█', 1+abs(y-x))), 'string_agg', ''));
----
[, , , , , , , ]
statement ok
CREATE TABLE lists (i integer, v varchar[])
statement ok
INSERT INTO lists VALUES (1, ['a', 'b', 'c']), (8, NULL), (3, ['duck', 'db', 'tests']), (NULL, NULL), (NULL, ['lambdas!'])
query I
SELECT list_transform(v, lambda x: list_transform(v, lambda y: x || y)) FROM lists
----
[[aa, ab, ac], [ba, bb, bc], [ca, cb, cc]]
NULL
[[duckduck, duckdb, ducktests], [dbduck, dbdb, dbtests], [testsduck, testsdb, teststests]]
NULL
[[lambdas!lambdas!]]
query I
SELECT list_transform(v, lambda x: list_transform(v, lambda y: list_transform(v, lambda z: x || y || z))) FROM lists
----
[[[aaa, aab, aac], [aba, abb, abc], [aca, acb, acc]], [[baa, bab, bac], [bba, bbb, bbc], [bca, bcb, bcc]], [[caa, cab, cac], [cba, cbb, cbc], [cca, ccb, ccc]]]
NULL
[[[duckduckduck, duckduckdb, duckducktests], [duckdbduck, duckdbdb, duckdbtests], [ducktestsduck, ducktestsdb, duckteststests]], [[dbduckduck, dbduckdb, dbducktests], [dbdbduck, dbdbdb, dbdbtests], [dbtestsduck, dbtestsdb, dbteststests]], [[testsduckduck, testsduckdb, testsducktests], [testsdbduck, testsdbdb, testsdbtests], [teststestsduck, teststestsdb, teststeststests]]]
NULL
[[[lambdas!lambdas!lambdas!]]]
query I
SELECT list_transform(v, lambda x: [list_transform([':-)'], lambda y: x || y || '-#lambdaLove')]
|| list_filter(list_transform(['B-)'], lambda k: [k] || [x]), lambda j: list_contains(j, 'a') or list_contains(j, 'duck')))
FROM lists
----
[[['a:-)-#lambdaLove'], ['B-)', a]], [['b:-)-#lambdaLove']], [['c:-)-#lambdaLove']]]
NULL
[[['duck:-)-#lambdaLove'], ['B-)', duck]], [['db:-)-#lambdaLove']], [['tests:-)-#lambdaLove']]]
NULL
[[['lambdas!:-)-#lambdaLove']]]
statement ok
CREATE TABLE no_overwrite AS SELECT [range, range + 1] l FROM range(3);
query II
SELECT l, [[{'x+y': x + y, 'x': x, 'y': y, 'l': l} for y in [42, 43]] for x in l] FROM no_overwrite;
----
[0, 1] [[{'x+y': 42, 'x': 0, 'y': 42, 'l': [0, 1]}, {'x+y': 43, 'x': 0, 'y': 43, 'l': [0, 1]}], [{'x+y': 43, 'x': 1, 'y': 42, 'l': [0, 1]}, {'x+y': 44, 'x': 1, 'y': 43, 'l': [0, 1]}]]
[1, 2] [[{'x+y': 43, 'x': 1, 'y': 42, 'l': [1, 2]}, {'x+y': 44, 'x': 1, 'y': 43, 'l': [1, 2]}], [{'x+y': 44, 'x': 2, 'y': 42, 'l': [1, 2]}, {'x+y': 45, 'x': 2, 'y': 43, 'l': [1, 2]}]]
[2, 3] [[{'x+y': 44, 'x': 2, 'y': 42, 'l': [2, 3]}, {'x+y': 45, 'x': 2, 'y': 43, 'l': [2, 3]}], [{'x+y': 45, 'x': 3, 'y': 42, 'l': [2, 3]}, {'x+y': 46, 'x': 3, 'y': 43, 'l': [2, 3]}]]

View File

@@ -0,0 +1,66 @@
# name: test/sql/function/list/lambdas/storage.test
# description: Test storing lambda functions
# group: [lambdas]
load __TEST_DIR__/lambda_storage.db
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# create macros containing a lambda functions
statement ok
CREATE MACRO my_transform(list) AS list_transform(list, lambda x: x * x)
statement ok
CREATE MACRO my_filter(list) AS list_filter(list, lambda x: x > 42)
statement ok
CREATE MACRO my_reduce(list) AS list_reduce(list, lambda x, y: x + y)
statement ok
CREATE MACRO my_nested_lambdas(nested_list) AS list_filter(nested_list, lambda elem: list_reduce(
list_transform(elem, lambda x: x + 1), lambda x, y: x + y) > 42)
query I
SELECT my_transform([1, 2, 3])
----
[1, 4, 9]
query I
SELECT my_filter([41, 42, NULL, 43, 44])
----
[43, 44]
query I
SELECT my_reduce([1, 2, 3])
----
6
query I
SELECT my_nested_lambdas([[40, NULL], [20, 21], [10, 10, 20]])
----
[[20, 21], [10, 10, 20]]
# restart the system
restart
query I
SELECT my_transform([1, 2, 3])
----
[1, 4, 9]
query I
SELECT my_filter([41, 42, NULL, 43, 44])
----
[43, 44]
query I
SELECT my_reduce([1, 2, 3])
----
6
query I
SELECT my_nested_lambdas([[40, NULL], [20, 21], [10, 10, 20]])
----
[[20, 21], [10, 10, 20]]

View File

@@ -0,0 +1,93 @@
# name: test/sql/function/list/lambdas/table_functions.test
# description: Test list lambdas in table functions
# group: [lambdas]
require parquet
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
statement ok
CREATE TABLE tmp AS SELECT range AS id FROM range(10);
# create a parquet file
query I
COPY tmp TO '__TEST_DIR__/my_file_cba.parquet' (FORMAT PARQUET);
----
10
# now test different table functions
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(['C', 'B', 'A'], lambda s: lower(s)), 'string_agg', '') || '.parquet');
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(list_sort(['a', 'b', 'c'], 'DESC'), lambda s: lower(s)), 'string_agg', '') || '.parquet');
----
10
# nested lambdas
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(list_filter(['s', 'c', 'b', NULL, 'a'], lambda x: x IS NOT NULL AND x != 's'),
lambda s: lower(s)), 'string_agg', '') || '.parquet');
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(list_filter(
list_filter(['s', 'c', 'b', NULL, 'a'], lambda y: y != 's'), lambda x: x IS NOT NULL),
lambda s: lower(s)), 'string_agg', '') || '.parquet');
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_reduce([['c', 'b', NULL, 'a']], lambda x, y: coalesce(x,y)), 'string_agg', '') || '.parquet');
----
10
# lambda parameters in rhs
query I
COPY tmp TO '__TEST_DIR__/my_file_ac.parquet' (FORMAT PARQUET);
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_aggr(list_transform(['a'], lambda x: list_transform(['a', 'c'], lambda y: x || y)[2]), 'string_agg', '') || '.parquet');
----
10
# issue 5821 (without httpfs)
query I
COPY tmp TO '__TEST_DIR__/my_file_a=1,b=2,c=3.parquet' (FORMAT PARQUET);
----
10
query I
SELECT COUNT(*) FROM read_parquet('__TEST_DIR__/my_file_' ||
list_string_agg([lower(s) for s in ['a=1', 'b=2', 'c=3']]) || '.parquet');
----
10
# lambdas in ALTER TABLE statements
statement ok
CREATE TABLE cities AS
SELECT * FROM (VALUES ('Amsterdam', [90, 10]), ('London', [89, 102])) cities (name, prices);
statement ok
ALTER TABLE cities
ALTER COLUMN prices SET DATA TYPE INTEGER[] USING
list_filter(cities.prices, lambda price: price < 100);
query II
SELECT name, prices AS cheap_options FROM cities;
----
Amsterdam [90, 10]
London [89]

View File

@@ -0,0 +1,30 @@
# name: test/sql/function/list/lambdas/test_lambda_storage.test
# description: Test loading a database file with the old lambda syntax.
# group: [lambdas]
# With DuckDB 1.2.2:
# CREATE TABLE tbl AS SELECT range AS i FROM range(100);
# CREATE VIEW lambda_view AS SELECT list_transform([i], x -> x + 1) AS list_i FROM tbl;
# CREATE MACRO lambda_macro(c1, c2) AS list_transform([c1, c2], (x, i) -> x + i + 1);
# The file has a vector size of 2048.
require vector_size 2048
unzip data/storage/lambda_storage.db.gz __TEST_DIR__/lambda_storage.db
load __TEST_DIR__/lambda_storage.db readonly
# We need to ensure backwards compatibility, even if we eventually stop allowing the deprecated syntax.
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
query I
SELECT SUM(list_i[1]) FROM lambda_view;
----
5050
query I
SELECT lambda_macro(1, 2);
----
[3, 5]

View File

@@ -0,0 +1,320 @@
# name: test/sql/function/list/lambdas/transform.test
# description: Test list_transform function
# group: [lambdas]
# NOTE: some of these tests are directly taken from the Presto Array Function examples
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
# Test NULLs and simple cases.
query II
SELECT [1] AS l, list_transform([1], lambda l: l + 1)
----
[1] [2]
query I
SELECT list_transform(NULL, lambda x: x + 1)
----
NULL
query I
SELECT list_transform([1], lambda x: x)
----
[1]
query I
SELECT list_transform(['duck', 'a', 'ö'], lambda duck: concat(duck, 'DB'))
----
[duckDB, aDB, öDB]
query I
SELECT list_transform([1, 2, 3], lambda x: 1)
----
[1, 1, 1]
query I
SELECT list_transform([], lambda x: x + 1)
----
[]
query I
SELECT list_transform([1, 2, 3], lambda x: x + 1)
----
[2, 3, 4]
query I
SELECT list_transform([1, NULL, -2, NULL], lambda x: x + 1)
----
[2, NULL, -1, NULL]
# Test on table with rows.
statement ok
CREATE TABLE lists (n integer, l integer[])
statement ok
INSERT INTO lists VALUES (1, [1]), (2, [1, 2, 3]), (3, NULL), (4, [-1, NULL, 2])
query I
SELECT list_transform(l, lambda x: x) FROM lists
----
[1]
[1, 2, 3]
NULL
[-1, NULL, 2]
query I
SELECT list_transform(l, lambda x: x + n) FROM lists
----
[2]
[3, 4, 5]
NULL
[3, NULL, 6]
query I
SELECT list_transform(l, lambda x: x < 2) FROM lists
----
[true]
[true, false, false]
NULL
[true, NULL, false]
# Test other operators and more complex/nested functions.
query I
SELECT list_transform(['x', 'abc', 'z'], lambda x: x || '0')
----
[x0, abc0, z0]
query I
SELECT list_transform([[1], [2, 3], [NULL], NULL], lambda x: list_transform(x, lambda y: y + 1))
----
[[2], [3, 4], [NULL], NULL]
query I
SELECT list_transform([[1], [2], [3]], lambda x: list_concat(x, x))
----
[[1, 1], [2, 2], [3, 3]]
query I
SELECT list_transform([5, NULL, 6], lambda x: POW(x, 2)::INTEGER)
----
[25, NULL, 36]
query I
SELECT list_transform([5, NULL, 6], lambda x: COALESCE(x, 0) + 1)
----
[6, 1, 7]
query I
SELECT list_transform(list_value(list_unique(list_concat([1,2],[2,2]))), lambda x: (x + 1)::INTEGER);
----
[3]
query I
SELECT list_sort(list_transform(list_distinct(list_concat([1,2],[2,2])), lambda x: x + 1));
----
[2, 3]
query I
SELECT list_transform([[1], [2], [3]], lambda x : list_concat(
list_transform(x, lambda y: y + 1),
list_transform(x, lambda z: z - 1)))
----
[[2, 0], [3, 1], [4, 2]]
statement error
SELECT list_transform([[1], [4], NULL, [1], [8]], lambda x: list_concat(
list_transform(x, lambda y: CASE WHEN y > 1 THEN 'yay' ELSE 'nay' END), x))
----
an explicit cast is required
query I
SELECT list_transform([[1], [4], NULL, [1], [8]], lambda x: list_concat(
list_transform(x, lambda y: CASE WHEN y > 1 THEN 'yay' ELSE 'nay' END), x::VARCHAR[]))
----
[[nay, 1], [yay, 4], [], [nay, 1], [yay, 8]]
# Test aliases.
query I
SELECT array_transform([1, NULL], lambda arr_elem: arr_elem - 4)
----
[-3, NULL]
query I
SELECT array_apply([1, NULL], lambda arr_elem: arr_elem - 4)
----
[-3, NULL]
query I
SELECT list_apply([1, NULL], lambda arr_elem: arr_elem - 4)
----
[-3, NULL]
# More tests on precedence.
query I
SELECT list_apply(i, lambda x: (6 + 2 * 12) // x) FROM (VALUES (list_value(1, 2, 3))) tbl(i);
----
[30, 15, 10]
query I
SELECT list_apply(i, lambda x: x + 1 AND x + 1) FROM (VALUES (list_value(1, 2, 3))) tbl(i);
----
[true, true, true]
# Test large lists.
statement ok
CREATE TABLE large_lists AS SELECT range % 4 g, list(range) l FROM range(10000) GROUP BY range % 4;
statement ok
CREATE TABLE transformed_lists (g integer, l integer[]);
statement ok
INSERT INTO transformed_lists (SELECT g + 1, list_transform(l, lambda x: x + 1) FROM large_lists WHERE g != 3)
statement ok
INSERT INTO transformed_lists (SELECT g - 3, list_transform(l, lambda x: x - 3) FROM large_lists WHERE g = 3)
query I
SELECT ll.l = tl.l FROM large_lists ll, transformed_lists tl WHERE ll.g = tl.g
----
True
True
True
True
# Test structs (issue #5005).
query I
SELECT list_transform([{'a': 1}], lambda x: x.a);
----
[1]
query I
SELECT list_transform([{'a': [1, 2, 3]}], lambda x: x.a[2]);
----
[2]
query I
SELECT list_transform([{'b' : {'a': 1}}], lambda x: x.b.a);
----
[1]
query I
SELECT list_transform([{'b' : {'a': 42, 'b': 43}}], lambda x: x.b.b);
----
[43]
query I
SELECT list_transform([{'b' : {'a': [{'c': 77}], 'b': 43}}], lambda x: x.b.a[1].c);
----
[77]
# test correlated subqueries
statement ok
CREATE TABLE corr_test (n integer, l integer[], g integer)
statement ok
INSERT INTO corr_test VALUES (1, [2, 1, 1], 1), (3, [NULL, 2, 4, 4], 1), (NULL, NULL, 1), (0, [], 1)
query I
SELECT n FROM corr_test WHERE list_sum(list_transform(l, lambda elem: elem - n)) >= n
----
1
query I
SELECT ct.n FROM corr_test ct
WHERE list_count(ct.l) < (
SELECT list_count(list_transform(list_concat(list(c.n), ct.l), lambda a: a))
FROM corr_test c GROUP BY c.g)
ORDER BY ct.n
----
0
1
3
query I
SELECT (SELECT list_transform(l, lambda elem: elem + 1)) FROM corr_test
----
[3, 2, 2]
[NULL, 3, 5, 5]
NULL
[]
query I
SELECT (SELECT list_transform(l, lambda elem: elem + n)) FROM corr_test
----
[3, 2, 2]
[NULL, 5, 7, 7]
NULL
[]
query I
SELECT (SELECT (SELECT (SELECT list_transform(l, lambda elem: elem + 1)))) FROM corr_test
----
[3, 2, 2]
[NULL, 3, 5, 5]
NULL
[]
# positional references in lambda functions
query I
SELECT list_transform([1, 2, 3], lambda x: x + #1) FROM range(10)
----
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 10]
[9, 10, 11]
[10, 11, 12]
# test for issue 4855
statement ok
create table test(a int, b int);
statement ok
insert into test values (1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4);
query III
select list_transform(bb, lambda x: [x, b]), bb, b
from (select list(b) over wind as bb, first(b) over wind as b
from test window wind as
(order by a asc, b asc rows between 4 preceding and current row)
qualify row_number() over wind >4);
----
[[2, 2], [3, 2], [4, 2], [2, 2], [3, 2]] [2, 3, 4, 2, 3] 2
[[3, 3], [4, 3], [2, 3], [3, 3], [4, 3]] [3, 4, 2, 3, 4] 3
[[4, 4], [2, 4], [3, 4], [4, 4], [2, 4]] [4, 2, 3, 4, 2] 4
[[2, 2], [3, 2], [4, 2], [2, 2], [3, 2]] [2, 3, 4, 2, 3] 2
[[3, 3], [4, 3], [2, 3], [3, 3], [4, 3]] [3, 4, 2, 3, 4] 3
query I
SELECT list_transform([[2, 3], [4]], lambda x: list_transform([42], lambda y: y + 1))
----
[[43], [43]]
query I
SELECT list_transform([[2, 3], [4]], lambda x: list_transform(x, lambda y: y + 1))
----
[[3, 4], [5]]
query I
SELECT list_transform([[2, 3], [4]], lambda x: list_transform([1], lambda y: x || [y]))
----
[[[2, 3, 1]], [[4, 1]]]
query I
SELECT list_transform([[2, 3], [4]], lambda x: list_transform(x, lambda y: x || [y]))
----
[[[2, 3, 2], [2, 3, 3]], [[4, 4]]]

View File

@@ -0,0 +1,145 @@
# name: test/sql/function/list/lambdas/transform_with_index.test
# description: Test the list_transform function with an index parameter
# group: [lambdas]
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
query I
SELECT list_transform([1, 2, 3], lambda x: list_transform([4, 5, 6], lambda y, y_i: x + y + y_i));
----
[[6, 8, 10], [7, 9, 11], [8, 10, 12]]
query I
SELECT list_transform(['abc'], lambda x, i: x[i + 1]);
----
[b]
query I
SELECT list_filter([1, 2, 1], lambda x, y: x >= y);
----
[1, 2]
query I
SELECT
list_transform([1, 2, 3], lambda x:
list_transform([4, 5, 6], lambda y:
list_transform([7, 8, 9], lambda z, i:
x + y + z + i)));
----
[[[13, 15, 17], [14, 16, 18], [15, 17, 19]], [[14, 16, 18], [15, 17, 19], [16, 18, 20]], [[15, 17, 19], [16, 18, 20], [17, 19, 21]]]
query I
SELECT list_transform([10, 20, 30], lambda x, i: x + i);
----
[11, 22, 33]
query I
SELECT list_transform([1, 2, 3, 4, 5, 6], lambda x, i: x * i);
----
[1, 4, 9, 16, 25, 36]
query I
SELECT list_transform([6, 5, 4, 3, 2, 1], lambda x, i: x * i);
----
[6, 10, 12, 12, 10, 6]
query I
SELECT list_transform([1, NULL, 3, 4, 5, 6], lambda x, i: x + i);
----
[2, NULL, 6, 8, 10, 12]
query I
SELECT list_transform(NULL, lambda x, i: x + i);
----
NULL
query I
SELECT list_transform(['1', '2', '3', '4'], lambda x, i: (x || ' + ' || CAST(i AS string)));
----
[1 + 1, 2 + 2, 3 + 3, 4 + 4]
query I
SELECT list_transform([1,2,3,4,5], lambda x, i: (x * 10 / i));
----
[10.0, 10.0, 10.0, 10.0, 10.0]
# tests with column references
statement ok
CREATE TABLE tbl(a int[]);
statement ok
INSERT INTO tbl VALUES ([5, 4, 3]), ([1, 2, 3]), (NULL), ([NULL, 101, 12]);
query I
SELECT list_transform(a, lambda x, i: x + i) FROM tbl;
----
[6, 6, 6]
[2, 4, 6]
NULL
[NULL, 103, 15]
query I
SELECT list_transform(a, lambda x, i: x + i + list_any_value(a)) FROM tbl;
----
[11, 11, 11]
[3, 5, 7]
NULL
[NULL, 204, 116]
statement ok
DROP TABLE tbl;
statement ok
CREATE TABLE tbl(a int[], b int, c int);
statement ok
INSERT INTO tbl VALUES ([5,4,3], 5, 10), ([1,2,3], 7, 14), (NULL, 9, 18), ([10,NULL,12], 11, 22);
query I
SELECT list_transform(a, lambda x, i: (c / b ) * (x + i)) FROM tbl;
----
[12.0, 12.0, 12.0]
[4.0, 8.0, 12.0]
NULL
[22.0, NULL, 30.0]
# test very large lists
query I transform list
SELECT range(1, 20000, 2);
----
query I transform list
SELECT list_transform(range(10000), lambda x, i: x + i);
----
query I
SELECT list_transform([1, 2, 3], lambda x, x_i: list_transform([4, 5, 6], lambda y: x + y + x_i));
----
[[6, 7, 8], [8, 9, 10], [10, 11, 12]]
query I
SELECT list_transform([1, 2, 3], lambda x, x_i: list_transform([4, 5, 6], lambda y, y_i: x + y + x_i + y_i));
----
[[7, 9, 11], [9, 11, 13], [11, 13, 15]]
query I
SELECT
list_transform([1, 2, 3], lambda x, i:
list_transform([4, 5, 6], lambda y:
list_transform([7, 8, 9], lambda z:
x + y + z + i)));
----
[[[13, 14, 15], [14, 15, 16], [15, 16, 17]], [[15, 16, 17], [16, 17, 18], [17, 18, 19]], [[17, 18, 19], [18, 19, 20], [19, 20, 21]]]
query I
SELECT
list_transform([1, 2, 3], lambda x:
list_transform([4, 5, 6], lambda y, i:
list_transform([7, 8, 9], lambda z:
x + y + z + i)));
----
[[[13, 14, 15], [15, 16, 17], [17, 18, 19]], [[14, 15, 16], [16, 17, 18], [18, 19, 20]], [[15, 16, 17], [17, 18, 19], [19, 20, 21]]]

View File

@@ -0,0 +1,51 @@
# name: test/sql/function/list/lambdas/vector_types.test
# description: Test list_filter and list_reduce function with 'test_vector_types'
# group: [lambdas]
require vector_size 2048
statement ok
SET lambda_syntax='DISABLE_SINGLE_ARROW'
query I
SELECT [x for x in c if x IS NOT NULL] FROM test_vector_types(NULL::INT[]) t(c);
----
[-2147483648, 2147483647]
[]
[]
[-2147483648, 2147483647]
[-2147483648, 2147483647]
[-2147483648, 2147483647]
[]
[]
[3, 5]
[]
[7]
query I
SELECT [x for x in c if x IS NULL] FROM test_vector_types(NULL::INT[]) t(c);
----
[]
[]
[NULL]
[]
[]
[]
[]
[NULL]
[]
[]
[]
query I
SELECT list_reduce(c, lambda x, y: x + y) FROM test_vector_types(NULL::INT[]) t(c) WHERE len(c) > 0;
----
-1
NULL
-1
-1
-1
NULL
8
7

View File

@@ -0,0 +1,277 @@
# name: test/sql/function/list/list_concat.test
# description: Test list_concat function
# group: [list]
# basic functionality
query T
SELECT list_concat([1, 2], [3, 4])
----
[1, 2, 3, 4]
query T
SELECT array_cat([1, 2], [3, 4])
----
[1, 2, 3, 4]
query T
SELECT list_concat(NULL, [3, 4])
----
[3, 4]
query T
SELECT list_concat([1, 2], NULL)
----
[1, 2]
query T
SELECT list_concat([], [])
----
[]
query T
SELECT list_concat([], [3, 4])
----
[3, 4]
query T
SELECT list_concat([1, 2], [])
----
[1, 2]
query T
SELECT list_concat([1, 2], [3, 4], [5, 6])
----
[1, 2, 3, 4, 5, 6]
query T
SELECT list_concat([1, 2], [3, 4], [])
----
[1, 2, 3, 4]
query T
SELECT list_concat([1, 2], [], [5, 6])
----
[1, 2, 5, 6]
query T
SELECT list_concat([], [3, 4], [5, 6])
----
[3, 4, 5, 6]
query T
SELECT list_concat([], [], [5, 6])
----
[5, 6]
query T
SELECT list_concat([1, 2], [3, 4], [5, 6], [7, 8])
----
[1, 2, 3, 4, 5, 6, 7, 8]
statement error
SELECT list_concat([1, 2], 3)
----
# operators
query T
SELECT [1, 2] || [3, 4]
----
[1, 2, 3, 4]
query T
SELECT [1, 2] + [3, 4]
----
[1, 2, 3, 4]
# type casting
foreach type_a <integral>
foreach type_b <integral>
query T
SELECT list_concat([1, 2]::${type_a}[], [3, 4]::${type_b}[])::INTEGER[]
----
[1, 2, 3, 4]
endloop
endloop
query T
SELECT list_concat([1.000000, 2.000000]::float[], [3.000000, 4.000000]::double[])
----
[1.0, 2.0, 3.0, 4.0]
query T
SELECT list_concat([1.000000, 2.000000]::double[], [3.000000, 4.000000]::float[])
----
[1.0, 2.0, 3.0, 4.0]
# nulls
query T
SELECT list_concat([NULL], [NULL])
----
[NULL, NULL]
query T
SELECT list_concat([1, 2], [NULL])
----
[1, 2, NULL]
query T
SELECT list_concat([NULL], [3, 4])
----
[NULL, 3, 4]
query T
SELECT list_concat([1, 2], [3, 4], [NULL])
----
[1, 2, 3, 4, NULL]
query T
SELECT list_concat([1, 2], [3, 4], NULL)
----
[1, 2, 3, 4]
query T
SELECT list_concat(NULL, [3, 4], [5, 6])
----
[3, 4, 5, 6]
# nested types
query T
SELECT list_concat([[1, 2]], [[3, 4]])
----
[[1, 2], [3, 4]]
query T
SELECT list_concat([[1, 2]], [[3, 4]], [[5, 6]])
----
[[1, 2], [3, 4], [5, 6]]
query T
SELECT list_concat([{a: 1}, {a: 2}], [{a: 3}, {a: 4}])
----
[{'a': 1}, {'a': 2}, {'a': 3}, {'a': 4}]
query T
SELECT list_concat([{a: 1}, {a: 2}], [{a: 3}, {a: 4}], [{a: 5}, {a: 6}])
----
[{'a': 1}, {'a': 2}, {'a': 3}, {'a': 4}, {'a': 5}, {'a': 6}]
query T
SELECT list_concat([[[1], [2]], [[3], [4]]], [[[5], [6]], [[7], [8]]])
----
[[[1], [2]], [[3], [4]], [[5], [6]], [[7], [8]]]
query T
SELECT list_concat([[[1], [2]], [[3], [4]]], [[[5], [6]], [[7], [8]]], [[[9], [10]], [[11], [12]]])
----
[[[1], [2]], [[3], [4]], [[5], [6]], [[7], [8]], [[9], [10]], [[11], [12]]]
statement ok
CREATE TABLE test AS SELECT range % 4 i, range j, range k FROM range(16)
statement ok
CREATE TABLE lists AS SELECT i, list(j) j, list(k) k FROM test GROUP BY i
query II rowsort
SELECT i, list_concat(j, k) FROM lists
----
0 [0, 4, 8, 12, 0, 4, 8, 12]
1 [1, 5, 9, 13, 1, 5, 9, 13]
2 [2, 6, 10, 14, 2, 6, 10, 14]
3 [3, 7, 11, 15, 3, 7, 11, 15]
query II rowsort
SELECT i, list_concat(j, k, j, k, j, k) FROM lists
----
0 [0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12, 0, 4, 8, 12]
1 [1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13, 1, 5, 9, 13]
2 [2, 6, 10, 14, 2, 6, 10, 14, 2, 6, 10, 14, 2, 6, 10, 14, 2, 6, 10, 14, 2, 6, 10, 14]
3 [3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15]
statement error
SELECT i, list_concat(j, cast(k AS VARCHAR)) FROM lists
----
# list_append(l, e) is an alias for list_concat(l, list_value(e))
query T
SELECT list_append([1, 2], 3)
----
[1, 2, 3]
query T
SELECT list_append([1, 2], NULL)
----
[1, 2, NULL]
query T
SELECT list_append(NULL, 3)
----
[3]
query II rowsort
SELECT i, list_append(list_concat(j, k), i) FROM lists ORDER BY i;
----
0 [0, 4, 8, 12, 0, 4, 8, 12, 0]
1 [1, 5, 9, 13, 1, 5, 9, 13, 1]
2 [2, 6, 10, 14, 2, 6, 10, 14, 2]
3 [3, 7, 11, 15, 3, 7, 11, 15, 3]
# prepend macro
query T
SELECT list_prepend(1, [2, 3])
----
[1, 2, 3]
query T
SELECT array_prepend(1, [2, 3])
----
[1, 2, 3]
# push back
query T
SELECT array_push_back([1, 2], 3);
----
[1, 2, 3]
query T
SELECT array_push_back(NULL, 3);
----
[3]
# push front
query T
SELECT array_push_front([2, 3], 1);
----
[1, 2, 3]
query T
SELECT array_push_front(NULL, 1);
----
[1]
# concat operator
query T
SELECT [1, 2] || NULL
----
NULL
query T
SELECT [1, 2] || b FROM (VALUES (NULL::INT[])) t(b)
----
NULL
query T
SELECT a || b FROM (VALUES ([1,2,3], NULL::INT[])) t(a,b)
----
NULL
# type mismatch
statement error
SELECT concat([42], [84], 'str')
----
an explicit cast is required

View File

@@ -0,0 +1,459 @@
# name: test/sql/function/list/list_contains.test
# description: Test list_contains function
# group: [list]
statement ok
PRAGMA enable_verification
statement ok
create table TEST2 (i int[], j int);
statement ok
insert into TEST2 values ([2,1,3], 2), ([2,3,4], 5), ([1], NULL);
query T
select list_contains(i, j) from TEST2
----
1
0
NULL
statement ok
create table TEST (i int[]);
statement ok
insert into TEST values ([2,1,3]), ([2,3,4]), ([1]);
query TT
SELECT i, list_contains(i,1) from TEST;
----
[2, 1, 3] 1
[2, 3, 4] 0
[1] 1
query TT
SELECT i, list_contains(i,4.0) from TEST;
----
[2, 1, 3] 0
[2, 3, 4] 1
[1] 0
statement ok
DROP table TEST;
statement ok
create table STR_TEST (i string[]);
statement ok
insert into STR_TEST values (['a','b','c']), (['d','a','e']), (['b']), (['aaaaaaaaaaaaaaaaaaaaaaaa']);
query TT
SELECT i, list_contains(i,'a') from STR_TEST;
----
[a, b, c] 1
[d, a, e] 1
[b] 0
[aaaaaaaaaaaaaaaaaaaaaaaa] 0
query TT
SELECT i, list_contains(i,'aaaaaaaaaaaaaaaaaaaaaaaa') from STR_TEST;
----
[a, b, c] 0
[d, a, e] 0
[b] 0
[aaaaaaaaaaaaaaaaaaaaaaaa] 1
query TT
SELECT i, list_contains(i, '0') from STR_TEST;
----
[a, b, c] 0
[d, a, e] 0
[b] 0
[aaaaaaaaaaaaaaaaaaaaaaaa] 0
query TT
SELECT i, list_contains(i,NULL) from STR_TEST;
----
[a, b, c] NULL
[d, a, e] NULL
[b] NULL
[aaaaaaaaaaaaaaaaaaaaaaaa] NULL
statement ok
DROP table STR_TEST;
# basic functionality
query T
SELECT list_contains([7,2,5], 7)
----
1
# Empty list
query T
SELECT list_contains([], 7)
----
0
# Mixed data types
query T
SELECT list_contains([1,2,3],1.0)
----
1
query T
SELECT list_contains([1.0,2.0,3.0,4.0],1)
----
1
query T
SELECT list_contains([1,2,3],4.0)
----
0
query T
SELECT list_contains([1.0,2.0,3.0],4)
----
0
statement error
SELECT list_contains([1.0,2.0,3.0], 'a')
----
Conversion Error: Could not convert string "a" to DECIMAL(2,1)
# Not a list as input
statement error
SELECT list_contains('a', 'a')
----
query T
SELECT list_contains(NULL,NULL)
----
NULL
query T
SELECT list_contains([7], 5)
----
0
query T
SELECT list_contains([1,2,3,4],4)
----
1
query T
SELECT list_contains([1,2,3,4],5)
----
0
query T
SELECT list_contains([1.0,2.0,3.0,4.0],5.0)
----
0
query T
SELECT list_contains([1.0,2.0,3.0,4.0],4.0)
----
1
query T
SELECT list_contains([true, false],true)
----
1
query T
SELECT list_contains([true, true],false)
----
0
query T
SELECT list_contains(['test', 'notest'],'notest')
----
1
query T
SELECT list_contains(['test', 'notest'],'a')
----
0
# Null types
query T
SELECT list_contains(NULL,1)
----
NULL
# Null types
query T
SELECT list_contains([1],NULL)
----
NULL
query T
SELECT list_contains([NULL],NULL)
----
NULL
query T
SELECT list_contains([NULL, 1],NULL)
----
NULL
query T
SELECT list_contains([NULL, 1],1)
----
1
query T
SELECT list_contains([NULL, 0],1)
----
0
query T
SELECT list_contains([],NULL)
----
NULL
query T
SELECT list_contains([NULL,7], 7)
----
1
statement error
SELECT list_contains([[1,2,3],[1],[1,2,3])
----
Parser Error: syntax error at or near ")"
statement error
SELECT list_contains([[1,2,3],[1],[1,2,3]])
----
statement error
SELECT list_contains(1)
----
statement error
SELECT list_contains(1,1)
----
statement ok
PRAGMA debug_force_external=true
loop i 0 2
foreach type <integral>
# list tests
statement ok
CREATE TABLE test0 (i ${type}[])
statement ok
INSERT INTO test0 VALUES ([2]), ([1]), ([1, 2]), ([]), ([2, 2]), ([NULL]), ([2, 3])
query T
SELECT list_contains(i,1) from test0
----
0
1
1
0
0
0
0
statement ok
DROP TABLE test0
statement ok
PRAGMA debug_force_external=false
endloop
endloop
query T
SELECT list_contains([[1,2,3],[1]],[1])
----
1
query T
SELECT list_contains([[1,2,3],[1]],[2])
----
0
query T
SELECT list_contains([[1,2,3],[1]],[1,2,3])
----
1
query T
SELECT list_contains([[1,3],[1]],[1,2,3])
----
0
query T
SELECT list_contains([[1,3],[1], [1,2,3]],[1,2,3])
----
1
query T
SELECT list_contains([[NULL],[1], [1,2,3]],NULL)
----
NULL
query T
SELECT list_contains([[NULL],[1], [1,2,3]],[NULL])
----
1
query T
SELECT list_contains([[1,NULL],[1], [1,2,3]],[1,NULL])
----
1
query T
SELECT list_contains([[1,NULL],[1], [1,2,3]],[0,NULL])
----
0
# nested types
query T
SELECT list_contains([{a: 1}, {a: 2}], {a: 2})
----
1
query T
SELECT list_contains([{a: 1}, {a: 2}], {a: 3})
----
0
query T
SELECT list_contains([{a: 1, b: 3}, {a: 2, b: 2}], {a: 2, b: 2})
----
1
query T
SELECT list_contains([{a: 1, b: 3}, {a: 2, b: 2}], {a: 1, b: 2})
----
0
query T
SELECT list_contains([MAP([1], [2])], MAP([1], [2]))
----
1
query T
SELECT list_contains([MAP([1], [2])], MAP([1], [3]))
----
0
query T
SELECT list_contains([MAP([1], [2]), NULL], NULL)
----
NULL
query T
SELECT list_contains([MAP([1], [2]), NULL], MAP([1], [2]))
----
1
query T
SELECT list_contains([[1,2,3],NULL],NULL)
----
NULL
statement ok
PRAGMA debug_force_external=true
loop i 0 2
foreach type float double
# list tests
statement ok
CREATE TABLE test0 (i ${type}[])
statement ok
INSERT INTO test0 VALUES ([2.0]), ([1.0]), ([1.0, 2.0]), ([]), ([2.0, 2.0]), ([NULL]), ([2.0, 3.0])
query T
SELECT list_contains(i,1.0) from test0
----
0
1
1
0
0
0
0
statement ok
DROP TABLE test0
statement ok
PRAGMA debug_force_external=false
endloop
endloop
# issue 3450 test case
statement ok
CREATE TABLE functions (function_name varchar, function_type varchar, parameter_types varchar[]);
statement ok
INSERT INTO functions VALUES ('last_day', 'scalar', ['TIMESTAMP']), ('dayname', 'else', ['TIMESTAMP']),
('date_part', 'scalar', ['DATE', 'VARCHAR']), ('scalar_part', 'scalar', ['VARCHAR', 'TIMESTAMP']);
query I
SELECT function_name FROM functions
WHERE function_type = 'scalar' AND list_has(parameter_types, 'TIMESTAMP');
----
last_day
scalar_part
# issue 3457 test case
statement ok
CREATE TABLE test (id int, name text[]);
statement ok
INSERT INTO test VALUES (1, ['U2']), (2, ['Blur','Rock']), (3, ['Oasis','2Pac']);
query II
SELECT id, name FROM test WHERE ARRAY_CONTAINS(name, '2Pac');
----
3 [Oasis, 2Pac]
query II
SELECT id, name FROM test WHERE id IN (2,3) AND ARRAY_CONTAINS(name, '2Pac');
----
3 [Oasis, 2Pac]
query II
WITH cte AS (SELECT id, name FROM test WHERE id IN (2,3))
SELECT id, name FROM cte WHERE ARRAY_CONTAINS(name, '2Pac');
----
3 [Oasis, 2Pac]
query II
SELECT id, name FROM test WHERE id IN (2,3) AND name::text ILIKE '%2Pac%';
----
3 [Oasis, 2Pac]
# Test list_contains with NULLs inside list_filter.
statement ok
CREATE TABLE list_of_list(l1 int[][], l2 int[][]);
statement ok
INSERT INTO list_of_list VALUES ([NULL], [NULL]);
query I
SELECT list_filter(l1, lambda x: list_contains(l2, x)) FROM list_of_list;
----
[]

View File

@@ -0,0 +1,51 @@
# name: test/sql/function/list/list_cosine_similarity.test
# group: [list]
foreach type FLOAT DOUBLE
query I
SELECT list_cosine_similarity([1, 2, 3]::${type}[], [1, 2, 3]::${type}[]);
----
1.0
statement ok
CREATE OR REPLACE TABLE lists (l ${type}[]);
statement ok
INSERT INTO lists VALUES ([1, 2, 3]), ([4, 5, 6]), ([7, 8, 9]), ([-1, -2, -3]), (NULL);
query I
SELECT list_cosine_similarity(l, [1, 2, 3]) FROM lists;
----
0.99999994
0.9746318
0.95941186
-0.99999994
NULL
statement error
SELECT list_cosine_similarity([1, NULL, 3]::${type}[], [1, 2, 3]::${type}[]);
----
left argument can not contain NULL values
statement error
SELECT list_cosine_similarity([1, 2, 3]::${type}[], [1, NULL, 3]::${type}[]);
----
right argument can not contain NULL values
statement error
SELECT list_cosine_similarity([1, 2, 3]::${type}[], [1, 2, 3, 4]::${type}[]);
----
list dimensions must be equal, got left length '3' and right length '4'
query I
SELECT list_cosine_similarity([], []);
----
NULL
query I
SELECT list_cosine_distance([1, 2, 3]::${type}[], [1, 2, 3]::${type}[]) = 1 - list_cosine_similarity([1, 2, 3]::${type}[], [1, 2, 3]::${type}[]);
----
true
endloop

View File

@@ -0,0 +1,47 @@
# name: test/sql/function/list/list_distance.test
# group: [list]
foreach type FLOAT DOUBLE
query I
SELECT list_distance([1, 2, 3]::${type}[], [1, 2, 3]::${type}[]);
----
0.0
statement ok
CREATE OR REPLACE TABLE lists (l ${type}[]);
statement ok
INSERT INTO lists VALUES ([1, 2, 3]), ([1, 2, 4]), ([7, 8, 9]), ([-1, -2, -3]), (NULL);
query I
SELECT list_distance(l, [1, 2, 3]) FROM lists;
----
0.0
1.0
10.392304
7.483315
NULL
statement error
SELECT list_distance([1, NULL, 3]::${type}[], [1, 2, 3]::${type}[]);
----
left argument can not contain NULL values
statement error
SELECT list_distance([1, 2, 3]::${type}[], [1, NULL, 3]::${type}[]);
----
right argument can not contain NULL values
statement error
SELECT list_distance([1, 2, 3]::${type}[], [1, 2, 3, 4]::${type}[]);
----
Invalid Input Error: list_distance: list dimensions must be equal, got left length '3' and right length '4'
query I
SELECT list_distance([], []);
----
0.0
endloop

View File

@@ -0,0 +1,273 @@
# name: test/sql/function/list/list_distinct.test
# description: Test the list_distinct function
# group: [list]
# FIXME: some of these test cases could be improved by using list_sort
# Currently, they use UNNEST(...) ORDER BY, because unordered maps seem to 'sort'
# different on Windows and other systems
statement ok
pragma enable_verification
# test null or empty
query I
SELECT list_distinct(NULL)
----
NULL
query I
SELECT list_distinct([NULL])
----
[]
query I
SELECT list_distinct([])
----
[]
query I
SELECT list_distinct([]) WHERE 1 = 0
----
# test incorrect syntax
statement error
SELECT list_distinct()
----
No function matches
statement error
SELECT list_distinct(*)
----
No function matches
statement error
SELECT list_distinct([1, 2], 2)
----
No function matches
# test incorrect parameter type
statement error
SELECT list_distinct(NULL::boolean)
----
No function matches
# other tests
query I
SELECT UNNEST(list_distinct([1, 1, 2, 2, 2, 3])) AS l ORDER BY l
----
1
2
3
query I
SELECT UNNEST(list_distinct([1, 1, NULL, 2, 2, 2, 3, NULL, NULL])) AS l ORDER BY l
----
1
2
3
query I
SELECT UNNEST(list_distinct(list_distinct([1, 1, -5, 10, 10, 2]))) AS l ORDER BY l
----
-5
1
2
10
statement ok
CREATE TABLE integers (l integer[])
statement ok
INSERT INTO integers VALUES ([1, 1, 1]), ([1, NULL, 1, NULL])
statement ok
INSERT INTO integers VALUES ([NULL]), (NULL), ([])
query I
SELECT list_distinct(l) FROM integers
----
[1]
[1]
[]
NULL
[]
# aliases
query I
SELECT UNNEST(array_distinct([1, 2, 2, NULL])) AS l ORDER BY l
----
1
2
# test all types
# BOOLEAN
query I
SELECT UNNEST(list_distinct([True, True, False, NULL])) AS l ORDER BY l
----
0
1
query I
SELECT list_distinct([NULL::BOOLEAN])
----
[]
# VARCHAR
query I
SELECT UNNEST(list_distinct(['aa', 'aa', 'cd', NULL, '42'])) AS l ORDER BY l
----
42
aa
cd
query I
SELECT list_distinct([NULL::VARCHAR])
----
[]
# INTEGER types
foreach type tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint uhugeint
query I
SELECT list_distinct([1::${type}, NULL, 1::${type}])
----
[1]
query I
SELECT list_distinct([NULL::${type}])
----
[]
endloop
# FLOAT, DOUBLE and DECIMAL types
foreach type float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10)
statement ok
SELECT list_distinct([1::${type}])
query I
SELECT list_distinct([NULL::${type}])
----
[]
endloop
# TEMPORAL types
# date
query I
SELECT list_distinct(['2021-08-20'::DATE])
----
[2021-08-20]
# time
query I
SELECT list_distinct(['14:59:37'::TIME])
----
['14:59:37']
# timestamp
query I
SELECT list_distinct(['2021-08-20'::TIMESTAMP])
----
['2021-08-20 00:00:00']
# timestamp s
query I
SELECT list_distinct(['2021-08-20'::TIMESTAMP_S])
----
['2021-08-20 00:00:00']
# timestamp ms
query I
SELECT list_distinct(['2021-08-20 00:00:00.123'::TIMESTAMP_MS])
----
['2021-08-20 00:00:00.123']
# timestamp ns
query I
SELECT list_distinct(['2021-08-20 00:00:00.123456'::TIMESTAMP_NS])
----
['2021-08-20 00:00:00.123456']
# time with time zone
query I
SELECT list_distinct(['14:59:37'::TIMETZ])
----
['14:59:37+00']
# timestamp with time zone
query I
SELECT list_distinct(['2021-08-20'::TIMESTAMPTZ])
----
['2021-08-20 00:00:00+00']
# interval
query I
SELECT list_distinct([INTERVAL 1 YEAR])
----
[1 year]
foreach type date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz
query I
SELECT list_distinct([NULL::${type}])
----
[]
endloop
# enums
statement ok
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')
statement ok
CREATE TABLE enums (e mood[])
statement ok
INSERT INTO enums VALUES (['happy', 'ok'])
query I
SELECT list_sort(list_distinct(e)) FROM enums
----
[ok, happy]
# test WHERE
statement ok
CREATE TABLE wheretest (name VARCHAR, l INTEGER[]);
statement ok
INSERT INTO wheretest VALUES ('one1', [2, 3, 3, 4, NULL, 2]), ('one2', [NULL, NULL, 2]), ('two1', [1, 2, 3, 10, 15]),
('one3', [2, 3, 4]), ('two2', NULL), ('two3', [10, 11, 12]);
query I
SELECT name FROM wheretest WHERE name ILIKE 'one%' AND list_unique(list_distinct(l)) > 1;
----
one1
one3
query I
SELECT name FROM wheretest WHERE name ILIKE 'two%' AND list_unique(list_distinct(l)) > 3;
----
two1
# bug in #3481
query I
SELECT list_sort(list_distinct(['a', 'b、c', 'a']))
----
[a, bc]
statement ok
CREATE TABLE all_types AS SELECT * FROM test_all_types();
# list distinct is supported for all types
statement ok
SELECT list_distinct([COLUMNS(*)]) FROM all_types;

View File

@@ -0,0 +1,326 @@
# name: test/sql/function/list/list_grade_up.test_slow
# description: Test list_grade_up function
# group: [list]
statement ok
PRAGMA enable_verification;
statement ok
PRAGMA default_order='ASC';
statement ok
PRAGMA default_null_order='NULLS FIRST';
query I
SELECT list_grade_up(NULL::INT[]);
----
NULL
query I
SELECT list_grade_up(l) FROM VALUES ([1,2,3]), (NULL) as v(l);
----
[1, 2, 3]
NULL
query I
SELECT list_grade_up([NULL])
----
[1]
query I
SELECT list_grade_up([])
----
[]
query I
SELECT list_grade_up([]) WHERE 1 = 0
----
statement error
SELECT list_grade_up()
----
statement error
SELECT list_grade_up(*)
----
statement error
SELECT list_grade_up([1, 2], 2)
----
statement error
SELECT list_grade_up([1, 2], 'DESC', 2)
----
statement error
SELECT list_grade_up([1, 2], 2, 2)
----
query I
SELECT list_grade_up([1, 2])
----
[1, 2]
query I
SELECT list_grade_up([1, 3, NULL, 5, NULL, -5])
----
[3, 5, 6, 1, 2, 4]
statement ok
CREATE TABLE integers AS SELECT LIST(i) AS i FROM range(1, 10, 1) t1(i)
statement ok
INSERT INTO integers VALUES ([NULL]), ([]), (NULL::int[])
query I
SELECT list_grade_up(i) FROM integers
----
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1]
[]
NULL
# test custom ordering
query I
SELECT list_grade_up([1, 3, NULL, 2], 'ASC')
----
[3, 1, 4, 2]
query I
SELECT list_grade_up([1, 3, NULL, 2], 'DESC')
----
[3, 2, 4, 1]
query I
SELECT list_grade_up([1, 3, NULL, 2], 'DESC', 'NULLS LAST')
----
[2, 4, 1, 3]
query I
SELECT list_grade_up([1, 3, NULL, 2], 'deSc', 'nuLls LAST')
----
[2, 4, 1, 3]
query I
SELECT list_grade_up([1, 3, NULL, 2], 'DESC', 'NULLS FIRST')
----
[3, 2, 4, 1]
query I
SELECT list_grade_up([1, 3, NULL, 2], 'ASC', 'NULLS FIRST')
----
[3, 1, 4, 2]
query I
SELECT list_grade_up([1, 3, NULL, 2], 'ASC', 'NULLS LAST')
----
[1, 4, 2, 3]
# test all types
# BOOLEAN
query I
SELECT list_grade_up([True, False, NULL, True, True, NULL])
----
[3, 6, 2, 1, 4, 5]
query I
SELECT list_grade_up([NULL::BOOLEAN])
----
[1]
# VARCHAR
query I
SELECT list_grade_up(['aa', 'a', 'cd', NULL, '42'])
----
[4, 5, 2, 1, 3]
query I
SELECT list_grade_up([NULL::VARCHAR])
----
[1]
# INTEGER types
foreach type tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint
query I
SELECT list_grade_up([1::${type}, NULL, 2::${type}])
----
[2, 1, 3]
query I
SELECT list_grade_up([NULL::${type}])
----
[1]
endloop
# FLOAT, DOUBLE and DECIMAL types
foreach type float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10)
statement ok
SELECT list_grade_up([1::${type}])
query I
SELECT list_grade_up([NULL::${type}])
----
[1]
endloop
# TEMPORAL types
# date
query I
SELECT list_grade_up(['2021-08-20'::DATE])
----
[1]
# time
query I
SELECT list_grade_up(['14:59:37'::TIME])
----
[1]
# timestamp
query I
SELECT list_grade_up(['2021-08-20'::TIMESTAMP])
----
[1]
# timestamp s
query I
SELECT list_grade_up(['2021-08-20'::TIMESTAMP_S])
----
[1]
# timestamp ms
query I
SELECT list_grade_up(['2021-08-20 00:00:00.123'::TIMESTAMP_MS])
----
[1]
# timestamp ns
query I
SELECT list_grade_up(['2021-08-20 00:00:00.123456'::TIMESTAMP_NS])
----
[1]
# time with time zone
query I
SELECT list_grade_up(['14:59:37'::TIMETZ])
----
[1]
# timestamp with time zone
query I
SELECT list_grade_up(['2021-08-20'::TIMESTAMPTZ])
----
[1]
# interval
query I
SELECT list_grade_up([INTERVAL 1 YEAR])
----
[1]
foreach type date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz interval
query I
SELECT list_grade_up([NULL::${type}])
----
[1]
endloop
# BLOB
query I
SELECT list_grade_up(['{a: 1}'::BLOB, '{a: 3}'::BLOB])
----
[1, 2]
query I
SELECT list_grade_up([NULL::BLOB])
----
[1]
# ENUMS
statement ok
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')
statement ok
CREATE TABLE enums (e mood[])
statement ok
INSERT INTO enums VALUES (['happy', 'sad'])
query I
SELECT list_grade_up(e) FROM enums
----
[2, 1]
# NESTED types
query I
SELECT list_grade_up([[1], [1, 2], NULL, [NULL], [], [1, 2, 3]])
----
[3, 5, 1, 2, 6, 4]
query I
SELECT list_grade_up([{'a': 1}, {'a': 5}, {'a': 3}])
----
[1, 3, 2]
statement ok
SELECT list_grade_up(range(3000));
# bug fixes test for #4591
query II
select k, list_grade_up(k,'DESC') from (values ([1,2,3,4])) as t(k);
----
[1, 2, 3, 4] [4, 3, 2, 1]
query IIII
select k, v, map(k,v), map(k,v)[(list_grade_up(k,'DESC'))[1]] from (values ([1,2,3,4],[2,3,4,5])) as t(k,v);
----
[1, 2, 3, 4] [2, 3, 4, 5] {1=2, 2=3, 3=4, 4=5} 5
# bug fixes test for #5694
require parquet
statement ok
CREATE TABLE stage AS SELECT * FROM 'data/parquet-testing/list_sort_segfault.parquet';
statement ok
CREATE TABLE health (a VARCHAR[]);
statement ok
INSERT INTO health SELECT list_grade_up(string_to_array(s, ',')) AS a FROM stage;
# Make sure it works for arrays too
query I
SELECT array_grade_up(array_value(4,5,3), 'ASC')
----
[3, 1, 2]
query I
SELECT array_grade_up(array_value(4,5,3), 'DESC');
----
[2, 1, 3]
query I
SELECT array_grade_up(NULL::INT[3]);
----
NULL

View File

@@ -0,0 +1,24 @@
# name: test/sql/function/list/list_has_any_and_all.test_slow
# description: Test list_has_any and list_has_all functions on Large Lists
# group: [list]
statement ok
create table large_lists(l1 int[], l2 int[]);
statement ok
insert into large_lists values (range(1, 3000), range(2000, 3000));
statement ok
insert into large_lists values (range(3000), range(3000));
query I
select list_has_any(l1, l2) from large_lists;
----
1
1
query I
select list_has_all(l1, l2) from large_lists;
----
1
1

View File

@@ -0,0 +1,279 @@
# name: test/sql/function/list/list_has_any_and_has_all.test
# description: Test list_has_any and list_has_all functions
# group: [list]
query I
select list_has_any([1,2,3], [2,3,4]);
----
true
query I
select list_has_all([1,2,3], [2,3,4]);
----
false
# Test NULLs
statement ok
CREATE TABLE list_data(l1 int[], l2 int[]);
statement ok
INSERT INTO list_data VALUES (NULL, NULL);
statement ok
INSERT INTO list_data VALUES (NULL, [1,2,3]);
statement ok
INSERT INTO list_data VALUES ([1,2,3], NULL);
statement ok
INSERT INTO list_data VALUES ([1,2,3], [2,3,NULL]);
statement ok
INSERT INTO list_data VALUES ([1,2,NULL], [2,3,NULL]);
statement ok
INSERT INTO list_data VALUES ([1,2,NULL], [NULL,3,4]);
statement ok
INSERT INTO list_data VALUES ([1,2,3], [1,2,3]);
statement ok
INSERT INTO list_data VALUES ([1,2,3], [1,2,NULL]);
query I
select list_has_any(l1, l2) from list_data;
----
NULL
NULL
NULL
1
1
0
1
1
query I
select list_has_all(l1, l2) from list_data;
----
NULL
NULL
NULL
1
0
0
1
1
# Test Lists in Lists
statement ok
DROP TABLE list_data;
statement ok
create table list_of_list(l1 int[][], l2 int[][]);
statement ok
insert into list_of_list values (NULL, NULL);
statement ok
insert into list_of_list values ([[1 , 2, 3], NULL, [3, 2, 1]], [[2, 3, 4], NULL, [1, 2, 3]]);
statement ok
insert into list_of_list values ([[1 , 2, 3], NULL, [3, 2, 1]], [[8, 8, 8], NULL, [8, 8, 8]]);
statement ok
insert into list_of_list values ([[1 , 2, 3], NULL, [8, 8, 8]], [[8, 8, 8], NULL, [1, 2, 3]]);
query I
select list_has_any(l1, l2) from list_of_list;
----
NULL
1
0
1
query I
select list_has_all(l1, l2) from list_of_list;
----
NULL
0
0
1
statement ok
drop table list_of_list;
# test string lists
statement ok
create table list_of_strings(l1 string[], l2 string[]);
statement ok
insert into list_of_strings values (NULL, NULL);
statement ok
insert into list_of_strings values ([NULL, 'a', 'b', 'c'], [NULL, 'b', 'c', 'd']);
statement ok
insert into list_of_strings values (['a', 'b', 'c'], ['a', 'b', 'c']);
statement ok
insert into list_of_strings values (['here is a very long long string that is def more than 12 bytes', 'and a shorty'], ['here is a very long long string that is def more than 12 bytes', 'here is a very long long string that is def more than 12 bytes', 'c', 'd']);
statement ok
insert into list_of_strings values (['here is a very long long string that is def more than 12 bytes', 'and a shorty'], ['here is a very long string that is def more than 12 bytes', 'here is a very long string that is def more than 12 bytes', 'c', 'd']);
statement ok
insert into list_of_strings values (['here is a very long long string that is def more than 12 bytes', 'and a shorty'], ['here is a very long long string that is def more than 12 bytes', 'and a shorty']);
query I
select list_has_any(l1, l2) from list_of_strings;
----
NULL
1
1
1
0
1
query I
select list_has_all(l1, l2) from list_of_strings;
----
NULL
0
1
0
0
1
# test error cases
statement error
select list_has_any(l1) from list_of_strings;
----
statement error
select list_has_any(l1, l2, l1) from list_of_strings;
----
statement error
select list_has_all(l1) from list_of_strings;
----
statement error
select list_has_all(l1, l2, l1) from list_of_strings;
----
statement error
select list_has_all([1, 2], 1);
----
statement error
select list_has_any([[1,2], [2,4]], ['abc', 'def']);
----
Binder Error: Cannot deduce template type
# Test Function in Function
foreach f list_has_all list_has_any array_has_all array_has_any
statement ok
create table tbl(l1 int[], l2 int[]);
statement ok
insert into tbl values ([1,2,3], [2,3,4]);
query I
select ${f}(list_intersect(l1, l2), list_intersect(l2, l1)) from tbl;
----
1
statement ok
drop table tbl;
endloop
# Test Lists of Different Lengths
statement ok
create table tbl(l1 int[], l2 int[]);
statement ok
insert into tbl values ([1,2,3,4,5,6], [2,3,4]);
statement ok
insert into tbl values ([1,2,3], [1,2,3,4,7,8,9]);
query I
select list_has_any(l1, l2) from tbl;
----
1
1
query I
select list_has_all(l1, l2) from tbl;
----
1
0
query I
select list_has_all(l2, l1) from tbl;
----
0
1
# Operators
query I
select l1 && l2 from tbl;
----
1
1
statement error
select 'hello' && l1 from tbl;
----
query I
select NULL && [NULL];
----
NULL
query I
select l1 && NULL from tbl;
----
NULL
NULL
query I
select l1 @> l2 from tbl;
----
1
0
query I
select l1 <@ l2 from tbl;
----
0
1
statement error
select 'hello' @> l1 from tbl;
----
statement error
select 'hello' <@ l1 from tbl;
----
query I
select l1 @> NULL from tbl;
----
NULL
NULL
query I
select l1 <@ NULL from tbl;
----
NULL
NULL

View File

@@ -0,0 +1,52 @@
# name: test/sql/function/list/list_inner_product.test
# group: [list]
query I
SELECT list_inner_product([], []);
----
0.0
foreach type FLOAT DOUBLE
query I
SELECT list_inner_product([1, 1, 1]::${type}[], [1, 1, 1]::${type}[]);
----
3.0
statement ok
CREATE OR REPLACE TABLE lists (l ${type}[]);
statement ok
INSERT INTO lists VALUES ([1, 2, 3]), ([1, 2, 4]), ([7, 8, 9]), ([-1, -2, -3]), (NULL);
query I
SELECT list_inner_product(l, [1, 2, 3]) FROM lists;
----
14.0
17.0
50.0
-14.0
NULL
statement error
SELECT list_inner_product([1, NULL, 3]::${type}[], [1, 2, 3]::${type}[]);
----
left argument can not contain NULL values
statement error
SELECT list_inner_product([1, 2, 3]::${type}[], [1, NULL, 3]::${type}[]);
----
right argument can not contain NULL values
statement error
SELECT list_inner_product([1, 2, 3]::${type}[], [1, 2, 3, 4]::${type}[]);
----
Invalid Input Error: list_inner_product: list dimensions must be equal, got left length '3' and right length '4'
query I
SELECT list_negative_inner_product([1,2,3]::${type}[], [1,2,3]::${type}[]) = -list_inner_product([1,2,3]::${type}[], [1,2,3]::${type}[]);
----
true
endloop

View File

@@ -0,0 +1,141 @@
# name: test/sql/function/list/list_intersect.test
# description: Test list_intersect
# group: [list]
foreach f list_intersect array_intersect
query I
select list_sort(${f}([1,2,3], [2,3,4]));
----
[2, 3]
statement ok
CREATE TABLE list_data(l1 int[], l2 int[]);
statement ok
INSERT INTO list_data VALUES (NULL, NULL);
statement ok
INSERT INTO list_data VALUES (NULL, [1,2,3]);
statement ok
INSERT INTO list_data VALUES ([1,2,3], NULL);
statement ok
INSERT INTO list_data VALUES ([1,2,3], [2,3,NULL]);
statement ok
INSERT INTO list_data VALUES ([1,2,NULL], [2,3,NULL]);
query I
select list_sort(${f}(l1, l2)) from list_data;
----
NULL
NULL
[]
[2, 3]
[2]
statement ok
DROP TABLE list_data;
statement ok
create table list_of_list(l1 int[][], l2 int[][]);
statement ok
insert into list_of_list values (NULL, NULL);
statement ok
insert into list_of_list values ([[1 , 2, 3], NULL, [3, 2, 1]], [[ 2, 3, 4], NULL, [1, 2, 3]]);
query I
select ${f}(l1, l2) from list_of_list;
----
NULL
[[1, 2, 3]]
statement ok
drop table list_of_list;
statement ok
create table list_of_strings(l1 string[], l2 string[]);
statement ok
insert into list_of_strings values (NULL, NULL);
statement ok
insert into list_of_strings values ([NULL, 'a', 'b', 'c'], [NULL, 'b', 'c', 'd']);
statement ok
insert into list_of_strings values (['here is a very long long string that is def more than 12 bytes', 'and a shorty'], ['here is a very long long string that is def more than 12 bytes', 'here is a very long long string that is def more than 12 bytes', 'c', 'd']);
query I
select list_sort(${f}(l1, l2)) from list_of_strings;
----
NULL
[b, c]
[here is a very long long string that is def more than 12 bytes]
statement ok
drop table list_of_strings;
endloop
# test error cases
statement error
select list_intersect(l1) from list_of_strings;
----
statement error
select list_intersect(l1, l2, l1) from list_of_strings;
----
statement error
select list_intersect([[1,2], [2,4]], ['abc', 'def']);
----
# Test Large Lists
statement ok
create table large_lists(l1 int[], l2 int[]);
statement ok
insert into large_lists values (range(1, 3000), range(2000, 3000));
statement ok
insert into large_lists values (range(3000), range(3000));
statement ok
select list_intersect(l1, l2) from large_lists;
query I
select list_intersect(list_filter([1, 2, 3, 4], lambda x: x > 2), list_filter([4, 5, 6, 7], lambda x: x > 2));
----
[4]
statement ok
prepare q1 as select list_intersect(?, ?);
query I
execute q1(['abc', 'def'], ['def', 'ghi']);
----
[def]
statement ok
CREATE TABLE all_types AS SELECT * FROM test_all_types();
foreach colname bool tinyint smallint int bigint utinyint usmallint uint ubigint date time timestamp timestamp_s timestamp_ms timestamp_ns time_tz timestamp_tz float double dec_4_1 dec_9_4 uuid interval varchar small_enum medium_enum large_enum
statement ok
select list_intersect(["${colname}"], ["${colname}"]) FROM all_types;
endloop
# issue 9942
query I
SELECT list_sort(list_intersect([1, 4, 3, 5, 5, 2, 2], [5, 5, 5, 1, 1, 2, 4]));
----
[1, 2, 4, 5]

View File

@@ -0,0 +1,494 @@
# name: test/sql/function/list/list_position.test
# description: Test list_position function
# group: [list]
statement ok
create table TEST2 (i int[], j int);
statement ok
insert into TEST2 values ([2,1,3], 2), ([2,3,4], 5), ([1], NULL);
query T
select list_position(i, j) from TEST2
----
1
NULL
NULL
statement ok
create table TEST (i int[]);
statement ok
insert into TEST values ([2,1,3]), ([2,3,4]), ([1]);
query TT
SELECT i, list_position(i,1) from TEST;
----
[2, 1, 3] 2
[2, 3, 4] NULL
[1] 1
query TT
SELECT i, list_position(i,4.0) from TEST;
----
[2, 1, 3] NULL
[2, 3, 4] 3
[1] NULL
statement ok
DROP table TEST;
# test for list_position with nulls and a non-const element
statement ok
create table TEST(i int[], j int);
statement ok
insert into TEST values ([2,1,3], 2), ([2,3,4], 5), ([1], NULL), ([1, NULL, 2], NULL);
query TTT
SELECT i, j, list_position(i,j) from TEST;
----
[2, 1, 3] 2 1
[2, 3, 4] 5 NULL
[1] NULL NULL
[1, NULL, 2] NULL 2
statement ok
DROP table TEST;
statement ok
CREATE TABLE NULL_TABLE (n int[], i int);
statement ok
INSERT INTO NULL_TABLE VALUES (NULL, 1), (NULL, 2), (NULL, 3);
query I
SELECT list_contains(n, i) FROM NULL_TABLE;
----
NULL
NULL
NULL
statement ok
DROP TABLE NULL_TABLE;
statement ok
create table STR_TEST (i string[]);
statement ok
insert into STR_TEST values (['a','b','c']), (['d','a','e']), (['b']), (['aaaaaaaaaaaaaaaaaaaaaaaa']);
query TT
SELECT i, list_position(i,'a') from STR_TEST;
----
[a, b, c] 1
[d, a, e] 2
[b] NULL
[aaaaaaaaaaaaaaaaaaaaaaaa] NULL
query TT
SELECT i, list_position(i,'aaaaaaaaaaaaaaaaaaaaaaaa') from STR_TEST;
----
[a, b, c] NULL
[d, a, e] NULL
[b] NULL
[aaaaaaaaaaaaaaaaaaaaaaaa] 1
query TT
SELECT i, list_position(i, '0') from STR_TEST;
----
[a, b, c] NULL
[d, a, e] NULL
[b] NULL
[aaaaaaaaaaaaaaaaaaaaaaaa] NULL
query TT
SELECT i, list_position(i,NULL) from STR_TEST;
----
[a, b, c] NULL
[d, a, e] NULL
[b] NULL
[aaaaaaaaaaaaaaaaaaaaaaaa] NULL
statement ok
DROP table STR_TEST;
# test for list_position with nulls and a non-const element in strings
statement ok
create table STR_TEST (i string[], j string);
statement ok
insert into STR_TEST values (['a','b','c'], 'a'), (['d','a','e'], 'b'), (['b'], NULL), (['aa', NULL, 'bb'], NULL);
query TTT
SELECT i, j, list_position(i,j) from STR_TEST;
----
[a, b, c] a 1
[d, a, e] b NULL
[b] NULL NULL
[aa, NULL, bb] NULL 2
statement ok
DROP table STR_TEST;
# basic functionality
query T
SELECT list_position([7,2,5], 7)
----
1
# Empty list
query T
SELECT list_position([], 7)
----
NULL
# Mixed data types
query T
SELECT list_position([1,2,3],1.0)
----
1
query T
SELECT list_position([1.0,2.0,3.0,4.0],1)
----
1
query T
SELECT list_position([1,2,3],4.0)
----
NULL
query T
SELECT list_position([1.0,2.0,3.0],4)
----
NULL
statement error
SELECT list_position([1.0,2.0,3.0], 'a')
----
Conversion Error: Could not convert string "a" to DECIMAL(2,1)
query I
SELECT list_position([1.0,2.0,3.0]::varchar[], 'a')
----
NULL
# Not a list as input
statement error
SELECT list_position('a', 'a')
----
Conversion Error: Type VARCHAR with value 'a' can't be cast to the destination type VARCHAR[]
query T
SELECT list_position(NULL,NULL)
----
NULL
query T
SELECT list_position([7], 5)
----
NULL
query T
SELECT list_position([1,2,3,4],4)
----
4
query T
SELECT list_position([1,2,3,4],5)
----
NULL
query T
SELECT list_position([1.0,2.0,3.0,4.0],5.0)
----
NULL
query T
SELECT list_position([1.0,2.0,3.0,4.0],4.0)
----
4
query T
SELECT list_position([true, false],true)
----
1
query T
SELECT list_position([true, true],false)
----
NULL
query T
SELECT list_position(['test', 'notest'],'notest')
----
2
query T
SELECT list_position(['test', 'notest'],'a')
----
NULL
query T
SELECT list_position(NULL,1)
----
NULL
# Null types
query T
SELECT list_position([1],NULL)
----
NULL
query T
SELECT list_position([NULL],NULL)
----
1
query T
SELECT list_position([NULL, 1],NULL)
----
1
query T
SELECT list_position([NULL, 1],1)
----
2
query T
SELECT list_position([NULL, 0],1)
----
NULL
query T
SELECT list_position([],NULL)
----
NULL
query T
SELECT list_position([NULL,7], 7)
----
2
statement error
SELECT list_position([[1,2,3],[1],[1,2,3])
----
Parser Error: syntax error at or near ")"
statement error
SELECT list_position([[1,2,3],[1],[1,2,3]])
----
statement error
SELECT list_position(1)
----
statement error
SELECT list_position(1,1)
----
statement ok
PRAGMA debug_force_external=true
loop i 0 2
foreach type <integral> varchar
# list tests
statement ok
CREATE TABLE test0 (i ${type}[])
statement ok
INSERT INTO test0 VALUES ([2]), ([1]), ([1, 2]), ([]), ([2, 2]), ([NULL]), ([2, 3])
query T
SELECT list_position(i,1::${type}) from test0
----
NULL
1
1
NULL
NULL
NULL
NULL
statement ok
DROP TABLE test0
statement ok
PRAGMA debug_force_external=false
endloop
endloop
query T
SELECT list_position([[1,2,3],[1]],[1])
----
2
query T
SELECT list_position([[1,2,3],[1]],[2])
----
NULL
query T
SELECT list_position([[1,2,3],[1]],[1,2,3])
----
1
query T
SELECT list_position([[1,3],[1]],[1,2,3])
----
NULL
query T
SELECT list_position([[1,3],[1], [1,2,3]],[1,2,3])
----
3
query T
SELECT list_position([[NULL],[1], [1,2,3]],NULL)
----
NULL
query T
SELECT list_position([[NULL],[1], [1,2,3]],[NULL])
----
1
query T
SELECT list_position([[1,NULL],[1], [1,2,3]],[1,NULL])
----
1
query T
SELECT list_position([[1,NULL],[1], [1,2,3]],[0,NULL])
----
NULL
query T
SELECT list_position([NULL, [1], [1,2,3]], [NULL])
----
NULL
# nested types
query T
SELECT list_position([{a: 1}, {a: 2}], {a: 2})
----
2
query T
SELECT list_position([{a: 1}, {a: 2}], {a: 3})
----
NULL
query T
SELECT list_position([{a: 1, b: 3}, {a: 2, b: 2}], {a: 2, b: 2})
----
2
query T
SELECT list_position([{a: 1, b: 3}, {a: 2, b: 2}], {a: 1, b: 2})
----
NULL
query T
SELECT list_position([MAP([1], [2])], MAP([1], [2]))
----
1
query T
SELECT list_position([MAP([1], [2])], MAP([1], [3]))
----
NULL
query T
SELECT list_position([MAP([1], [2]), NULL], NULL)
----
2
query T
SELECT list_position([MAP([1], [2]), NULL], MAP([1], [2]))
----
1
query T
SELECT list_position([[1,2,3],NULL],NULL)
----
2
# test nested lists in tables
statement ok
CREATE TABLE test0 (i int[][], j int[]);
statement ok
INSERT INTO test0 VALUES ([[2,1,3],[1,2]], [1, 2]), ([[2,3,4],[1,2]], [1, 3]), ([[1]], NULL), ([[1, NULL, 2], [NULL]], [NULL]);
query TTT
SELECT i, j, list_position(i,j) from test0
----
[[2, 1, 3], [1, 2]] [1, 2] 2
[[2, 3, 4], [1, 2]] [1, 3] NULL
[[1]] NULL NULL
[[1, NULL, 2], [NULL]] [NULL] 2
statement ok
DROP TABLE test0;
statement ok
PRAGMA debug_force_external=true
loop i 0 2
foreach type float double
# test floats and doubles
statement ok
CREATE TABLE test0 (i ${type}[])
statement ok
INSERT INTO test0 VALUES ([2.0]), ([1.0]), ([1.0, 2.0]), ([]), ([2.0, 2.0]), ([NULL]), ([2.0, 3.0])
query T
SELECT list_position(i,1.0) from test0
----
NULL
1
1
NULL
NULL
NULL
NULL
statement ok
DROP TABLE test0
# with nulls and non-const element
statement ok
CREATE TABLE test0 (i ${type}[], j ${type})
statement ok
INSERT INTO test0 VALUES ([2.0,1.0,3.0], 2.0), ([2.0,3.0,4.0], 5.0), ([1.0], NULL), ([1.0, NULL, 2.0], NULL);
query TTT
SELECT i, j, list_position(i,j) from test0
----
[2.0, 1.0, 3.0] 2.0 1
[2.0, 3.0, 4.0] 5.0 NULL
[1.0] NULL NULL
[1.0, NULL, 2.0] NULL 2
statement ok
DROP TABLE test0
statement ok
PRAGMA debug_force_external=false
endloop
endloop

View File

@@ -0,0 +1,24 @@
# name: test/sql/function/list/list_position_nan.test
# description: Test list_position function with nans
# group: [list]
# list position with NaN
query I
SELECT list_position(['NaN'::DOUBLE], 'NaN'::DOUBLE)
----
1
query I
SELECT list_position([NULL, 0, 'NaN'::DOUBLE], 'NaN'::DOUBLE)
----
3
query I
SELECT list_contains([NULL, 0, 'NaN'::DOUBLE], 'NaN'::DOUBLE)
----
true
query I
SELECT list_position([[[NULL, 42]]], [[NULL, 42]])
----
1

View File

@@ -0,0 +1,315 @@
# name: test/sql/function/list/list_resize.test
# description: test for list_resize()
# group: [list]
statement ok
PRAGMA enable_verification;
query I
SELECT list_resize([1, 2, 4], 2);
----
[1, 2]
statement ok
create table tbl(a int[], b int);
statement ok
insert into tbl values ([5,4,3], 3);
statement ok
insert into tbl values ([1,2,3], 5);
statement ok
insert into tbl values (NULL, 8);
statement ok
insert into tbl values ([10,11,12], 2);
query I
select list_resize(a, b) from tbl;
----
[5, 4, 3]
[1, 2, 3, NULL, NULL]
NULL
[10, 11]
query I
SELECT list_resize([], 2);
----
[NULL, NULL]
# Strings
statement ok
create table string_tbl(a string[], b int);
statement ok
insert into string_tbl values (['abc', 'def'], 3);
statement ok
insert into string_tbl values (['d', 'ef', 'ghij'], 8);
statement ok
insert into string_tbl values (['lmnopqrs'], 5);
statement ok
insert into string_tbl values (['here is a little story about a duck,', 'whose name is harold.', 'He is a cool duck who lives in a cool world'], 5);
query I
select list_resize(a, b) from string_tbl;
----
[abc, def, NULL]
[d, ef, ghij, NULL, NULL, NULL, NULL, NULL]
[lmnopqrs, NULL, NULL, NULL, NULL]
['here is a little story about a duck,', whose name is harold., He is a cool duck who lives in a cool world, NULL, NULL]
# Null Check
query I
SELECT list_resize(NULL, 1, 1);
----
NULL
query I
SELECT list_resize(NULL, 2, NULL);
----
NULL
query I
SELECT list_resize(NULL, NULL, NULL);
----
NULL
statement ok
SELECT list_resize([1,2,3], NULL);
statement ok
CREATE TABLE nulls(l INT[], b INT);
statement ok
INSERT INTO nulls VALUES ([1, 2, 3], 2), (NULL, 6), ([], 4), ([NULL, NULL, 5, 6, NULL], 6);
query I
SELECT list_resize(l, b) FROM nulls;
----
[1, 2]
NULL
[NULL, NULL, NULL, NULL]
[NULL, NULL, 5, 6, NULL, NULL]
query I
select * from (SELECT list_resize(NULL, 1, 1))
----
NULL
# Nested Lists
query I
SELECT list_resize([[1], [1, 2], NULL, [NULL], [], [1, 2, 3]], 3)
----
[[1], [1, 2], NULL]
statement ok
create table list_tbl(a int[][], b int);
statement ok
insert into list_tbl values ([[1, 2, 3], [4, 5, 6]], 3);
statement ok
insert into list_tbl values ([[7, 8, 9], [10, NULL, 6], [9, 8, 7]], 5);
statement ok
insert into list_tbl values ([[1, 2, 3], NULL, [4, 5, 6]], 2);
query I
select list_resize(a, b) from list_tbl;
----
[[1, 2, 3], [4, 5, 6], NULL]
[[7, 8, 9], [10, NULL, 6], [9, 8, 7], NULL, NULL]
[[1, 2, 3], NULL]
# Structs
query I
select list_resize([{'i': 1,'j': 2}, NULL, {'i': 3, 'j': 4}], 2);
----
[{'i': 1, 'j': 2}, NULL]
query I
select list_resize([{'i': 1,'j': [2, 3]}, NULL, {'i': 1, 'j': [2, 3]}], 4);
----
[{'i': 1, 'j': [2, 3]}, NULL, {'i': 1, 'j': [2, 3]}, NULL]
# Nested Lists of Structs and Structs of Lists in Structs and Lists of Structs in Lists
query I
select list_resize([{'i': 1,'j': [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]}, NULL, {'i': 1, 'j': [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]}], 4);
----
[{'i': 1, 'j': [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]}, NULL, {'i': 1, 'j': [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}]}, NULL]
query I
select list_resize([{'i': 1,'j': [{'a': 1, 'b': [2, 3]}, {'a': 3, 'b': [4, 5]}]}, NULL, {'i': 1, 'j': [{'a': 1, 'b': [2, 3]}, {'a': 3, 'b': [4, 5]}]}], 4);
----
[{'i': 1, 'j': [{'a': 1, 'b': [2, 3]}, {'a': 3, 'b': [4, 5]}]}, NULL, {'i': 1, 'j': [{'a': 1, 'b': [2, 3]}, {'a': 3, 'b': [4, 5]}]}, NULL]
query I
select list_resize([[[1, 2, 3], [4, 5, 6]], [[ 7, 8, 9 ]], [[10, 11, 12], [13, 14, 15]]], 2);
----
[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9]]]
query I
select list_resize([[[1, 2, 3], [4, 5, 6]], [[ 7, 8, 9 ], NULL], NULL, [NULL], [[10, 11, 12], [13, 14, 15]]], 8);
----
[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], NULL], NULL, [NULL], [[10, 11, 12], [13, 14, 15]], NULL, NULL, NULL]
# Nested Function
query I
select list_resize([1, 2, 3], len(list_resize([1, 2, 3], 2)));
----
[1, 2]
query I
select list_resize(list_filter([1, 2, 3, 4, 5, 6], lambda x: x > 1), 4);
----
[2, 3, 4, 5]
# Default Values
query I
SELECT list_resize([1, 2], 3, 4)
----
[1, 2, 4]
statement ok
CREATE TABLE def(tbl INT[], b INT, d INT);
statement ok
INSERT INTO def VALUES ([1, 2, 3], 5, 4), ([4, 5, 6], 6, NULL), ([7, 8, NULL], 3, 10);
query I
SELECT list_resize(tbl, b, d) FROM def;
----
[1, 2, 3, 4, 4]
[4, 5, 6, NULL, NULL, NULL]
[7, 8, NULL]
query I
SELECT list_resize([1, 2], 3, NULL);
----
[1, 2, NULL]
# Struct Default Values
query I
select list_resize([{'i': 1,'j': [2, 3]}, NULL, {'i': 1, 'j': [2, 3]}], 4, {'i': 5, 'j': [10, 10]});
----
[{'i': 1, 'j': [2, 3]}, NULL, {'i': 1, 'j': [2, 3]}, {'i': 5, 'j': [10, 10]}]
query I
select list_resize([{'i': 1,'j': [2, 3]}, NULL, {'i': 1, 'j': [2, 3]}], 6, NULL);
----
[{'i': 1, 'j': [2, 3]}, NULL, {'i': 1, 'j': [2, 3]}, NULL, NULL, NULL]
# Lists that exceed standard vector size (2048)
statement ok
SELECT list_resize(range(10000), 4000);
statement ok
SELECT list_resize([1, 2, 3], 4000);
# Vector_types
statement ok
CREATE TABLE bool_table(a bool[], b int);
statement ok
INSERT INTO bool_table VALUES ([true, false, true], 1);
statement ok
INSERT INTO bool_table VALUES ([false, true, false], 2);
statement ok
INSERT INTO bool_table VALUES ([true, true, NULL], 3);
query I
SELECT list_resize(a, b) FROM bool_table;
----
[true]
[false, true]
[true, true, NULL]
query I
SELECT list_resize([true], 2);
----
[true, NULL]
query I
SELECT list_resize([false], 2);
----
[false, NULL]
query I
SELECT list_resize([NULL], 2);
----
[NULL, NULL]
# Prepared Statements
statement ok
prepare q1 as select list_resize(?, ?);
statement ok
prepare q2 as select array_resize(?, ?);
foreach q q1 q2
query I
execute ${q}([1, 2, 3], 4);
----
[1, 2, 3, NULL]
query I
execute ${q}([1, 2, 3], 2);
----
[1, 2]
query I
execute ${q}([1, 2, 3], 0);
----
[]
query I
execute ${q}([1, 2, 3], NULL);
----
[]
query I
execute ${q}([1, 2, 3], 1.4);
----
[1]
statement ok
execute ${q}([2], 2::TINYINT);
statement error
execute ${q}([1, 2, 3], -1);
----
Conversion Error: Type INT32 with value -1 can't be cast because the value is out of range for the destination type UINT64
statement error
SELECT LIST_RESIZE([1, 2, 3], 9999999999999999999);
----
maximum allowed vector size
statement error
SELECT LIST_RESIZE([1, 2, 3], 4000999999999999999)
----
maximum allowed vector size
endloop
query I
SELECT list_resize([1, 2, 3]::BIGINT[], 5, 42);
----
[1, 2, 3, 42, 42]

View File

@@ -0,0 +1,23 @@
# name: test/sql/function/list/list_resize.test_slow
# description: Tests list_resize for large padding counts.
# group: [list]
statement ok
PRAGMA enable_verification;
# Issue 12816
statement ok
CREATE TABLE test_table (id INTEGER,
data STRUCT(a INTEGER, b DOUBLE, c VARCHAR)[]);
statement ok
INSERT INTO test_table SELECT range, [
{'a': 1, 'b': 1.1, 'c': 'one'},
{'a': 2, 'b': 2.2, 'c': 'two'},
{'a': 3, 'b': 3.3, 'c': 'three'}] FROM range(1001);
statement ok
CREATE OR REPLACE TABLE padded_test_table AS
SELECT id, list_resize(data, 10000, struct_pack(a := 0, b := 0.0, c := 'padding')) AS padded_data
FROM test_table;

View File

@@ -0,0 +1,65 @@
# name: test/sql/function/list/list_resize_error.test
# description: test for list_resize() that should error
# group: [list]
statement ok
PRAGMA enable_verification;
statement ok
prepare q1 as select list_resize(?, ?);
statement ok
prepare q2 as select array_resize(?, ?);
foreach q q1 q2
statement error
execute ${q}([1, 2, 3], -1);
----
statement error
execute ${q}([1, 2, 3], 'a');
----
statement error
execute ${q}('cici n est pas een list', 2);
----
statement error
execute ${q}([1, 2, 3], 'huh');
----
Conversion Error: Could not convert string 'huh' to UINT64
statement error
execute ${q}();
----
statement error
execute ${q}([1, 2, 3]);
----
endloop
statement ok
prepare q3 as select list_resize(?, ?, ?);
statement ok
prepare q4 as select array_resize(?, ?, ?);
foreach q q3 q4
statement error
execute ${q}([1, 2, 3], 5, 'abc');
----
Conversion Error: Could not convert string 'abc' to INT32
statement error
execute ${q}([1, 2, 3], 2, 3, 4);
----
statement error
execute ${q}([1, 2, 3], 1, [1, 2, 3]);
----
Conversion Error: Unimplemented type for cast (INTEGER[] -> INTEGER)
endloop

View File

@@ -0,0 +1,48 @@
# name: test/sql/function/list/list_resize_types.test_slow
# description: test for list_resize() that take a long time
# group: [list]
require vector_size 512
statement ok
PRAGMA enable_verification;
query I
select list_resize(c, 3) from test_vector_types(NULL::INT[], false) t(c);
----
[-2147483648, 2147483647, NULL]
[NULL, NULL, NULL]
[NULL, NULL, NULL]
[-2147483648, 2147483647, NULL]
[-2147483648, 2147483647, NULL]
[-2147483648, 2147483647, NULL]
[NULL, NULL, NULL]
[NULL, NULL, NULL]
[3, 5, NULL]
[NULL, NULL, NULL]
[7, NULL, NULL]
query I
select list_resize(c, 1) from test_vector_types(NULL::INT[], false) t(c);
----
[-2147483648]
[NULL]
[NULL]
[-2147483648]
[-2147483648]
[-2147483648]
[NULL]
[NULL]
[3]
[NULL]
[7]
statement ok
CREATE TABLE all_types AS SELECT * FROM test_all_types();
foreach colname bool tinyint smallint int bigint hugeint utinyint usmallint uint ubigint uhugeint date time timestamp timestamp_s timestamp_ms timestamp_ns time_tz timestamp_tz float double dec_4_1 dec_9_4 dec_18_6 dec38_10 uuid interval varchar blob small_enum medium_enum large_enum int_array double_array date_array timestamp_array timestamptz_array varchar_array nested_int_array struct struct_of_arrays array_of_structs map
statement ok
select list_resize(["${colname}"], 2) FROM all_types;
endloop

View File

@@ -0,0 +1,283 @@
# name: test/sql/function/list/list_reverse.test
# group: [list]
statement ok
PRAGMA enable_verification
query I
SELECT list_reverse(NULL);
----
NULL
query I
SELECT list_reverse([]);
----
[]
query I
SELECT list_reverse([NULL]);
----
[NULL]
query I
SELECT list_reverse([1, 42, 2]);
----
[2, 42, 1]
query I
SELECT array_reverse([1, 42, 2]);
----
[2, 42, 1]
query I
SELECT list_reverse([1, 42, NULL, 2]);
----
[2, NULL, 42, 1]
query I
SELECT list_reverse(list_reverse([1, 3, 3, 42, 117, 69, NULL]));
----
[1, 3, 3, 42, 117, 69, NULL]
query I
SELECT list_reverse ([[1, 2 ,42], [3, 4]]);
----
[[3, 4], [1, 2, 42]]
query I
prepare q1 as select list_reverse(?);
execute q1([5, 42, 3]);
----
[3, 42, 5]
statement ok
create or replace table tbl_big as select range(5000) as list;
query I
select list_sort((list), 'desc') == list_reverse(list) from tbl_big;
----
true
statement ok
CREATE TABLE tbl (id INTEGER, list INTEGER[]);
statement ok
INSERT INTO tbl VALUES (1, [NULL, 3, 117, 42, 1]), (2, NULL), (3, [1, 8, 9]), (4, NULL), (5, NULL), (6, [NULL]);
query II
SELECT id, list_reverse(list) FROM tbl ORDER BY id;
----
1 [1, 42, 117, 3, NULL]
2 NULL
3 [9, 8, 1]
4 NULL
5 NULL
6 [NULL]
statement ok
DROP TABLE tbl;
statement ok
CREATE TABLE tbl2 (id INTEGER, list INTEGER[]);
statement ok
INSERT INTO tbl2 VALUES (1, [1, 2, 3]), (1, [4, 5, 6]), (3, [7, 8, 9]);
query II
SELECT id, list_reverse(list) FROM tbl2 ORDER BY id;
----
1 [3, 2, 1]
1 [6, 5, 4]
3 [9, 8, 7]
statement ok
DROP TABLE tbl2;
query IIIIIIII
select list_reverse(list_reverse(columns(['int_array', 'varchar_array', 'nested_int_array', 'array_of_structs', 'timestamp_array', 'double_array', 'date_array', 'timestamptz_array'])))
IS NOT DISTINCT FROM
columns(['int_array', 'varchar_array', 'nested_int_array', 'array_of_structs', 'timestamp_array', 'double_array', 'date_array', 'timestamptz_array'])
from test_all_types();
----
true true true true true true true true
true true true true true true true true
true true true true true true true true
statement ok
select list_reverse(test_vector) from test_vector_types(null::int[], false);
statement ok
select list_reverse(test_vector) from test_vector_types(null::int[], true);
query I nosort q1
select true from test_vector_types(null::int[], false);
----
query I nosort q1
select list_sort((list), 'desc') IS NOT DISTINCT FROM list
from (select list_reverse(test_vector) as list from test_vector_types(null::int[], false));
----
query I nosort q1
select list_sort((list), 'desc') IS NOT DISTINCT FROM list
from (select list_reverse(test_vector) as list from test_vector_types(null::int[], true));
----
statement error
SELECT list_reverse()
----
statement error
SELECT list_reverse(42)
----
statement error
SELECT list_reverse ([1, 3, 2, 42, 117,, NULL])
----
Parser Error: syntax error at or near ","
statement ok
CREATE TABLE palindromes (s VARCHAR);
statement ok
INSERT INTO palindromes VALUES ('racecar'), ('civic'), ('defied'), ('repaper'), ('kayak'), ('rotator'), ('tattarrattat'), ('saippuakivikauppias'), ('malayalam');
query I
SELECT list_aggr(list_reverse(str_split(s, '')), 'string_agg', '') FROM palindromes ORDER BY s;
----
civic
deifed
kayak
malayalam
racecar
repaper
rotator
saippuakivikauppias
tattarrattat
statement ok
DROP TABLE palindromes;
query I
WITH example AS (
SELECT [1, 2, 3] AS arr UNION ALL
SELECT [4, 5] AS arr UNION ALL
SELECT [] AS arr
)
SELECT
list_reverse(arr) AS reverse_arr
FROM example ORDER BY length(reverse_arr) DESC;
----
[3, 2, 1]
[5, 4]
[]
# test incorrect syntax
statement error
SELECT list_reverse()
----
statement error
SELECT list_reverse(*)
----
statement error
SELECT list_reverse([1, 2], 2)
----
# list constant tests
query I
SELECT list_reverse([1, 42, 39, 58])
----
[58, 39, 42, 1]
query I
SELECT list_reverse([1, NULL, 42, 39, NULL, 58])
----
[58, NULL, 39, 42, NULL, 1]
query I
SELECT list_reverse([1, 42, -39, 58, -1, 18])
----
[18, -1, 58, -39, 42, 1]
query I
SELECT list_reverse(list_reverse([11, -100, 678]))
----
[11, -100, 678]
# list column tests
statement ok
CREATE OR REPLACE TABLE integers AS SELECT LIST(i) AS i FROM range(1, 10, 1) t1(i)
statement ok
INSERT INTO integers VALUES ([NULL]), (NULL), ([])
query I
SELECT list_reverse(i) FROM integers
----
[9, 8, 7, 6, 5, 4, 3, 2, 1]
[NULL]
NULL
[]
query I
SELECT (i).list_reverse() FROM integers
----
[9, 8, 7, 6, 5, 4, 3, 2, 1]
[NULL]
NULL
[]
# Nested list and very Large list
query I
SELECT list_reverse([[1], [1, 2], NULL, [NULL], [], [1, 2, 3]])
----
[[1, 2, 3], [], [NULL], NULL, [1, 2], [1]]
query I
SELECT ([[1], [1, 2], NULL, [NULL], [], [1, 2, 3]]).list_reverse()
----
[[1, 2, 3], [], [NULL], NULL, [1, 2], [1]]
statement ok
CREATE OR REPLACE TABLE lists AS SELECT range % 4 g, list(range) l FROM range(10000) GROUP BY range % 4;
query T
with cte0 as (
select g, list_reverse(l) l from lists
), cte1 as (
select g, unnest(l) i from cte0
), cte2 as (
select g, i, lead(g, 1) over () lg, lead(i, 1) over () li from cte1
)
select count(*)
from cte2
where g = lg
and lg not null
and li > i
----
0
# bug found in PR10587
query I
WITH example AS (
SELECT [1, 2, 3] AS arr UNION ALL
SELECT [4, 5] AS arr UNION ALL
SELECT [] AS arr
)
SELECT
list_reverse(arr) AS reverse_arr
FROM example ORDER BY length(reverse_arr) DESC;
----
[3, 2, 1]
[5, 4]
[]

View File

@@ -0,0 +1,35 @@
# name: test/sql/function/list/list_reverse.test_slow
# group: [list]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE all_types AS SELECT * FROM test_all_types();
foreach colname bool tinyint smallint int bigint hugeint utinyint usmallint uint ubigint date time timestamp timestamp_s timestamp_ms timestamp_ns time_tz timestamp_tz float double dec_4_1 dec_9_4 dec_18_6 dec38_10 uuid interval varchar blob small_enum medium_enum large_enum int_array double_array date_array timestamp_array timestamptz_array varchar_array nested_int_array struct struct_of_arrays array_of_structs map
statement ok
select list_reverse(["${colname}"]) FROM all_types;
endloop
statement ok
create table tbl as select range(5000) as list;
query I nosort reversered list
select list_sort(range(5000), 'desc');
----
query I nosort reversered list
select list_reverse(list) from tbl;
----
# test incorrect parameter type
foreach type boolean varchar tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10) date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz interval blob
statement error
SELECT list_reverse(NULL::${type})
----
endloop

View File

@@ -0,0 +1,26 @@
# name: test/sql/function/list/list_reverse_all_types.test_slow
# group: [list]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE all_types AS SELECT * FROM test_all_types();
foreach colname bool tinyint smallint int bigint hugeint utinyint usmallint uint ubigint date time timestamp timestamp_s timestamp_ms timestamp_ns time_tz timestamp_tz float double dec_4_1 dec_9_4 dec_18_6 dec38_10 uuid interval varchar blob small_enum medium_enum large_enum int_array double_array date_array timestamp_array timestamptz_array varchar_array nested_int_array struct struct_of_arrays array_of_structs map
statement ok
select list_reverse(["${colname}"]) FROM all_types;
endloop
statement ok
create table tbl as select range(5000) as list;
query I nosort reversered list
select list_sort(range(5000), 'desc');
----
query I nosort reversered list
select list_reverse(list) from tbl;
----

View File

@@ -0,0 +1,332 @@
# name: test/sql/function/list/list_select.test_slow
# description: Test list_select function
# group: [list]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE integers (i int[])
statement ok
INSERT INTO integers VALUES ([1,2,3]), ([4,5,6]), (NULL), ([]), ([NULL]), ([4])
statement ok
CREATE TABLE selections (j int[])
statement ok
INSERT INTO selections VALUES ([2,1]), ([3,1,3]), ([]), (NULL)
# standard test
query I
SELECT list_select([], [])
----
[]
query I
SELECT list_select(NULL, [])
----
NULL
query I
SELECT list_select([], NULL)
----
NULL
query I
SELECT list_select([1,2,3], [1,2,3])
----
[1, 2, 3]
query I
SELECT list_select([1,2,3], [3,2,3,3])
----
[3, 2, 3, 3]
query I
SELECT list_select([1,2,3], [1,2])
----
[1, 2]
# selections out of bounds
query I
SELECT list_select([1,2,3], [3,2,1,4])
----
[3, 2, 1, NULL]
query I
SELECT list_select([1,2,3], [3,2,3,-1])
----
[3, 2, 3, NULL]
# queries with multiple rows
query I
SELECT list_select(i, [1,2]) FROM integers
----
[1, 2]
[4, 5]
NULL
[NULL, NULL]
[NULL, NULL]
[4, NULL]
query I
SELECT list_select(i, j) FROM integers, selections ORDER BY i, j;
----
[]
[NULL, NULL]
[NULL, NULL, NULL]
NULL
[]
[2, 1]
[3, 1, 3]
NULL
[]
[NULL, 4]
[NULL, 4, NULL]
NULL
[]
[5, 4]
[6, 4, 6]
NULL
[]
[NULL, NULL]
[NULL, NULL, NULL]
NULL
NULL
NULL
NULL
NULL
statement error
SELECT list_select([1,2,3], [NULL])
----
NULLs are not allowed as list elements in the second input parameter.
query I
SELECT list_select(i, [2,3,4]) FROM integers
----
[2, 3, NULL]
[5, 6, NULL]
NULL
[NULL, NULL, NULL]
[NULL, NULL, NULL]
[NULL, NULL, NULL]
# test all types
# BOOLEAN
query I
SELECT list_select([True, False, NULL, True, True, NULL], [1,3,2])
----
[true, NULL, false]
query I
SELECT list_select([NULL::BOOLEAN], [1])
----
[NULL]
# VARCHAR
query I
SELECT list_select(['aa', 'a', 'cd', NULL, '42'], [4,5,2,1,3])
----
[NULL, 42, a, aa, cd]
query I
SELECT list_select([NULL::VARCHAR], [1])
----
[NULL]
# INTEGER types
foreach type tinyint smallint integer bigint hugeint utinyint usmallint uinteger ubigint
query I
SELECT list_select([1::${type}, NULL, 2::${type}], [2,1,3])
----
[NULL, 1, 2]
query I
SELECT list_select([NULL::${type}], [1])
----
[NULL]
endloop
# FLOAT, DOUBLE and DECIMAL types
foreach type float double decimal(4,1) decimal(9,4) decimal(18,6) decimal(38,10)
statement ok
SELECT list_select([1::${type}], [2,1])
query I
SELECT list_select([NULL::${type}], [1])
----
[NULL]
endloop
# TEMPORAL types
# date
query I
SELECT list_select(['2021-08-20'::DATE], [1])
----
[2021-08-20]
# time
query I
SELECT list_select(['14:59:37'::TIME], [1])
----
['14:59:37']
# timestamp
query I
SELECT list_select(['2021-08-20'::TIMESTAMP], [1])
----
['2021-08-20 00:00:00']
# timestamp s
query I
SELECT list_select(['2021-08-20'::TIMESTAMP_S], [1])
----
['2021-08-20 00:00:00']
# timestamp ms
query I
SELECT list_select(['2021-08-20 00:00:00.123'::TIMESTAMP_MS], [1])
----
['2021-08-20 00:00:00.123']
# timestamp ns
query I
SELECT list_select(['2021-08-20 00:00:00.123456'::TIMESTAMP_NS], [1])
----
['2021-08-20 00:00:00.123456']
# time with time zone
query I
SELECT list_select(['14:59:37'::TIMETZ], [1])
----
['14:59:37+00']
# timestamp with time zone
query I
SELECT list_select(['2021-08-20'::TIMESTAMPTZ], [1])
----
['2021-08-20 00:00:00+00']
# interval
query I
SELECT list_select([INTERVAL 1 YEAR], [1])
----
[1 year]
foreach type date time timestamp timestamp_s timestamp_ms timestamp_ns timetz timestamptz interval
query I
SELECT list_select([NULL::${type}], [1])
----
[NULL]
endloop
# BLOB
query I
SELECT list_select(['{a: 1}'::BLOB, '{a: 3}'::BLOB], [1,2])
----
['{a: 1}', '{a: 3}']
query I
SELECT list_select([NULL::BLOB], [1])
----
[NULL]
# ENUMS
statement ok
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy')
statement ok
CREATE TABLE enums (e mood[])
statement ok
INSERT INTO enums VALUES (['happy', 'sad'])
query I
SELECT list_select(e, [2,1]) FROM enums
----
[sad, happy]
# NESTED types
query I
SELECT list_select([[1], [1, 2], NULL, [NULL], [], [1, 2, 3]], [3,5,1,2,6,4])
----
[NULL, [], [1], [1, 2], [1, 2, 3], [NULL]]
query I
SELECT list_select([{'a': 1}, {'a': 5}, {'a': 3}], [1,3,2])
----
[{'a': 1}, {'a': 3}, {'a': 5}]
# very large lists
statement ok
CREATE TABLE lists AS SELECT range % 4 g, list(range) l FROM range(6000) GROUP BY range % 4;
query T
with cte0 as (
select g, list_select(l, range(5)) l from lists
), cte1 as (
select g, unnest(l) i from cte0
)
select count(*)
from cte1
----
20
statement ok
SELECT list_select(range(6000), range(6000))
query I
SELECT i FROM integers WHERE [4] = list_select(i, [1])
----
[4, 5, 6]
[4]
query I
SELECT (list_select([1,2,3], [2,3]))[1]
----
2
# errors
statement error
SELECT list_select([1, 2], 'hello');
----
Conversion Error
statement error
SELECT list_select([1, 2], ['hello']);
----
No function matches
statement ok
CREATE TABLE all_types AS SELECT * exclude(small_enum, medium_enum, large_enum) FROM test_all_types();
statement error
SELECT list_select(c34, 'enum_0')
FROM all_types AS t43(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, c31, c32, c33, c34, c35, c36, c37, c38, c39, c40, c41, c42),
all_types AS t86(c44, c45, c46, c47, c48, c49, c50, c51, c52, c53, c54, c55, c56, c57, c58, c59, c60, c61, c62, c63, c64, c65, c66, c67, c68, c69, c70, c71, c72, c73, c74, c75, c76, c77, c78, c79, c80, c81, c82, c83, c84, c85);
----
Conversion Error
query I
SELECT LIST_SELECT(ARRAY_VALUE('1', NULL), [1, 2, 3]);
----
[1, NULL, NULL]

Some files were not shown because too many files have changed in this diff Show More