Fix nullable processing in JSONFunctions

This commit is contained in:
Amos Bird 2021-10-02 12:20:56 +08:00
parent a391b64f57
commit a34a08268b
No known key found for this signature in database
GPG Key ID: 80D430DCBECFEDB4
3 changed files with 27 additions and 9 deletions

View File

@ -282,8 +282,8 @@ class ExecutableFunctionJSON : public IExecutableFunction, WithContext
{
public:
explicit ExecutableFunctionJSON(const NullPresence & null_presence_, bool allow_simdjson_)
: null_presence(null_presence_), allow_simdjson(allow_simdjson_)
explicit ExecutableFunctionJSON(const NullPresence & null_presence_, bool allow_simdjson_, const DataTypePtr & json_return_type_)
: null_presence(null_presence_), allow_simdjson(allow_simdjson_), json_return_type(json_return_type_)
{
}
@ -297,7 +297,7 @@ public:
return result_type->createColumnConstWithDefaultValue(input_rows_count);
ColumnsWithTypeAndName temporary_columns = null_presence.has_nullable ? createBlockWithNestedColumns(arguments) : arguments;
ColumnPtr temporary_result = chooseAndRunJSONParser(temporary_columns, result_type, input_rows_count);
ColumnPtr temporary_result = chooseAndRunJSONParser(temporary_columns, json_return_type, input_rows_count);
if (null_presence.has_nullable)
return wrapInNullable(temporary_result, arguments, result_type, input_rows_count);
return temporary_result;
@ -322,6 +322,7 @@ private:
NullPresence null_presence;
bool allow_simdjson;
DataTypePtr json_return_type;
};
@ -330,11 +331,16 @@ class FunctionBaseFunctionJSON : public IFunctionBase
{
public:
explicit FunctionBaseFunctionJSON(
const NullPresence & null_presence_, bool allow_simdjson_, DataTypes argument_types_, DataTypePtr return_type_)
const NullPresence & null_presence_,
bool allow_simdjson_,
DataTypes argument_types_,
DataTypePtr return_type_,
DataTypePtr json_return_type_)
: null_presence(null_presence_)
, allow_simdjson(allow_simdjson_)
, argument_types(std::move(argument_types_))
, return_type(std::move(return_type_))
, json_return_type(std::move(json_return_type_))
{
}
@ -354,7 +360,7 @@ public:
ExecutableFunctionPtr prepare(const ColumnsWithTypeAndName &) const override
{
return std::make_unique<ExecutableFunctionJSON<Name, Impl>>(null_presence, allow_simdjson);
return std::make_unique<ExecutableFunctionJSON<Name, Impl>>(null_presence, allow_simdjson, json_return_type);
}
private:
@ -362,6 +368,7 @@ private:
bool allow_simdjson;
DataTypes argument_types;
DataTypePtr return_type;
DataTypePtr json_return_type;
};
@ -388,21 +395,25 @@ public:
FunctionBasePtr build(const ColumnsWithTypeAndName & arguments) const override
{
DataTypePtr json_return_type = Impl<DummyJSONParser>::getReturnType(Name::name, createBlockWithNestedColumns(arguments));
NullPresence null_presence = getNullPresense(arguments);
DataTypePtr return_type;
if (null_presence.has_null_constant)
return_type = makeNullable(std::make_shared<DataTypeNothing>());
else if (null_presence.has_nullable)
return_type = makeNullable(Impl<DummyJSONParser>::getReturnType(Name::name, createBlockWithNestedColumns(arguments)));
return_type = makeNullable(json_return_type);
else
return_type = Impl<DummyJSONParser>::getReturnType(Name::name, arguments);
return_type = json_return_type;
/// Top-level LowCardinality columns are processed outside JSON parser.
json_return_type = removeLowCardinality(json_return_type);
DataTypes argument_types;
argument_types.reserve(arguments.size());
for (const auto & argument : arguments)
argument_types.emplace_back(argument.type);
return std::make_unique<FunctionBaseFunctionJSON<Name, Impl>>(
null_presence, getContext()->getSettingsRef().allow_simdjson, argument_types, return_type);
null_presence, getContext()->getSettingsRef().allow_simdjson, argument_types, return_type, json_return_type);
}
};

View File

@ -1,6 +1,12 @@
\N Nullable(String)
String
\N Nullable(String)
\N Nullable(String)
Nullable(String)
\N Nullable(Nothing)
\N Nullable(Nothing)
b
\N
c

View File

@ -6,3 +6,4 @@ SELECT JSONExtract(toNullable('{"string_value":null}'), 'string_value', 'Nullabl
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', 'String') as x, toTypeName(x);
SELECT JSONExtractString('["a", "b", "c", "d", "e"]', idx) FROM (SELECT arrayJoin([2, NULL, 2147483646, 65535, 65535, 3]) AS idx);