diff --git a/fuzz/fuzz_seeds/postgres_alter_extension.sql b/fuzz/fuzz_seeds/postgres_alter_extension.sql index 10a912beb2..d3213eb565 100644 --- a/fuzz/fuzz_seeds/postgres_alter_extension.sql +++ b/fuzz/fuzz_seeds/postgres_alter_extension.sql @@ -32,3 +32,4 @@ ALTER EXTENSION citext ADD ROUTINE public.r(int); ALTER EXTENSION citext DROP AGGREGATE agg(int ORDER BY text); ALTER EXTENSION citext ADD AGGREGATE cnt(*); ALTER EXTENSION citext ADD OPERATOR - (NONE, int); +ALTER EXTENSION citext DROP OPERATOR CLASS oc USING btree; diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index dcc40c7f35..9697dcdd06 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -4963,6 +4963,13 @@ pub enum AlterExtensionMember { MaterializedView(ObjectName), /// `OPERATOR operator_name (left_type, right_type)` Operator(DropOperatorSignature), + /// `OPERATOR CLASS object_name USING index_method` + OperatorClass { + /// Operator class name. + name: ObjectName, + /// Index method. + using: Ident, + }, /// `PROCEDURE procedure_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ]` Procedure(FunctionDesc), /// `PUBLICATION object_name` @@ -5041,6 +5048,9 @@ impl fmt::Display for AlterExtensionMember { } AlterExtensionMember::MaterializedView(name) => write!(f, "MATERIALIZED VIEW {name}"), AlterExtensionMember::Operator(signature) => write!(f, "OPERATOR {signature}"), + AlterExtensionMember::OperatorClass { name, using } => { + write!(f, "OPERATOR CLASS {name} USING {using}") + } AlterExtensionMember::Procedure(function) => write!(f, "PROCEDURE {function}"), AlterExtensionMember::Publication(name) => write!(f, "PUBLICATION {name}"), AlterExtensionMember::Routine(function) => write!(f, "ROUTINE {function}"), diff --git a/src/parser/mod.rs b/src/parser/mod.rs index a1515ffd03..95fff4d916 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -12577,9 +12577,16 @@ impl<'a> Parser<'a> { self.parse_object_name(false)?, )) } else if self.parse_keyword(Keyword::OPERATOR) { - Ok(AlterExtensionMember::Operator( - self.parse_drop_operator_signature()?, - )) + if self.parse_keyword(Keyword::CLASS) { + let name = self.parse_object_name(false)?; + self.expect_keyword_is(Keyword::USING)?; + let using = self.parse_identifier()?; + Ok(AlterExtensionMember::OperatorClass { name, using }) + } else { + Ok(AlterExtensionMember::Operator( + self.parse_drop_operator_signature()?, + )) + } } else if self.parse_keyword(Keyword::PROCEDURE) { Ok(AlterExtensionMember::Procedure(self.parse_function_desc()?)) } else if self.parse_keyword(Keyword::PUBLICATION) { diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index ae5b566511..9ad3b12b42 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -13560,6 +13560,7 @@ fn alter_extension_member_round_trip_forms(action: &str) { format!("ALTER EXTENSION ext_name {action} MATERIALIZED VIEW mv"), format!("ALTER EXTENSION ext_name {action} OPERATOR + (INT, TEXT)"), format!("ALTER EXTENSION ext_name {action} OPERATOR - (NONE, INT)"), + format!("ALTER EXTENSION ext_name {action} OPERATOR CLASS oc USING btree"), format!("ALTER EXTENSION ext_name {action} PROCEDURE p"), format!("ALTER EXTENSION ext_name {action} PROCEDURE p()"), format!("ALTER EXTENSION ext_name {action} PROCEDURE p(INT)"), @@ -13809,6 +13810,18 @@ fn parse_alter_extension_add_member() { "ALTER EXTENSION ext_name ADD OPERATOR +", "Expected: (, found: EOF", ), + ( + "ALTER EXTENSION ext_name ADD OPERATOR CLASS oc", + "Expected: USING, found: EOF", + ), + ( + "ALTER EXTENSION ext_name ADD OPERATOR CLASS oc USING", + "Expected: identifier, found: EOF", + ), + ( + "ALTER EXTENSION ext_name ADD OPERATOR CLASS", + "Expected: identifier, found: EOF", + ), ] { assert_eq!( pg_and_generic().parse_sql_statements(sql).unwrap_err(),