Skip to content

Commit 8ec3967

Browse files
authored
feat(ast): support EXPLAIN VERBOSE alias (#16161) (#19726)
1 parent b549e0d commit 8ec3967

3 files changed

Lines changed: 65 additions & 5 deletions

File tree

src/query/ast/src/parser/statement.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,19 @@ fn query_statement(i: Input) -> IResult<Statement> {
7979
}
8080

8181
pub fn statement_body(i: Input) -> IResult<Statement> {
82+
let explain_options = map(
83+
rule! {
84+
"(" ~ #comma_separated_list1(explain_option) ~ ")"
85+
},
86+
|(a, opts, b)| (merge_span(Some(a.span), Some(b.span)), opts),
87+
);
88+
let explain_verbose_alias = map(rule! { VERBOSE }, |verbose| {
89+
(Some(verbose.span), vec![ExplainOption::Verbose])
90+
});
91+
8292
let explain = map_res(
8393
rule! {
84-
EXPLAIN ~ ( "(" ~ #comma_separated_list1(explain_option) ~ ")" )? ~ ( AST | SYNTAX | PIPELINE | JOIN | GRAPH | FRAGMENTS | RAW | OPTIMIZED | MEMO | DECORRELATED | PERF)? ~ #statement
94+
EXPLAIN ~ ( #explain_options | #explain_verbose_alias )? ~ ( AST | SYNTAX | PIPELINE | JOIN | GRAPH | FRAGMENTS | RAW | OPTIMIZED | MEMO | DECORRELATED | PERF)? ~ #statement
8595
},
8696
|(_, options, opt_kind, statement)| {
8797
Ok(Statement::Explain {
@@ -105,9 +115,7 @@ pub fn statement_body(i: Input) -> IResult<Statement> {
105115
None => ExplainKind::Plan,
106116
_ => unreachable!(),
107117
},
108-
options: options
109-
.map(|(a, opts, b)| (merge_span(Some(a.span), Some(b.span)), opts))
110-
.unwrap_or_default(),
118+
options: options.unwrap_or_default(),
111119
query: Box::new(statement.stmt),
112120
})
113121
},
@@ -2783,7 +2791,7 @@ pub fn statement_body(i: Input) -> IResult<Statement> {
27832791
HintPrefix | LParen | FROM => query_statement(i),
27842792
EXPLAIN => rule!(
27852793
#explain_perf : "`EXPLAIN PERF [(events='<event>,...')] <statement>`"
2786-
| #explain : "`EXPLAIN [PIPELINE | GRAPH] <statement>`"
2794+
| #explain : "`EXPLAIN [VERBOSE | (<option>, ...)] [PIPELINE | GRAPH] <statement>`"
27872795
| #explain_analyze : "`EXPLAIN ANALYZE <statement>`"
27882796
).parse(i),
27892797
REPORT => rule!(#report: "`REPORT ISSUE <statement>`").parse(i),

src/query/ast/tests/it/display.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use databend_common_ast::ast::ExplainKind;
16+
use databend_common_ast::ast::ExplainOption;
17+
use databend_common_ast::ast::Statement;
1518
use databend_common_ast::parser::Dialect;
1619
use databend_common_ast::parser::parse_sql;
1720
use databend_common_ast::parser::tokenize_sql;
@@ -82,3 +85,24 @@ fn test_parse_sql_nested_join_conditions_without_panic() {
8285
parse_sql(&tokens, Dialect::PostgreSQL).unwrap();
8386
}
8487
}
88+
89+
#[test]
90+
fn test_explain_verbose_alias_display() {
91+
let tokens = tokenize_sql("EXPLAIN VERBOSE SELECT * FROM t").unwrap();
92+
let (stmt, _) = parse_sql(&tokens, Dialect::PostgreSQL).unwrap();
93+
94+
match &stmt {
95+
Statement::Explain {
96+
kind,
97+
options: (_, options),
98+
..
99+
} => {
100+
assert_eq!(kind, &ExplainKind::Plan);
101+
assert_eq!(options, &vec![ExplainOption::Verbose]);
102+
}
103+
_ => panic!("expected EXPLAIN statement"),
104+
}
105+
106+
assert_eq!(stmt.to_string(), "EXPLAIN(VERBOSE) SELECT * FROM t");
107+
test_stmt_display("EXPLAIN VERBOSE SELECT * FROM t");
108+
}

tests/sqllogictests/suites/mode/standalone/explain/explain.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,34 @@ TableScan
3737
├── push downs: [filters: [t1.a (#0) > 0], limit: NONE]
3838
└── estimated rows: 0.00
3939

40+
query T
41+
explain(verbose) select * from numbers(0)
42+
----
43+
TableScan
44+
├── table: default.system.numbers
45+
├── scan id: 0
46+
├── output columns: [number (#0)]
47+
├── read rows: 0
48+
├── read size: 0
49+
├── partitions total: 1
50+
├── partitions scanned: 1
51+
├── push downs: [filters: [], limit: NONE]
52+
└── estimated rows: 0.00
53+
54+
query T
55+
explain verbose select * from numbers(0)
56+
----
57+
TableScan
58+
├── table: default.system.numbers
59+
├── scan id: 0
60+
├── output columns: [number (#0)]
61+
├── read rows: 0
62+
├── read size: 0
63+
├── partitions total: 1
64+
├── partitions scanned: 1
65+
├── push downs: [filters: [], limit: NONE]
66+
└── estimated rows: 0.00
67+
4068
query T
4169
explain select * from t1, t2 where (t1.a = t2.a and t1.a > 3) or (t1.a = t2.a and t2.a > 5 and t1.a > 1)
4270
----

0 commit comments

Comments
 (0)