Parse a query expression, i.e. a `SELECT` statement optionally preceded with some `WITH` CTE declarations and optionally followed by `ORDER BY`. Unlike some other parse_... methods, this one doesn't expect the initial keyword to be already consumed
(&mut self)
| 7499 | /// by `ORDER BY`. Unlike some other parse_... methods, this one doesn't |
| 7500 | /// expect the initial keyword to be already consumed |
| 7501 | fn parse_query(&mut self) -> Result<Query<Raw>, ParserError> { |
| 7502 | self.checked_recur_mut(|parser| { |
| 7503 | let cte_block = if parser.parse_keyword(WITH) { |
| 7504 | if parser.parse_keyword(MUTUALLY) { |
| 7505 | parser.expect_keyword(RECURSIVE)?; |
| 7506 | let options = if parser.consume_token(&Token::LParen) { |
| 7507 | let options = |
| 7508 | parser.parse_comma_separated(Self::parse_mut_rec_block_option)?; |
| 7509 | parser.expect_token(&Token::RParen)?; |
| 7510 | options |
| 7511 | } else { |
| 7512 | vec![] |
| 7513 | }; |
| 7514 | CteBlock::MutuallyRecursive(MutRecBlock { |
| 7515 | options, |
| 7516 | ctes: parser.parse_comma_separated(Parser::parse_cte_mut_rec)?, |
| 7517 | }) |
| 7518 | } else { |
| 7519 | // TODO: optional RECURSIVE |
| 7520 | CteBlock::Simple(parser.parse_comma_separated(Parser::parse_cte)?) |
| 7521 | } |
| 7522 | } else { |
| 7523 | CteBlock::empty() |
| 7524 | }; |
| 7525 | |
| 7526 | let body = parser.parse_query_body(SetPrecedence::Zero)?; |
| 7527 | |
| 7528 | parser.parse_query_tail(cte_block, body) |
| 7529 | }) |
| 7530 | } |
| 7531 | |
| 7532 | fn parse_mut_rec_block_option(&mut self) -> Result<MutRecBlockOption<Raw>, ParserError> { |
| 7533 | match self.expect_one_of_keywords(&[RECURSION, RETURN, ERROR])? { |
no test coverage detected