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
1065            .join_span(&self.name)
1066            .join_span(&self.index_method)
1067            .join_span(&self.lparen_span)
1068            .join_span(&self.rparen_span)
1069    }
1070}
1071
1072/// Parse CREATE OPERATOR FAMILY statement
1073pub(crate) fn parse_create_operator_family<'a>(
1074    parser: &mut Parser<'a, '_>,
1075    create_operator_family_span: Span,
1076    create_options: Vec<CreateOption<'a>>,
1077) -> Result<CreateOperatorFamily<'a>, ParseError> {
1078    parser.postgres_only(&create_operator_family_span);
1079    for create_option in create_options {
1080        parser.err(
1081            "CREATE OPERATOR FAMILY does not support any options",
1082            &create_option.span(),
1083        );
1084    }
1085    let name = parse_qualified_name_unreserved(parser)?;
1086    let using_span = parser.consume_keyword(Keyword::USING)?;
1087    let using_index_method = crate::create_index::parse_using_index_method(parser, using_span)?;
1088    let lparen_span = parser.consume_token(Token::LParen)?;
1089    let rparen_span = parser.consume_token(Token::RParen)?;
1090    Ok(CreateOperatorFamily {
1091        create_operator_family_span,
1092        name,
1093        index_method: using_index_method,
1094        lparen_span,
1095        rparen_span,
1096    })
1097}
1098
1099/// ALTER OPERATOR FAMILY statement (PostgreSQL)
1100#[derive(Clone, Debug)]
1101pub struct AlterOperatorFamily<'a> {
1102    /// Span of "ALTER OPERATOR FAMILY"
1103    pub alter_operator_family_span: Span,
1104    /// The operator family name
1105    pub name: QualifiedName<'a>,
1106    /// The index method (btree, hash, gist, gin)
1107    pub index_method: UsingIndexMethod,
1108    /// The action (ADD, DROP, RENAME TO, OWNER TO, SET SCHEMA)
1109    pub action: AlterOperatorFamilyAction<'a>,
1110}
1111
1112impl<'a> Spanned for AlterOperatorFamily<'a> {
1113    fn span(&self) -> Span {
1114        self.alter_operator_family_span
1115            .join_span(&self.name)
1116            .join_span(&self.index_method)
1117            .join_span(&self.action)
1118    }
1119}
1120
1121/// Actions for ALTER OPERATOR FAMILY (ADD, DROP, RENAME TO, OWNER TO, SET SCHEMA)
1122#[derive(Clone, Debug)]
1123pub enum AlterOperatorFamilyAction<'a> {
1124    /// ADD OPERATOR/FUNCTION(s) to the family
1125    Add {
1126        /// Span of ADD keyword
1127        add_span: Span,
1128        /// Items to add (operators/functions)
1129        items: Vec<OperatorFamilyItem<'a>>,
1130    },
1131    /// DROP OPERATOR/FUNCTION(s) from the family
1132    Drop {
1133        /// Span of DROP keyword
1134        drop_span: Span,
1135        /// Items to drop (operators/functions)
1136        items: Vec<OperatorFamilyDropItem<'a>>,
1137    },
1138    /// RENAME TO new_name
1139    RenameTo {
1140        /// Span of RENAME keyword
1141        rename_span: Span,
1142        /// Span of TO keyword
1143        to_span: Span,
1144        /// The new operator family name
1145        new_name: QualifiedName<'a>,
1146    },
1147    /// OWNER TO new_owner
1148    OwnerTo {
1149        /// Span of OWNER keyword
1150        owner_span: Span,
1151        /// Span of TO keyword
1152        to_span: Span,
1153        /// The new owner name
1154        new_owner: crate::alter_table::AlterTableOwner<'a>,
1155    },
1156    /// SET SCHEMA new_schema
1157    SetSchema {
1158        /// Span of SET keyword
1159        set_span: Span,
1160        /// Span of SCHEMA keyword
1161        schema_span: Span,
1162        /// The new schema name
1163        new_schema: QualifiedName<'a>,
1164    },
1165}
1166
1167impl<'a> Spanned for AlterOperatorFamilyAction<'a> {
1168    fn span(&self) -> Span {
1169        match self {
1170            AlterOperatorFamilyAction::Add { add_span, items } => add_span.join_span(items),
1171            AlterOperatorFamilyAction::Drop { drop_span, items } => drop_span.join_span(items),
1172            AlterOperatorFamilyAction::RenameTo {
1173                rename_span,
1174                to_span,
1175                new_name,
1176            } => rename_span.join_span(to_span).join_span(new_name),
1177            AlterOperatorFamilyAction::OwnerTo {
1178                owner_span,
1179                to_span,
1180                new_owner,
1181            } => owner_span.join_span(to_span).join_span(new_owner),
1182            AlterOperatorFamilyAction::SetSchema {
1183                set_span,
1184                schema_span,
1185                new_schema,
1186            } => set_span.join_span(schema_span).join_span(new_schema),
1187        }
1188    }
1189}
1190
1191/// Item to add to an operator family (OPERATOR or FUNCTION)
1192#[derive(Clone, Debug)]
1193pub enum OperatorFamilyItem<'a> {
1194    /// OPERATOR entry
1195    Operator {
1196        /// Span of OPERATOR keyword
1197        operator_span: Span,
1198        /// Strategy number and its span
1199        number: (usize, Span),
1200        /// Operator name
1201        operator: QualifiedName<'a>,
1202        /// Span of left parenthesis
1203        lparen_span: Span,
1204        /// Left operand type
1205        left_type: DataType<'a>,
1206        /// Span of comma
1207        comma_span: Span,
1208        /// Right operand type
1209        right_type: DataType<'a>,
1210        /// Span of right parenthesis
1211        rparen_span: Span,
1212        /// Optional FOR SEARCH span
1213        for_search: Option<Span>,
1214        /// Optional FOR ORDER BY (span, sort family)
1215        for_order_by: Option<(Span, QualifiedName<'a>)>,
1216    },
1217    /// FUNCTION entry
1218    Function {
1219        /// Span of FUNCTION keyword
1220        function_span: Span,
1221        /// Support number and its span
1222        number: (usize, Span),
1223        /// Span of left parenthesis, if present
1224        lparen_span: Option<Span>,
1225        /// Left operand type, if present
1226        left_type: Option<DataType<'a>>,
1227        /// Span of comma, if present
1228        comma_span: Option<Span>,
1229        /// Right operand type, if present
1230        right_type: Option<DataType<'a>>,
1231        /// Span of right parenthesis, if present
1232        rparen_span: Option<Span>,
1233        /// Function name
1234        function: QualifiedName<'a>,
1235        /// Span of argument type list left parenthesis, if present
1236        arg_lparen_span: Option<Span>,
1237        /// Argument types for function
1238        arg_types: Vec<DataType<'a>>,
1239        /// Span of argument type list right parenthesis, if present
1240        arg_rparen_span: Option<Span>,
1241    },
1242}
1243
1244impl<'a> Spanned for OperatorFamilyItem<'a> {
1245    fn span(&self) -> Span {
1246        match self {
1247            OperatorFamilyItem::Operator {
1248                operator_span,
1249                rparen_span,
1250                ..
1251            } => operator_span.join_span(rparen_span),
1252            OperatorFamilyItem::Function {
1253                function_span,
1254                arg_rparen_span,
1255                ..
1256            } => function_span.join_span(arg_rparen_span),
1257        }
1258    }
1259}
1260
1261/// Item to drop from an operator family (OPERATOR or FUNCTION)
1262#[derive(Clone, Debug)]
1263pub enum OperatorFamilyDropItem<'a> {
1264    /// OPERATOR entry to drop
1265    Operator {
1266        /// Span of OPERATOR keyword
1267        operator_span: Span,
1268        /// Strategy number and its span
1269        number: (usize, Span),
1270        /// Span of left parenthesis
1271        lparen_span: Span,
1272        /// Left operand type
1273        left_type: DataType<'a>,
1274        /// Span of comma, if present
1275        comma_span: Option<Span>,
1276        /// Right operand type, if present
1277        right_type: Option<DataType<'a>>,
1278        /// Span of right parenthesis
1279        rparen_span: Span,
1280    },
1281    /// FUNCTION entry to drop
1282    Function {
1283        /// Span of FUNCTION keyword
1284        function_span: Span,
1285        /// Support number and its span
1286        number: (usize, Span),
1287        /// Span of left parenthesis
1288        lparen_span: Span,
1289        /// Left operand type, if present
1290        left_type: Option<DataType<'a>>,
1291        /// Span of comma, if present
1292        comma_span: Option<Span>,
1293        /// Right operand type, if present
1294        right_type: Option<DataType<'a>>,
1295        /// Span of right parenthesis
1296        rparen_span: Span,
1297    },
1298}
1299
1300impl<'a> Spanned for OperatorFamilyDropItem<'a> {
1301    fn span(&self) -> Span {
1302        match self {
1303            OperatorFamilyDropItem::Operator {
1304                operator_span,
1305                rparen_span,
1306                ..
1307            } => operator_span.join_span(rparen_span),
1308            OperatorFamilyDropItem::Function {
1309                function_span,
1310                rparen_span,
1311                ..
1312            } => function_span.join_span(rparen_span),
1313        }
1314    }
1315}
1316
1317/// Parse ALTER OPERATOR FAMILY statement
1318pub(crate) fn parse_alter_operator_family<'a>(
1319    parser: &mut Parser<'a, '_>,
1320    alter_operator_family_span: Span,
1321) -> Result<AlterOperatorFamily<'a>, ParseError> {
1322    parser.postgres_only(&alter_operator_family_span);
1323    let name = parse_qualified_name_unreserved(parser)?;
1324    let using_span = parser.consume_keyword(Keyword::USING)?;
1325    let index_method = crate::create_index::parse_using_index_method(parser, using_span)?;
1326
1327    let action = match &parser.token {
1328        Token::Ident(_, Keyword::ADD) => {
1329            let add_span = parser.consume_keyword(Keyword::ADD)?;
1330            let mut items = Vec::new();
1331            loop {
1332                items.push(parse_operator_family_item(parser)?);
1333                if parser.skip_token(Token::Comma).is_none() {
1334                    break;
1335                }
1336            }
1337            AlterOperatorFamilyAction::Add { add_span, items }
1338        }
1339        Token::Ident(_, Keyword::DROP) => {
1340            let drop_span = parser.consume_keyword(Keyword::DROP)?;
1341            let mut items = Vec::new();
1342            loop {
1343                items.push(parse_operator_family_drop_item(parser)?);
1344                if parser.skip_token(Token::Comma).is_none() {
1345                    break;
1346                }
1347            }
1348            AlterOperatorFamilyAction::Drop { drop_span, items }
1349        }
1350        Token::Ident(_, Keyword::RENAME) => {
1351            let rename_span = parser.consume_keyword(Keyword::RENAME)?;
1352            let to_span = parser.consume_keyword(Keyword::TO)?;
1353            let new_name = parse_qualified_name_unreserved(parser)?;
1354            AlterOperatorFamilyAction::RenameTo {
1355                rename_span,
1356                to_span,
1357                new_name,
1358            }
1359        }
1360        Token::Ident(_, Keyword::OWNER) => {
1361            let owner_span = parser.consume_keyword(Keyword::OWNER)?;
1362            let to_span = parser.consume_keyword(Keyword::TO)?;
1363            let new_owner = crate::alter_table::parse_alter_owner(parser)?;
1364            AlterOperatorFamilyAction::OwnerTo {
1365                owner_span,
1366                to_span,
1367                new_owner,
1368            }
1369        }
1370        Token::Ident(_, Keyword::SET) => {
1371            let set_span = parser.consume_keyword(Keyword::SET)?;
1372            let schema_span = parser.consume_keyword(Keyword::SCHEMA)?;
1373            let new_schema = parse_qualified_name_unreserved(parser)?;
1374            AlterOperatorFamilyAction::SetSchema {
1375                set_span,
1376                schema_span,
1377                new_schema,
1378            }
1379        }
1380        _ => parser.expected_failure("'ADD', 'DROP', 'RENAME', 'OWNER', or 'SET SCHEMA'")?,
1381    };
1382
1383    Ok(AlterOperatorFamily {
1384        alter_operator_family_span,
1385        name,
1386        index_method,
1387        action,
1388    })
1389}
1390
1391fn parse_operator_family_item<'a>(
1392    parser: &mut Parser<'a, '_>,
1393) -> Result<OperatorFamilyItem<'a>, ParseError> {
1394    match &parser.token {
1395        Token::Ident(_, Keyword::OPERATOR) => {
1396            let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1397            let (num, num_span) = parser.consume_int()?;
1398            let operator = parse_operator_name(parser)?;
1399            let lparen_span = parser.consume_token(Token::LParen)?;
1400            let left_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
1401            let comma_span = parser.consume_token(Token::Comma)?;
1402            let right_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
1403            let rparen_span = parser.consume_token(Token::RParen)?;
1404            let mut for_search = None;
1405            let mut for_order_by = None;
1406            if let Some(for_span) = parser.skip_keyword(Keyword::FOR) {
1407                if let Some(search_span) = parser.skip_keyword(Keyword::SEARCH) {
1408                    for_search = Some(for_span.join_span(&search_span));
1409                } else if let Some(order_span) = parser.skip_keyword(Keyword::ORDER) {
1410                    parser.consume_keyword(Keyword::BY)?;
1411                    let sort_family = parse_operator_name(parser)?;
1412                    for_order_by = Some((for_span.join_span(&order_span), sort_family));
1413                } else {
1414                    parser.expected_failure("'SEARCH' or 'ORDER BY' after 'FOR'")?;
1415                }
1416            }
1417            Ok(OperatorFamilyItem::Operator {
1418                operator_span,
1419                number: (num, num_span),
1420                operator,
1421                lparen_span,
1422                left_type,
1423                comma_span,
1424                right_type,
1425                rparen_span,
1426                for_search,
1427                for_order_by,
1428            })
1429        }
1430        Token::Ident(_, Keyword::FUNCTION) => {
1431            let function_span = parser.consume_keyword(Keyword::FUNCTION)?;
1432            let (num, num_span) = parser.consume_int()?;
1433            let (lparen_span, left_type, comma_span, right_type, rparen_span) =
1434                if let Ok(lparen_span) = parser.consume_token(Token::LParen) {
1435                    let left_type = Some(parse_data_type(parser, DataTypeContext::TypeRef)?);
1436                    let comma_span = parser.consume_token(Token::Comma).ok();
1437                    let right_type = if comma_span.is_some() {
1438                        Some(parse_data_type(parser, DataTypeContext::TypeRef)?)
1439                    } else {
1440                        None
1441                    };
1442                    let rparen_span = parser.consume_token(Token::RParen)?;
1443                    (
1444                        Some(lparen_span),
1445                        left_type,
1446                        comma_span,
1447                        right_type,
1448                        Some(rparen_span),
1449                    )
1450                } else {
1451                    (None, None, None, None, None)
1452                };
1453            let function = parse_qualified_name_unreserved(parser)?;
1454            // Optional argument type list for function
1455            let (arg_lparen_span, arg_types, arg_rparen_span) =
1456                if let Ok(arg_lparen_span) = parser.consume_token(Token::LParen) {
1457                    let mut arg_types = Vec::new();
1458                    loop {
1459                        arg_types.push(parse_data_type(parser, DataTypeContext::TypeRef)?);
1460                        if parser.skip_token(Token::Comma).is_none() {
1461                            break;
1462                        }
1463                    }
1464                    let arg_rparen_span = parser.consume_token(Token::RParen)?;
1465                    (Some(arg_lparen_span), arg_types, Some(arg_rparen_span))
1466                } else {
1467                    (None, Vec::new(), None)
1468                };
1469            Ok(OperatorFamilyItem::Function {
1470                function_span,
1471                number: (num, num_span),
1472                lparen_span,
1473                left_type,
1474                comma_span,
1475                right_type,
1476                rparen_span,
1477                function,
1478                arg_lparen_span,
1479                arg_types,
1480                arg_rparen_span,
1481            })
1482        }
1483        _ => parser.expected_failure("'OPERATOR' or 'FUNCTION'")?,
1484    }
1485}
1486
1487fn parse_operator_family_drop_item<'a>(
1488    parser: &mut Parser<'a, '_>,
1489) -> Result<OperatorFamilyDropItem<'a>, ParseError> {
1490    match &parser.token {
1491        Token::Ident(_, Keyword::OPERATOR) => {
1492            let operator_span = parser.consume_keyword(Keyword::OPERATOR)?;
1493            let (num, num_span) = parser.consume_int()?;
1494            let lparen_span = parser.consume_token(Token::LParen)?;
1495            let left_type = parse_data_type(parser, DataTypeContext::TypeRef)?;
1496            let comma_span = parser.consume_token(Token::Comma).ok();
1497            let right_type = if comma_span.is_some() {
1498                Some(parse_data_type(parser, DataTypeContext::TypeRef)?)
1499            } else {
1500                None
1501            };
1502            let rparen_span = parser.consume_token(Token::RParen)?;
1503            Ok(OperatorFamilyDropItem::Operator {
1504                operator_span,
1505                number: (num, num_span),
1506                lparen_span,
1507                left_type,
1508                comma_span,
1509                right_type,
1510                rparen_span,
1511            })
1512        }
1513        Token::Ident(_, Keyword::FUNCTION) => {
1514            let function_span = parser.consume_keyword(Keyword::FUNCTION)?;
1515            let (num, num_span) = parser.consume_int()?;
1516            let lparen_span = parser.consume_token(Token::LParen)?;
1517            let left_type = Some(parse_data_type(parser, DataTypeContext::TypeRef)?);
1518            let comma_span = parser.consume_token(Token::Comma).ok();
1519            let right_type = if comma_span.is_some() {
1520                Some(parse_data_type(parser, DataTypeContext::TypeRef)?)
1521            } else {
1522                None
1523            };
1524            let rparen_span = parser.consume_token(Token::RParen)?;
1525            Ok(OperatorFamilyDropItem::Function {
1526                function_span,
1527                number: (num, num_span),
1528                lparen_span,
1529                left_type,
1530                comma_span,
1531                right_type,
1532                rparen_span,
1533            })
1534        }
1535        _ => parser.expected_failure("'OPERATOR' or 'FUNCTION'")?,
1536    }
1537}