diff --git a/expression/builtin_time.go b/expression/builtin_time.go index 44842541a41ff..ba08265945dc6 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -1847,6 +1847,9 @@ func (b *builtinStrToDateDateSig) evalTime(row chunk.Row) (types.Time, bool, err if !succ { return types.Time{}, true, handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(t.String())) } + if b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() && (t.Time.Year() == 0 || t.Time.Month() == 0 || t.Time.Day() == 0) { + return types.Time{}, true, handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(t.String())) + } t.Type, t.Fsp = mysql.TypeDate, types.MinFsp return t, false, nil } @@ -1876,6 +1879,9 @@ func (b *builtinStrToDateDatetimeSig) evalTime(row chunk.Row) (types.Time, bool, if !succ { return types.Time{}, true, handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(t.String())) } + if b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() && (t.Time.Year() == 0 || t.Time.Month() == 0 || t.Time.Day() == 0) { + return types.Time{}, true, handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(t.String())) + } t.Type, t.Fsp = mysql.TypeDatetime, b.tp.Decimal return t, false, nil } @@ -1908,6 +1914,9 @@ func (b *builtinStrToDateDurationSig) evalDuration(row chunk.Row) (types.Duratio if !succ { return types.Duration{}, true, handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(t.String())) } + if b.ctx.GetSessionVars().SQLMode.HasNoZeroDateMode() && (t.Time.Year() == 0 || t.Time.Month() == 0 || t.Time.Day() == 0) { + return types.Duration{}, true, handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(t.String())) + } t.Fsp = b.tp.Decimal dur, err := t.ConvertToDuration() return dur, err != nil, err diff --git a/expression/integration_test.go b/expression/integration_test.go index 73f27629ee844..6bd91b57691bf 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -4135,6 +4135,37 @@ func (s *testIntegrationSuite) TestDecimalConvertToTime(c *C) { tk.MustQuery("select * from t").Check(testkit.Rows("2001-01-01 10:00:00.123456 2011-07-07 10:11:12")) } +func (s *testIntegrationSuite) TestIssue9732(c *C) { + tk := testkit.NewTestKit(c, s.store) + defer s.cleanEnv(c) + + tk.MustQuery(`select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')), +monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));`).Check(testkit.Rows(" ")) + + nullCases := []struct { + sql string + ret string + }{ + {"select str_to_date(1, '%m')", "0000-01-00"}, + {"select str_to_date(01, '%d')", "0000-00-01"}, + {"select str_to_date(2019, '%Y')", "2019-00-00"}, + {"select str_to_date('5,2019','%m,%Y')", "2019-05-00"}, + {"select str_to_date('01,2019','%d,%Y')", "2019-00-01"}, + {"select str_to_date('01,5','%d,%m')", "0000-05-01"}, + } + + for _, nullCase := range nullCases { + tk.MustQuery(nullCase.sql).Check(testkit.Rows("")) + } + + // remove NO_ZERO_DATE mode + tk.MustExec("set sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'") + + for _, nullCase := range nullCases { + tk.MustQuery(nullCase.sql).Check(testkit.Rows(nullCase.ret)) + } +} + func (s *testIntegrationSuite) TestDaynameArithmetic(c *C) { tk := testkit.NewTestKit(c, s.store) defer s.cleanEnv(c)