Parse an `EXPLAIN ... PLAN` statement, assuming that the `EXPLAIN` token has already been consumed.
(&mut self)
| 9041 | /// Parse an `EXPLAIN ... PLAN` statement, assuming that the `EXPLAIN` token |
| 9042 | /// has already been consumed. |
| 9043 | fn parse_explain_plan(&mut self) -> Result<Statement<Raw>, ParserError> { |
| 9044 | let start = self.peek_pos(); |
| 9045 | let (has_stage, stage) = match self.parse_one_of_keywords(&[ |
| 9046 | RAW, |
| 9047 | DECORRELATED, |
| 9048 | LOCALLY, |
| 9049 | OPTIMIZED, |
| 9050 | PHYSICAL, |
| 9051 | OPTIMIZER, |
| 9052 | PLAN, |
| 9053 | ]) { |
| 9054 | Some(RAW) => { |
| 9055 | self.expect_keyword(PLAN)?; |
| 9056 | (true, Some(ExplainStage::RawPlan)) |
| 9057 | } |
| 9058 | Some(DECORRELATED) => { |
| 9059 | self.expect_keyword(PLAN)?; |
| 9060 | (true, Some(ExplainStage::DecorrelatedPlan)) |
| 9061 | } |
| 9062 | Some(LOCALLY) => { |
| 9063 | self.expect_keywords(&[OPTIMIZED, PLAN])?; |
| 9064 | (true, Some(ExplainStage::LocalPlan)) |
| 9065 | } |
| 9066 | Some(OPTIMIZED) => { |
| 9067 | self.expect_keyword(PLAN)?; |
| 9068 | (true, Some(ExplainStage::GlobalPlan)) |
| 9069 | } |
| 9070 | Some(PHYSICAL) => { |
| 9071 | self.expect_keyword(PLAN)?; |
| 9072 | (true, Some(ExplainStage::PhysicalPlan)) |
| 9073 | } |
| 9074 | Some(OPTIMIZER) => { |
| 9075 | self.expect_keyword(TRACE)?; |
| 9076 | (true, Some(ExplainStage::Trace)) |
| 9077 | } |
| 9078 | Some(PLAN) => { |
| 9079 | if self.parse_keyword(INSIGHTS) { |
| 9080 | (true, Some(ExplainStage::PlanInsights)) |
| 9081 | } else { |
| 9082 | // Use the default plan for the explainee. |
| 9083 | (true, None) |
| 9084 | } |
| 9085 | } |
| 9086 | None => { |
| 9087 | // Use the default plan for the explainee. |
| 9088 | (false, None) |
| 9089 | } |
| 9090 | _ => unreachable!(), |
| 9091 | }; |
| 9092 | |
| 9093 | let with_options = if self.parse_keyword(WITH) { |
| 9094 | if self.consume_token(&Token::LParen) { |
| 9095 | let options = self.parse_comma_separated(Parser::parse_explain_plan_option)?; |
| 9096 | self.expect_token(&Token::RParen)?; |
| 9097 | options |
| 9098 | } else { |
| 9099 | self.prev_token(); // push back WITH in case it's actually a CTE |
| 9100 | vec![] |
no test coverage detected