Skip to content

Commit 1b2598b

Browse files
Merge branch 'operator-extension' into future-main2
2 parents c710a30 + 994344d commit 1b2598b

File tree

6 files changed

+710
-9
lines changed

6 files changed

+710
-9
lines changed

src/ast/ddl.rs

Lines changed: 237 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@
1919
//! (commonly referred to as Data Definition Language, or DDL)
2020
2121
#[cfg(not(feature = "std"))]
22-
use alloc::{boxed::Box, format, string::String, vec, vec::Vec};
22+
use alloc::{
23+
boxed::Box,
24+
format,
25+
string::{String, ToString},
26+
vec,
27+
vec::Vec,
28+
};
2329
use core::fmt::{self, Display, Write};
2430

2531
#[cfg(feature = "serde")]
@@ -3926,3 +3932,233 @@ impl Spanned for DropFunction {
39263932
Span::empty()
39273933
}
39283934
}
3935+
3936+
/// CREATE OPERATOR statement
3937+
/// See <https://www.postgresql.org/docs/current/sql-createoperator.html>
3938+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3939+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3940+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3941+
pub struct CreateOperator {
3942+
/// Operator name (can be schema-qualified)
3943+
pub name: ObjectName,
3944+
/// FUNCTION or PROCEDURE parameter (function name)
3945+
pub function: ObjectName,
3946+
/// Whether PROCEDURE keyword was used (vs FUNCTION)
3947+
pub is_procedure: bool,
3948+
/// LEFTARG parameter (left operand type)
3949+
pub left_arg: Option<DataType>,
3950+
/// RIGHTARG parameter (right operand type)
3951+
pub right_arg: Option<DataType>,
3952+
/// COMMUTATOR parameter (commutator operator)
3953+
pub commutator: Option<ObjectName>,
3954+
/// NEGATOR parameter (negator operator)
3955+
pub negator: Option<ObjectName>,
3956+
/// RESTRICT parameter (restriction selectivity function)
3957+
pub restrict: Option<ObjectName>,
3958+
/// JOIN parameter (join selectivity function)
3959+
pub join: Option<ObjectName>,
3960+
/// HASHES flag
3961+
pub hashes: bool,
3962+
/// MERGES flag
3963+
pub merges: bool,
3964+
}
3965+
3966+
/// CREATE OPERATOR FAMILY statement
3967+
/// See <https://www.postgresql.org/docs/current/sql-createopfamily.html>
3968+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3969+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3970+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3971+
pub struct CreateOperatorFamily {
3972+
/// Operator family name (can be schema-qualified)
3973+
pub name: ObjectName,
3974+
/// Index method (btree, hash, gist, gin, etc.)
3975+
pub using: Ident,
3976+
}
3977+
3978+
/// CREATE OPERATOR CLASS statement
3979+
/// See <https://www.postgresql.org/docs/current/sql-createopclass.html>
3980+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3981+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3982+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3983+
pub struct CreateOperatorClass {
3984+
/// Operator class name (can be schema-qualified)
3985+
pub name: ObjectName,
3986+
/// Whether this is the default operator class for the type
3987+
pub default: bool,
3988+
/// The data type
3989+
pub for_type: DataType,
3990+
/// Index method (btree, hash, gist, gin, etc.)
3991+
pub using: Ident,
3992+
/// Optional operator family name
3993+
pub family: Option<ObjectName>,
3994+
/// List of operator class items (operators, functions, storage)
3995+
pub items: Vec<OperatorClassItem>,
3996+
}
3997+
3998+
impl fmt::Display for CreateOperator {
3999+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4000+
write!(f, "CREATE OPERATOR {} (", self.name)?;
4001+
4002+
let function_keyword = if self.is_procedure {
4003+
"PROCEDURE"
4004+
} else {
4005+
"FUNCTION"
4006+
};
4007+
let mut params = vec![format!("{} = {}", function_keyword, self.function)];
4008+
4009+
if let Some(left_arg) = &self.left_arg {
4010+
params.push(format!("LEFTARG = {}", left_arg));
4011+
}
4012+
if let Some(right_arg) = &self.right_arg {
4013+
params.push(format!("RIGHTARG = {}", right_arg));
4014+
}
4015+
if let Some(commutator) = &self.commutator {
4016+
params.push(format!("COMMUTATOR = {}", commutator));
4017+
}
4018+
if let Some(negator) = &self.negator {
4019+
params.push(format!("NEGATOR = {}", negator));
4020+
}
4021+
if let Some(restrict) = &self.restrict {
4022+
params.push(format!("RESTRICT = {}", restrict));
4023+
}
4024+
if let Some(join) = &self.join {
4025+
params.push(format!("JOIN = {}", join));
4026+
}
4027+
if self.hashes {
4028+
params.push("HASHES".to_string());
4029+
}
4030+
if self.merges {
4031+
params.push("MERGES".to_string());
4032+
}
4033+
4034+
write!(f, "{}", params.join(", "))?;
4035+
write!(f, ")")
4036+
}
4037+
}
4038+
4039+
impl fmt::Display for CreateOperatorFamily {
4040+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4041+
write!(
4042+
f,
4043+
"CREATE OPERATOR FAMILY {} USING {}",
4044+
self.name, self.using
4045+
)
4046+
}
4047+
}
4048+
4049+
impl fmt::Display for CreateOperatorClass {
4050+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4051+
write!(f, "CREATE OPERATOR CLASS {}", self.name)?;
4052+
if self.default {
4053+
write!(f, " DEFAULT")?;
4054+
}
4055+
write!(f, " FOR TYPE {} USING {}", self.for_type, self.using)?;
4056+
if let Some(family) = &self.family {
4057+
write!(f, " FAMILY {}", family)?;
4058+
}
4059+
write!(f, " AS {}", display_comma_separated(&self.items))
4060+
}
4061+
}
4062+
4063+
/// Operator argument types for CREATE OPERATOR CLASS
4064+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4065+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4066+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4067+
pub struct OperatorArgTypes {
4068+
pub left: DataType,
4069+
pub right: DataType,
4070+
}
4071+
4072+
impl fmt::Display for OperatorArgTypes {
4073+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4074+
write!(f, "{}, {}", self.left, self.right)
4075+
}
4076+
}
4077+
4078+
/// An item in a CREATE OPERATOR CLASS statement
4079+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4080+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4081+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4082+
pub enum OperatorClassItem {
4083+
/// OPERATOR clause
4084+
Operator {
4085+
strategy_number: u32,
4086+
operator_name: ObjectName,
4087+
/// Optional operator argument types
4088+
op_types: Option<OperatorArgTypes>,
4089+
/// FOR SEARCH or FOR ORDER BY
4090+
purpose: Option<OperatorPurpose>,
4091+
},
4092+
/// FUNCTION clause
4093+
Function {
4094+
support_number: u32,
4095+
/// Optional function argument types for the operator class
4096+
op_types: Option<Vec<DataType>>,
4097+
function_name: ObjectName,
4098+
/// Function argument types
4099+
argument_types: Vec<DataType>,
4100+
},
4101+
/// STORAGE clause
4102+
Storage { storage_type: DataType },
4103+
}
4104+
4105+
/// Purpose of an operator in an operator class
4106+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4107+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4108+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4109+
pub enum OperatorPurpose {
4110+
ForSearch,
4111+
ForOrderBy { sort_family: ObjectName },
4112+
}
4113+
4114+
impl fmt::Display for OperatorClassItem {
4115+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4116+
match self {
4117+
OperatorClassItem::Operator {
4118+
strategy_number,
4119+
operator_name,
4120+
op_types,
4121+
purpose,
4122+
} => {
4123+
write!(f, "OPERATOR {strategy_number} {operator_name}")?;
4124+
if let Some(types) = op_types {
4125+
write!(f, " ({types})")?;
4126+
}
4127+
if let Some(purpose) = purpose {
4128+
write!(f, " {purpose}")?;
4129+
}
4130+
Ok(())
4131+
}
4132+
OperatorClassItem::Function {
4133+
support_number,
4134+
op_types,
4135+
function_name,
4136+
argument_types,
4137+
} => {
4138+
write!(f, "FUNCTION {support_number}")?;
4139+
if let Some(types) = op_types {
4140+
write!(f, " ({})", display_comma_separated(types))?;
4141+
}
4142+
write!(f, " {function_name}")?;
4143+
if !argument_types.is_empty() {
4144+
write!(f, "({})", display_comma_separated(argument_types))?;
4145+
}
4146+
Ok(())
4147+
}
4148+
OperatorClassItem::Storage { storage_type } => {
4149+
write!(f, "STORAGE {storage_type}")
4150+
}
4151+
}
4152+
}
4153+
}
4154+
4155+
impl fmt::Display for OperatorPurpose {
4156+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4157+
match self {
4158+
OperatorPurpose::ForSearch => write!(f, "FOR SEARCH"),
4159+
OperatorPurpose::ForOrderBy { sort_family } => {
4160+
write!(f, "FOR ORDER BY {sort_family}")
4161+
}
4162+
}
4163+
}
4164+
}

