From ec849d1491d3fbee3ae11b3ecf7777ff41f87f09 Mon Sep 17 00:00:00 2001 From: "TONG, Zhigao" Date: Tue, 14 May 2024 17:09:18 +0800 Subject: [PATCH] Revert "expression: unify casting real to string in tidb (tikv#16975) (#53129)" This reverts commit f311d7751aa0a7834addbea6ddbbe63f56382461. --- pkg/expression/builtin_cast.go | 36 +------------------ pkg/expression/builtin_cast_test.go | 55 ----------------------------- pkg/expression/builtin_cast_vec.go | 2 +- 3 files changed, 2 insertions(+), 91 deletions(-) diff --git a/pkg/expression/builtin_cast.go b/pkg/expression/builtin_cast.go index 3aac238d86e10..134b6b88ce0a5 100644 --- a/pkg/expression/builtin_cast.go +++ b/pkg/expression/builtin_cast.go @@ -23,7 +23,6 @@ package expression import ( - "bytes" "fmt" "math" "strconv" @@ -1037,39 +1036,6 @@ func (b *builtinCastRealAsStringSig) Clone() builtinFunc { return newSig } -func formatFloat(f float64, bitSize int) string { - // MySQL makes float to string max 6 significant digits - // MySQL makes double to string max 17 significant digits - - // Unified to display behavior of TiDB. TiKV should also follow this rule. - const ( - expFormatBig = 1e15 - expFormatSmall = 1e-15 - ) - - absVal := math.Abs(f) - isEFormat := false - - if bitSize == 32 { - isEFormat = float32(absVal) >= float32(expFormatBig) || (float32(absVal) != 0 && float32(absVal) < float32(expFormatSmall)) - } else { - isEFormat = absVal >= expFormatBig || (absVal != 0 && absVal < expFormatSmall) - } - - dst := make([]byte, 0, 24) - if isEFormat { - dst = strconv.AppendFloat(dst, f, 'e', -1, bitSize) - if idx := bytes.IndexByte(dst, '+'); idx != -1 { - copy(dst[idx:], dst[idx+1:]) - dst = dst[:len(dst)-1] - } - } else { - dst = strconv.AppendFloat(dst, f, 'f', -1, bitSize) - } - - return string(dst) -} - func (b *builtinCastRealAsStringSig) evalString(ctx EvalContext, row chunk.Row) (res string, isNull bool, err error) { val, isNull, err := b.args[0].EvalReal(ctx, row) if isNull || err != nil { @@ -1083,7 +1049,7 @@ func (b *builtinCastRealAsStringSig) evalString(ctx EvalContext, row chunk.Row) // If we strconv.FormatFloat the value with 64bits, the result is incorrect! bits = 32 } - res, err = types.ProduceStrWithSpecifiedTp(formatFloat(val, bits), b.tp, typeCtx(ctx), false) + res, err = types.ProduceStrWithSpecifiedTp(strconv.FormatFloat(val, 'f', -1, bits), b.tp, typeCtx(ctx), false) if err != nil { return res, false, err } diff --git a/pkg/expression/builtin_cast_test.go b/pkg/expression/builtin_cast_test.go index 4e60397a199b8..4f106a5837961 100644 --- a/pkg/expression/builtin_cast_test.go +++ b/pkg/expression/builtin_cast_test.go @@ -1116,61 +1116,6 @@ func TestCastFuncSig(t *testing.T) { require.False(t, iRes.IsNull()) require.Equal(t, types.KindInt64, iRes.Kind()) require.Equal(t, int64(0), iRes.GetInt64()) - - // test cast real to string - zero := float32(0.00) - negZero := -zero - castFloat32ToStringCases := []struct { - v float32 - expect string - }{ - {negZero, "-0"}, - {00000.0, "0"}, - {4474.78125, "4474.7812"}, - {1e15, "1e15"}, - {-1e15, "-1e15"}, - {9.99999e14, "999999000000000"}, - {-9.99999e14, "-999999000000000"}, - {1e15 - 1.0, "1e15"}, - {-3.4028235e38, "-3.4028235e38"}, - {3.4028235e38, "3.4028235e38"}, - {1.1754944e-38, "1.1754944e-38"}, - {1.000, "1"}, - {-123456789123000.0, "-123456790000000"}, - {1e-15, "0.000000000000001"}, - {9.9999e-16, "9.9999e-16"}, - {1.23456789123000e-9, "0.0000000012345679"}, - } - - for _, d := range castFloat32ToStringCases { - require.Equal(t, formatFloat(float64(d.v), 32), d.expect) - } - - castFloat64ToStringCases := []struct { - v float64 - expect string - }{ - {float64(negZero), "-0"}, - {00000.0, "0"}, - {4474.78125, "4474.78125"}, - {1e15, "1e15"}, - {-1e15, "-1e15"}, - {9.99999e14, "999999000000000"}, - {-9.99999e14, "-999999000000000"}, - {1e15 - 1.0, "999999999999999"}, - {-1.7976931348623157e308, "-1.7976931348623157e308"}, - {1.7976931348623157e308, "1.7976931348623157e308"}, - {2.2250738585072014e-308, "2.2250738585072014e-308"}, - {1.000, "1"}, - {-123456789123000.0, "-123456789123000"}, - {1e-15, "0.000000000000001"}, - {9.9999e-16, "9.9999e-16"}, - {1.23456789123000e-9, "0.00000000123456789123"}, - } - - for _, d := range castFloat64ToStringCases { - require.Equal(t, formatFloat(d.v, 64), d.expect) - } } func TestCastJSONAsDecimalSig(t *testing.T) { diff --git a/pkg/expression/builtin_cast_vec.go b/pkg/expression/builtin_cast_vec.go index 0ffe672b7f0e1..bce2383171338 100644 --- a/pkg/expression/builtin_cast_vec.go +++ b/pkg/expression/builtin_cast_vec.go @@ -221,7 +221,7 @@ func (b *builtinCastRealAsStringSig) vecEvalString(ctx EvalContext, input *chunk result.AppendNull() continue } - res, err = types.ProduceStrWithSpecifiedTp(formatFloat(v, bits), b.tp, tc, false) + res, err = types.ProduceStrWithSpecifiedTp(strconv.FormatFloat(v, 'f', -1, bits), b.tp, tc, false) if err != nil { return err }