mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-20 12:49:47 +00:00
Support Modify Column
for MySQL dialect (#1216)
This commit is contained in:
parent
4604628c43
commit
7b49c69b3a
4 changed files with 135 additions and 0 deletions
|
@ -134,6 +134,14 @@ pub enum AlterTableOperation {
|
|||
/// MySQL `ALTER TABLE` only [FIRST | AFTER column_name]
|
||||
column_position: Option<MySQLColumnPosition>,
|
||||
},
|
||||
// CHANGE [ COLUMN ] <col_name> <data_type> [ <options> ]
|
||||
ModifyColumn {
|
||||
col_name: Ident,
|
||||
data_type: DataType,
|
||||
options: Vec<ColumnOption>,
|
||||
/// MySQL `ALTER TABLE` only [FIRST | AFTER column_name]
|
||||
column_position: Option<MySQLColumnPosition>,
|
||||
},
|
||||
/// `RENAME CONSTRAINT <old_constraint_name> TO <new_constraint_name>`
|
||||
///
|
||||
/// Note: this is a PostgreSQL-specific operation.
|
||||
|
@ -292,6 +300,22 @@ impl fmt::Display for AlterTableOperation {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
AlterTableOperation::ModifyColumn {
|
||||
col_name,
|
||||
data_type,
|
||||
options,
|
||||
column_position,
|
||||
} => {
|
||||
write!(f, "MODIFY COLUMN {col_name} {data_type}")?;
|
||||
if !options.is_empty() {
|
||||
write!(f, " {}", display_separated(options, " "))?;
|
||||
}
|
||||
if let Some(position) = column_position {
|
||||
write!(f, " {position}")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
AlterTableOperation::RenameConstraint { old_name, new_name } => {
|
||||
write!(f, "RENAME CONSTRAINT {old_name} TO {new_name}")
|
||||
}
|
||||
|
|
|
@ -438,6 +438,7 @@ define_keywords!(
|
|||
MOD,
|
||||
MODE,
|
||||
MODIFIES,
|
||||
MODIFY,
|
||||
MODULE,
|
||||
MONTH,
|
||||
MSCK,
|
||||
|
|
|
@ -5757,6 +5757,23 @@ impl<'a> Parser<'a> {
|
|||
options,
|
||||
column_position,
|
||||
}
|
||||
} else if self.parse_keyword(Keyword::MODIFY) {
|
||||
let _ = self.parse_keyword(Keyword::COLUMN); // [ COLUMN ]
|
||||
let col_name = self.parse_identifier(false)?;
|
||||
let data_type = self.parse_data_type()?;
|
||||
let mut options = vec![];
|
||||
while let Some(option) = self.parse_optional_column_option()? {
|
||||
options.push(option);
|
||||
}
|
||||
|
||||
let column_position = self.parse_column_position()?;
|
||||
|
||||
AlterTableOperation::ModifyColumn {
|
||||
col_name,
|
||||
data_type,
|
||||
options,
|
||||
column_position,
|
||||
}
|
||||
} else if self.parse_keyword(Keyword::ALTER) {
|
||||
let _ = self.parse_keyword(Keyword::COLUMN); // [ COLUMN ]
|
||||
let column_name = self.parse_identifier(false)?;
|
||||
|
|
|
@ -2218,6 +2218,99 @@ fn parse_alter_table_change_column_with_column_position() {
|
|||
assert_eq!(expected_operation_after, operation);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_alter_table_modify_column() {
|
||||
let expected_name = ObjectName(vec![Ident::new("orders")]);
|
||||
let expected_operation = AlterTableOperation::ModifyColumn {
|
||||
col_name: Ident::new("description"),
|
||||
data_type: DataType::Text,
|
||||
options: vec![ColumnOption::NotNull],
|
||||
column_position: None,
|
||||
};
|
||||
|
||||
let sql1 = "ALTER TABLE orders MODIFY COLUMN description TEXT NOT NULL";
|
||||
let operation =
|
||||
alter_table_op_with_name(mysql().verified_stmt(sql1), &expected_name.to_string());
|
||||
assert_eq!(expected_operation, operation);
|
||||
|
||||
let sql2 = "ALTER TABLE orders MODIFY description TEXT NOT NULL";
|
||||
let operation = alter_table_op_with_name(
|
||||
mysql().one_statement_parses_to(sql2, sql1),
|
||||
&expected_name.to_string(),
|
||||
);
|
||||
assert_eq!(expected_operation, operation);
|
||||
|
||||
let expected_operation = AlterTableOperation::ModifyColumn {
|
||||
col_name: Ident::new("description"),
|
||||
data_type: DataType::Text,
|
||||
options: vec![ColumnOption::NotNull],
|
||||
column_position: Some(MySQLColumnPosition::First),
|
||||
};
|
||||
let sql3 = "ALTER TABLE orders MODIFY COLUMN description TEXT NOT NULL FIRST";
|
||||
let operation =
|
||||
alter_table_op_with_name(mysql().verified_stmt(sql3), &expected_name.to_string());
|
||||
assert_eq!(expected_operation, operation);
|
||||
|
||||
let expected_operation = AlterTableOperation::ModifyColumn {
|
||||
col_name: Ident::new("description"),
|
||||
data_type: DataType::Text,
|
||||
options: vec![ColumnOption::NotNull],
|
||||
column_position: Some(MySQLColumnPosition::After(Ident {
|
||||
value: String::from("foo"),
|
||||
quote_style: None,
|
||||
})),
|
||||
};
|
||||
let sql4 = "ALTER TABLE orders MODIFY COLUMN description TEXT NOT NULL AFTER foo";
|
||||
let operation =
|
||||
alter_table_op_with_name(mysql().verified_stmt(sql4), &expected_name.to_string());
|
||||
assert_eq!(expected_operation, operation);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_alter_table_modify_column_with_column_position() {
|
||||
let expected_name = ObjectName(vec![Ident::new("orders")]);
|
||||
let expected_operation_first = AlterTableOperation::ModifyColumn {
|
||||
col_name: Ident::new("description"),
|
||||
data_type: DataType::Text,
|
||||
options: vec![ColumnOption::NotNull],
|
||||
column_position: Some(MySQLColumnPosition::First),
|
||||
};
|
||||
|
||||
let sql1 = "ALTER TABLE orders MODIFY COLUMN description TEXT NOT NULL FIRST";
|
||||
let operation =
|
||||
alter_table_op_with_name(mysql().verified_stmt(sql1), &expected_name.to_string());
|
||||
assert_eq!(expected_operation_first, operation);
|
||||
|
||||
let sql2 = "ALTER TABLE orders MODIFY description TEXT NOT NULL FIRST";
|
||||
let operation = alter_table_op_with_name(
|
||||
mysql().one_statement_parses_to(sql2, sql1),
|
||||
&expected_name.to_string(),
|
||||
);
|
||||
assert_eq!(expected_operation_first, operation);
|
||||
|
||||
let expected_operation_after = AlterTableOperation::ModifyColumn {
|
||||
col_name: Ident::new("description"),
|
||||
data_type: DataType::Text,
|
||||
options: vec![ColumnOption::NotNull],
|
||||
column_position: Some(MySQLColumnPosition::After(Ident {
|
||||
value: String::from("total_count"),
|
||||
quote_style: None,
|
||||
})),
|
||||
};
|
||||
|
||||
let sql1 = "ALTER TABLE orders MODIFY COLUMN description TEXT NOT NULL AFTER total_count";
|
||||
let operation =
|
||||
alter_table_op_with_name(mysql().verified_stmt(sql1), &expected_name.to_string());
|
||||
assert_eq!(expected_operation_after, operation);
|
||||
|
||||
let sql2 = "ALTER TABLE orders MODIFY description TEXT NOT NULL AFTER total_count";
|
||||
let operation = alter_table_op_with_name(
|
||||
mysql().one_statement_parses_to(sql2, sql1),
|
||||
&expected_name.to_string(),
|
||||
);
|
||||
assert_eq!(expected_operation_after, operation);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_substring_in_select() {
|
||||
let sql = "SELECT DISTINCT SUBSTRING(description, 0, 1) FROM test";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue