From 4129fcbefff12bfc7f6a4564aa0363250a9ce6c8 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Wed, 30 Jun 2021 20:07:11 +0800 Subject: [PATCH 01/14] executor: query memory table TIKV_REGION_PEERS and TIKV_REGION_STATUS get error --- executor/infoschema_reader.go | 4 ++-- executor/show.go | 4 ++-- executor/split.go | 4 ++-- store/helper/helper.go | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go index 739ab763e5fc0..5848b7591607d 100644 --- a/executor/infoschema_reader.go +++ b/executor/infoschema_reader.go @@ -1416,8 +1416,8 @@ func (e *memtableRetriever) setNewTiKVRegionStatusCol(region *helper.RegionInfo, } row[9].SetInt64(region.Epoch.ConfVer) row[10].SetInt64(region.Epoch.Version) - row[11].SetInt64(region.WrittenBytes) - row[12].SetInt64(region.ReadBytes) + row[11].SetUint64(region.WrittenBytes) + row[12].SetUint64(region.ReadBytes) row[13].SetInt64(region.ApproximateSize) row[14].SetInt64(region.ApproximateKeys) if region.ReplicationStatus != nil { diff --git a/executor/show.go b/executor/show.go index 802be12b22c8a..3b26ebca59e12 100644 --- a/executor/show.go +++ b/executor/show.go @@ -1712,8 +1712,8 @@ func (e *ShowExec) fillRegionsToChunk(regions []regionMeta) { e.result.AppendInt64(6, 0) } - e.result.AppendInt64(7, regions[i].writtenBytes) - e.result.AppendInt64(8, regions[i].readBytes) + e.result.AppendUint64(7, regions[i].writtenBytes) + e.result.AppendUint64(8, regions[i].readBytes) e.result.AppendInt64(9, regions[i].approximateSize) e.result.AppendInt64(10, regions[i].approximateKeys) } diff --git a/executor/split.go b/executor/split.go index a0e8696339276..a611c31678437 100644 --- a/executor/split.go +++ b/executor/split.go @@ -615,8 +615,8 @@ type regionMeta struct { start string end string scattering bool - writtenBytes int64 - readBytes int64 + writtenBytes uint64 + readBytes uint64 approximateSize int64 approximateKeys int64 } diff --git a/store/helper/helper.go b/store/helper/helper.go index c3816ed29c311..ce8666ab0df49 100644 --- a/store/helper/helper.go +++ b/store/helper/helper.go @@ -555,8 +555,8 @@ type RegionInfo struct { Leader RegionPeer `json:"leader"` DownPeers []RegionPeerStat `json:"down_peers"` PendingPeers []RegionPeer `json:"pending_peers"` - WrittenBytes int64 `json:"written_bytes"` - ReadBytes int64 `json:"read_bytes"` + WrittenBytes uint64 `json:"written_bytes"` + ReadBytes uint64 `json:"read_bytes"` ApproximateSize int64 `json:"approximate_size"` ApproximateKeys int64 `json:"approximate_keys"` From a8660e67155c4ac18621b09f696d9a88e191a277 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Tue, 6 Jul 2021 20:42:18 +0800 Subject: [PATCH 02/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- expression/integration_test.go | 10 ++++++++++ types/mydecimal.go | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/expression/integration_test.go b/expression/integration_test.go index 51ee8669f521b..9caf29b2537f4 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2723,6 +2723,16 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { result.Check(testkit.Rows("9223372036854775808", "9223372036854775808")) tk.MustExec(`drop table tb5`) + // test builtinCastStringAsDecimalSig + tk.MustExec(`drop table if exists tb5`) + tk.MustExec(`create table tb5 (a varchar(20));`) + tk.MustExec(`insert into tb5 values ('123', '.0a1');`) + result = tk.MustQuery(`select cast(a as decimal(10, 2)) from tb5;`) + result.Check(testkit.Rows("123.00", "0.00")) + + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '.0a1'")) + tk.MustExec(`drop table tb5`) + // test builtinCastIntAsRealSig tk.MustExec(`drop table if exists tb5`) tk.MustExec(`create table tb5 (a bigint(64) unsigned, b double(64, 10));`) diff --git a/types/mydecimal.go b/types/mydecimal.go index 348b229b11120..213204b9808df 100644 --- a/types/mydecimal.go +++ b/types/mydecimal.go @@ -529,6 +529,10 @@ func (d *MyDecimal) FromString(str []byte) error { if strErr != nil { return strErr } + + if endIdx != len(str) { + return ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) + } return err } From 219c74603faec721800d604460bfb8a75d0fb760 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Wed, 7 Jul 2021 20:43:40 +0800 Subject: [PATCH 03/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- expression/integration_test.go | 17 ++++++++++++++++- types/mydecimal.go | 30 +++++++++++++++++++++++------- types/mydecimal_test.go | 4 ++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/expression/integration_test.go b/expression/integration_test.go index 9a78e24cbf550..6049e5e2f9391 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2729,8 +2729,23 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { tk.MustExec(`insert into tb5 values ('123', '.0a1');`) result = tk.MustQuery(`select cast(a as decimal(10, 2)) from tb5;`) result.Check(testkit.Rows("123.00", "0.00")) - tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '.0a1'")) + + result = tk.MustQuery("select cast('123E5a' as decimal(10,2));") + result.Check(testkit.Rows("123.00")) + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '123E5a'")) + + result = tk.MustQuery(`select cast('123aE5 ' as decimal(10, 2));`) + result.Check(testkit.Rows("123.00")) + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '123aE5 '")) + + result = tk.MustQuery(`select cast('1e - 1' as decimal);`) + result.Check(testkit.Rows("0")) + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '1e - 1'")) + + result = tk.MustQuery(`select cast('1 1' as decimal)`) + result.Check(testkit.Rows("1")) + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '1 1'")) tk.MustExec(`drop table tb5`) // test builtinCastIntAsRealSig diff --git a/types/mydecimal.go b/types/mydecimal.go index 213204b9808df..5b33289fa9754 100644 --- a/types/mydecimal.go +++ b/types/mydecimal.go @@ -393,6 +393,7 @@ 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 str_bak = str var strErr error for i := 0; i < len(str); i++ { if !isSpace(str[i]) { @@ -402,7 +403,7 @@ func (d *MyDecimal) FromString(str []byte) error { } if len(str) == 0 { *d = zeroMyDecimal - return ErrBadNumber + return ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) } switch str[0] { case '-': @@ -423,9 +424,13 @@ func (d *MyDecimal) FromString(str []byte) error { for endIdx < len(str) && isDigit(str[endIdx]) { endIdx++ } + + if endIdx != len(str) { + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) + } digitsFrac = endIdx - strIdx - 1 } else if strIdx < len(str) && (str[strIdx] != 'e' && str[strIdx] != 'E' && str[strIdx] != ' ') { - strErr = ErrBadNumber + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) } else { digitsFrac = 0 endIdx = strIdx @@ -461,6 +466,11 @@ func (d *MyDecimal) FromString(str []byte) error { innerIdx = 0 } } + + if digitsInt != 0 { + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) + } + if innerIdx != 0 { wordIdx-- d.wordBuf[wordIdx] = word @@ -488,8 +498,8 @@ func (d *MyDecimal) FromString(str []byte) error { if endIdx+1 <= len(str) && (str[endIdx] == 'e' || str[endIdx] == 'E') { exponent, err1 := strToInt(string(str[endIdx+1:])) if err1 != nil { - err = errors.Cause(err1) - if err != ErrTruncated { + err = err1 + if errors.Cause(err1) != ErrTruncated { *d = zeroMyDecimal } } @@ -515,6 +525,15 @@ func (d *MyDecimal) FromString(str []byte) error { } } } + + if err == ErrTruncated { + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) + } + + if strErr == nil && (endIdx+1 <= len(str) && str[endIdx] == ' ') { + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) + } + allZero := true for i := 0; i < wordBufLen; i++ { if d.wordBuf[i] != 0 { @@ -530,9 +549,6 @@ func (d *MyDecimal) FromString(str []byte) error { return strErr } - if endIdx != len(str) { - return ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) - } return err } diff --git a/types/mydecimal_test.go b/types/mydecimal_test.go index 8bbc3492566f9..3f94287fb6e48 100644 --- a/types/mydecimal_test.go +++ b/types/mydecimal_test.go @@ -523,6 +523,10 @@ func (s *testMyDecimalSerialSuite) TestFromString(c *C) { {"1e - 1", "1", ErrTruncated}, {"1e -1", "0.1", nil}, {"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0.000000000000000000000000000000000000000000000000000000000000000000000000", ErrTruncated}, + {"0.1a2", "0.1", ErrTruncated}, + {"123aE5", "123", ErrTruncated}, + {"123E5a", "123", ErrTruncated}, + {"1 1", "1", ErrTruncated}, } for _, ca := range tests { var dec MyDecimal From e3826605489dc27fa4682356a5077854da1c9f61 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Wed, 7 Jul 2021 20:49:34 +0800 Subject: [PATCH 04/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- types/mydecimal.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/types/mydecimal.go b/types/mydecimal.go index 5b33289fa9754..6a706bc6b0a27 100644 --- a/types/mydecimal.go +++ b/types/mydecimal.go @@ -393,7 +393,7 @@ 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 str_bak = str + var strBak = str var strErr error for i := 0; i < len(str); i++ { if !isSpace(str[i]) { @@ -403,7 +403,7 @@ func (d *MyDecimal) FromString(str []byte) error { } if len(str) == 0 { *d = zeroMyDecimal - return ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) + return ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) } switch str[0] { case '-': @@ -426,11 +426,11 @@ func (d *MyDecimal) FromString(str []byte) error { } if endIdx != len(str) { - strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) } digitsFrac = endIdx - strIdx - 1 } else if strIdx < len(str) && (str[strIdx] != 'e' && str[strIdx] != 'E' && str[strIdx] != ' ') { - strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) } else { digitsFrac = 0 endIdx = strIdx @@ -468,7 +468,7 @@ func (d *MyDecimal) FromString(str []byte) error { } if digitsInt != 0 { - strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str_bak)) + strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) } if innerIdx != 0 { From e73d76f48ef52f45d8e78f174d23c68bfb3f3d8b Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Thu, 8 Jul 2021 10:42:53 +0800 Subject: [PATCH 05/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- types/datum.go | 10 +++++----- types/mydecimal_test.go | 24 +++++++++++++----------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/types/datum.go b/types/datum.go index 8071139e0571f..bd352bff4fc6a 100644 --- a/types/datum.go +++ b/types/datum.go @@ -1374,15 +1374,15 @@ func ProduceDecWithSpecifiedTp(dec *MyDecimal, tp *FieldType, sc *stmtctx.Statem // select (cast 111 as decimal(1)) causes a warning in MySQL. err = ErrOverflow.GenWithStackByArgs("DECIMAL", fmt.Sprintf("(%d, %d)", flen, decimal)) } else if frac != decimal { - old := *dec + //old := *dec err = dec.Round(dec, decimal, ModeHalfEven) if err != nil { return nil, err } - if !dec.IsZero() && frac > decimal && dec.Compare(&old) != 0 { - sc.AppendWarning(ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", &old)) - err = nil - } + //if !dec.IsZero() && frac > decimal && dec.Compare(&old) != 0 { + // sc.AppendWarning(ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", &old)) + // err = nil + //} } } diff --git a/types/mydecimal_test.go b/types/mydecimal_test.go index 3f94287fb6e48..b44d58a6d4ab7 100644 --- a/types/mydecimal_test.go +++ b/types/mydecimal_test.go @@ -504,8 +504,8 @@ func (s *testMyDecimalSerialSuite) TestFromString(c *C) { tests := []tcase{ {"12345", "12345", nil}, {"12345.", "12345", nil}, - {"123.45.", "123.45", nil}, - {"-123.45.", "-123.45", nil}, + {"123.45.", "123.45", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "123.45.")}, + {"-123.45.", "-123.45", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "-123.45.")}, {".00012345000098765", "0.00012345000098765", nil}, {".12345000098765", "0.12345000098765", nil}, {"-.000000012345000098765", "-0.000000012345000098765", nil}, @@ -515,18 +515,20 @@ func (s *testMyDecimalSerialSuite) TestFromString(c *C) { {"1e1073741823", "999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow}, {"-1e1073741823", "-999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow}, {"1e18446744073709551620", "0", ErrBadNumber}, - {"1e", "1", ErrTruncated}, + {"1e", "1", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1e")}, {"1e001", "10", nil}, {"1e00", "1", nil}, - {"1eabc", "1", ErrTruncated}, - {"1e 1dddd ", "10", ErrTruncated}, - {"1e - 1", "1", ErrTruncated}, + {"1eabc", "1", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1eabc")}, + {"1e 1dddd ", "10", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1e 1dddd ")}, + {"1e - 1", "1", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1e - 1")}, {"1e -1", "0.1", nil}, - {"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0.000000000000000000000000000000000000000000000000000000000000000000000000", ErrTruncated}, - {"0.1a2", "0.1", ErrTruncated}, - {"123aE5", "123", ErrTruncated}, - {"123E5a", "123", ErrTruncated}, - {"1 1", "1", ErrTruncated}, + {"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0.000000000000000000000000000000000000000000000000000000000000000000000000", + ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "0.000000000000000000000000000000000000000000000000000000000000000000000000")}, + {"0.1a2", "0.1", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "0.1a2")}, + {"123aE5", "123", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "123aE5")}, + {"123E5a", "123", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "123E5a")}, + {"1 1", "1", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1 1")}, } for _, ca := range tests { var dec MyDecimal From 7393274c340157aeeb96d6d428c4a94bdb93c956 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 09:58:38 +0800 Subject: [PATCH 06/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- types/convert_test.go | 5 +++-- types/mydecimal.go | 14 +++++++++++--- types/mydecimal_test.go | 24 +++++++++++++++++++----- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/types/convert_test.go b/types/convert_test.go index 34a5f5aea5435..0d798d1d8afa7 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -244,10 +244,11 @@ func (s *testTypeConvertSuite) TestConvertType(c *C) { 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(terror.ErrorEqual(err, + ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1,999.00")), 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(terror.ErrorEqual(err, ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1,999,999.00")), IsTrue, Commentf("err %v", err)) c.Assert(v.(*MyDecimal).String(), Equals, "1.0000") v, err = Convert("199.00 ", ft) c.Assert(err, IsNil) diff --git a/types/mydecimal.go b/types/mydecimal.go index 4a2b964c66411..cb44c75f58f69 100644 --- a/types/mydecimal.go +++ b/types/mydecimal.go @@ -413,14 +413,22 @@ 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 strBak = str var strErr error + var strBak = str for i := 0; i < len(str); i++ { if !isSpace(str[i]) { str = str[i:] break } } + // trim space in the end + for j := len(str) - 1; j >= 0; j-- { + if !isSpace(str[j]) { + str = str[:j+1] + break + } + } + if len(str) == 0 { *d = zeroMyDecimal return ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) @@ -445,7 +453,7 @@ func (d *MyDecimal) FromString(str []byte) error { endIdx++ } - if endIdx != len(str) { + if endIdx < len(str) && str[endIdx] != 'E' && str[endIdx] != 'e' && str[endIdx] != ' ' { strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(strBak)) } digitsFrac = endIdx - strIdx - 1 @@ -550,7 +558,7 @@ func (d *MyDecimal) FromString(str []byte) error { strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) } - if strErr == nil && (endIdx+1 <= len(str) && str[endIdx] == ' ') { + if strErr == nil && (endIdx+1 < len(str) && str[endIdx] == ' ') { strErr = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", string(str)) } diff --git a/types/mydecimal_test.go b/types/mydecimal_test.go index b44d58a6d4ab7..3c8f7f97ffda1 100644 --- a/types/mydecimal_test.go +++ b/types/mydecimal_test.go @@ -14,6 +14,7 @@ package types import ( + "github.com/pingcap/parser/terror" "strings" "testing" @@ -524,28 +525,41 @@ func (s *testMyDecimalSerialSuite) TestFromString(c *C) { {"1e -1", "0.1", nil}, {"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0.000000000000000000000000000000000000000000000000000000000000000000000000", - ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "0.000000000000000000000000000000000000000000000000000000000000000000000000")}, + ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", + "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")}, {"0.1a2", "0.1", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "0.1a2")}, {"123aE5", "123", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "123aE5")}, - {"123E5a", "123", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "123E5a")}, + {"123E5a", "12300000", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "123E5a")}, {"1 1", "1", ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "1 1")}, } for _, ca := range tests { var dec MyDecimal err := dec.FromString([]byte(ca.input)) - c.Check(err, Equals, ca.err, Commentf("input: %s", ca.input)) + + //if err == nil || ca.err == nil { + // c.Check(err, Equals, ca.err, Commentf("input: %s", ca.input)) + //} else { + // c.Check(err.Error(), Equals, ca.err.Error(), Commentf("input: %s", ca.input)) + //} + c.Assert(terror.ErrorEqual(err, ca.err), IsTrue, Commentf("input: %s", ca.input)) result := dec.ToString() c.Check(string(result), Equals, ca.output, Commentf("dec:%s", dec.String())) } wordBufLen = 1 tests = []tcase{ {"123450000098765", "98765", ErrOverflow}, - {"123450.000098765", "123450", ErrTruncated}, + {"123450.000098765", "123450", + ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", "123450.000098765")}, } for _, ca := range tests { var dec MyDecimal err := dec.FromString([]byte(ca.input)) - c.Check(err, Equals, ca.err) + //if err == nil || ca.err == nil { + // c.Check(err, Equals, ca.err) + //} else { + // c.Check(err.Error(), Equals, ca.err.Error()) + //} + c.Assert(terror.ErrorEqual(err, ca.err), IsTrue) result := dec.ToString() c.Check(string(result), Equals, ca.output, Commentf("dec:%s", dec.String())) } From 66235fcf6aa6ce065399c8a0124dd1d9ebbf5a37 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 10:34:56 +0800 Subject: [PATCH 07/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- types/mydecimal_test.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/types/mydecimal_test.go b/types/mydecimal_test.go index e817de2075bb9..22a160ee3c5e3 100644 --- a/types/mydecimal_test.go +++ b/types/mydecimal_test.go @@ -565,11 +565,6 @@ func (s *testMyDecimalSerialSuite) TestFromString(c *C) { var dec MyDecimal err := dec.FromString([]byte(ca.input)) - //if err == nil || ca.err == nil { - // c.Check(err, Equals, ca.err, Commentf("input: %s", ca.input)) - //} else { - // c.Check(err.Error(), Equals, ca.err.Error(), Commentf("input: %s", ca.input)) - //} c.Assert(terror.ErrorEqual(err, ca.err), IsTrue, Commentf("input: %s", ca.input)) result := dec.ToString() c.Check(string(result), Equals, ca.output, Commentf("dec:%s", dec.String())) @@ -583,11 +578,6 @@ func (s *testMyDecimalSerialSuite) TestFromString(c *C) { for _, ca := range tests { var dec MyDecimal err := dec.FromString([]byte(ca.input)) - //if err == nil || ca.err == nil { - // c.Check(err, Equals, ca.err) - //} else { - // c.Check(err.Error(), Equals, ca.err.Error()) - //} c.Assert(terror.ErrorEqual(err, ca.err), IsTrue) result := dec.ToString() c.Check(string(result), Equals, ca.output, Commentf("dec:%s", dec.String())) From b9646b3f4c04d76b6abc2db0ff039fa2ce203e8e Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 10:55:09 +0800 Subject: [PATCH 08/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- types/mydecimal_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/mydecimal_test.go b/types/mydecimal_test.go index 22a160ee3c5e3..21ea4689a7589 100644 --- a/types/mydecimal_test.go +++ b/types/mydecimal_test.go @@ -14,12 +14,12 @@ package types import ( - "github.com/pingcap/parser/terror" "strconv" "strings" "testing" . "github.com/pingcap/check" + "github.com/pingcap/parser/terror" ) var _ = Suite(&testMyDecimalSuite{}) From b20c17bfd19d125527e813a0dfe85a8bd80f576e Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 18:34:57 +0800 Subject: [PATCH 09/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- ddl/column_type_change_test.go | 3 ++- expression/builtin_cast_vec.go | 2 +- expression/integration_test.go | 2 +- types/datum.go | 10 +++++----- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ddl/column_type_change_test.go b/ddl/column_type_change_test.go index 273522c00f874..a14cbc15145d7 100644 --- a/ddl/column_type_change_test.go +++ b/ddl/column_type_change_test.go @@ -551,7 +551,8 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromStringToOthers(c *C) reset(tk) tk.MustExec("insert into t values ('123.45', '123.45', '123.45', '123.45', '123.45', '123.45', '123', '123')") tk.MustExec("alter table t modify c decimal(7, 4)") - tk.MustExec("alter table t modify vc decimal(7, 4)") + // alter binary 0x3132332E34350000 to decimal(7,4) will get error + tk.MustGetErrCode("alter table t modify vc decimal(7, 4)", mysql.ErrTruncatedWrongValue) tk.MustExec("alter table t modify bny decimal(7, 4)") tk.MustExec("alter table t modify vbny decimal(7, 4)") tk.MustExec("alter table t modify bb decimal(7, 4)") diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index 567df361fd8c8..788d0d89a62e2 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -836,7 +836,7 @@ func (b *builtinCastRealAsDecimalSig) vecEvalDecimal(input *chunk.Chunk, result if types.ErrOverflow.Equal(err) { warnErr := types.ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", b.args[0]) err = b.ctx.GetSessionVars().StmtCtx.HandleOverflow(err, warnErr) - } else if types.ErrTruncated.Equal(err) { + } else if strings.Contains(err.Error(), "Truncated incorrect") { // This behavior is consistent with MySQL. err = nil } diff --git a/expression/integration_test.go b/expression/integration_test.go index 0b839d1a7af6a..25e231df69f9d 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2726,7 +2726,7 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { // test builtinCastStringAsDecimalSig tk.MustExec(`drop table if exists tb5`) tk.MustExec(`create table tb5 (a varchar(20));`) - tk.MustExec(`insert into tb5 values ('123', '.0a1');`) + tk.MustExec(`insert into tb5 values ('123'), ('.0a1');`) result = tk.MustQuery(`select cast(a as decimal(10, 2)) from tb5;`) result.Check(testkit.Rows("123.00", "0.00")) tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '.0a1'")) diff --git a/types/datum.go b/types/datum.go index 70baf4c9be79d..123d6e0670348 100644 --- a/types/datum.go +++ b/types/datum.go @@ -1374,15 +1374,15 @@ func ProduceDecWithSpecifiedTp(dec *MyDecimal, tp *FieldType, sc *stmtctx.Statem // select (cast 111 as decimal(1)) causes a warning in MySQL. err = ErrOverflow.GenWithStackByArgs("DECIMAL", fmt.Sprintf("(%d, %d)", flen, decimal)) } else if frac != decimal { - //old := *dec + old := *dec err = dec.Round(dec, decimal, ModeHalfEven) if err != nil { return nil, err } - //if !dec.IsZero() && frac > decimal && dec.Compare(&old) != 0 { - // sc.AppendWarning(ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", &old)) - // err = nil - //} + if !dec.IsZero() && frac > decimal && dec.Compare(&old) != 0 { + sc.AppendWarning(ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", &old)) + err = nil + } } } From e4e4165090b37edd06b8199a8d716d8ba1dad0b1 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 19:20:40 +0800 Subject: [PATCH 10/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- ddl/column_type_change_test.go | 4 ++-- expression/integration_test.go | 2 +- types/parser_driver/value_expr.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ddl/column_type_change_test.go b/ddl/column_type_change_test.go index a14cbc15145d7..c283396619368 100644 --- a/ddl/column_type_change_test.go +++ b/ddl/column_type_change_test.go @@ -551,9 +551,9 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromStringToOthers(c *C) reset(tk) tk.MustExec("insert into t values ('123.45', '123.45', '123.45', '123.45', '123.45', '123.45', '123', '123')") tk.MustExec("alter table t modify c decimal(7, 4)") + tk.MustExec("alter table t modify vc decimal(7, 4)") // alter binary 0x3132332E34350000 to decimal(7,4) will get error - tk.MustGetErrCode("alter table t modify vc decimal(7, 4)", mysql.ErrTruncatedWrongValue) - tk.MustExec("alter table t modify bny decimal(7, 4)") + tk.MustGetErrCode("alter table t modify bny decimal(7, 4)", mysql.ErrTruncatedWrongValue) tk.MustExec("alter table t modify vbny decimal(7, 4)") tk.MustExec("alter table t modify bb decimal(7, 4)") tk.MustExec("alter table t modify txt decimal(7, 4)") diff --git a/expression/integration_test.go b/expression/integration_test.go index 25e231df69f9d..0802a920a7396 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2732,7 +2732,7 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '.0a1'")) result = tk.MustQuery("select cast('123E5a' as decimal(10,2));") - result.Check(testkit.Rows("123.00")) + result.Check(testkit.Rows("12300000.00")) tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '123E5a'")) result = tk.MustQuery(`select cast('123aE5 ' as decimal(10, 2));`) diff --git a/types/parser_driver/value_expr.go b/types/parser_driver/value_expr.go index d3f358994f5be..549a64c1e1b9a 100644 --- a/types/parser_driver/value_expr.go +++ b/types/parser_driver/value_expr.go @@ -46,7 +46,7 @@ func init() { ast.NewDecimal = func(str string) (interface{}, error) { dec := new(types.MyDecimal) err := dec.FromString(hack.Slice(str)) - if err == types.ErrTruncated { + if err == types.ErrTruncated || (err != nil && strings.Contains(err.Error(), "Truncate incorrect")) { err = nil } return dec, err From cc2277d293019d1bbe29bff0a96971364374f518 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 19:45:13 +0800 Subject: [PATCH 11/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- ddl/column_type_change_test.go | 2 +- expression/integration_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ddl/column_type_change_test.go b/ddl/column_type_change_test.go index c283396619368..480bc1f11cb2d 100644 --- a/ddl/column_type_change_test.go +++ b/ddl/column_type_change_test.go @@ -559,7 +559,7 @@ func (s *testColumnTypeChangeSuite) TestColumnTypeChangeFromStringToOthers(c *C) tk.MustExec("alter table t modify txt decimal(7, 4)") tk.MustExec("alter table t modify e decimal(7, 4)") tk.MustExec("alter table t modify s decimal(7, 4)") - tk.MustQuery("select * from t").Check(testkit.Rows("123.4500 123.4500 123.4500 123.4500 123.4500 123.4500 1.0000 1.0000")) + tk.MustQuery("select * from t").Check(testkit.Rows("123.4500 123.4500 123.45\x00\x00 123.4500 123.4500 123.4500 1.0000 1.0000")) // double reset(tk) tk.MustExec("insert into t values ('123.45', '123.45', '123.45', '123.45', '123.45', '123.45', '123', '123')") diff --git a/expression/integration_test.go b/expression/integration_test.go index 0802a920a7396..439000616ccbf 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2737,7 +2737,7 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { result = tk.MustQuery(`select cast('123aE5 ' as decimal(10, 2));`) result.Check(testkit.Rows("123.00")) - tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '123aE5 '")) + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '123aE5'")) result = tk.MustQuery(`select cast('1e - 1' as decimal);`) result.Check(testkit.Rows("0")) From 8f76d73e01fa95bf8a49675e269defdd848c26f9 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 19:51:09 +0800 Subject: [PATCH 12/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- expression/integration_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/expression/integration_test.go b/expression/integration_test.go index 439000616ccbf..cca22223e465b 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2735,10 +2735,14 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { result.Check(testkit.Rows("12300000.00")) tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '123E5a'")) - result = tk.MustQuery(`select cast('123aE5 ' as decimal(10, 2));`) + result = tk.MustQuery(`select cast('123aE5' as decimal(10, 2));`) result.Check(testkit.Rows("123.00")) tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '123aE5'")) + result = tk.MustQuery(`select cast('1.4a' as decimal(10, 2));`) + result.Check(testkit.Rows("1.40")) + tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '1.4a'")) + result = tk.MustQuery(`select cast('1e - 1' as decimal);`) result.Check(testkit.Rows("0")) tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '1e - 1'")) From a65bd7bacef1a1ab7cba3791c754c515d6a42a16 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 20:07:00 +0800 Subject: [PATCH 13/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- expression/integration_test.go | 2 +- types/parser_driver/value_expr.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/expression/integration_test.go b/expression/integration_test.go index cca22223e465b..96cec0f91e797 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2744,7 +2744,7 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '1.4a'")) result = tk.MustQuery(`select cast('1e - 1' as decimal);`) - result.Check(testkit.Rows("0")) + result.Check(testkit.Rows("1")) tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Truncated incorrect DECIMAL value: '1e - 1'")) result = tk.MustQuery(`select cast('1 1' as decimal)`) diff --git a/types/parser_driver/value_expr.go b/types/parser_driver/value_expr.go index 549a64c1e1b9a..ec40539e566ac 100644 --- a/types/parser_driver/value_expr.go +++ b/types/parser_driver/value_expr.go @@ -46,7 +46,8 @@ func init() { ast.NewDecimal = func(str string) (interface{}, error) { dec := new(types.MyDecimal) err := dec.FromString(hack.Slice(str)) - if err == types.ErrTruncated || (err != nil && strings.Contains(err.Error(), "Truncate incorrect")) { + if err == types.ErrTruncated || (err != nil && + strings.Contains(err.Error(), "Truncated incorrect MyDecimal")) { err = nil } return dec, err From 05258c7c8273c5ea1d3ae7866c067e218ebb57d2 Mon Sep 17 00:00:00 2001 From: yuqi1129 Date: Fri, 9 Jul 2021 20:18:19 +0800 Subject: [PATCH 14/14] expression: fix cast string like '.1a1' to decimal has no warnings infromation --- types/parser_driver/value_expr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/parser_driver/value_expr.go b/types/parser_driver/value_expr.go index ec40539e566ac..a61f704dcf09e 100644 --- a/types/parser_driver/value_expr.go +++ b/types/parser_driver/value_expr.go @@ -47,7 +47,7 @@ func init() { dec := new(types.MyDecimal) err := dec.FromString(hack.Slice(str)) if err == types.ErrTruncated || (err != nil && - strings.Contains(err.Error(), "Truncated incorrect MyDecimal")) { + strings.Contains(err.Error(), "Truncated incorrect")) { err = nil } return dec, err