Merge pull request #38675 from amosbird/index-fix-1

Fix toHour() monotonicity which can lead to incorrect query result (incorrect index analysis)
This commit is contained in:
Alexey Milovidov 2022-07-08 00:32:27 +03:00 committed by GitHub
commit 89fdcbf08c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 8 deletions

View File

@ -148,8 +148,10 @@ public:
const IFunction::Monotonicity is_monotonic = { .is_monotonic = true }; const IFunction::Monotonicity is_monotonic = { .is_monotonic = true };
const IFunction::Monotonicity is_not_monotonic; const IFunction::Monotonicity is_not_monotonic;
/// This method is called only if the function has one argument. Therefore, we do not care about the non-local time zone. const DateLUTImpl * date_lut = &DateLUT::instance();
const DateLUTImpl & date_lut = DateLUT::instance(); if (const auto * timezone = dynamic_cast<const TimezoneMixin *>(&type))
date_lut = &timezone->getTimeZone();
if (left.isNull() || right.isNull()) if (left.isNull() || right.isNull())
return is_not_monotonic; return is_not_monotonic;
@ -157,20 +159,20 @@ public:
if (checkAndGetDataType<DataTypeDate>(&type)) if (checkAndGetDataType<DataTypeDate>(&type))
{ {
return Transform::FactorTransform::execute(UInt16(left.get<UInt64>()), date_lut) return Transform::FactorTransform::execute(UInt16(left.get<UInt64>()), *date_lut)
== Transform::FactorTransform::execute(UInt16(right.get<UInt64>()), date_lut) == Transform::FactorTransform::execute(UInt16(right.get<UInt64>()), *date_lut)
? is_monotonic : is_not_monotonic; ? is_monotonic : is_not_monotonic;
} }
else if (checkAndGetDataType<DataTypeDate32>(&type)) else if (checkAndGetDataType<DataTypeDate32>(&type))
{ {
return Transform::FactorTransform::execute(Int32(left.get<UInt64>()), date_lut) return Transform::FactorTransform::execute(Int32(left.get<UInt64>()), *date_lut)
== Transform::FactorTransform::execute(Int32(right.get<UInt64>()), date_lut) == Transform::FactorTransform::execute(Int32(right.get<UInt64>()), *date_lut)
? is_monotonic : is_not_monotonic; ? is_monotonic : is_not_monotonic;
} }
else else
{ {
return Transform::FactorTransform::execute(UInt32(left.get<UInt64>()), date_lut) return Transform::FactorTransform::execute(UInt32(left.get<UInt64>()), *date_lut)
== Transform::FactorTransform::execute(UInt32(right.get<UInt64>()), date_lut) == Transform::FactorTransform::execute(UInt32(right.get<UInt64>()), *date_lut)
? is_monotonic : is_not_monotonic; ? is_monotonic : is_not_monotonic;
} }
} }

View File

@ -0,0 +1 @@
5 8 42

View File

@ -0,0 +1,8 @@
drop table if exists test_tz_hour;
create table test_tz_hour(t DateTime, x String) engine MergeTree partition by toYYYYMMDD(t) order by x;
insert into test_tz_hour select toDateTime('2021-06-01 00:00:00') + number * 600, 'x' from numbers(1e3);
select toHour(toTimeZone(t, 'UTC')) as toHour_UTC, toHour(toTimeZone(t, 'Asia/Jerusalem')) as toHour_Israel, count() from test_tz_hour where toHour_Israel = 8 group by toHour_UTC, toHour_Israel;
drop table test_tz_hour;