Fix bad cast in monotonicity analysis

This commit is contained in:
Alexey Milovidov 2023-01-01 20:41:18 +01:00
parent d4d0647ccd
commit e20eb570c5
3 changed files with 18 additions and 8 deletions

View File

@ -2147,14 +2147,18 @@ struct ToNumberMonotonicity
if constexpr (std::is_floating_point_v<T>) if constexpr (std::is_floating_point_v<T>)
return { .is_monotonic = true, .is_always_monotonic = true }; return { .is_monotonic = true, .is_always_monotonic = true };
/// If converting from Float, for monotonicity, arguments must fit in range of result type. const auto * low_cardinality = typeid_cast<const DataTypeLowCardinality *>(&type);
bool is_type_float = false; const IDataType * low_cardinality_dictionary_type = nullptr;
if (const auto * low_cardinality = typeid_cast<const DataTypeLowCardinality *>(&type)) if (low_cardinality)
is_type_float = WhichDataType(low_cardinality->getDictionaryType()).isFloat(); low_cardinality_dictionary_type = low_cardinality->getDictionaryType().get();
else
is_type_float = WhichDataType(type).isFloat();
if (is_type_float) WhichDataType which_type(type);
WhichDataType which_inner_type = low_cardinality
? WhichDataType(low_cardinality_dictionary_type)
: WhichDataType(type);
/// If converting from Float, for monotonicity, arguments must fit in range of result type.
if (which_inner_type.isFloat())
{ {
if (left.isNull() || right.isNull()) if (left.isNull() || right.isNull())
return {}; return {};
@ -2180,7 +2184,7 @@ struct ToNumberMonotonicity
const size_t size_of_to = sizeof(T); const size_t size_of_to = sizeof(T);
/// Do not support 128 bit integers and decimals for now. /// Do not support 128 bit integers and decimals for now.
if (size_of_from > sizeof(Int64)) if (size_of_from > sizeof(Int64) || which_inner_type.isDecimal())
return {}; return {};
const bool left_in_first_half = left.isNull() const bool left_in_first_half = left.isNull()

View File

@ -0,0 +1 @@
1.1

View File

@ -0,0 +1,5 @@
DROP TABLE IF EXISTS t;
CREATE TABLE t (x Decimal(18, 3)) ENGINE = MergeTree ORDER BY x;
INSERT INTO t VALUES (1.1);
SELECT * FROM t WHERE toUInt64(x) = 1;
DROP TABLE t;