Skip to content

Commit 39761b0

Browse files
authored
Add optional format for explain (#621)
* Add format for explain * Add comment
1 parent 495ab59 commit 39761b0

File tree

4 files changed

+88
-5
lines changed

4 files changed

+88
-5
lines changed

src/ast/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,6 +1294,8 @@ pub enum Statement {
12941294
verbose: bool,
12951295
/// A SQL query that specifies what to explain
12961296
statement: Box<Statement>,
1297+
/// Optional output format of explain
1298+
format: Option<AnalyzeFormat>,
12971299
},
12981300
/// SAVEPOINT -- define a new savepoint within the current transaction
12991301
Savepoint { name: Ident },
@@ -1344,6 +1346,7 @@ impl fmt::Display for Statement {
13441346
verbose,
13451347
analyze,
13461348
statement,
1349+
format,
13471350
} => {
13481351
if *describe_alias {
13491352
write!(f, "DESCRIBE ")?;
@@ -1359,6 +1362,10 @@ impl fmt::Display for Statement {
13591362
write!(f, "VERBOSE ")?;
13601363
}
13611364

1365+
if let Some(format) = format {
1366+
write!(f, "FORMAT {} ", format)?;
1367+
}
1368+
13621369
write!(f, "{}", statement)
13631370
}
13641371
Statement::Query(s) => write!(f, "{}", s),
@@ -2489,6 +2496,24 @@ pub struct Function {
24892496
pub special: bool,
24902497
}
24912498

2499+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2500+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2501+
pub enum AnalyzeFormat {
2502+
TEXT,
2503+
GRAPHVIZ,
2504+
JSON,
2505+
}
2506+
2507+
impl fmt::Display for AnalyzeFormat {
2508+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
2509+
f.write_str(match self {
2510+
AnalyzeFormat::TEXT => "TEXT",
2511+
AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
2512+
AnalyzeFormat::JSON => "JSON",
2513+
})
2514+
}
2515+
}
2516+
24922517
impl fmt::Display for Function {
24932518
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24942519
if self.special {

src/keywords.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ define_keywords!(
256256
GLOBAL,
257257
GRANT,
258258
GRANTED,
259+
GRAPHVIZ,
259260
GROUP,
260261
GROUPING,
261262
GROUPS,
@@ -288,6 +289,7 @@ define_keywords!(
288289
ISOYEAR,
289290
JAR,
290291
JOIN,
292+
JSON,
291293
JSONFILE,
292294
JULIAN,
293295
KEY,

src/parser.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,18 @@ impl<'a> Parser<'a> {
20232023
}
20242024
}
20252025

2026+
pub fn parse_analyze_format(&mut self) -> Result<AnalyzeFormat, ParserError> {
2027+
match self.next_token() {
2028+
Token::Word(w) => match w.keyword {
2029+
Keyword::TEXT => Ok(AnalyzeFormat::TEXT),
2030+
Keyword::GRAPHVIZ => Ok(AnalyzeFormat::GRAPHVIZ),
2031+
Keyword::JSON => Ok(AnalyzeFormat::JSON),
2032+
_ => self.expected("fileformat", Token::Word(w)),
2033+
},
2034+
unexpected => self.expected("fileformat", unexpected),
2035+
}
2036+
}
2037+
20262038
pub fn parse_create_view(&mut self, or_replace: bool) -> Result<Statement, ParserError> {
20272039
let materialized = self.parse_keyword(Keyword::MATERIALIZED);
20282040
self.expect_keyword(Keyword::VIEW)?;
@@ -3432,13 +3444,18 @@ impl<'a> Parser<'a> {
34323444
pub fn parse_explain(&mut self, describe_alias: bool) -> Result<Statement, ParserError> {
34333445
let analyze = self.parse_keyword(Keyword::ANALYZE);
34343446
let verbose = self.parse_keyword(Keyword::VERBOSE);
3447+
let mut format = None;
3448+
if self.parse_keyword(Keyword::FORMAT) {
3449+
format = Some(self.parse_analyze_format()?);
3450+
}
34353451

34363452
if let Some(statement) = self.maybe_parse(|parser| parser.parse_statement()) {
34373453
Ok(Statement::Explain {
34383454
describe_alias,
34393455
analyze,
34403456
verbose,
34413457
statement: Box::new(statement),
3458+
format,
34423459
})
34433460
} else {
34443461
let table_name = self.parse_object_name()?;

tests/sqlparser_common.rs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2657,16 +2657,23 @@ fn parse_scalar_function_in_projection() {
26572657
}
26582658
}
26592659

2660-
fn run_explain_analyze(query: &str, expected_verbose: bool, expected_analyze: bool) {
2660+
fn run_explain_analyze(
2661+
query: &str,
2662+
expected_verbose: bool,
2663+
expected_analyze: bool,
2664+
expected_format: Option<AnalyzeFormat>,
2665+
) {
26612666
match verified_stmt(query) {
26622667
Statement::Explain {
26632668
describe_alias: _,
26642669
analyze,
26652670
verbose,
26662671
statement,
2672+
format,
26672673
} => {
26682674
assert_eq!(verbose, expected_verbose);
26692675
assert_eq!(analyze, expected_analyze);
2676+
assert_eq!(format, expected_format);
26702677
assert_eq!("SELECT sqrt(id) FROM foo", statement.to_string());
26712678
}
26722679
_ => panic!("Unexpected Statement, must be Explain"),
@@ -2693,15 +2700,47 @@ fn parse_explain_table() {
26932700
#[test]
26942701
fn parse_explain_analyze_with_simple_select() {
26952702
// Describe is an alias for EXPLAIN
2696-
run_explain_analyze("DESCRIBE SELECT sqrt(id) FROM foo", false, false);
2703+
run_explain_analyze("DESCRIBE SELECT sqrt(id) FROM foo", false, false, None);
26972704

2698-
run_explain_analyze("EXPLAIN SELECT sqrt(id) FROM foo", false, false);
2699-
run_explain_analyze("EXPLAIN VERBOSE SELECT sqrt(id) FROM foo", true, false);
2700-
run_explain_analyze("EXPLAIN ANALYZE SELECT sqrt(id) FROM foo", false, true);
2705+
run_explain_analyze("EXPLAIN SELECT sqrt(id) FROM foo", false, false, None);
2706+
run_explain_analyze(
2707+
"EXPLAIN VERBOSE SELECT sqrt(id) FROM foo",
2708+
true,
2709+
false,
2710+
None,
2711+
);
2712+
run_explain_analyze(
2713+
"EXPLAIN ANALYZE SELECT sqrt(id) FROM foo",
2714+
false,
2715+
true,
2716+
None,
2717+
);
27012718
run_explain_analyze(
27022719
"EXPLAIN ANALYZE VERBOSE SELECT sqrt(id) FROM foo",
27032720
true,
27042721
true,
2722+
None,
2723+
);
2724+
2725+
run_explain_analyze(
2726+
"EXPLAIN ANALYZE FORMAT GRAPHVIZ SELECT sqrt(id) FROM foo",
2727+
false,
2728+
true,
2729+
Some(AnalyzeFormat::GRAPHVIZ),
2730+
);
2731+
2732+
run_explain_analyze(
2733+
"EXPLAIN ANALYZE VERBOSE FORMAT JSON SELECT sqrt(id) FROM foo",
2734+
true,
2735+
true,
2736+
Some(AnalyzeFormat::JSON),
2737+
);
2738+
2739+
run_explain_analyze(
2740+
"EXPLAIN VERBOSE FORMAT TEXT SELECT sqrt(id) FROM foo",
2741+
true,
2742+
false,
2743+
Some(AnalyzeFormat::TEXT),
27052744
);
27062745
}
27072746

0 commit comments

Comments
 (0)