This is an automated email from the ASF dual-hosted git repository.

iffyio 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 94ea2062 Add support for MYSQL's `RENAME TABLE` (#1616)
94ea2062 is described below

commit 94ea20628fbc9950e87d165e3b4f904419ec03f0
Author: wugeer <[email protected]>
AuthorDate: Thu Jan 2 04:54:58 2025 +0800

    Add support for MYSQL's `RENAME TABLE` (#1616)
    
    Co-authored-by: Ifeanyi Ubah <[email protected]>
---
 src/ast/mod.rs            | 26 +++++++++++++++++++++
 src/ast/spans.rs          |  1 +
 src/parser/mod.rs         | 18 +++++++++++++++
 tests/sqlparser_common.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 104 insertions(+)

diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index d99f6888..75677435 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -3413,6 +3413,13 @@ pub enum Statement {
         partitioned: Option<Vec<Expr>>,
         table_format: Option<HiveLoadDataFormat>,
     },
+    /// ```sql
+    /// Rename TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2] ...
+    /// ```
+    /// Renames one or more tables
+    ///
+    /// See Mysql <https://dev.mysql.com/doc/refman/9.1/en/rename-table.html>
+    RenameTable(Vec<RenameTable>),
 }
 
 impl fmt::Display for Statement {
@@ -4970,6 +4977,9 @@ impl fmt::Display for Statement {
                 }
                 Ok(())
             }
+            Statement::RenameTable(rename_tables) => {
+                write!(f, "RENAME TABLE {}", 
display_comma_separated(rename_tables))
+            }
         }
     }
 }
@@ -7672,6 +7682,22 @@ impl Display for JsonNullClause {
     }
 }
 
+/// rename object definition
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct RenameTable {
+    pub old_name: ObjectName,
+    pub new_name: ObjectName,
+}
+
+impl fmt::Display for RenameTable {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{} TO {}", self.old_name, self.new_name)?;
+        Ok(())
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index 574830ef..dad0c537 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -492,6 +492,7 @@ impl Spanned for Statement {
             Statement::NOTIFY { .. } => Span::empty(),
             Statement::LoadData { .. } => Span::empty(),
             Statement::UNLISTEN { .. } => Span::empty(),
+            Statement::RenameTable { .. } => Span::empty(),
         }
     }
 }
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 012314b4..47d4d6f0 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -595,6 +595,7 @@ impl<'a> Parser<'a> {
                 // `PRAGMA` is sqlite specific 
https://www.sqlite.org/pragma.html
                 Keyword::PRAGMA => self.parse_pragma(),
                 Keyword::UNLOAD => self.parse_unload(),
+                Keyword::RENAME => self.parse_rename(),
                 // `INSTALL` is duckdb specific 
https://duckdb.org/docs/extensions/overview
                 Keyword::INSTALL if dialect_of!(self is DuckDbDialect | 
GenericDialect) => {
                     self.parse_install()
@@ -1085,6 +1086,23 @@ impl<'a> Parser<'a> {
         Ok(Statement::NOTIFY { channel, payload })
     }
 
+    /// Parses a `RENAME TABLE` statement. See [Statement::RenameTable]
+    pub fn parse_rename(&mut self) -> Result<Statement, ParserError> {
+        if self.peek_keyword(Keyword::TABLE) {
+            self.expect_keyword(Keyword::TABLE)?;
+            let rename_tables = self.parse_comma_separated(|parser| {
+                let old_name = parser.parse_object_name(false)?;
+                parser.expect_keyword(Keyword::TO)?;
+                let new_name = parser.parse_object_name(false)?;
+
+                Ok(RenameTable { old_name, new_name })
+            })?;
+            Ok(Statement::RenameTable(rename_tables))
+        } else {
+            self.expected("KEYWORD `TABLE` after RENAME", self.peek_token())
+        }
+    }
+
     // Tries to parse an expression by matching the specified word to known 
keywords that have a special meaning in the dialect.
     // Returns `None if no match is found.
     fn parse_expr_prefix_by_reserved_word(
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 3b21160b..3c2e0899 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -4133,6 +4133,65 @@ fn parse_alter_table() {
     }
 }
 
+#[test]
+fn parse_rename_table() {
+    match verified_stmt("RENAME TABLE test.test1 TO test_db.test2") {
+        Statement::RenameTable(rename_tables) => {
+            assert_eq!(
+                vec![RenameTable {
+                    old_name: ObjectName(vec![
+                        Ident::new("test".to_string()),
+                        Ident::new("test1".to_string()),
+                    ]),
+                    new_name: ObjectName(vec![
+                        Ident::new("test_db".to_string()),
+                        Ident::new("test2".to_string()),
+                    ]),
+                }],
+                rename_tables
+            );
+        }
+        _ => unreachable!(),
+    };
+
+    match verified_stmt(
+        "RENAME TABLE old_table1 TO new_table1, old_table2 TO new_table2, 
old_table3 TO new_table3",
+    ) {
+        Statement::RenameTable(rename_tables) => {
+            assert_eq!(
+                vec![
+                    RenameTable {
+                        old_name: 
ObjectName(vec![Ident::new("old_table1".to_string())]),
+                        new_name: 
ObjectName(vec![Ident::new("new_table1".to_string())]),
+                    },
+                    RenameTable {
+                        old_name: 
ObjectName(vec![Ident::new("old_table2".to_string())]),
+                        new_name: 
ObjectName(vec![Ident::new("new_table2".to_string())]),
+                    },
+                    RenameTable {
+                        old_name: 
ObjectName(vec![Ident::new("old_table3".to_string())]),
+                        new_name: 
ObjectName(vec![Ident::new("new_table3".to_string())]),
+                    }
+                ],
+                rename_tables
+            );
+        }
+        _ => unreachable!(),
+    };
+
+    assert_eq!(
+        parse_sql_statements("RENAME TABLE old_table TO new_table 
a").unwrap_err(),
+        ParserError::ParserError("Expected: end of statement, found: 
a".to_string())
+    );
+
+    assert_eq!(
+        parse_sql_statements("RENAME TABLE1 old_table TO new_table 
a").unwrap_err(),
+        ParserError::ParserError(
+            "Expected: KEYWORD `TABLE` after RENAME, found: TABLE1".to_string()
+        )
+    );
+}
+
 #[test]
 fn test_alter_table_with_on_cluster() {
     match all_dialects()


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to