This commit is contained in:
李扬 2024-09-18 23:54:18 +03:00 committed by GitHub
commit 23e172806a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 782 additions and 433 deletions

View File

@ -595,6 +595,7 @@ SELECT arrayConcat([1, 2], [3, 4], [5, 6]) AS res
Get the element with the index `n` from the array `arr`. `n` must be any integer type. Get the element with the index `n` from the array `arr`. `n` must be any integer type.
Indexes in an array begin from one. Indexes in an array begin from one.
Negative indexes are supported. In this case, it selects the corresponding element numbered from the end. For example, `arr[-1]` is the last item in the array. Negative indexes are supported. In this case, it selects the corresponding element numbered from the end. For example, `arr[-1]` is the last item in the array.
If the index falls outside of the bounds of an array, it returns some default value (0 for numbers, an empty string for strings, etc.), except for the case with a non-constant array and a constant index 0 (in this case there will be an error `Array indices are 1-based`). If the index falls outside of the bounds of an array, it returns some default value (0 for numbers, an empty string for strings, etc.), except for the case with a non-constant array and a constant index 0 (in this case there will be an error `Array indices are 1-based`).
@ -616,6 +617,27 @@ SELECT has([1, 2, NULL], NULL)
└─────────────────────────┘ └─────────────────────────┘
``` ```
## arrayElementOrNull(arr, n)
Get the element with the index `n`from the array `arr`. `n` must be any integer type.
Indexes in an array begin from one.
Negative indexes are supported. In this case, it selects the corresponding element numbered from the end. For example, `arr[-1]` is the last item in the array.
If the index falls outside of the bounds of an array, it returns `NULL` instead of a default value.
### Examples
``` sql
SELECT arrayElementOrNull([1, 2, 3], 2), arrayElementOrNull([1, 2, 3], 4)
```
``` text
┌─arrayElementOrNull([1, 2, 3], 2)─┬─arrayElementOrNull([1, 2, 3], 4)─┐
│ 2 │ ᴺᵁᴸᴸ │
└──────────────────────────────────┴──────────────────────────────────┘
```
## hasAll {#hasall} ## hasAll {#hasall}
Checks whether one array is a subset of another. Checks whether one array is a subset of another.

File diff suppressed because it is too large Load Diff

View File

@ -101,7 +101,6 @@ arrayCumSumNonNegative
arrayDifference arrayDifference
arrayDistinct arrayDistinct
arrayDotProduct arrayDotProduct
arrayElement
arrayEnumerate arrayEnumerate
arrayEnumerateDense arrayEnumerateDense
arrayEnumerateDenseRanked arrayEnumerateDenseRanked

View File