src/ast/mod.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,14 @@ pub use self::ddl::{
6565
AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue, ClusteredBy, ColumnDef,
6666
ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy, ColumnPolicyProperty,
6767
ConstraintCharacteristics, CreateConnector, CreateDomain, CreateExtension, CreateFunction,
68-
CreateIndex, CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial,
69-
DropBehavior, DropExtension, DropFunction, DropTrigger, GeneratedAs, GeneratedExpressionMode,
70-
IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
71-
IdentityPropertyOrder, IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck,
72-
NullsDistinctOption, Owner, Partition, ProcedureParam, ReferentialAction, RenameTableNameKind,
73-
ReplicaIdentity, TagsColumnOption, TriggerObjectKind, Truncate,
74-
UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
68+
CreateIndex, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreateTable,
69+
CreateTrigger, CreateView, Deduplicate, DeferrableInitial, DropBehavior, DropExtension,
70+
DropFunction, DropTrigger, GeneratedAs, GeneratedExpressionMode, IdentityParameters,
71+
IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind, IdentityPropertyOrder,
72+
IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck, NullsDistinctOption,
73+
OperatorArgTypes, OperatorClassItem, OperatorPurpose, Owner, Partition, ProcedureParam,
74+
ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption, TriggerObjectKind,
75+
Truncate, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
7576
UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
7677
UserDefinedTypeStorage, ViewColumnDef,
7778
};
@@ -3337,6 +3338,21 @@ pub enum Statement {
33373338
/// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-CreateDataConnectorCreateConnector)
33383339
CreateConnector(CreateConnector),
33393340
/// ```sql
3341+
/// CREATE OPERATOR
3342+
/// ```
3343+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createoperator.html)
3344+
CreateOperator(CreateOperator),
3345+
/// ```sql
3346+
/// CREATE OPERATOR FAMILY
3347+
/// ```
3348+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopfamily.html)
3349+
CreateOperatorFamily(CreateOperatorFamily),
3350+
/// ```sql
3351+
/// CREATE OPERATOR CLASS
3352+
/// ```
3353+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopclass.html)
3354+
CreateOperatorClass(CreateOperatorClass),
3355+
/// ```sql
33403356
/// ALTER TABLE
33413357
/// ```
33423358
AlterTable(AlterTable),
@@ -4883,6 +4899,11 @@ impl fmt::Display for Statement {
48834899
Ok(())
48844900
}
48854901
Statement::CreateConnector(create_connector) => create_connector.fmt(f),
4902+
Statement::CreateOperator(create_operator) => create_operator.fmt(f),
4903+
Statement::CreateOperatorFamily(create_operator_family) => {
4904+
create_operator_family.fmt(f)
4905+
}
4906+
Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
48864907
Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
48874908
Statement::AlterIndex { name, operation } => {
48884909
write!(f, "ALTER INDEX {name} {operation}")

src/ast/spans.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717

1818
use crate::ast::{
1919
ddl::AlterSchema, query::SelectItemQualifiedWildcardKind, AlterSchemaOperation, AlterTable,
20-
ColumnOptions, CreateView, ExportData, Owner, TypedString,
20+
ColumnOptions, CreateOperator, CreateOperatorClass, CreateOperatorFamily, CreateView,
21+
ExportData, Owner, TypedString,
2122
};
2223
use core::iter;
2324

@@ -367,6 +368,11 @@ impl Spanned for Statement {
367368
Statement::CreateSecret { .. } => Span::empty(),
368369
Statement::CreateServer { .. } => Span::empty(),
369370
Statement::CreateConnector { .. } => Span::empty(),
371+
Statement::CreateOperator(create_operator) => create_operator.span(),
372+
Statement::CreateOperatorFamily(create_operator_family) => {
373+
create_operator_family.span()
374+
}
375+
Statement::CreateOperatorClass(create_operator_class) => create_operator_class.span(),
370376
Statement::AlterTable(alter_table) => alter_table.span(),
371377
Statement::AlterIndex { name, operation } => name.span().union(&operation.span()),
372378
Statement::AlterView {
@@ -2345,6 +2351,24 @@ impl Spanned for AlterTable {
23452351
}
23462352
}
23472353

2354+
impl Spanned for CreateOperator {
2355+
fn span(&self) -> Span {
2356+
Span::empty()
2357+
}
2358+
}
2359+
2360+
impl Spanned for CreateOperatorFamily {
2361+
fn span(&self) -> Span {
2362+
Span::empty()
2363+
}
2364+
}
2365+
2366+
impl Spanned for CreateOperatorClass {
2367+
fn span(&self) -> Span {
2368+
Span::empty()
2369+
}
2370+
}
2371+
23482372
#[cfg(test)]
23492373
pub mod tests {
23502374
use crate::dialect::{Dialect, GenericDialect, SnowflakeDialect};

0 commit comments

Comments
 (0)