Parse string into Interval expression. [@] [quantity unit...] quantity: is a number (possibly signed) unit: is microsecond, millisecond, second, minute, hour, day, week, month, year, decade, century, millennium, or abbreviations or plurals of these units direction: can be ago or empty The at sign (@) is optional noise Ref: https://www.postgresql.org/docs/current/da
(
interval_str: &str,
location: SourceLocation,
)
| 51 | /// |
| 52 | /// Ref: https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-INTERVAL-INPUT |
| 53 | fn parse_interval_literal( |
| 54 | interval_str: &str, |
| 55 | location: SourceLocation, |
| 56 | ) -> Result<Interval, Box<Diagnostic>> { |
| 57 | let tokens = interval_str.split_whitespace().collect::<Vec<&str>>(); |
| 58 | if tokens.is_empty() { |
| 59 | return Err(Diagnostic::error("Interval value can't be empty") |
| 60 | .add_help("Please check the documentation for help") |
| 61 | .with_location(location) |
| 62 | .as_boxed()); |
| 63 | } |
| 64 | |
| 65 | let mut position = 0; |
| 66 | let mut interval = Interval::default(); |
| 67 | |
| 68 | // Date part |
| 69 | let mut has_millenniums = false; |
| 70 | let mut has_centuries = false; |
| 71 | let mut has_decades = false; |
| 72 | let mut has_years = false; |
| 73 | let mut has_months = false; |
| 74 | let mut has_week = false; |
| 75 | let mut has_days = false; |
| 76 | |
| 77 | // Time part |
| 78 | let mut has_any_time_part = false; |
| 79 | let mut has_hours: bool = false; |
| 80 | let mut has_minutes = false; |
| 81 | let mut has_seconds = false; |
| 82 | |
| 83 | let mut has_direction_ago = false; |
| 84 | |
| 85 | while position < tokens.len() { |
| 86 | let token = tokens[position].trim(); |
| 87 | if token.is_empty() { |
| 88 | position += 1; |
| 89 | continue; |
| 90 | } |
| 91 | |
| 92 | if token == "ago" { |
| 93 | if has_direction_ago { |
| 94 | return Err( |
| 95 | Diagnostic::error("Interval can't contains more than one `ago`") |
| 96 | .add_help("Please keep at most only one `ago` direction") |
| 97 | .with_location(location) |
| 98 | .as_boxed(), |
| 99 | ); |
| 100 | } |
| 101 | |
| 102 | has_direction_ago = true; |
| 103 | position += 1; |
| 104 | continue; |
| 105 | } |
| 106 | |
| 107 | // Parse Millienniums, Centuries, Decades, Years, Weeks, Months and Days |
| 108 | if let Ok(value) = token.parse::<i64>() { |
| 109 | // Consume value |
| 110 | position += 1; |
searching dependent graphs…