mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Forbid Nullable for JSONExtract* (JSONExtract() still supports Nullable)
Only JSONExtract() can support Nullable, others JSONExtract* (JSONExtractString and similar) does not. And right now this file is pretty complex already, so adding support of Nullable for others will make it even more complex. CI: https://clickhouse-test-reports.s3.yandex.net/29680/d0fc26f91a0141b56a0550741219c3dc43630e03/fuzzer_ubsan/report.html#fail1
This commit is contained in:
parent
613b814e24
commit
20e706766c
@ -304,19 +304,32 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template <class Parser>
|
||||
ColumnPtr
|
||||
chooseAndRunJSONParserOne(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
|
||||
{
|
||||
/// Only implementations with prepare() can handle NULL.
|
||||
///
|
||||
/// (and right now this file is pretty complex already, and adding
|
||||
/// support of Nullable for others will make it even more complex)
|
||||
if (null_presence.has_nullable && !Impl<Parser>::supportNullable())
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "{} does not support Nullable", Name::name);
|
||||
|
||||
return FunctionJSONHelpers::Executor<Name, Impl, Parser>::run(arguments, result_type, input_rows_count);
|
||||
}
|
||||
|
||||
ColumnPtr
|
||||
chooseAndRunJSONParser(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const
|
||||
{
|
||||
#if USE_SIMDJSON
|
||||
if (allow_simdjson)
|
||||
return FunctionJSONHelpers::Executor<Name, Impl, SimdJSONParser>::run(arguments, result_type, input_rows_count);
|
||||
return chooseAndRunJSONParserOne<SimdJSONParser>(arguments, result_type, input_rows_count);
|
||||
#endif
|
||||
|
||||
#if USE_RAPIDJSON
|
||||
return FunctionJSONHelpers::Executor<Name, Impl, RapidJSONParser>::run(arguments, result_type, input_rows_count);
|
||||
return chooseAndRunJSONParserOne<RapidJSONParser>(arguments, result_type, input_rows_count);
|
||||
#else
|
||||
return FunctionJSONHelpers::Executor<Name, Impl, DummyJSONParser>::run(arguments, result_type, input_rows_count);
|
||||
return chooseAndRunJSONParserOne<DummyJSONParser>(arguments, result_type, input_rows_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -433,6 +446,7 @@ public:
|
||||
static DataTypePtr getReturnType(const char *, const ColumnsWithTypeAndName &) { return std::make_shared<DataTypeUInt8>(); }
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view &)
|
||||
{
|
||||
@ -461,6 +475,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName &) { return 0; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view &)
|
||||
{
|
||||
@ -485,6 +500,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
@ -515,6 +531,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element &, const std::string_view & last_key)
|
||||
{
|
||||
@ -549,6 +566,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
@ -591,6 +609,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
@ -666,6 +685,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
@ -691,6 +711,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
@ -1090,6 +1111,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 2; }
|
||||
static bool supportNullable() { return true; }
|
||||
|
||||
void prepare(const char * function_name, const ColumnsWithTypeAndName &, const DataTypePtr & result_type)
|
||||
{
|
||||
@ -1131,6 +1153,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 2; }
|
||||
static bool supportNullable() { return true; }
|
||||
|
||||
void prepare(const char * function_name, const ColumnsWithTypeAndName &, const DataTypePtr & result_type)
|
||||
{
|
||||
@ -1182,6 +1205,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
@ -1286,6 +1310,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
static bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
@ -1318,6 +1343,7 @@ public:
|
||||
}
|
||||
|
||||
static size_t getNumberOfIndexArguments(const ColumnsWithTypeAndName & arguments) { return arguments.size() - 1; }
|
||||
static bool supportNullable() { return false; }
|
||||
|
||||
bool insertResultToColumn(IColumn & dest, const Element & element, const std::string_view &)
|
||||
{
|
||||
|
19
tests/queries/0_stateless/02045_json_extract_null.reference
Normal file
19
tests/queries/0_stateless/02045_json_extract_null.reference
Normal file
@ -0,0 +1,19 @@
|
||||
-- { echoOn }
|
||||
SELECT JSONExtractInt('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractUInt('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractBool('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractFloat('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractString('["a"]', 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 }
|
||||
SELECT JSONExtractKeysAndValues('["1"]', toNullable(1)); -- { serverError ILLEGAL_COLUMN }
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(Int)');
|
||||
1
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(UInt8)');
|
||||
1
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(Bool)');
|
||||
1
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(Float)');
|
||||
1
|
||||
SELECT JSONExtract('["a"]', toNullable(1), 'Nullable(String)');
|
||||
a
|
21
tests/queries/0_stateless/02045_json_extract_null.sql
Normal file
21
tests/queries/0_stateless/02045_json_extract_null.sql
Normal file
@ -0,0 +1,21 @@
|
||||
-- Tags: no-fasttest
|
||||
|
||||
-- to avoid merging Tags and echoOn
|
||||
SELECT 1 FORMAT Null;
|
||||
|
||||
-- { echoOn }
|
||||
SELECT JSONExtractInt('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractUInt('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractBool('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractFloat('[1]', toNullable(1)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT JSONExtractString('["a"]', 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 }
|
||||
SELECT JSONExtractKeysAndValues('["1"]', toNullable(1)); -- { serverError ILLEGAL_COLUMN }
|
||||
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(Int)');
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(UInt8)');
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(Bool)');
|
||||
SELECT JSONExtract('[1]', toNullable(1), 'Nullable(Float)');
|
||||
SELECT JSONExtract('["a"]', toNullable(1), 'Nullable(String)');
|
Loading…
Reference in New Issue
Block a user