From 2e0d32fdeee84c16fa2972855403a046c9fc9bf4 Mon Sep 17 00:00:00 2001 From: pingcap-github-bot Date: Mon, 5 Aug 2019 15:16:46 +0800 Subject: [PATCH] fix ConvertJSONToInt unsigned bug (#11483) (#11551) --- expression/integration_test.go | 1 + types/convert.go | 6 +++++- types/convert_test.go | 36 ++++++++++++++++++++-------------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/expression/integration_test.go b/expression/integration_test.go index 381dcae4cad6a..c67d53e446492 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2173,6 +2173,7 @@ func (s *testIntegrationSuite) TestBuiltin(c *C) { result.Check(testkit.Rows("2017-01-01 00:00:00.00")) result = tk.MustQuery(`select cast(20170118.999 as datetime);`) result.Check(testkit.Rows("2017-01-18 00:00:00")) + tk.MustQuery(`select convert(a2.a, unsigned int) from (select cast('"9223372036854775808"' as json) as a) as a2;`) tk.MustExec(`create table tb5(a bigint(64) unsigned, b double);`) tk.MustExec(`insert into tb5 (a, b) values (9223372036854776000, 9223372036854776000);`) diff --git a/types/convert.go b/types/convert.go index d202c5ceb806a..2cb4998e150c0 100644 --- a/types/convert.go +++ b/types/convert.go @@ -566,7 +566,11 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned return int64(u), errors.Trace(err) case json.TypeCodeString: str := string(hack.String(j.GetString())) - return StrToInt(sc, str) + if !unsigned { + return StrToInt(sc, str) + } + u, err := StrToUint(sc, str) + return int64(u), errors.Trace(err) } return 0, errors.New("Unknown type code in JSON") } diff --git a/types/convert_test.go b/types/convert_test.go index 9d292632e518e..3411423942d2d 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -706,22 +706,24 @@ func (s *testTypeConvertSuite) TestGetValidInt(c *C) { tests := []struct { origin string valid string + signed bool warning bool }{ - {"100", "100", false}, - {"-100", "-100", false}, - {"1abc", "1", true}, - {"-1-1", "-1", true}, - {"+1+1", "+1", true}, - {"123..34", "123", true}, - {"123.23E-10", "123", true}, - {"1.1e1.3", "1", true}, - {"11e1.3", "11", true}, - {"1.", "1", true}, - {".1", "0", true}, - {"", "0", true}, - {"123e+", "123", true}, - {"123de", "123", true}, + {"100", "100", true, false}, + {"-100", "-100", true, false}, + {"9223372036854775808", "9223372036854775808", false, false}, + {"1abc", "1", true, true}, + {"-1-1", "-1", true, true}, + {"+1+1", "+1", true, true}, + {"123..34", "123", true, true}, + {"123.23E-10", "123", true, true}, + {"1.1e1.3", "1", true, true}, + {"11e1.3", "11", true, true}, + {"1.", "1", true, true}, + {".1", "0", true, true}, + {"", "0", true, true}, + {"123e+", "123", true, true}, + {"123de", "123", true, true}, } sc := new(stmtctx.StatementContext) sc.TruncateAsWarning = true @@ -731,7 +733,11 @@ func (s *testTypeConvertSuite) TestGetValidInt(c *C) { prefix, err := getValidIntPrefix(sc, tt.origin) c.Assert(err, IsNil) c.Assert(prefix, Equals, tt.valid) - _, err = strconv.ParseInt(prefix, 10, 64) + if tt.signed { + _, err = strconv.ParseInt(prefix, 10, 64) + } else { + _, err = strconv.ParseUint(prefix, 10, 64) + } c.Assert(err, IsNil) warnings := sc.GetWarnings() if tt.warning {