From 628d0d3fc93c68eec6c309c1670475a50c57b6ac Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 15 Nov 2024 10:35:30 +0000 Subject: [PATCH 1/3] Fix monotonic function argument type in PK monotonic chain transformation. --- src/Storages/MergeTree/KeyCondition.cpp | 18 ++++++++++++++++-- ...tition_pruning_monotonic_func_bug.reference | 2 ++ ...72_partition_pruning_monotonic_func_bug.sql | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference create mode 100644 tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql diff --git a/src/Storages/MergeTree/KeyCondition.cpp b/src/Storages/MergeTree/KeyCondition.cpp index 9e19ffe1b04..b8c03ba2cd6 100644 --- a/src/Storages/MergeTree/KeyCondition.cpp +++ b/src/Storages/MergeTree/KeyCondition.cpp @@ -945,6 +945,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. @@ -976,7 +978,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); @@ -1005,7 +1007,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; @@ -1489,6 +1491,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(&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, diff --git a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference new file mode 100644 index 00000000000..1191247b6d9 --- /dev/null +++ b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference @@ -0,0 +1,2 @@ +1 +2 diff --git a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql new file mode 100644 index 00000000000..665d146521b --- /dev/null +++ b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql @@ -0,0 +1,15 @@ +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); + From 483141447618288039174280b5bd665ba6d219c6 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 15 Nov 2024 17:57:26 +0000 Subject: [PATCH 2/3] Updating test. --- .../03272_partition_pruning_monotonic_func_bug.reference | 9 +++++++++ .../03272_partition_pruning_monotonic_func_bug.sql | 8 +++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference index 1191247b6d9..a355d04df50 100644 --- a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference +++ b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference @@ -1,2 +1,11 @@ 1 2 +Expression ((Project names + (Projection + Change column names to column identifiers))) + ReadFromMergeTree (default.tt) + 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 diff --git a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql index 665d146521b..cc46ffc7925 100644 --- a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql +++ b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS tt; CREATE TABLE tt ( `id` Int64, @@ -9,7 +10,8 @@ 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); +SELECT id FROM tt PREWHERE ts BETWEEN toDateTime(1731506400) AND toDateTime(1731594420); +explain indexes=1 SELECT id FROM tt PREWHERE ts BETWEEN toDateTime(1731506400) AND toDateTime(1731594420); + +DROP TABLE tt; From 5a23d19c752e1aadc7e62f42ce312a06948efd89 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 18 Nov 2024 10:37:33 +0000 Subject: [PATCH 3/3] Fix timezone in tests and old analyzer run. --- .../03272_partition_pruning_monotonic_func_bug.reference | 4 ++-- .../03272_partition_pruning_monotonic_func_bug.sql | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference index a355d04df50..cbb68477a29 100644 --- a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference +++ b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.reference @@ -1,7 +1,7 @@ 1 2 -Expression ((Project names + (Projection + Change column names to column identifiers))) - ReadFromMergeTree (default.tt) +Expression + ReadFromMergeTree Indexes: PrimaryKey Keys: diff --git a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql index cc46ffc7925..b69b7b8a754 100644 --- a/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql +++ b/tests/queries/0_stateless/03272_partition_pruning_monotonic_func_bug.sql @@ -1,3 +1,5 @@ +SET session_timezone = 'Etc/UTC'; + DROP TABLE IF EXISTS tt; CREATE TABLE tt ( @@ -12,6 +14,6 @@ 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 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;