fix wrong index analysis with functions

This commit is contained in:
Anton Popov 2020-07-29 19:09:38 +03:00
parent 89abf4a7b0
commit 4c266d1e5d
3 changed files with 78 additions and 1 deletions

View File

@ -1089,7 +1089,7 @@ BoolMask KeyCondition::checkInRange(
/* std::cerr << "Hyperrectangle: ";
for (size_t i = 0, size = key_ranges.size(); i != size; ++i)
std::cerr << (i != 0 ? " x " : "") << key_ranges[i].toString();
std::cerr << ": " << res << "\n";*/
std::cerr << ": " << res.can_be_true << "\n";*/
return res;
});
@ -1112,10 +1112,20 @@ std::optional<Range> KeyCondition::applyMonotonicFunctionsChainToRange(
return {};
}
/// If we apply function to open interval, we can get empty intervals in result.
/// E.g. for ('2020-01-03', '2020-01-20') after applying 'toYYYYMM' we will get ('202001', '202001').
/// To avoid this we make range left and right included.
if (!key_range.left.isNull())
{
key_range.left = applyFunction(func, current_type, key_range.left);
key_range.left_included = true;
}
if (!key_range.right.isNull())
{
key_range.right = applyFunction(func, current_type, key_range.right);
key_range.right_included = true;
}
current_type = func->getReturnType();

View File

@ -0,0 +1,24 @@
2020-07-03 706
2020-07-04 695
2020-07-05 726
2020-07-06 686
2020-07-07 715
2020-07-08 706
2020-07-09 695
2020-07-10 726
2020-07-11 686
2020-07-12 715
2020-07-13 706
2020-07-14 695
2020-07-15 726
2020-07-16 686
2020-07-17 715
2020-07-18 706
2020-07-19 695
2020-07-20 726
2020-07-21 686
2020-07-22 715
2020-07-23 706
2020-07-24 695
2020-07-25 726
2

View File

@ -0,0 +1,43 @@
DROP TABLE IF EXISTS mytable_local;
CREATE TABLE mytable_local (
created DateTime,
eventday Date,
user_id UInt32
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(eventday)
ORDER BY (eventday, user_id);
INSERT INTO mytable_local SELECT
toDateTime('2020-06-01 00:00:00') + toIntervalMinute(number) AS created,
toDate(created) AS eventday,
if((number % 100) > 50, 742522, number % 32141) AS user_id
FROM numbers(100000);
SELECT
eventday,
count(*)
FROM mytable_local
WHERE (toYYYYMM(eventday) = 202007) AND (user_id = 742522) AND (eventday >= '2020-07-03') AND (eventday <= '2020-07-25')
GROUP BY eventday
ORDER BY eventday;
DROP TABLE mytable_local;
DROP TABLE IF EXISTS table_float;
CREATE TABLE table_float
(
f Float64,
u UInt32
)
ENGINE = MergeTree
ORDER BY (f, u);
INSERT INTO table_float VALUES (1.2, 1) (1.3, 2) (1.4, 3) (1.5, 4);
SELECT count()
FROM table_float
WHERE (toUInt64(f) = 1) AND (f >= 1.3) AND (f <= 1.4) AND (u > 0);
DROP TABLE table_float;