Skip to content

Commit f9987c8

Browse files
committed
The key condition can use binary search in more cases
1 parent 1b7dc9c commit f9987c8

File tree

3 files changed

+73
-3
lines changed

3 files changed

+73
-3
lines changed

src/Storages/MergeTree/KeyCondition.cpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,9 +2901,41 @@ std::optional<Range> KeyCondition::applyMonotonicFunctionsChainToRange(
29012901
// This allows to use a more efficient lookup with no extra reads.
29022902
bool KeyCondition::matchesExactContinuousRange() const
29032903
{
2904-
// Not implemented yet.
2905-
if (hasMonotonicFunctionsChain())
2906-
return false;
2904+
const Field field{};
2905+
auto is_always_monotonic_chain = [&field](const std::vector<FunctionBasePtr> & chain)
2906+
{
2907+
for (const auto & func : chain)
2908+
{
2909+
if (!func || !func->hasInformationAboutMonotonicity())
2910+
return false;
2911+
2912+
const auto & types = func->getArgumentTypes();
2913+
if (types.empty() || !types.front())
2914+
return false;
2915+
2916+
const auto monotonicity = func->getMonotonicityForRange(*types.front(), field, field);
2917+
if (!monotonicity.is_always_monotonic)
2918+
return false;
2919+
}
2920+
2921+
return true;
2922+
};
2923+
2924+
for (const auto & elem : rpn)
2925+
{
2926+
if (!elem.monotonic_functions_chain.empty() && !is_always_monotonic_chain(elem.monotonic_functions_chain))
2927+
return false;
2928+
2929+
if (elem.set_index)
2930+
{
2931+
if (elem.function != RPNElement::Function::FUNCTION_IN_SET || elem.set_index->size() != 1)
2932+
return false;
2933+
2934+
for (const auto & mapping : elem.set_index->getIndexesMapping())
2935+
if (!mapping.functions.empty() && !is_always_monotonic_chain(mapping.functions))
2936+
return false;
2937+
}
2938+
}
29072939

29082940
enum Constraint
29092941
{
@@ -2945,6 +2977,11 @@ bool KeyCondition::matchesExactContinuousRange() const
29452977
continue;
29462978
}
29472979

2980+
if (element.function == RPNElement::Function::ALWAYS_TRUE)
2981+
{
2982+
continue;
2983+
}
2984+
29482985
return false;
29492986
}
29502987

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
3
2+
1
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bash
2+
3+
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
4+
# shellcheck source=../shell_config.sh
5+
. "$CUR_DIR"/../shell_config.sh
6+
7+
$CLICKHOUSE_CLIENT -n -q "
8+
DROP TABLE IF EXISTS t;
9+
CREATE TABLE t
10+
(
11+
c Enum8('Zero' = 0, 'One' = 1, 'Two' = 2, 'Three' = 3, 'Four' = 4, 'Five' = 5)
12+
)
13+
ENGINE = MergeTree
14+
ORDER BY c;
15+
INSERT INTO t values('One');
16+
SELECT * FROM t WHERE c = 1 settings send_logs_level='trace';
17+
SELECT * FROM t WHERE c = 'One' settings send_logs_level='trace';
18+
SELECT * FROM t WHERE c = 1 and 1 = 1 settings send_logs_level='trace';
19+
" 2>&1 | grep -c "binary search"
20+
21+
$CLICKHOUSE_CLIENT -n -q "
22+
DROP TABLE IF EXISTS t1;
23+
CREATE TABLE t1
24+
(
25+
timestamp DateTime64(3, 'Asia/shanghai')
26+
)
27+
ENGINE = MergeTree
28+
ORDER BY timestamp;
29+
INSERT INTO t1 VALUES ('2025-05-21 00:00:00');
30+
SELECT * FROM t1 WHERE toDayOfMonth(timestamp) = 1 settings send_logs_level='trace';
31+
" 2>&1 | grep -c "generic exclusion search"

0 commit comments

Comments
 (0)