Another fix

This commit is contained in:
Amos Bird 2021-04-20 14:15:28 +08:00
parent aeff06d67d
commit d5f606c544
No known key found for this signature in database
GPG Key ID: 80D430DCBECFEDB4
3 changed files with 39 additions and 23 deletions

View File

@ -609,8 +609,8 @@ bool KeyCondition::canConstantBeWrappedByMonotonicFunctions(
bool found_transformation = false;
auto input_column = sample_block.getByName(expr_name);
auto const_column = out_type->createColumnConst(1, out_value);
out_value = (*castColumn({const_column, out_type, "c"}, input_column.type))[0];
out_type = input_column.type;
auto const_value = (*castColumn({const_column, out_type, "c"}, input_column.type))[0];
auto const_type = input_column.type;
for (const auto & action : key_expr->getActions())
{
/** The key functional expression constraint may be inferred from a plain column in the expression.
@ -632,14 +632,14 @@ bool KeyCondition::canConstantBeWrappedByMonotonicFunctions(
return false;
/// Range is irrelevant in this case.
IFunction::Monotonicity monotonicity = action.node->function_base->getMonotonicityForRange(*out_type, Field(), Field());
IFunction::Monotonicity monotonicity = action.node->function_base->getMonotonicityForRange(*const_type, Field(), Field());
if (!monotonicity.is_always_monotonic)
return false;
/// Apply the next transformation step.
std::tie(out_value, out_type) = applyFunctionForFieldOfUnknownType(
std::tie(const_value, const_type) = applyFunctionForFieldOfUnknownType(
action.node->function_builder,
out_type, out_value);
const_type, const_value);
expr_name = action.node->result_name;
@ -649,6 +649,8 @@ bool KeyCondition::canConstantBeWrappedByMonotonicFunctions(
{
out_key_column_num = it->second;
out_key_column_type = sample_block.getByName(it->first).type;
out_value = const_value;
out_type = const_type;
found_transformation = true;
break;
}
@ -719,12 +721,10 @@ bool KeyCondition::canConstantBeWrappedByFunctions(
if (is_valid_chain)
{
{
auto input_column = sample_block.getByName(expr_name);
auto const_column = out_type->createColumnConst(1, out_value);
out_value = (*castColumn({const_column, out_type, "c"}, input_column.type))[0];
out_type = input_column.type;
}
auto input_column = sample_block.getByName(expr_name);
auto const_column = out_type->createColumnConst(1, out_value);
auto const_value = (*castColumn({const_column, out_type, "c"}, input_column.type))[0];
auto const_type = input_column.type;
while (!chain.empty())
{
@ -736,7 +736,7 @@ bool KeyCondition::canConstantBeWrappedByFunctions(
if (func->children.size() == 1)
{
std::tie(out_value, out_type) = applyFunctionForFieldOfUnknownType(func->function_builder, out_type, out_value);
std::tie(const_value, const_type) = applyFunctionForFieldOfUnknownType(func->function_builder, const_type, const_value);
}
else if (func->children.size() == 2)
{
@ -746,21 +746,23 @@ bool KeyCondition::canConstantBeWrappedByFunctions(
{
auto left_arg_type = left->result_type;
auto left_arg_value = (*left->column)[0];
std::tie(out_value, out_type) = applyBinaryFunctionForFieldOfUnknownType(
func->function_builder, left_arg_type, left_arg_value, out_type, out_value);
std::tie(const_value, const_type) = applyBinaryFunctionForFieldOfUnknownType(
func->function_builder, left_arg_type, left_arg_value, const_type, const_value);
}
else
{
auto right_arg_type = right->result_type;
auto right_arg_value = (*right->column)[0];
std::tie(out_value, out_type) = applyBinaryFunctionForFieldOfUnknownType(
func->function_builder, out_type, out_value, right_arg_type, right_arg_value);
std::tie(const_value, const_type) = applyBinaryFunctionForFieldOfUnknownType(
func->function_builder, const_type, const_value, right_arg_type, right_arg_value);
}
}
}
out_key_column_num = it->second;
out_key_column_type = sample_block.getByName(it->first).type;
out_value = const_value;
out_type = const_type;
return true;
}
}
@ -1103,13 +1105,13 @@ bool KeyCondition::tryParseAtomFromAST(const ASTPtr & node, ContextPtr context,
///
/// toDate(DateTime) is always monotonic, but we cannot relaxing the predicates to be
/// >= toDate(toDateTime('2020-09-01 10:00:00')), which returns 3 instead of the right count: 2.
bool strict_ = strict;
bool strict_condition = strict;
/// If we are using this key condition to prune partitions by single value, we cannot relax conditions for NOT.
/// If we use this key condition to prune partitions by single value, we cannot relax conditions for NOT.
if (single_point
&& (func_name == "notLike" || func_name == "notIn" || func_name == "globalNotIn" || func_name == "notEquals"
|| func_name == "notEmpty"))
strict_ = true;
strict_condition = true;
if (functionIsInOrGlobalInOperator(func_name))
{
@ -1127,13 +1129,15 @@ bool KeyCondition::tryParseAtomFromAST(const ASTPtr & node, ContextPtr context,
{
key_arg_pos = 0;
}
else if (!strict_ && canConstantBeWrappedByMonotonicFunctions(args[0], key_column_num, key_expr_type, const_value, const_type))
else if (
!strict_condition
&& canConstantBeWrappedByMonotonicFunctions(args[0], key_column_num, key_expr_type, const_value, const_type))
{
key_arg_pos = 0;
is_constant_transformed = true;
}
else if (
single_point && func_name == "equals" && !strict_
single_point && func_name == "equals" && !strict_condition
&& canConstantBeWrappedByFunctions(args[0], key_column_num, key_expr_type, const_value, const_type))
{
key_arg_pos = 0;
@ -1148,13 +1152,15 @@ bool KeyCondition::tryParseAtomFromAST(const ASTPtr & node, ContextPtr context,
{
key_arg_pos = 1;
}
else if (!strict_ && canConstantBeWrappedByMonotonicFunctions(args[1], key_column_num, key_expr_type, const_value, const_type))
else if (
!strict_condition
&& canConstantBeWrappedByMonotonicFunctions(args[1], key_column_num, key_expr_type, const_value, const_type))
{
key_arg_pos = 1;
is_constant_transformed = true;
}
else if (
single_point && func_name == "equals" && !strict_
single_point && func_name == "equals" && !strict_condition
&& canConstantBeWrappedByFunctions(args[1], key_column_num, key_expr_type, const_value, const_type))
{
key_arg_pos = 0;

View File

@ -3,3 +3,4 @@
8 4
1 2 3
2020-01-02 1
2021-01-02 2

View File

@ -38,3 +38,12 @@ insert into test values ('2020-01-02', 1, '');
select * from test where d != '2020-01-01';
drop table test;
-- Test if single value partition pruning works correctly for Date = String
drop table if exists myTable;
CREATE TABLE myTable (myDay Date, myOrder Int32, someData String) ENGINE = ReplacingMergeTree PARTITION BY floor(toYYYYMMDD(myDay), -1) ORDER BY (myOrder);
INSERT INTO myTable (myDay, myOrder) VALUES ('2021-01-01', 1);
INSERT INTO myTable (myDay, myOrder) VALUES ('2021-01-02', 2); // This row should be returned
INSERT INTO myTable (myDay, myOrder) VALUES ('2021-01-03', 3);
SELECT * FROM myTable mt WHERE myDay = '2021-01-02';
drop table myTable;