Merge pull request #71966 from ClickHouse/fix-pk-const-monotonic-transform-for-2-args

Fix partition pruning with binary monotonic function by second arg.
This commit is contained in:
Nikolai Kochetov 2024-11-18 14:41:14 +00:00 committed by GitHub
commit b25a01922c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 2 deletions

View File

@ -945,6 +945,8 @@ static FieldRef applyFunction(const FunctionBasePtr & func, const DataTypePtr &
return {field.columns, field.row_idx, result_idx}; return {field.columns, field.row_idx, result_idx};
} }
DataTypePtr getArgumentTypeOfMonotonicFunction(const IFunctionBase & func);
/// Sequentially applies functions to the column, returns `true` /// Sequentially applies functions to the column, returns `true`
/// if all function arguments are compatible with functions /// if all function arguments are compatible with functions
/// signatures, and none of the functions produce `NULL` output. /// signatures, and none of the functions produce `NULL` output.
@ -976,7 +978,7 @@ bool applyFunctionChainToColumn(
} }
// And cast it to the argument type of the first function in the chain // And cast it to the argument type of the first function in the chain
auto in_argument_type = functions[0]->getArgumentTypes()[0]; auto in_argument_type = getArgumentTypeOfMonotonicFunction(*functions[0]);
if (canBeSafelyCasted(result_type, in_argument_type)) if (canBeSafelyCasted(result_type, in_argument_type))
{ {
result_column = castColumnAccurate({result_column, result_type, ""}, in_argument_type); result_column = castColumnAccurate({result_column, result_type, ""}, in_argument_type);
@ -1005,7 +1007,7 @@ bool applyFunctionChainToColumn(
if (func->getArgumentTypes().empty()) if (func->getArgumentTypes().empty())
return false; return false;
auto argument_type = func->getArgumentTypes()[0]; auto argument_type = getArgumentTypeOfMonotonicFunction(*func);
if (!canBeSafelyCasted(result_type, argument_type)) if (!canBeSafelyCasted(result_type, argument_type))
return false; return false;
@ -1489,6 +1491,18 @@ private:
Kind kind = Kind::NO_CONST; Kind kind = Kind::NO_CONST;
}; };
DataTypePtr getArgumentTypeOfMonotonicFunction(const IFunctionBase & func)
{
const auto & arg_types = func.getArgumentTypes();
if (const auto * func_ptr = typeid_cast<const FunctionWithOptionalConstArg *>(&func))
{
if (func_ptr->getKind() == FunctionWithOptionalConstArg::Kind::LEFT_CONST)
return arg_types.at(1);
}
return arg_types.at(0);
}
bool KeyCondition::isKeyPossiblyWrappedByMonotonicFunctions( bool KeyCondition::isKeyPossiblyWrappedByMonotonicFunctions(
const RPNBuilderTreeNode & node, const RPNBuilderTreeNode & node,

View File

@ -0,0 +1,11 @@
1
2
Expression
ReadFromMergeTree
Indexes:
PrimaryKey
Keys:
dateTrunc(\'hour\', ts)
Condition: and((dateTrunc(\'hour\', ts) in (-Inf, 1731592800]), (dateTrunc(\'hour\', ts) in [1731506400, +Inf)))
Parts: 1/1
Granules: 1/1

View File

@ -0,0 +1,19 @@
SET session_timezone = 'Etc/UTC';
DROP TABLE IF EXISTS tt;
CREATE TABLE tt
(
`id` Int64,
`ts` DateTime
)
ENGINE = MergeTree()
ORDER BY dateTrunc('hour', ts)
SETTINGS index_granularity = 8192;
INSERT INTO tt VALUES (1, '2024-11-14 00:00:00'), (2, '2024-11-14 00:00:00');
SELECT id FROM tt PREWHERE ts BETWEEN toDateTime(1731506400) AND toDateTime(1731594420);
explain indexes=1, description=0 SELECT id FROM tt PREWHERE ts BETWEEN toDateTime(1731506400) AND toDateTime(1731594420);
DROP TABLE tt;