diff --git a/expression/integration_test.go b/expression/integration_test.go index d70786f8c46cb..99e732dce6bff 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2062,6 +2062,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 1d60604aeb50d..72e5520c4b243 100644 --- a/types/convert.go +++ b/types/convert.go @@ -537,7 +537,12 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned u, err := ConvertFloatToUint(sc, f, bound, mysql.TypeLonglong) return int64(u), errors.Trace(err) case json.TypeCodeString: - return StrToInt(sc, hack.String(j.GetString())) + str := string(hack.String(j.GetString())) + 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 5d6e9b383e8b7..f968ca8783ebc 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -733,22 +733,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 @@ -758,7 +760,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 {