This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 7905fb49 Add support of `EXPLAIN QUERY PLAN` syntax for SQLite dialect
(#1458)
7905fb49 is described below
commit 7905fb49054c28538a69dabd802c7bad6ef86fe8
Author: hulk <[email protected]>
AuthorDate: Wed Oct 9 00:27:07 2024 +0800
Add support of `EXPLAIN QUERY PLAN` syntax for SQLite dialect (#1458)
---
src/ast/mod.rs | 9 +++++++++
src/keywords.rs | 1 +
src/parser/mod.rs | 4 ++++
tests/sqlparser_common.rs | 32 ++++++++++++++++++++++++++++++++
4 files changed, 46 insertions(+)
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index 995370f5..bc559a66 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -3111,6 +3111,11 @@ pub enum Statement {
analyze: bool,
// Display additional information regarding the plan.
verbose: bool,
+ /// `EXPLAIN QUERY PLAN`
+ /// Display the query plan without running the query.
+ ///
+ /// [SQLite](https://sqlite.org/lang_explain.html)
+ query_plan: bool,
/// A SQL query that specifies what to explain
statement: Box<Statement>,
/// Optional output format of explain
@@ -3302,12 +3307,16 @@ impl fmt::Display for Statement {
describe_alias,
verbose,
analyze,
+ query_plan,
statement,
format,
options,
} => {
write!(f, "{describe_alias} ")?;
+ if *query_plan {
+ write!(f, "QUERY PLAN ")?;
+ }
if *analyze {
write!(f, "ANALYZE ")?;
}
diff --git a/src/keywords.rs b/src/keywords.rs
index 49c6ce20..ecf4bd47 100644
--- a/src/keywords.rs
+++ b/src/keywords.rs
@@ -572,6 +572,7 @@ define_keywords!(
PERSISTENT,
PIVOT,
PLACING,
+ PLAN,
PLANS,
POLICY,
PORTION,
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 34574a6b..cc60bbbd 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -8662,6 +8662,7 @@ impl<'a> Parser<'a> {
) -> Result<Statement, ParserError> {
let mut analyze = false;
let mut verbose = false;
+ let mut query_plan = false;
let mut format = None;
let mut options = None;
@@ -8672,6 +8673,8 @@ impl<'a> Parser<'a> {
&& self.peek_token().token == Token::LParen
{
options = Some(self.parse_utility_options()?)
+ } else if self.parse_keywords(&[Keyword::QUERY, Keyword::PLAN]) {
+ query_plan = true;
} else {
analyze = self.parse_keyword(Keyword::ANALYZE);
verbose = self.parse_keyword(Keyword::VERBOSE);
@@ -8688,6 +8691,7 @@ impl<'a> Parser<'a> {
describe_alias,
analyze,
verbose,
+ query_plan,
statement: Box::new(statement),
format,
options,
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 5d5a17ca..7068ffc3 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -4295,6 +4295,7 @@ fn run_explain_analyze(
describe_alias: _,
analyze,
verbose,
+ query_plan,
statement,
format,
options,
@@ -4303,6 +4304,7 @@ fn run_explain_analyze(
assert_eq!(analyze, expected_analyze);
assert_eq!(format, expected_format);
assert_eq!(options, exepcted_options);
+ assert!(!query_plan);
assert_eq!("SELECT sqrt(id) FROM foo", statement.to_string());
}
_ => panic!("Unexpected Statement, must be Explain"),
@@ -4417,6 +4419,36 @@ fn parse_explain_analyze_with_simple_select() {
);
}
+#[test]
+fn parse_explain_query_plan() {
+ match all_dialects().verified_stmt("EXPLAIN QUERY PLAN SELECT sqrt(id)
FROM foo") {
+ Statement::Explain {
+ query_plan,
+ analyze,
+ verbose,
+ statement,
+ ..
+ } => {
+ assert!(query_plan);
+ assert!(!analyze);
+ assert!(!verbose);
+ assert_eq!("SELECT sqrt(id) FROM foo", statement.to_string());
+ }
+ _ => unreachable!(),
+ }
+
+ // omit QUERY PLAN should be good
+ all_dialects().verified_stmt("EXPLAIN SELECT sqrt(id) FROM foo");
+
+ // missing PLAN keyword should return error
+ assert_eq!(
+ ParserError::ParserError("Expected: end of statement, found:
SELECT".to_string()),
+ all_dialects()
+ .parse_sql_statements("EXPLAIN QUERY SELECT sqrt(id) FROM foo")
+ .unwrap_err()
+ );
+}
+
#[test]
fn parse_named_argument_function() {
let sql = "SELECT FUN(a => '1', b => '2') FROM foo";
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]