diff --git a/types/convert.go b/types/convert.go index 5e16ad43ac2d1..58913cb2252eb 100644 --- a/types/convert.go +++ b/types/convert.go @@ -394,6 +394,9 @@ func roundIntStr(numNextDot byte, intStr string) string { // strconv.ParseInt, we can't parse float first then convert it to string because precision will // be lost. For example, the string value "18446744073709551615" which is the max number of unsigned // int will cause some precision to lose. intStr[0] may be a positive and negative sign like '+' or '-'. +// +// This func will find serious overflow such as the len of intStr > 20 (without prefix `+/-`) +// however, it will not check whether the intStr overflow BIGINT. func floatStrToIntStr(sc *stmtctx.StatementContext, validFloat string, oriStr string) (intStr string, _ error) { var dotIdx = -1 var eIdx = -1 @@ -443,12 +446,15 @@ func floatStrToIntStr(sc *stmtctx.StatementContext, validFloat string, oriStr st if err != nil { return validFloat, errors.Trace(err) } - if exp > 0 && int64(intCnt) > (math.MaxInt64-int64(exp)) { - // (exp + incCnt) overflows MaxInt64. + intCnt += exp + if exp >= 0 && (intCnt > 21 || intCnt < 0) { + // MaxInt64 has 19 decimal digits. + // MaxUint64 has 20 decimal digits. + // And the intCnt may contain the len of `+/-`, + // so I use 21 here as the early detection. sc.AppendWarning(ErrOverflow.GenWithStackByArgs("BIGINT", oriStr)) return validFloat[:eIdx], nil } - intCnt += exp if intCnt <= 0 { intStr = "0" if intCnt == 0 && len(digits) > 0 { @@ -474,11 +480,6 @@ func floatStrToIntStr(sc *stmtctx.StatementContext, validFloat string, oriStr st } else { // convert scientific notation decimal number extraZeroCount := intCnt - len(digits) - if extraZeroCount > 20 { - // Append overflow warning and return to avoid allocating too much memory. - sc.AppendWarning(ErrOverflow.GenWithStackByArgs("BIGINT", oriStr)) - return validFloat[:eIdx], nil - } intStr = string(digits) + strings.Repeat("0", extraZeroCount) } return intStr, nil diff --git a/types/convert_test.go b/types/convert_test.go index c591650952056..47f13e99306ad 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -708,6 +708,7 @@ func (s *testTypeConvertSuite) TestGetValidFloat(c *C) { {".5e0", "1"}, {"+.5e0", "+1"}, {"-.5e0", "-1"}, + {".5", "1"}, {"123.456789e5", "12345679"}, {"123.456784e5", "12345678"}, }