mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-25 16:34:04 +00:00
Add support for MYSQL's RENAME TABLE
(#1616)
Co-authored-by: Ifeanyi Ubah <ify1992@yahoo.com>
This commit is contained in:
parent
3bad04e9e8
commit
94ea20628f
4 changed files with 104 additions and 0 deletions
|
@ -3413,6 +3413,13 @@ pub enum Statement {
|
||||||
partitioned: Option<Vec<Expr>>,
|
partitioned: Option<Vec<Expr>>,
|
||||||
table_format: Option<HiveLoadDataFormat>,
|
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 {
|
impl fmt::Display for Statement {
|
||||||
|
@ -4970,6 +4977,9 @@ impl fmt::Display for Statement {
|
||||||
}
|
}
|
||||||
Ok(())
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -492,6 +492,7 @@ impl Spanned for Statement {
|
||||||
Statement::NOTIFY { .. } => Span::empty(),
|
Statement::NOTIFY { .. } => Span::empty(),
|
||||||
Statement::LoadData { .. } => Span::empty(),
|
Statement::LoadData { .. } => Span::empty(),
|
||||||
Statement::UNLISTEN { .. } => Span::empty(),
|
Statement::UNLISTEN { .. } => Span::empty(),
|
||||||
|
Statement::RenameTable { .. } => Span::empty(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,6 +595,7 @@ impl<'a> Parser<'a> {
|
||||||
// `PRAGMA` is sqlite specific https://www.sqlite.org/pragma.html
|
// `PRAGMA` is sqlite specific https://www.sqlite.org/pragma.html
|
||||||
Keyword::PRAGMA => self.parse_pragma(),
|
Keyword::PRAGMA => self.parse_pragma(),
|
||||||
Keyword::UNLOAD => self.parse_unload(),
|
Keyword::UNLOAD => self.parse_unload(),
|
||||||
|
Keyword::RENAME => self.parse_rename(),
|
||||||
// `INSTALL` is duckdb specific https://duckdb.org/docs/extensions/overview
|
// `INSTALL` is duckdb specific https://duckdb.org/docs/extensions/overview
|
||||||
Keyword::INSTALL if dialect_of!(self is DuckDbDialect | GenericDialect) => {
|
Keyword::INSTALL if dialect_of!(self is DuckDbDialect | GenericDialect) => {
|
||||||
self.parse_install()
|
self.parse_install()
|
||||||
|
@ -1085,6 +1086,23 @@ impl<'a> Parser<'a> {
|
||||||
Ok(Statement::NOTIFY { channel, payload })
|
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.
|
// 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.
|
// Returns `None if no match is found.
|
||||||
fn parse_expr_prefix_by_reserved_word(
|
fn parse_expr_prefix_by_reserved_word(
|
||||||
|
|
|
@ -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]
|
#[test]
|
||||||
fn test_alter_table_with_on_cluster() {
|
fn test_alter_table_with_on_cluster() {
|
||||||
match all_dialects()
|
match all_dialects()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue