Skip to content

Commit d6a6a44

Browse files
Added support for CREATE OPERATOR * statements
1 parent 308a723 commit d6a6a44

File tree

6 files changed

+692
-15
lines changed

6 files changed

+692
-15
lines changed

src/ast/ddl.rs

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3613,3 +3613,233 @@ impl Spanned for DropFunction {
36133613
Span::empty()
36143614
}
36153615
}
3616+
3617+
/// CREATE OPERATOR statement
3618+
/// See <https://www.postgresql.org/docs/current/sql-createoperator.html>
3619+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3620+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3621+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3622+
pub struct CreateOperator {
3623+
/// Operator name (can be schema-qualified)
3624+
pub name: ObjectName,
3625+
/// FUNCTION or PROCEDURE parameter (function name)
3626+
pub function: ObjectName,
3627+
/// Whether PROCEDURE keyword was used (vs FUNCTION)
3628+
pub is_procedure: bool,
3629+
/// LEFTARG parameter (left operand type)
3630+
pub left_arg: Option<DataType>,
3631+
/// RIGHTARG parameter (right operand type)
3632+
pub right_arg: Option<DataType>,
3633+
/// COMMUTATOR parameter (commutator operator)
3634+
pub commutator: Option<ObjectName>,
3635+
/// NEGATOR parameter (negator operator)
3636+
pub negator: Option<ObjectName>,
3637+
/// RESTRICT parameter (restriction selectivity function)
3638+
pub restrict: Option<ObjectName>,
3639+
/// JOIN parameter (join selectivity function)
3640+
pub join: Option<ObjectName>,
3641+
/// HASHES flag
3642+
pub hashes: bool,
3643+
/// MERGES flag
3644+
pub merges: bool,
3645+
}
3646+
3647+
/// CREATE OPERATOR FAMILY statement
3648+
/// See <https://www.postgresql.org/docs/current/sql-createopfamily.html>
3649+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3650+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3651+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3652+
pub struct CreateOperatorFamily {
3653+
/// Operator family name (can be schema-qualified)
3654+
pub name: ObjectName,
3655+
/// Index method (btree, hash, gist, gin, etc.)
3656+
pub using: Ident,
3657+
}
3658+
3659+
/// CREATE OPERATOR CLASS statement
3660+
/// See <https://www.postgresql.org/docs/current/sql-createopclass.html>
3661+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3662+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3663+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3664+
pub struct CreateOperatorClass {
3665+
/// Operator class name (can be schema-qualified)
3666+
pub name: ObjectName,
3667+
/// Whether this is the default operator class for the type
3668+
pub default: bool,
3669+
/// The data type
3670+
pub for_type: DataType,
3671+
/// Index method (btree, hash, gist, gin, etc.)
3672+
pub using: Ident,
3673+
/// Optional operator family name
3674+
pub family: Option<ObjectName>,
3675+
/// List of operator class items (operators, functions, storage)
3676+
pub items: Vec<OperatorClassItem>,
3677+
}
3678+
3679+
impl fmt::Display for CreateOperator {
3680+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3681+
write!(f, "CREATE OPERATOR {} (", self.name)?;
3682+
3683+
let function_keyword = if self.is_procedure {
3684+
"PROCEDURE"
3685+
} else {
3686+
"FUNCTION"
3687+
};
3688+
let mut params = vec![format!("{} = {}", function_keyword, self.function)];
3689+
3690+
if let Some(left_arg) = &self.left_arg {
3691+
params.push(format!("LEFTARG = {}", left_arg));
3692+
}
3693+
if let Some(right_arg) = &self.right_arg {
3694+
params.push(format!("RIGHTARG = {}", right_arg));
3695+
}
3696+
if let Some(commutator) = &self.commutator {
3697+
params.push(format!("COMMUTATOR = {}", commutator));
3698+
}
3699+
if let Some(negator) = &self.negator {
3700+
params.push(format!("NEGATOR = {}", negator));
3701+
}
3702+
if let Some(restrict) = &self.restrict {
3703+
params.push(format!("RESTRICT = {}", restrict));
3704+
}
3705+
if let Some(join) = &self.join {
3706+
params.push(format!("JOIN = {}", join));
3707+
}
3708+
if self.hashes {
3709+
params.push("HASHES".to_string());
3710+
}
3711+
if self.merges {
3712+
params.push("MERGES".to_string());
3713+
}
3714+
3715+
write!(f, "{}", params.join(", "))?;
3716+
write!(f, ")")
3717+
}
3718+
}
3719+
3720+
impl fmt::Display for CreateOperatorFamily {
3721+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3722+
write!(
3723+
f,
3724+
"CREATE OPERATOR FAMILY {} USING {}",
3725+
self.name, self.using
3726+
)
3727+
}
3728+
}
3729+
3730+
impl fmt::Display for CreateOperatorClass {
3731+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3732+
write!(f, "CREATE OPERATOR CLASS {}", self.name)?;
3733+
if self.default {
3734+
write!(f, " DEFAULT")?;
3735+
}
3736+
write!(f, " FOR TYPE {} USING {}", self.for_type, self.using)?;
3737+
if let Some(family) = &self.family {
3738+
write!(f, " FAMILY {}", family)?;
3739+
}
3740+
write!(f, " AS {}", display_comma_separated(&self.items))
3741+
}
3742+
}
3743+
3744+
/// Operator argument types for CREATE OPERATOR CLASS
3745+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3746+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3747+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3748+
pub struct OperatorArgTypes {
3749+
pub left: DataType,
3750+
pub right: DataType,
3751+
}
3752+
3753+
impl fmt::Display for OperatorArgTypes {
3754+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3755+
write!(f, "{}, {}", self.left, self.right)
3756+
}
3757+
}
3758+
3759+
/// An item in a CREATE OPERATOR CLASS statement
3760+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3761+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3762+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3763+
pub enum OperatorClassItem {
3764+
/// OPERATOR clause
3765+
Operator {
3766+
strategy_number: u32,
3767+
operator_name: ObjectName,
3768+
/// Optional operator argument types
3769+
op_types: Option<OperatorArgTypes>,
3770+
/// FOR SEARCH or FOR ORDER BY
3771+
purpose: Option<OperatorPurpose>,
3772+
},
3773+
/// FUNCTION clause
3774+
Function {
3775+
support_number: u32,
3776+
/// Optional function argument types for the operator class
3777+
op_types: Option<Vec<DataType>>,
3778+
function_name: ObjectName,
3779+
/// Function argument types
3780+
argument_types: Vec<DataType>,
3781+
},
3782+
/// STORAGE clause
3783+
Storage { storage_type: DataType },
3784+
}
3785+
3786+
/// Purpose of an operator in an operator class
3787+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3788+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3789+
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3790+
pub enum OperatorPurpose {
3791+
ForSearch,
3792+
ForOrderBy { sort_family: ObjectName },
3793+
}
3794+
3795+
impl fmt::Display for OperatorClassItem {
3796+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3797+
match self {
3798+
OperatorClassItem::Operator {
3799+
strategy_number,
3800+
operator_name,
3801+
op_types,
3802+
purpose,
3803+
} => {
3804+
write!(f, "OPERATOR {strategy_number} {operator_name}")?;
3805+
if let Some(types) = op_types {
3806+
write!(f, " ({types})")?;
3807+
}
3808+
if let Some(purpose) = purpose {
3809+
write!(f, " {purpose}")?;
3810+
}
3811+
Ok(())
3812+
}
3813+
OperatorClassItem::Function {
3814+
support_number,
3815+
op_types,
3816+
function_name,
3817+
argument_types,
3818+
} => {
3819+
write!(f, "FUNCTION {support_number}")?;
3820+
if let Some(types) = op_types {
3821+
write!(f, " ({})", display_comma_separated(types))?;
3822+
}
3823+
write!(f, " {function_name}")?;
3824+
if !argument_types.is_empty() {
3825+
write!(f, "({})", display_comma_separated(argument_types))?;
3826+
}
3827+
Ok(())
3828+
}
3829+
OperatorClassItem::Storage { storage_type } => {
3830+
write!(f, "STORAGE {storage_type}")
3831+
}
3832+
}
3833+
}
3834+
}
3835+
3836+
impl fmt::Display for OperatorPurpose {
3837+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3838+
match self {
3839+
OperatorPurpose::ForSearch => write!(f, "FOR SEARCH"),
3840+
OperatorPurpose::ForOrderBy { sort_family } => {
3841+
write!(f, "FOR ORDER BY {sort_family}")
3842+
}
3843+
}
3844+
}
3845+
}

