diff --git a/br/pkg/task/backup.go b/br/pkg/task/backup.go index 725efe75f7e74..89c3a1e3c4fc6 100644 --- a/br/pkg/task/backup.go +++ b/br/pkg/task/backup.go @@ -770,7 +770,7 @@ func ParseTSString(ts string, tzCheck bool) (uint64, error) { return 0, errors.Errorf("must set timezone when using datetime format ts, e.g. '2018-05-11 01:42:23+0800'") } } - t, err := types.ParseTime(sc.TypeCtx(), ts, mysql.TypeTimestamp, types.MaxFsp, nil) + t, err := types.ParseTime(sc.TypeCtx(), ts, mysql.TypeTimestamp, types.MaxFsp) if err != nil { return 0, errors.Trace(err) } diff --git a/pkg/ddl/ddl_api.go b/pkg/ddl/ddl_api.go index 2c0415196227b..ea7c6a8c046a1 100644 --- a/pkg/ddl/ddl_api.go +++ b/pkg/ddl/ddl_api.go @@ -1043,7 +1043,7 @@ func convertTimestampDefaultValToUTC(ctx sessionctx.Context, defaultVal interfac } if vv, ok := defaultVal.(string); ok { if vv != types.ZeroDatetimeStr && !strings.EqualFold(vv, ast.CurrentTimestamp) { - t, err := types.ParseTime(ctx.GetSessionVars().StmtCtx.TypeCtx(), vv, col.GetType(), col.GetDecimal(), nil) + t, err := types.ParseTime(ctx.GetSessionVars().StmtCtx.TypeCtx(), vv, col.GetType(), col.GetDecimal()) if err != nil { return defaultVal, errors.Trace(err) } diff --git a/pkg/executor/brie.go b/pkg/executor/brie.go index 953d725225a20..b4c3577e0adff 100644 --- a/pkg/executor/brie.go +++ b/pkg/executor/brie.go @@ -236,7 +236,7 @@ func (bq *brieQueue) clearTask(sc *stmtctx.StatementContext) { func (b *executorBuilder) parseTSString(ts string) (uint64, error) { sc := stmtctx.NewStmtCtxWithTimeZone(b.ctx.GetSessionVars().Location()) - t, err := types.ParseTime(sc.TypeCtx(), ts, mysql.TypeTimestamp, types.MaxFsp, nil) + t, err := types.ParseTime(sc.TypeCtx(), ts, mysql.TypeTimestamp, types.MaxFsp) if err != nil { return 0, err } diff --git a/pkg/executor/inspection_result_test.go b/pkg/executor/inspection_result_test.go index 462290347e446..f144ec0e0e632 100644 --- a/pkg/executor/inspection_result_test.go +++ b/pkg/executor/inspection_result_test.go @@ -179,7 +179,7 @@ func TestInspectionResult(t *testing.T) { } func parseTime(t *testing.T, se session.Session, str string) types.Time { - time, err := types.ParseTime(se.GetSessionVars().StmtCtx.TypeCtx(), str, mysql.TypeDatetime, types.MaxFsp, nil) + time, err := types.ParseTime(se.GetSessionVars().StmtCtx.TypeCtx(), str, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) return time } @@ -338,7 +338,7 @@ func TestThresholdCheckInspection2(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") datetime := func(s string) types.Time { - time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp, nil) + time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) return time } @@ -421,7 +421,7 @@ func TestThresholdCheckInspection3(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") datetime := func(s string) types.Time { - time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp, nil) + time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) return time } @@ -628,7 +628,7 @@ func TestNodeLoadInspection(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") datetime := func(s string) types.Time { - time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp, nil) + time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) return time } @@ -704,7 +704,7 @@ func TestConfigCheckOfStorageBlockCacheSize(t *testing.T) { tk := testkit.NewTestKit(t, store) tk.MustExec("use test") datetime := func(s string) types.Time { - time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp, nil) + time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) return time } diff --git a/pkg/executor/inspection_summary_test.go b/pkg/executor/inspection_summary_test.go index e36cc44db715c..25e84b77c2589 100644 --- a/pkg/executor/inspection_summary_test.go +++ b/pkg/executor/inspection_summary_test.go @@ -51,7 +51,7 @@ func TestInspectionSummary(t *testing.T) { defer func() { require.NoError(t, failpoint.Disable(fpName)) }() datetime := func(s string) types.Time { - time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp, nil) + time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) return time } diff --git a/pkg/executor/internal/calibrateresource/calibrate_resource_test.go b/pkg/executor/internal/calibrateresource/calibrate_resource_test.go index 681ced04ff498..6fb9467454c7e 100644 --- a/pkg/executor/internal/calibrateresource/calibrate_resource_test.go +++ b/pkg/executor/internal/calibrateresource/calibrate_resource_test.go @@ -89,7 +89,7 @@ func TestCalibrateResource(t *testing.T) { }() datetime := func(s string) types.Time { - time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp, nil) + time, err := types.ParseTime(tk.Session().GetSessionVars().StmtCtx.TypeCtx(), s, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) return time } diff --git a/pkg/expression/builtin_cast.go b/pkg/expression/builtin_cast.go index 3746fd3706850..2466cc4a7e108 100644 --- a/pkg/expression/builtin_cast.go +++ b/pkg/expression/builtin_cast.go @@ -1481,7 +1481,7 @@ func (b *builtinCastStringAsTimeSig) evalTime(ctx sessionctx.Context, row chunk. return res, isNull, err } sc := ctx.GetSessionVars().StmtCtx - res, err = types.ParseTime(sc.TypeCtx(), val, b.tp.GetType(), b.tp.GetDecimal(), nil) + res, err = types.ParseTime(sc.TypeCtx(), val, b.tp.GetType(), b.tp.GetDecimal()) if err != nil { return types.ZeroTime, true, handleInvalidTimeError(ctx, err) } @@ -1960,7 +1960,7 @@ func (b *builtinCastJSONAsTimeSig) evalTime(ctx sessionctx.Context, row chunk.Ro return res, false, err } sc := ctx.GetSessionVars().StmtCtx - res, err = types.ParseTime(sc.TypeCtx(), s, b.tp.GetType(), b.tp.GetDecimal(), nil) + res, err = types.ParseTime(sc.TypeCtx(), s, b.tp.GetType(), b.tp.GetDecimal()) if err != nil { return types.ZeroTime, true, handleInvalidTimeError(ctx, err) } diff --git a/pkg/expression/builtin_cast_vec.go b/pkg/expression/builtin_cast_vec.go index 44221ab6302b5..66a034ee2500d 100644 --- a/pkg/expression/builtin_cast_vec.go +++ b/pkg/expression/builtin_cast_vec.go @@ -531,7 +531,7 @@ func (b *builtinCastJSONAsTimeSig) vecEvalTime(ctx sessionctx.Context, input *ch if err != nil { return err } - tm, err := types.ParseTime(stmtCtx.TypeCtx(), s, b.tp.GetType(), fsp, nil) + tm, err := types.ParseTime(stmtCtx.TypeCtx(), s, b.tp.GetType(), fsp) if err != nil { if err = handleInvalidTimeError(ctx, err); err != nil { return err @@ -1770,7 +1770,7 @@ func (b *builtinCastStringAsTimeSig) vecEvalTime(ctx sessionctx.Context, input * if result.IsNull(i) { continue } - tm, err := types.ParseTime(stmtCtx.TypeCtx(), buf.GetString(i), b.tp.GetType(), fsp, nil) + tm, err := types.ParseTime(stmtCtx.TypeCtx(), buf.GetString(i), b.tp.GetType(), fsp) if err != nil { if errors.Is(err, strconv.ErrSyntax) || errors.Is(err, strconv.ErrRange) { err = types.ErrIncorrectDatetimeValue.GenWithStackByArgs(buf.GetString(i)) diff --git a/pkg/expression/builtin_time.go b/pkg/expression/builtin_time.go index 02d6e158ce33f..6f4a507ac97b1 100644 --- a/pkg/expression/builtin_time.go +++ b/pkg/expression/builtin_time.go @@ -2770,7 +2770,7 @@ func (du *baseDateArithmetical) getDateFromString(ctx sessionctx.Context, args [ } sc := ctx.GetSessionVars().StmtCtx - date, err := types.ParseTime(sc.TypeCtx(), dateStr, dateTp, types.MaxFsp, nil) + date, err := types.ParseTime(sc.TypeCtx(), dateStr, dateTp, types.MaxFsp) if err != nil { err = handleInvalidTimeError(ctx, err) if err != nil { @@ -3180,7 +3180,7 @@ func (du *baseDateArithmetical) vecGetDateFromString(b *baseBuiltinFunc, ctx ses dateTp = mysql.TypeDatetime } - date, err := types.ParseTime(sc.TypeCtx(), dateStr, dateTp, types.MaxFsp, nil) + date, err := types.ParseTime(sc.TypeCtx(), dateStr, dateTp, types.MaxFsp) if err != nil { err = handleInvalidTimeError(ctx, err) if err != nil { @@ -4349,7 +4349,7 @@ func (b *builtinTimestamp1ArgSig) evalTime(ctx sessionctx.Context, row chunk.Row if b.isFloat { tm, err = types.ParseTimeFromFloatString(sc.TypeCtx(), s, mysql.TypeDatetime, types.GetFsp(s)) } else { - tm, err = types.ParseTime(sc.TypeCtx(), s, mysql.TypeDatetime, types.GetFsp(s), nil) + tm, err = types.ParseTime(sc.TypeCtx(), s, mysql.TypeDatetime, types.GetFsp(s)) } if err != nil { return types.ZeroTime, true, handleInvalidTimeError(ctx, err) @@ -4381,7 +4381,7 @@ func (b *builtinTimestamp2ArgsSig) evalTime(ctx sessionctx.Context, row chunk.Ro if b.isFloat { tm, err = types.ParseTimeFromFloatString(sc.TypeCtx(), arg0, mysql.TypeDatetime, types.GetFsp(arg0)) } else { - tm, err = types.ParseTime(sc.TypeCtx(), arg0, mysql.TypeDatetime, types.GetFsp(arg0), nil) + tm, err = types.ParseTime(sc.TypeCtx(), arg0, mysql.TypeDatetime, types.GetFsp(arg0)) } if err != nil { return types.ZeroTime, true, handleInvalidTimeError(ctx, err) @@ -4432,7 +4432,7 @@ func (c *timestampLiteralFunctionClass) getFunction(ctx sessionctx.Context, args if !timestampPattern.MatchString(str) { return nil, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, str) } - tm, err := types.ParseTime(ctx.GetSessionVars().StmtCtx.TypeCtx(), str, mysql.TypeDatetime, types.GetFsp(str), nil) + tm, err := types.ParseTime(ctx.GetSessionVars().StmtCtx.TypeCtx(), str, mysql.TypeDatetime, types.GetFsp(str)) if err != nil { return nil, err } @@ -4540,7 +4540,7 @@ func isDuration(str string) bool { // strDatetimeAddDuration adds duration to datetime string, returns a string value. func strDatetimeAddDuration(sc *stmtctx.StatementContext, d string, arg1 types.Duration) (result string, isNull bool, err error) { - arg0, err := types.ParseTime(sc.TypeCtx(), d, mysql.TypeDatetime, types.MaxFsp, nil) + arg0, err := types.ParseTime(sc.TypeCtx(), d, mysql.TypeDatetime, types.MaxFsp) if err != nil { // Return a warning regardless of the sql_mode, this is compatible with MySQL. sc.AppendWarning(err) @@ -4577,7 +4577,7 @@ func strDurationAddDuration(sc *stmtctx.StatementContext, d string, arg1 types.D // strDatetimeSubDuration subtracts duration from datetime string, returns a string value. func strDatetimeSubDuration(sc *stmtctx.StatementContext, d string, arg1 types.Duration) (result string, isNull bool, err error) { - arg0, err := types.ParseTime(sc.TypeCtx(), d, mysql.TypeDatetime, types.MaxFsp, nil) + arg0, err := types.ParseTime(sc.TypeCtx(), d, mysql.TypeDatetime, types.MaxFsp) if err != nil { // Return a warning regardless of the sql_mode, this is compatible with MySQL. sc.AppendWarning(err) diff --git a/pkg/expression/builtin_time_vec.go b/pkg/expression/builtin_time_vec.go index ce0e1fbff195e..075f3965edc18 100644 --- a/pkg/expression/builtin_time_vec.go +++ b/pkg/expression/builtin_time_vec.go @@ -2652,7 +2652,7 @@ func (b *builtinTimestamp1ArgSig) vecEvalTime(ctx sessionctx.Context, input *chu if b.isFloat { tm, err = types.ParseTimeFromFloatString(sc.TypeCtx(), s, mysql.TypeDatetime, types.GetFsp(s)) } else { - tm, err = types.ParseTime(sc.TypeCtx(), s, mysql.TypeDatetime, types.GetFsp(s), nil) + tm, err = types.ParseTime(sc.TypeCtx(), s, mysql.TypeDatetime, types.GetFsp(s)) } if err != nil { if err = handleInvalidTimeError(ctx, err); err != nil { @@ -2705,7 +2705,7 @@ func (b *builtinTimestamp2ArgsSig) vecEvalTime(ctx sessionctx.Context, input *ch if b.isFloat { tm, err = types.ParseTimeFromFloatString(sc.TypeCtx(), arg0, mysql.TypeDatetime, types.GetFsp(arg0)) } else { - tm, err = types.ParseTime(sc.TypeCtx(), arg0, mysql.TypeDatetime, types.GetFsp(arg0), nil) + tm, err = types.ParseTime(sc.TypeCtx(), arg0, mysql.TypeDatetime, types.GetFsp(arg0)) } if err != nil { if err = handleInvalidTimeError(ctx, err); err != nil { diff --git a/pkg/expression/helper.go b/pkg/expression/helper.go index 0643db7f850e9..d2e7649bd4fa2 100644 --- a/pkg/expression/helper.go +++ b/pkg/expression/helper.go @@ -89,8 +89,11 @@ func getTimeCurrentTimeStamp(ctx sessionctx.Context, tp byte, fsp int) (t types. // GetTimeValue gets the time value with type tp. func GetTimeValue(ctx sessionctx.Context, v interface{}, tp byte, fsp int, explicitTz *time.Location) (d types.Datum, err error) { var value types.Time + tc := ctx.GetSessionVars().StmtCtx.TypeCtx() + if explicitTz != nil { + tc = tc.WithLocation(explicitTz) + } - sc := ctx.GetSessionVars().StmtCtx switch x := v.(type) { case string: lowerX := strings.ToLower(x) @@ -99,10 +102,10 @@ func GetTimeValue(ctx sessionctx.Context, v interface{}, tp byte, fsp int, expli return d, err } } else if lowerX == types.ZeroDatetimeStr { - value, err = types.ParseTimeFromNum(sc.TypeCtx(), 0, tp, fsp) + value, err = types.ParseTimeFromNum(tc, 0, tp, fsp) terror.Log(err) } else { - value, err = types.ParseTime(sc.TypeCtx(), x, tp, fsp, explicitTz) + value, err = types.ParseTime(tc, x, tp, fsp) if err != nil { return d, err } @@ -110,12 +113,12 @@ func GetTimeValue(ctx sessionctx.Context, v interface{}, tp byte, fsp int, expli case *driver.ValueExpr: switch x.Kind() { case types.KindString: - value, err = types.ParseTime(sc.TypeCtx(), x.GetString(), tp, fsp, nil) + value, err = types.ParseTime(tc, x.GetString(), tp, fsp) if err != nil { return d, err } case types.KindInt64: - value, err = types.ParseTimeFromNum(sc.TypeCtx(), x.GetInt64(), tp, fsp) + value, err = types.ParseTimeFromNum(tc, x.GetInt64(), tp, fsp) if err != nil { return d, err } @@ -137,12 +140,12 @@ func GetTimeValue(ctx sessionctx.Context, v interface{}, tp byte, fsp int, expli return d, err } ft := types.NewFieldType(mysql.TypeLonglong) - xval, err := v.ConvertTo(ctx.GetSessionVars().StmtCtx.TypeCtx(), ft) + xval, err := v.ConvertTo(tc, ft) if err != nil { return d, err } - value, err = types.ParseTimeFromNum(sc.TypeCtx(), xval.GetInt64(), tp, fsp) + value, err = types.ParseTimeFromNum(tc, xval.GetInt64(), tp, fsp) if err != nil { return d, err } diff --git a/pkg/server/handler/optimizor/statistics_handler.go b/pkg/server/handler/optimizor/statistics_handler.go index 4af77791cd901..ba83fc805a68f 100644 --- a/pkg/server/handler/optimizor/statistics_handler.go +++ b/pkg/server/handler/optimizor/statistics_handler.go @@ -111,7 +111,7 @@ func (sh StatsHistoryHandler) ServeHTTP(w http.ResponseWriter, req *http.Request } se.GetSessionVars().StmtCtx.SetTimeZone(time.Local) - t, err := types.ParseTime(se.GetSessionVars().StmtCtx.TypeCtx(), params[handler.Snapshot], mysql.TypeTimestamp, 6, nil) + t, err := types.ParseTime(se.GetSessionVars().StmtCtx.TypeCtx(), params[handler.Snapshot], mysql.TypeTimestamp, 6) if err != nil { handler.WriteError(w, err) return diff --git a/pkg/server/internal/column/column_test.go b/pkg/server/internal/column/column_test.go index ba63d52a5b9d8..f4fdceab40962 100644 --- a/pkg/server/internal/column/column_test.go +++ b/pkg/server/internal/column/column_test.go @@ -184,7 +184,7 @@ func TestDumpTextValue(t *testing.T) { require.NoError(t, err) typeCtx := types.NewContext(types.StrictFlags.WithIgnoreZeroInDate(true), losAngelesTz, func(err error) {}) - time, err := types.ParseTime(typeCtx, "2017-01-05 23:59:59.575601", mysql.TypeDatetime, 0, nil) + time, err := types.ParseTime(typeCtx, "2017-01-05 23:59:59.575601", mysql.TypeDatetime, 0) require.NoError(t, err) d.SetMysqlTime(time) columns[0].Type = mysql.TypeDatetime diff --git a/pkg/sessionctx/variable/varsutil.go b/pkg/sessionctx/variable/varsutil.go index 765367a999526..46e13f2e0a8c4 100644 --- a/pkg/sessionctx/variable/varsutil.go +++ b/pkg/sessionctx/variable/varsutil.go @@ -441,7 +441,7 @@ func parseTSFromNumberOrTime(s *SessionVars, sVal string) (uint64, error) { return tso, nil } - t, err := types.ParseTime(s.StmtCtx.TypeCtx(), sVal, mysql.TypeTimestamp, types.MaxFsp, nil) + t, err := types.ParseTime(s.StmtCtx.TypeCtx(), sVal, mysql.TypeTimestamp, types.MaxFsp) if err != nil { return 0, err } @@ -456,7 +456,7 @@ func setTxnReadTS(s *SessionVars, sVal string) error { return nil } - t, err := types.ParseTime(s.StmtCtx.TypeCtx(), sVal, mysql.TypeTimestamp, types.MaxFsp, nil) + t, err := types.ParseTime(s.StmtCtx.TypeCtx(), sVal, mysql.TypeTimestamp, types.MaxFsp) if err != nil { return err } diff --git a/pkg/types/convert.go b/pkg/types/convert.go index 9927ecf879151..2dff482ac5d1f 100644 --- a/pkg/types/convert.go +++ b/pkg/types/convert.go @@ -316,7 +316,7 @@ func StrToUint(ctx Context, str string, isFuncCast bool) (uint64, error) { // StrToDateTime converts str to MySQL DateTime. func StrToDateTime(ctx Context, str string, fsp int) (Time, error) { - return ParseTime(ctx, str, mysql.TypeDatetime, fsp, nil) + return ParseTime(ctx, str, mysql.TypeDatetime, fsp) } // StrToDuration converts str to Duration. It returns Duration in normal case, diff --git a/pkg/types/convert_test.go b/pkg/types/convert_test.go index fed44d5670603..4f78ef6267589 100644 --- a/pkg/types/convert_test.go +++ b/pkg/types/convert_test.go @@ -147,14 +147,14 @@ func TestConvertType(t *testing.T) { require.NoError(t, err) require.Equal(t, "10:11:12.1", vv.(Duration).String()) typeCtx := DefaultStmtNoWarningContext - vd, err := ParseTime(typeCtx, "2010-10-10 10:11:11.12345", mysql.TypeDatetime, 2, nil) + vd, err := ParseTime(typeCtx, "2010-10-10 10:11:11.12345", mysql.TypeDatetime, 2) require.Equal(t, "2010-10-10 10:11:11.12", vd.String()) require.NoError(t, err) v, err = Convert(vd, ft) require.NoError(t, err) require.Equal(t, "10:11:11.1", v.(Duration).String()) - vt, err := ParseTime(typeCtx, "2010-10-10 10:11:11.12345", mysql.TypeTimestamp, 2, nil) + vt, err := ParseTime(typeCtx, "2010-10-10 10:11:11.12345", mysql.TypeTimestamp, 2) require.Equal(t, "2010-10-10 10:11:11.12", vt.String()) require.NoError(t, err) v, err = Convert(vt, ft) @@ -343,7 +343,7 @@ func TestConvertToString(t *testing.T) { testToString(t, Enum{Name: "a", Value: 1}, "a") testToString(t, Set{Name: "a", Value: 1}, "a") - t1, err := ParseTime(DefaultStmtNoWarningContext, "2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 6, nil) + t1, err := ParseTime(DefaultStmtNoWarningContext, "2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 6) require.NoError(t, err) testToString(t, t1, "2011-11-10 11:11:11.999999") diff --git a/pkg/types/datum.go b/pkg/types/datum.go index 50ec3035fead6..ac50494fb01cc 100644 --- a/pkg/types/datum.go +++ b/pkg/types/datum.go @@ -1270,7 +1270,7 @@ func (d *Datum) convertToMysqlTimestamp(ctx Context, target *FieldType) (Datum, } t, err = t.RoundFrac(ctx, fsp) case KindString, KindBytes: - t, err = ParseTime(ctx, d.GetString(), mysql.TypeTimestamp, fsp, nil) + t, err = ParseTime(ctx, d.GetString(), mysql.TypeTimestamp, fsp) case KindInt64: t, err = ParseTimeFromNum(ctx, d.GetInt64(), mysql.TypeTimestamp, fsp) case KindMysqlDecimal: @@ -1283,7 +1283,7 @@ func (d *Datum) convertToMysqlTimestamp(ctx Context, target *FieldType) (Datum, ret.SetMysqlTime(t) return ret, err } - t, err = ParseTime(ctx, s, mysql.TypeTimestamp, fsp, nil) + t, err = ParseTime(ctx, s, mysql.TypeTimestamp, fsp) default: return invalidConv(d, mysql.TypeTimestamp) } @@ -1324,7 +1324,7 @@ func (d *Datum) convertToMysqlTime(ctx Context, target *FieldType) (Datum, error case KindMysqlDecimal: t, err = ParseTimeFromFloatString(ctx, d.GetMysqlDecimal().String(), tp, fsp) case KindString, KindBytes: - t, err = ParseTime(ctx, d.GetString(), tp, fsp, nil) + t, err = ParseTime(ctx, d.GetString(), tp, fsp) case KindInt64: t, err = ParseTimeFromNum(ctx, d.GetInt64(), tp, fsp) case KindUint64: @@ -1343,7 +1343,7 @@ func (d *Datum) convertToMysqlTime(ctx Context, target *FieldType) (Datum, error ret.SetMysqlTime(t) return ret, err } - t, err = ParseTime(ctx, s, tp, fsp, nil) + t, err = ParseTime(ctx, s, tp, fsp) default: return invalidConv(d, tp) } diff --git a/pkg/types/datum_test.go b/pkg/types/datum_test.go index b1f4dc053e0eb..53dc48ef05c69 100644 --- a/pkg/types/datum_test.go +++ b/pkg/types/datum_test.go @@ -92,7 +92,7 @@ func TestToBool(t *testing.T) { testDatumToBool(t, CreateBinaryJSON(true), 1) testDatumToBool(t, CreateBinaryJSON(false), 1) testDatumToBool(t, CreateBinaryJSON(""), 1) - t1, err := ParseTime(DefaultStmtNoWarningContext, "2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 6, nil) + t1, err := ParseTime(DefaultStmtNoWarningContext, "2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 6) require.NoError(t, err) testDatumToBool(t, t1, 1) @@ -133,7 +133,7 @@ func TestToInt64(t *testing.T) { testDatumToInt64(t, Set{Name: "a", Value: 1}, int64(1)) testDatumToInt64(t, CreateBinaryJSON(int64(3)), int64(3)) - t1, err := ParseTime(DefaultStmtNoWarningContext, "2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 0, nil) + t1, err := ParseTime(DefaultStmtNoWarningContext, "2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 0) require.NoError(t, err) testDatumToInt64(t, t1, int64(20111110111112)) @@ -221,7 +221,7 @@ func TestConvertToFloat(t *testing.T) { } func mustParseTime(s string, tp byte, fsp int) Time { - t, err := ParseTime(DefaultStmtNoWarningContext, s, tp, fsp, nil) + t, err := ParseTime(DefaultStmtNoWarningContext, s, tp, fsp) if err != nil { panic("ParseTime fail") } diff --git a/pkg/types/format_test.go b/pkg/types/format_test.go index a63d8f161ee7e..a6caefdbe4911 100644 --- a/pkg/types/format_test.go +++ b/pkg/types/format_test.go @@ -68,7 +68,7 @@ func TestTimeFormatMethod(t *testing.T) { }, } for i, tt := range tblDate { - tm, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, 6, nil) + tm, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, 6) require.NoErrorf(t, err, "Parse time fail: %s", tt.Input) str, err := tm.DateFormat(tt.Format) diff --git a/pkg/types/time.go b/pkg/types/time.go index 19df35a56b996..d03cf63560b33 100644 --- a/pkg/types/time.go +++ b/pkg/types/time.go @@ -460,7 +460,7 @@ func (t Time) Convert(ctx Context, tp uint8) (Time, error) { } t1.SetType(tp) - err := t1.check(ctx, nil) + err := t1.Check(ctx) return t1, errors.Trace(err) } @@ -491,7 +491,7 @@ func (t Time) Compare(o Time) int { // but parses string to Time then compares. func (t Time) CompareString(ctx Context, str string) (int, error) { // use MaxFsp to parse the string - o, err := ParseTime(ctx, str, t.Type(), MaxFsp, nil) + o, err := ParseTime(ctx, str, t.Type(), MaxFsp) if err != nil { return 0, errors.Trace(err) } @@ -670,27 +670,22 @@ func (t *Time) FromPackedUint(packed uint64) error { return nil } -// check whether t matches valid Time format. +// Check function checks whether t matches valid Time format. // If allowZeroInDate is false, it returns ErrZeroDate when month or day is zero. // FIXME: See https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_in_date -func (t Time) check(ctx Context, explicitTz *gotime.Location) error { +func (t Time) Check(ctx Context) error { allowZeroInDate := ctx.Flags().IgnoreZeroInDate() allowInvalidDate := ctx.Flags().IgnoreInvalidDateErr() var err error switch t.Type() { case mysql.TypeTimestamp: - err = checkTimestampType(ctx, t.coreTime, explicitTz) + err = checkTimestampType(t.coreTime, ctx.Location()) case mysql.TypeDatetime, mysql.TypeDate: err = checkDatetimeType(t.coreTime, allowZeroInDate, allowInvalidDate) } return errors.Trace(err) } -// Check if 't' is valid -func (t *Time) Check(ctx Context) error { - return t.check(ctx, nil) -} - // Sub subtracts t1 from t, returns a duration value. // Note that sub should not be done on different time types. func (t *Time) Sub(ctx Context, t1 *Time) Duration { @@ -947,7 +942,7 @@ func splitDateTime(format string) (seps []string, fracStr string, hasTZ bool, tz } // See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-literals.html. -func parseDatetime(ctx Context, str string, fsp int, isFloat bool, explicitTz *gotime.Location) (Time, error) { +func parseDatetime(ctx Context, str string, fsp int, isFloat bool) (Time, error) { var ( year, month, day, hour, minute, second, deltaHour, deltaMinute int fracStr string @@ -1183,12 +1178,7 @@ func parseDatetime(ctx Context, str string, fsp int, isFloat bool, explicitTz *g if overflow { // Convert to Go time and add 1 second, to handle input like 2017-01-05 08:40:59.575601 var t1 gotime.Time - if explicitTz != nil { - t1, err = tmp.GoTime(explicitTz) - } else { - t1, err = tmp.GoTime(ctx.Location()) - } - if err != nil { + if t1, err = tmp.GoTime(ctx.Location()); err != nil { return ZeroDatetime, errors.Trace(err) } tmp = FromGoTime(t1.Add(gotime.Second)) @@ -1220,11 +1210,7 @@ func parseDatetime(ctx Context, str string, fsp int, isFloat bool, explicitTz *g if err != nil { return ZeroDatetime, errors.Trace(err) } - if explicitTz != nil { - t1 = t1.In(explicitTz) - } else { - t1 = t1.In(ctx.Location()) - } + t1 = t1.In(ctx.Location()) tmp = FromGoTime(t1) } @@ -1879,7 +1865,7 @@ func getTime(ctx Context, num, originNum int64, tp byte) (Time, error) { return ZeroDatetime, errors.Trace(ErrWrongValue.GenWithStackByArgs(TimeStr, numStr)) } t := NewTime(ct, tp, DefaultFsp) - err := t.check(ctx, nil) + err := t.Check(ctx) return t, errors.Trace(err) } @@ -1972,8 +1958,8 @@ func parseDateTimeFromNum(ctx Context, num int64) (Time, error) { // The valid timestamp range is from '1970-01-01 00:00:01.000000' to '2038-01-19 03:14:07.999999'. // The valid date range is from '1000-01-01' to '9999-12-31' // explicitTz is used to handle a data race of timeZone, refer to https://github.com/pingcap/tidb/issues/40710. It only works for timestamp now, be careful to use it! -func ParseTime(ctx Context, str string, tp byte, fsp int, explicitTz *gotime.Location) (Time, error) { - return parseTime(ctx, str, tp, fsp, false, explicitTz) +func ParseTime(ctx Context, str string, tp byte, fsp int) (Time, error) { + return parseTime(ctx, str, tp, fsp, false) } // ParseTimeFromFloatString is similar to ParseTime, except that it's used to parse a float converted string. @@ -1982,22 +1968,22 @@ func ParseTimeFromFloatString(ctx Context, str string, tp byte, fsp int) (Time, if len(str) >= 3 && str[:3] == "0.0" { return NewTime(ZeroCoreTime, tp, DefaultFsp), nil } - return parseTime(ctx, str, tp, fsp, true, nil) + return parseTime(ctx, str, tp, fsp, true) } -func parseTime(ctx Context, str string, tp byte, fsp int, isFloat bool, explicitTz *gotime.Location) (Time, error) { +func parseTime(ctx Context, str string, tp byte, fsp int, isFloat bool) (Time, error) { fsp, err := CheckFsp(fsp) if err != nil { return NewTime(ZeroCoreTime, tp, DefaultFsp), errors.Trace(err) } - t, err := parseDatetime(ctx, str, fsp, isFloat, explicitTz) + t, err := parseDatetime(ctx, str, fsp, isFloat) if err != nil { return NewTime(ZeroCoreTime, tp, DefaultFsp), errors.Trace(err) } t.SetType(tp) - if err = t.check(ctx, explicitTz); err != nil { + if err = t.Check(ctx); err != nil { return NewTime(ZeroCoreTime, tp, DefaultFsp), errors.Trace(err) } return t, nil @@ -2005,18 +1991,18 @@ func parseTime(ctx Context, str string, tp byte, fsp int, isFloat bool, explicit // ParseDatetime is a helper function wrapping ParseTime with datetime type and default fsp. func ParseDatetime(ctx Context, str string) (Time, error) { - return ParseTime(ctx, str, mysql.TypeDatetime, GetFsp(str), nil) + return ParseTime(ctx, str, mysql.TypeDatetime, GetFsp(str)) } // ParseTimestamp is a helper function wrapping ParseTime with timestamp type and default fsp. func ParseTimestamp(ctx Context, str string) (Time, error) { - return ParseTime(ctx, str, mysql.TypeTimestamp, GetFsp(str), nil) + return ParseTime(ctx, str, mysql.TypeTimestamp, GetFsp(str)) } // ParseDate is a helper function wrapping ParseTime with date type. func ParseDate(ctx Context, str string) (Time, error) { // date has no fractional seconds precision - return ParseTime(ctx, str, mysql.TypeDate, MinFsp, nil) + return ParseTime(ctx, str, mysql.TypeDate, MinFsp) } // ParseTimeFromYear parse a `YYYY` formed year to corresponded Datetime type. @@ -2060,7 +2046,7 @@ func ParseTimeFromNum(ctx Context, num int64, tp byte, fsp int) (Time, error) { t.SetType(tp) t.SetFsp(fsp) - if err := t.check(ctx, nil); err != nil { + if err := t.Check(ctx); err != nil { return NewTime(ZeroCoreTime, tp, DefaultFsp), errors.Trace(err) } return t, nil @@ -2149,16 +2135,12 @@ func checkMonthDay(year, month, day int, allowInvalidDate bool) error { return nil } -func checkTimestampType(ctx Context, t CoreTime, explicitTz *gotime.Location) error { +func checkTimestampType(t CoreTime, tz *gotime.Location) error { if compareTime(t, ZeroCoreTime) == 0 { return nil } var checkTime CoreTime - tz := ctx.Location() - if explicitTz != nil { - tz = explicitTz - } if tz != BoundTimezone { convertTime := NewTime(t, mysql.TypeTimestamp, DefaultFsp) err := convertTime.ConvertTimeZone(tz, BoundTimezone) @@ -2897,7 +2879,7 @@ func (t *Time) StrToDate(typeCtx Context, date, format string) bool { t.SetCoreTime(tm) t.SetType(mysql.TypeDatetime) - if t.check(typeCtx, nil) != nil { + if t.Check(typeCtx) != nil { return false } if warning { diff --git a/pkg/types/time_test.go b/pkg/types/time_test.go index 0af88d4aaf276..931ed7d2eb55c 100644 --- a/pkg/types/time_test.go +++ b/pkg/types/time_test.go @@ -147,12 +147,12 @@ func TestDateTime(t *testing.T) { } for _, test := range fspTbl { - v, err := types.ParseTime(typeCtx, test.Input, mysql.TypeDatetime, test.Fsp, nil) + v, err := types.ParseTime(typeCtx, test.Input, mysql.TypeDatetime, test.Fsp) require.NoError(t, err) require.Equal(t, test.Expect, v.String()) } - v, _ := types.ParseTime(typeCtx, "121231113045.9999999", mysql.TypeDatetime, 6, nil) + v, _ := types.ParseTime(typeCtx, "121231113045.9999999", mysql.TypeDatetime, 6) require.Equal(t, 46, v.Second()) require.Equal(t, 0, v.Microsecond()) @@ -615,7 +615,7 @@ func TestCodec(t *testing.T) { } for _, test := range tbl { - v, err := types.ParseTime(typeCtx, test, mysql.TypeDatetime, types.MaxFsp, nil) + v, err := types.ParseTime(typeCtx, test, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) packed, _ = v.ToPackedUint() @@ -719,7 +719,7 @@ func TestToNumber(t *testing.T) { } for _, test := range tblDateTime { - v, err := types.ParseTime(typeCtx, test.Input, mysql.TypeDatetime, test.Fsp, nil) + v, err := types.ParseTime(typeCtx, test.Input, mysql.TypeDatetime, test.Fsp) require.NoError(t, err) require.Equal(t, test.Expect, v.ToNumber().String()) } @@ -742,7 +742,7 @@ func TestToNumber(t *testing.T) { } for _, test := range tblDate { - v, err := types.ParseTime(typeCtx, test.Input, mysql.TypeDate, 0, nil) + v, err := types.ParseTime(typeCtx, test.Input, mysql.TypeDate, 0) require.NoError(t, err) require.Equal(t, test.Expect, v.ToNumber().String()) } @@ -860,7 +860,7 @@ func TestRoundFrac(t *testing.T) { } for _, tt := range tbl { - v, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, types.MaxFsp, nil) + v, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) nv, err := v.RoundFrac(typeCtx, tt.Fsp) require.NoError(t, err) @@ -885,7 +885,7 @@ func TestRoundFrac(t *testing.T) { } for _, tt := range tbl { - v, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, types.MaxFsp, nil) + v, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) nv, err := v.RoundFrac(typeCtx, tt.Fsp) require.NoError(t, err) @@ -947,7 +947,7 @@ func TestConvert(t *testing.T) { } for _, tt := range tbl { - v, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, tt.Fsp, nil) + v, err := types.ParseTime(typeCtx, tt.Input, mysql.TypeDatetime, tt.Fsp) require.NoError(t, err) nv, err := v.ConvertToDuration() require.NoError(t, err) @@ -992,7 +992,7 @@ func TestCompare(t *testing.T) { } for _, tt := range tbl { - v1, err := types.ParseTime(typeCtx, tt.Arg1, mysql.TypeDatetime, types.MaxFsp, nil) + v1, err := types.ParseTime(typeCtx, tt.Arg1, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) ret, err := v1.CompareString(types.DefaultStmtNoWarningContext, tt.Arg2) @@ -1000,7 +1000,7 @@ func TestCompare(t *testing.T) { require.Equal(t, tt.Ret, ret) } - v1, err := types.ParseTime(typeCtx, "2011-10-10 11:11:11", mysql.TypeDatetime, types.MaxFsp, nil) + v1, err := types.ParseTime(typeCtx, "2011-10-10 11:11:11", mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) res, err := v1.CompareString(types.DefaultStmtNoWarningContext, "Test should error") require.Error(t, err) @@ -1154,11 +1154,11 @@ func TestTimeAdd(t *testing.T) { typeCtx := types.DefaultStmtNoWarningContext for _, tt := range tbl { - v1, err := types.ParseTime(typeCtx, tt.Arg1, mysql.TypeDatetime, types.MaxFsp, nil) + v1, err := types.ParseTime(typeCtx, tt.Arg1, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) dur, _, err := types.ParseDuration(typeCtx, tt.Arg2, types.MaxFsp) require.NoError(t, err) - result, err := types.ParseTime(typeCtx, tt.Ret, mysql.TypeDatetime, types.MaxFsp, nil) + result, err := types.ParseTime(typeCtx, tt.Ret, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) v2, err := v1.Add(typeCtx, dur) require.NoError(t, err) @@ -1241,7 +1241,7 @@ func TestCheckTimestamp(t *testing.T) { } for _, tt := range tests { - validTimestamp := types.CheckTimestampTypeForTest(types.NewContext(types.StrictFlags, tt.tz, func(err error) {}), tt.input, nil) + validTimestamp := types.CheckTimestampTypeForTest(tt.input, tt.tz) if tt.expectRetError { require.Errorf(t, validTimestamp, "For %s %s", tt.input, tt.tz) } else { @@ -1298,7 +1298,7 @@ func TestCheckTimestamp(t *testing.T) { } for _, tt := range tests { - validTimestamp := types.CheckTimestampTypeForTest(types.NewContext(types.StrictFlags, tt.tz, func(err error) {}), tt.input, nil) + validTimestamp := types.CheckTimestampTypeForTest(tt.input, tt.tz) if tt.expectRetError { require.Errorf(t, validTimestamp, "For %s %s", tt.input, tt.tz) } else { @@ -1970,9 +1970,9 @@ func TestTimeSub(t *testing.T) { typeCtx := types.DefaultStmtNoWarningContext for _, tt := range tbl { - v1, err := types.ParseTime(typeCtx, tt.Arg1, mysql.TypeDatetime, types.MaxFsp, nil) + v1, err := types.ParseTime(typeCtx, tt.Arg1, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) - v2, err := types.ParseTime(typeCtx, tt.Arg2, mysql.TypeDatetime, types.MaxFsp, nil) + v2, err := types.ParseTime(typeCtx, tt.Arg2, mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) dur, _, err := types.ParseDuration(typeCtx, tt.Ret, types.MaxFsp) require.NoError(t, err) @@ -2166,7 +2166,7 @@ func TestParseWithTimezone(t *testing.T) { }, } for ith, ca := range cases { - v, err := types.ParseTime(types.NewContext(types.StrictFlags, ca.sysTZ, func(err error) {}), ca.lit, mysql.TypeTimestamp, ca.fsp, nil) + v, err := types.ParseTime(types.NewContext(types.StrictFlags, ca.sysTZ, func(err error) {}), ca.lit, mysql.TypeTimestamp, ca.fsp) require.NoErrorf(t, err, "tidb time parse misbehaved on %d", ith) if err != nil { continue @@ -2179,7 +2179,7 @@ func TestParseWithTimezone(t *testing.T) { func TestMarshalTime(t *testing.T) { typeCtx := types.DefaultStmtNoWarningContext - v1, err := types.ParseTime(typeCtx, "2017-01-18 01:01:01.123456", mysql.TypeDatetime, types.MaxFsp, nil) + v1, err := types.ParseTime(typeCtx, "2017-01-18 01:01:01.123456", mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) j, err := json.Marshal(v1) require.NoError(t, err) @@ -2200,7 +2200,7 @@ func BenchmarkFormat(b *testing.B) { func BenchmarkTimeAdd(b *testing.B) { typeCtx := types.DefaultStmtNoWarningContext - arg1, _ := types.ParseTime(typeCtx, "2017-01-18", mysql.TypeDatetime, types.MaxFsp, nil) + arg1, _ := types.ParseTime(typeCtx, "2017-01-18", mysql.TypeDatetime, types.MaxFsp) arg2, _, _ := types.ParseDuration(typeCtx, "12:30:59", types.MaxFsp) for i := 0; i < b.N; i++ { _, err := arg1.Add(typeCtx, arg2) diff --git a/pkg/util/codec/codec_test.go b/pkg/util/codec/codec_test.go index b223938662c23..6fad14dc5088d 100644 --- a/pkg/util/codec/codec_test.go +++ b/pkg/util/codec/codec_test.go @@ -520,7 +520,7 @@ func TestBytes(t *testing.T) { func parseTime(t *testing.T, s string) types.Time { sc := stmtctx.NewStmtCtxWithTimeZone(time.UTC) - m, err := types.ParseTime(sc.TypeCtx(), s, mysql.TypeDatetime, types.DefaultFsp, nil) + m, err := types.ParseTime(sc.TypeCtx(), s, mysql.TypeDatetime, types.DefaultFsp) require.NoError(t, err) return m } diff --git a/pkg/util/dbutil/common.go b/pkg/util/dbutil/common.go index 0ab538e247371..dabae40c8059d 100644 --- a/pkg/util/dbutil/common.go +++ b/pkg/util/dbutil/common.go @@ -551,7 +551,7 @@ func AnalyzeValuesFromBuckets(valueString string, cols []*model.ColumnInfo) ([]s if IsTimeTypeAndNeedDecode(col.GetType()) { // check if values[i] is already a time string sc := stmtctx.NewStmtCtxWithTimeZone(time.UTC) - _, err := types.ParseTime(sc.TypeCtx(), values[i], col.GetType(), types.MinFsp, nil) + _, err := types.ParseTime(sc.TypeCtx(), values[i], col.GetType(), types.MinFsp) if err == nil { continue } diff --git a/pkg/util/rowcodec/rowcodec_test.go b/pkg/util/rowcodec/rowcodec_test.go index e3c6086cdc12d..94f49bf3c3abd 100644 --- a/pkg/util/rowcodec/rowcodec_test.go +++ b/pkg/util/rowcodec/rowcodec_test.go @@ -292,7 +292,7 @@ func TestTypesNewRowCodec(t *testing.T) { return d } getTime := func(value string) types.Time { - d, err := types.ParseTime(types.DefaultStmtNoWarningContext, value, mysql.TypeTimestamp, 6, nil) + d, err := types.ParseTime(types.DefaultStmtNoWarningContext, value, mysql.TypeTimestamp, 6) require.NoError(t, err) return d }