diff --git a/expression/integration_test.go b/expression/integration_test.go index 1e0da39536561..04b4526e3cb53 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2180,6 +2180,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 079a2b0e152ba..4a8368332b5f7 100644 --- a/types/convert.go +++ b/types/convert.go @@ -567,7 +567,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 2d5c97cc2a215..de86c398f7195 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -721,22 +721,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 @@ -746,7 +748,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 {