From 2b4c7164e7fc91b30fde5b132c6b5b2d5f96de84 Mon Sep 17 00:00:00 2001 From: tvallotton Date: Tue, 28 Dec 2021 10:42:24 -0300 Subject: [PATCH 1/2] adding support for DROP CONSTRAINT [ IF EXISTS ] --- src/ast/ddl.rs | 13 +++++++++--- src/parser.rs | 4 ++++ tests/sqlparser_common.rs | 44 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 78ec2e0c7..5330bc0cd 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -31,8 +31,8 @@ pub enum AlterTableOperation { AddConstraint(TableConstraint), /// `ADD [ COLUMN ] ` AddColumn { column_def: ColumnDef }, - /// TODO: implement `DROP CONSTRAINT ` - DropConstraint { name: Ident }, + /// `DROP CONSTRAINT [ IF EXISTS ] ` + DropConstraint { if_exists: bool, name: Ident }, /// `DROP [ COLUMN ] [ IF EXISTS ] [ CASCADE ]` DropColumn { column_name: Ident, @@ -106,7 +106,14 @@ impl fmt::Display for AlterTableOperation { display_comma_separated(partitions), ie = if *if_exists { " IF EXISTS" } else { "" } ), - AlterTableOperation::DropConstraint { name } => write!(f, "DROP CONSTRAINT {}", name), + AlterTableOperation::DropConstraint { if_exists, name } => { + write!( + f, + "DROP CONSTRAINT {}{}", + if *if_exists { "IF EXISTS " } else { "" }, + name + ) + } AlterTableOperation::DropColumn { column_name, if_exists, diff --git a/src/parser.rs b/src/parser.rs index 6d917f027..615d4bb35 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1982,6 +1982,10 @@ impl<'a> Parser<'a> { partitions, if_exists: false, } + } else if self.parse_keyword(Keyword::CONSTRAINT) { + let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]); + let name = self.parse_identifier()?; + AlterTableOperation::DropConstraint { if_exists, name } } else { let _ = self.parse_keyword(Keyword::COLUMN); let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]); diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 07a0db524..81b79b089 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -2052,6 +2052,50 @@ fn parse_alter_table_alter_column_type() { ); } +#[test] +fn parse_alter_table_drop_constraint() { + let alter_stmt = "ALTER TABLE tab"; + match verified_stmt("ALTER TABLE tab DROP CONSTRAINT constraint_name") { + Statement::AlterTable { + name, + operation: + AlterTableOperation::DropConstraint { + name: constr_name, + if_exists, + }, + } => { + assert_eq!("tab", name.to_string()); + assert_eq!("constraint_name", constr_name.to_string()); + assert!(!if_exists); + } + _ => unreachable!(), + } + match verified_stmt("ALTER TABLE tab DROP CONSTRAINT IF EXISTS constraint_name") { + Statement::AlterTable { + name, + operation: + AlterTableOperation::DropConstraint { + name: constr_name, + if_exists, + }, + } => { + assert_eq!("tab", name.to_string()); + assert_eq!("constraint_name", constr_name.to_string()); + assert!(if_exists); + } + _ => unreachable!(), + } + + let res = Parser::parse_sql( + &GenericDialect {}, + &format!("{} DROP CONSTRAINT is_active TEXT", alter_stmt), + ); + assert_eq!( + ParserError::ParserError("Expected end of statement, found: TEXT".to_string()), + res.unwrap_err() + ); +} + #[test] fn parse_bad_constraint() { let res = parse_sql_statements("ALTER TABLE tab ADD"); From 1180063ed213935b0829d6e5c8a014bd963524fd Mon Sep 17 00:00:00 2001 From: tvallotton Date: Tue, 28 Dec 2021 14:08:14 -0300 Subject: [PATCH 2/2] implementing [ CASCADE ] for DROP CONSTRAINT --- src/ast/ddl.rs | 17 +++++++++++++---- src/parser.rs | 7 ++++++- tests/sqlparser_common.rs | 6 +++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 5330bc0cd..7ff17c616 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -32,7 +32,11 @@ pub enum AlterTableOperation { /// `ADD [ COLUMN ] ` AddColumn { column_def: ColumnDef }, /// `DROP CONSTRAINT [ IF EXISTS ] ` - DropConstraint { if_exists: bool, name: Ident }, + DropConstraint { + if_exists: bool, + name: Ident, + cascade: bool, + }, /// `DROP [ COLUMN ] [ IF EXISTS ] [ CASCADE ]` DropColumn { column_name: Ident, @@ -106,12 +110,17 @@ impl fmt::Display for AlterTableOperation { display_comma_separated(partitions), ie = if *if_exists { " IF EXISTS" } else { "" } ), - AlterTableOperation::DropConstraint { if_exists, name } => { + AlterTableOperation::DropConstraint { + if_exists, + name, + cascade, + } => { write!( f, - "DROP CONSTRAINT {}{}", + "DROP CONSTRAINT {}{}{}", if *if_exists { "IF EXISTS " } else { "" }, - name + name, + if *cascade { " CASCADE" } else { "" }, ) } AlterTableOperation::DropColumn { diff --git a/src/parser.rs b/src/parser.rs index 615d4bb35..3fd2cf537 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1985,7 +1985,12 @@ 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()?; - AlterTableOperation::DropConstraint { if_exists, name } + let cascade = self.parse_keyword(Keyword::CASCADE); + AlterTableOperation::DropConstraint { + if_exists, + name, + cascade, + } } else { let _ = self.parse_keyword(Keyword::COLUMN); let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]); diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 81b79b089..82c59bd1c 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -2055,18 +2055,20 @@ fn parse_alter_table_alter_column_type() { #[test] fn parse_alter_table_drop_constraint() { let alter_stmt = "ALTER TABLE tab"; - match verified_stmt("ALTER TABLE tab DROP CONSTRAINT constraint_name") { + match verified_stmt("ALTER TABLE tab DROP CONSTRAINT constraint_name CASCADE") { Statement::AlterTable { name, operation: AlterTableOperation::DropConstraint { name: constr_name, if_exists, + cascade, }, } => { assert_eq!("tab", name.to_string()); assert_eq!("constraint_name", constr_name.to_string()); assert!(!if_exists); + assert!(cascade); } _ => unreachable!(), } @@ -2077,11 +2079,13 @@ fn parse_alter_table_drop_constraint() { AlterTableOperation::DropConstraint { name: constr_name, if_exists, + cascade, }, } => { assert_eq!("tab", name.to_string()); assert_eq!("constraint_name", constr_name.to_string()); assert!(if_exists); + assert!(!cascade); } _ => unreachable!(), }