Backport #71966 to 24.9: Fix partition pruning with binary monotonic function by second arg.

This commit is contained in:
robot-clickhouse 2024-11-18 15:07:47 +00:00
parent 9a816c73dd
commit 67e9136c50
3 changed files with 46 additions and 2 deletions

View File

@ -929,6 +929,8 @@ static FieldRef applyFunction(const FunctionBasePtr & func, const DataTypePtr &
return {field.columns, field.row_idx, result_idx};
}
DataTypePtr getArgumentTypeOfMonotonicFunction(const IFunctionBase & func);
/// Sequentially applies functions to the column, returns `true`
/// if all function arguments are compatible with functions
/// signatures, and none of the functions produce `NULL` output.
@ -960,7 +962,7 @@ bool applyFunctionChainToColumn(
}
// 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))
{
result_column = castColumnAccurate({result_column, result_type, ""}, in_argument_type);
@ -989,7 +991,7 @@ bool applyFunctionChainToColumn(
if (func->getArgumentTypes().empty())
return false;
auto argument_type = func->getArgumentTypes()[0];
auto argument_type = getArgumentTypeOfMonotonicFunction(*func);
if (!canBeSafelyCasted(result_type, argument_type))
return false;
@ -1451,6 +1453,18 @@ private:
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(
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;