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 into: None,
77 from: vec![sqlparser::ast::TableWithJoins {
78 relation: sqlparser::ast::TableFactor::Table {
79 name: sqlparser::ast::ObjectName::from(vec![sqlparser::ast::Ident::new("foo")]),
80 alias: None,
81 args: None,
82 with_hints: vec![],
83 partitions: vec![],
84 version: None,
85 with_ordinality: false,
86 json_path: None,
87 sample: None,
88 index_hints: vec![],
89 },
90 joins: vec![],
91 }],
92 lateral_views: vec![],
93 selection: None,
94 group_by: GroupByExpr::Expressions(vec![], vec![]),
95 cluster_by: vec![],
96 distribute_by: vec![],
97 sort_by: vec![],
98 having: None,
99 qualify: None,
100 named_window: vec![],
101 value_table_mode: None,
102 top_before_distinct: false,
103 prewhere: None,
104 window_before_qualify: false,
105 connect_by: None,
106 select_token: AttachedToken::empty(),
107 flavor: SelectFlavor::Standard,
108 };
109
110 let sp_query = Box::new(
111 SpQuery {
112 with: None,
113 body: Box::new(sqlparser::ast::SetExpr::Select(Box::new(select))),
114 order_by: None,
115 limit: None,
116 limit_by: vec![],
117 offset: None,
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}