diff --git a/internal/function_time_parser.go b/internal/function_time_parser.go index 0becda7..2658f40 100644 --- a/internal/function_time_parser.go +++ b/internal/function_time_parser.go @@ -639,8 +639,8 @@ func yearMonthDayParser(text []rune, t *time.Time) (int, error) { if err != nil { return 0, fmt.Errorf("could not parse year number: %s", err) } - if len(text) < progress || text[progress] != separator { - return 0, fmt.Errorf("could not parse year-month-day: [%c] not found after [%s]", separator, string(text[:progress])) + if len(text) <= progress || text[progress] != separator { + return 0, fmt.Errorf("could not parse year-month-day: [%c] not found after [%s]", separator, string(text)) } progress += 1 @@ -649,8 +649,8 @@ func yearMonthDayParser(text []rune, t *time.Time) (int, error) { return 0, fmt.Errorf("could not parse month number: %s", err) } progress += mProgress - if len(text) < progress || text[progress] != separator { - return 0, fmt.Errorf("could not parse year-month-day: [%c] not found after [%s]", separator, string(text[:progress])) + if len(text) <= progress || text[progress] != separator { + return 0, fmt.Errorf("could not parse year-month-day: [%c] not found after [%s]", separator, string(text)) } progress += 1 @@ -895,11 +895,11 @@ func hourMinuteParser(text []rune, t *time.Time) (int, error) { if err != nil { return 0, fmt.Errorf("could not parse hour: %s", err) } - if text[hProgress] != ':' { - return 0, fmt.Errorf("could not parse hour:minute format: character after hour [%s] is not a `:`", string(text[:hProgress])) + if len(text) <= hProgress || text[hProgress] != ':' { + return 0, fmt.Errorf("could not parse hour:minute format: character after hour [%s] is not a [:]", string(text)) } hProgress += 1 - mProgress, m, err := parseDigitRespectingOptionalPlaces(text, 0, 59) + mProgress, m, err := parseDigitRespectingOptionalPlaces(text[hProgress:], 0, 59) if err != nil { return 0, fmt.Errorf("could not parse minute: %s", err) } diff --git a/query_test.go b/query_test.go index 93924e0..a5dd71f 100644 --- a/query_test.go +++ b/query_test.go @@ -3785,6 +3785,16 @@ SELECT date, EXTRACT(ISOYEAR FROM date), EXTRACT(YEAR FROM date), EXTRACT(MONTH query: `SELECT PARSE_DATE("%Y%m%d", "20081225") AS parsed`, expectedRows: [][]interface{}{{"2008-12-25"}}, }, + { + name: "parse date with %F no day field", + query: `SELECT PARSE_DATE("%F", "2008-01") AS parsed`, + expectedErr: "could not parse year-month-day: [-] not found after [2008-01]", + }, + { + name: "parse date with %F no month field", + query: `SELECT PARSE_DATE("%F", "2008") AS parsed`, + expectedErr: "could not parse year-month-day: [-] not found after [2008]", + }, { name: "parse date with %F", query: `SELECT PARSE_DATE("%F", "2008-12-25") AS parsed`, @@ -3986,6 +3996,22 @@ SELECT date, EXTRACT(ISOYEAR FROM date), EXTRACT(YEAR FROM date), EXTRACT(MONTH query: `SELECT TIME_TRUNC(TIME "15:30:00", HOUR)`, expectedRows: [][]interface{}{{"15:00:00"}}, }, + { + name: "parse_time with %R", + query: `SELECT PARSE_TIME("%R", "14:30")`, + expectedRows: [][]interface{}{{"14:30:00"}}, + }, + { + name: "parse_time with %R without minute element", + query: `SELECT PARSE_TIME("%R", "14")`, + expectedErr: "could not parse hour:minute format: character after hour [14] is not a [:]", + }, + + { + name: "parse_time with %R without separator", + query: `SELECT PARSE_TIME("%R", "14")`, + expectedErr: "could not parse hour:minute format: character after hour [14] is not a [:]", + }, { name: "format_time with %R", query: `SELECT FORMAT_TIME("%R", TIME "15:30:00")`,