linkrs_query/parser/parsing/
explain_parser.rs1use crate::parser::ast::stmt::*;
6use crate::parser::core::error::{ParseError, ParseErrorKind};
7use crate::parser::parsing::parse_context::ParseContext;
8use crate::parser::parsing::stmt_parser::StmtParser;
9use crate::parser::TokenKind;
10
11pub struct ExplainParser;
13
14impl Default for ExplainParser {
15 fn default() -> Self {
16 Self
17 }
18}
19
20impl ExplainParser {
21 pub fn new() -> Self {
22 Self
23 }
24
25 pub fn parse_explain_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
27 let start_span = ctx.current_span();
28 ctx.expect_token(TokenKind::Explain)?;
29
30 let analyze = ctx.match_token(TokenKind::Analyze);
31
32 let format = if ctx.match_token(TokenKind::Format) {
33 ctx.expect_token(TokenKind::Assign)?;
34 let format_name = ctx.expect_identifier()?;
35 match format_name.to_uppercase().as_str() {
36 "DOT" => ExplainFormat::Dot,
37 "TABLE" => ExplainFormat::Table,
38 _ => {
39 return Err(ParseError::new(
40 ParseErrorKind::SyntaxError,
41 format!(
42 "Unknown EXPLAIN format: {}, expects DOT or TABLE",
43 format_name
44 ),
45 ctx.current_position(),
46 ));
47 }
48 }
49 } else {
50 ExplainFormat::default()
51 };
52
53 let statement = Box::new(StmtParser::parse_statement(ctx)?);
54
55 Ok(Stmt::Explain(ExplainStmt {
56 span: start_span,
57 statement,
58 format,
59 analyze,
60 }))
61 }
62
63 pub fn parse_profile_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
65 let start_span = ctx.current_span();
66 ctx.expect_token(TokenKind::Profile)?;
67
68 let format = if ctx.match_token(TokenKind::Format) {
69 ctx.expect_token(TokenKind::Assign)?;
70 let format_name = ctx.expect_identifier()?;
71 match format_name.to_uppercase().as_str() {
72 "DOT" => ExplainFormat::Dot,
73 "TABLE" => ExplainFormat::Table,
74 _ => {
75 return Err(ParseError::new(
76 ParseErrorKind::SyntaxError,
77 format!(
78 "Unknown PROFILE format: {}, expects DOT or TABLE",
79 format_name
80 ),
81 ctx.current_position(),
82 ));
83 }
84 }
85 } else {
86 ExplainFormat::default()
87 };
88
89 let statement = Box::new(StmtParser::parse_statement(ctx)?);
90
91 Ok(Stmt::Profile(ProfileStmt {
92 span: start_span,
93 statement,
94 format,
95 }))
96 }
97
98 pub fn parse_analyze_statement(&mut self, ctx: &mut ParseContext) -> Result<Stmt, ParseError> {
100 let start_span = ctx.current_span();
101 ctx.expect_token(TokenKind::Analyze)?;
102
103 let space = if ctx.match_token(TokenKind::Space) {
104 Some(ctx.expect_identifier()?)
105 } else {
106 None
107 };
108
109 Ok(Stmt::Analyze(AnalyzeStmt {
110 span: start_span,
111 space,
112 }))
113 }
114}