mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Parse MySQL ALTER TABLE ALGORITHM option (#1745)
This commit is contained in:
parent
de4dbc5b1d
commit
3adc746b11
6 changed files with 119 additions and 13 deletions
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -1062,6 +1062,7 @@ impl Spanned for AlterTableOperation {
|
|||
AlterTableOperation::DropClusteringKey => Span::empty(),
|
||||
AlterTableOperation::SuspendRecluster => Span::empty(),
|
||||
AlterTableOperation::ResumeRecluster => Span::empty(),
|
||||
AlterTableOperation::Algorithm { .. } => Span::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -427,11 +427,13 @@ define_keywords!(
|
|||
INNER,
|
||||
INOUT,
|
||||
INPATH,
|
||||
INPLACE,
|
||||
INPUT,
|
||||
INPUTFORMAT,
|
||||
INSENSITIVE,
|
||||
INSERT,
|
||||
INSTALL,
|
||||
INSTANT,
|
||||
INSTEAD,
|
||||
INT,
|
||||
INT128,
|
||||
|
|
|
@ -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])?;
|
||||
|
|
|
@ -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")]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue