diff --git a/executor/write_test.go b/executor/write_test.go index 1dc1c9b389ae9..f9f60eaa9889d 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -2955,6 +2955,19 @@ func (s *testSerialSuite1) TestIssue20724(c *C) { tk.MustExec("drop table t1") } +func (s *testSuite) TestIssue22496(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t12") + tk.MustExec("create table t12(d decimal(15,2));") + _, err := tk.Exec("insert into t12 values('1,9999.00')") + c.Assert(err, NotNil) + tk.MustExec("set sql_mode=''") + tk.MustExec("insert into t12 values('1,999.00');") + tk.MustQuery("SELECT * FROM t12;").Check(testkit.Rows("1.00")) + tk.MustExec("drop table t12") +} + func (s *testSuite) TestIssue21232(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") diff --git a/types/convert_test.go b/types/convert_test.go index 1a2954d9c93e8..082c1d08bde7e 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -243,6 +243,15 @@ func (s *testTypeConvertSuite) TestConvertType(c *C) { v, err = Convert("-10000", ft) c.Assert(terror.ErrorEqual(err, ErrOverflow), IsTrue, Commentf("err %v", err)) c.Assert(v.(*MyDecimal).String(), Equals, "-9999.9999") + v, err = Convert("1,999.00", ft) + c.Assert(terror.ErrorEqual(err, ErrBadNumber), IsTrue, Commentf("err %v", err)) + c.Assert(v.(*MyDecimal).String(), Equals, "1.0000") + v, err = Convert("1,999,999.00", ft) + c.Assert(terror.ErrorEqual(err, ErrBadNumber), IsTrue, Commentf("err %v", err)) + c.Assert(v.(*MyDecimal).String(), Equals, "1.0000") + v, err = Convert("199.00 ", ft) + c.Assert(err, IsNil) + c.Assert(v.(*MyDecimal).String(), Equals, "199.0000") // Test Datum.ToDecimal with bad number. d := NewDatum("hello") diff --git a/types/mydecimal.go b/types/mydecimal.go index 3a04afa7a4bfe..350d2ac3ea153 100644 --- a/types/mydecimal.go +++ b/types/mydecimal.go @@ -389,6 +389,8 @@ func (d *MyDecimal) ToString() (str []byte) { // FromString parses decimal from string. func (d *MyDecimal) FromString(str []byte) error { + // strErr is used to check str is bad number or not + var strErr error for i := 0; i < len(str); i++ { if !isSpace(str[i]) { str = str[i:] @@ -419,6 +421,8 @@ func (d *MyDecimal) FromString(str []byte) error { endIdx++ } digitsFrac = endIdx - strIdx - 1 + } else if strIdx < len(str) && (str[strIdx] != 'e' && str[strIdx] != 'E' && str[strIdx] != ' ') { + strErr = ErrBadNumber } else { digitsFrac = 0 endIdx = strIdx @@ -519,6 +523,9 @@ func (d *MyDecimal) FromString(str []byte) error { d.negative = false } d.resultFrac = d.digitsFrac + if strErr != nil { + return strErr + } return err }