Skip to content

Commit

Permalink
ALTER TABLE DROP {COLUMN|CONSTRAINT} RESTRICT (#1651)
Browse files Browse the repository at this point in the history
  • Loading branch information
stepancheg authored Jan 10, 2025
1 parent 5a761dd commit c54ba4d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 42 deletions.
20 changes: 14 additions & 6 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,13 @@ pub enum AlterTableOperation {
DropConstraint {
if_exists: bool,
name: Ident,
cascade: bool,
drop_behavior: Option<DropBehavior>,
},
/// `DROP [ COLUMN ] [ IF EXISTS ] <column_name> [ CASCADE ]`
DropColumn {
column_name: Ident,
if_exists: bool,
cascade: bool,
drop_behavior: Option<DropBehavior>,
},
/// `ATTACH PART|PARTITION <partition_expr>`
/// Note: this is a ClickHouse-specific operation, please refer to
Expand Down Expand Up @@ -451,27 +451,35 @@ impl fmt::Display for AlterTableOperation {
AlterTableOperation::DropConstraint {
if_exists,
name,
cascade,
drop_behavior,
} => {
write!(
f,
"DROP CONSTRAINT {}{}{}",
if *if_exists { "IF EXISTS " } else { "" },
name,
if *cascade { " CASCADE" } else { "" },
match drop_behavior {
None => "",
Some(DropBehavior::Restrict) => " RESTRICT",
Some(DropBehavior::Cascade) => " CASCADE",
}
)
}
AlterTableOperation::DropPrimaryKey => write!(f, "DROP PRIMARY KEY"),
AlterTableOperation::DropColumn {
column_name,
if_exists,
cascade,
drop_behavior,
} => write!(
f,
"DROP COLUMN {}{}{}",
if *if_exists { "IF EXISTS " } else { "" },
column_name,
if *cascade { " CASCADE" } else { "" }
match drop_behavior {
None => "",
Some(DropBehavior::Restrict) => " RESTRICT",
Some(DropBehavior::Cascade) => " CASCADE",
}
),
AlterTableOperation::AttachPartition { partition } => {
write!(f, "ATTACH {partition}")
Expand Down
4 changes: 2 additions & 2 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -961,12 +961,12 @@ impl Spanned for AlterTableOperation {
AlterTableOperation::DropConstraint {
if_exists: _,
name,
cascade: _,
drop_behavior: _,
} => name.span,
AlterTableOperation::DropColumn {
column_name,
if_exists: _,
cascade: _,
drop_behavior: _,
} => column_name.span,
AlterTableOperation::AttachPartition { partition } => partition.span(),
AlterTableOperation::DetachPartition { partition } => partition.span(),
Expand Down
8 changes: 4 additions & 4 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7680,11 +7680,11 @@ impl<'a> Parser<'a> {
} else if self.parse_keyword(Keyword::CONSTRAINT) {
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
let name = self.parse_identifier()?;
let cascade = self.parse_keyword(Keyword::CASCADE);
let drop_behavior = self.parse_optional_drop_behavior();
AlterTableOperation::DropConstraint {
if_exists,
name,
cascade,
drop_behavior,
}
} else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY])
&& dialect_of!(self is MySqlDialect | GenericDialect)
Expand All @@ -7702,11 +7702,11 @@ impl<'a> Parser<'a> {
let _ = self.parse_keyword(Keyword::COLUMN); // [ COLUMN ]
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
let column_name = self.parse_identifier()?;
let cascade = self.parse_keyword(Keyword::CASCADE);
let drop_behavior = self.parse_optional_drop_behavior();
AlterTableOperation::DropColumn {
column_name,
if_exists,
cascade,
drop_behavior,
}
}
} else if self.parse_keyword(Keyword::PARTITION) {
Expand Down
58 changes: 28 additions & 30 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4388,7 +4388,9 @@ fn parse_alter_table_constraints() {

#[test]
fn parse_alter_table_drop_column() {
check_one("DROP COLUMN IF EXISTS is_active");
check_one("DROP COLUMN IF EXISTS is_active CASCADE");
check_one("DROP COLUMN IF EXISTS is_active RESTRICT");
one_statement_parses_to(
"ALTER TABLE tab DROP IF EXISTS is_active CASCADE",
"ALTER TABLE tab DROP COLUMN IF EXISTS is_active CASCADE",
Expand All @@ -4403,11 +4405,15 @@ fn parse_alter_table_drop_column() {
AlterTableOperation::DropColumn {
column_name,
if_exists,
cascade,
drop_behavior,
} => {
assert_eq!("is_active", column_name.to_string());
assert!(if_exists);
assert!(cascade);
match drop_behavior {
None => assert!(constraint_text.ends_with(" is_active")),
Some(DropBehavior::Restrict) => assert!(constraint_text.ends_with(" RESTRICT")),
Some(DropBehavior::Cascade) => assert!(constraint_text.ends_with(" CASCADE")),
}
}
_ => unreachable!(),
}
Expand Down Expand Up @@ -4497,37 +4503,29 @@ fn parse_alter_table_alter_column_type() {

#[test]
fn parse_alter_table_drop_constraint() {
let alter_stmt = "ALTER TABLE tab";
match alter_table_op(verified_stmt(
"ALTER TABLE tab DROP CONSTRAINT constraint_name CASCADE",
)) {
AlterTableOperation::DropConstraint {
name: constr_name,
if_exists,
cascade,
} => {
assert_eq!("constraint_name", constr_name.to_string());
assert!(!if_exists);
assert!(cascade);
}
_ => unreachable!(),
}
match alter_table_op(verified_stmt(
"ALTER TABLE tab DROP CONSTRAINT IF EXISTS constraint_name",
)) {
AlterTableOperation::DropConstraint {
name: constr_name,
if_exists,
cascade,
} => {
assert_eq!("constraint_name", constr_name.to_string());
assert!(if_exists);
assert!(!cascade);
check_one("DROP CONSTRAINT IF EXISTS constraint_name");
check_one("DROP CONSTRAINT IF EXISTS constraint_name RESTRICT");
check_one("DROP CONSTRAINT IF EXISTS constraint_name CASCADE");
fn check_one(constraint_text: &str) {
match alter_table_op(verified_stmt(&format!("ALTER TABLE tab {constraint_text}"))) {
AlterTableOperation::DropConstraint {
name: constr_name,
if_exists,
drop_behavior,
} => {
assert_eq!("constraint_name", constr_name.to_string());
assert!(if_exists);
match drop_behavior {
None => assert!(constraint_text.ends_with(" constraint_name")),
Some(DropBehavior::Restrict) => assert!(constraint_text.ends_with(" RESTRICT")),
Some(DropBehavior::Cascade) => assert!(constraint_text.ends_with(" CASCADE")),
}
}
_ => unreachable!(),
}
_ => unreachable!(),
}

let res = parse_sql_statements(&format!("{alter_stmt} DROP CONSTRAINT is_active TEXT"));
let res = parse_sql_statements("ALTER TABLE tab DROP CONSTRAINT is_active TEXT");
assert_eq!(
ParserError::ParserError("Expected: end of statement, found: TEXT".to_string()),
res.unwrap_err()
Expand Down

0 comments on commit c54ba4d

Please sign in to comment.