MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / parse_interval_value

Method parse_interval_value

src/sql-parser/src/parser.rs:1199–1274  ·  view source on GitHub ↗

Parse an INTERVAL literal. Some syntactically valid intervals: - `INTERVAL '1' DAY` - `INTERVAL '1-1' YEAR TO MONTH` - `INTERVAL '1' SECOND` - `INTERVAL '1:1' MINUTE TO SECOND - `INTERVAL '1:1:1.1' HOUR TO SECOND (5)` - `INTERVAL '1.111' SECOND (2)`

(&mut self)

Source from the content-addressed store, hash-verified

1197 /// - `INTERVAL '1.111' SECOND (2)`
1198 ///
1199 fn parse_interval_value(&mut self) -> Result<IntervalValue, ParserError> {
1200 // The first token in an interval is a string literal which specifies
1201 // the duration of the interval.
1202 let value = self.parse_literal_string()?;
1203
1204 // Determine the range of TimeUnits, whether explicit (`INTERVAL ... DAY TO MINUTE`) or
1205 // implicit (in which all date fields are eligible).
1206 let (precision_high, precision_low, fsec_max_precision) =
1207 match self.expect_one_of_keywords(&[
1208 YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, YEARS, MONTHS, DAYS, HOURS, MINUTES,
1209 SECONDS,
1210 ]) {
1211 Ok(d) => {
1212 let d_pos = self.peek_prev_pos();
1213 if self.parse_keyword(TO) {
1214 let e = self.expect_one_of_keywords(&[
1215 YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, YEARS, MONTHS, DAYS, HOURS,
1216 MINUTES, SECONDS,
1217 ])?;
1218
1219 let high: DateTimeField = d
1220 .as_str()
1221 .parse()
1222 .map_err(|e| self.error(self.peek_prev_pos(), e))?;
1223 let low: DateTimeField = e
1224 .as_str()
1225 .parse()
1226 .map_err(|e| self.error(self.peek_prev_pos(), e))?;
1227
1228 // Check for invalid ranges, i.e. precision_high is the same
1229 // as or a less significant DateTimeField than
1230 // precision_low.
1231 if high >= low {
1232 return parser_err!(
1233 self,
1234 d_pos,
1235 "Invalid field range in INTERVAL '{}' {} TO {}; the value in the \
1236 position of {} should be more significant than {}.",
1237 value,
1238 d,
1239 e,
1240 d,
1241 e,
1242 );
1243 }
1244
1245 let fsec_max_precision = if low == DateTimeField::Second {
1246 self.parse_optional_precision()?
1247 } else {
1248 None
1249 };
1250
1251 (high, low, fsec_max_precision)
1252 } else {
1253 let low: DateTimeField = d
1254 .as_str()
1255 .parse()
1256 .map_err(|e| self.error(self.peek_prev_pos(), e))?;

Calls 8

parse_literal_stringMethod · 0.80
peek_prev_posMethod · 0.80
parse_keywordMethod · 0.80
parseMethod · 0.45
as_strMethod · 0.45
errorMethod · 0.45

Tested by

no test coverage detected