Skip to content

Commit 62a056e

Browse files
Added support for DROP OPERATOR FAMILY
1 parent 4beea9a commit 62a056e

File tree

5 files changed

+132
-8
lines changed

5 files changed

+132
-8
lines changed

src/ast/ddl.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4251,3 +4251,40 @@ impl Spanned for DropOperator {
42514251
Span::empty()
42524252
}
42534253
}
4254+
4255+
/// `DROP OPERATOR FAMILY` statement
4256+
/// See <https://www.postgresql.org/docs/current/sql-dropopfamily.html>
4257+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4258+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4259+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4260+
pub struct DropOperatorFamily {
4261+
/// `IF EXISTS` clause
4262+
pub if_exists: bool,
4263+
/// One or more operator families to drop
4264+
pub names: Vec<ObjectName>,
4265+
/// Index method (btree, hash, gist, gin, etc.)
4266+
pub using: Ident,
4267+
/// `CASCADE or RESTRICT`
4268+
pub drop_behavior: Option<DropBehavior>,
4269+
}
4270+
4271+
impl fmt::Display for DropOperatorFamily {
4272+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4273+
write!(f, "DROP OPERATOR FAMILY")?;
4274+
if self.if_exists {
4275+
write!(f, " IF EXISTS")?;
4276+
}
4277+
write!(f, " {}", display_comma_separated(&self.names))?;
4278+
write!(f, " USING {}", self.using)?;
4279+
if let Some(drop_behavior) = &self.drop_behavior {
4280+
write!(f, " {}", drop_behavior)?;
4281+
}
4282+
Ok(())
4283+
}
4284+
}
4285+
4286+
impl Spanned for DropOperatorFamily {
4287+
fn span(&self) -> Span {
4288+
Span::empty()
4289+
}
4290+
}

