Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expression: Truncate FSP instead of rounding for utc_timestamp() | tidb-test=pr/2405 #56431

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
8 changes: 4 additions & 4 deletions pkg/expression/builtin_cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -1838,7 +1838,7 @@ func (b *builtinCastTimeAsDurationSig) evalDuration(ctx EvalContext, row chunk.R
if err != nil {
return res, false, err
}
res, err = res.RoundFrac(b.tp.GetDecimal(), location(ctx))
res, err = res.RoundFrac(b.tp.GetDecimal())
return res, false, err
}

Expand All @@ -1857,7 +1857,7 @@ func (b *builtinCastDurationAsDurationSig) evalDuration(ctx EvalContext, row chu
if isNull || err != nil {
return res, isNull, err
}
res, err = res.RoundFrac(b.tp.GetDecimal(), location(ctx))
res, err = res.RoundFrac(b.tp.GetDecimal())
return res, false, err
}

Expand All @@ -1881,7 +1881,7 @@ func (b *builtinCastDurationAsIntSig) evalInt(ctx EvalContext, row chunk.Row) (r
res, err = val.ConvertToYear(typeCtx(ctx))
} else {
var dur types.Duration
dur, err = val.RoundFrac(types.DefaultFsp, location(ctx))
dur, err = val.RoundFrac(types.DefaultFsp)
if err != nil {
return res, false, err
}
Expand Down Expand Up @@ -2207,7 +2207,7 @@ func (b *builtinCastJSONAsDurationSig) evalDuration(ctx EvalContext, row chunk.R
if err != nil {
return res, false, err
}
res, err = res.RoundFrac(b.tp.GetDecimal(), location(ctx))
res, err = res.RoundFrac(b.tp.GetDecimal())
return res, isNull, err
case types.JSONTypeCodeDuration:
res = val.GetDuration()
Expand Down
8 changes: 4 additions & 4 deletions pkg/expression/builtin_cast_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ func (b *builtinCastDurationAsIntSig) vecEvalInt(ctx EvalContext, input *chunk.C
i64s[i], err = duration.ConvertToYear(tc)
} else {
var dur types.Duration
dur, err = duration.RoundFrac(types.DefaultFsp, location(ctx))
dur, err = duration.RoundFrac(types.DefaultFsp)
if err != nil {
return err
}
Expand Down Expand Up @@ -1346,7 +1346,7 @@ func (b *builtinCastTimeAsDurationSig) vecEvalDuration(ctx EvalContext, input *c
if err != nil {
return err
}
d, err = d.RoundFrac(b.tp.GetDecimal(), location(ctx))
d, err = d.RoundFrac(b.tp.GetDecimal())
if err != nil {
return err
}
Expand Down Expand Up @@ -1375,7 +1375,7 @@ func (b *builtinCastDurationAsDurationSig) vecEvalDuration(ctx EvalContext, inpu
continue
}
dur.Duration = v
rd, err = dur.RoundFrac(b.tp.GetDecimal(), location(ctx))
rd, err = dur.RoundFrac(b.tp.GetDecimal())
if err != nil {
return err
}
Expand Down Expand Up @@ -1981,7 +1981,7 @@ func (b *builtinCastJSONAsDurationSig) vecEvalDuration(ctx EvalContext, input *c
if err != nil {
return err
}
d, err = d.RoundFrac(b.tp.GetDecimal(), location(ctx))
d, err = d.RoundFrac(b.tp.GetDecimal())
if err != nil {
return err
}
Expand Down
15 changes: 7 additions & 8 deletions pkg/expression/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -2060,7 +2060,7 @@ func (b *builtinSysDateWithFspSig) evalTime(ctx EvalContext, row chunk.Row) (val

loc := location(ctx)
now := time.Now().In(loc)
result, err := convertTimeToMysqlTime(now, int(fsp), types.ModeHalfUp)
result, err := convertTimeToMysqlTime(now, int(fsp), types.ModeTruncate)
if err != nil {
return types.ZeroTime, true, err
}
Expand All @@ -2082,7 +2082,7 @@ func (b *builtinSysDateWithoutFspSig) Clone() builtinFunc {
func (b *builtinSysDateWithoutFspSig) evalTime(ctx EvalContext, row chunk.Row) (val types.Time, isNull bool, err error) {
tz := location(ctx)
now := time.Now().In(tz)
result, err := convertTimeToMysqlTime(now, 0, types.ModeHalfUp)
result, err := convertTimeToMysqlTime(now, 0, types.ModeTruncate)
if err != nil {
return types.ZeroTime, true, err
}
Expand Down Expand Up @@ -2181,7 +2181,7 @@ func (b *builtinCurrentTime0ArgSig) evalDuration(ctx EvalContext, row chunk.Row)
return types.Duration{}, true, err
}
dur := nowTs.In(tz).Format(types.TimeFormat)
res, _, err := types.ParseDuration(typeCtx(ctx), dur, types.MinFsp)
res, _, err := types.ParseDurationTruncateFsp(typeCtx(ctx), dur, types.MinFsp)
if err != nil {
return types.Duration{}, true, err
}
Expand Down Expand Up @@ -2209,8 +2209,7 @@ func (b *builtinCurrentTime1ArgSig) evalDuration(ctx EvalContext, row chunk.Row)
return types.Duration{}, true, err
}
dur := nowTs.In(tz).Format(types.TimeFSPFormat)
tc := typeCtx(ctx)
res, _, err := types.ParseDuration(tc, dur, int(fsp))
res, _, err := types.ParseDurationTruncateFsp(typeCtx(ctx), dur, int(fsp))
if err != nil {
return types.Duration{}, true, err
}
Expand Down Expand Up @@ -2404,7 +2403,7 @@ func evalUTCTimestampWithFsp(ctx EvalContext, fsp int) (types.Time, bool, error)
if err != nil {
return types.ZeroTime, true, err
}
result, err := convertTimeToMysqlTime(nowTs.UTC(), fsp, types.ModeHalfUp)
result, err := convertTimeToMysqlTime(nowTs.UTC(), fsp, types.ModeTruncate)
if err != nil {
return types.ZeroTime, true, err
}
Expand Down Expand Up @@ -6492,7 +6491,7 @@ func (b *builtinUTCTimeWithoutArgSig) evalDuration(ctx EvalContext, row chunk.Ro
if err != nil {
return types.Duration{}, true, err
}
v, _, err := types.ParseDuration(typeCtx(ctx), nowTs.UTC().Format(types.TimeFormat), 0)
v, _, err := types.ParseDurationTruncateFsp(typeCtx(ctx), nowTs.UTC().Format(types.TimeFormat), 0)
return v, false, err
}

Expand Down Expand Up @@ -6523,7 +6522,7 @@ func (b *builtinUTCTimeWithArgSig) evalDuration(ctx EvalContext, row chunk.Row)
if err != nil {
return types.Duration{}, true, err
}
v, _, err := types.ParseDuration(typeCtx(ctx), nowTs.UTC().Format(types.TimeFSPFormat), int(fsp))
v, _, err := types.ParseDurationTruncateFsp(typeCtx(ctx), nowTs.UTC().Format(types.TimeFSPFormat), int(fsp))
return v, false, err
}

Expand Down
12 changes: 6 additions & 6 deletions pkg/expression/builtin_time_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ func (b *builtinSysDateWithoutFspSig) vecEvalTime(ctx EvalContext, input *chunk.

result.ResizeTime(n, false)
times := result.Times()
t, err := convertTimeToMysqlTime(now, 0, types.ModeHalfUp)
t, err := convertTimeToMysqlTime(now, 0, types.ModeTruncate)
if err != nil {
return err
}
Expand Down Expand Up @@ -411,7 +411,7 @@ func (b *builtinUTCTimeWithArgSig) vecEvalDuration(ctx EvalContext, input *chunk
if fsp < int64(types.MinFsp) {
return errors.Errorf("Invalid negative %d specified, must in [0, 6]", fsp)
}
res, _, err := types.ParseDuration(tc, utc, int(fsp))
res, _, err := types.ParseDurationTruncateFsp(tc, utc, int(fsp))
if err != nil {
return err
}
Expand Down Expand Up @@ -765,7 +765,7 @@ func (b *builtinSysDateWithFspSig) vecEvalTime(ctx EvalContext, input *chunk.Chu
if result.IsNull(i) {
continue
}
t, err := convertTimeToMysqlTime(now, int(ds[i]), types.ModeHalfUp)
t, err := convertTimeToMysqlTime(now, int(ds[i]), types.ModeTruncate)
if err != nil {
return err
}
Expand Down Expand Up @@ -1959,7 +1959,7 @@ func (b *builtinUTCTimeWithoutArgSig) vecEvalDuration(ctx EvalContext, input *ch
if err != nil {
return err
}
res, _, err := types.ParseDuration(typeCtx(ctx), nowTs.UTC().Format(types.TimeFormat), types.DefaultFsp)
res, _, err := types.ParseDurationTruncateFsp(typeCtx(ctx), nowTs.UTC().Format(types.TimeFormat), types.DefaultFsp)
if err != nil {
return err
}
Expand Down Expand Up @@ -2362,7 +2362,7 @@ func (b *builtinCurrentTime0ArgSig) vecEvalDuration(ctx EvalContext, input *chun
}
tz := location(ctx)
dur := nowTs.In(tz).Format(types.TimeFormat)
res, _, err := types.ParseDuration(typeCtx(ctx), dur, types.MinFsp)
res, _, err := types.ParseDurationTruncateFsp(typeCtx(ctx), dur, types.MinFsp)
if err != nil {
return err
}
Expand Down Expand Up @@ -2556,7 +2556,7 @@ func (b *builtinCurrentTime1ArgSig) vecEvalDuration(ctx EvalContext, input *chun
result.ResizeGoDuration(n, false)
durations := result.GoDurations()
for i := 0; i < n; i++ {
res, _, err := types.ParseDuration(tc, dur, int(i64s[i]))
res, _, err := types.ParseDurationTruncateFsp(tc, dur, int(i64s[i]))
if err != nil {
return err
}
Expand Down
81 changes: 65 additions & 16 deletions pkg/expression/integration_test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1421,30 +1421,79 @@ func TestIssue9710(t *testing.T) {
store := testkit.CreateMockStore(t)

tk := testkit.NewTestKit(t, store)
getSAndMS := func(str string) (int, int) {
getSAndMS := func(str string) (string, string) {
results := strings.Split(str, ":")
SAndMS := strings.Split(results[len(results)-1], ".")
var s, ms int
s, _ = strconv.Atoi(SAndMS[0])
if len(SAndMS) > 1 {
ms, _ = strconv.Atoi(SAndMS[1])
return SAndMS[0], SAndMS[1]
}
return s, ms
return SAndMS[0], ""
}

for {
rs := tk.MustQuery("select now(), now(6), unix_timestamp(), unix_timestamp(now())")
s, ms := getSAndMS(rs.Rows()[0][1].(string))
if ms < 500000 {
time.Sleep(time.Second / 10)
continue
rs := tk.MustQuery("select now(), now(4), now(6), unix_timestamp(), unix_timestamp(now()), unix_timestamp(now(5)), unix_timestamp(now(6)), utc_timestamp(), utc_timestamp(3), utc_timestamp(6), sysdate(), sysdate(2), sysdate(6), curtime(), curtime(1), curtime(6), utc_time(), utc_time(5), utc_time(6)")
n0, nms0 := getSAndMS(rs.Rows()[0][0].(string))
n4, nms4 := getSAndMS(rs.Rows()[0][1].(string))
n6, nms6 := getSAndMS(rs.Rows()[0][2].(string))

unix0, unixms0 := getSAndMS(rs.Rows()[0][3].(string))
unixn0, unixnms0 := getSAndMS(rs.Rows()[0][4].(string))
unixn5, unixnms5 := getSAndMS(rs.Rows()[0][5].(string))
unixn6, unixnms6 := getSAndMS(rs.Rows()[0][6].(string))

utc0, utcms0 := getSAndMS(rs.Rows()[0][7].(string))
utc3, utcms3 := getSAndMS(rs.Rows()[0][8].(string))
utc6, utcms6 := getSAndMS(rs.Rows()[0][9].(string))

sysDate0, sysDatems0 := getSAndMS(rs.Rows()[0][10].(string))
sysDate2, sysDatems2 := getSAndMS(rs.Rows()[0][11].(string))
sysDate6, sysDatems6 := getSAndMS(rs.Rows()[0][12].(string))

curTime0, curTimems0 := getSAndMS(rs.Rows()[0][13].(string))
curTime1, curTimems1 := getSAndMS(rs.Rows()[0][14].(string))
curTime6, curTimems6 := getSAndMS(rs.Rows()[0][15].(string))

utcT0, utcTms0 := getSAndMS(rs.Rows()[0][16].(string))
utcT5, utcTms5 := getSAndMS(rs.Rows()[0][17].(string))
utcT6, utcTms6 := getSAndMS(rs.Rows()[0][18].(string))

require.Equal(t, n0, n4) // now() will truncate the result instead of rounding it
require.Equal(t, n0, n6) // now() will truncate the result instead of rounding it
require.Equal(t, nms0, "")
require.LessOrEqual(t, nms4, nms6)

require.Equal(t, unix0, unixn0)
require.Equal(t, unix0, unixn5)
require.Equal(t, unix0, unixn6)
require.Equal(t, unixms0, "")
require.Equal(t, unixnms0, "")
require.LessOrEqual(t, unixnms5, unixnms6)

require.Equal(t, utc0, utc3)
require.Equal(t, utc0, utc6)
require.Equal(t, utcms0, "")
require.LessOrEqual(t, utcms3, utcms6)

require.Equal(t, sysDate0, sysDate2)
require.Equal(t, sysDate0, sysDate6)
require.Equal(t, sysDatems0, "")
require.LessOrEqual(t, sysDatems2, sysDatems6)

require.Equal(t, curTime0, curTime1)
require.Equal(t, curTime0, curTime6)
require.Equal(t, curTimems0, "")
require.LessOrEqual(t, curTimems1, curTimems6)

require.Equal(t, utcT0, utcT5)
require.Equal(t, utcT0, utcT6)
require.Equal(t, utcTms0, "")
require.LessOrEqual(t, utcTms5, utcTms6)

// We really want to test truncate when fsp >= .5
if nms6 >= "500000" {
break
}

s1, _ := getSAndMS(rs.Rows()[0][0].(string))
require.Equal(t, s, s1) // now() will truncate the result instead of rounding it

require.Equal(t, rs.Rows()[0][2], rs.Rows()[0][3]) // unix_timestamp() will truncate the result
break
time.Sleep(time.Second / 10)
}
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1501,13 +1501,13 @@ func (d *Datum) convertToMysqlDuration(typeCtx Context, target *FieldType) (Datu
ret.SetMysqlDuration(dur)
return ret, errors.Trace(err)
}
dur, err = dur.RoundFrac(fsp, typeCtx.Location())
dur, err = dur.RoundFrac(fsp)
ret.SetMysqlDuration(dur)
if err != nil {
return ret, errors.Trace(err)
}
case KindMysqlDuration:
dur, err := d.GetMysqlDuration().RoundFrac(fsp, typeCtx.Location())
dur, err := d.GetMysqlDuration().RoundFrac(fsp)
ret.SetMysqlDuration(dur)
if err != nil {
return ret, errors.Trace(err)
Expand Down Expand Up @@ -2037,7 +2037,7 @@ func (d *Datum) toSignedInteger(ctx Context, tp byte) (int64, error) {
case KindMysqlDuration:
// 11:11:11.999999 -> 111112
// 11:59:59.999999 -> 120000
dur, err := d.GetMysqlDuration().RoundFrac(DefaultFsp, ctx.Location())
dur, err := d.GetMysqlDuration().RoundFrac(DefaultFsp)
if err != nil {
return 0, errors.Trace(err)
}
Expand Down
Loading