diff --git a/internal/types/numeric.go b/internal/types/numeric.go index a4ec1519..0c744e3b 100644 --- a/internal/types/numeric.go +++ b/internal/types/numeric.go @@ -38,17 +38,27 @@ type Integral interface { } func isMulOverflow[T int32 | int64](left, right, min, max T) bool { - if right > 0 { - if left > max/right { - return true - } - } else { - if left < min/right { - return true - } + // zero multiplication cannot overflow + if left == 0 || right == 0 { + return false } - return false + if left > 0 { + if right > 0 { + // both positive: overflow if left > max / right + return left > max/right + } + // left > 0, right < 0: product negative. overflow if left > min / right + return left > min/right + } + + // left < 0 + if right > 0 { + // left < 0, right > 0: product negative. overflow if left < min / right + return left < min/right + } + // both negative: product positive. overflow if left < max / right + return left < max/right } func isAddOverflow[T int32 | int64](left, right, min, max T) bool { diff --git a/sqltests/expr/arithmetic.sql b/sqltests/expr/arithmetic.sql index 8d562865..44b1f2ce 100644 --- a/sqltests/expr/arithmetic.sql +++ b/sqltests/expr/arithmetic.sql @@ -96,6 +96,11 @@ NULL > 4.5 + 4.5 9.0 +> 10 * -10 +-100 + +> 10 + -10 + ! 1000000000 * 1000000000 ! 1000000000000000000 * 1000000000000000000 * 1000000000000000000