Fixed FunctionComparison with special edge case

This commit is contained in:
Maksim Kita 2021-05-08 21:04:21 +03:00
parent 9b405b4c07
commit 2a630b68a4
5 changed files with 50 additions and 12 deletions

View File

@ -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"

View File

@ -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<Op>::equals
|| IsOperation<Op>::less_or_equals
|| IsOperation<Op>::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};

View File

@ -13,6 +13,7 @@
#include <Common/assert_cast.h>
#include <DataTypes/DataTypeNullable.h>
#include <DataTypes/DataTypesNumber.h>
#include <Functions/FunctionsComparison.h>
#include <DataTypes/Native.h>
#include <Functions/IFunctionAdaptors.h>
@ -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<std::string_view> 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();
}

View File

@ -0,0 +1,6 @@
1
1
1
1
1
1

View File

@ -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;