@@ -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+ }
0 commit comments