From e2bcb88c5692678bb24c5bee4a24f756c2093b2b Mon Sep 17 00:00:00 2001 From: zian Date: Mon, 25 Mar 2019 14:59:13 +0800 Subject: [PATCH] expression: fix week func format (#9685) (#9753) --- expression/builtin_time.go | 12 +++++++++++- expression/builtin_time_test.go | 28 +++++++++++++++++++++++++++- expression/errors.go | 3 ++- types/time.go | 1 + 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/expression/builtin_time.go b/expression/builtin_time.go index 1b2de9f601b92..46acaba245637 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -31,6 +31,7 @@ import ( "github.com/pingcap/parser/terror" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" + "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tipb/go-tipb" @@ -1284,7 +1285,16 @@ func (b *builtinWeekWithoutModeSig) evalInt(row chunk.Row) (int64, bool, error) return 0, true, errors.Trace(handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(date.String()))) } - week := date.Time.Week(0) + mode := 0 + modeStr, ok := b.ctx.GetSessionVars().GetSystemVar(variable.DefaultWeekFormat) + if ok && modeStr != "" { + mode, err = strconv.Atoi(modeStr) + if err != nil { + return 0, true, handleInvalidTimeError(b.ctx, types.ErrInvalidWeekModeFormat.GenWithStackByArgs(modeStr)) + } + } + + week := date.Time.Week(mode) return int64(week), false, nil } diff --git a/expression/builtin_time_test.go b/expression/builtin_time_test.go index 74dca9594a50f..2c5d409b5a20c 100644 --- a/expression/builtin_time_test.go +++ b/expression/builtin_time_test.go @@ -1456,9 +1456,35 @@ func (s *testEvaluatorSuite) TestWeek(c *C) { c.Assert(err, IsNil) c.Assert(result.GetInt64(), Equals, test.expect) } - } +func (s *testEvaluatorSuite) TestWeekWithoutModeSig(c *C) { + tests := []struct { + t string + expect int64 + }{ + {"2008-02-20", 7}, + {"2000-12-31", 53}, + {"2000-12-31", 1}, //set default week mode + {"2005-12-3", 48}, //set default week mode + {"2008-02-20", 7}, + } + + fc := funcs[ast.Week] + for i, test := range tests { + arg1 := types.NewStringDatum(test.t) + f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Datum{arg1})) + c.Assert(err, IsNil) + result, err := evalBuiltinFunc(f, chunk.Row{}) + c.Assert(err, IsNil) + c.Assert(result.GetInt64(), Equals, test.expect) + if i == 1 { + s.ctx.GetSessionVars().SetSystemVar("default_week_format", "6") + } else if i == 3 { + s.ctx.GetSessionVars().SetSystemVar("default_week_format", "") + } + } +} func (s *testEvaluatorSuite) TestYearWeek(c *C) { sc := s.ctx.GetSessionVars().StmtCtx sc.IgnoreZeroInDate = true diff --git a/expression/errors.go b/expression/errors.go index 1ebc4ffdaba7b..4b60261337cd8 100644 --- a/expression/errors.go +++ b/expression/errors.go @@ -68,7 +68,8 @@ func init() { // handleInvalidTimeError reports error or warning depend on the context. func handleInvalidTimeError(ctx sessionctx.Context, err error) error { - if err == nil || !(terror.ErrorEqual(err, types.ErrInvalidTimeFormat) || types.ErrIncorrectDatetimeValue.Equal(err) || types.ErrTruncatedWrongValue.Equal(err)) { + if err == nil || !(terror.ErrorEqual(err, types.ErrInvalidTimeFormat) || types.ErrIncorrectDatetimeValue.Equal(err) || + types.ErrTruncatedWrongValue.Equal(err) || types.ErrInvalidWeekModeFormat.Equal(err)) { return err } sc := ctx.GetSessionVars().StmtCtx diff --git a/types/time.go b/types/time.go index 4ad9d9d45cc94..354124d77a992 100644 --- a/types/time.go +++ b/types/time.go @@ -33,6 +33,7 @@ import ( // Portable analogs of some common call errors. var ( ErrInvalidTimeFormat = terror.ClassTypes.New(mysql.ErrTruncatedWrongValue, "invalid time format: '%v'") + ErrInvalidWeekModeFormat = terror.ClassTypes.New(mysql.ErrTruncatedWrongValue, "invalid week mode format: '%v'") ErrInvalidYearFormat = errors.New("invalid year format") ErrInvalidYear = errors.New("invalid year") ErrZeroDate = errors.New("datetime zero in date")