// Copyright 2023 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include #include #include namespace DB::tests { class TestJsonContainsPath : public DB::tests::FunctionTest { public: static constexpr auto func_name = "json_contains_path"; ColumnWithTypeAndName castStringToJson(const ColumnWithTypeAndName & column) { assert(removeNullable(column.type)->isString()); ColumnsWithTypeAndName origin_inputs{column}; return executeFunction("cast_string_as_json", origin_inputs, nullptr, true); } }; TEST_F(TestJsonContainsPath, TestOnlyNull) try { size_t rows_count = 2; ColumnWithTypeAndName json_column = castStringToJson(createColumn>({"[]", "[]"})); auto type_column = createColumn>({"one", "one"}); ColumnWithTypeAndName path_column = createColumn>({"$", "$"}); ColumnWithTypeAndName path_column2 = createColumn>({"$.a", "$.a"}); ColumnWithTypeAndName null_string_const = createConstColumn>(rows_count, {}); ColumnWithTypeAndName null_bool_const = createConstColumn>(rows_count, {}); ColumnWithTypeAndName only_null_const = createOnlyNullColumnConst(rows_count); ASSERT_COLUMN_EQ( createColumn>({true, true}), executeFunction(func_name, json_column, type_column, path_column)); ASSERT_COLUMN_EQ(only_null_const, executeFunction(func_name, only_null_const, type_column, path_column)); ASSERT_COLUMN_EQ(null_bool_const, executeFunction(func_name, null_string_const, type_column, path_column)); ASSERT_COLUMN_EQ(only_null_const, executeFunction(func_name, json_column, only_null_const, path_column)); ASSERT_COLUMN_EQ(null_bool_const, executeFunction(func_name, json_column, null_string_const, path_column)); ASSERT_COLUMN_EQ(only_null_const, executeFunction(func_name, json_column, type_column, only_null_const)); ASSERT_COLUMN_EQ(null_bool_const, executeFunction(func_name, json_column, type_column, null_string_const)); ASSERT_COLUMN_EQ( createColumn>({true, true}), executeFunction(func_name, json_column, type_column, path_column, only_null_const)); ASSERT_COLUMN_EQ( createColumn>({true, true}), executeFunction(func_name, json_column, type_column, path_column, null_string_const)); ASSERT_COLUMN_EQ( createColumn>({{}, {}}), executeFunction(func_name, json_column, type_column, path_column2, only_null_const)); ASSERT_COLUMN_EQ( createColumn>({{}, {}}), executeFunction(func_name, json_column, type_column, path_column2, null_string_const)); ASSERT_COLUMN_EQ( only_null_const, executeFunction(func_name, json_column, type_column, only_null_const, path_column)); ASSERT_COLUMN_EQ( null_bool_const, executeFunction(func_name, json_column, type_column, null_string_const, path_column)); // type and path const. ASSERT_COLUMN_EQ( createColumn>({true, true}), executeFunction( func_name, json_column, createConstColumn(2, "one"), createConstColumn(2, "$"), null_string_const)); ASSERT_COLUMN_EQ( createColumn>({true, true}), executeFunction( func_name, json_column, createConstColumn(2, "one"), createConstColumn(2, "$"), only_null_const)); ASSERT_COLUMN_EQ( null_bool_const, executeFunction( func_name, json_column, createConstColumn(2, "one"), null_string_const, createConstColumn(2, "$"))); ASSERT_COLUMN_EQ( only_null_const, executeFunction( func_name, json_column, createConstColumn(2, "one"), only_null_const, createConstColumn(2, "$"))); } CATCH TEST_F(TestJsonContainsPath, TestNullable) try { ColumnWithTypeAndName json_column = castStringToJson(createColumn>({{}, "[]", "[]", "[]"})); auto type_column = createColumn>({"one", {}, "one", "one"}); ColumnWithTypeAndName path_column = createColumn>({"$", "$", {}, "$"}); ASSERT_COLUMN_EQ( createColumn>({{}, {}, {}, true}), executeFunction(func_name, json_column, type_column, path_column)); } CATCH TEST_F(TestJsonContainsPath, TestNotNull) try { auto exec_assert1 = [&](const String & json, const String & type, const String & path, bool expect) { ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createColumn({type, type}), createColumn({path, path})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createConstColumn(2, json)), createColumn({type, type}), createColumn({path, path})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createConstColumn(2, type), createColumn({path, path})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createColumn({type, type}), createConstColumn(2, path)})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createConstColumn(2, type), createConstColumn(2, path)})); }; auto exec_assert2 = [&](const String & json, const String & type, const String & path1, const String & path2, bool expect) { ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createColumn({type, type}), createColumn({path1, path1}), createColumn({path2, path2})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createColumn({type, type}), createColumn({path1, path1}), createColumn({path2, path2})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createConstColumn(2, json)), createColumn({type, type}), createColumn({path1, path1}), createColumn({path2, path2})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createConstColumn(2, type), createColumn({path1, path1}), createColumn({path2, path2})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createColumn({type, type}), createConstColumn(2, path1), createColumn({path2, path2})})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createColumn({type, type}), createColumn({path1, path1}), createConstColumn(2, path2)})); ASSERT_COLUMN_EQ( createColumn({expect, expect}), executeFunction( func_name, {castStringToJson(createColumn({json, json})), createConstColumn(2, type), createConstColumn(2, path1), createConstColumn(2, path2)})); }; exec_assert1("{}", "one", "$", true); exec_assert1("{}", "one", "$.a", false); exec_assert1("{}", "all", "$", true); exec_assert1("{}", "all", "$.a", false); exec_assert2("{}", "one", "$", "$", true); exec_assert2("{}", "one", "$.a", "$.b", false); exec_assert2("{}", "one", "$", "$.b", true); exec_assert2("{}", "one", "$.a", "$", true); exec_assert2("{}", "all", "$", "$", true); exec_assert2("{}", "all", "$.a", "$.b", false); exec_assert2("{}", "all", "$", "$.b", false); exec_assert2("{}", "all", "$.a", "$", false); exec_assert1("{}", "ONE", "$", true); exec_assert1("{}", "OnE", "$", true); exec_assert1("{}", "oNe", "$", true); exec_assert1("{}", "onE", "$", true); exec_assert1("{}", "One", "$", true); exec_assert1("{}", "ALL", "$", true); exec_assert1("{}", "All", "$", true); exec_assert1("{}", "aLl", "$", true); exec_assert1("{}", "alL", "$", true); exec_assert1("{}", "aLL", "$", true); } CATCH } // namespace DB::tests