Parse an expression prefix
(&mut self)
| 609 | |
| 610 | /// Parse an expression prefix |
| 611 | fn parse_prefix(&mut self) -> Result<Expr<Raw>, ParserError> { |
| 612 | // PostgreSQL allows any string literal to be preceded by a type name, |
| 613 | // indicating that the string literal represents a literal of that type. |
| 614 | // Some examples: |
| 615 | // |
| 616 | // DATE '2020-05-20' |
| 617 | // TIMESTAMP WITH TIME ZONE '2020-05-20 7:43:54' |
| 618 | // BOOL 'true' |
| 619 | // |
| 620 | // The first two are standard SQL, while the latter is a PostgreSQL |
| 621 | // extension. Complicating matters is the fact that INTERVAL string |
| 622 | // literals may optionally be followed by some special keywords, e.g.: |
| 623 | // |
| 624 | // INTERVAL '7' DAY |
| 625 | // |
| 626 | // Note also that naively `SELECT date` looks like a syntax error |
| 627 | // because the `date` type name is not followed by a string literal, but |
| 628 | // in fact is a valid expression that should parse as the column name |
| 629 | // "date". |
| 630 | // |
| 631 | // Note: the maybe! block here does swallow valid parsing errors |
| 632 | // See <https://github.com/MaterializeInc/incidents-and-escalations/issues/90> for more details |
| 633 | maybe!(self.maybe_parse(|parser| { |
| 634 | let data_type = parser.parse_data_type()?; |
| 635 | if data_type.to_string().as_str() == "interval" { |
| 636 | Ok(Expr::Value(Value::Interval(parser.parse_interval_value()?))) |
| 637 | } else { |
| 638 | Ok(Expr::Cast { |
| 639 | expr: Box::new(Expr::Value(Value::String(parser.parse_literal_string()?))), |
| 640 | data_type, |
| 641 | }) |
| 642 | } |
| 643 | })); |
| 644 | |
| 645 | let tok = self |
| 646 | .next_token() |
| 647 | .ok_or_else(|| self.error(self.peek_prev_pos(), "Unexpected EOF".to_string()))?; |
| 648 | let expr = match (tok, self.peek_token()) { |
| 649 | (Token::LBracket, _) => { |
| 650 | self.prev_token(); |
| 651 | let function = self.parse_named_function()?; |
| 652 | Ok(Expr::Function(function)) |
| 653 | } |
| 654 | (Token::Keyword(TRUE) | Token::Keyword(FALSE) | Token::Keyword(NULL), _) => { |
| 655 | self.prev_token(); |
| 656 | Ok(Expr::Value(self.parse_value()?)) |
| 657 | } |
| 658 | (Token::Keyword(ARRAY), _) => self.parse_array(), |
| 659 | (Token::Keyword(LIST), Some(Token::LBracket) | Some(Token::LParen)) => { |
| 660 | self.parse_list() |
| 661 | } |
| 662 | (Token::Keyword(MAP), Some(Token::LBracket) | Some(Token::LParen)) => self.parse_map(), |
| 663 | (Token::Keyword(CASE), _) => self.parse_case_expr(), |
| 664 | (Token::Keyword(CAST), _) => self.parse_cast_expr(), |
| 665 | (Token::Keyword(COALESCE), Some(Token::LParen)) => { |
| 666 | self.parse_homogenizing_function(HomogenizingFunction::Coalesce) |
| 667 | } |
| 668 | (Token::Keyword(GREATEST), Some(Token::LParen)) => { |
no test coverage detected