diff --git a/src/IO/ReadHelpers.h b/src/IO/ReadHelpers.h index bdfb1f5d33e..47e574416ce 100644 --- a/src/IO/ReadHelpers.h +++ b/src/IO/ReadHelpers.h @@ -331,12 +331,24 @@ ReturnType readIntTextImpl(T & x, ReadBuffer & buf) if (buf.count() - initial_pos + 1 >= std::numeric_limits::max_digits10) { - T signed_res = negative ? -res : res; - if (common::mulOverflow(signed_res, 10, signed_res) || (negative ? common::subOverflow(signed_res, (*buf.position() - '0'), signed_res) : - common::addOverflow(signed_res, (*buf.position() - '0'), signed_res))) - return ReturnType(false); + if (negative) + { + T signed_res = -res; + if (common::mulOverflow(signed_res, 10, signed_res) || + common::subOverflow(signed_res, (*buf.position() - '0'), signed_res)) + return ReturnType(false); - res = negative ? -signed_res : signed_res; + res = -signed_res; + } + else + { + T signed_res = res; + if (common::mulOverflow(signed_res, 10, signed_res) + || common::addOverflow(signed_res, (*buf.position() - '0'), signed_res)) + return ReturnType(false); + + res = signed_res; + } break; } } diff --git a/tests/queries/0_stateless/2020_cast_integer_overflow.reference b/tests/queries/0_stateless/2020_cast_integer_overflow.reference new file mode 100644 index 00000000000..acceae4a72e --- /dev/null +++ b/tests/queries/0_stateless/2020_cast_integer_overflow.reference @@ -0,0 +1,2 @@ +-2147483648 +-2147483648 diff --git a/tests/queries/0_stateless/2020_cast_integer_overflow.sql b/tests/queries/0_stateless/2020_cast_integer_overflow.sql new file mode 100644 index 00000000000..57aeff9a982 --- /dev/null +++ b/tests/queries/0_stateless/2020_cast_integer_overflow.sql @@ -0,0 +1,2 @@ +SELECT toInt32('-2147483648'); +SELECT toInt32OrNull('-2147483648');