Skip to content

Commit

Permalink
types: fix incompatible issue for builtin function str_to_date (pin…
Browse files Browse the repository at this point in the history
  • Loading branch information
qw4990 committed Mar 20, 2019
1 parent 2129872 commit 0529b56
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 11 deletions.
5 changes: 5 additions & 0 deletions expression/builtin_time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,11 @@ func (s *testEvaluatorSuite) TestStrToDate(c *C) {
{"2016 11 22 16 50 22", `%Y%m%d%H%i%s`, true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.Local)},
{"16-50-22 2016 11 22", `%H-%i-%s%Y%m%d`, true, time.Date(2016, 11, 22, 16, 50, 22, 0, time.Local)},
{"16-50 2016 11 22", `%H-%i-%s%Y%m%d`, false, time.Time{}},
{"15-01-2001 1:59:58.999", "%d-%m-%Y %I:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 59, 58, 999000000, time.Local)},
{"15-01-2001 1:59:58.1", "%d-%m-%Y %H:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 59, 58, 100000000, time.Local)},
{"15-01-2001 1:59:58.", "%d-%m-%Y %H:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 59, 58, 000000000, time.Local)},
{"15-01-2001 1:9:8.999", "%d-%m-%Y %H:%i:%s.%f", true, time.Date(2001, 1, 15, 1, 9, 8, 999000000, time.Local)},
{"15-01-2001 1:9:8.999", "%d-%m-%Y %H:%i:%S.%f", true, time.Date(2001, 1, 15, 1, 9, 8, 999000000, time.Local)},
}

fc := funcs[ast.StrToDate]
Expand Down
39 changes: 28 additions & 11 deletions types/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -2152,8 +2152,8 @@ var dateFormatParserTable = map[string]dateFormatParser{
"%e": dayOfMonthNumeric, // Day of the month, numeric (0..31)
"%f": microSeconds, // Microseconds (000000..999999)
"%h": hour24TwoDigits, // Hour (01..12)
"%H": hour24TwoDigits, // Hour (01..12)
"%I": hour24TwoDigits, // Hour (01..12)
"%H": hour24Numeric, // Hour (00..23)
"%I": hour12Numeric, // Hour (01..12)
"%i": minutesNumeric, // Minutes, numeric (00..59)
"%j": dayOfYearThreeDigits, // Day of year (001..366)
"%k": hour24Numeric, // Hour (0..23)
Expand Down Expand Up @@ -2257,21 +2257,27 @@ func hour24TwoDigits(t *MysqlTime, input string, ctx map[string]int) (string, bo
}

func secondsNumeric(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
v, succ := parseDigits(input, 2)
result := oneOrTwoDigitRegex.FindString(input)
length := len(result)

v, succ := parseDigits(input, length)
if !succ || v >= 60 {
return input, false
}
t.second = uint8(v)
return input[2:], true
return input[length:], true
}

func minutesNumeric(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
v, succ := parseDigits(input, 2)
result := oneOrTwoDigitRegex.FindString(input)
length := len(result)

v, succ := parseDigits(input, length)
if !succ || v >= 60 {
return input, false
}
t.minute = uint8(v)
return input[2:], true
return input[length:], true
}

const time12HourLen = len("hh:mm:ssAM")
Expand Down Expand Up @@ -2368,6 +2374,9 @@ var oneOrTwoDigitRegex = regexp.MustCompile("^[0-9]{1,2}")
// twoDigitRegex: it was just for two digit number string. Ex: "01" or "12"
var twoDigitRegex = regexp.MustCompile("^[1-9][0-9]?")

// oneToSixDigitRegex: it was just for [0, 999999]
var oneToSixDigitRegex = regexp.MustCompile("^[0-9]{0,6}")

// parseTwoNumeric is used for pattens 0..31 0..24 0..60 and so on.
// It returns the parsed int, and remain data after parse.
func parseTwoNumeric(input string) (int, string) {
Expand Down Expand Up @@ -2427,15 +2436,23 @@ func hour12Numeric(t *MysqlTime, input string, ctx map[string]int) (string, bool
}

func microSeconds(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
if len(input) < 6 {
return input, false
result := oneToSixDigitRegex.FindString(input)
length := len(result)
if length == 0 {
t.microsecond = 0
return input, true
}
v, err := strconv.ParseUint(input[:6], 10, 64)
if err != nil {

v, ok := parseDigits(input, length)

if !ok {
return input, false
}
for v > 0 && v*10 < 1000000 {
v *= 10
}
t.microsecond = uint32(v)
return input[6:], true
return input[length:], true
}

func yearNumericFourDigits(t *MysqlTime, input string, ctx map[string]int) (string, bool) {
Expand Down

0 comments on commit 0529b56

Please sign in to comment.