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

Method parse_cast_expr

src/sql-parser/src/parser.rs:976–1027  ·  view source on GitHub ↗

Parse a SQL CAST function e.g. `CAST(expr AS FLOAT)`

(&mut self)

Source from the content-addressed store, hash-verified

974
975 /// Parse a SQL CAST function e.g. `CAST(expr AS FLOAT)`
976 fn parse_cast_expr(&mut self) -> Result<Expr<Raw>, ParserError> {
977 // Whether `expr` is safe to print directly to the left of a Postgres-style
978 // `::<type>` cast without wrapping it in parentheses. `Expr::Cast` /
979 // `Expr::Collate` print as the postfix forms `<inner>::<type>` /
980 // `<inner> COLLATE <c>`, so they are only safe when their *own* operand is
981 // — otherwise an inner low-precedence spine (e.g. the quantified comparison
982 // in `CAST(a = ANY (...) AS t)`, parsed as `Cast(AnySubquery)`) would
983 // re-associate against a surrounding operator on reparse. Everything else
984 // in the list is atomic or self-delimiting and so always safe.
985 fn safe_before_pg_cast(expr: &Expr<Raw>) -> bool {
986 match expr {
987 Expr::Nested(_)
988 | Expr::Value(_)
989 | Expr::Function { .. }
990 | Expr::Identifier { .. }
991 | Expr::HomogenizingFunction { .. }
992 | Expr::NullIf { .. }
993 | Expr::Subquery { .. }
994 | Expr::Parameter(..) => true,
995 Expr::Cast { expr, .. } | Expr::Collate { expr, .. } => safe_before_pg_cast(expr),
996 _ => false,
997 }
998 }
999
1000 self.expect_token(&Token::LParen)?;
1001 let expr = self.parse_expr()?;
1002 self.expect_keyword(AS)?;
1003 let data_type = self.parse_data_type()?;
1004 self.expect_token(&Token::RParen)?;
1005 // We are potentially rewriting an expression like
1006 // CAST(<expr> OP <expr> AS <type>)
1007 // to
1008 // <expr> OP <expr>::<type>
1009 // (because we print Expr::Cast always as a Postgres-style cast, i.e. `::`)
1010 // which could incorrectly change the meaning of the expression
1011 // as the `::` binds tightly. To be safe, we wrap the inner
1012 // expression in parentheses
1013 // (<expr> OP <expr>)::<type>
1014 // unless the inner expression is of a kind that we know is
1015 // safe to follow with a `::` without wrapping.
1016 if safe_before_pg_cast(&expr) {
1017 Ok(Expr::Cast {
1018 expr: Box::new(expr),
1019 data_type,
1020 })
1021 } else {
1022 Ok(Expr::Cast {
1023 expr: Box::new(Expr::Nested(Box::new(expr))),
1024 data_type,
1025 })
1026 }
1027 }
1028
1029 /// Parse a SQL EXISTS expression e.g. `WHERE EXISTS(SELECT ...)`.
1030 fn parse_exists_expr(&mut self) -> Result<Expr<Raw>, ParserError> {

Callers 1

parse_prefixMethod · 0.80

Calls 4

expect_tokenMethod · 0.80
parse_exprMethod · 0.80
expect_keywordMethod · 0.80
parse_data_typeMethod · 0.80

Tested by

no test coverage detected