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 3adc746b Parse MySQL ALTER TABLE ALGORITHM option (#1745)
3adc746b is described below
commit 3adc746b11411746f78f5c2506e1bf72e1caf583
Author: Michael Victor Zink <[email protected]>
AuthorDate: Tue Feb 25 22:03:38 2025 -0800
Parse MySQL ALTER TABLE ALGORITHM option (#1745)
---
src/ast/ddl.rs | 45 +++++++++++++++++++++++++++++++++++++++++----
src/ast/mod.rs | 18 +++++++++---------
src/ast/spans.rs | 1 +
src/keywords.rs | 2 ++
src/parser/mod.rs | 18 ++++++++++++++++++
tests/sqlparser_mysql.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 119 insertions(+), 13 deletions(-)
diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs
index 1fbc4560..372a75ad 100644
--- a/src/ast/ddl.rs
+++ b/src/ast/ddl.rs
@@ -65,7 +65,6 @@ pub enum AlterTableOperation {
name: Ident,
select: ProjectionSelect,
},
-
/// `DROP PROJECTION [IF EXISTS] name`
///
/// Note: this is a ClickHouse-specific operation.
@@ -74,7 +73,6 @@ pub enum AlterTableOperation {
if_exists: bool,
name: Ident,
},
-
/// `MATERIALIZE PROJECTION [IF EXISTS] name [IN PARTITION partition_name]`
///
/// Note: this is a ClickHouse-specific operation.
@@ -84,7 +82,6 @@ pub enum AlterTableOperation {
name: Ident,
partition: Option<Ident>,
},
-
/// `CLEAR PROJECTION [IF EXISTS] name [IN PARTITION partition_name]`
///
/// Note: this is a ClickHouse-specific operation.
@@ -94,7 +91,6 @@ pub enum AlterTableOperation {
name: Ident,
partition: Option<Ident>,
},
-
/// `DISABLE ROW LEVEL SECURITY`
///
/// Note: this is a PostgreSQL-specific operation.
@@ -272,6 +268,15 @@ pub enum AlterTableOperation {
DropClusteringKey,
SuspendRecluster,
ResumeRecluster,
+ /// `ALGORITHM [=] { DEFAULT | INSTANT | INPLACE | COPY }`
+ ///
+ /// [MySQL]-specific table alter algorithm.
+ ///
+ /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/alter-table.html
+ Algorithm {
+ equals: bool,
+ algorithm: AlterTableAlgorithm,
+ },
}
/// An `ALTER Policy` (`Statement::AlterPolicy`) operation
@@ -317,6 +322,30 @@ impl fmt::Display for AlterPolicyOperation {
}
}
+/// [MySQL] `ALTER TABLE` algorithm.
+///
+/// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/alter-table.html
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub enum AlterTableAlgorithm {
+ Default,
+ Instant,
+ Inplace,
+ Copy,
+}
+
+impl fmt::Display for AlterTableAlgorithm {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(match self {
+ Self::Default => "DEFAULT",
+ Self::Instant => "INSTANT",
+ Self::Inplace => "INPLACE",
+ Self::Copy => "COPY",
+ })
+ }
+}
+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
@@ -407,6 +436,14 @@ impl fmt::Display for AlterTableOperation {
}
write!(f, " {} ({})", name, query)
}
+ AlterTableOperation::Algorithm { equals, algorithm } => {
+ write!(
+ f,
+ "ALGORITHM {}{}",
+ if *equals { "= " } else { "" },
+ algorithm
+ )
+ }
AlterTableOperation::DropProjection { if_exists, name } => {
write!(f, "DROP PROJECTION")?;
if *if_exists {
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index 85d3ed91..72be3ff6 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -48,15 +48,15 @@ pub use self::dcl::{
};
pub use self::ddl::{
AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation,
AlterPolicyOperation,
- AlterTableOperation, AlterType, AlterTypeAddValue,
AlterTypeAddValuePosition,
- AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy,
ColumnDef,
- ColumnOption, ColumnOptionDef, ColumnPolicy, ColumnPolicyProperty,
ConstraintCharacteristics,
- CreateConnector, CreateFunction, Deduplicate, DeferrableInitial,
DropBehavior, GeneratedAs,
- GeneratedExpressionMode, IdentityParameters, IdentityProperty,
IdentityPropertyFormatKind,
- IdentityPropertyKind, IdentityPropertyOrder, IndexOption, IndexType,
KeyOrIndexDisplay,
- NullsDistinctOption, Owner, Partition, ProcedureParam, ReferentialAction,
TableConstraint,
- TagsColumnOption, UserDefinedTypeCompositeAttributeDef,
UserDefinedTypeRepresentation,
- ViewColumnDef,
+ AlterTableAlgorithm, AlterTableOperation, AlterType, AlterTypeAddValue,
+ AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
AlterTypeRenameValue,
+ ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnPolicy,
ColumnPolicyProperty,
+ ConstraintCharacteristics, CreateConnector, CreateFunction, Deduplicate,
DeferrableInitial,
+ DropBehavior, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
IdentityProperty,
+ IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
IndexOption,
+ IndexType, KeyOrIndexDisplay, NullsDistinctOption, Owner, Partition,
ProcedureParam,
+ ReferentialAction, TableConstraint, TagsColumnOption,
UserDefinedTypeCompositeAttributeDef,
+ UserDefinedTypeRepresentation, ViewColumnDef,
};
pub use self::dml::{CreateIndex, CreateTable, Delete, Insert};
pub use self::operator::{BinaryOperator, UnaryOperator};
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index cfc3eb63..7cb5ddfe 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -1062,6 +1062,7 @@ impl Spanned for AlterTableOperation {
AlterTableOperation::DropClusteringKey => Span::empty(),
AlterTableOperation::SuspendRecluster => Span::empty(),
AlterTableOperation::ResumeRecluster => Span::empty(),
+ AlterTableOperation::Algorithm { .. } => Span::empty(),
}
}
}
diff --git a/src/keywords.rs b/src/keywords.rs
index 020b404e..a6854f07 100644
--- a/src/keywords.rs
+++ b/src/keywords.rs
@@ -427,11 +427,13 @@ define_keywords!(
INNER,
INOUT,
INPATH,
+ INPLACE,
INPUT,
INPUTFORMAT,
INSENSITIVE,
INSERT,
INSTALL,
+ INSTANT,
INSTEAD,
INT,
INT128,
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index ddcb6055..86a86824 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -8163,6 +8163,24 @@ impl<'a> Parser<'a> {
AlterTableOperation::SuspendRecluster
} else if self.parse_keywords(&[Keyword::RESUME, Keyword::RECLUSTER]) {
AlterTableOperation::ResumeRecluster
+ } else if self.parse_keyword(Keyword::ALGORITHM) {
+ let equals = self.consume_token(&Token::Eq);
+ let algorithm = match self.parse_one_of_keywords(&[
+ Keyword::DEFAULT,
+ Keyword::INSTANT,
+ Keyword::INPLACE,
+ Keyword::COPY,
+ ]) {
+ Some(Keyword::DEFAULT) => AlterTableAlgorithm::Default,
+ Some(Keyword::INSTANT) => AlterTableAlgorithm::Instant,
+ Some(Keyword::INPLACE) => AlterTableAlgorithm::Inplace,
+ Some(Keyword::COPY) => AlterTableAlgorithm::Copy,
+ _ => self.expected(
+ "DEFAULT, INSTANT, INPLACE, or COPY after ALGORITHM [=]",
+ self.peek_token(),
+ )?,
+ };
+ AlterTableOperation::Algorithm { equals, algorithm }
} else {
let options: Vec<SqlOption> =
self.parse_options_with_keywords(&[Keyword::SET,
Keyword::TBLPROPERTIES])?;
diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs
index 4856bd89..5e98d3f4 100644
--- a/tests/sqlparser_mysql.rs
+++ b/tests/sqlparser_mysql.rs
@@ -2422,6 +2422,54 @@ fn parse_alter_table_modify_column() {
assert_eq!(expected_operation, operation);
}
+#[test]
+fn parse_alter_table_with_algorithm() {
+ let sql = "ALTER TABLE tab ALGORITHM = COPY";
+ let expected_operation = AlterTableOperation::Algorithm {
+ equals: true,
+ algorithm: AlterTableAlgorithm::Copy,
+ };
+ let operation = alter_table_op(mysql_and_generic().verified_stmt(sql));
+ assert_eq!(expected_operation, operation);
+
+ // Check order doesn't matter
+ let sql =
+ "ALTER TABLE users DROP COLUMN password_digest, ALGORITHM = COPY,
RENAME COLUMN name TO username";
+ let stmt = mysql_and_generic().verified_stmt(sql);
+ match stmt {
+ Statement::AlterTable { operations, .. } => {
+ assert_eq!(
+ operations,
+ vec![
+ AlterTableOperation::DropColumn {
+ column_name: Ident::new("password_digest"),
+ if_exists: false,
+ drop_behavior: None,
+ },
+ AlterTableOperation::Algorithm {
+ equals: true,
+ algorithm: AlterTableAlgorithm::Copy,
+ },
+ AlterTableOperation::RenameColumn {
+ old_column_name: Ident::new("name"),
+ new_column_name: Ident::new("username")
+ },
+ ]
+ )
+ }
+ _ => panic!("Unexpected statement {stmt}"),
+ }
+
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM DEFAULT");
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM INSTANT");
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM INPLACE");
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM COPY");
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM =
DEFAULT");
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM =
INSTANT");
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM =
INPLACE");
+ mysql_and_generic().verified_stmt("ALTER TABLE `users` ALGORITHM = COPY");
+}
+
#[test]
fn parse_alter_table_modify_column_with_column_position() {
let expected_name = ObjectName::from(vec![Ident::new("orders")]);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]