From 77cf321a732709922daaf06579fd97a4c584b46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=9E=E6=96=87=E7=8F=91?= Date: Fri, 20 Sep 2024 03:52:55 +0000 Subject: [PATCH] Merge 'cp_405852314724db75147aea7bee4be0e2bb24a900_cnch-dev' into 'cnch-dev' fix(clickhousech@m-3000759214):fix json function parse lc null return value See merge request: !25198 --- src/Functions/FunctionsJSON.h | 15 ++++++++++++++- .../12294_function_get_json_object.reference | 2 ++ .../12294_function_get_json_object.sql | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Functions/FunctionsJSON.h b/src/Functions/FunctionsJSON.h index 074715c792..7a05639b44 100644 --- a/src/Functions/FunctionsJSON.h +++ b/src/Functions/FunctionsJSON.h @@ -114,7 +114,7 @@ public: throw Exception{"The first argument of function " + String(Name::name) + " should be a string containing JSON, illegal type: " + first_column.type->getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; - const ColumnPtr & arg_json = recursiveAssumeNotNullable(first_column.column); + const ColumnPtr & arg_json = recursiveAssumeNotNullable(recursiveRemoveLowCardinality(first_column.column)); const auto * col_json_const = typeid_cast(arg_json.get()); const auto * col_json_string = typeid_cast(col_json_const ? col_json_const->getDataColumnPtr().get() : arg_json.get()); @@ -510,9 +510,11 @@ public: String getName() const override { return Name::name; } bool useDefaultImplementationForNulls() const override { return false; } bool useDefaultImplementationForConstants() const override { return true; } + // bool useDefaultImplementationForLowCardinalityColumns() const override { return false; } ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override { + NullPresence lc_null_presence = getNullPresense(arguments); if (null_presence.has_null_constant) return result_type->createColumnConstWithDefaultValue(input_rows_count); @@ -520,6 +522,10 @@ public: auto temporary_result = Derived::run(temp_arguments, json_return_type, input_rows_count); if (null_presence.has_nullable) return wrapInNullable(temporary_result, arguments, result_type, input_rows_count); + + if (lc_null_presence.has_nullable) + return wrapInNullable(temporary_result, arguments, result_type, input_rows_count); + return temporary_result; } @@ -750,6 +756,7 @@ public: bool isVariadic() const override { return true; } size_t getNumberOfArguments() const override { return 0; } bool useDefaultImplementationForNulls() const override { return false; } + // bool useDefaultImplementationForLowCardinalityColumns() const override { return false; } FunctionBasePtr build(const ColumnsWithTypeAndName & arguments) const override { @@ -763,6 +770,8 @@ public: const auto & first_column = arguments[0]; auto first_type_base = removeNullable(removeLowCardinality(first_column.type)); + auto first_type_is_lc_null = first_column.type->isLowCardinalityNullable(); + auto first_type_is_lc = WhichDataType(first_column.type).isLowCardinality(); bool is_string = isString(first_type_base); bool is_object = isObject(first_type_base); @@ -783,6 +792,10 @@ public: return_type = makeNullable(std::make_shared()); else if (null_presence.has_nullable) return_type = makeNullable(json_return_type); + else if (first_type_is_lc_null) + return_type = std::make_shared(makeNullable(json_return_type)); + else if (first_type_is_lc) + return_type = std::make_shared(json_return_type); else return_type = json_return_type; diff --git a/tests/queries/4_cnch_stateless/12294_function_get_json_object.reference b/tests/queries/4_cnch_stateless/12294_function_get_json_object.reference index 95f7c49aa6..48a2ffd9e0 100644 --- a/tests/queries/4_cnch_stateless/12294_function_get_json_object.reference +++ b/tests/queries/4_cnch_stateless/12294_function_get_json_object.reference @@ -6,6 +6,8 @@ abc [{"ac":"abc","xz":"xz"},{"def":"def"}] 100 100 +\N +\N {"a":"b"} 2017-08-31 18:36:48 -1 1504193808 ["a","c"] 1504193808 diff --git a/tests/queries/4_cnch_stateless/12294_function_get_json_object.sql b/tests/queries/4_cnch_stateless/12294_function_get_json_object.sql index d19dc4c4a8..08a68c8e4c 100644 --- a/tests/queries/4_cnch_stateless/12294_function_get_json_object.sql +++ b/tests/queries/4_cnch_stateless/12294_function_get_json_object.sql @@ -8,6 +8,9 @@ SELECT JSONExtractRaw('{"n_s" : [{"ac":"abc","xz":"xz"}, {"def":"def"}], "n_i" : select get_json_object('{"a":100}'::Nullable(String), '$.a'); select get_json_object('{"a":100}'::LowCardinality(Nullable(String)), '$.a'); +select get_json_object(null::Nullable(String), '$.a'); +select get_json_object(null::LowCardinality(Nullable(String)), '$.a'); + DROP TABLE IF EXISTS test; CREATE TABLE test(a Nullable(String)) ENGINE = CnchMergeTree ORDER BY tuple() PARTITION BY tuple(); SELECT get_json_object('{"test": "test"}', a) FROM test;