diff --git a/expression/builtin_cast.go b/expression/builtin_cast.go index 4c16f1b6b2b96..302e72e2140e4 100644 --- a/expression/builtin_cast.go +++ b/expression/builtin_cast.go @@ -746,6 +746,10 @@ func (b *builtinCastRealAsIntSig) evalInt(row chunk.Row) (res int64, isNull bool uintVal, err = types.ConvertFloatToUint(sc, val, types.IntergerUnsignedUpperBound(mysql.TypeLonglong), mysql.TypeLonglong) res = int64(uintVal) } + err = b.ctx.GetSessionVars().StmtCtx.HandleOverflow(err, err) + if err != nil { + return res, false, err + } return res, isNull, err } diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index a524d1c6d7bde..f7157051bc57e 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -500,7 +500,7 @@ func (b *builtinCastRealAsIntSig) vecEvalInt(input *chunk.Chunk, result *chunk.C uintVal, err = types.ConvertFloatToUint(sc, f64s[i], types.IntergerUnsignedUpperBound(mysql.TypeLonglong), mysql.TypeLonglong) i64s[i] = int64(uintVal) } - + err = b.ctx.GetSessionVars().StmtCtx.HandleOverflow(err, err) if err != nil { return err } diff --git a/expression/integration_test.go b/expression/integration_test.go index 91301e35ca9b7..e07c4f47fee6a 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -2232,6 +2232,13 @@ func (s *testIntegrationSuite2) TestBuiltin(c *C) { c.Assert(last, Equals, "bigint") tk.MustExec(`drop table tb5;`) + tk.MustExec(`create table tb5(a double(64));`) + tk.MustExec(`insert into test.tb5 (a) values (18446744073709551616);`) + tk.MustExec(`insert into test.tb5 (a) values (184467440737095516160);`) + result = tk.MustQuery(`select cast(a as unsigned) from test.tb5;`) + result.Check(testkit.Rows("9223372036854775807", "9223372036854775807")) + tk.MustExec(`drop table tb5`) + // test builtinCastIntAsDecimalSig tk.MustExec(`create table tb5(a bigint(64) unsigned, b decimal(64, 10));`) tk.MustExec(`insert into tb5 (a, b) values (9223372036854775808, 9223372036854775808);`) diff --git a/types/convert.go b/types/convert.go index db9c9dfdb5a4a..f3d841113d736 100644 --- a/types/convert.go +++ b/types/convert.go @@ -168,8 +168,12 @@ func ConvertFloatToUint(sc *stmtctx.StatementContext, fval float64, upperBound u return uint64(int64(val)), overflow(val, tp) } - if val > float64(upperBound) { - return upperBound, overflow(val, tp) + ubf := float64(upperBound) + if val == ubf { + return uint64(math.MaxInt64), nil + } + if val > ubf { + return uint64(math.MaxInt64), overflow(val, tp) } return uint64(val), nil } diff --git a/types/convert_test.go b/types/convert_test.go index e97cfa96d0e2a..f88defda557be 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -615,7 +615,7 @@ func (s *testTypeConvertSuite) TestConvert(c *C) { unsignedAccept(c, mysql.TypeLonglong, -1, "18446744073709551615") unsignedAccept(c, mysql.TypeLonglong, 0, "0") unsignedAccept(c, mysql.TypeLonglong, uint64(math.MaxUint64), strvalue(uint64(math.MaxUint64))) - unsignedDeny(c, mysql.TypeLonglong, math.MaxUint64*1.1, strvalue(uint64(math.MaxUint64))) + unsignedDeny(c, mysql.TypeLonglong, math.MaxUint64*1.1, strvalue(uint64(math.MaxInt64))) // integer from string signedAccept(c, mysql.TypeLong, " 234 ", "234")