This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 982f7669 Added support for `DROP OPERATOR FAMILY` (#2106)
982f7669 is described below
commit 982f7669c2e1a86604bde560d1350050712344bc
Author: Luca Cappelletti <[email protected]>
AuthorDate: Sat Nov 29 07:14:58 2025 +0100
Added support for `DROP OPERATOR FAMILY` (#2106)
---
src/ast/ddl.rs | 37 ++++++++++++++++++++++++++++++
src/ast/mod.rs | 23 +++++++++++++------
src/ast/spans.rs | 1 +
src/parser/mod.rs | 24 +++++++++++++++++++-
tests/sqlparser_postgres.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 132 insertions(+), 8 deletions(-)
diff --git a/src/ast/ddl.rs b/src/ast/ddl.rs
index 078e3623..1719c6c0 100644
--- a/src/ast/ddl.rs
+++ b/src/ast/ddl.rs
@@ -4251,3 +4251,40 @@ impl Spanned for DropOperator {
Span::empty()
}
}
+
+/// `DROP OPERATOR FAMILY` statement
+/// See <https://www.postgresql.org/docs/current/sql-dropopfamily.html>
+#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
+pub struct DropOperatorFamily {
+ /// `IF EXISTS` clause
+ pub if_exists: bool,
+ /// One or more operator families to drop
+ pub names: Vec<ObjectName>,
+ /// Index method (btree, hash, gist, gin, etc.)
+ pub using: Ident,
+ /// `CASCADE or RESTRICT`
+ pub drop_behavior: Option<DropBehavior>,
+}
+
+impl fmt::Display for DropOperatorFamily {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "DROP OPERATOR FAMILY")?;
+ if self.if_exists {
+ write!(f, " IF EXISTS")?;
+ }
+ write!(f, " {}", display_comma_separated(&self.names))?;
+ write!(f, " USING {}", self.using)?;
+ if let Some(drop_behavior) = &self.drop_behavior {
+ write!(f, " {}", drop_behavior)?;
+ }
+ Ok(())
+ }
+}
+
+impl Spanned for DropOperatorFamily {
+ fn span(&self) -> Span {
+ Span::empty()
+ }
+}
diff --git a/src/ast/mod.rs b/src/ast/mod.rs
index 2d768c24..63a7bebc 100644
--- a/src/ast/mod.rs
+++ b/src/ast/mod.rs
@@ -67,13 +67,13 @@ pub use self::ddl::{
ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector,
CreateDomain,
CreateExtension, CreateFunction, CreateIndex, CreateOperator,
CreateOperatorClass,
CreateOperatorFamily, CreateTable, CreateTrigger, CreateView, Deduplicate,
DeferrableInitial,
- DropBehavior, DropExtension, DropFunction, DropOperator,
DropOperatorSignature, DropTrigger,
- GeneratedAs, GeneratedExpressionMode, IdentityParameters, IdentityProperty,
- IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
IndexColumn,
- IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
OperatorArgTypes,
- OperatorClassItem, OperatorPurpose, Owner, Partition, ProcedureParam,
ReferentialAction,
- RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind,
Truncate,
- UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
+ DropBehavior, DropExtension, DropFunction, DropOperator,
DropOperatorFamily,
+ DropOperatorSignature, DropTrigger, GeneratedAs, GeneratedExpressionMode,
IdentityParameters,
+ IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
IdentityPropertyOrder,
+ IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck,
NullsDistinctOption,
+ OperatorArgTypes, OperatorClassItem, OperatorPurpose, Owner, Partition,
ProcedureParam,
+ ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption,
TriggerObjectKind,
+ Truncate, UserDefinedTypeCompositeAttributeDef,
UserDefinedTypeInternalLength,
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
UserDefinedTypeSqlDefinitionOption,
UserDefinedTypeStorage, ViewColumnDef,
};
@@ -3580,6 +3580,12 @@ pub enum Statement {
/// <https://www.postgresql.org/docs/current/sql-dropoperator.html>
DropOperator(DropOperator),
/// ```sql
+ /// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE |
RESTRICT ]
+ /// ```
+ /// Note: this is a PostgreSQL-specific statement.
+ /// <https://www.postgresql.org/docs/current/sql-dropopfamily.html>
+ DropOperatorFamily(DropOperatorFamily),
+ /// ```sql
/// FETCH
/// ```
/// Retrieve rows from a query using a cursor
@@ -4844,6 +4850,9 @@ impl fmt::Display for Statement {
Statement::CreateExtension(create_extension) => write!(f,
"{create_extension}"),
Statement::DropExtension(drop_extension) => write!(f,
"{drop_extension}"),
Statement::DropOperator(drop_operator) => write!(f,
"{drop_operator}"),
+ Statement::DropOperatorFamily(drop_operator_family) => {
+ write!(f, "{drop_operator_family}")
+ }
Statement::CreateRole(create_role) => write!(f, "{create_role}"),
Statement::CreateSecret {
or_replace,
diff --git a/src/ast/spans.rs b/src/ast/spans.rs
index 66799fe5..994cee97 100644
--- a/src/ast/spans.rs
+++ b/src/ast/spans.rs
@@ -376,6 +376,7 @@ impl Spanned for Statement {
Statement::CreateExtension(create_extension) =>
create_extension.span(),
Statement::DropExtension(drop_extension) => drop_extension.span(),
Statement::DropOperator(drop_operator) => drop_operator.span(),
+ Statement::DropOperatorFamily(drop_operator_family) =>
drop_operator_family.span(),
Statement::CreateSecret { .. } => Span::empty(),
Statement::CreateServer { .. } => Span::empty(),
Statement::CreateConnector { .. } => Span::empty(),
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 0d561089..f3daf628 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -6773,7 +6773,12 @@ impl<'a> Parser<'a> {
} else if self.parse_keyword(Keyword::EXTENSION) {
return self.parse_drop_extension();
} else if self.parse_keyword(Keyword::OPERATOR) {
- return self.parse_drop_operator();
+ // Check if this is DROP OPERATOR FAMILY
+ return if self.parse_keyword(Keyword::FAMILY) {
+ self.parse_drop_operator_family()
+ } else {
+ self.parse_drop_operator()
+ };
} else {
return self.expected(
"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> {
})
}
+ /// Parse a [Statement::DropOperatorFamily]
+ ///
+ /// [PostgreSQL
Documentation](https://www.postgresql.org/docs/current/sql-dropopfamily.html)
+ pub fn parse_drop_operator_family(&mut self) -> Result<Statement,
ParserError> {
+ let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
+ let names = self.parse_comma_separated(|p|
p.parse_object_name(false))?;
+ self.expect_keyword(Keyword::USING)?;
+ let using = self.parse_identifier()?;
+ let drop_behavior = self.parse_optional_drop_behavior();
+ Ok(Statement::DropOperatorFamily(DropOperatorFamily {
+ if_exists,
+ names,
+ using,
+ drop_behavior,
+ }))
+ }
+
//TODO: Implement parsing for Skewed
pub fn parse_hive_distribution(&mut self) -> Result<HiveDistributionStyle,
ParserError> {
if self.parse_keywords(&[Keyword::PARTITIONED, Keyword::BY]) {
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 91150666..14b11052 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -6910,6 +6910,61 @@ fn parse_drop_operator() {
);
}
+#[test]
+fn parse_drop_operator_family() {
+ for if_exists in [true, false] {
+ for drop_behavior in [
+ None,
+ Some(DropBehavior::Cascade),
+ Some(DropBehavior::Restrict),
+ ] {
+ for index_method in &["btree", "hash", "gist", "gin", "spgist",
"brin"] {
+ for (names_str, names_vec) in [
+ (
+ "float_ops",
+ vec![ObjectName::from(vec![Ident::new("float_ops")])],
+ ),
+ (
+ "myschema.custom_ops",
+ vec![ObjectName::from(vec![
+ Ident::new("myschema"),
+ Ident::new("custom_ops"),
+ ])],
+ ),
+ (
+ "ops1, ops2, schema.ops3",
+ vec![
+ ObjectName::from(vec![Ident::new("ops1")]),
+ ObjectName::from(vec![Ident::new("ops2")]),
+ ObjectName::from(vec![Ident::new("schema"),
Ident::new("ops3")]),
+ ],
+ ),
+ ] {
+ let sql = format!(
+ "DROP OPERATOR FAMILY{} {} USING {}{}",
+ if if_exists { " IF EXISTS" } else { "" },
+ names_str,
+ index_method,
+ match drop_behavior {
+ Some(behavior) => format!(" {}", behavior),
+ None => String::new(),
+ }
+ );
+ assert_eq!(
+ pg_and_generic().verified_stmt(&sql),
+ Statement::DropOperatorFamily(DropOperatorFamily {
+ if_exists,
+ names: names_vec,
+ using: Ident::new(*index_method),
+ drop_behavior,
+ })
+ );
+ }
+ }
+ }
+ }
+}
+
#[test]
fn parse_create_operator_family() {
for index_method in &["btree", "hash", "gist", "gin", "spgist", "brin"] {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]