Skip to content

Commit 26361fd

Browse files
ivancerasnickolay
andauthored
Implement ALTER TABLE DROP COLUMN (#148)
This implements `DROP [ COLUMN ] [ IF EXISTS ] column_name [ CASCADE ]` sub-command of `ALTER TABLE`, which is what PostgreSQL supports https://www.postgresql.org/docs/12/sql-altertable.html (except for the RESTRICT option) Co-authored-by: Nickolay Ponomarev <[email protected]>
1 parent faeb7d4 commit 26361fd

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Check https://github.com/andygrove/sqlparser-rs/commits/master for undocumented
3131
- Support bitwise AND (`&`), OR (`|`), XOR (`^`) (#181) - thanks @Dandandan!
3232
- Add serde support to AST structs and enums (#196) - thanks @panarch!
3333
- Support `ALTER TABLE ADD COLUMN`, `RENAME COLUMN`, and `RENAME TO` (#203) - thanks @mashuai!
34+
- Support `ALTER TABLE DROP COLUMN` (#148) - thanks @ivanceras!
3435

3536
### Fixed
3637
- Report an error for unterminated string literals (#165)

src/ast/ddl.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ pub enum AlterTableOperation {
2727
AddColumn { column_def: ColumnDef },
2828
/// TODO: implement `DROP CONSTRAINT <name>`
2929
DropConstraint { name: Ident },
30+
/// `DROP [ COLUMN ] [ IF EXISTS ] <column_name> [ CASCADE ]`
31+
DropColumn {
32+
column_name: Ident,
33+
if_exists: bool,
34+
cascade: bool,
35+
},
3036
/// `RENAME [ COLUMN ] <old_column_name> TO <new_column_name>`
3137
RenameColumn {
3238
old_column_name: Ident,
@@ -44,6 +50,17 @@ impl fmt::Display for AlterTableOperation {
4450
write!(f, "ADD COLUMN {}", column_def.to_string())
4551
}
4652
AlterTableOperation::DropConstraint { name } => write!(f, "DROP CONSTRAINT {}", name),
53+
AlterTableOperation::DropColumn {
54+
column_name,
55+
if_exists,
56+
cascade,
57+
} => write!(
58+
f,
59+
"DROP COLUMN {}{}{}",
60+
if *if_exists { "IF EXISTS " } else { "" },
61+
column_name,
62+
if *cascade { " CASCADE" } else { "" }
63+
),
4764
AlterTableOperation::RenameColumn {
4865
old_column_name,
4966
new_column_name,

src/parser.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1340,8 +1340,18 @@ impl Parser {
13401340
new_column_name,
13411341
}
13421342
}
1343+
} else if self.parse_keyword(Keyword::DROP) {
1344+
let _ = self.parse_keyword(Keyword::COLUMN);
1345+
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
1346+
let column_name = self.parse_identifier()?;
1347+
let cascade = self.parse_keyword(Keyword::CASCADE);
1348+
AlterTableOperation::DropColumn {
1349+
column_name,
1350+
if_exists,
1351+
cascade,
1352+
}
13431353
} else {
1344-
return self.expected("ADD or RENAME after ALTER TABLE", self.peek_token());
1354+
return self.expected("ADD, RENAME, or DROP after ALTER TABLE", self.peek_token());
13451355
};
13461356
Ok(Statement::AlterTable {
13471357
name: table_name,

tests/sqlparser_common.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,6 +1388,39 @@ fn parse_alter_table_constraints() {
13881388
}
13891389
}
13901390

1391+
#[test]
1392+
fn parse_alter_table_drop_column() {
1393+
check_one("DROP COLUMN IF EXISTS is_active CASCADE");
1394+
one_statement_parses_to(
1395+
"ALTER TABLE tab DROP IF EXISTS is_active CASCADE",
1396+
"ALTER TABLE tab DROP COLUMN IF EXISTS is_active CASCADE",
1397+
);
1398+
one_statement_parses_to(
1399+
"ALTER TABLE tab DROP is_active CASCADE",
1400+
"ALTER TABLE tab DROP COLUMN is_active CASCADE",
1401+
);
1402+
1403+
fn check_one(constraint_text: &str) {
1404+
match verified_stmt(&format!("ALTER TABLE tab {}", constraint_text)) {
1405+
Statement::AlterTable {
1406+
name,
1407+
operation:
1408+
AlterTableOperation::DropColumn {
1409+
column_name,
1410+
if_exists,
1411+
cascade,
1412+
},
1413+
} => {
1414+
assert_eq!("tab", name.to_string());
1415+
assert_eq!("is_active", column_name.to_string());
1416+
assert_eq!(true, if_exists);
1417+
assert_eq!(true, cascade);
1418+
}
1419+
_ => unreachable!(),
1420+
}
1421+
}
1422+
}
1423+
13911424
#[test]
13921425
fn parse_bad_constraint() {
13931426
let res = parse_sql_statements("ALTER TABLE tab ADD");

0 commit comments

Comments
 (0)