mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-12-23 11:12:51 +00:00
Added support for ALTER OPERATOR FAMILY syntax (#2125)
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
Some checks are pending
license / Release Audit Tool (RAT) (push) Waiting to run
Rust / codestyle (push) Waiting to run
Rust / lint (push) Waiting to run
Rust / benchmark-lint (push) Waiting to run
Rust / compile (push) Waiting to run
Rust / docs (push) Waiting to run
Rust / compile-no-std (push) Waiting to run
Rust / test (beta) (push) Waiting to run
Rust / test (nightly) (push) Waiting to run
Rust / test (stable) (push) Waiting to run
This commit is contained in:
parent
f84887d004
commit
d78dbc97a1
5 changed files with 778 additions and 25 deletions
198
src/ast/ddl.rs
198
src/ast/ddl.rs
|
|
@ -4198,25 +4198,25 @@ impl fmt::Display for OperatorArgTypes {
|
|||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum OperatorClassItem {
|
||||
/// OPERATOR clause
|
||||
/// `OPERATOR` clause
|
||||
Operator {
|
||||
strategy_number: u32,
|
||||
strategy_number: u64,
|
||||
operator_name: ObjectName,
|
||||
/// Optional operator argument types
|
||||
op_types: Option<OperatorArgTypes>,
|
||||
/// FOR SEARCH or FOR ORDER BY
|
||||
/// `FOR SEARCH` or `FOR ORDER BY`
|
||||
purpose: Option<OperatorPurpose>,
|
||||
},
|
||||
/// FUNCTION clause
|
||||
/// `FUNCTION` clause
|
||||
Function {
|
||||
support_number: u32,
|
||||
support_number: u64,
|
||||
/// Optional function argument types for the operator class
|
||||
op_types: Option<Vec<DataType>>,
|
||||
function_name: ObjectName,
|
||||
/// Function argument types
|
||||
argument_types: Vec<DataType>,
|
||||
},
|
||||
/// STORAGE clause
|
||||
/// `STORAGE` clause
|
||||
Storage { storage_type: DataType },
|
||||
}
|
||||
|
||||
|
|
@ -4413,3 +4413,189 @@ impl Spanned for DropOperatorClass {
|
|||
Span::empty()
|
||||
}
|
||||
}
|
||||
|
||||
/// An item in an ALTER OPERATOR FAMILY ADD statement
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum OperatorFamilyItem {
|
||||
/// `OPERATOR` clause
|
||||
Operator {
|
||||
strategy_number: u64,
|
||||
operator_name: ObjectName,
|
||||
/// Operator argument types
|
||||
op_types: Vec<DataType>,
|
||||
/// `FOR SEARCH` or `FOR ORDER BY`
|
||||
purpose: Option<OperatorPurpose>,
|
||||
},
|
||||
/// `FUNCTION` clause
|
||||
Function {
|
||||
support_number: u64,
|
||||
/// Optional operator argument types for the function
|
||||
op_types: Option<Vec<DataType>>,
|
||||
function_name: ObjectName,
|
||||
/// Function argument types
|
||||
argument_types: Vec<DataType>,
|
||||
},
|
||||
}
|
||||
|
||||
/// An item in an ALTER OPERATOR FAMILY DROP statement
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum OperatorFamilyDropItem {
|
||||
/// `OPERATOR` clause
|
||||
Operator {
|
||||
strategy_number: u64,
|
||||
/// Operator argument types
|
||||
op_types: Vec<DataType>,
|
||||
},
|
||||
/// `FUNCTION` clause
|
||||
Function {
|
||||
support_number: u64,
|
||||
/// Operator argument types for the function
|
||||
op_types: Vec<DataType>,
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for OperatorFamilyItem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
OperatorFamilyItem::Operator {
|
||||
strategy_number,
|
||||
operator_name,
|
||||
op_types,
|
||||
purpose,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"OPERATOR {strategy_number} {operator_name} ({})",
|
||||
display_comma_separated(op_types)
|
||||
)?;
|
||||
if let Some(purpose) = purpose {
|
||||
write!(f, " {purpose}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
OperatorFamilyItem::Function {
|
||||
support_number,
|
||||
op_types,
|
||||
function_name,
|
||||
argument_types,
|
||||
} => {
|
||||
write!(f, "FUNCTION {support_number}")?;
|
||||
if let Some(types) = op_types {
|
||||
write!(f, " ({})", display_comma_separated(types))?;
|
||||
}
|
||||
write!(f, " {function_name}")?;
|
||||
if !argument_types.is_empty() {
|
||||
write!(f, "({})", display_comma_separated(argument_types))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for OperatorFamilyDropItem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
OperatorFamilyDropItem::Operator {
|
||||
strategy_number,
|
||||
op_types,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"OPERATOR {strategy_number} ({})",
|
||||
display_comma_separated(op_types)
|
||||
)
|
||||
}
|
||||
OperatorFamilyDropItem::Function {
|
||||
support_number,
|
||||
op_types,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"FUNCTION {support_number} ({})",
|
||||
display_comma_separated(op_types)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `ALTER OPERATOR FAMILY` statement
|
||||
/// See <https://www.postgresql.org/docs/current/sql-alteropfamily.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 AlterOperatorFamily {
|
||||
/// Operator family name (can be schema-qualified)
|
||||
pub name: ObjectName,
|
||||
/// Index method (btree, hash, gist, gin, etc.)
|
||||
pub using: Ident,
|
||||
/// The operation to perform
|
||||
pub operation: AlterOperatorFamilyOperation,
|
||||
}
|
||||
|
||||
/// An [AlterOperatorFamily] operation
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
|
||||
pub enum AlterOperatorFamilyOperation {
|
||||
/// `ADD { OPERATOR ... | FUNCTION ... } [, ...]`
|
||||
Add {
|
||||
/// List of operator family items to add
|
||||
items: Vec<OperatorFamilyItem>,
|
||||
},
|
||||
/// `DROP { OPERATOR ... | FUNCTION ... } [, ...]`
|
||||
Drop {
|
||||
/// List of operator family items to drop
|
||||
items: Vec<OperatorFamilyDropItem>,
|
||||
},
|
||||
/// `RENAME TO new_name`
|
||||
RenameTo { new_name: ObjectName },
|
||||
/// `OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }`
|
||||
OwnerTo(Owner),
|
||||
/// `SET SCHEMA new_schema`
|
||||
SetSchema { schema_name: ObjectName },
|
||||
}
|
||||
|
||||
impl fmt::Display for AlterOperatorFamily {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"ALTER OPERATOR FAMILY {} USING {}",
|
||||
self.name, self.using
|
||||
)?;
|
||||
write!(f, " {}", self.operation)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for AlterOperatorFamilyOperation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
AlterOperatorFamilyOperation::Add { items } => {
|
||||
write!(f, "ADD {}", display_comma_separated(items))
|
||||
}
|
||||
AlterOperatorFamilyOperation::Drop { items } => {
|
||||
write!(f, "DROP {}", display_comma_separated(items))
|
||||
}
|
||||
AlterOperatorFamilyOperation::RenameTo { new_name } => {
|
||||
write!(f, "RENAME TO {new_name}")
|
||||
}
|
||||
AlterOperatorFamilyOperation::OwnerTo(owner) => {
|
||||
write!(f, "OWNER TO {owner}")
|
||||
}
|
||||
AlterOperatorFamilyOperation::SetSchema { schema_name } => {
|
||||
write!(f, "SET SCHEMA {schema_name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for AlterOperatorFamily {
|
||||
fn span(&self) -> Span {
|
||||
Span::empty()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,22 +60,24 @@ pub use self::dcl::{
|
|||
};
|
||||
pub use self::ddl::{
|
||||
Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator,
|
||||
AlterOperatorOperation, AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable,
|
||||
AlterTableAlgorithm, AlterTableLock, AlterTableOperation, AlterTableType, AlterType,
|
||||
AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
|
||||
AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
|
||||
ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
|
||||
AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation,
|
||||
AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
|
||||
AlterTableLock, AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue,
|
||||
AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
|
||||
ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
|
||||
ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
|
||||
CreateExtension, CreateFunction, CreateIndex, CreateOperator, CreateOperatorClass,
|
||||
CreateOperatorFamily, CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial,
|
||||
DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
|
||||
DropOperatorSignature, DropTrigger, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
|
||||
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
|
||||
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
|
||||
OperatorArgTypes, OperatorClassItem, OperatorOption, OperatorPurpose, Owner, Partition,
|
||||
ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption,
|
||||
TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
|
||||
UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
|
||||
UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef,
|
||||
OperatorArgTypes, OperatorClassItem, OperatorFamilyDropItem, OperatorFamilyItem,
|
||||
OperatorOption, OperatorPurpose, Owner, Partition, ProcedureParam, ReferentialAction,
|
||||
RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind, Truncate,
|
||||
UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
|
||||
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
|
||||
UserDefinedTypeStorage, ViewColumnDef,
|
||||
};
|
||||
pub use self::dml::{
|
||||
Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,
|
||||
|
|
@ -3411,6 +3413,11 @@ pub enum Statement {
|
|||
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
|
||||
AlterOperator(AlterOperator),
|
||||
/// ```sql
|
||||
/// ALTER OPERATOR FAMILY
|
||||
/// ```
|
||||
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteropfamily.html)
|
||||
AlterOperatorFamily(AlterOperatorFamily),
|
||||
/// ```sql
|
||||
/// ALTER ROLE
|
||||
/// ```
|
||||
AlterRole {
|
||||
|
|
@ -4972,6 +4979,9 @@ impl fmt::Display for Statement {
|
|||
write!(f, "ALTER TYPE {name} {operation}")
|
||||
}
|
||||
Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
|
||||
Statement::AlterOperatorFamily(alter_operator_family) => {
|
||||
write!(f, "{alter_operator_family}")
|
||||
}
|
||||
Statement::AlterRole { name, operation } => {
|
||||
write!(f, "ALTER ROLE {name} {operation}")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -403,6 +403,7 @@ impl Spanned for Statement {
|
|||
// These statements need to be implemented
|
||||
Statement::AlterType { .. } => Span::empty(),
|
||||
Statement::AlterOperator { .. } => Span::empty(),
|
||||
Statement::AlterOperatorFamily { .. } => Span::empty(),
|
||||
Statement::AlterRole { .. } => Span::empty(),
|
||||
Statement::AlterSession { .. } => Span::empty(),
|
||||
Statement::AttachDatabase { .. } => Span::empty(),
|
||||
|
|
|
|||
|
|
@ -6701,7 +6701,7 @@ impl<'a> Parser<'a> {
|
|||
let mut items = vec![];
|
||||
loop {
|
||||
if self.parse_keyword(Keyword::OPERATOR) {
|
||||
let strategy_number = self.parse_literal_uint()? as u32;
|
||||
let strategy_number = self.parse_literal_uint()?;
|
||||
let operator_name = self.parse_operator_name()?;
|
||||
|
||||
// Optional operator argument types
|
||||
|
|
@ -6736,7 +6736,7 @@ impl<'a> Parser<'a> {
|
|||
purpose,
|
||||
});
|
||||
} else if self.parse_keyword(Keyword::FUNCTION) {
|
||||
let support_number = self.parse_literal_uint()? as u32;
|
||||
let support_number = self.parse_literal_uint()?;
|
||||
|
||||
// Optional operator types
|
||||
let op_types =
|
||||
|
|
@ -9898,7 +9898,13 @@ impl<'a> Parser<'a> {
|
|||
operation,
|
||||
})
|
||||
}
|
||||
Keyword::OPERATOR => self.parse_alter_operator(),
|
||||
Keyword::OPERATOR => {
|
||||
if self.parse_keyword(Keyword::FAMILY) {
|
||||
self.parse_alter_operator_family()
|
||||
} else {
|
||||
self.parse_alter_operator()
|
||||
}
|
||||
}
|
||||
Keyword::ROLE => self.parse_alter_role(),
|
||||
Keyword::POLICY => self.parse_alter_policy(),
|
||||
Keyword::CONNECTOR => self.parse_alter_connector(),
|
||||
|
|
@ -10130,6 +10136,170 @@ impl<'a> Parser<'a> {
|
|||
}))
|
||||
}
|
||||
|
||||
/// Parse an operator item for ALTER OPERATOR FAMILY ADD operations
|
||||
fn parse_operator_family_add_operator(&mut self) -> Result<OperatorFamilyItem, ParserError> {
|
||||
let strategy_number = self.parse_literal_uint()?;
|
||||
let operator_name = self.parse_operator_name()?;
|
||||
|
||||
// Operator argument types (required for ALTER OPERATOR FAMILY)
|
||||
self.expect_token(&Token::LParen)?;
|
||||
let op_types = self.parse_comma_separated(Parser::parse_data_type)?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
|
||||
// Optional purpose
|
||||
let purpose = if self.parse_keyword(Keyword::FOR) {
|
||||
if self.parse_keyword(Keyword::SEARCH) {
|
||||
Some(OperatorPurpose::ForSearch)
|
||||
} else if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
|
||||
let sort_family = self.parse_object_name(false)?;
|
||||
Some(OperatorPurpose::ForOrderBy { sort_family })
|
||||
} else {
|
||||
return self.expected("SEARCH or ORDER BY after FOR", self.peek_token());
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(OperatorFamilyItem::Operator {
|
||||
strategy_number,
|
||||
operator_name,
|
||||
op_types,
|
||||
purpose,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a function item for ALTER OPERATOR FAMILY ADD operations
|
||||
fn parse_operator_family_add_function(&mut self) -> Result<OperatorFamilyItem, ParserError> {
|
||||
let support_number = self.parse_literal_uint()?;
|
||||
|
||||
// Optional operator types
|
||||
let op_types = if self.consume_token(&Token::LParen) && self.peek_token() != Token::RParen {
|
||||
let types = self.parse_comma_separated(Parser::parse_data_type)?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
Some(types)
|
||||
} else if self.consume_token(&Token::LParen) {
|
||||
self.expect_token(&Token::RParen)?;
|
||||
Some(vec![])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let function_name = self.parse_object_name(false)?;
|
||||
|
||||
// Function argument types
|
||||
let argument_types = if self.consume_token(&Token::LParen) {
|
||||
if self.peek_token() == Token::RParen {
|
||||
self.expect_token(&Token::RParen)?;
|
||||
vec![]
|
||||
} else {
|
||||
let types = self.parse_comma_separated(Parser::parse_data_type)?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
types
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
Ok(OperatorFamilyItem::Function {
|
||||
support_number,
|
||||
op_types,
|
||||
function_name,
|
||||
argument_types,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse an operator item for ALTER OPERATOR FAMILY DROP operations
|
||||
fn parse_operator_family_drop_operator(
|
||||
&mut self,
|
||||
) -> Result<OperatorFamilyDropItem, ParserError> {
|
||||
let strategy_number = self.parse_literal_uint()?;
|
||||
|
||||
// Operator argument types (required for DROP)
|
||||
self.expect_token(&Token::LParen)?;
|
||||
let op_types = self.parse_comma_separated(Parser::parse_data_type)?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
|
||||
Ok(OperatorFamilyDropItem::Operator {
|
||||
strategy_number,
|
||||
op_types,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a function item for ALTER OPERATOR FAMILY DROP operations
|
||||
fn parse_operator_family_drop_function(
|
||||
&mut self,
|
||||
) -> Result<OperatorFamilyDropItem, ParserError> {
|
||||
let support_number = self.parse_literal_uint()?;
|
||||
|
||||
// Operator types (required for DROP)
|
||||
self.expect_token(&Token::LParen)?;
|
||||
let op_types = self.parse_comma_separated(Parser::parse_data_type)?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
|
||||
Ok(OperatorFamilyDropItem::Function {
|
||||
support_number,
|
||||
op_types,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse an operator family item for ADD operations (dispatches to operator or function parsing)
|
||||
fn parse_operator_family_add_item(&mut self) -> Result<OperatorFamilyItem, ParserError> {
|
||||
if self.parse_keyword(Keyword::OPERATOR) {
|
||||
self.parse_operator_family_add_operator()
|
||||
} else if self.parse_keyword(Keyword::FUNCTION) {
|
||||
self.parse_operator_family_add_function()
|
||||
} else {
|
||||
self.expected("OPERATOR or FUNCTION", self.peek_token())
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse an operator family item for DROP operations (dispatches to operator or function parsing)
|
||||
fn parse_operator_family_drop_item(&mut self) -> Result<OperatorFamilyDropItem, ParserError> {
|
||||
if self.parse_keyword(Keyword::OPERATOR) {
|
||||
self.parse_operator_family_drop_operator()
|
||||
} else if self.parse_keyword(Keyword::FUNCTION) {
|
||||
self.parse_operator_family_drop_function()
|
||||
} else {
|
||||
self.expected("OPERATOR or FUNCTION", self.peek_token())
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a [Statement::AlterOperatorFamily]
|
||||
/// See <https://www.postgresql.org/docs/current/sql-alteropfamily.html>
|
||||
pub fn parse_alter_operator_family(&mut self) -> Result<Statement, ParserError> {
|
||||
let name = self.parse_object_name(false)?;
|
||||
self.expect_keyword(Keyword::USING)?;
|
||||
let using = self.parse_identifier()?;
|
||||
|
||||
let operation = if self.parse_keyword(Keyword::ADD) {
|
||||
let items = self.parse_comma_separated(Parser::parse_operator_family_add_item)?;
|
||||
AlterOperatorFamilyOperation::Add { items }
|
||||
} else if self.parse_keyword(Keyword::DROP) {
|
||||
let items = self.parse_comma_separated(Parser::parse_operator_family_drop_item)?;
|
||||
AlterOperatorFamilyOperation::Drop { items }
|
||||
} else if self.parse_keywords(&[Keyword::RENAME, Keyword::TO]) {
|
||||
let new_name = self.parse_object_name(false)?;
|
||||
AlterOperatorFamilyOperation::RenameTo { new_name }
|
||||
} else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
|
||||
let owner = self.parse_owner()?;
|
||||
AlterOperatorFamilyOperation::OwnerTo(owner)
|
||||
} else if self.parse_keywords(&[Keyword::SET, Keyword::SCHEMA]) {
|
||||
let schema_name = self.parse_object_name(false)?;
|
||||
AlterOperatorFamilyOperation::SetSchema { schema_name }
|
||||
} else {
|
||||
return self.expected_ref(
|
||||
"ADD, DROP, RENAME TO, OWNER TO, or SET SCHEMA after ALTER OPERATOR FAMILY",
|
||||
self.peek_token_ref(),
|
||||
);
|
||||
};
|
||||
|
||||
Ok(Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name,
|
||||
using,
|
||||
operation,
|
||||
}))
|
||||
}
|
||||
|
||||
// Parse a [Statement::AlterSchema]
|
||||
// ALTER SCHEMA [ IF EXISTS ] schema_name
|
||||
pub fn parse_alter_schema(&mut self) -> Result<Statement, ParserError> {
|
||||
|
|
|
|||
|
|
@ -23,15 +23,11 @@
|
|||
mod test_utils;
|
||||
|
||||
use helpers::attached_token::AttachedToken;
|
||||
use sqlparser::ast::{
|
||||
DataType, DropBehavior, DropOperator, DropOperatorClass, DropOperatorSignature,
|
||||
};
|
||||
use sqlparser::tokenizer::Span;
|
||||
use test_utils::*;
|
||||
|
||||
use sqlparser::ast::*;
|
||||
use sqlparser::dialect::{GenericDialect, PostgreSqlDialect};
|
||||
use sqlparser::parser::ParserError;
|
||||
use sqlparser::tokenizer::Span;
|
||||
use test_utils::*;
|
||||
|
||||
#[test]
|
||||
fn parse_create_table_generated_always_as_identity() {
|
||||
|
|
@ -7145,6 +7141,396 @@ fn parse_alter_operator() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_alter_operator_family() {
|
||||
// Test ALTER OPERATOR FAMILY ... ADD OPERATOR
|
||||
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree ADD OPERATOR 1 < (INT4, INT2)";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("integer_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::Add {
|
||||
items: vec![OperatorFamilyItem::Operator {
|
||||
strategy_number: 1,
|
||||
operator_name: ObjectName::from(vec![Ident::new("<")]),
|
||||
op_types: vec![DataType::Int4(None), DataType::Int2(None)],
|
||||
purpose: None,
|
||||
}],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Test ALTER OPERATOR FAMILY ... ADD OPERATOR with FOR SEARCH
|
||||
let sql =
|
||||
"ALTER OPERATOR FAMILY text_ops USING btree ADD OPERATOR 1 @@ (TEXT, TEXT) FOR SEARCH";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("text_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::Add {
|
||||
items: vec![OperatorFamilyItem::Operator {
|
||||
strategy_number: 1,
|
||||
operator_name: ObjectName::from(vec![Ident::new("@@")]),
|
||||
op_types: vec![DataType::Text, DataType::Text],
|
||||
purpose: Some(OperatorPurpose::ForSearch),
|
||||
}],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Test ALTER OPERATOR FAMILY ... ADD FUNCTION
|
||||
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree ADD FUNCTION 1 btint42cmp(INT4, INT2)";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("integer_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::Add {
|
||||
items: vec![OperatorFamilyItem::Function {
|
||||
support_number: 1,
|
||||
op_types: None,
|
||||
function_name: ObjectName::from(vec![Ident::new("btint42cmp")]),
|
||||
argument_types: vec![DataType::Int4(None), DataType::Int2(None)],
|
||||
}],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Test ALTER OPERATOR FAMILY ... DROP OPERATOR
|
||||
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree DROP OPERATOR 1 (INT4, INT2)";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("integer_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::Drop {
|
||||
items: vec![OperatorFamilyDropItem::Operator {
|
||||
strategy_number: 1,
|
||||
op_types: vec![DataType::Int4(None), DataType::Int2(None)],
|
||||
}],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Test ALTER OPERATOR FAMILY ... DROP FUNCTION
|
||||
let sql = "ALTER OPERATOR FAMILY integer_ops USING btree DROP FUNCTION 1 (INT4, INT2)";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("integer_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::Drop {
|
||||
items: vec![OperatorFamilyDropItem::Function {
|
||||
support_number: 1,
|
||||
op_types: vec![DataType::Int4(None), DataType::Int2(None)],
|
||||
}],
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Test ALTER OPERATOR FAMILY ... RENAME TO
|
||||
let sql = "ALTER OPERATOR FAMILY old_ops USING btree RENAME TO new_ops";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("old_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::RenameTo {
|
||||
new_name: ObjectName::from(vec![Ident::new("new_ops")]),
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Test ALTER OPERATOR FAMILY ... OWNER TO
|
||||
let sql = "ALTER OPERATOR FAMILY my_ops USING btree OWNER TO joe";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("my_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::OwnerTo(Owner::Ident(Ident::new("joe"))),
|
||||
})
|
||||
);
|
||||
|
||||
// Test ALTER OPERATOR FAMILY ... SET SCHEMA
|
||||
let sql = "ALTER OPERATOR FAMILY my_ops USING btree SET SCHEMA new_schema";
|
||||
assert_eq!(
|
||||
pg_and_generic().verified_stmt(sql),
|
||||
Statement::AlterOperatorFamily(AlterOperatorFamily {
|
||||
name: ObjectName::from(vec![Ident::new("my_ops")]),
|
||||
using: Ident::new("btree"),
|
||||
operation: AlterOperatorFamilyOperation::SetSchema {
|
||||
schema_name: ObjectName::from(vec![Ident::new("new_schema")]),
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Test error cases
|
||||
// Missing USING clause
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops ADD OPERATOR 1 < (INT4, INT2)")
|
||||
.is_err());
|
||||
|
||||
// Invalid operation
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree INVALID_OPERATION")
|
||||
.is_err());
|
||||
|
||||
// Missing operator name in ADD OPERATOR
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing function name in ADD FUNCTION
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing parentheses in DROP OPERATOR
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 INT4, INT2")
|
||||
.is_err());
|
||||
|
||||
// Invalid operator name (empty)
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Invalid operator name (special characters)
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 @#$ (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Negative strategy number
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR -1 < (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Non-integer strategy number
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1.5 < (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing closing parenthesis in operator types
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing opening parenthesis in operator types
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Empty operator types
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < ()")
|
||||
.is_err());
|
||||
|
||||
// Invalid data type (using punctuation)
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (@#$%, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Incomplete FOR clause
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Invalid FOR clause keyword
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR INVALID"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// FOR ORDER BY without sort family
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR ORDER BY"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing function name in ADD FUNCTION
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Invalid function name
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 123invalid(INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Negative support number
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION -1 func(INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Non-integer support number
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1.5 func(INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing closing parenthesis in function operator types
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4, INT2 func()"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing closing parenthesis in function arguments
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 func(INT4, INT2"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Invalid data type in function arguments
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 func(@#$%, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// DROP OPERATOR with FOR clause (not allowed)
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 (INT4, INT2) FOR SEARCH"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// DROP FUNCTION with function arguments (not allowed)
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree DROP FUNCTION 1 (INT4, INT2) func(INT4)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Multiple ADD items with error in middle
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2), INVALID_ITEM"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Multiple DROP items with error in middle
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 (INT4, INT2), INVALID_ITEM"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// RENAME TO with invalid new name
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree RENAME TO 123invalid")
|
||||
.is_err());
|
||||
|
||||
// OWNER TO with invalid owner
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree OWNER TO 123invalid")
|
||||
.is_err());
|
||||
|
||||
// SET SCHEMA with invalid schema name
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree SET SCHEMA 123invalid")
|
||||
.is_err());
|
||||
|
||||
// Schema-qualified operator family name with invalid schema
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY 123invalid.my_ops USING btree ADD OPERATOR 1 < (INT4, INT2)"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Missing operator family name
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY USING btree ADD OPERATOR 1 < (INT4, INT2)")
|
||||
.is_err());
|
||||
|
||||
// Extra tokens at end
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) EXTRA"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// Incomplete statement
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD")
|
||||
.is_err());
|
||||
|
||||
// Very long numbers
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 999999999999999999999 < (INT4, INT2)")
|
||||
.is_err());
|
||||
|
||||
// Multiple FOR clauses
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR SEARCH FOR ORDER BY sort_family")
|
||||
.is_err());
|
||||
|
||||
// FOR SEARCH with extra tokens
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR SEARCH EXTRA")
|
||||
.is_err());
|
||||
|
||||
// FOR ORDER BY with invalid sort family
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD OPERATOR 1 < (INT4, INT2) FOR ORDER BY 123invalid")
|
||||
.is_err());
|
||||
|
||||
// Function with empty operator types but missing function args parens
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 () func")
|
||||
.is_err());
|
||||
|
||||
// Function with mismatched parentheses
|
||||
assert!(pg()
|
||||
.parse_sql_statements(
|
||||
"ALTER OPERATOR FAMILY my_ops USING btree ADD FUNCTION 1 (INT4 func(INT2"
|
||||
)
|
||||
.is_err());
|
||||
|
||||
// DROP with empty types
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree DROP OPERATOR 1 ()")
|
||||
.is_err());
|
||||
|
||||
// DROP FUNCTION with empty types
|
||||
assert!(pg()
|
||||
.parse_sql_statements("ALTER OPERATOR FAMILY my_ops USING btree DROP FUNCTION 1 ()")
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_drop_operator_family() {
|
||||
for if_exists in [true, false] {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue