From e80bab6d46869a77d56bdaef29d950bcbd4fdc40 Mon Sep 17 00:00:00 2001 From: Lonng Date: Tue, 15 Oct 2019 17:51:25 +0800 Subject: [PATCH] fix the STR_TO_DATE incompatible between MySQL and TiDB (#12623) Signed-off-by: Lonng --- executor/executor_test.go | 3 +++ expression/builtin_time.go | 1 + types/time.go | 18 ++++++++---------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/executor/executor_test.go b/executor/executor_test.go index 5a1ab52dc2..f999c5cef7 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -3997,6 +3997,9 @@ func (s *testSuite4) TearDownTest(c *C) { func (s *testSuiteP1) 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 f121613370..8d29ec263e 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -1788,6 +1788,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 746e0507fb..739db5fd2c 100644 --- a/types/time.go +++ b/types/time.go @@ -2199,6 +2199,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 @@ -2316,21 +2321,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 }