diff --git a/fuzz/fuzz_seeds/postgres_alter_extension.sql b/fuzz/fuzz_seeds/postgres_alter_extension.sql index dc1fee895c..c63e6ef6f9 100644 --- a/fuzz/fuzz_seeds/postgres_alter_extension.sql +++ b/fuzz/fuzz_seeds/postgres_alter_extension.sql @@ -8,3 +8,4 @@ ALTER EXTENSION citext DROP FOREIGN TABLE public.ft; ALTER EXTENSION citext ADD SEQUENCE public.seq; ALTER EXTENSION citext DROP SCHEMA other; ALTER EXTENSION citext DROP PROCEDURAL LANGUAGE plpgsql; +ALTER EXTENSION citext ADD ACCESS METHOD btree; diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index b0fcc014ee..8a9bb98337 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -4926,6 +4926,8 @@ pub enum AlterExtensionOperation { #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] pub enum AlterExtensionMember { + /// `ACCESS METHOD object_name` + AccessMethod(Ident), /// `FOREIGN TABLE object_name` ForeignTable(ObjectName), /// `[ PROCEDURAL ] LANGUAGE object_name` @@ -4969,6 +4971,7 @@ impl fmt::Display for AlterExtensionOperation { impl fmt::Display for AlterExtensionMember { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { + AlterExtensionMember::AccessMethod(name) => write!(f, "ACCESS METHOD {name}"), AlterExtensionMember::ForeignTable(name) => write!(f, "FOREIGN TABLE {name}"), AlterExtensionMember::Language { procedural, name } => { if *procedural { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index f0ca9648f7..52458899c1 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -12539,7 +12539,9 @@ impl<'a> Parser<'a> { /// Parse a member object of `ALTER EXTENSION ADD` or `ALTER EXTENSION DROP` fn parse_alter_extension_member(&mut self) -> Result { - if self.parse_keywords(&[Keyword::FOREIGN, Keyword::TABLE]) { + if self.parse_keywords(&[Keyword::ACCESS, Keyword::METHOD]) { + Ok(AlterExtensionMember::AccessMethod(self.parse_identifier()?)) + } else if self.parse_keywords(&[Keyword::FOREIGN, Keyword::TABLE]) { Ok(AlterExtensionMember::ForeignTable( self.parse_object_name(false)?, )) diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index f8326403bd..47768e4543 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -13528,6 +13528,7 @@ fn parse_case_ending_in_end_keyword_is_not_silently_dropped() { fn alter_extension_member_round_trip_forms(action: &str) { let sqls = [ + format!("ALTER EXTENSION ext_name {action} ACCESS METHOD btree"), format!("ALTER EXTENSION ext_name {action} FOREIGN TABLE ft"), format!("ALTER EXTENSION ext_name {action} FOREIGN TABLE schema.ft"), format!("ALTER EXTENSION ext_name {action} LANGUAGE plpgsql"), @@ -13665,6 +13666,19 @@ fn parse_alter_extension_set_schema() { fn parse_alter_extension_add_member() { alter_extension_member_round_trip_forms("ADD"); + match pg_and_generic().verified_stmt("ALTER EXTENSION ext_name ADD ACCESS METHOD btree") { + Statement::AlterExtension(AlterExtension { name, operation }) => { + assert_eq!(name, Ident::new("ext_name")); + assert_eq!( + operation, + AlterExtensionOperation::Add(AlterExtensionMember::AccessMethod(Ident::new( + "btree" + ))) + ); + } + other => panic!("unexpected statement: {other:?}"), + } + match pg_and_generic().verified_stmt("ALTER EXTENSION ext_name ADD PROCEDURAL LANGUAGE plpgsql") { Statement::AlterExtension(AlterExtension { @@ -13700,6 +13714,7 @@ fn parse_alter_extension_add_member() { } for member in [ + "ACCESS METHOD", "FOREIGN TABLE", "LANGUAGE", "MATERIALIZED VIEW",