Skip to content

Commit

Permalink
types: fix unsigned decimal check and negative overflow bugs (pingcap…
Browse files Browse the repository at this point in the history
  • Loading branch information
lysu authored and jackysp committed Jun 4, 2018
1 parent 64e3aca commit 30f1601
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
50 changes: 50 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2787,3 +2787,53 @@ func (s *testSuite) TestYearTypeDeleteIndex(c *C) {
tk.MustExec("delete from t;")
tk.MustExec("admin check table t")
}

func (s *testSuite) TestUnsignedDecimalOverflow(c *C) {
tests := []struct {
input interface{}
hasErr bool
err string
}{{
-1,
true,
"Out of range value for column",
}, {
"-1.1e-1",
true,
"Out of range value for column",
}, {
-1.1,
true,
"Out of range value for column",
}, {
-0,
false,
"",
},
}
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a decimal(10,2) unsigned)")
for _, t := range tests {
res, err := tk.Exec("insert into t values (?)", t.input)
if res != nil {
defer res.Close()
}
if t.hasErr {
c.Assert(err, NotNil)
c.Assert(strings.Contains(err.Error(), t.err), IsTrue)
} else {
c.Assert(err, IsNil)
}
if res != nil {
res.Close()
}
}

tk.MustExec("set sql_mode=''")
tk.MustExec("delete from t")
tk.MustExec("insert into t values (?)", -1)
r := tk.MustQuery("select a from t limit 1")
r.Check(testkit.Rows("0.00"))
}
6 changes: 6 additions & 0 deletions types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,12 @@ func (d *Datum) convertToMysqlDecimal(sc *stmtctx.StatementContext, target *Fiel
if err == nil && err1 != nil {
err = err1
}
if dec.negative && mysql.HasUnsignedFlag(target.Flag) {
*dec = zeroMyDecimal
if err == nil {
err = ErrOverflow.GenByArgs("DECIMAL", fmt.Sprintf("(%d, %d)", target.Flen, target.Decimal))
}
}
ret.SetValue(dec)
return ret, errors.Trace(err)
}
Expand Down
4 changes: 4 additions & 0 deletions types/mydecimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,9 @@ func (d *MyDecimal) FromString(str []byte) error {
}
}
if exponent > math.MaxInt32/2 {
negative := d.negative
maxDecimal(wordBufLen*digitsPerWord, 0, d)
d.negative = negative
err = ErrOverflow
}
if exponent < math.MinInt32/2 && err != ErrOverflow {
Expand All @@ -411,7 +413,9 @@ func (d *MyDecimal) FromString(str []byte) error {
shiftErr := d.Shift(int(exponent))
if shiftErr != nil {
if shiftErr == ErrOverflow {
negative := d.negative
maxDecimal(wordBufLen*digitsPerWord, 0, d)
d.negative = negative
}
err = shiftErr
}
Expand Down
1 change: 1 addition & 0 deletions types/mydecimal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ func (s *testMyDecimalSuite) TestFromString(c *C) {
{"123E5", "12300000", nil},
{"123E-2", "1.23", nil},
{"1e1073741823", "999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow},
{"-1e1073741823", "-999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow},
{"1e18446744073709551620", "0", ErrBadNumber},
{"1e", "1", ErrTruncated},
{"1e001", "10", nil},
Expand Down

0 comments on commit 30f1601

Please sign in to comment.