Skip to main content

qusql_parse/
operator.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13use alloc::vec::Vec;
14
15use crate::AlterTableOwner;
16use crate::alter_table::parse_alter_owner;
17use crate::qualified_name::parse_qualified_name_unreserved;
18use crate::{
19    CreateOption, DataType, QualifiedName, Span, Spanned, UsingIndexMethod,
20    data_type::{DataTypeContext, parse_data_type},
21    keywords::Keyword,
22    lexer::Token,
23    parser::{ParseError, Parser},
24};
25
26/// ALTER OPERATOR actions (OWNER TO, SET SCHEMA, SET (...))
27#[derive(Clone, Debug)]
28pub enum AlterOperatorAction<'a> {
29    /// OWNER TO new_owner
30    OwnerTo {
31        /// Span of OWNER TO keywords
32        owner_to_span: Span,
33        /// The new owner name
34        new_owner: crate::alter_table::AlterTableOwner<'a>,
35    },
36    /// SET SCHEMA new_schema
37    SetSchema {
38        /// Span of SET SCHEMA keywords
39        set_schema_span: Span,
40        /// The new schema name
41        new_schema: QualifiedName<'a>,
42    },
43    /// SET (option = value, ...)
44    SetOptions {
45        /// Span of SET keyword
46        set_span: Span,
47        /// List of options
48        options: Vec<OperatorOption<'a>>,
49    },
50}
51
52impl<'a> Spanned for AlterOperatorAction<'a> {
53    fn span(&self) -> Span {
54        match self {
55            AlterOperatorAction::OwnerTo {
56                owner_to_span,
57                new_owner,
58            } => owner_to_span.join_span(new_owner),
59            AlterOperatorAction::SetSchema {
60                set_schema_span,
61                new_schema,
62            } => set_schema_span.join_span(new_schema),
63            AlterOperatorAction::SetOptions { set_span, options } => set_span.join_span(options),
64        }
65    }
66}
67
68/// Left operator type for ALTER OPERATOR (explicitly stores NONE span or DataType)
69#[derive(Clone, Debug)]
70pub enum LeftOperatorType<'a> {
71    /// NONE keyword
72    None(Span),
73    /// Data type
74    DataType(DataType<'a>),
75}
76
77impl<'a> Spanned for LeftOperatorType<'a> {
78    fn span(&self) -> Span {
79        match self {
80            LeftOperatorType::None(span) => span.clone(),
81            LeftOperatorType::DataType(dt) => dt.span(),
82        }
83    }
84}
85
86/// ALTER OPERATOR statement (PostgreSQL)
87#[derive(Clone, Debug)]
88pub struct AlterOperator<'a> {
89    /// Span of "ALTER OPERATOR"
90    pub alter_operator_span: Span,
91    /// The operator name (e.g., +, -, @@, myschema.@@)
92    pub name: QualifiedName<'a>,
93    /// Left parenthesis span
94    pub lparen_span: Span,
95    /// Left operator type (either NONE or a data type)
96    pub left_type: LeftOperatorType<'a>,
97    /// Comma span
98    pub comma_span: Span,
99    /// Right operator type
100    pub right_type: DataType<'a>,
101    /// Right parenthesis span
102    pub rparen_span: Span,
103    /// ALTER OPERATOR action
104    pub action: AlterOperatorAction<'a>,
105}
106
107impl<'a> Spanned for AlterOperator<'a> {
108    fn span(&self) -> Span {
109        self.alter_operator_span
110            .join_span(&self.name)
111            .join_span(&self.lparen_span)
112            .join_span(&self.left_type)
113            .join_span(&self.comma_span)
114            .join_span(&self.right_type)
115            .join_span(&self.rparen_span)
116            .join_span(&self.action)
117    }
118}
119
120/// Parse ALTER OPERATOR statement
121pub(crate) fn parse_alter_operator<'a>(
122    parser: &mut Parser<'a, '_>,
123    alter_operator_span: Span,
124) -> Result<AlterOperator<'a>, ParseError> {
125    parser.postgres_only(&alter_operator_span);
126    let name = parse_operator_name(parser)?;
127    let lparen_span = parser.consume_token(Token::LParen)?;
128    let left_type = if let Some(none_span) = parser.skip_keyword(Keyword::NONE) {
129        LeftOperatorType::None(none_span)
130    } else {
131        LeftOperatorType::DataType(parse_data_type(parser, DataTypeContext::TypeRef)?)
132    };
133    let comma_span = parser.consume_token(Token::Comma)?;
134    let right_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
135    let rparen_span = parser.consume_token(Token::RParen)?;
136    let action = match &parser.token {
137        Token::Ident(_, Keyword::OWNER) => {
138            let owner_to_span = parser.consume_keywords(&[Keyword::OWNER, Keyword::TO])?;
139            let new_owner = parse_alter_owner(parser)?;
140            AlterOperatorAction::OwnerTo {
141                owner_to_span,
142                new_owner,
143            }
144        }
145        Token::Ident(_, Keyword::SET) => {
146            let set_span = parser.consume_keyword(Keyword::SET)?;
147            match &parser.token {
148                Token::Ident(_, Keyword::SCHEMA) => {
149                    let set_schema_span =
150                        set_span.join_span(&parser.consume_keyword(Keyword::SCHEMA)?);
151                    let new_schema = parse_qualified_name_unreserved(parser)?;
152                    AlterOperatorAction::SetSchema {
153                        set_schema_span,
154                        new_schema,
155                    }
156                }
157                Token::LParen => {
158                    let lparen2_span = parser.consume_token(Token::LParen)?;
159                    let options = parser.recovered(
160                        "'RESTRICT' | 'JOIN' | 'COMMUTATOR' | 'NEGATOR' | 'HASHES' | 'MERGES'",
161                        &|tok| matches!(tok, Token::RParen),
162                        |parser| {
163                            let mut options = Vec::new();
164                            loop {
165                                // Accept RESTRICT, JOIN, COMMUTATOR, NEGATOR, HASHES, MERGES
166                                let option = match &parser.token {
167                                    Token::Ident(_, Keyword::RESTRICT) => {
168                                        let keyword_span = parser.consume_keyword(Keyword::RESTRICT)?;
169                                        let eq_span = parser.consume_token(Token::Eq)?;
170                                        if parser.skip_keyword(Keyword::NONE).is_some() {
171                                            // NONE disables the estimator
172                                            OperatorOption::Restrict { restrict_span: keyword_span.clone(), eq_span: eq_span.clone(), function_name: QualifiedName { prefix: Vec::new(), identifier: crate::Identifier::new("NONE", eq_span) } }
173                                        } else {
174                                            let function_name = parse_qualified_name_unreserved(parser)?;
175                                            OperatorOption::Restrict { restrict_span: keyword_span, eq_span, function_name }
176                                        }
177                                    }
178                                    Token::Ident(_, Keyword::JOIN) => {
179                                        let keyword_span = parser.consume_keyword(Keyword::JOIN)?;
180                                        let eq_span = parser.consume_token(Token::Eq)?;
181                                        if parser.skip_keyword(Keyword::NONE).is_some() {
182                                            OperatorOption::Join { join_span: keyword_span.clone(), eq_span: eq_span.clone(), function_name: QualifiedName { prefix: Vec::new(), identifier: crate::Identifier::new("NONE", eq_span) } }
183                                        } else {
184                                            let function_name = parse_qualified_name_unreserved(parser)?;
185                                            OperatorOption::Join { join_span: keyword_span, eq_span, function_name }
186                                        }
187                                    }
188                                    Token::Ident(_, Keyword::COMMUTATOR) => {
189                                        let keyword_span = parser.consume_keyword(Keyword::COMMUTATOR)?;
190                                        let eq_span = parser.consume_token(Token::Eq)?;
191                                        let operator = parse_operator_ref(parser)?;
192                                        OperatorOption::Commutator { commutator_span: keyword_span, eq_span, operator }
193                                    }
194                                    Token::Ident(_, Keyword::NEGATOR) => {
195                                        let keyword_span = parser.consume_keyword(Keyword::NEGATOR)?;
196                                        let eq_span = parser.consume_token(Token::Eq)?;
197                                        let operator = parse_operator_ref(parser)?;
198                                        OperatorOption::Negator { negator_span: keyword_span, eq_span, operator }
199                                    }
200                                    Token::Ident(_, Keyword::HASHES) => {
201                                        OperatorOption::Hashes(parser.consume_keyword(Keyword::HASHES)?)
202                                    }
203                                    Token::Ident(_, Keyword::MERGES) => {
204                                        OperatorOption::Merges(parser.consume_keyword(Keyword::MERGES)?)
205                                    }
206                                    _ => parser.expected_failure("'RESTRICT' | 'JOIN' | 'COMMUTATOR' | 'NEGATOR' | 'HASHES' | 'MERGES'")?
207                                };
208                                options.push(option);
209                                if parser.skip_token(Token::Comma).is_none() {
210                                    break;
211                                }
212                            }
213                            Ok(options)
214                        },
215                    )?;
216                    let rparen2_span = parser.consume_token(Token::RParen)?;
217
218                    AlterOperatorAction::SetOptions {
219                        set_span: set_span.join_span(&lparen2_span).join_span(&rparen2_span),
220                        options,
221                    }
222                }
223                _ => parser.expected_failure("'SCHEMA' or '(' after SET")?,
224            }
225        }
226        _ => parser.expected_failure("'OWNER TO' or 'SET' after ALTER OPERATOR ...")?,
227    };
228    Ok(AlterOperator {
229        alter_operator_span,
230        name,
231        lparen_span,
232        left_type,
233        comma_span,
234        right_type,
235        rparen_span,
236        action,
237    })
238}
239
240///// ALTER OPERATOR CLASS actions (RENAME TO, OWNER TO, SET SCHEMA)
241#[derive(Clone, Debug)]
242pub enum AlterOperatorClassAction<'a> {
243    /// RENAME TO new_name
244    RenameTo {
245        /// Span of RENAME TO keywords
246        rename_to_span: Span,
247        /// The new operator class name
248        new_name: QualifiedName<'a>,
249    },
250    OwnerTo {
251        /// Span of OWNER TO keywords
252        owner_to_span: Span,
253        /// The new owner name
254        new_owner: AlterTableOwner<'a>,
255    },
256    SetSchema {
257        /// Span of SET SCHEMA keywords
258        set_schema_span: Span,
259        /// The new schema name
260        new_schema: QualifiedName<'a>,
261    },
262}
263
264impl<'a> Spanned for AlterOperatorClassAction<'a> {
265    fn span(&self) -> Span {
266        match self {
267            AlterOperatorClassAction::RenameTo {
268                rename_to_span,
269                new_name,
270            } => rename_to_span.join_span(new_name),
271            AlterOperatorClassAction::OwnerTo {
272                owner_to_span,
273                new_owner,
274            } => owner_to_span.join_span(new_owner),
275            AlterOperatorClassAction::SetSchema {
276                set_schema_span,
277                new_schema,
278            } => set_schema_span.join_span(new_schema),
279        }
280    }
281}
282
283/// ALTER OPERATOR CLASS statement (PostgreSQL)
284#[derive(Clone, Debug)]
285pub struct AlterOperatorClass<'a> {
286    /// Span of "ALTER OPERATOR CLASS"
287    pub alter_operator_class_span: Span,
288    /// The operator class name
289    pub name: QualifiedName<'a>,
290    /// The index method (btree, hash, gist, gin)
291    pub index_method: UsingIndexMethod,
292    /// The action (RENAME TO, OWNER TO, SET SCHEMA)
293    pub action: AlterOperatorClassAction<'a>,
294}
295
296impl<'a> Spanned for AlterOperatorClass<'a> {
297    fn span(&self) -> Span {
298        self.alter_operator_class_span
299            .join_span(&self.name)
300            .join_span(&self.index_method)
301            .join_span(&self.action)
302    }
303}
304
305/// Parse ALTER OPERATOR CLASS statement
306pub(crate) fn parse_alter_operator_class<'a>(
307    parser: &mut Parser<'a, '_>,
308    alter_operator_class_span: Span,
309) -> Result<AlterOperatorClass<'a>, ParseError> {
310    parser.postgres_only(&alter_operator_class_span);
311    let name = parse_qualified_name_unreserved(parser)?;
312    let using_span = parser.consume_keyword(Keyword::USING)?;
313    let index_method = crate::create_index::parse_using_index_method(parser, using_span)?;
314    let action = match &parser.token {
315        Token::Ident(_, Keyword::RENAME) => {
316            let rename_to_span = parser.consume_keywords(&[Keyword::RENAME, Keyword::TO])?;
317            let new_name = parse_qualified_name_unreserved(parser)?;
318            AlterOperatorClassAction::RenameTo {
319                rename_to_span,
320                new_name,
321            }
322        }
323        Token::Ident(_, Keyword::OWNER) => {
324            let owner_to_span = parser.consume_keywords(&[Keyword::OWNER, Keyword::TO])?;
325            let new_owner = parse_alter_owner(parser)?;
326            AlterOperatorClassAction::OwnerTo {
327                owner_to_span,
328                new_owner,
329            }
330        }
331        Token::Ident(_, Keyword::SET) => {
332            let set_schema_span = parser.consume_keywords(&[Keyword::SET, Keyword::SCHEMA])?;
333            let new_schema = parse_qualified_name_unreserved(parser)?;
334            AlterOperatorClassAction::SetSchema {
335                set_schema_span,
336                new_schema,
337            }
338        }
339        _ => parser.expected_failure("'RENAME', 'OWNER', or 'SET SCHEMA'")?,
340    };
341    Ok(AlterOperatorClass {
342        alter_operator_class_span,
343        name,
344        index_method,
345        action,
346    })
347}
348
349/// CREATE OPERATOR statement (PostgreSQL)
350#[derive(Clone, Debug)]
351pub struct CreateOperator<'a> {
352    /// Span of "CREATE OPERATOR"
353    pub create_operator_span: Span,
354    /// The operator name (e.g., +, -, @@, myschema.@@)
355    pub name: QualifiedName<'a>,
356    /// Left parenthesis span
357    pub lparen_span: Span,
358    /// Operator options
359    pub options: Vec<OperatorOption<'a>>,
360    /// Right parenthesis span
361    pub rparen_span: Span,
362}
363
364impl<'a> Spanned for CreateOperator<'a> {
365    fn span(&self) -> Span {
366        self.create_operator_span
367            .join_span(&self.name)
368            .join_span(&self.lparen_span)
369            .join_span(&self.options)
370            .join_span(&self.rparen_span)
371    }
372}
373
374/// Options for CREATE OPERATOR
375#[derive(Clone, Debug)]
376pub enum OperatorOption<'a> {
377    /// FUNCTION = function_name
378    Function {
379        /// Span of FUNCTION keyword
380        function_span: Span,
381        /// Span of equal sign
382        eq_span: Span,
383        /// The function name that implements the operator
384        function_name: QualifiedName<'a>,
385    },
386    /// PROCEDURE = procedure_name (synonym for FUNCTION)
387    Procedure {
388        /// Span of PROCEDURE keyword
389        procedure_span: Span,
390        /// Span of equal sign
391        eq_span: Span,
392        /// The procedure name that implements the operator
393        procedure_name: QualifiedName<'a>,
394    },
395    /// LEFTARG = type
396    LeftArg {
397        /// Span of LEFTARG keyword
398        leftarg_span: Span,
399        /// Span of equal sign
400        eq_span: Span,
401        /// The data type of the left argument (or NONE)
402        arg_type: DataType<'a>,
403    },
404    /// RIGHTARG = type
405    RightArg {
406        /// Span of RIGHTARG keyword
407        rightarg_span: Span,
408        /// Span of equal sign
409        eq_span: Span,
410        /// The data type of the right argument (or NONE)
411        arg_type: DataType<'a>,
412    },
413    /// COMMUTATOR = operator or COMMUTATOR = OPERATOR(operator)
414    Commutator {
415        /// Span of COMMUTATOR keyword
416        commutator_span: Span,
417        /// Span of equal sign
418        eq_span: Span,
419        /// The commutator operator (the operator that gives the same result when left and right arguments are swapped)
420        operator: OperatorRef<'a>,
421    },
422    /// NEGATOR = operator or NEGATOR = OPERATOR(operator)
423    Negator {
424        /// Span of NEGATOR keyword
425        negator_span: Span,
426        /// Span of equal sign
427        eq_span: Span,
428        /// The negator operator (the operator that gives the negated result of the original operator)
429        operator: OperatorRef<'a>,
430    },
431    /// RESTRICT = function
432    Restrict {
433        /// Span of RESTRICT keyword
434        restrict_span: Span,
435        /// Span of equal sign
436        eq_span: Span,
437        /// The function name that implements the selectivity estimator for the operator
438        function_name: QualifiedName<'a>,
439    },
440    /// RESTRICT = NONE
441    RestrictNone {
442        /// Span of RESTRICT keyword
443        restrict_span: Span,
444        /// Span of equal sign
445        eq_span: Span,
446        /// Span of NONE keyword
447        none_span: Span,
448    },
449    /// JOIN = function
450    Join {
451        /// Span of JOIN keyword
452        join_span: Span,
453        /// Span of equal sign
454        eq_span: Span,
455        /// The function name that implements the join selectivity estimator for the operator
456        function_name: QualifiedName<'a>,
457    },
458    /// JOIN = NONE
459    JoinNone {
460        /// Span of JOIN keyword
461        join_span: Span,
462        /// Span of equal sign
463        eq_span: Span,
464        /// Span of NONE keyword
465        none_span: Span,
466    },
467    /// HASHES
468    Hashes(Span),
469    /// MERGES
470    Merges(Span),
471}
472
473impl<'a> Spanned for OperatorOption<'a> {
474    fn span(&self) -> Span {
475        match self {
476            OperatorOption::Function {
477                function_span,
478                eq_span,
479                function_name,
480            } => function_span.join_span(eq_span).join_span(function_name),
481            OperatorOption::Procedure {
482                procedure_span,
483                eq_span,
484                procedure_name,
485            } => procedure_span.join_span(eq_span).join_span(procedure_name),
486            OperatorOption::LeftArg {
487                leftarg_span,
488                eq_span,
489                arg_type,
490            } => leftarg_span.join_span(eq_span).join_span(arg_type),
491            OperatorOption::RightArg {
492                rightarg_span,
493                eq_span,
494                arg_type,
495            } => rightarg_span.join_span(eq_span).join_span(arg_type),
496            OperatorOption::Commutator {
497                commutator_span,
498                eq_span,
499                operator,
500            } => commutator_span.join_span(eq_span).join_span(operator),
501            OperatorOption::Negator {
502                negator_span,
503                eq_span,
504                operator,
505            } => negator_span.join_span(eq_span).join_span(operator),
506            OperatorOption::Restrict {
507                restrict_span,
508                eq_span,
509                function_name,
510            } => restrict_span.join_span(eq_span).join_span(function_name),
511            OperatorOption::RestrictNone {
512                restrict_span,
513                eq_span,
514                none_span,
515            } => restrict_span.join_span(eq_span).join_span(none_span),
516            OperatorOption::Join {
517                join_span,
518                eq_span,
519                function_name,
520            } => join_span.join_span(eq_span).join_span(function_name),
521            OperatorOption::JoinNone {
522                join_span,
523                eq_span,
524                none_span,
525            } => join_span.join_span(eq_span).join_span(none_span),
526            OperatorOption::Hashes(span) => span.clone(),
527            OperatorOption::Merges(span) => span.clone(),
528        }
529    }
530}
531
532/// Reference to an operator
533#[derive(Clone, Debug)]
534pub enum OperatorRef<'a> {
535    /// Simple operator reference (e.g., >)
536    Simple(QualifiedName<'a>),
537    /// OPERATOR(operator_name) syntax
538    Wrapped {
539        operator_span: Span,
540        lparen_span: Span,
541        operator_name: QualifiedName<'a>,
542        rparen_span: Span,
543    },
544}
545
546impl<'a> Spanned for OperatorRef<'a> {
547    fn span(&self) -> Span {
548        match self {
549            OperatorRef::Simple(name) => name.span(),
550            OperatorRef::Wrapped {
551                operator_span,
552                rparen_span,
553                ..
554            } => operator_span.join_span(rparen_span),
555        }
556    }
557}
558
559pub(crate) fn parse_create_operator<'a>(
560    parser: &mut Parser<'a, '_>,
561    create_operator_span: Span,
562    create_options: Vec<crate::create_option::CreateOption<'a>>,
563) -> Result<CreateOperator<'a>, ParseError> {
564    parser.postgres_only(&create_operator_span);
565
566    // Report errors for unsupported create options
567    for option in create_options {
568        parser.err("Not supported for CREATE OPERATOR", &option.span());
569    }
570
571    // Parse operator name (can be a qualified name with schema or an operator symbol)
572    // Operators can be symbols like +, -, @@, !=, or schema-qualified like myschema.@@
573    let name = parse_operator_name(parser)?;
574
575    // Parse options in parentheses
576    let lparen_span = parser.consume_token(Token::LParen)?;
577
578    let mut options = Vec::new();
579
580    // Handle empty operator definition (requires at least FUNCTION or PROCEDURE)
581    if let Some(rparen_span) = parser.skip_token(Token::RParen) {
582        parser.err(
583            "CREATE OPERATOR requires at least a FUNCTION or PROCEDURE option",
584            &lparen_span.join_span(&rparen_span),
585        );
586        return Ok(CreateOperator {
587            create_operator_span,
588            name,
589            lparen_span,
590            options,
591            rparen_span,
592        });
593    }
594
595    // Parse operator options
596    loop {
597        let option = match &parser.token {
598            Token::Ident(_, Keyword::FUNCTION) => {
599                let keyword_span = parser.consume_keyword(Keyword::FUNCTION)?;
600                let eq_span = parser.consume_token(Token::Eq)?;
601                let function_name = parse_qualified_name_unreserved(parser)?;
602                OperatorOption::Function {
603                    function_span: keyword_span,
604                    eq_span,
605                    function_name,
606                }
607            }
608            Token::Ident(_, Keyword::PROCEDURE) => {
609                let keyword_span = parser.consume_keyword(Keyword::PROCEDURE)?;
610                let eq_span = parser.consume_token(Token::Eq)?;
611                let procedure_name = parse_qualified_name_unreserved(parser)?;
612                OperatorOption::Procedure {
613                    procedure_span: keyword_span,
614                    eq_span,
615                    procedure_name,
616                }
617            }
618            Token::Ident(_, Keyword::LEFTARG) => {
619                let keyword_span = parser.consume_keyword(Keyword::LEFTARG)?;
620                let eq_span = parser.consume_token(Token::Eq)?;
621                let arg_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
622                OperatorOption::LeftArg {
623                    leftarg_span: keyword_span,
624                    eq_span,
625                    arg_type,
626                }
627            }
628            Token::Ident(_, Keyword::RIGHTARG) => {
629                let keyword_span = parser.consume_keyword(Keyword::RIGHTARG)?;
630                let eq_span = parser.consume_token(Token::Eq)?;
631                let arg_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
632                OperatorOption::RightArg {
633                    rightarg_span: keyword_span,
634                    eq_span,
635                    arg_type,
636                }
637            }
638            Token::Ident(_, Keyword::COMMUTATOR) => {
639                let keyword_span = parser.consume_keyword(Keyword::COMMUTATOR)?;
640                let eq_span = parser.consume_token(Token::Eq)?;
641                let operator = parse_operator_ref(parser)?;
642                OperatorOption::Commutator {
643                    commutator_span: keyword_span,
644                    eq_span,
645                    operator,
646                }
647            }
648            Token::Ident(_, Keyword::NEGATOR) => {
649                let keyword_span = parser.consume_keyword(Keyword::NEGATOR)?;
650                let eq_span = parser.consume_token(Token::Eq)?;
651                let operator = parse_operator_ref(parser)?;
652                OperatorOption::Negator {
653                    negator_span: keyword_span,
654                    eq_span,
655                    operator,
656                }
657            }
658            Token::Ident(_, Keyword::RESTRICT) => {
659                let keyword_span = parser.consume_keyword(Keyword::RESTRICT)?;
660                let eq_span = parser.consume_token(Token::Eq)?;
661                if let Some(none_span) = parser.skip_keyword(Keyword::NONE) {
662                    OperatorOption::RestrictNone { restrict_span: keyword_span, eq_span, none_span }
663                } else {
664                    let function_name = parse_qualified_name_unreserved(parser)?;
665                    OperatorOption::Restrict {
666                        restrict_span: keyword_span,
667                        eq_span,
668                        function_name,
669                    }
670                }
671            }
672            Token::Ident(_, Keyword::JOIN) => {
673                let keyword_span = parser.consume_keyword(Keyword::JOIN)?;
674                let eq_span = parser.consume_token(Token::Eq)?;
675                if let Some(none_span) = parser.skip_keyword(Keyword::NONE) {
676                    OperatorOption::JoinNone { join_span: keyword_span, eq_span, none_span }
677                } else {
678                    let function_name = parse_qualified_name_unreserved(parser)?;
679                    OperatorOption::Join {
680                        join_span: keyword_span,
681                        eq_span,
682                        function_name,
683                    }
684                }
685            }
686            Token::Ident(_, Keyword::HASHES) => {
687                OperatorOption::Hashes(parser.consume_keyword(Keyword::HASHES)?)
688            }
689            Token::Ident(_, Keyword::MERGES) => {
690                OperatorOption::Merges(parser.consume_keyword(Keyword::MERGES)?)
691            }
692            _ => {
693                parser.expected_failure(
694                    "'FUNCTION' | 'PROCEDURE' | 'LEFTARG' | 'RIGHTARG' | 'COMMUTATOR' | 'NEGATOR' | 'RESTRICT' | 'JOIN' | 'HASHES' | 'MERGES'"
695                )?
696            }
697        };
698
699        options.push(option);
700
701        // Check for comma or end of options
702        if parser.skip_token(Token::Comma).is_none() {
703            break;
704        }
705    }
706
707    let rparen_span = parser.consume_token(Token::RParen)?;
708
709    Ok(CreateOperator {
710        create_operator_span,
711        name,
712        lparen_span,
713        options,
714        rparen_span,
715    })
716}
717
718/// Parse an operator reference (either simple or OPERATOR(...) syntax)
719fn parse_operator_ref<'a>(parser: &mut Parser<'a, '_>) -> Result<OperatorRef<'a>, ParseError> {
720    if let Token::Ident(_, Keyword::OPERATOR) = &parser.token {
721        let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
722        let lparen_span = parser.consume_token(Token::LParen)?;
723        let operator_name = parse_operator_name(parser)?;
724        let rparen_span = parser.consume_token(Token::RParen)?;
725        Ok(OperatorRef::Wrapped {
726            operator_span,
727            lparen_span,
728            operator_name,
729            rparen_span,
730        })
731    } else {
732        let name = parse_operator_name(parser)?;
733        Ok(OperatorRef::Simple(name))
734    }
735}
736
737/// Consume an operator symbol or identifier token
738fn consume_operator_or_identifier<'a>(
739    parser: &mut Parser<'a, '_>,
740) -> Result<crate::Identifier<'a>, ParseError> {
741    use crate::Identifier;
742
743    match &parser.token {
744        // Handle operator symbols as identifiers
745        Token::Plus => Ok(Identifier::new("+", parser.consume())),
746        Token::Minus => Ok(Identifier::new("-", parser.consume())),
747        Token::Mul => Ok(Identifier::new("*", parser.consume())),
748        Token::Div => Ok(Identifier::new("/", parser.consume())),
749        Token::Mod => Ok(Identifier::new("%", parser.consume())),
750        Token::Eq => Ok(Identifier::new("=", parser.consume())),
751        Token::Neq => Ok(Identifier::new("!=", parser.consume())),
752        Token::Lt => Ok(Identifier::new("<", parser.consume())),
753        Token::LtEq => Ok(Identifier::new("<=", parser.consume())),
754        Token::Gt => Ok(Identifier::new(">", parser.consume())),
755        Token::GtEq => Ok(Identifier::new(">=", parser.consume())),
756        Token::Ampersand => Ok(Identifier::new("&", parser.consume())),
757        Token::Pipe => Ok(Identifier::new("|", parser.consume())),
758        Token::Caret => Ok(Identifier::new("^", parser.consume())),
759        Token::Tilde => Ok(Identifier::new("~", parser.consume())),
760        Token::ExclamationMark => Ok(Identifier::new("!", parser.consume())),
761        Token::At => Ok(Identifier::new("@", parser.consume())),
762        Token::AtAt => Ok(Identifier::new("@@", parser.consume())),
763        Token::Sharp => Ok(Identifier::new("#", parser.consume())),
764        Token::ShiftLeft => Ok(Identifier::new("<<", parser.consume())),
765        Token::ShiftRight => Ok(Identifier::new(">>", parser.consume())),
766        Token::DoublePipe => Ok(Identifier::new("||", parser.consume())),
767        Token::DoubleAmpersand => Ok(Identifier::new("&&", parser.consume())),
768        Token::Spaceship => Ok(Identifier::new("<=>", parser.consume())),
769        Token::RArrow => Ok(Identifier::new("->", parser.consume())),
770        Token::RArrowJson => Ok(Identifier::new("->>", parser.consume())),
771        Token::RDoubleArrowJson => Ok(Identifier::new("#>>", parser.consume())),
772        Token::DoubleExclamationMark => Ok(Identifier::new("!!", parser.consume())),
773        Token::PostgresOperator(op) => Ok(Identifier::new(op, parser.consume())),
774        // Regular identifiers
775        _ => parser.consume_plain_identifier_unreserved(),
776    }
777}
778
779/// Parse an operator name (can be an identifier, operator symbol, or schema-qualified)
780pub(crate) fn parse_operator_name<'a>(
781    parser: &mut Parser<'a, '_>,
782) -> Result<QualifiedName<'a>, ParseError> {
783    let mut identifier = consume_operator_or_identifier(parser)?;
784    let mut prefix = Vec::new();
785
786    // Handle schema qualification (e.g., myschema.@@)
787    while let Some(dot) = parser.skip_token(Token::Period) {
788        prefix.push((identifier, dot));
789        identifier = consume_operator_or_identifier(parser)?;
790    }
791
792    Ok(QualifiedName { prefix, identifier })
793}
794
795/// CREATE OPERATOR CLASS statement (PostgreSQL)
796
797#[derive(Clone, Debug)]
798pub struct CreateOperatorClass<'a> {
799    /// Span of "CREATE OPERATOR CLASS"
800    pub create_operator_class_span: Span,
801    /// Name of the operator class
802    pub name: QualifiedName<'a>,
803    /// DEFAULT keyword span (optional)
804    pub default_span: Option<Span>,
805    /// FOR TYPE span
806    pub for_type_span: Span,
807    /// Data type for the operator class
808    pub data_type: DataType<'a>,
809    /// Index method (btree, gist, etc)
810    pub index_method: UsingIndexMethod,
811    /// FAMILY clause (optional)
812    pub family: Option<(Span, QualifiedName<'a>)>,
813    /// AS span
814    pub as_span: Span,
815    /// Items (operators, functions, storage)
816    pub items: Vec<OperatorClassItem<'a>>,
817}
818
819impl<'a> Spanned for CreateOperatorClass<'a> {
820    fn span(&self) -> Span {
821        self.create_operator_class_span
822            .join_span(&self.name)
823            .join_span(&self.default_span)
824            .join_span(&self.for_type_span)
825            .join_span(&self.data_type)
826            .join_span(&self.index_method)
827            .join_span(&self.family)
828            .join_span(&self.as_span)
829            .join_span(&self.items)
830    }
831}
832
833#[derive(Clone, Debug)]
834pub enum OperatorClassItem<'a> {
835    Operator {
836        operator_span: Span,
837        number: (usize, Span),
838        operator: QualifiedName<'a>,
839        op_types: Vec<DataType<'a>>,
840        rest: Vec<OperatorClassOperatorOption<'a>>,
841    },
842    Function {
843        function_span: Span,
844        number: (usize, Span),
845        function: QualifiedName<'a>,
846        arg_types: Vec<DataType<'a>>,
847        fn_arg_types: Vec<DataType<'a>>,
848    },
849    Storage {
850        storage_span: Span,
851        data_type: DataType<'a>,
852    },
853}
854
855impl<'a> Spanned for OperatorClassItem<'a> {
856    fn span(&self) -> Span {
857        match self {
858            OperatorClassItem::Operator {
859                operator_span,
860                number: (_, nspan),
861                operator,
862                op_types,
863                rest,
864            } => operator_span
865                .join_span(nspan)
866                .join_span(operator)
867                .join_span(op_types)
868                .join_span(rest),
869            OperatorClassItem::Function {
870                function_span,
871                number: (_, nspan),
872                function,
873                arg_types,
874                fn_arg_types,
875            } => function_span
876                .join_span(nspan)
877                .join_span(arg_types)
878                .join_span(function)
879                .join_span(fn_arg_types),
880            OperatorClassItem::Storage {
881                storage_span,
882                data_type,
883            } => storage_span.join_span(data_type),
884        }
885    }
886}
887
888#[derive(Clone, Debug)]
889pub enum OperatorClassOperatorOption<'a> {
890    ForSearch(Span),
891    ForOrderBy(Span, QualifiedName<'a>),
892}
893
894impl<'a> Spanned for OperatorClassOperatorOption<'a> {
895    fn span(&self) -> Span {
896        match self {
897            OperatorClassOperatorOption::ForSearch(span) => span.clone(),
898            OperatorClassOperatorOption::ForOrderBy(span, qn) => span.join_span(qn),
899        }
900    }
901}
902
903pub(crate) fn parse_create_operator_class<'a>(
904    parser: &mut Parser<'a, '_>,
905    create_operator_class_span: Span,
906    create_options: Vec<CreateOption<'a>>,
907) -> Result<CreateOperatorClass<'a>, ParseError> {
908    parser.postgres_only(&create_operator_class_span);
909
910    for create_option in create_options {
911        parser.err(
912            "CREATE OPERATOR CLASS does not support any options",
913            &create_option.span(),
914        );
915    }
916
917    // Parse name
918    let name = parse_qualified_name_unreserved(parser)?;
919
920    // Optional DEFAULT
921    let default_span = parser.skip_keyword(Keyword::DEFAULT);
922
923    // FOR TYPE
924    let for_type_span = parser.consume_keywords(&[Keyword::FOR, Keyword::TYPE])?;
925    let data_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
926
927    // USING index_method
928    let using_span = parser.consume_keyword(Keyword::USING)?;
929    let index_method = crate::create_index::parse_using_index_method(parser, using_span)?;
930
931    // Optional FAMILY clause
932    let family = if let Some(family_span) = parser.skip_keyword(Keyword::FAMILY) {
933        let family_name = parse_qualified_name_unreserved(parser)?;
934        Some((family_span, family_name))
935    } else {
936        None
937    };
938
939    // AS
940    let as_span = parser.consume_keyword(Keyword::AS)?;
941
942    // Parse items (operators, functions, storage)
943    let mut items = Vec::new();
944    loop {
945        match &parser.token {
946            Token::Ident(_, Keyword::OPERATOR) => {
947                let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
948                let (num, num_span) = parser.consume_int()?;
949                let operator = parse_operator_name(parser)?;
950                // Optional (op_type, op_type)
951                let mut op_types = Vec::new();
952                if parser.skip_token(Token::LParen).is_some() {
953                    loop {
954                        op_types.push(parse_data_type(parser, DataTypeContext::TypeRef)?);
955                        if parser.skip_token(Token::Comma).is_none() {
956                            break;
957                        }
958                    }
959                    parser.consume_token(Token::RParen)?;
960                }
961                let mut rest = Vec::new();
962                // Optional FOR SEARCH / FOR ORDER BY
963                if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
964                    if let Some(search_span) = parser.skip_keyword(Keyword::SEARCH) {
965                        rest.push(OperatorClassOperatorOption::ForSearch(
966                            for_span.join_span(&search_span),
967                        ));
968                    } else if let Some(order_span) = parser.skip_keyword(Keyword::ORDER) {
969                        parser.consume_keyword(Keyword::BY)?;
970                        let opclass = parse_operator_name(parser)?;
971                        rest.push(OperatorClassOperatorOption::ForOrderBy(
972                            for_span.join_span(&order_span),
973                            opclass,
974                        ));
975                    }
976                }
977                items.push(OperatorClassItem::Operator {
978                    operator_span,
979                    number: (num, num_span),
980                    operator,
981                    op_types,
982                    rest,
983                });
984            }
985            Token::Ident(_, Keyword::FUNCTION) => {
986                let function_span = parser.consume_keyword(Keyword::FUNCTION)?;
987                let (num, num_span) = parser.consume_int()?;
988                // Optional (op_type, op_type) before function name
989                let mut arg_types = Vec::new();
990                if parser.skip_token(Token::LParen).is_some() {
991                    loop {
992                        arg_types.push(parse_data_type(parser, DataTypeContext::TypeRef)?);
993                        if parser.skip_token(Token::Comma).is_none() {
994                            break;
995                        }
996                    }
997                    parser.consume_token(Token::RParen)?;
998                }
999                let function = parse_qualified_name_unreserved(parser)?;
1000                // Optional (argument_type, ...) after function name
1001                let mut fn_arg_types = Vec::new();
1002                if parser.skip_token(Token::LParen).is_some() {
1003                    loop {
1004                        fn_arg_types.push(parse_data_type(parser, DataTypeContext::TypeRef)?);
1005                        if parser.skip_token(Token::Comma).is_none() {
1006                            break;
1007                        }
1008                    }
1009                    parser.consume_token(Token::RParen)?;
1010                }
1011                items.push(OperatorClassItem::Function {
1012                    function_span,
1013                    number: (num, num_span),
1014                    function,
1015                    arg_types,
1016                    fn_arg_types,
1017                });
1018            }
1019            Token::Ident(_, Keyword::STORAGE) => {
1020                let storage_span = parser.consume_keyword(Keyword::STORAGE)?;
1021                let data_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
1022                items.push(OperatorClassItem::Storage {
1023                    storage_span,
1024                    data_type,
1025                });
1026            }
1027            _ => break,
1028        }
1029        if parser.skip_token(Token::Comma).is_none() {
1030            break;
1031        }
1032    }
1033
1034    Ok(CreateOperatorClass {
1035        create_operator_class_span,
1036        name,
1037        default_span,
1038        for_type_span,
1039        data_type,
1040        index_method,
1041        family,
1042        as_span,
1043        items,
1044    })
1045}
1046
1047/// CREATE OPERATOR FAMILY statement (PostgreSQL)
1048#[derive(Clone, Debug)]
1049pub struct CreateOperatorFamily<'a> {
1050    /// Span of "CREATE OPERATOR FAMILY"
1051    pub create_operator_family_span: Span,
1052    /// The operator family name
1053    pub name: QualifiedName<'a>,
1054    /// The index method (btree, hash, gist, gin)
1055    pub index_method: UsingIndexMethod,
1056    /// Left parenthesis span
1057    pub lparen_span: Span,
1058    /// Right parenthesis span
1059    pub rparen_span: Span,
1060}
1061
1062impl<'a> Spanned for CreateOperatorFamily<'a> {
1063    fn span(&self) -> Span {
1064        self.create_operator_family_span.clone()
1065    }
1066}
1067
1068/// Parse CREATE OPERATOR FAMILY statement
1069pub(crate) fn parse_create_operator_family<'a>(
1070    parser: &mut Parser<'a, '_>,
1071    create_operator_family_span: Span,
1072    create_options: Vec<CreateOption<'a>>,
1073) -> Result<CreateOperatorFamily<'a>, ParseError> {
1074    parser.postgres_only(&create_operator_family_span);
1075    for create_option in create_options {
1076        parser.err(
1077            "CREATE OPERATOR FAMILY does not support any options",
1078            &create_option.span(),
1079        );
1080    }
1081    let name = parse_qualified_name_unreserved(parser)?;
1082    let using_span = parser.consume_keyword(Keyword::USING)?;
1083    let using_index_method = crate::create_index::parse_using_index_method(parser, using_span)?;
1084    let lparen_span = parser.consume_token(Token::LParen)?;
1085    let rparen_span = parser.consume_token(Token::RParen)?;
1086    Ok(CreateOperatorFamily {
1087        create_operator_family_span,
1088        name,
1089        index_method: using_index_method,
1090        lparen_span,
1091        rparen_span,
1092    })
1093}
1094
1095/// ALTER OPERATOR FAMILY statement (PostgreSQL)
1096#[derive(Clone, Debug)]
1097pub struct AlterOperatorFamily<'a> {
1098    /// Span of "ALTER OPERATOR FAMILY"
1099    pub alter_operator_family_span: Span,
1100    /// The operator family name
1101    pub name: QualifiedName<'a>,
1102    /// The index method (btree, hash, gist, gin)
1103    pub index_method: UsingIndexMethod,
1104    /// The action (ADD, DROP, RENAME TO, OWNER TO, SET SCHEMA)
1105    pub action: AlterOperatorFamilyAction<'a>,
1106}
1107
1108impl<'a> Spanned for AlterOperatorFamily<'a> {
1109    fn span(&self) -> Span {
1110        self.alter_operator_family_span
1111            .join_span(&self.name)
1112            .join_span(&self.index_method)
1113            .join_span(&self.action)
1114    }
1115}
1116
1117/// Actions for ALTER OPERATOR FAMILY (ADD, DROP, RENAME TO, OWNER TO, SET SCHEMA)
1118#[derive(Clone, Debug)]
1119pub enum AlterOperatorFamilyAction<'a> {
1120    /// ADD OPERATOR/FUNCTION(s) to the family
1121    Add {
1122        /// Span of ADD keyword
1123        add_span: Span,
1124        /// Items to add (operators/functions)
1125        items: Vec<OperatorFamilyItem<'a>>,
1126    },
1127    /// DROP OPERATOR/FUNCTION(s) from the family
1128    Drop {
1129        /// Span of DROP keyword
1130        drop_span: Span,
1131        /// Items to drop (operators/functions)
1132        items: Vec<OperatorFamilyDropItem<'a>>,
1133    },
1134    /// RENAME TO new_name
1135    RenameTo {
1136        /// Span of RENAME keyword
1137        rename_span: Span,
1138        /// Span of TO keyword
1139        to_span: Span,
1140        /// The new operator family name
1141        new_name: QualifiedName<'a>,
1142    },
1143    /// OWNER TO new_owner
1144    OwnerTo {
1145        /// Span of OWNER keyword
1146        owner_span: Span,
1147        /// Span of TO keyword
1148        to_span: Span,
1149        /// The new owner name
1150        new_owner: crate::alter_table::AlterTableOwner<'a>,
1151    },
1152    /// SET SCHEMA new_schema
1153    SetSchema {
1154        /// Span of SET keyword
1155        set_span: Span,
1156        /// Span of SCHEMA keyword
1157        schema_span: Span,
1158        /// The new schema name
1159        new_schema: QualifiedName<'a>,
1160    },
1161}
1162
1163impl<'a> Spanned for AlterOperatorFamilyAction<'a> {
1164    fn span(&self) -> Span {
1165        match self {
1166            AlterOperatorFamilyAction::Add { add_span, items } => add_span.join_span(items),
1167            AlterOperatorFamilyAction::Drop { drop_span, items } => drop_span.join_span(items),
1168            AlterOperatorFamilyAction::RenameTo {
1169                rename_span,
1170                to_span,
1171                new_name,
1172            } => rename_span.join_span(to_span).join_span(new_name),
1173            AlterOperatorFamilyAction::OwnerTo {
1174                owner_span,
1175                to_span,
1176                new_owner,
1177            } => owner_span.join_span(to_span).join_span(new_owner),
1178            AlterOperatorFamilyAction::SetSchema {
1179                set_span,
1180                schema_span,
1181                new_schema,
1182            } => set_span.join_span(schema_span).join_span(new_schema),
1183        }
1184    }
1185}
1186
1187/// Item to add to an operator family (OPERATOR or FUNCTION)
1188#[derive(Clone, Debug)]
1189pub enum OperatorFamilyItem<'a> {
1190    /// OPERATOR entry
1191    Operator {
1192        /// Span of OPERATOR keyword
1193        operator_span: Span,
1194        /// Strategy number and its span
1195        number: (usize, Span),
1196        /// Operator name
1197        operator: QualifiedName<'a>,
1198        /// Span of left parenthesis
1199        lparen_span: Span,
1200        /// Left operand type
1201        left_type: DataType<'a>,
1202        /// Span of comma
1203        comma_span: Span,
1204        /// Right operand type
1205        right_type: DataType<'a>,
1206        /// Span of right parenthesis
1207        rparen_span: Span,
1208        /// Optional FOR SEARCH span
1209        for_search: Option<Span>,
1210        /// Optional FOR ORDER BY (span, sort family)
1211        for_order_by: Option<(Span, QualifiedName<'a>)>,
1212    },
1213    /// FUNCTION entry
1214    Function {
1215        /// Span of FUNCTION keyword
1216        function_span: Span,
1217        /// Support number and its span
1218        number: (usize, Span),
1219        /// Span of left parenthesis, if present
1220        lparen_span: Option<Span>,
1221        /// Left operand type, if present
1222        left_type: Option<DataType<'a>>,
1223        /// Span of comma, if present
1224        comma_span: Option<Span>,
1225        /// Right operand type, if present
1226        right_type: Option<DataType<'a>>,
1227        /// Span of right parenthesis, if present
1228        rparen_span: Option<Span>,
1229        /// Function name
1230        function: QualifiedName<'a>,
1231        /// Span of argument type list left parenthesis, if present
1232        arg_lparen_span: Option<Span>,
1233        /// Argument types for function
1234        arg_types: Vec<DataType<'a>>,
1235        /// Span of argument type list right parenthesis, if present
1236        arg_rparen_span: Option<Span>,
1237    },
1238}
1239
1240impl<'a> Spanned for OperatorFamilyItem<'a> {
1241    fn span(&self) -> Span {
1242        match self {
1243            OperatorFamilyItem::Operator {
1244                operator_span,
1245                rparen_span,
1246                ..
1247            } => operator_span.join_span(rparen_span),
1248            OperatorFamilyItem::Function {
1249                function_span,
1250                arg_rparen_span,
1251                ..
1252            } => function_span.join_span(arg_rparen_span),
1253        }
1254    }
1255}
1256
1257/// Item to drop from an operator family (OPERATOR or FUNCTION)
1258#[derive(Clone, Debug)]
1259pub enum OperatorFamilyDropItem<'a> {
1260    /// OPERATOR entry to drop
1261    Operator {
1262        /// Span of OPERATOR keyword
1263        operator_span: Span,
1264        /// Strategy number and its span
1265        number: (usize, Span),
1266        /// Span of left parenthesis
1267        lparen_span: Span,
1268        /// Left operand type
1269        left_type: DataType<'a>,
1270        /// Span of comma, if present
1271        comma_span: Option<Span>,
1272        /// Right operand type, if present
1273        right_type: Option<DataType<'a>>,
1274        /// Span of right parenthesis
1275        rparen_span: Span,
1276    },
1277    /// FUNCTION entry to drop
1278    Function {
1279        /// Span of FUNCTION keyword
1280        function_span: Span,
1281        /// Support number and its span
1282        number: (usize, Span),
1283        /// Span of left parenthesis
1284        lparen_span: Span,
1285        /// Left operand type, if present
1286        left_type: Option<DataType<'a>>,
1287        /// Span of comma, if present
1288        comma_span: Option<Span>,
1289        /// Right operand type, if present
1290        right_type: Option<DataType<'a>>,
1291        /// Span of right parenthesis
1292        rparen_span: Span,
1293    },
1294}
1295
1296impl<'a> Spanned for OperatorFamilyDropItem<'a> {
1297    fn span(&self) -> Span {
1298        match self {
1299            OperatorFamilyDropItem::Operator {
1300                operator_span,
1301                rparen_span,
1302                ..
1303            } => operator_span.join_span(rparen_span),
1304            OperatorFamilyDropItem::Function {
1305                function_span,
1306                rparen_span,
1307                ..
1308            } => function_span.join_span(rparen_span),
1309        }
1310    }
1311}
1312
1313/// Parse ALTER OPERATOR FAMILY statement
1314pub(crate) fn parse_alter_operator_family<'a>(
1315    parser: &mut Parser<'a, '_>,
1316    alter_operator_family_span: Span,
1317) -> Result<AlterOperatorFamily<'a>, ParseError> {
1318    parser.postgres_only(&alter_operator_family_span);
1319    let name = parse_qualified_name_unreserved(parser)?;
1320    let using_span = parser.consume_keyword(Keyword::USING)?;
1321    let index_method = crate::create_index::parse_using_index_method(parser, using_span)?;
1322
1323    let action = match &parser.token {
1324        Token::Ident(_, Keyword::ADD) => {
1325            let add_span = parser.consume_keyword(Keyword::ADD)?;
1326            let mut items = Vec::new();
1327            loop {
1328                items.push(parse_operator_family_item(parser)?);
1329                if parser.skip_token(Token::Comma).is_none() {
1330                    break;
1331                }
1332            }
1333            AlterOperatorFamilyAction::Add { add_span, items }
1334        }
1335        Token::Ident(_, Keyword::DROP) => {
1336            let drop_span = parser.consume_keyword(Keyword::DROP)?;
1337            let mut items = Vec::new();
1338            loop {
1339                items.push(parse_operator_family_drop_item(parser)?);
1340                if parser.skip_token(Token::Comma).is_none() {
1341                    break;
1342                }
1343            }
1344            AlterOperatorFamilyAction::Drop { drop_span, items }
1345        }
1346        Token::Ident(_, Keyword::RENAME) => {
1347            let rename_span = parser.consume_keyword(Keyword::RENAME)?;
1348            let to_span = parser.consume_keyword(Keyword::TO)?;
1349            let new_name = parse_qualified_name_unreserved(parser)?;
1350            AlterOperatorFamilyAction::RenameTo {
1351                rename_span,
1352                to_span,
1353                new_name,
1354            }
1355        }
1356        Token::Ident(_, Keyword::OWNER) => {
1357            let owner_span = parser.consume_keyword(Keyword::OWNER)?;
1358            let to_span = parser.consume_keyword(Keyword::TO)?;
1359            let new_owner = crate::alter_table::parse_alter_owner(parser)?;
1360            AlterOperatorFamilyAction::OwnerTo {
1361                owner_span,
1362                to_span,
1363                new_owner,
1364            }
1365        }
1366        Token::Ident(_, Keyword::SET) => {
1367            let set_span = parser.consume_keyword(Keyword::SET)?;
1368            let schema_span = parser.consume_keyword(Keyword::SCHEMA)?;
1369            let new_schema = parse_qualified_name_unreserved(parser)?;
1370            AlterOperatorFamilyAction::SetSchema {
1371                set_span,
1372                schema_span,
1373                new_schema,
1374            }
1375        }
1376        _ => parser.expected_failure("'ADD', 'DROP', 'RENAME', 'OWNER', or 'SET SCHEMA'")?,
1377    };
1378
1379    Ok(AlterOperatorFamily {
1380        alter_operator_family_span,
1381        name,
1382        index_method,
1383        action,
1384    })
1385}
1386
1387fn parse_operator_family_item<'a>(
1388    parser: &mut Parser<'a, '_>,
1389) -> Result<OperatorFamilyItem<'a>, ParseError> {
1390    match &parser.token {
1391        Token::Ident(_, Keyword::OPERATOR) => {
1392            let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1393            let (num, num_span) = parser.consume_int()?;
1394            let operator = parse_operator_name(parser)?;
1395            let lparen_span = parser.consume_token(Token::LParen)?;
1396            let left_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
1397            let comma_span = parser.consume_token(Token::Comma)?;
1398            let right_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
1399            let rparen_span = parser.consume_token(Token::RParen)?;
1400            let mut for_search = None;
1401            let mut for_order_by = None;
1402            if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
1403                if let Some(search_span) = parser.skip_keyword(Keyword::SEARCH) {
1404                    for_search = Some(for_span.join_span(&search_span));
1405                } else if let Some(order_span) = parser.skip_keyword(Keyword::ORDER) {
1406                    parser.consume_keyword(Keyword::BY)?;
1407                    let sort_family = parse_operator_name(parser)?;
1408                    for_order_by = Some((for_span.join_span(&order_span), sort_family));
1409                } else {
1410                    parser.expected_failure("'SEARCH' or 'ORDER BY' after 'FOR'")?;
1411                }
1412            }
1413            Ok(OperatorFamilyItem::Operator {
1414                operator_span,
1415                number: (num, num_span),
1416                operator,
1417                lparen_span,
1418                left_type,
1419                comma_span,
1420                right_type,
1421                rparen_span,
1422                for_search,
1423                for_order_by,
1424            })
1425        }
1426        Token::Ident(_, Keyword::FUNCTION) => {
1427            let function_span = parser.consume_keyword(Keyword::FUNCTION)?;
1428            let (num, num_span) = parser.consume_int()?;
1429            let (lparen_span, left_type, comma_span, right_type, rparen_span) =
1430                if let Ok(lparen_span) = parser.consume_token(Token::LParen) {
1431                    let left_type = Some(parse_data_type(parser, DataTypeContext::TypeRef)?);
1432                    let comma_span = parser.consume_token(Token::Comma).ok();
1433                    let right_type = if comma_span.is_some() {
1434                        Some(parse_data_type(parser, DataTypeContext::TypeRef)?)
1435                    } else {
1436                        None
1437                    };
1438                    let rparen_span = parser.consume_token(Token::RParen)?;
1439                    (
1440                        Some(lparen_span),
1441                        left_type,
1442                        comma_span,
1443                        right_type,
1444                        Some(rparen_span),
1445                    )
1446                } else {
1447                    (None, None, None, None, None)
1448                };
1449            let function = parse_qualified_name_unreserved(parser)?;
1450            // Optional argument type list for function
1451            let (arg_lparen_span, arg_types, arg_rparen_span) =
1452                if let Ok(arg_lparen_span) = parser.consume_token(Token::LParen) {
1453                    let mut arg_types = Vec::new();
1454                    loop {
1455                        arg_types.push(parse_data_type(parser, DataTypeContext::TypeRef)?);
1456                        if parser.skip_token(Token::Comma).is_none() {
1457                            break;
1458                        }
1459                    }
1460                    let arg_rparen_span = parser.consume_token(Token::RParen)?;
1461                    (Some(arg_lparen_span), arg_types, Some(arg_rparen_span))
1462                } else {
1463                    (None, Vec::new(), None)
1464                };
1465            Ok(OperatorFamilyItem::Function {
1466                function_span,
1467                number: (num, num_span),
1468                lparen_span,
1469                left_type,
1470                comma_span,
1471                right_type,
1472                rparen_span,
1473                function,
1474                arg_lparen_span,
1475                arg_types,
1476                arg_rparen_span,
1477            })
1478        }
1479        _ => parser.expected_failure("'OPERATOR' or 'FUNCTION'")?,
1480    }
1481}
1482
1483fn parse_operator_family_drop_item<'a>(
1484    parser: &mut Parser<'a, '_>,
1485) -> Result<OperatorFamilyDropItem<'a>, ParseError> {
1486    match &parser.token {
1487        Token::Ident(_, Keyword::OPERATOR) => {
1488            let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1489            let (num, num_span) = parser.consume_int()?;
1490            let lparen_span = parser.consume_token(Token::LParen)?;
1491            let left_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
1492            let comma_span = parser.consume_token(Token::Comma).ok();
1493            let right_type = if comma_span.is_some() {
1494                Some(parse_data_type(parser, DataTypeContext::TypeRef)?)
1495            } else {
1496                None
1497            };
1498            let rparen_span = parser.consume_token(Token::RParen)?;
1499            Ok(OperatorFamilyDropItem::Operator {
1500                operator_span,
1501                number: (num, num_span),
1502                lparen_span,
1503                left_type,
1504                comma_span,
1505                right_type,
1506                rparen_span,
1507            })
1508        }
1509        Token::Ident(_, Keyword::FUNCTION) => {
1510            let function_span = parser.consume_keyword(Keyword::FUNCTION)?;
1511            let (num, num_span) = parser.consume_int()?;
1512            let lparen_span = parser.consume_token(Token::LParen)?;
1513            let left_type = Some(parse_data_type(parser, DataTypeContext::TypeRef)?);
1514            let comma_span = parser.consume_token(Token::Comma).ok();
1515            let right_type = if comma_span.is_some() {
1516                Some(parse_data_type(parser, DataTypeContext::TypeRef)?)
1517            } else {
1518                None
1519            };
1520            let rparen_span = parser.consume_token(Token::RParen)?;
1521            Ok(OperatorFamilyDropItem::Function {
1522                function_span,
1523                number: (num, num_span),
1524                lparen_span,
1525                left_type,
1526                comma_span,
1527                right_type,
1528                rparen_span,
1529            })
1530        }
1531        _ => parser.expected_failure("'OPERATOR' or 'FUNCTION'")?,
1532    }
1533}