src/ast/mod.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ pub use self::ddl::{
6767
ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
6868
CreateExtension, CreateFunction, CreateIndex, CreateOperator, CreateOperatorClass,
6969
CreateOperatorFamily, CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial,
70-
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorSignature, DropTrigger,
71-
GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty,
72-
IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder, IndexColumn,
73-
IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes,
74-
OperatorClassItem, OperatorPurpose, Owner, Partition, ProcedureParam, ReferentialAction,
75-
RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind, Truncate,
76-
UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
70+
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorFamily,
71+
DropOperatorSignature, DropTrigger, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
72+
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
73+
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
74+
OperatorArgTypes, OperatorClassItem, OperatorPurpose, Owner, Partition, ProcedureParam,
75+
ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind,
76+
Truncate, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
7777
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
7878
UserDefinedTypeStorage, ViewColumnDef,
7979
};
@@ -3580,6 +3580,12 @@ pub enum Statement {
35803580
/// <https://www.postgresql.org/docs/current/sql-dropoperator.html>
35813581
DropOperator(DropOperator),
35823582
/// ```sql
3583+
/// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3584+
/// ```
3585+
/// Note: this is a PostgreSQL-specific statement.
3586+
/// <https://www.postgresql.org/docs/current/sql-dropopfamily.html>
3587+
DropOperatorFamily(DropOperatorFamily),
3588+
/// ```sql
35833589
/// FETCH
35843590
/// ```
35853591
/// Retrieve rows from a query using a cursor
@@ -4844,6 +4850,9 @@ impl fmt::Display for Statement {
48444850
Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
48454851
Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
48464852
Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
4853+
Statement::DropOperatorFamily(drop_operator_family) => {
4854+
write!(f, "{drop_operator_family}")
4855+
}
48474856
Statement::CreateRole(create_role) => write!(f, "{create_role}"),
48484857
Statement::CreateSecret {
48494858
or_replace,

src/ast/spans.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ impl Spanned for Statement {
376376
Statement::CreateExtension(create_extension) => create_extension.span(),
377377
Statement::DropExtension(drop_extension) => drop_extension.span(),
378378
Statement::DropOperator(drop_operator) => drop_operator.span(),
379+
Statement::DropOperatorFamily(drop_operator_family) => drop_operator_family.span(),
379380
Statement::CreateSecret { .. } => Span::empty(),
380381
Statement::CreateServer { .. } => Span::empty(),
381382
Statement::CreateConnector { .. } => Span::empty(),

src/parser/mod.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6773,7 +6773,12 @@ impl<'a> Parser<'a> {
67736773
} else if self.parse_keyword(Keyword::EXTENSION) {
67746774
return self.parse_drop_extension();
67756775
} else if self.parse_keyword(Keyword::OPERATOR) {
6776-
return self.parse_drop_operator();
6776+
// Check if this is DROP OPERATOR FAMILY
6777+
return if self.parse_keyword(Keyword::FAMILY) {
6778+
self.parse_drop_operator_family()
6779+
} else {
6780+
self.parse_drop_operator()
6781+
};
67776782
} else {
67786783
return self.expected(
67796784
"CONNECTOR, DATABASE, EXTENSION, FUNCTION, INDEX, OPERATOR, POLICY, PROCEDURE, ROLE, SCHEMA, SECRET, SEQUENCE, STAGE, TABLE, TRIGGER, TYPE, VIEW, MATERIALIZED VIEW or USER after DROP",
@@ -7572,6 +7577,23 @@ impl<'a> Parser<'a> {
75727577
})
75737578
}
75747579

7580+
/// Parse a [Statement::DropOperatorFamily]
7581+
///
7582+
/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-dropopfamily.html)
7583+
pub fn parse_drop_operator_family(&mut self) -> Result<Statement, ParserError> {
7584+
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
7585+
let names = self.parse_comma_separated(|p| p.parse_object_name(false))?;
7586+
self.expect_keyword(Keyword::USING)?;
7587+
let using = self.parse_identifier()?;
7588+
let drop_behavior = self.parse_optional_drop_behavior();
7589+
Ok(Statement::DropOperatorFamily(DropOperatorFamily {
7590+
if_exists,
7591+
names,
7592+
using,
7593+
drop_behavior,
7594+
}))
7595+
}
7596+
75757597
//TODO: Implement parsing for Skewed
75767598
pub fn parse_hive_distribution(&mut self) -> Result<HiveDistributionStyle, ParserError> {
75777599
if self.parse_keywords(&[Keyword::PARTITIONED, Keyword::BY]) {

tests/sqlparser_postgres.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6910,6 +6910,61 @@ fn parse_drop_operator() {
69106910
);
69116911
}
69126912

6913+
#[test]
6914+
fn parse_drop_operator_family() {
6915+
for if_exists in [true, false] {
6916+
for drop_behavior in [
6917+
None,
6918+
Some(DropBehavior::Cascade),
6919+
Some(DropBehavior::Restrict),
6920+
] {
6921+
for index_method in &["btree", "hash", "gist", "gin", "spgist", "brin"] {
6922+
for (names_str, names_vec) in [
6923+
(
6924+
"float_ops",
6925+
vec![ObjectName::from(vec![Ident::new("float_ops")])],
6926+
),
6927+
(
6928+
"myschema.custom_ops",
6929+
vec![ObjectName::from(vec![
6930+
Ident::new("myschema"),
6931+
Ident::new("custom_ops"),
6932+
])],
6933+
),
6934+
(
6935+
"ops1, ops2, schema.ops3",
6936+
vec![
6937+
ObjectName::from(vec![Ident::new("ops1")]),
6938+
ObjectName::from(vec![Ident::new("ops2")]),
6939+
ObjectName::from(vec![Ident::new("schema"), Ident::new("ops3")]),
6940+
],
6941+
),
6942+
] {
6943+
let sql = format!(
6944+
"DROP OPERATOR FAMILY{} {} USING {}{}",
6945+
if if_exists { " IF EXISTS" } else { "" },
6946+
names_str,
6947+
index_method,
6948+
match drop_behavior {
6949+
Some(behavior) => format!(" {}", behavior),
6950+
None => String::new(),
6951+
}
6952+
);
6953+
assert_eq!(
6954+
pg_and_generic().verified_stmt(&sql),
6955+
Statement::DropOperatorFamily(DropOperatorFamily {
6956+
if_exists,
6957+
names: names_vec,
6958+
using: Ident::new(*index_method),
6959+
drop_behavior,
6960+
})
6961+
);
6962+
}
6963+
}
6964+
}
6965+
}
6966+
}
6967+
69136968
#[test]
69146969
fn parse_create_operator_family() {
69156970
for index_method in &["btree", "hash", "gist", "gin", "spgist", "brin"] {

0 commit comments

Comments
 (0)