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

Method parse_prefix

src/sql-parser/src/parser.rs:611–744  ·  view source on GitHub ↗

Parse an expression prefix

(&mut self)

Source from the content-addressed store, hash-verified

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)) => {

Callers 1

parse_subexprMethod · 0.80

Calls 15

FunctionClass · 0.85
next_tokenMethod · 0.80
peek_prev_posMethod · 0.80
peek_tokenMethod · 0.80
prev_tokenMethod · 0.80
parse_named_functionMethod · 0.80
parse_valueMethod · 0.80
parse_listMethod · 0.80
parse_case_exprMethod · 0.80
parse_cast_exprMethod · 0.80
parse_nullif_exprMethod · 0.80

Tested by

no test coverage detected