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 select_modifiers: None,
73 top: None,
74 projection: vec![sqlparser::ast::SelectItem::Wildcard(
75 WildcardAdditionalOptions::default(),
76 )],
77 exclude: None,
78 into: None,
79 from: vec![sqlparser::ast::TableWithJoins {
80 relation: sqlparser::ast::TableFactor::Table {
81 name: sqlparser::ast::ObjectName::from(vec![sqlparser::ast::Ident::new("foo")]),
82 alias: None,
83 args: None,
84 with_hints: vec![],
85 partitions: vec![],
86 version: None,
87 with_ordinality: false,
88 json_path: None,
89 sample: None,
90 index_hints: vec![],
91 },
92 joins: vec![],
93 }],
94 lateral_views: vec![],
95 selection: None,
96 group_by: GroupByExpr::Expressions(vec![], vec![]),
97 cluster_by: vec![],
98 distribute_by: vec![],
99 sort_by: vec![],
100 having: None,
101 qualify: None,
102 named_window: vec![],
103 value_table_mode: None,
104 top_before_distinct: false,
105 prewhere: None,
106 window_before_qualify: false,
107 connect_by: vec![],
108 select_token: AttachedToken::empty(),
109 flavor: SelectFlavor::Standard,
110 optimizer_hint: None,
111 };
112
113 let sp_query = Box::new(
114 SpQuery {
115 with: None,
116 body: Box::new(sqlparser::ast::SetExpr::Select(Box::new(select))),
117 order_by: None,
118 limit_clause: None,
119 pipe_operators: vec![],
120 fetch: None,
121 locks: vec![],
122 for_clause: None,
123 settings: None,
124 format_clause: None,
125 }
126 .try_into()
127 .unwrap(),
128 );
129
130 let explain = ExplainStatement {
131 analyze: false,
132 verbose: false,
133 format: None,
134 statement: Box::new(Statement::Query(sp_query)),
135 };
136
137 assert_eq!(stmts[0], Statement::Explain(Box::new(explain)))
138 }
139}