diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index ffe7677afe7..2210c61d157 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -1570,25 +1570,15 @@ struct ToNumberMonotonicity if (left.isNull() || right.isNull()) return {}; - if (from_is_unsigned == to_is_unsigned) - { - /// all bits other than that fits, must be same. - if (divideByRangeOfType(left.get()) == divideByRangeOfType(right.get())) - return {true}; - + /// Function cannot be monotonic when left and right are not on the same ranges. + if (divideByRangeOfType(left.get()) != divideByRangeOfType(right.get())) return {}; - } + + if (to_is_unsigned) + return {true}; else - { - /// When signedness is changed, it's also required for arguments to be from the same half. - /// And they must be in the same half after converting to the result type. - if (left_in_first_half == right_in_first_half - && (T(left.get()) >= 0) == (T(right.get()) >= 0) - && divideByRangeOfType(left.get()) == divideByRangeOfType(right.get())) - return {true}; - - return {}; - } + // If To is signed, it's possible that the signedness is different after conversion. So we check it explicitly. + return {(T(left.get()) >= 0) == (T(right.get()) >= 0)}; } __builtin_unreachable(); diff --git a/tests/queries/0_stateless/01496_signedness_conversion_monotonicity.reference b/tests/queries/0_stateless/01496_signedness_conversion_monotonicity.reference new file mode 100644 index 00000000000..d00491fd7e5 --- /dev/null +++ b/tests/queries/0_stateless/01496_signedness_conversion_monotonicity.reference @@ -0,0 +1 @@ +1 diff --git a/tests/queries/0_stateless/01496_signedness_conversion_monotonicity.sql b/tests/queries/0_stateless/01496_signedness_conversion_monotonicity.sql new file mode 100644 index 00000000000..5c87ba3c57c --- /dev/null +++ b/tests/queries/0_stateless/01496_signedness_conversion_monotonicity.sql @@ -0,0 +1,9 @@ +drop table if exists test1; + +create table test1 (i Int64) engine MergeTree order by i; + +insert into test1 values (53), (1777), (53284); + +select count() from test1 where toInt16(i) = 1777; + +drop table if exists test1;