Parse an operator following an expression
(
&mut self,
expr: Expr<Raw>,
precedence: Precedence,
)
| 1275 | |
| 1276 | /// Parse an operator following an expression |
| 1277 | fn parse_infix( |
| 1278 | &mut self, |
| 1279 | expr: Expr<Raw>, |
| 1280 | precedence: Precedence, |
| 1281 | ) -> Result<Expr<Raw>, ParserError> { |
| 1282 | let tok = self.next_token().unwrap(); // safe as EOF's precedence is the lowest |
| 1283 | |
| 1284 | let regular_binary_operator = match &tok { |
| 1285 | Token::Op(s) => Some(Op::bare(s)), |
| 1286 | Token::Eq => Some(Op::bare("=")), |
| 1287 | Token::Star => Some(Op::bare("*")), |
| 1288 | Token::Keyword(OPERATOR) => { |
| 1289 | self.expect_token(&Token::LParen)?; |
| 1290 | let op = self.parse_operator()?; |
| 1291 | self.expect_token(&Token::RParen)?; |
| 1292 | Some(op) |
| 1293 | } |
| 1294 | _ => None, |
| 1295 | }; |
| 1296 | |
| 1297 | if let Some(op) = regular_binary_operator { |
| 1298 | if let Some(kw) = self.parse_one_of_keywords(ANY_ALL_KEYWORDS) { |
| 1299 | self.parse_any_all(expr, op, kw) |
| 1300 | } else { |
| 1301 | Ok(Expr::Op { |
| 1302 | op, |
| 1303 | expr1: Box::new(expr), |
| 1304 | expr2: Some(Box::new(self.parse_subexpr(precedence)?)), |
| 1305 | }) |
| 1306 | } |
| 1307 | } else if let Token::Keyword(kw) = tok { |
| 1308 | match kw { |
| 1309 | IS => { |
| 1310 | let negated = self.parse_keyword(NOT); |
| 1311 | if let Some(construct) = |
| 1312 | self.parse_one_of_keywords(&[NULL, TRUE, FALSE, UNKNOWN, DISTINCT]) |
| 1313 | { |
| 1314 | let construct = match construct { |
| 1315 | NULL => IsExprConstruct::Null, |
| 1316 | TRUE => IsExprConstruct::True, |
| 1317 | FALSE => IsExprConstruct::False, |
| 1318 | UNKNOWN => IsExprConstruct::Unknown, |
| 1319 | DISTINCT => { |
| 1320 | self.expect_keyword(FROM)?; |
| 1321 | // Parse the right-hand side at the precedence of |
| 1322 | // the `IS` operator we are in the middle of, not |
| 1323 | // at `Precedence::Zero`. Otherwise we greedily |
| 1324 | // pull a trailing `AND`/`OR` into the RHS and |
| 1325 | // parse `a IS DISTINCT FROM b AND c` as `a IS |
| 1326 | // DISTINCT FROM (b AND c)`. `IS DISTINCT FROM` |
| 1327 | // binds tighter than `AND`/`OR` (and looser than |
| 1328 | // comparison and arithmetic), matching |
| 1329 | // PostgreSQL. |
| 1330 | let expr = self.parse_subexpr(precedence)?; |
| 1331 | IsExprConstruct::DistinctFrom(Box::new(expr)) |
| 1332 | } |
| 1333 | _ => unreachable!(), |
| 1334 | }; |
no test coverage detected