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]

Reply via email to