@ -0,0 +1,142 @@
-- { echoOn }
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(Int32), id Int32) ENGINE = Memory;
insert into array_element_or_null_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], -1), ([11,12], -2), ([11,12], -3), ([11], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
12
\N
13
11
\N
\N
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(Int32), id UInt32) ENGINE = Memory;
insert into array_element_or_null_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], 1), ([11,12], 4), ([11], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
12
\N
11
\N
\N
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(String), id Int32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], -1), (['Ab','ber'], -2), (['AB','asd'], -3), (['A'], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
Df
\N
ERT
Ab
\N
\N
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(String), id UInt32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], 1), (['Ab','ber'], 4), (['A'], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
Df
\N
ABC
\N
\N
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (id UInt32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (2), (1), (4), (3), (0);
select [1, 2, 3] as arr, arrayElementOrNull(arr, id) from array_element_or_null_test;
[1,2,3] 2
[1,2,3] 1
[1,2,3] \N
[1,2,3] 3
[1,2,3] \N
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (id Int32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (-2), (1), (-4), (3), (2), (-1), (4), (-3), (0);
select [1, 2, 3] as arr, arrayElementOrNull(arr, id) from array_element_or_null_test;
[1,2,3] 2
[1,2,3] 1
[1,2,3] \N
[1,2,3] 3
[1,2,3] 2
[1,2,3] 3
[1,2,3] \N
[1,2,3] 1
[1,2,3] \N
DROP TABLE array_element_or_null_test;
SELECT arrayElementOrNull(range(0), -1);
\N
SELECT arrayElementOrNull(range(0), 1);
\N
SELECT arrayElementOrNull(range(number), 2) FROM system.numbers LIMIT 3;
\N
\N
1
SELECT arrayElementOrNull(range(number), -1) FROM system.numbers LIMIT 3;
\N
0
1
SELECT arrayElementOrNull(range(number), number) FROM system.numbers LIMIT 3;
\N
0
1
SELECT arrayElementOrNull(range(number), 2 - number) FROM system.numbers LIMIT 3;
\N
0
\N
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), 2) FROM system.numbers LIMIT 3;
\N
\N
1
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), -1) FROM system.numbers LIMIT 3;
\N
0
1
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), number) FROM system.numbers LIMIT 3;
\N
0
1
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), 2 - number) FROM system.numbers LIMIT 3;
\N
0
\N
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), 2) FROM system.numbers LIMIT 3;
[]
[]
[0]
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), -1) FROM system.numbers LIMIT 3;
[]
[]
[0]
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), number) FROM system.numbers LIMIT 3;
[]
[]
[0]
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), 2 - number) FROM system.numbers LIMIT 3;
[]
[]
[]
SELECT arrayElementOrNull([[1]], 1), arrayElementOrNull(materialize([[1]]), 1), arrayElementOrNull([[1]], materialize(1)), arrayElementOrNull(materialize([[1]]), materialize(1));
[1] [1] [1] [1]
SELECT arrayElementOrNull([['Hello']], 1), arrayElementOrNull(materialize([['World']]), 1), arrayElementOrNull([['Hello']], materialize(1)), arrayElementOrNull(materialize([['World']]), materialize(1));
['Hello'] ['World'] ['Hello'] ['World']
SELECT arrayElementOrNull(([[['a'], ['b', 'c']], [['d', 'e', 'f'], ['g', 'h', 'i', 'j'], ['k', 'l', 'm', 'n', 'o']], [['p', 'q', 'r', 's', 't', 'u'], ['v', 'w', 'x', 'y', 'z', 'aa', 'bb'], ['cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'ii', 'jj'], ['kk', 'll', 'mm', 'nn', 'oo', 'pp', 'qq', 'rr', 'ss']]] AS arr), number), arrayElementOrNull(arr[number], number), arrayElementOrNull(arr[number][number], number) FROM system.numbers LIMIT 10;
[] [] \N
[['a'],['b','c']] ['a'] a
[['d','e','f'],['g','h','i','j'],['k','l','m','n','o']] ['g','h','i','j'] h
[['p','q','r','s','t','u'],['v','w','x','y','z','aa','bb'],['cc','dd','ee','ff','gg','hh','ii','jj'],['kk','ll','mm','nn','oo','pp','qq','rr','ss']] ['cc','dd','ee','ff','gg','hh','ii','jj'] ee
[] [] \N
[] [] \N
[] [] \N
[] [] \N
[] [] \N
[] [] \N
SELECT arrayElementOrNull([1, 2], 3), arrayElementOrNull([1, NULL, 2], 4), arrayElementOrNull([('1', 1), ('2', 2)], -3);
\N \N ('',0)
select groupArray(a) as b, arrayElementOrNull(b, 1), arrayElementOrNull(b, 0) from (select (1, 2) as a);
[(1,2)] (1,2) (0,0)
SELECT [toNullable(1)] AS x, arrayElementOrNull(x, toNullable(1)) AS y;
[1] 1
SELECT materialize([toNullable(1)]) AS x, arrayElementOrNull(x, toNullable(1)) AS y;
[1] 1
SELECT [toNullable(1)] AS x, arrayElementOrNull(x, materialize(toNullable(1))) AS y;
[1] 1
SELECT materialize([toNullable(1)]) AS x, arrayElementOrNull(x, materialize(toNullable(1))) AS y;
[1] 1
select arrayElementOrNull(m, 0), materialize(map('key', 42)) as m; -- {serverError ILLEGAL_TYPE_OF_ARGUMENT}

View File

@ -0,0 +1,67 @@
-- { echoOn }
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(Int32), id Int32) ENGINE = Memory;
insert into array_element_or_null_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], -1), ([11,12], -2), ([11,12], -3), ([11], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(Int32), id UInt32) ENGINE = Memory;
insert into array_element_or_null_test VALUES ([11,12,13], 2), ([11,12], 3), ([11,12,13], 1), ([11,12], 4), ([11], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(String), id Int32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], -1), (['Ab','ber'], -2), (['AB','asd'], -3), (['A'], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (arr Array(String), id UInt32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (['Abc','Df','Q'], 2), (['Abc','DEFQ'], 3), (['ABC','Q','ERT'], 1), (['Ab','ber'], 4), (['A'], 0);
select arrayElementOrNull(arr, id) from array_element_or_null_test;
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (id UInt32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (2), (1), (4), (3), (0);
select [1, 2, 3] as arr, arrayElementOrNull(arr, id) from array_element_or_null_test;
DROP TABLE IF EXISTS array_element_or_null_test;
CREATE TABLE array_element_or_null_test (id Int32) ENGINE = Memory;
insert into array_element_or_null_test VALUES (-2), (1), (-4), (3), (2), (-1), (4), (-3), (0);
select [1, 2, 3] as arr, arrayElementOrNull(arr, id) from array_element_or_null_test;
DROP TABLE array_element_or_null_test;
SELECT arrayElementOrNull(range(0), -1);
SELECT arrayElementOrNull(range(0), 1);
SELECT arrayElementOrNull(range(number), 2) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(range(number), -1) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(range(number), number) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(range(number), 2 - number) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), 2) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), -1) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), number) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> toString(x), range(number)), 2 - number) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), 2) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), -1) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), number) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull(arrayMap(x -> range(x), range(number)), 2 - number) FROM system.numbers LIMIT 3;
SELECT arrayElementOrNull([[1]], 1), arrayElementOrNull(materialize([[1]]), 1), arrayElementOrNull([[1]], materialize(1)), arrayElementOrNull(materialize([[1]]), materialize(1));
SELECT arrayElementOrNull([['Hello']], 1), arrayElementOrNull(materialize([['World']]), 1), arrayElementOrNull([['Hello']], materialize(1)), arrayElementOrNull(materialize([['World']]), materialize(1));
SELECT arrayElementOrNull(([[['a'], ['b', 'c']], [['d', 'e', 'f'], ['g', 'h', 'i', 'j'], ['k', 'l', 'm', 'n', 'o']], [['p', 'q', 'r', 's', 't', 'u'], ['v', 'w', 'x', 'y', 'z', 'aa', 'bb'], ['cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'ii', 'jj'], ['kk', 'll', 'mm', 'nn', 'oo', 'pp', 'qq', 'rr', 'ss']]] AS arr), number), arrayElementOrNull(arr[number], number), arrayElementOrNull(arr[number][number], number) FROM system.numbers LIMIT 10;
SELECT arrayElementOrNull([1, 2], 3), arrayElementOrNull([1, NULL, 2], 4), arrayElementOrNull([('1', 1), ('2', 2)], -3);
select groupArray(a) as b, arrayElementOrNull(b, 1), arrayElementOrNull(b, 0) from (select (1, 2) as a);
SELECT [toNullable(1)] AS x, arrayElementOrNull(x, toNullable(1)) AS y;
SELECT materialize([toNullable(1)]) AS x, arrayElementOrNull(x, toNullable(1)) AS y;
SELECT [toNullable(1)] AS x, arrayElementOrNull(x, materialize(toNullable(1))) AS y;
SELECT materialize([toNullable(1)]) AS x, arrayElementOrNull(x, materialize(toNullable(1))) AS y;
select arrayElementOrNull(m, 0), materialize(map('key', 42)) as m; -- {serverError ILLEGAL_TYPE_OF_ARGUMENT}
-- { echoOff }

View File

@ -0,0 +1,26 @@
...const maps...
\N
2
\N
4
\N
\N
2
\N
4
\N
4
4
...int keys...
foo bar bar
\N foo foo
...string keys...
foo foo
foo foo
foo foo
bar bar
\N
...tuple values...
(1,'foo') (0,'')
...map values...
{1:'foo'} {}

View File

@ -0,0 +1,38 @@
SELECT '...const maps...';
WITH map(1, 2, 3, 4) AS m SELECT arrayElementOrNull(m, number) FROM numbers(5);
WITH map('1', 2, '3', 4) AS m SELECT arrayElementOrNull(m, toString(number)) FROM numbers(5);
WITH map(1, 2, 3, 4) AS m SELECT arrayElementOrNull(m, 3);
WITH map('1', 2, '3', 4) AS m SELECT arrayElementOrNull(m, '3');
DROP TABLE IF EXISTS t_map_03240;
CREATE TABLE t_map_03240(i1 UInt64, i2 Int32, m1 Map(UInt32, String), m2 Map(Int8, String), m3 Map(Int128, String)) ENGINE = Memory;
INSERT INTO t_map_03240 VALUES (1, -1, map(1, 'foo', 2, 'bar'), map(-1, 'foo', 1, 'bar'), map(-1, 'foo', 1, 'bar'));
SELECT '...int keys...';
SELECT arrayElementOrNull(m1, i1), arrayElementOrNull(m2, i1), arrayElementOrNull(m3, i1) FROM t_map_03240;
SELECT arrayElementOrNull(m1, i2), arrayElementOrNull(m2, i2), arrayElementOrNull(m3, i2) FROM t_map_03240;
DROP TABLE IF EXISTS t_map_03240;
CREATE TABLE t_map_03240(s String, fs FixedString(3), m1 Map(String, String), m2 Map(FixedString(3), String)) ENGINE = Memory;
INSERT INTO t_map_03240 VALUES ('aaa', 'bbb', map('aaa', 'foo', 'bbb', 'bar'), map('aaa', 'foo', 'bbb', 'bar'));
SELECT '...string keys...';
SELECT arrayElementOrNull(m1, 'aaa'), arrayElementOrNull(m2, 'aaa') FROM t_map_03240;
SELECT arrayElementOrNull(m1, 'aaa'::FixedString(3)), arrayElementOrNull(m2, 'aaa'::FixedString(3)) FROM t_map_03240;
SELECT arrayElementOrNull(m1, s), arrayElementOrNull(m2, s) FROM t_map_03240;
SELECT arrayElementOrNull(m1, fs), arrayElementOrNull(m2, fs) FROM t_map_03240;
SELECT length(arrayElementOrNull(m2, 'aaa'::FixedString(4))) FROM t_map_03240;
DROP TABLE IF EXISTS t_map_03240;
SELECT '...tuple values...';
with map('a', (1, 'foo')) as m select arrayElementOrNull(m, 'a'), arrayElementOrNull(m, 'c');
SELECT '...map values...';
with map('a', map(1, 'foo')) as m select arrayElementOrNull(m, 'a'), arrayElementOrNull(m, 'c');

View File

@ -1164,6 +1164,7 @@ arrayDifference
arrayDistinct arrayDistinct
arrayDotProduct arrayDotProduct
arrayElement arrayElement
arrayElementOrNull
arrayEnumerate arrayEnumerate
arrayEnumerateDense arrayEnumerateDense
arrayEnumerateDenseRanked arrayEnumerateDenseRanked