github.com/dolthub/go-mysql-server@v0.18.0/sql/planbuilder/dateparse/parsers.go (about) 1 package dateparse 2 3 import ( 4 "fmt" 5 "time" 6 ) 7 8 // parser defines a function that processes a string and returns the 9 // remaining characters unconsumed by the given parser. 10 // 11 // The data parsed from the consumed characters should be 12 // written to the `datetime` struct. 13 type parser func(result *datetime, chars string) (rest string, err error) 14 15 func trimPrefix(count int, str string) string { 16 if len(str) > count { 17 return str[count:] 18 } 19 return "" 20 } 21 22 func literalParser(literal byte) parser { 23 return func(dt *datetime, chars string) (rest string, _ error) { 24 if len(chars) < 1 && literal != ' ' { 25 return "", fmt.Errorf("expected literal \"%c\", found empty string", literal) 26 } 27 chars = takeAllSpaces(chars) 28 if literal == ' ' { 29 return chars, nil 30 } 31 if chars[0] != literal { 32 return "", fmt.Errorf("expected literal \"%c\", got \"%c\"", literal, chars[0]) 33 } 34 return trimPrefix(1, chars), nil 35 } 36 } 37 38 func parseAmPm(result *datetime, chars string) (rest string, _ error) { 39 if len(chars) < 2 { 40 return "", fmt.Errorf("expected > 2 chars, found %d", len(chars)) 41 } 42 switch chars[:2] { 43 case "am": 44 result.am = boolPtr(true) 45 case "pm": 46 result.am = boolPtr(false) 47 default: 48 return "", fmt.Errorf("expected AM or PM, got \"%s\"", chars[:2]) 49 } 50 return trimPrefix(2, chars), nil 51 } 52 53 func parseWeekdayAbbreviation(result *datetime, chars string) (rest string, _ error) { 54 if len(chars) < 3 { 55 return "", fmt.Errorf("expected at least 3 chars, got %d", len(chars)) 56 } 57 weekday, ok := weekdayAbbrev(chars[:3]) 58 if !ok { 59 return "", fmt.Errorf("invalid week abbreviation \"%s\"", chars[:3]) 60 } 61 result.weekday = &weekday 62 return trimPrefix(3, chars), nil 63 } 64 65 func parseMonthAbbreviation(result *datetime, chars string) (rest string, _ error) { 66 if len(chars) < 3 { 67 return "", fmt.Errorf("expected at least 3 chars, got %d", len(chars)) 68 } 69 month, ok := monthAbbrev(chars[:3]) 70 if !ok { 71 return "", fmt.Errorf("invalid month abbreviation \"%s\"", chars[:3]) 72 } 73 result.month = &month 74 return trimPrefix(3, chars), nil 75 } 76 77 func parseMonthNumeric(result *datetime, chars string) (rest string, _ error) { 78 num, rest, err := takeNumber(chars) 79 if err != nil { 80 return "", err 81 } 82 month := time.Month(num) 83 result.month = &month 84 return rest, nil 85 } 86 87 func parseDayOfMonthNumeric(result *datetime, chars string) (rest string, _ error) { 88 num, rest, err := takeNumber(chars) 89 if err != nil { 90 return "", err 91 } 92 result.day = &num 93 return rest, nil 94 } 95 96 func parseMicrosecondsNumeric(result *datetime, chars string) (rest string, _ error) { 97 num, rest, err := takeNumber(chars) 98 if err != nil { 99 return "", err 100 } 101 result.microseconds = &num 102 return rest, nil 103 } 104 105 func parse24HourNumeric(result *datetime, chars string) (rest string, _ error) { 106 hour, rest, err := takeNumber(chars) 107 if err != nil { 108 return "", err 109 } 110 result.hours = &hour 111 return rest, nil 112 } 113 114 func parse12HourNumeric(result *datetime, chars string) (rest string, _ error) { 115 num, rest, err := takeNumber(chars) 116 if err != nil { 117 return "", err 118 } 119 result.hours = &num 120 return rest, nil 121 } 122 123 func parseMinuteNumeric(result *datetime, chars string) (rest string, _ error) { 124 min, rest, err := takeNumber(chars) 125 if err != nil { 126 return "", err 127 } 128 result.minutes = &min 129 return rest, nil 130 } 131 132 func parseMonthName(result *datetime, chars string) (rest string, _ error) { 133 month, charCount, ok := monthName(chars) 134 if !ok { 135 return "", fmt.Errorf("unknown month name, got \"%s\"", chars) 136 } 137 result.month = &month 138 return trimPrefix(charCount, chars), nil 139 } 140 141 func parse12HourTimestamp(result *datetime, chars string) (rest string, _ error) { 142 hour, rest, err := takeNumberAtMostNChars(2, chars) 143 if err != nil { 144 return "", err 145 } 146 rest, err = literalParser(':')(result, rest) 147 if err != nil { 148 return "", err 149 } 150 min, rest, err := takeNumberAtMostNChars(2, rest) 151 if err != nil { 152 return "", err 153 } 154 rest, err = literalParser(':')(result, rest) 155 if err != nil { 156 return "", err 157 } 158 sec, rest, err := takeNumberAtMostNChars(2, rest) 159 if err != nil { 160 return "", err 161 } 162 rest = takeAllSpaces(rest) 163 rest, err = parseAmPm(result, rest) 164 if err != nil { 165 return "", err 166 } 167 result.seconds = &sec 168 result.minutes = &min 169 result.hours = &hour 170 return rest, nil 171 } 172 173 func parseSecondsNumeric(result *datetime, chars string) (rest string, _ error) { 174 sec, rest, err := takeNumber(chars) 175 if err != nil { 176 return "", err 177 } 178 result.seconds = &sec 179 return rest, nil 180 } 181 182 func parse24HourTimestamp(result *datetime, chars string) (rest string, _ error) { 183 hour, rest, err := takeNumberAtMostNChars(2, chars) 184 if err != nil { 185 return "", err 186 } 187 rest, err = literalParser(':')(result, rest) 188 if err != nil { 189 return "", err 190 } 191 minute, rest, err := takeNumberAtMostNChars(2, rest) 192 if err != nil { 193 return "", err 194 } 195 rest, err = literalParser(':')(result, rest) 196 if err != nil { 197 return "", err 198 } 199 seconds, rest, err := takeNumberAtMostNChars(2, rest) 200 if err != nil { 201 return "", err 202 } 203 result.hours = &hour 204 result.minutes = &minute 205 result.seconds = &seconds 206 return rest, err 207 } 208 209 func parseYear2DigitNumeric(result *datetime, chars string) (rest string, _ error) { 210 year, rest, err := takeNumberAtMostNChars(2, chars) 211 if err != nil { 212 return "", err 213 } 214 if year >= 70 { 215 year += 1900 216 } else { 217 year += 2000 218 } 219 result.year = &year 220 return rest, nil 221 } 222 223 func parseYear4DigitNumeric(result *datetime, chars string) (rest string, _ error) { 224 if len(chars) < 4 { 225 return "", fmt.Errorf("expected at least 4 chars, got %d", len(chars)) 226 } 227 year, rest, err := takeNumber(chars) 228 if err != nil { 229 return "", err 230 } 231 result.year = &year 232 return rest, nil 233 } 234 235 func parseDayNumericWithEnglishSuffix(result *datetime, chars string) (rest string, _ error) { 236 num, rest, err := takeNumber(chars) 237 if err != nil { 238 return "", err 239 } 240 result.day = &num 241 return trimPrefix(2, rest), nil 242 } 243 244 func parseDayOfYearNumeric(result *datetime, chars string) (rest string, _ error) { 245 num, rest, err := takeNumber(chars) 246 if err != nil { 247 return "", err 248 } 249 result.dayOfYear = &num 250 return rest, nil 251 }