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]