diff --git a/src/Analyzer/Passes/ConvertInToEqualPass.cpp b/src/Analyzer/Passes/ConvertInToEqualPass.cpp index b204d2fb9224..2f7372637242 100644 --- a/src/Analyzer/Passes/ConvertInToEqualPass.cpp +++ b/src/Analyzer/Passes/ConvertInToEqualPass.cpp @@ -21,6 +21,8 @@ class ConvertInToEqualPassVisitor : public InDepthQueryTreeVisitorWithContextas(); if (!func_node || !MAPPING.contains(func_node->getFunctionName()) @@ -39,11 +41,11 @@ class ConvertInToEqualPassVisitor : public InDepthQueryTreeVisitorWithContextgetValue().isNull()) return ; auto result_func_name = MAPPING.at(func_node->getFunctionName()); - auto equal = std::make_shared(result_func_name); - auto new_const = std::make_shared(constant_node->getValue(), removeNullable(constant_node->getResultType())); + auto replace_node = std::make_shared(result_func_name); + auto new_const = std::make_shared(constant_node->getValue(), removeNullableOrLowCardinalityNullable(constant_node->getResultType())); new_const->getSourceExpression() = constant_node->getSourceExpression(); QueryTreeNodes arguments{column_node->clone(), new_const}; - equal->getArguments().getNodes() = std::move(arguments); + replace_node->getArguments().getNodes() = std::move(arguments); FunctionOverloadResolverPtr resolver; bool decimal_check_overflow = getContext()->getSettingsRef().decimal_check_overflow; if (result_func_name == "equals") @@ -56,14 +58,16 @@ class ConvertInToEqualPassVisitor : public InDepthQueryTreeVisitorWithContextresolveAsFunction(resolver); + replace_node->resolveAsFunction(resolver); } catch (...) { // When function resolver fails, we should not replace the function node return; } - node = equal; + // check if the result type of the new function is the same as the old one + if (replace_node->getResultType()->equals(*func_node->getResultType())) + node = replace_node; } }; diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 84e709294aaf..f9faeb2aed6d 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -599,7 +599,8 @@ class IColumn; M(Bool, optimize_arithmetic_operations_in_aggregate_functions, true, "Move arithmetic operations out of aggregation functions", 0) \ M(Bool, optimize_redundant_functions_in_order_by, true, "Remove functions from ORDER BY if its argument is also in ORDER BY", 0) \ M(Bool, optimize_if_chain_to_multiif, false, "Replace if(cond1, then1, if(cond2, ...)) chains to multiIf. Currently it's not beneficial for numeric types.", 0) \ - M(Bool, optimize_multiif_to_if, true, "Replace 'multiIf' with only one condition to 'if'.", 0) \ + M(Bool, optimize_multiif_to_if, true, "Replace 'multiIf' with only one condition to 'if'.", 0) \ + M(Bool, optimize_in_single_value, true, "Replace in to equals when in single value", 0) \ M(Bool, optimize_if_transform_strings_to_enum, false, "Replaces string-type arguments in If and Transform to enum. Disabled by default cause it could make inconsistent change in distributed query that would lead to its fail.", 0) \ M(Bool, optimize_monotonous_functions_in_order_by, false, "Replace monotonous function with its argument in ORDER BY", 0) \ M(Bool, optimize_functions_to_subcolumns, false, "Transform functions to subcolumns, if possible, to reduce amount of read data. E.g. 'length(arr)' -> 'arr.size0', 'col IS NULL' -> 'col.null' ", 0) \ diff --git a/src/Core/SettingsChangesHistory.h b/src/Core/SettingsChangesHistory.h index 768b6aa6cbdf..8c5c26929ed1 100644 --- a/src/Core/SettingsChangesHistory.h +++ b/src/Core/SettingsChangesHistory.h @@ -86,6 +86,7 @@ namespace SettingsChangesHistory static std::map settings_changes_history = { {"24.4", {{"input_format_json_throw_on_bad_escape_sequence", true, true, "Allow to save JSON strings with bad escape sequences"}, + {"optimize_in_single_value", false, true, "Optimize in single value, convert in to equals."} }}, {"24.3", {{"s3_connect_timeout_ms", 1000, 1000, "Introduce new dedicated setting for s3 connection timeout"}, {"allow_experimental_shared_merge_tree", false, true, "The setting is obsolete"}, diff --git a/tests/queries/0_stateless/03013_optimize_in_to_equal.sql b/tests/queries/0_stateless/03013_optimize_in_to_equal.sql index e0eaa84cb8d7..86d253bbf835 100644 --- a/tests/queries/0_stateless/03013_optimize_in_to_equal.sql +++ b/tests/queries/0_stateless/03013_optimize_in_to_equal.sql @@ -30,3 +30,4 @@ explain query tree select * from test where x in (NULL); select '-------------------'; --- fuzzed SELECT number FROM numbers(2) WHERE arrayExists(_ -> (_ IN toNullable(4294967290)), [number]); +select 1 from test where (x in concat('/clickhouse/', toLowCardinality(12), currentDatabase(), toNullable('/01700_system_zookeeper_path_in/'), 32)) AND (x LIKE 'block%') settings allow_experimental_analyzer=1;