Skip to content

Commit

Permalink
Fix JSONExtract function for LowCardinality(Nullable) columns
Browse files Browse the repository at this point in the history
  • Loading branch information
vdimir committed Jan 15, 2024
1 parent 22a0e08 commit 2970812
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/Functions/FunctionsJSON.h
Expand Up @@ -1053,6 +1053,13 @@ struct JSONExtractTree

bool insertResultToColumn(IColumn & dest, const Element & element) override
{
if (dest.getDataType() == TypeIndex::LowCardinality)
{
/// We do not need to handle nullability in that case
/// because nested node handles LowCardinality columns and will call proper overload of `insertData`
return nested->insertResultToColumn(dest, element);
}

ColumnNullable & col_null = assert_cast<ColumnNullable &>(dest);
if (!nested->insertResultToColumn(col_null.getNestedColumn(), element))
return false;
Expand Down
6 changes: 6 additions & 0 deletions tests/queries/0_stateless/00918_json_functions.reference
Expand Up @@ -44,11 +44,14 @@ hello
(-100,200,300)
[-100,0,0]
[-100,NULL,NULL]
[-100,NULL,NULL]
[0,200,0]
[NULL,200,NULL]
[NULL,200,NULL]
-100
200
\N
\N
1
Thursday
Friday
Expand Down Expand Up @@ -209,11 +212,14 @@ hello
(-100,200,300)
[-100,0,0]
[-100,NULL,NULL]
[-100,NULL,NULL]
[0,200,0]
[NULL,200,NULL]
[NULL,200,NULL]
-100
200
\N
\N
1
Thursday
Friday
Expand Down
6 changes: 6 additions & 0 deletions tests/queries/0_stateless/00918_json_functions.sql
Expand Up @@ -56,11 +56,14 @@ SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Float3
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Tuple(Int8, Float32, UInt16)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Int8)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Nullable(Int8))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(LowCardinality(Nullable(Int8)))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(UInt8)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Nullable(UInt8))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(LowCardinality(Nullable(UInt8)))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 1, 'Int8');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 2, 'Int32');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 4, 'Nullable(Int64)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 4, 'LowCardinality(Nullable(Int64))');
SELECT JSONExtract('{"passed": true}', 'passed', 'UInt8');
SELECT JSONExtract('{"day": "Thursday"}', 'day', 'Enum8(\'Sunday\' = 0, \'Monday\' = 1, \'Tuesday\' = 2, \'Wednesday\' = 3, \'Thursday\' = 4, \'Friday\' = 5, \'Saturday\' = 6)');
SELECT JSONExtract('{"day": 5}', 'day', 'Enum8(\'Sunday\' = 0, \'Monday\' = 1, \'Tuesday\' = 2, \'Wednesday\' = 3, \'Thursday\' = 4, \'Friday\' = 5, \'Saturday\' = 6)');
Expand Down Expand Up @@ -241,11 +244,14 @@ SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Float3
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Tuple(Int8, Float32, UInt16)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Int8)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Nullable(Int8))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(LowCardinality(Nullable(Int8)))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(UInt8)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(Nullable(UInt8))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 'Array(LowCardinality(Nullable(UInt8)))');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 1, 'Int8');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 2, 'Int32');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 4, 'Nullable(Int64)');
SELECT JSONExtract('{"a": "hello", "b": [-100, 200.0, 300]}', 'b', 4, 'LowCardinality(Nullable(Int64))');
SELECT JSONExtract('{"passed": true}', 'passed', 'UInt8');
SELECT JSONExtract('{"day": "Thursday"}', 'day', 'Enum8(\'Sunday\' = 0, \'Monday\' = 1, \'Tuesday\' = 2, \'Wednesday\' = 3, \'Thursday\' = 4, \'Friday\' = 5, \'Saturday\' = 6)');
SELECT JSONExtract('{"day": 5}', 'day', 'Enum8(\'Sunday\' = 0, \'Monday\' = 1, \'Tuesday\' = 2, \'Wednesday\' = 3, \'Thursday\' = 4, \'Friday\' = 5, \'Saturday\' = 6)');
Expand Down
@@ -1,5 +1,6 @@
('123','456','[7,8,9]')
\N
\N
123
123

