diff --git a/fuzz/fuzz_seeds/postgres_alter_extension.sql b/fuzz/fuzz_seeds/postgres_alter_extension.sql index d3213eb565..20931ac0fd 100644 --- a/fuzz/fuzz_seeds/postgres_alter_extension.sql +++ b/fuzz/fuzz_seeds/postgres_alter_extension.sql @@ -33,3 +33,4 @@ 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; +ALTER EXTENSION citext DROP OPERATOR FAMILY of USING btree; diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs index 9697dcdd06..01d6c392c8 100644 --- a/src/ast/ddl.rs +++ b/src/ast/ddl.rs @@ -4970,6 +4970,13 @@ pub enum AlterExtensionMember { /// Index method. using: Ident, }, + /// `OPERATOR FAMILY object_name USING index_method` + OperatorFamily { + /// Operator family name. + name: ObjectName, + /// Index method. + using: Ident, + }, /// `PROCEDURE procedure_name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ]` Procedure(FunctionDesc), /// `PUBLICATION object_name` @@ -5051,6 +5058,9 @@ impl fmt::Display for AlterExtensionMember { AlterExtensionMember::OperatorClass { name, using } => { write!(f, "OPERATOR CLASS {name} USING {using}") } + AlterExtensionMember::OperatorFamily { name, using } => { + write!(f, "OPERATOR FAMILY {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 95fff4d916..cd78d41dbc 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -12582,6 +12582,11 @@ impl<'a> Parser<'a> { self.expect_keyword_is(Keyword::USING)?; let using = self.parse_identifier()?; Ok(AlterExtensionMember::OperatorClass { name, using }) + } else if self.parse_keyword(Keyword::FAMILY) { + let name = self.parse_object_name(false)?; + self.expect_keyword_is(Keyword::USING)?; + let using = self.parse_identifier()?; + Ok(AlterExtensionMember::OperatorFamily { name, using }) } else { Ok(AlterExtensionMember::Operator( self.parse_drop_operator_signature()?, diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 9ad3b12b42..dc86429746 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -13561,6 +13561,7 @@ fn alter_extension_member_round_trip_forms(action: &str) { 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} OPERATOR FAMILY of 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)"), @@ -13822,6 +13823,18 @@ fn parse_alter_extension_add_member() { "ALTER EXTENSION ext_name ADD OPERATOR CLASS", "Expected: identifier, found: EOF", ), + ( + "ALTER EXTENSION ext_name ADD OPERATOR FAMILY", + "Expected: identifier, found: EOF", + ), + ( + "ALTER EXTENSION ext_name ADD OPERATOR FAMILY of", + "Expected: USING, found: EOF", + ), + ( + "ALTER EXTENSION ext_name ADD OPERATOR FAMILY of USING", + "Expected: identifier, found: EOF", + ), ] { assert_eq!( pg_and_generic().parse_sql_statements(sql).unwrap_err(),