diff --git a/fuzz/fuzz_seeds/postgres_alter_extension.sql b/fuzz/fuzz_seeds/postgres_alter_extension.sql index 83b250d433..10a912beb2 100644 --- a/fuzz/fuzz_seeds/postgres_alter_extension.sql +++ b/fuzz/fuzz_seeds/postgres_alter_extension.sql @@ -31,3 +31,4 @@ ALTER EXTENSION citext DROP PROCEDURE public.p(int); 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); diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 2c6cd08e8e..dcc40c7f35 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -4961,6 +4961,8 @@ pub enum AlterExtensionMember { }, /// `MATERIALIZED VIEW object_name` MaterializedView(ObjectName), + /// `OPERATOR operator_name (left_type, right_type)` + Operator(DropOperatorSignature), /// `PROCEDURE procedure_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ]` Procedure(FunctionDesc), /// `PUBLICATION object_name` @@ -5038,6 +5040,7 @@ impl fmt::Display for AlterExtensionMember { } } AlterExtensionMember::MaterializedView(name) => write!(f, "MATERIALIZED VIEW {name}"), + AlterExtensionMember::Operator(signature) => write!(f, "OPERATOR {signature}"), 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 82a1e14e2d..a1515ffd03 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -9131,8 +9131,8 @@ impl<'a> Parser<'a> { })) } - /// Parse an operator signature for a [Statement::DropOperator] - /// Format: `name ( { left_type | NONE } , right_type )` + /// Parse an operator signature in the form + /// `name ( { left_type | NONE } , right_type )` fn parse_drop_operator_signature(&mut self) -> Result { let name = self.parse_operator_name()?; self.expect_token(&Token::LParen)?; @@ -12576,6 +12576,10 @@ impl<'a> Parser<'a> { Ok(AlterExtensionMember::MaterializedView( self.parse_object_name(false)?, )) + } else if self.parse_keyword(Keyword::OPERATOR) { + 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 a1471e052e..ae5b566511 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -13558,6 +13558,8 @@ fn alter_extension_member_round_trip_forms(action: &str) { format!("ALTER EXTENSION ext_name {action} LANGUAGE plpgsql"), format!("ALTER EXTENSION ext_name {action} PROCEDURAL LANGUAGE plpgsql"), 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} PROCEDURE p"), format!("ALTER EXTENSION ext_name {action} PROCEDURE p()"), format!("ALTER EXTENSION ext_name {action} PROCEDURE p(INT)"), @@ -13762,6 +13764,18 @@ fn parse_alter_extension_add_member() { other => panic!("unexpected statement: {other:?}"), } + match pg_and_generic().verified_stmt("ALTER EXTENSION ext_name ADD OPERATOR - (NONE, INT)") { + Statement::AlterExtension(AlterExtension { + operation: AlterExtensionOperation::Add(AlterExtensionMember::Operator(signature)), + .. + }) => { + assert_eq!(signature.name, ObjectName::from(Ident::new("-"))); + assert_eq!(signature.left_type, None); + assert_eq!(signature.right_type, DataType::Int(None)); + } + other => panic!("unexpected statement: {other:?}"), + } + for (sql, error) in [ ( "ALTER EXTENSION ext_name ADD", @@ -13791,6 +13805,10 @@ fn parse_alter_extension_add_member() { "ALTER EXTENSION ext_name ADD ROUTINE 1", "Expected: identifier, found: 1", ), + ( + "ALTER EXTENSION ext_name ADD OPERATOR +", + "Expected: (, found: EOF", + ), ] { assert_eq!( pg_and_generic().parse_sql_statements(sql).unwrap_err(),