From aa82a038f1aa1739885592b57251eb77eaff9991 Mon Sep 17 00:00:00 2001 From: Alkaid Jiang <38248129+jyz0309@users.noreply.github.com> Date: Tue, 9 Mar 2021 15:54:55 +0800 Subject: [PATCH] types: fix the bug about the wrong query result for decimal type (#22507) --- executor/write_test.go | 13 +++++++++++++ types/convert_test.go | 9 +++++++++ types/mydecimal.go | 7 +++++++ 3 files changed, 29 insertions(+) diff --git a/executor/write_test.go b/executor/write_test.go index 9bcaa68199b4b..1721d726179b1 100644 --- a/executor/write_test.go +++ b/executor/write_test.go @@ -3901,6 +3901,19 @@ func (s *testSerialSuite) TestIssue20840(c *C) { tk.MustExec("drop table t1") } +func (s *testSerialSuite) 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) TestEqualDatumsAsBinary(c *C) { tests := []struct { a []interface{} diff --git a/types/convert_test.go b/types/convert_test.go index 9c3326a7ae846..34a5f5aea5435 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 f86d74206049b..acd5ca48ff01d 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 }