diff --git a/docker/test/fasttest/run.sh b/docker/test/fasttest/run.sh index ec70911d822..d639443c5bc 100755 --- a/docker/test/fasttest/run.sh +++ b/docker/test/fasttest/run.sh @@ -373,6 +373,7 @@ function run_tests # Depents on LLVM JIT 01852_jit_if + 01865_jit_comparison_constant_result ) (time clickhouse-test --hung-check -j 8 --order=random --use-skip-list --no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" -- "$FASTTEST_FOCUS" 2>&1 ||:) | ts '%Y-%m-%d %H:%M:%S' | tee "$FASTTEST_OUTPUT/test_log.txt" diff --git a/src/Functions/FunctionsComparison.h b/src/Functions/FunctionsComparison.h index 0900e094f2a..f724915b3bc 100644 --- a/src/Functions/FunctionsComparison.h +++ b/src/Functions/FunctionsComparison.h @@ -1148,27 +1148,17 @@ public: /// NOTE: We consider NaN comparison to be implementation specific (and in our implementation NaNs are sometimes equal sometimes not). if (left_type->equals(*right_type) && !left_type->isNullable() && !isTuple(left_type) && col_left_untyped == col_right_untyped) { - bool constant_arguments = isColumnConst(*col_left_untyped); - - ColumnPtr result_column; - /// Always true: =, <=, >= if constexpr (IsOperation::equals || IsOperation::less_or_equals || IsOperation::greater_or_equals) { - result_column = DataTypeUInt8().createColumnConst(input_rows_count, 1u); + return DataTypeUInt8().createColumnConst(input_rows_count, 1u); } else { - result_column = result_type->createColumnConst(input_rows_count, 1u); + return DataTypeUInt8().createColumnConst(input_rows_count, 0u); } - - /// We avoid returning constant result for non constant arguments - if (!constant_arguments) - result_column = result_column->convertToFullColumnIfConst(); - - return result_column; } WhichDataType which_left{left_type}; diff --git a/src/Interpreters/ExpressionJIT.cpp b/src/Interpreters/ExpressionJIT.cpp index 5d1c3578fbb..9564437f72e 100644 --- a/src/Interpreters/ExpressionJIT.cpp +++ b/src/Interpreters/ExpressionJIT.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -314,6 +315,28 @@ static bool isCompilableConstant(const ActionsDAG::Node & node) return node.column && isColumnConst(*node.column) && canBeNativeType(*node.result_type) && node.allow_constant_folding; } +static bool checkIfFunctionIsComparisonEdgeCase(const ActionsDAG::Node & node, const IFunctionBase & impl) +{ + static std::unordered_set comparison_functions + { + NameEquals::name, + NameNotEquals::name, + NameLess::name, + NameGreater::name, + NameLessOrEquals::name, + NameGreaterOrEquals::name + }; + + auto it = comparison_functions.find(impl.getName()); + if (it == comparison_functions.end()) + return false; + + const auto * lhs_node = node.children[0]; + const auto * rhs_node = node.children[1]; + + return lhs_node == rhs_node && !isTuple(lhs_node->result_type); +} + static bool isCompilableFunction(const ActionsDAG::Node & node) { if (node.type != ActionsDAG::ActionType::FUNCTION) @@ -330,6 +353,9 @@ static bool isCompilableFunction(const ActionsDAG::Node & node) return false; } + if (checkIfFunctionIsComparisonEdgeCase(node, *node.function_base)) + return false; + return function.isCompilable(); } diff --git a/tests/queries/0_stateless/01855_jit_comparison_constant_result.reference b/tests/queries/0_stateless/01855_jit_comparison_constant_result.reference new file mode 100644 index 00000000000..a9e2f17562a --- /dev/null +++ b/tests/queries/0_stateless/01855_jit_comparison_constant_result.reference @@ -0,0 +1,6 @@ +1 +1 +1 +1 +1 +1 diff --git a/tests/queries/0_stateless/01855_jit_comparison_constant_result.sql b/tests/queries/0_stateless/01855_jit_comparison_constant_result.sql new file mode 100644 index 00000000000..b8d06e218e0 --- /dev/null +++ b/tests/queries/0_stateless/01855_jit_comparison_constant_result.sql @@ -0,0 +1,15 @@ +SET compile_expressions = 1; +SET min_count_to_compile_expression = 0; + +DROP TABLE IF EXISTS test_table; +CREATE TABLE test_table (a UInt64) ENGINE = MergeTree() ORDER BY tuple(); +INSERT INTO test_table VALUES (1); + +SELECT test_table.a FROM test_table ORDER BY (test_table.a > test_table.a) + 1; +SELECT test_table.a FROM test_table ORDER BY (test_table.a >= test_table.a) + 1; + +SELECT test_table.a FROM test_table ORDER BY (test_table.a < test_table.a) + 1; +SELECT test_table.a FROM test_table ORDER BY (test_table.a <= test_table.a) + 1; + +SELECT test_table.a FROM test_table ORDER BY (test_table.a == test_table.a) + 1; +SELECT test_table.a FROM test_table ORDER BY (test_table.a != test_table.a) + 1;