diff --git a/executor/executor_test.go b/executor/executor_test.go index 0685150707ffd..3a3fad0568fd7 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -3796,6 +3796,9 @@ func (s *testSuite4) TearDownTest(c *C) { func (s *testSuite) TestStrToDateBuiltin(c *C) { tk := testkit.NewTestKit(c, s.store) + tk.MustQuery(`select str_to_date('20190101','%Y%m%d%!') from dual`).Check(testkit.Rows("2019-01-01")) + tk.MustQuery(`select str_to_date('20190101','%Y%m%d%f') from dual`).Check(testkit.Rows("2019-01-01 00:00:00.000000")) + tk.MustQuery(`select str_to_date('20190101','%Y%m%d%H%i%s') from dual`).Check(testkit.Rows("2019-01-01 00:00:00")) tk.MustQuery(`select str_to_date('18/10/22','%y/%m/%d') from dual`).Check(testkit.Rows("2018-10-22")) tk.MustQuery(`select str_to_date('a18/10/22','%y/%m/%d') from dual`).Check(testkit.Rows("")) tk.MustQuery(`select str_to_date('69/10/22','%y/%m/%d') from dual`).Check(testkit.Rows("2069-10-22")) diff --git a/expression/builtin_time.go b/expression/builtin_time.go index 45ef659976f09..9b88af516f94c 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -1789,6 +1789,7 @@ func (c *strToDateFunctionClass) getRetTp(ctx sessionctx.Context, arg Expression if err != nil || isNull { return } + isDuration, isDate := types.GetFormatType(format) if isDuration && !isDate { tp = mysql.TypeDuration diff --git a/types/time.go b/types/time.go index 16fade6e14be0..eddbb34bd30a2 100644 --- a/types/time.go +++ b/types/time.go @@ -2179,6 +2179,11 @@ func strToDate(t *MysqlTime, date string, format string, ctx map[string]int) boo return true } + if len(date) == 0 { + ctx[token] = 0 + return true + } + dateRemain, succ := matchDateWithToken(t, date, token, ctx) if !succ { return false @@ -2296,21 +2301,14 @@ func GetFormatType(format string) (isDuration, isDate bool) { isDuration, isDate = false, false break } - var durationTokens bool - var dateTokens bool if len(token) >= 2 && token[0] == '%' { switch token[1] { - case 'h', 'H', 'i', 'I', 's', 'S', 'k', 'l': - durationTokens = true + case 'h', 'H', 'i', 'I', 's', 'S', 'k', 'l', 'f': + isDuration = true case 'y', 'Y', 'm', 'M', 'c', 'b', 'D', 'd', 'e': - dateTokens = true + isDate = true } } - if durationTokens { - isDuration = true - } else if dateTokens { - isDate = true - } if isDuration && isDate { break }