Skip to content

Commit

Permalink
expression: fix incompatible last_day func behavior in sql mode (#25953
Browse files Browse the repository at this point in the history
…) (#26000)
  • Loading branch information
ti-srebot committed Sep 3, 2021
1 parent 814d442 commit 4bb384b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 14 deletions.
2 changes: 1 addition & 1 deletion expression/builtin_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -7034,7 +7034,7 @@ func (b *builtinLastDaySig) evalTime(row chunk.Row) (types.Time, bool, error) {
}
tm := arg
year, month := tm.Year(), tm.Month()
if arg.InvalidZero() {
if tm.Month() == 0 || (tm.Day() == 0 && b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode()) {
return types.ZeroTime, true, handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, arg.String()))
}
lastDay := types.GetLastDay(year, month)
Expand Down
33 changes: 23 additions & 10 deletions expression/builtin_time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2781,22 +2781,35 @@ func (s *testEvaluatorSuite) TestLastDay(c *C) {
c.Assert(result, Equals, test.expect)
}

testsNull := []interface{}{
"0000-00-00",
"1992-13-00",
"2007-10-07 23:59:61",
"2005-00-00",
"2005-00-01",
"2243-01 00:00:00",
123456789}
var timeData types.Time
timeData.StrToDate(s.ctx.GetSessionVars().StmtCtx, "202010", "%Y%m")
testsNull := []struct {
param interface{}
isNilNoZeroDate bool
isNil bool
}{
{"0000-00-00", true, true},
{"1992-13-00", true, true},
{"2007-10-07 23:59:61", true, true},
{"2005-00-00", true, true},
{"2005-00-01", true, true},
{"2243-01 00:00:00", true, true},
{123456789, true, true},
{timeData, true, false},
}

for _, i := range testsNull {
t := []types.Datum{types.NewDatum(i)}
t := []types.Datum{types.NewDatum(i.param)}
f, err := fc.getFunction(s.ctx, s.datumsToConstants(t))
c.Assert(err, IsNil)
d, err := evalBuiltinFunc(f, chunk.Row{})
c.Assert(err, IsNil)
c.Assert(d.IsNull(), IsTrue)
c.Assert(d.IsNull() == i.isNilNoZeroDate, IsTrue)
s.ctx.GetSessionVars().SQLMode &= ^mysql.ModeNoZeroDate
d, err = evalBuiltinFunc(f, chunk.Row{})
c.Assert(err, IsNil)
c.Assert(d.IsNull() == i.isNil, IsTrue)
s.ctx.GetSessionVars().SQLMode |= mysql.ModeNoZeroDate
}
}

Expand Down
6 changes: 3 additions & 3 deletions expression/builtin_time_vec.go
Original file line number Diff line number Diff line change
Expand Up @@ -712,15 +712,15 @@ func (b *builtinLastDaySig) vecEvalTime(input *chunk.Chunk, result *chunk.Column
if result.IsNull(i) {
continue
}
if times[i].InvalidZero() {
tm := times[i]
year, month := tm.Year(), tm.Month()
if tm.Month() == 0 || (tm.Day() == 0 && b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode()) {
if err := handleInvalidTimeError(b.ctx, types.ErrWrongValue.GenWithStackByArgs(types.DateTimeStr, times[i].String())); err != nil {
return err
}
result.SetNull(i, true)
continue
}
tm := times[i]
year, month := tm.Year(), tm.Month()
lastDay := types.GetLastDay(year, month)
times[i] = types.NewTime(types.FromDate(year, month, lastDay, 0, 0, 0, 0), mysql.TypeDate, types.DefaultFsp)
}
Expand Down

0 comments on commit 4bb384b

Please sign in to comment.