From c40a4a1139ab5d3353b69bf9eb472bbbf52439a9 Mon Sep 17 00:00:00 2001 From: Aleksandar Maksimovic Date: Wed, 26 Aug 2026 16:32:50 -0700 Subject: [PATCH] feat(dsql): parse ALTER COLUMN drop forms --- Cargo.toml | 4 ++-- src/ast/ddl.rs | 24 ++++++++++++++++++++++++ src/ast/spans.rs | 4 ++++ src/keywords.rs | 1 + src/parser/mod.rs | 12 ++++++++++-- tests/sqlparser_postgres.rs | 18 ++++++++++++++++++ 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7d384228e..82f7f51af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,8 @@ [package] name = "sqlparser-dsql" -description = "SQL parser fork with Aurora DSQL extensions (CREATE INDEX ASYNC, ALTER TABLE ASYNC, ALTER COLUMN SET STORAGE, order-independent CREATE SEQUENCE, INCLUDE on table constraints). Based on sqlparser 0.62.0." -version = "0.62.4" +description = "SQL parser fork with Aurora DSQL extensions (CREATE INDEX ASYNC, ALTER TABLE ASYNC, ALTER COLUMN DROP IDENTITY/EXPRESSION, ALTER COLUMN SET STORAGE, order-independent CREATE SEQUENCE, INCLUDE on table constraints). Based on sqlparser 0.62.0." +version = "0.62.5" authors = [ "Apache DataFusion ", "Amazon Web Services", diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 6923bea4a..81fe67578 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -1278,6 +1278,16 @@ pub enum AlterColumnOperation { }, /// `DROP DEFAULT` DropDefault, + /// `DROP IDENTITY [ IF EXISTS ]` + DropIdentity { + /// Whether `IF EXISTS` was specified. + if_exists: bool, + }, + /// `DROP EXPRESSION [ IF EXISTS ]` + DropExpression { + /// Whether `IF EXISTS` was specified. + if_exists: bool, + }, /// `SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN | DEFAULT }` SetStorage { /// PostgreSQL column storage strategy. @@ -1315,6 +1325,20 @@ impl fmt::Display for AlterColumnOperation { AlterColumnOperation::DropDefault => { write!(f, "DROP DEFAULT") } + AlterColumnOperation::DropIdentity { if_exists } => { + write!(f, "DROP IDENTITY")?; + if *if_exists { + write!(f, " IF EXISTS")?; + } + Ok(()) + } + AlterColumnOperation::DropExpression { if_exists } => { + write!(f, "DROP EXPRESSION")?; + if *if_exists { + write!(f, " IF EXISTS")?; + } + Ok(()) + } AlterColumnOperation::SetStorage { storage } => { write!(f, "SET STORAGE {storage}") } diff --git a/src/ast/spans.rs b/src/ast/spans.rs index 8b318bf0d..d9c6f3ea7 100644 --- a/src/ast/spans.rs +++ b/src/ast/spans.rs @@ -893,6 +893,8 @@ impl Spanned for Analyze { /// - [AlterColumnOperation::SetNotNull] /// - [AlterColumnOperation::DropNotNull] /// - [AlterColumnOperation::DropDefault] +/// - [AlterColumnOperation::DropIdentity] +/// - [AlterColumnOperation::DropExpression] /// - [AlterColumnOperation::SetStorage] /// - [AlterColumnOperation::AddGenerated] impl Spanned for AlterColumnOperation { @@ -902,6 +904,8 @@ impl Spanned for AlterColumnOperation { AlterColumnOperation::DropNotNull => Span::empty(), AlterColumnOperation::SetDefault { value } => value.span(), AlterColumnOperation::DropDefault => Span::empty(), + AlterColumnOperation::DropIdentity { .. } => Span::empty(), + AlterColumnOperation::DropExpression { .. } => Span::empty(), AlterColumnOperation::SetStorage { .. } => Span::empty(), AlterColumnOperation::SetDataType { data_type: _, diff --git a/src/keywords.rs b/src/keywords.rs index 8c8460176..cd3a253a2 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -406,6 +406,7 @@ define_keywords!( EXPLAIN, EXPLICIT, EXPORT, + EXPRESSION, EXTEND, EXTENDED, EXTENSION, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 65db3a711..a5adff0d0 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -10615,6 +10615,14 @@ impl<'a> Parser<'a> { } } else if self.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) { AlterColumnOperation::DropDefault {} + } else if self.parse_keywords(&[Keyword::DROP, Keyword::IDENTITY]) { + AlterColumnOperation::DropIdentity { + if_exists: self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]), + } + } else if self.parse_keywords(&[Keyword::DROP, Keyword::EXPRESSION]) { + AlterColumnOperation::DropExpression { + if_exists: self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]), + } } else if self.parse_keywords(&[Keyword::SET, Keyword::STORAGE]) { let storage = self.parse_column_storage()?; AlterColumnOperation::SetStorage { storage } @@ -10647,9 +10655,9 @@ impl<'a> Parser<'a> { } } else { let message = if is_postgresql { - "SET/DROP NOT NULL, SET DEFAULT, SET STORAGE, SET DATA TYPE, or ADD GENERATED after ALTER COLUMN" + "SET/DROP NOT NULL, SET/DROP DEFAULT, DROP IDENTITY, DROP EXPRESSION, SET STORAGE, SET DATA TYPE, or ADD GENERATED after ALTER COLUMN" } else { - "SET/DROP NOT NULL, SET DEFAULT, SET STORAGE, or SET DATA TYPE after ALTER COLUMN" + "SET/DROP NOT NULL, SET/DROP DEFAULT, DROP IDENTITY, DROP EXPRESSION, SET STORAGE, or SET DATA TYPE after ALTER COLUMN" }; return self.expected_ref(message, self.peek_token_ref()); diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 94421d60a..af73767b5 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -1110,6 +1110,24 @@ fn parse_alter_table_alter_column_set_storage() { } } +#[test] +fn parse_alter_table_alter_column_drop_identity() { + for suffix in ["", " IF EXISTS"] { + pg_and_generic().verified_stmt(&format!( + "ALTER TABLE tab ALTER COLUMN id DROP IDENTITY{suffix}" + )); + } +} + +#[test] +fn parse_alter_table_alter_column_drop_expression() { + for suffix in ["", " IF EXISTS"] { + pg_and_generic().verified_stmt(&format!( + "ALTER TABLE tab ALTER COLUMN generated_value DROP EXPRESSION{suffix}" + )); + } +} + #[test] fn parse_create_table_column_storage() { for (storage, expected) in [