sql/parsers/
explain_parser.rs1use snafu::ResultExt;
16use sqlparser::keywords::Keyword;
17
18use crate::error::{self, Result};
19use crate::parser::ParserContext;
20use crate::statements::explain::ExplainStatement;
21use crate::statements::statement::Statement;
22
23impl ParserContext<'_> {
25 pub(crate) fn parse_explain(&mut self) -> Result<Statement> {
27 let analyze = self.parser.parse_keyword(Keyword::ANALYZE);
28 let verbose = self.parser.parse_keyword(Keyword::VERBOSE);
29 let format =
30 if self.parser.parse_keyword(Keyword::FORMAT) {
31 Some(self.parser.parse_analyze_format().with_context(|_| {
32 error::UnexpectedSnafu {
33 expected: "analyze format",
34 actual: self.peek_token_as_string(),
35 }
36 })?)
37 } else {
38 None
39 };
40
41 let statement = self.parse_statement()?;
42
43 let explain = ExplainStatement {
44 analyze,
45 verbose,
46 format,
47 statement: Box::new(statement),
48 };
49 Ok(Statement::Explain(Box::new(explain)))
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use sqlparser::ast::helpers::attached_token::AttachedToken;
56 use sqlparser::ast::{GroupByExpr, Query as SpQuery, SelectFlavor, WildcardAdditionalOptions};
57
58 use super::*;
59 use crate::dialect::GreptimeDbDialect;
60 use crate::parser::ParseOptions;
61
62 #[test]
63 pub fn test_explain() {
64 let sql = "EXPLAIN select * from foo";
65 let result =
66 ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
67 let stmts = result.unwrap();
68 assert_eq!(1, stmts.len());
69
70 let select = sqlparser::ast::Select {
71 distinct: None,
72 top: None,
73 projection: vec![sqlparser::ast::SelectItem::Wildcard(
74 WildcardAdditionalOptions::default(),
75 )],
76 exclude: None,
77 into: None,
78 from: vec![sqlparser::ast::TableWithJoins {
79 relation: sqlparser::ast::TableFactor::Table {
80 name: sqlparser::ast::ObjectName::from(vec![sqlparser::ast::Ident::new("foo")]),
81 alias: None,
82 args: None,
83 with_hints: vec![],
84 partitions: vec![],
85 version: None,
86 with_ordinality: false,
87 json_path: None,
88 sample: None,
89 index_hints: vec![],
90 },
91 joins: vec![],
92 }],
93 lateral_views: vec![],
94 selection: None,
95 group_by: GroupByExpr::Expressions(vec![], vec![]),
96 cluster_by: vec![],
97 distribute_by: vec![],
98 sort_by: vec![],
99 having: None,
100 qualify: None,
101 named_window: vec![],
102 value_table_mode: None,
103 top_before_distinct: false,
104 prewhere: None,
105 window_before_qualify: false,
106 connect_by: None,
107 select_token: AttachedToken::empty(),
108 flavor: SelectFlavor::Standard,
109 };
110
111 let sp_query = Box::new(
112 SpQuery {
113 with: None,
114 body: Box::new(sqlparser::ast::SetExpr::Select(Box::new(select))),
115 order_by: None,
116 limit_clause: None,
117 pipe_operators: vec![],
118 fetch: None,
119 locks: vec![],
120 for_clause: None,
121 settings: None,
122 format_clause: None,
123 }
124 .try_into()
125 .unwrap(),
126 );
127
128 let explain = ExplainStatement {
129 analyze: false,
130 verbose: false,
131 format: None,
132 statement: Box::new(Statement::Query(sp_query)),
133 };
134
135 assert_eq!(stmts[0], Statement::Explain(Box::new(explain)))
136 }
137}