src/ast/mod.rs

Lines changed: 30 additions & 14 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, UserDefinedTypeRepresentation, ViewColumnDef,
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, UserDefinedTypeRepresentation, ViewColumnDef,
7576
};
7677
pub use self::dml::{Delete, Insert, Update};
7778
pub use self::operator::{BinaryOperator, UnaryOperator};
@@ -2787,10 +2788,11 @@ impl fmt::Display for Declare {
27872788
}
27882789

27892790
/// Sql options of a `CREATE TABLE` statement.
2790-
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2791+
#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
27912792
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
27922793
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
27932794
pub enum CreateTableOptions {
2795+
#[default]
27942796
None,
27952797
/// Options specified using the `WITH` keyword.
27962798
/// e.g. `WITH (description = "123")`
@@ -2819,12 +2821,6 @@ pub enum CreateTableOptions {
28192821
TableProperties(Vec<SqlOption>),
28202822
}
28212823

2822-
impl Default for CreateTableOptions {
2823-
fn default() -> Self {
2824-
Self::None
2825-
}
2826-
}
2827-
28282824
impl fmt::Display for CreateTableOptions {
28292825
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28302826
match self {
@@ -3340,6 +3336,21 @@ pub enum Statement {
33403336
/// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-CreateDataConnectorCreateConnector)
33413337
CreateConnector(CreateConnector),
33423338
/// ```sql
3339+
/// CREATE OPERATOR
3340+
/// ```
3341+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createoperator.html)
3342+
CreateOperator(CreateOperator),
3343+
/// ```sql
3344+
/// CREATE OPERATOR FAMILY
3345+
/// ```
3346+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopfamily.html)
3347+
CreateOperatorFamily(CreateOperatorFamily),
3348+
/// ```sql
3349+
/// CREATE OPERATOR CLASS
3350+
/// ```
3351+
/// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopclass.html)
3352+
CreateOperatorClass(CreateOperatorClass),
3353+
/// ```sql
33433354
/// ALTER TABLE
33443355
/// ```
33453356
AlterTable(AlterTable),
@@ -4886,6 +4897,11 @@ impl fmt::Display for Statement {
48864897
Ok(())
48874898
}
48884899
Statement::CreateConnector(create_connector) => create_connector.fmt(f),
4900+
Statement::CreateOperator(create_operator) => create_operator.fmt(f),
4901+
Statement::CreateOperatorFamily(create_operator_family) => {
4902+
create_operator_family.fmt(f)
4903+
}
4904+
Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
48894905
Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
48904906
Statement::AlterIndex { name, operation } => {
48914907
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 {
@@ -2536,3 +2542,21 @@ ALTER TABLE users
25362542
assert_eq!(stmt_span.end, (4, 11).into());
25372543
}
25382544
}
2545+
2546+
impl Spanned for CreateOperator {
2547+
fn span(&self) -> Span {
2548+
Span::empty()
2549+
}
2550+
}
2551+
2552+
impl Spanned for CreateOperatorFamily {
2553+
fn span(&self) -> Span {
2554+
Span::empty()
2555+
}
2556+
}
2557+
2558+
impl Spanned for CreateOperatorClass {
2559+
fn span(&self) -> Span {
2560+
Span::empty()
2561+
}
2562+
}

src/keywords.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ define_keywords!(
194194
CHECK,
195195
CHECKSUM,
196196
CIRCLE,
197+
CLASS,
197198
CLEANPATH,
198199
CLEAR,
199200
CLOB,
@@ -381,6 +382,7 @@ define_keywords!(
381382
FAIL,
382383
FAILOVER,
383384
FALSE,
385+
FAMILY,
384386
FETCH,
385387
FIELDS,
386388
FILE,

0 commit comments

Comments
 (0)