Expand Up @@ -2,6 +2,7 @@
select JSONExtract('{"a": "123", "b": 456, "c": [7, 8, 9]}', 'Tuple(a String, b String, c String)');

with '{"string_value":null}' as json select JSONExtract(json, 'string_value', 'Nullable(String)');
with '{"string_value":null}' as json select JSONExtract(json, 'string_value', 'LowCardinality(Nullable(String))');

select JSONExtractString('{"a": 123}', 'a');
select JSONExtractString('{"a": "123"}', 'a');
Expand Down
@@ -1,9 +1,11 @@
\N Nullable(String)
\N LowCardinality(Nullable(String))
String
\N Nullable(String)
Nullable(String)
\N Nullable(Nothing)
\N Nullable(Nothing)
\N Nullable(Nothing)
b
\N

Expand All @@ -21,3 +23,6 @@ true
a
\N
\N
('value')
(NULL)
(NULL)
8 changes: 8 additions & 0 deletions tests/queries/0_stateless/02013_json_function_null_column.sql
@@ -1,16 +1,20 @@

SELECT JSONExtract('{"string_value":null}', 'string_value', 'Nullable(String)') as x, toTypeName(x);
SELECT JSONExtract('{"string_value":null}', 'string_value', 'LowCardinality(Nullable(String))') as x, toTypeName(x);
SELECT JSONExtract('{"string_value":null}', 'string_value', 'String') as x, toTypeName(x);
SELECT JSONExtract(toNullable('{"string_value":null}'), 'string_value', 'Nullable(String)') as x, toTypeName(x);
SELECT JSONExtract(toNullable('{"string_value":null}'), 'string_value', 'LowCardinality(Nullable(String))') as x, toTypeName(x); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT JSONExtract(toNullable('{"string_value":null}'), 'string_value', 'String') as x, toTypeName(x);
SELECT JSONExtract(NULL, 'string_value', 'Nullable(String)') as x, toTypeName(x);
SELECT JSONExtract(NULL, 'string_value', 'LowCardinality(Nullable(String))') as x, toTypeName(x);
SELECT JSONExtract(NULL, 'string_value', 'String') as x, toTypeName(x);
SELECT JSONExtractString('["a", "b", "c", "d", "e"]', idx) FROM (SELECT arrayJoin([2, NULL, 2147483646, 65535, 65535, 3]) AS idx);

SELECT JSONExtractInt('[1]', toNullable(1));
SELECT JSONExtractBool('[1]', toNullable(1));
SELECT JSONExtractFloat('[1]', toNullable(1));
SELECT JSONExtractString('["a"]', toNullable(1));
SELECT JSONExtractInt('[1]', toLowCardinality(toNullable(1))); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }

SELECT JSONExtractArrayRaw('["1"]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
SELECT JSONExtractKeysAndValuesRaw('["1"]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
Expand All @@ -23,3 +27,7 @@ SELECT JSONExtract('[1]', toNullable(1), 'Nullable(Float)');
SELECT JSONExtract('["a"]', toNullable(1), 'Nullable(String)');
SELECT JSONExtract('["a"]', toNullable(1), 'Nullable(Int)');
SELECT JSONExtract('["-a"]', toNullable(1), 'Nullable(Int)');

SELECT JSONExtract(materialize('{"key":"value"}'), 'Tuple(key LowCardinality(Nullable(String)))');
SELECT JSONExtract(materialize('{"key":null}'), 'Tuple(key LowCardinality(Nullable(String)))');
SELECT JSONExtract(materialize('{"not_a_key":"value"}'), 'Tuple(key LowCardinality(Nullable(String)))');

0 comments on commit 2970812

Please sign in to comment.