Skip to content

Commit

Permalink
expression: fix float64 overflow check in plus/minus real function (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ti-srebot authored Sep 3, 2021
1 parent 7bdcf69 commit a58a482
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 4 deletions.
5 changes: 3 additions & 2 deletions expression/builtin_arithmetic.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
math2 "github.com/pingcap/tidb/util/math"
"github.com/pingcap/tipb/go-tipb"
)

Expand Down Expand Up @@ -293,7 +294,7 @@ func (s *builtinArithmeticPlusRealSig) evalReal(row chunk.Row) (float64, bool, e
if isLHSNull || isRHSNull {
return 0, true, nil
}
if (a > 0 && b > math.MaxFloat64-a) || (a < 0 && b < -math.MaxFloat64-a) {
if !math2.IsFinite(a + b) {
return 0, true, types.ErrOverflow.GenWithStackByArgs("DOUBLE", fmt.Sprintf("(%s + %s)", s.args[0].String(), s.args[1].String()))
}
return a + b, false, nil
Expand Down Expand Up @@ -362,7 +363,7 @@ func (s *builtinArithmeticMinusRealSig) evalReal(row chunk.Row) (float64, bool,
if isNull || err != nil {
return 0, isNull, err
}
if (a > 0 && -b > math.MaxFloat64-a) || (a < 0 && -b < -math.MaxFloat64-a) {
if !math2.IsFinite(a - b) {
return 0, true, types.ErrOverflow.GenWithStackByArgs("DOUBLE", fmt.Sprintf("(%s - %s)", s.args[0].String(), s.args[1].String()))
}
return a - b, false, nil
Expand Down
5 changes: 3 additions & 2 deletions expression/builtin_arithmetic_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/pingcap/parser/terror"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
math2 "github.com/pingcap/tidb/util/math"
)

func (b *builtinArithmeticMultiplyRealSig) vectorized() bool {
Expand Down Expand Up @@ -276,7 +277,7 @@ func (b *builtinArithmeticMinusRealSig) vecEvalReal(input *chunk.Chunk, result *
if result.IsNull(i) {
continue
}
if (x[i] > 0 && -y[i] > math.MaxFloat64-x[i]) || (x[i] < 0 && -y[i] < -math.MaxFloat64-x[i]) {
if !math2.IsFinite(x[i] - y[i]) {
return types.ErrOverflow.GenWithStackByArgs("DOUBLE", fmt.Sprintf("(%s - %s)", b.args[0].String(), b.args[1].String()))
}
x[i] = x[i] - y[i]
Expand Down Expand Up @@ -475,7 +476,7 @@ func (b *builtinArithmeticPlusRealSig) vecEvalReal(input *chunk.Chunk, result *c
if result.IsNull(i) {
continue
}
if (x[i] > 0 && y[i] > math.MaxFloat64-x[i]) || (x[i] < 0 && y[i] < -math.MaxFloat64-x[i]) {
if !math2.IsFinite(x[i] + y[i]) {
return types.ErrOverflow.GenWithStackByArgs("DOUBLE", fmt.Sprintf("(%s + %s)", b.args[0].String(), b.args[1].String()))
}
x[i] = x[i] + y[i]
Expand Down
9 changes: 9 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9161,6 +9161,15 @@ func (s *testIntegrationSuite) TestIssue23889(c *C) {
testkit.Rows("<nil>", "0"))
}

func (s *testIntegrationSuite) TestFloat64Inf(c *C) {
defer s.cleanEnv(c)
tk := testkit.NewTestKit(c, s.store)
tk.MustQuery("select '1e800' + 1e100;").Check(
testkit.Rows("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))
tk.MustQuery("select '-1e800' - 1e100;").Check(
testkit.Rows("-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))
}

func (s *testIntegrationSuite2) TestIssue25591(c *C) {
tk := testkit.NewTestKit(c, s.store)

Expand Down
5 changes: 5 additions & 0 deletions util/math/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,8 @@ func StrLenOfInt64Fast(x int64) int {
}
return size + StrLenOfUint64Fast(uint64(Abs(x)))
}

// IsFinite reports whether f is neither NaN nor an infinity.
func IsFinite(f float64) bool {
return !math.IsNaN(f - f)
}

0 comments on commit a58a482

Please sign in to comment.