Skip to main content

risingwave_sqlparser/
parser.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
13//! SQL Parser
14
15use std::fmt;
16
17use ddl::{AlterRateLimit, AlterRateLimitType, WebhookSourceInfo};
18use itertools::Itertools;
19use tracing::{debug, instrument};
20use winnow::combinator::{
21    alt, cut_err, dispatch, fail, opt, peek, preceded, repeat, separated, separated_pair,
22};
23use winnow::{ModalResult, Parser as _};
24
25use crate::ast::*;
26use crate::keywords::{self, Keyword};
27use crate::parser_v2::{
28    ParserExt as _, dollar_quoted_string, keyword, literal_i64, literal_u32, literal_u64,
29    single_quoted_string,
30};
31use crate::tokenizer::*;
32use crate::{impl_parse_to, parser_v2};
33
34pub(crate) const UPSTREAM_SOURCE_KEY: &str = "connector";
35pub(crate) const WEBHOOK_CONNECTOR: &str = "webhook";
36
37const WEBHOOK_WAIT_FOR_PERSISTENCE: &str = "webhook.wait_for_persistence";
38const WEBHOOK_IS_BATCHED: &str = "is_batched";
39
40#[derive(Debug, Clone, PartialEq)]
41pub enum ParserError {
42    TokenizerError(String),
43    ParserError(String),
44}
45
46impl ParserError {
47    pub fn inner_msg(self) -> String {
48        match self {
49            ParserError::TokenizerError(s) | ParserError::ParserError(s) => s,
50        }
51    }
52}
53
54#[derive(Debug, thiserror::Error)]
55#[error("{0}")]
56pub struct StrError(pub String);
57
58// Use `Parser::expected` instead, if possible
59#[macro_export]
60macro_rules! parser_err {
61    ($($arg:tt)*) => {
62        return Err(winnow::error::ErrMode::Backtrack(<winnow::error::ContextError as winnow::error::FromExternalError<_, _>>::from_external_error(
63            &Parser::default(),
64            $crate::parser::StrError(format!($($arg)*)),
65        )))
66    };
67}
68
69impl From<StrError> for winnow::error::ErrMode<winnow::error::ContextError> {
70    fn from(e: StrError) -> Self {
71        winnow::error::ErrMode::Backtrack(<winnow::error::ContextError as winnow::error::FromExternalError<_, _>>::from_external_error(
72            &Parser::default(),
73            e,
74        ))
75    }
76}
77
78// Returns a successful result if the optional expression is some
79macro_rules! return_ok_if_some {
80    ($e:expr) => {{
81        if let Some(v) = $e {
82            return Ok(v);
83        }
84    }};
85}
86
87#[derive(PartialEq)]
88pub enum IsOptional {
89    Optional,
90    Mandatory,
91}
92
93use IsOptional::*;
94
95pub enum IsLateral {
96    Lateral,
97    NotLateral,
98}
99
100use IsLateral::*;
101
102use crate::ast::ddl::{AlterCompactionGroupOperation, AlterFragmentOperation};
103
104pub type IncludeOption = Vec<IncludeOptionItem>;
105
106#[derive(Eq, Clone, Debug, PartialEq, Hash)]
107pub struct IncludeOptionItem {
108    pub column_type: Ident,
109    pub column_alias: Option<Ident>,
110    pub inner_field: Option<String>,
111    pub header_inner_expect_type: Option<DataType>,
112}
113
114#[derive(Debug)]
115pub enum WildcardOrExpr {
116    Expr(Expr),
117    /// Expr is an arbitrary expression, returning either a table or a column.
118    /// Idents are the prefix of `*`, which are consecutive field accesses.
119    /// e.g. `(table.v1).*` or `(table).v1.*`
120    ///
121    /// See also [`Expr::FieldIdentifier`] for behaviors of parentheses.
122    ExprQualifiedWildcard(Expr, Vec<Ident>),
123    /// `QualifiedWildcard` and `Wildcard` can be followed by EXCEPT (columns)
124    QualifiedWildcard(ObjectName, Option<Vec<Expr>>),
125    Wildcard(Option<Vec<Expr>>),
126}
127
128impl From<WildcardOrExpr> for FunctionArgExpr {
129    fn from(wildcard_expr: WildcardOrExpr) -> Self {
130        match wildcard_expr {
131            WildcardOrExpr::Expr(expr) => Self::Expr(expr),
132            WildcardOrExpr::ExprQualifiedWildcard(expr, prefix) => {
133                Self::ExprQualifiedWildcard(expr, prefix)
134            }
135            WildcardOrExpr::QualifiedWildcard(prefix, except) => {
136                Self::QualifiedWildcard(prefix, except)
137            }
138            WildcardOrExpr::Wildcard(except) => Self::Wildcard(except),
139        }
140    }
141}
142
143impl From<TokenizerError> for ParserError {
144    fn from(e: TokenizerError) -> Self {
145        ParserError::TokenizerError(e.to_string())
146    }
147}
148
149impl fmt::Display for ParserError {
150    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151        write!(
152            f,
153            "sql parser error: {}",
154            match self {
155                ParserError::TokenizerError(s) => s,
156                ParserError::ParserError(s) => s,
157            }
158        )
159    }
160}
161
162impl std::error::Error for ParserError {}
163
164type ColumnsDefTuple = (
165    Vec<ColumnDef>,
166    Vec<TableConstraint>,
167    Vec<SourceWatermark>,
168    Option<usize>,
169);
170
171/// Reference:
172/// <https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-PRECEDENCE>
173#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
174pub enum Precedence {
175    Zero = 0,
176    LogicalOr, // 5 in upstream
177    LogicalXor,
178    LogicalAnd, // 10 in upstream
179    UnaryNot,   // 15 in upstream
180    Is,         // 17 in upstream
181    Cmp,
182    Like,    // 19 in upstream
183    Between, // 20 in upstream
184    Other,
185    PlusMinus, // 30 in upstream
186    MulDiv,    // 40 in upstream
187    Exp,
188    At,
189    Collate,
190    UnaryPosNeg,
191    Array,
192    DoubleColon, // 50 in upstream
193}
194
195#[derive(Clone, Copy, Default)]
196pub struct Parser<'a>(pub(crate) &'a [TokenWithLocation]);
197
198impl Parser<'_> {
199    /// Parse a SQL statement and produce an Abstract Syntax Tree (AST)
200    #[instrument(level = "debug")]
201    pub fn parse_sql(sql: &str) -> Result<Vec<Statement>, ParserError> {
202        let mut tokenizer = Tokenizer::new(sql);
203        let tokens = tokenizer.tokenize_with_location()?;
204        let parser = Parser(&tokens);
205        let stmts = Parser::parse_statements.parse(parser).map_err(|e| {
206            // append SQL context to the error message, e.g.:
207            // LINE 1: SELECT 1::int(2);
208            let loc = match tokens.get(e.offset()) {
209                Some(token) => token.location.clone(),
210                None => {
211                    // get location of EOF
212                    Location {
213                        line: sql.lines().count() as u64,
214                        column: sql.lines().last().map_or(0, |l| l.len() as u64) + 1,
215                    }
216                }
217            };
218            let prefix = format!("LINE {}: ", loc.line);
219            let sql_line = sql.split('\n').nth(loc.line as usize - 1).unwrap();
220            let cursor = " ".repeat(prefix.len() + loc.column as usize - 1);
221            ParserError::ParserError(format!(
222                "{}\n{}{}\n{}^",
223                e.inner().to_string().replace('\n', ": "),
224                prefix,
225                sql_line,
226                cursor
227            ))
228        })?;
229        Ok(stmts)
230    }
231
232    /// Parse exactly one statement from a string.
233    pub fn parse_exactly_one(sql: &str) -> Result<Statement, ParserError> {
234        Itertools::exactly_one(
235            Parser::parse_sql(sql)
236                .map_err(|e| {
237                    ParserError::ParserError(format!("failed to parse definition sql: {}", e))
238                })?
239                .into_iter(),
240        )
241        .map_err(|e| {
242            ParserError::ParserError(format!(
243                "expecting exactly one statement in definition: {}",
244                e
245            ))
246        })
247    }
248
249    /// Parse object name from a string.
250    pub fn parse_object_name_str(s: &str) -> Result<ObjectName, ParserError> {
251        let mut tokenizer = Tokenizer::new(s);
252        let tokens = tokenizer.tokenize_with_location()?;
253        let parser = Parser(&tokens);
254        Parser::parse_object_name
255            .parse(parser)
256            .map_err(|e| ParserError::ParserError(e.inner().to_string()))
257    }
258
259    /// Parse function description from a string.
260    pub fn parse_function_desc_str(func: &str) -> Result<FunctionDesc, ParserError> {
261        let mut tokenizer = Tokenizer::new(func);
262        let tokens = tokenizer.tokenize_with_location()?;
263        let parser = Parser(&tokens);
264        Parser::parse_function_desc
265            .parse(parser)
266            .map_err(|e| ParserError::ParserError(e.inner().to_string()))
267    }
268
269    /// Parse a list of semicolon-separated statements.
270    fn parse_statements(&mut self) -> ModalResult<Vec<Statement>> {
271        let mut stmts = Vec::new();
272        let mut expecting_statement_delimiter = false;
273        loop {
274            // ignore empty statements (between successive statement delimiters)
275            while self.consume_token(&Token::SemiColon) {
276                expecting_statement_delimiter = false;
277            }
278
279            if self.peek_token() == Token::EOF {
280                break;
281            }
282            if expecting_statement_delimiter {
283                return self.expected("end of statement");
284            }
285
286            let statement = self.parse_statement()?;
287            stmts.push(statement);
288            expecting_statement_delimiter = true;
289        }
290        debug!("parsed statements:\n{:#?}", stmts);
291        Ok(stmts)
292    }
293
294    /// Parse a single top-level statement (such as SELECT, INSERT, CREATE, etc.),
295    /// stopping before the statement separator, if any.
296    pub fn parse_statement(&mut self) -> ModalResult<Statement> {
297        let checkpoint = *self;
298        let token = self.next_token();
299        match token.token {
300            Token::Word(w) => match w.keyword {
301                Keyword::EXPLAIN => Ok(self.parse_explain()?),
302                Keyword::ANALYZE => Ok(self.parse_analyze()?),
303                Keyword::SELECT | Keyword::WITH | Keyword::VALUES => {
304                    *self = checkpoint;
305                    Ok(Statement::Query(Box::new(self.parse_query()?)))
306                }
307                Keyword::DECLARE => Ok(self.parse_declare()?),
308                Keyword::FETCH => Ok(self.parse_fetch_cursor()?),
309                Keyword::CLOSE => Ok(self.parse_close_cursor()?),
310                Keyword::TRUNCATE => Ok(self.parse_truncate()?),
311                Keyword::REFRESH => Ok(self.parse_refresh()?),
312                Keyword::CREATE => Ok(self.parse_create()?),
313                Keyword::REPLACE => Ok(self.parse_replace()?),
314                Keyword::DISCARD => Ok(self.parse_discard()?),
315                Keyword::DROP => Ok(self.parse_drop()?),
316                Keyword::DELETE => Ok(self.parse_delete()?),
317                Keyword::INSERT => Ok(self.parse_insert()?),
318                Keyword::UPDATE => Ok(self.parse_update()?),
319                Keyword::ALTER => Ok(self.parse_alter()?),
320                Keyword::COPY => Ok(self.parse_copy()?),
321                Keyword::SET => Ok(self.parse_set()?),
322                Keyword::SHOW => {
323                    if self.parse_keyword(Keyword::CREATE) {
324                        Ok(self.parse_show_create()?)
325                    } else {
326                        Ok(self.parse_show()?)
327                    }
328                }
329                Keyword::CANCEL => Ok(self.parse_cancel_job()?),
330                Keyword::KILL => Ok(self.parse_kill_process()?),
331                Keyword::DESCRIBE => Ok(self.parse_describe()?),
332                Keyword::GRANT => Ok(self.parse_grant()?),
333                Keyword::REVOKE => Ok(self.parse_revoke()?),
334                Keyword::START => Ok(self.parse_start_transaction()?),
335                Keyword::ABORT => Ok(Statement::Abort),
336                // `BEGIN` is a nonstandard but common alias for the
337                // standard `START TRANSACTION` statement. It is supported
338                // by at least PostgreSQL and MySQL.
339                Keyword::BEGIN => Ok(self.parse_begin()?),
340                Keyword::COMMIT => Ok(self.parse_commit()?),
341                Keyword::ROLLBACK => Ok(self.parse_rollback()?),
342                // `PREPARE`, `EXECUTE` and `DEALLOCATE` are Postgres-specific
343                // syntaxes. They are used for Postgres prepared statement.
344                Keyword::DEALLOCATE => Ok(self.parse_deallocate()?),
345                Keyword::EXECUTE => Ok(self.parse_execute()?),
346                Keyword::PREPARE => Ok(self.parse_prepare()?),
347                Keyword::COMMENT => Ok(self.parse_comment()?),
348                Keyword::FLUSH => Ok(Statement::Flush),
349                Keyword::WAIT => Ok(self.parse_wait()?),
350                Keyword::BACKUP => Ok(Statement::Backup),
351                Keyword::RECOVER => Ok(Statement::Recover),
352                Keyword::USE => Ok(self.parse_use()?),
353                Keyword::VACUUM => Ok(self.parse_vacuum()?),
354                _ => self.expected_at(checkpoint, "statement"),
355            },
356            Token::LParen => {
357                *self = checkpoint;
358                Ok(Statement::Query(Box::new(self.parse_query()?)))
359            }
360            _ => self.expected_at(checkpoint, "statement"),
361        }
362    }
363
364    pub fn parse_truncate(&mut self) -> ModalResult<Statement> {
365        let _ = self.parse_keyword(Keyword::TABLE);
366        let table_name = self.parse_object_name()?;
367        Ok(Statement::Truncate { table_name })
368    }
369
370    pub fn parse_refresh(&mut self) -> ModalResult<Statement> {
371        self.expect_keyword(Keyword::TABLE)?;
372        let table_name = self.parse_object_name()?;
373        Ok(Statement::Refresh { table_name })
374    }
375
376    pub fn parse_analyze(&mut self) -> ModalResult<Statement> {
377        let table_name = self.parse_object_name()?;
378
379        Ok(Statement::Analyze { table_name })
380    }
381
382    pub fn parse_vacuum(&mut self) -> ModalResult<Statement> {
383        let mode = if self.parse_keyword(Keyword::FULL) {
384            VacuumMode::Full
385        } else if self.parse_keyword(Keyword::ORPHAN) {
386            VacuumMode::OrphanFiles
387        } else {
388            VacuumMode::Default
389        };
390        let object_name = self.parse_object_name()?;
391
392        Ok(Statement::Vacuum { object_name, mode })
393    }
394
395    /// Tries to parse a wildcard expression. If it is not a wildcard, parses an expression.
396    ///
397    /// A wildcard expression either means:
398    /// - Selecting all fields from a struct. In this case, it is a
399    ///   [`WildcardOrExpr::ExprQualifiedWildcard`]. Similar to [`Expr::FieldIdentifier`], It must
400    ///   contain parentheses.
401    /// - Selecting all columns from a table. In this case, it is a
402    ///   [`WildcardOrExpr::QualifiedWildcard`] or a [`WildcardOrExpr::Wildcard`].
403    pub fn parse_wildcard_or_expr(&mut self) -> ModalResult<WildcardOrExpr> {
404        let checkpoint = *self;
405
406        match self.next_token().token {
407            Token::Word(w) if self.peek_token() == Token::Period => {
408                // Since there's no parenthesis, `w` must be a column or a table
409                // So what follows must be dot-delimited identifiers, e.g. `a.b.c.*`
410                let wildcard_expr = self.parse_simple_wildcard_expr(checkpoint)?;
411                return self.word_concat_wildcard_expr(w.to_ident()?, wildcard_expr);
412            }
413            Token::Mul => {
414                return Ok(WildcardOrExpr::Wildcard(self.parse_except()?));
415            }
416            // parses wildcard field selection expression.
417            // Code is similar to `parse_struct_selection`
418            Token::LParen => {
419                let mut expr = self.parse_expr()?;
420                if self.consume_token(&Token::RParen) {
421                    // Unwrap parentheses
422                    while let Expr::Nested(inner) = expr {
423                        expr = *inner;
424                    }
425                    // Now that we have an expr, what follows must be
426                    // dot-delimited identifiers, e.g. `b.c.*` in `(a).b.c.*`
427                    let wildcard_expr = self.parse_simple_wildcard_expr(checkpoint)?;
428                    return self.expr_concat_wildcard_expr(expr, wildcard_expr);
429                }
430            }
431            _ => (),
432        };
433
434        *self = checkpoint;
435        self.parse_expr().map(WildcardOrExpr::Expr)
436    }
437
438    /// Concats `ident` and `wildcard_expr` in `ident.wildcard_expr`
439    pub fn word_concat_wildcard_expr(
440        &mut self,
441        ident: Ident,
442        simple_wildcard_expr: WildcardOrExpr,
443    ) -> ModalResult<WildcardOrExpr> {
444        let mut idents = vec![ident];
445        let mut except_cols = vec![];
446        match simple_wildcard_expr {
447            WildcardOrExpr::QualifiedWildcard(ids, except) => {
448                idents.extend(ids.0);
449                if let Some(cols) = except {
450                    except_cols = cols;
451                }
452            }
453            WildcardOrExpr::Wildcard(except) => {
454                if let Some(cols) = except {
455                    except_cols = cols;
456                }
457            }
458            WildcardOrExpr::ExprQualifiedWildcard(_, _) => unreachable!(),
459            WildcardOrExpr::Expr(e) => return Ok(WildcardOrExpr::Expr(e)),
460        }
461        Ok(WildcardOrExpr::QualifiedWildcard(
462            ObjectName(idents),
463            if except_cols.is_empty() {
464                None
465            } else {
466                Some(except_cols)
467            },
468        ))
469    }
470
471    /// Concats `expr` and `wildcard_expr` in `(expr).wildcard_expr`.
472    pub fn expr_concat_wildcard_expr(
473        &mut self,
474        expr: Expr,
475        simple_wildcard_expr: WildcardOrExpr,
476    ) -> ModalResult<WildcardOrExpr> {
477        if let WildcardOrExpr::Expr(e) = simple_wildcard_expr {
478            return Ok(WildcardOrExpr::Expr(e));
479        }
480
481        // similar to `parse_struct_selection`
482        let mut idents = vec![];
483        let expr = match expr {
484            // expr is `(foo)`
485            Expr::Identifier(_) => expr,
486            // expr is `(foo.v1)`
487            Expr::CompoundIdentifier(_) => expr,
488            // expr is `((1,2,3)::foo)`
489            Expr::Cast { .. } => expr,
490            // expr is `(func())`
491            Expr::Function(_) => expr,
492            // expr is `((foo.v1).v2)`
493            Expr::FieldIdentifier(expr, ids) => {
494                // Put `ids` to the latter part!
495                idents.extend(ids);
496                *expr
497            }
498            // expr is other things, e.g., `(1+2)`. It will become an unexpected period error at
499            // upper level.
500            _ => return Ok(WildcardOrExpr::Expr(expr)),
501        };
502
503        match simple_wildcard_expr {
504            WildcardOrExpr::QualifiedWildcard(ids, except) => {
505                if except.is_some() {
506                    return self.expected("Expr quantified wildcard does not support except");
507                }
508                idents.extend(ids.0);
509            }
510            WildcardOrExpr::Wildcard(except) => {
511                if except.is_some() {
512                    return self.expected("Expr quantified wildcard does not support except");
513                }
514            }
515            WildcardOrExpr::ExprQualifiedWildcard(_, _) => unreachable!(),
516            WildcardOrExpr::Expr(_) => unreachable!(),
517        }
518        Ok(WildcardOrExpr::ExprQualifiedWildcard(expr, idents))
519    }
520
521    /// Tries to parses a wildcard expression without any parentheses.
522    ///
523    /// If wildcard is not found, go back to `index` and parse an expression.
524    pub fn parse_simple_wildcard_expr(&mut self, checkpoint: Self) -> ModalResult<WildcardOrExpr> {
525        let mut id_parts = vec![];
526        while self.consume_token(&Token::Period) {
527            let ckpt = *self;
528            let token = self.next_token();
529            match token.token {
530                Token::Word(w) => id_parts.push(w.to_ident()?),
531                Token::Mul => {
532                    return if id_parts.is_empty() {
533                        Ok(WildcardOrExpr::Wildcard(self.parse_except()?))
534                    } else {
535                        Ok(WildcardOrExpr::QualifiedWildcard(
536                            ObjectName(id_parts),
537                            self.parse_except()?,
538                        ))
539                    };
540                }
541                _ => {
542                    *self = ckpt;
543                    return self.expected("an identifier or a '*' after '.'");
544                }
545            }
546        }
547        *self = checkpoint;
548        self.parse_expr().map(WildcardOrExpr::Expr)
549    }
550
551    pub fn parse_except(&mut self) -> ModalResult<Option<Vec<Expr>>> {
552        if !self.parse_keyword(Keyword::EXCEPT) {
553            return Ok(None);
554        }
555        if !self.consume_token(&Token::LParen) {
556            return self.expected("EXCEPT should be followed by (");
557        }
558        let exprs = self.parse_comma_separated(Parser::parse_expr)?;
559        if self.consume_token(&Token::RParen) {
560            Ok(Some(exprs))
561        } else {
562            self.expected("( should be followed by ) after column names")
563        }
564    }
565
566    /// Parse a new expression
567    pub fn parse_expr(&mut self) -> ModalResult<Expr> {
568        self.parse_subexpr(Precedence::Zero)
569    }
570
571    /// Parse tokens until the precedence changes
572    pub fn parse_subexpr(&mut self, precedence: Precedence) -> ModalResult<Expr> {
573        debug!("parsing expr, current token: {:?}", self.peek_token().token);
574        let mut expr = self.parse_prefix()?;
575        debug!("prefix: {:?}", expr);
576        loop {
577            let next_precedence = self.get_next_precedence()?;
578            debug!("precedence: {precedence:?}, next precedence: {next_precedence:?}");
579
580            if precedence >= next_precedence {
581                break;
582            }
583
584            expr = self.parse_infix(expr, next_precedence)?;
585        }
586        Ok(expr)
587    }
588
589    /// Parse an expression prefix
590    pub fn parse_prefix(&mut self) -> ModalResult<Expr> {
591        // PostgreSQL allows any string literal to be preceded by a type name, indicating that the
592        // string literal represents a literal of that type. Some examples:
593        //
594        //      DATE '2020-05-20'
595        //      TIMESTAMP WITH TIME ZONE '2020-05-20 7:43:54'
596        //      BOOL 'true'
597        //
598        // The first two are standard SQL, while the latter is a PostgreSQL extension. Complicating
599        // matters is the fact that INTERVAL string literals may optionally be followed by special
600        // keywords, e.g.:
601        //
602        //      INTERVAL '7' DAY
603        //
604        // Note also that naively `SELECT date` looks like a syntax error because the `date` type
605        // name is not followed by a string literal, but in fact in PostgreSQL it is a valid
606        // expression that should parse as the column name "date".
607        return_ok_if_some!(self.maybe_parse(|parser| {
608            match parser.parse_data_type()? {
609                DataType::Interval => parser.parse_literal_interval(),
610                // PostgreSQL allows almost any identifier to be used as custom data type name,
611                // and we support that in `parse_data_type()`. But unlike Postgres we don't
612                // have a list of globally reserved keywords (since they vary across dialects),
613                // so given `NOT 'a' LIKE 'b'`, we'd accept `NOT` as a possible custom data type
614                // name, resulting in `NOT 'a'` being recognized as a `TypedString` instead of
615                // an unary negation `NOT ('a' LIKE 'b')`. To solve this, we don't accept the
616                // `type 'string'` syntax for the custom data types at all.
617                DataType::Custom(..) => parser_err!("dummy"),
618                data_type => Ok(Expr::TypedString {
619                    data_type,
620                    value: parser.parse_literal_string()?,
621                }),
622            }
623        }));
624
625        let checkpoint = *self;
626        let token = self.next_token();
627        let expr = match token.token.clone() {
628            Token::Word(w) => match w.keyword {
629                Keyword::TRUE | Keyword::FALSE | Keyword::NULL => {
630                    *self = checkpoint;
631                    Ok(Expr::Value(self.ensure_parse_value()?))
632                }
633                Keyword::CASE => self.parse_case_expr(),
634                Keyword::CAST => self.parse_cast_expr(),
635                Keyword::TRY_CAST => self.parse_try_cast_expr(),
636                Keyword::EXISTS => self.parse_exists_expr(),
637                Keyword::EXTRACT => self.parse_extract_expr(),
638                Keyword::SUBSTRING => self.parse_substring_expr(),
639                Keyword::POSITION => self.parse_position_expr(),
640                Keyword::OVERLAY => self.parse_overlay_expr(),
641                Keyword::TRIM => self.parse_trim_expr(),
642                Keyword::INTERVAL => self.parse_literal_interval(),
643                Keyword::NOT => Ok(Expr::UnaryOp {
644                    op: UnaryOperator::Not,
645                    expr: Box::new(self.parse_subexpr(Precedence::UnaryNot)?),
646                }),
647                Keyword::ROW => self.parse_row_expr(),
648                Keyword::ARRAY if self.peek_token() == Token::LParen => {
649                    // similar to `exists(subquery)`
650                    self.expect_token(&Token::LParen)?;
651                    let exists_node = Expr::ArraySubquery(Box::new(self.parse_query()?));
652                    self.expect_token(&Token::RParen)?;
653                    Ok(exists_node)
654                }
655                Keyword::ARRAY if self.peek_token() == Token::LBracket => self.parse_array_expr(),
656                Keyword::MAP if self.peek_token() == Token::LBrace => self.parse_map_expr(),
657                // `LEFT` and `RIGHT` are reserved as identifier but okay as function
658                Keyword::LEFT | Keyword::RIGHT => {
659                    *self = checkpoint;
660                    self.parse_function()
661                }
662                Keyword::OPERATOR if self.peek_token().token == Token::LParen => {
663                    let op = UnaryOperator::PGQualified(Box::new(self.parse_qualified_operator()?));
664                    Ok(Expr::UnaryOp {
665                        op,
666                        expr: Box::new(self.parse_subexpr(Precedence::Other)?),
667                    })
668                }
669                keyword @ (Keyword::ALL | Keyword::ANY | Keyword::SOME) => {
670                    self.expect_token(&Token::LParen)?;
671                    // In upstream's PR of parser-rs, there is `self.parser_subexpr(precedence)` here.
672                    // But it will fail to parse `select 1 = any(null and true);`.
673                    let sub = self.parse_expr()?;
674                    self.expect_token(&Token::RParen)?;
675
676                    // TODO: support `all/any/some(subquery)`.
677                    if let Expr::Subquery(_) = &sub {
678                        parser_err!("ANY/SOME/ALL(Subquery) is not implemented");
679                    }
680
681                    Ok(match keyword {
682                        Keyword::ALL => Expr::AllOp(Box::new(sub)),
683                        // `SOME` is a synonym for `ANY`.
684                        Keyword::ANY | Keyword::SOME => Expr::SomeOp(Box::new(sub)),
685                        _ => unreachable!(),
686                    })
687                }
688                k if keywords::RESERVED_FOR_COLUMN_OR_TABLE_NAME.contains(&k) => {
689                    parser_err!("syntax error at or near {token}")
690                }
691                Keyword::AGGREGATE => {
692                    *self = checkpoint;
693                    self.parse_function()
694                }
695                // Here `w` is a word, check if it's a part of a multi-part
696                // identifier, a function call, or a simple identifier:
697                _ => match self.peek_token().token {
698                    Token::LParen | Token::Period => {
699                        *self = checkpoint;
700                        if let Ok(object_name) = self.parse_object_name()
701                            && !matches!(self.peek_token().token, Token::LParen)
702                        {
703                            Ok(Expr::CompoundIdentifier(object_name.0))
704                        } else {
705                            *self = checkpoint;
706                            self.parse_function()
707                        }
708                    }
709                    _ => Ok(Expr::Identifier(w.to_ident()?)),
710                },
711            }, // End of Token::Word
712
713            tok @ Token::Minus | tok @ Token::Plus => {
714                let op = if tok == Token::Plus {
715                    UnaryOperator::Plus
716                } else {
717                    UnaryOperator::Minus
718                };
719                let mut sub_expr = self.parse_subexpr(Precedence::UnaryPosNeg)?;
720                if let Expr::Value(Value::Number(ref mut s)) = sub_expr {
721                    if tok == Token::Minus {
722                        *s = format!("-{}", s);
723                    }
724                    return Ok(sub_expr);
725                }
726                Ok(Expr::UnaryOp {
727                    op,
728                    expr: Box::new(sub_expr),
729                })
730            }
731            Token::Op(name) => {
732                let op = UnaryOperator::Custom(name);
733                // Counter-intuitively, `|/ 4 + 12` means `|/ (4+12)` rather than `(|/4) + 12` in
734                // PostgreSQL.
735                Ok(Expr::UnaryOp {
736                    op,
737                    expr: Box::new(self.parse_subexpr(Precedence::Other)?),
738                })
739            }
740            Token::Number(_)
741            | Token::SingleQuotedString(_)
742            | Token::DollarQuotedString(_)
743            | Token::NationalStringLiteral(_)
744            | Token::HexStringLiteral(_)
745            | Token::CstyleEscapesString(_) => {
746                *self = checkpoint;
747                Ok(Expr::Value(self.ensure_parse_value()?))
748            }
749            Token::Parameter(number) => self.parse_param(number),
750            Token::Pipe => {
751                let args = self.parse_comma_separated(Parser::parse_identifier)?;
752                self.expect_token(&Token::Pipe)?;
753                let body = self.parse_expr()?;
754                Ok(Expr::LambdaFunction {
755                    args,
756                    body: Box::new(body),
757                })
758            }
759            Token::LParen => {
760                let expr = if matches!(self.peek_token().token, Token::Word(w) if w.keyword == Keyword::SELECT || w.keyword == Keyword::WITH)
761                {
762                    Expr::Subquery(Box::new(self.parse_query()?))
763                } else {
764                    let mut exprs = self.parse_comma_separated(Parser::parse_expr)?;
765                    if exprs.len() == 1 {
766                        Expr::Nested(Box::new(exprs.pop().unwrap()))
767                    } else {
768                        Expr::Row(exprs)
769                    }
770                };
771                self.expect_token(&Token::RParen)?;
772                if self.peek_token() == Token::Period && matches!(expr, Expr::Nested(_)) {
773                    self.parse_struct_selection(expr)
774                } else {
775                    Ok(expr)
776                }
777            }
778            _ => self.expected_at(checkpoint, "an expression"),
779        }?;
780
781        if self.parse_keyword(Keyword::COLLATE) {
782            Ok(Expr::Collate {
783                expr: Box::new(expr),
784                collation: self.parse_object_name()?,
785            })
786        } else {
787            Ok(expr)
788        }
789    }
790
791    fn parse_param(&mut self, param: String) -> ModalResult<Expr> {
792        let Ok(index) = param.parse() else {
793            parser_err!("Parameter symbol has a invalid index {}.", param);
794        };
795        Ok(Expr::Parameter { index })
796    }
797
798    /// Parses a field selection expression. See also [`Expr::FieldIdentifier`].
799    pub fn parse_struct_selection(&mut self, expr: Expr) -> ModalResult<Expr> {
800        let mut nested_expr = expr;
801        // Unwrap parentheses
802        while let Expr::Nested(inner) = nested_expr {
803            nested_expr = *inner;
804        }
805        let fields = self.parse_fields()?;
806        Ok(Expr::FieldIdentifier(Box::new(nested_expr), fields))
807    }
808
809    /// Parses consecutive field identifiers after a period. i.e., `.foo.bar.baz`
810    pub fn parse_fields(&mut self) -> ModalResult<Vec<Ident>> {
811        repeat(.., preceded(Token::Period, cut_err(Self::parse_identifier))).parse_next(self)
812    }
813
814    pub fn parse_qualified_operator(&mut self) -> ModalResult<QualifiedOperator> {
815        self.expect_token(&Token::LParen)?;
816
817        let checkpoint = *self;
818        let schema = match self.parse_identifier_non_reserved() {
819            Ok(ident) => {
820                self.expect_token(&Token::Period)?;
821                Some(ident)
822            }
823            Err(_) => {
824                *self = checkpoint;
825                None
826            }
827        };
828
829        // https://www.postgresql.org/docs/15/sql-syntax-lexical.html#SQL-SYNTAX-OPERATORS
830        const OP_CHARS: &[char] = &[
831            '+', '-', '*', '/', '<', '>', '=', '~', '!', '@', '#', '%', '^', '&', '|', '`', '?',
832        ];
833        let name = {
834            // Unlike PostgreSQL, we only take 1 token here rather than any sequence of `OP_CHARS`.
835            // This is enough because we do not support custom operators like `x *@ y` anyways,
836            // and all builtin sequences are already single tokens.
837            //
838            // To support custom operators and be fully compatible with PostgreSQL later, the
839            // tokenizer should also be updated.
840            let checkpoint = *self;
841            let token = self.next_token();
842            let name = token.token.to_string();
843            if !name.trim_matches(OP_CHARS).is_empty() {
844                return self
845                    .expected_at(checkpoint, &format!("one of {}", OP_CHARS.iter().join(" ")));
846            }
847            name
848        };
849
850        self.expect_token(&Token::RParen)?;
851        Ok(QualifiedOperator { schema, name })
852    }
853
854    /// Parse a function call.
855    pub fn parse_function(&mut self) -> ModalResult<Expr> {
856        // [aggregate:]
857        let scalar_as_agg = if self.parse_keyword(Keyword::AGGREGATE) {
858            self.expect_token(&Token::Colon)?;
859            true
860        } else {
861            false
862        };
863        let name = self.parse_object_name()?;
864        let arg_list = self.parse_argument_list()?;
865
866        let within_group = if self.parse_keywords(&[Keyword::WITHIN, Keyword::GROUP]) {
867            self.expect_token(&Token::LParen)?;
868            self.expect_keywords(&[Keyword::ORDER, Keyword::BY])?;
869            let order_by = self.parse_order_by_expr()?;
870            self.expect_token(&Token::RParen)?;
871            Some(Box::new(order_by))
872        } else {
873            None
874        };
875
876        let filter = if self.parse_keyword(Keyword::FILTER) {
877            self.expect_token(&Token::LParen)?;
878            self.expect_keyword(Keyword::WHERE)?;
879            let filter_expr = self.parse_expr()?;
880            self.expect_token(&Token::RParen)?;
881            Some(Box::new(filter_expr))
882        } else {
883            None
884        };
885
886        let over = if self.parse_keyword(Keyword::OVER) {
887            if self.peek_token() == Token::LParen {
888                // Inline window specification: OVER (...)
889                self.expect_token(&Token::LParen)?;
890                let window_spec = self.parse_window_spec()?;
891                self.expect_token(&Token::RParen)?;
892                Some(Window::Spec(window_spec))
893            } else {
894                // Named window: OVER window_name
895                let window_name = self.parse_identifier()?;
896                Some(Window::Name(window_name))
897            }
898        } else {
899            None
900        };
901
902        Ok(Expr::Function(Function {
903            scalar_as_agg,
904            name,
905            arg_list,
906            within_group,
907            filter,
908            over,
909        }))
910    }
911
912    pub fn parse_window_frame_units(&mut self) -> ModalResult<WindowFrameUnits> {
913        dispatch! { peek(keyword);
914            Keyword::ROWS => keyword.value(WindowFrameUnits::Rows),
915            Keyword::RANGE => keyword.value(WindowFrameUnits::Range),
916            Keyword::GROUPS => keyword.value(WindowFrameUnits::Groups),
917            Keyword::SESSION => keyword.value(WindowFrameUnits::Session),
918            _ => fail,
919        }
920        .expect("ROWS, RANGE, or GROUPS")
921        .parse_next(self)
922    }
923
924    pub fn parse_window_frame(&mut self) -> ModalResult<WindowFrame> {
925        let units = self.parse_window_frame_units()?;
926        let bounds = if self.parse_keyword(Keyword::BETWEEN) {
927            // `BETWEEN <frame_start> AND <frame_end>`
928            let start = self.parse_window_frame_bound()?;
929            self.expect_keyword(Keyword::AND)?;
930            let end = Some(self.parse_window_frame_bound()?);
931            WindowFrameBounds::Bounds { start, end }
932        } else if self.parse_keywords(&[Keyword::WITH, Keyword::GAP]) {
933            // `WITH GAP <gap>`, only for session frames
934            WindowFrameBounds::Gap(Box::new(self.parse_expr()?))
935        } else {
936            // `<frame_start>`
937            WindowFrameBounds::Bounds {
938                start: self.parse_window_frame_bound()?,
939                end: None,
940            }
941        };
942        let exclusion = if self.parse_keyword(Keyword::EXCLUDE) {
943            Some(self.parse_window_frame_exclusion()?)
944        } else {
945            None
946        };
947        Ok(WindowFrame {
948            units,
949            bounds,
950            exclusion,
951        })
952    }
953
954    /// Parse `CURRENT ROW` or `{ <non-negative numeric | datetime | interval> | UNBOUNDED } { PRECEDING | FOLLOWING }`
955    pub fn parse_window_frame_bound(&mut self) -> ModalResult<WindowFrameBound> {
956        if self.parse_keywords(&[Keyword::CURRENT, Keyword::ROW]) {
957            Ok(WindowFrameBound::CurrentRow)
958        } else {
959            let rows = if self.parse_keyword(Keyword::UNBOUNDED) {
960                None
961            } else {
962                Some(Box::new(self.parse_expr()?))
963            };
964            if self.parse_keyword(Keyword::PRECEDING) {
965                Ok(WindowFrameBound::Preceding(rows))
966            } else if self.parse_keyword(Keyword::FOLLOWING) {
967                Ok(WindowFrameBound::Following(rows))
968            } else {
969                self.expected("PRECEDING or FOLLOWING")
970            }
971        }
972    }
973
974    pub fn parse_window_frame_exclusion(&mut self) -> ModalResult<WindowFrameExclusion> {
975        if self.parse_keywords(&[Keyword::CURRENT, Keyword::ROW]) {
976            Ok(WindowFrameExclusion::CurrentRow)
977        } else if self.parse_keyword(Keyword::GROUP) {
978            Ok(WindowFrameExclusion::Group)
979        } else if self.parse_keyword(Keyword::TIES) {
980            Ok(WindowFrameExclusion::Ties)
981        } else if self.parse_keywords(&[Keyword::NO, Keyword::OTHERS]) {
982            Ok(WindowFrameExclusion::NoOthers)
983        } else {
984            self.expected("CURRENT ROW, GROUP, TIES, or NO OTHERS")
985        }
986    }
987
988    /// parse a group by expr. a group by expr can be one of group sets, roll up, cube, or simple
989    /// expr.
990    fn parse_group_by_expr(&mut self) -> ModalResult<Expr> {
991        if self.parse_keywords(&[Keyword::GROUPING, Keyword::SETS]) {
992            self.expect_token(&Token::LParen)?;
993            let result = self.parse_comma_separated(|p| p.parse_tuple(true, true))?;
994            self.expect_token(&Token::RParen)?;
995            Ok(Expr::GroupingSets(result))
996        } else if self.parse_keyword(Keyword::CUBE) {
997            self.expect_token(&Token::LParen)?;
998            let result = self.parse_comma_separated(|p| p.parse_tuple(true, false))?;
999            self.expect_token(&Token::RParen)?;
1000            Ok(Expr::Cube(result))
1001        } else if self.parse_keyword(Keyword::ROLLUP) {
1002            self.expect_token(&Token::LParen)?;
1003            let result = self.parse_comma_separated(|p| p.parse_tuple(true, false))?;
1004            self.expect_token(&Token::RParen)?;
1005            Ok(Expr::Rollup(result))
1006        } else {
1007            self.parse_expr()
1008        }
1009    }
1010
1011    /// parse a tuple with `(` and `)`.
1012    /// If `lift_singleton` is true, then a singleton tuple is lifted to a tuple of length 1,
1013    /// otherwise it will fail. If `allow_empty` is true, then an empty tuple is allowed.
1014    fn parse_tuple(&mut self, lift_singleton: bool, allow_empty: bool) -> ModalResult<Vec<Expr>> {
1015        if lift_singleton {
1016            if self.consume_token(&Token::LParen) {
1017                let result = if allow_empty && self.consume_token(&Token::RParen) {
1018                    vec![]
1019                } else {
1020                    let result = self.parse_comma_separated(Parser::parse_expr)?;
1021                    self.expect_token(&Token::RParen)?;
1022                    result
1023                };
1024                Ok(result)
1025            } else {
1026                Ok(vec![self.parse_expr()?])
1027            }
1028        } else {
1029            self.expect_token(&Token::LParen)?;
1030            let result = if allow_empty && self.consume_token(&Token::RParen) {
1031                vec![]
1032            } else {
1033                let result = self.parse_comma_separated(Parser::parse_expr)?;
1034                self.expect_token(&Token::RParen)?;
1035                result
1036            };
1037            Ok(result)
1038        }
1039    }
1040
1041    pub fn parse_case_expr(&mut self) -> ModalResult<Expr> {
1042        parser_v2::expr_case(self)
1043    }
1044
1045    /// Parse a SQL CAST function e.g. `CAST(expr AS FLOAT)`
1046    pub fn parse_cast_expr(&mut self) -> ModalResult<Expr> {
1047        parser_v2::expr_cast(self)
1048    }
1049
1050    /// Parse a SQL TRY_CAST function e.g. `TRY_CAST(expr AS FLOAT)`
1051    pub fn parse_try_cast_expr(&mut self) -> ModalResult<Expr> {
1052        parser_v2::expr_try_cast(self)
1053    }
1054
1055    /// Parse a SQL EXISTS expression e.g. `WHERE EXISTS(SELECT ...)`.
1056    pub fn parse_exists_expr(&mut self) -> ModalResult<Expr> {
1057        self.expect_token(&Token::LParen)?;
1058        let exists_node = Expr::Exists(Box::new(self.parse_query()?));
1059        self.expect_token(&Token::RParen)?;
1060        Ok(exists_node)
1061    }
1062
1063    pub fn parse_extract_expr(&mut self) -> ModalResult<Expr> {
1064        parser_v2::expr_extract(self)
1065    }
1066
1067    pub fn parse_substring_expr(&mut self) -> ModalResult<Expr> {
1068        parser_v2::expr_substring(self)
1069    }
1070
1071    /// `POSITION(<expr> IN <expr>)`
1072    pub fn parse_position_expr(&mut self) -> ModalResult<Expr> {
1073        parser_v2::expr_position(self)
1074    }
1075
1076    /// `OVERLAY(<expr> PLACING <expr> FROM <expr> [ FOR <expr> ])`
1077    pub fn parse_overlay_expr(&mut self) -> ModalResult<Expr> {
1078        parser_v2::expr_overlay(self)
1079    }
1080
1081    /// `TRIM ([WHERE] ['text'] FROM 'text')`\
1082    /// `TRIM ([WHERE] [FROM] 'text' [, 'text'])`
1083    pub fn parse_trim_expr(&mut self) -> ModalResult<Expr> {
1084        self.expect_token(&Token::LParen)?;
1085        let mut trim_where = None;
1086        if let Token::Word(word) = self.peek_token().token
1087            && [Keyword::BOTH, Keyword::LEADING, Keyword::TRAILING].contains(&word.keyword)
1088        {
1089            trim_where = Some(self.parse_trim_where()?);
1090        }
1091
1092        let (mut trim_what, expr) = if self.parse_keyword(Keyword::FROM) {
1093            (None, self.parse_expr()?)
1094        } else {
1095            let mut expr = self.parse_expr()?;
1096            if self.parse_keyword(Keyword::FROM) {
1097                let trim_what = std::mem::replace(&mut expr, self.parse_expr()?);
1098                (Some(Box::new(trim_what)), expr)
1099            } else {
1100                (None, expr)
1101            }
1102        };
1103
1104        if trim_what.is_none() && self.consume_token(&Token::Comma) {
1105            trim_what = Some(Box::new(self.parse_expr()?));
1106        }
1107        self.expect_token(&Token::RParen)?;
1108
1109        Ok(Expr::Trim {
1110            expr: Box::new(expr),
1111            trim_where,
1112            trim_what,
1113        })
1114    }
1115
1116    pub fn parse_trim_where(&mut self) -> ModalResult<TrimWhereField> {
1117        dispatch! { peek(keyword);
1118            Keyword::BOTH => keyword.value(TrimWhereField::Both),
1119            Keyword::LEADING => keyword.value(TrimWhereField::Leading),
1120            Keyword::TRAILING => keyword.value(TrimWhereField::Trailing),
1121            _ => fail
1122        }
1123        .expect("BOTH, LEADING, or TRAILING")
1124        .parse_next(self)
1125    }
1126
1127    /// Parses an array expression `[ex1, ex2, ..]`
1128    pub fn parse_array_expr(&mut self) -> ModalResult<Expr> {
1129        let mut expected_depth = None;
1130        let exprs = self.parse_array_inner(0, &mut expected_depth)?;
1131        Ok(Expr::Array(Array {
1132            elem: exprs,
1133            // Top-level array is named.
1134            named: true,
1135        }))
1136    }
1137
1138    fn parse_array_inner(
1139        &mut self,
1140        depth: usize,
1141        expected_depth: &mut Option<usize>,
1142    ) -> ModalResult<Vec<Expr>> {
1143        self.expect_token(&Token::LBracket)?;
1144        if let Some(expected_depth) = *expected_depth
1145            && depth > expected_depth
1146        {
1147            return self.expected("]");
1148        }
1149        let exprs = if self.peek_token() == Token::LBracket {
1150            self.parse_comma_separated(|parser| {
1151                let exprs = parser.parse_array_inner(depth + 1, expected_depth)?;
1152                Ok(Expr::Array(Array {
1153                    elem: exprs,
1154                    named: false,
1155                }))
1156            })?
1157        } else {
1158            if let Some(expected_depth) = *expected_depth {
1159                if depth < expected_depth {
1160                    return self.expected("[");
1161                }
1162            } else {
1163                *expected_depth = Some(depth);
1164            }
1165            if self.consume_token(&Token::RBracket) {
1166                return Ok(vec![]);
1167            }
1168            self.parse_comma_separated(Self::parse_expr)?
1169        };
1170        self.expect_token(&Token::RBracket)?;
1171        Ok(exprs)
1172    }
1173
1174    /// Parses a map expression `MAP {k1:v1, k2:v2, ..}`
1175    pub fn parse_map_expr(&mut self) -> ModalResult<Expr> {
1176        self.expect_token(&Token::LBrace)?;
1177        if self.consume_token(&Token::RBrace) {
1178            return Ok(Expr::Map { entries: vec![] });
1179        }
1180        let entries = self.parse_comma_separated(|parser| {
1181            let key = parser.parse_expr()?;
1182            parser.expect_token(&Token::Colon)?;
1183            let value = parser.parse_expr()?;
1184            Ok((key, value))
1185        })?;
1186        self.expect_token(&Token::RBrace)?;
1187        Ok(Expr::Map { entries })
1188    }
1189
1190    // This function parses date/time fields for interval qualifiers.
1191    pub fn parse_date_time_field(&mut self) -> ModalResult<DateTimeField> {
1192        dispatch! { peek(keyword);
1193            Keyword::YEAR => keyword.value(DateTimeField::Year),
1194            Keyword::MONTH => keyword.value(DateTimeField::Month),
1195            Keyword::DAY => keyword.value(DateTimeField::Day),
1196            Keyword::HOUR => keyword.value(DateTimeField::Hour),
1197            Keyword::MINUTE => keyword.value(DateTimeField::Minute),
1198            Keyword::SECOND => keyword.value(DateTimeField::Second),
1199            _ => fail,
1200        }
1201        .expect("date/time field")
1202        .parse_next(self)
1203    }
1204
1205    // This function parses date/time fields for the EXTRACT function-like operator. PostgreSQL
1206    // allows arbitrary inputs including invalid ones.
1207    //
1208    // ```
1209    //   select extract(day from null::date);
1210    //   select extract(invalid from null::date);
1211    //   select extract("invaLId" from null::date);
1212    //   select extract('invaLId' from null::date);
1213    // ```
1214    pub fn parse_date_time_field_in_extract(&mut self) -> ModalResult<String> {
1215        let checkpoint = *self;
1216        let token = self.next_token();
1217        match token.token {
1218            Token::Word(w) => Ok(w.value.to_uppercase()),
1219            Token::SingleQuotedString(s) => Ok(s.to_uppercase()),
1220            _ => {
1221                *self = checkpoint;
1222                self.expected("date/time field")
1223            }
1224        }
1225    }
1226
1227    /// Parse an INTERVAL literal.
1228    ///
1229    /// Some syntactically valid intervals:
1230    ///
1231    ///   1. `INTERVAL '1' DAY`
1232    ///   2. `INTERVAL '1-1' YEAR TO MONTH`
1233    ///   3. `INTERVAL '1' SECOND`
1234    ///   4. `INTERVAL '1:1:1.1' HOUR (5) TO SECOND (5)`
1235    ///   5. `INTERVAL '1.1' SECOND (2, 2)`
1236    ///   6. `INTERVAL '1:1' HOUR (5) TO MINUTE (5)`
1237    ///
1238    /// Note that we do not currently attempt to parse the quoted value.
1239    pub fn parse_literal_interval(&mut self) -> ModalResult<Expr> {
1240        // The SQL standard allows an optional sign before the value string, but
1241        // it is not clear if any implementations support that syntax, so we
1242        // don't currently try to parse it. (The sign can instead be included
1243        // inside the value string.)
1244
1245        // The first token in an interval is a string literal which specifies
1246        // the duration of the interval.
1247        let value = self.parse_literal_string()?;
1248
1249        // Following the string literal is a qualifier which indicates the units
1250        // of the duration specified in the string literal.
1251        //
1252        // Note that PostgreSQL allows omitting the qualifier, so we provide
1253        // this more general implementation.
1254        let leading_field = match self.peek_token().token {
1255            Token::Word(kw)
1256                if [
1257                    Keyword::YEAR,
1258                    Keyword::MONTH,
1259                    Keyword::DAY,
1260                    Keyword::HOUR,
1261                    Keyword::MINUTE,
1262                    Keyword::SECOND,
1263                ]
1264                .contains(&kw.keyword) =>
1265            {
1266                Some(self.parse_date_time_field()?)
1267            }
1268            _ => None,
1269        };
1270
1271        let (leading_precision, last_field, fsec_precision) =
1272            if leading_field == Some(DateTimeField::Second) {
1273                // SQL mandates special syntax for `SECOND TO SECOND` literals.
1274                // Instead of
1275                //     `SECOND [(<leading precision>)] TO SECOND[(<fractional seconds precision>)]`
1276                // one must use the special format:
1277                //     `SECOND [( <leading precision> [ , <fractional seconds precision>] )]`
1278                let last_field = None;
1279                let (leading_precision, fsec_precision) = self.parse_optional_precision_scale()?;
1280                (leading_precision, last_field, fsec_precision)
1281            } else {
1282                let leading_precision = self.parse_optional_precision()?;
1283                if self.parse_keyword(Keyword::TO) {
1284                    let last_field = Some(self.parse_date_time_field()?);
1285                    let fsec_precision = if last_field == Some(DateTimeField::Second) {
1286                        self.parse_optional_precision()?
1287                    } else {
1288                        None
1289                    };
1290                    (leading_precision, last_field, fsec_precision)
1291                } else {
1292                    (leading_precision, None, None)
1293                }
1294            };
1295
1296        Ok(Expr::Value(Value::Interval {
1297            value,
1298            leading_field,
1299            leading_precision,
1300            last_field,
1301            fractional_seconds_precision: fsec_precision,
1302        }))
1303    }
1304
1305    /// Parse an operator following an expression
1306    pub fn parse_infix(&mut self, expr: Expr, precedence: Precedence) -> ModalResult<Expr> {
1307        let checkpoint = *self;
1308        let tok = self.next_token();
1309        debug!("parsing infix {:?}", tok.token);
1310        let regular_binary_operator = match &tok.token {
1311            Token::Eq => Some(BinaryOperator::Eq),
1312            Token::Neq => Some(BinaryOperator::NotEq),
1313            Token::Gt => Some(BinaryOperator::Gt),
1314            Token::GtEq => Some(BinaryOperator::GtEq),
1315            Token::Lt => Some(BinaryOperator::Lt),
1316            Token::LtEq => Some(BinaryOperator::LtEq),
1317            Token::Plus => Some(BinaryOperator::Plus),
1318            Token::Minus => Some(BinaryOperator::Minus),
1319            Token::Mul => Some(BinaryOperator::Multiply),
1320            Token::Mod => Some(BinaryOperator::Modulo),
1321            Token::Pipe => Some(BinaryOperator::Custom("|".to_owned())),
1322            Token::Caret => Some(BinaryOperator::Pow),
1323            Token::Div => Some(BinaryOperator::Divide),
1324            Token::Op(name) => Some(BinaryOperator::Custom(name.clone())),
1325            Token::Word(w) => match w.keyword {
1326                Keyword::AND => Some(BinaryOperator::And),
1327                Keyword::OR => Some(BinaryOperator::Or),
1328                Keyword::XOR => Some(BinaryOperator::Xor),
1329                Keyword::OPERATOR if self.peek_token() == Token::LParen => Some(
1330                    BinaryOperator::PGQualified(Box::new(self.parse_qualified_operator()?)),
1331                ),
1332                _ => None,
1333            },
1334            _ => None,
1335        };
1336
1337        if let Some(op) = regular_binary_operator {
1338            // // `all/any/some` only appears to the right of the binary op.
1339            // if let Some(keyword) =
1340            //     self.parse_one_of_keywords(&[Keyword::ANY, Keyword::ALL, Keyword::SOME])
1341            // {
1342            //     self.expect_token(&Token::LParen)?;
1343            //     // In upstream's PR of parser-rs, there is `self.parser_subexpr(precedence)` here.
1344            //     // But it will fail to parse `select 1 = any(null and true);`.
1345            //     let right = self.parse_expr()?;
1346            //     self.expect_token(&Token::RParen)?;
1347
1348            //     // TODO: support `all/any/some(subquery)`.
1349            //     if let Expr::Subquery(_) = &right {
1350            //         parser_err!("ANY/SOME/ALL(Subquery) is not implemented");
1351            //     }
1352
1353            //     let right = match keyword {
1354            //         Keyword::ALL => Box::new(Expr::AllOp(Box::new(right))),
1355            //         // `SOME` is a synonym for `ANY`.
1356            //         Keyword::ANY | Keyword::SOME => Box::new(Expr::SomeOp(Box::new(right))),
1357            //         _ => unreachable!(),
1358            //     };
1359
1360            //     Ok(Expr::BinaryOp {
1361            //         left: Box::new(expr),
1362            //         op,
1363            //         right,
1364            //     })
1365            // } else {
1366            Ok(Expr::BinaryOp {
1367                left: Box::new(expr),
1368                op,
1369                right: Box::new(self.parse_subexpr(precedence)?),
1370            })
1371            // }
1372        } else if let Token::Word(w) = &tok.token {
1373            match w.keyword {
1374                Keyword::IS => {
1375                    if self.parse_keyword(Keyword::TRUE) {
1376                        Ok(Expr::IsTrue(Box::new(expr)))
1377                    } else if self.parse_keywords(&[Keyword::NOT, Keyword::TRUE]) {
1378                        Ok(Expr::IsNotTrue(Box::new(expr)))
1379                    } else if self.parse_keyword(Keyword::FALSE) {
1380                        Ok(Expr::IsFalse(Box::new(expr)))
1381                    } else if self.parse_keywords(&[Keyword::NOT, Keyword::FALSE]) {
1382                        Ok(Expr::IsNotFalse(Box::new(expr)))
1383                    } else if self.parse_keyword(Keyword::UNKNOWN) {
1384                        Ok(Expr::IsUnknown(Box::new(expr)))
1385                    } else if self.parse_keywords(&[Keyword::NOT, Keyword::UNKNOWN]) {
1386                        Ok(Expr::IsNotUnknown(Box::new(expr)))
1387                    } else if self.parse_keyword(Keyword::NULL) {
1388                        Ok(Expr::IsNull(Box::new(expr)))
1389                    } else if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) {
1390                        Ok(Expr::IsNotNull(Box::new(expr)))
1391                    } else if self.parse_keywords(&[Keyword::DISTINCT, Keyword::FROM]) {
1392                        let expr2 = self.parse_is_distinct_from_rhs()?;
1393                        Ok(Expr::IsDistinctFrom(Box::new(expr), Box::new(expr2)))
1394                    } else if self.parse_keywords(&[Keyword::NOT, Keyword::DISTINCT, Keyword::FROM])
1395                    {
1396                        let expr2 = self.parse_is_distinct_from_rhs()?;
1397                        Ok(Expr::IsNotDistinctFrom(Box::new(expr), Box::new(expr2)))
1398                    } else {
1399                        let negated = self.parse_keyword(Keyword::NOT);
1400
1401                        if self.parse_keyword(Keyword::JSON) {
1402                            self.parse_is_json(expr, negated)
1403                        } else {
1404                            self.expected(
1405                                "[NOT] { TRUE | FALSE | UNKNOWN | NULL | DISTINCT FROM | JSON } after IS",
1406                            )
1407                        }
1408                    }
1409                }
1410                Keyword::AT => {
1411                    assert_eq!(precedence, Precedence::At);
1412                    let time_zone = Box::new(
1413                        preceded(
1414                            (Keyword::TIME, Keyword::ZONE),
1415                            cut_err(|p: &mut Self| p.parse_subexpr(precedence)),
1416                        )
1417                        .parse_next(self)?,
1418                    );
1419                    Ok(Expr::AtTimeZone {
1420                        timestamp: Box::new(expr),
1421                        time_zone,
1422                    })
1423                }
1424                keyword @ (Keyword::ALL | Keyword::ANY | Keyword::SOME) => {
1425                    self.expect_token(&Token::LParen)?;
1426                    // In upstream's PR of parser-rs, there is `self.parser_subexpr(precedence)` here.
1427                    // But it will fail to parse `select 1 = any(null and true);`.
1428                    let sub = self.parse_expr()?;
1429                    self.expect_token(&Token::RParen)?;
1430
1431                    // TODO: support `all/any/some(subquery)`.
1432                    if let Expr::Subquery(_) = &sub {
1433                        parser_err!("ANY/SOME/ALL(Subquery) is not implemented");
1434                    }
1435
1436                    Ok(match keyword {
1437                        Keyword::ALL => Expr::AllOp(Box::new(sub)),
1438                        // `SOME` is a synonym for `ANY`.
1439                        Keyword::ANY | Keyword::SOME => Expr::SomeOp(Box::new(sub)),
1440                        _ => unreachable!(),
1441                    })
1442                }
1443                Keyword::NOT
1444                | Keyword::IN
1445                | Keyword::BETWEEN
1446                | Keyword::LIKE
1447                | Keyword::ILIKE
1448                | Keyword::SIMILAR => {
1449                    *self = checkpoint;
1450                    let negated = self.parse_keyword(Keyword::NOT);
1451                    if self.parse_keyword(Keyword::IN) {
1452                        self.parse_in(expr, negated)
1453                    } else if self.parse_keyword(Keyword::BETWEEN) {
1454                        self.parse_between(expr, negated)
1455                    } else if self.parse_keyword(Keyword::LIKE) {
1456                        Ok(Expr::Like {
1457                            negated,
1458                            expr: Box::new(expr),
1459                            pattern: Box::new(self.parse_subexpr(Precedence::Like)?),
1460                            escape_char: self.parse_escape()?,
1461                        })
1462                    } else if self.parse_keyword(Keyword::ILIKE) {
1463                        Ok(Expr::ILike {
1464                            negated,
1465                            expr: Box::new(expr),
1466                            pattern: Box::new(self.parse_subexpr(Precedence::Like)?),
1467                            escape_char: self.parse_escape()?,
1468                        })
1469                    } else if self.parse_keywords(&[Keyword::SIMILAR, Keyword::TO]) {
1470                        Ok(Expr::SimilarTo {
1471                            negated,
1472                            expr: Box::new(expr),
1473                            pattern: Box::new(self.parse_subexpr(Precedence::Like)?),
1474                            escape_char: self.parse_escape()?,
1475                        })
1476                    } else {
1477                        self.expected("IN, BETWEEN or SIMILAR TO after NOT")
1478                    }
1479                }
1480                // Can only happen if `get_next_precedence` got out of sync with this function
1481                _ => parser_err!("No infix parser for token {:?}", tok),
1482            }
1483        } else if Token::DoubleColon == tok {
1484            self.parse_pg_cast(expr)
1485        } else if Token::LBracket == tok {
1486            self.parse_array_index(expr)
1487        } else {
1488            // Can only happen if `get_next_precedence` got out of sync with this function
1489            parser_err!("No infix parser for token {:?}", tok)
1490        }
1491    }
1492
1493    /// parse the ESCAPE CHAR portion of LIKE, ILIKE, and SIMILAR TO
1494    pub fn parse_escape(&mut self) -> ModalResult<Option<EscapeChar>> {
1495        if self.parse_keyword(Keyword::ESCAPE) {
1496            let s = self.parse_literal_string()?;
1497            let mut chs = s.chars();
1498            if let Some(ch) = chs.next() {
1499                if chs.next().is_some() {
1500                    parser_err!("Escape string must be empty or one character, found {s:?}")
1501                } else {
1502                    Ok(Some(EscapeChar::escape(ch)))
1503                }
1504            } else {
1505                Ok(Some(EscapeChar::empty()))
1506            }
1507        } else {
1508            Ok(None)
1509        }
1510    }
1511
1512    /// We parse both `array[1,9][1]`, `array[1,9][1:2]`, `array[1,9][:2]`, `array[1,9][1:]` and
1513    /// `array[1,9][:]` in this function.
1514    pub fn parse_array_index(&mut self, expr: Expr) -> ModalResult<Expr> {
1515        let new_expr = match self.peek_token().token {
1516            Token::Colon => {
1517                // [:] or [:N]
1518                assert!(self.consume_token(&Token::Colon));
1519                let end = match self.peek_token().token {
1520                    Token::RBracket => None,
1521                    _ => {
1522                        let end_index = Box::new(self.parse_expr()?);
1523                        Some(end_index)
1524                    }
1525                };
1526                Expr::ArrayRangeIndex {
1527                    obj: Box::new(expr),
1528                    start: None,
1529                    end,
1530                }
1531            }
1532            _ => {
1533                // [N], [N:], [N:M]
1534                let index = Box::new(self.parse_expr()?);
1535                match self.peek_token().token {
1536                    Token::Colon => {
1537                        // [N:], [N:M]
1538                        assert!(self.consume_token(&Token::Colon));
1539                        match self.peek_token().token {
1540                            Token::RBracket => {
1541                                // [N:]
1542                                Expr::ArrayRangeIndex {
1543                                    obj: Box::new(expr),
1544                                    start: Some(index),
1545                                    end: None,
1546                                }
1547                            }
1548                            _ => {
1549                                // [N:M]
1550                                let end = Some(Box::new(self.parse_expr()?));
1551                                Expr::ArrayRangeIndex {
1552                                    obj: Box::new(expr),
1553                                    start: Some(index),
1554                                    end,
1555                                }
1556                            }
1557                        }
1558                    }
1559                    _ => {
1560                        // [N]
1561                        Expr::Index {
1562                            obj: Box::new(expr),
1563                            index,
1564                        }
1565                    }
1566                }
1567            }
1568        };
1569        self.expect_token(&Token::RBracket)?;
1570        // recursively checking for more indices
1571        if self.consume_token(&Token::LBracket) {
1572            self.parse_array_index(new_expr)
1573        } else {
1574            Ok(new_expr)
1575        }
1576    }
1577
1578    /// Parses the right operand of `IS [NOT] DISTINCT FROM`.
1579    ///
1580    /// Like PostgreSQL, where `IS` is non-associative, rejects another `IS`, `ISNULL`, or
1581    /// `NOTNULL` right after the operand.
1582    fn parse_is_distinct_from_rhs(&mut self) -> ModalResult<Expr> {
1583        let expr = self.parse_subexpr(Precedence::Is)?;
1584
1585        if self.get_next_precedence()? == Precedence::Is {
1586            parser_err!("syntax error at or near {}", self.peek_token().token);
1587        }
1588
1589        Ok(expr)
1590    }
1591
1592    /// Parses the optional constraints following the `IS [NOT] JSON` predicate
1593    pub fn parse_is_json(&mut self, expr: Expr, negated: bool) -> ModalResult<Expr> {
1594        let item_type = match self.peek_token().token {
1595            Token::Word(w) => match w.keyword {
1596                Keyword::VALUE => Some(JsonPredicateType::Value),
1597                Keyword::ARRAY => Some(JsonPredicateType::Array),
1598                Keyword::OBJECT => Some(JsonPredicateType::Object),
1599                Keyword::SCALAR => Some(JsonPredicateType::Scalar),
1600                _ => None,
1601            },
1602            _ => None,
1603        };
1604        if item_type.is_some() {
1605            self.next_token();
1606        }
1607        let item_type = item_type.unwrap_or_default();
1608
1609        let unique_keys = self.parse_one_of_keywords(&[Keyword::WITH, Keyword::WITHOUT]);
1610        if unique_keys.is_some() {
1611            self.expect_keyword(Keyword::UNIQUE)?;
1612            _ = self.parse_keyword(Keyword::KEYS);
1613        }
1614        let unique_keys = unique_keys.is_some_and(|w| w == Keyword::WITH);
1615
1616        Ok(Expr::IsJson {
1617            expr: Box::new(expr),
1618            negated,
1619            item_type,
1620            unique_keys,
1621        })
1622    }
1623
1624    /// Parses the parens following the `[ NOT ] IN` operator
1625    pub fn parse_in(&mut self, expr: Expr, negated: bool) -> ModalResult<Expr> {
1626        self.expect_token(&Token::LParen)?;
1627        let in_op = if matches!(self.peek_token().token, Token::Word(w) if w.keyword == Keyword::SELECT || w.keyword == Keyword::WITH)
1628        {
1629            Expr::InSubquery {
1630                expr: Box::new(expr),
1631                subquery: Box::new(self.parse_query()?),
1632                negated,
1633            }
1634        } else {
1635            Expr::InList {
1636                expr: Box::new(expr),
1637                list: self.parse_comma_separated(Parser::parse_expr)?,
1638                negated,
1639            }
1640        };
1641        self.expect_token(&Token::RParen)?;
1642        Ok(in_op)
1643    }
1644
1645    /// Parses `BETWEEN <low> AND <high>`, assuming the `BETWEEN` keyword was already consumed
1646    pub fn parse_between(&mut self, expr: Expr, negated: bool) -> ModalResult<Expr> {
1647        // Stop parsing subexpressions for <low> and <high> on tokens with
1648        // precedence lower than that of `BETWEEN`, such as `AND`, `IS`, etc.
1649        let low = self.parse_subexpr(Precedence::Between)?;
1650        self.expect_keyword(Keyword::AND)?;
1651        let high = self.parse_subexpr(Precedence::Between)?;
1652        Ok(Expr::Between {
1653            expr: Box::new(expr),
1654            negated,
1655            low: Box::new(low),
1656            high: Box::new(high),
1657        })
1658    }
1659
1660    /// Parse a postgresql casting style which is in the form of `expr::datatype`
1661    pub fn parse_pg_cast(&mut self, expr: Expr) -> ModalResult<Expr> {
1662        Ok(Expr::Cast {
1663            expr: Box::new(expr),
1664            data_type: self.parse_data_type()?,
1665        })
1666    }
1667
1668    /// Get the precedence of the next token
1669    pub fn get_next_precedence(&self) -> ModalResult<Precedence> {
1670        use Precedence as P;
1671
1672        let token = self.peek_token();
1673        debug!("get_next_precedence() {:?}", token);
1674        match token.token {
1675            Token::Word(w) if w.keyword == Keyword::OR => Ok(P::LogicalOr),
1676            Token::Word(w) if w.keyword == Keyword::XOR => Ok(P::LogicalXor),
1677            Token::Word(w) if w.keyword == Keyword::AND => Ok(P::LogicalAnd),
1678            Token::Word(w) if w.keyword == Keyword::AT => {
1679                match (self.peek_nth_token(1).token, self.peek_nth_token(2).token) {
1680                    (Token::Word(w), Token::Word(w2))
1681                        if w.keyword == Keyword::TIME && w2.keyword == Keyword::ZONE =>
1682                    {
1683                        Ok(P::At)
1684                    }
1685                    _ => Ok(P::Zero),
1686                }
1687            }
1688
1689            Token::Word(w) if w.keyword == Keyword::NOT => match self.peek_nth_token(1).token {
1690                // The precedence of NOT varies depending on keyword that
1691                // follows it. If it is followed by IN, BETWEEN, or LIKE,
1692                // it takes on the precedence of those tokens. Otherwise it
1693                // is not an infix operator, and therefore has zero
1694                // precedence.
1695                Token::Word(w) if w.keyword == Keyword::BETWEEN => Ok(P::Between),
1696                Token::Word(w) if w.keyword == Keyword::IN => Ok(P::Between),
1697                Token::Word(w) if w.keyword == Keyword::LIKE => Ok(P::Like),
1698                Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(P::Like),
1699                Token::Word(w) if w.keyword == Keyword::SIMILAR => Ok(P::Like),
1700                _ => Ok(P::Zero),
1701            },
1702
1703            Token::Word(w) if w.keyword == Keyword::IS => Ok(P::Is),
1704            Token::Word(w) if w.keyword == Keyword::ISNULL => Ok(P::Is),
1705            Token::Word(w) if w.keyword == Keyword::NOTNULL => Ok(P::Is),
1706            Token::Eq | Token::Lt | Token::LtEq | Token::Neq | Token::Gt | Token::GtEq => {
1707                Ok(P::Cmp)
1708            }
1709            Token::Word(w) if w.keyword == Keyword::IN => Ok(P::Between),
1710            Token::Word(w) if w.keyword == Keyword::BETWEEN => Ok(P::Between),
1711            Token::Word(w) if w.keyword == Keyword::LIKE => Ok(P::Like),
1712            Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(P::Like),
1713            Token::Word(w) if w.keyword == Keyword::SIMILAR => Ok(P::Like),
1714            Token::Word(w) if w.keyword == Keyword::ALL => Ok(P::Other),
1715            Token::Word(w) if w.keyword == Keyword::ANY => Ok(P::Other),
1716            Token::Word(w) if w.keyword == Keyword::SOME => Ok(P::Other),
1717            Token::Op(_) => Ok(P::Other),
1718            Token::Word(w)
1719                if w.keyword == Keyword::OPERATOR && self.peek_nth_token(1) == Token::LParen =>
1720            {
1721                Ok(P::Other)
1722            }
1723            // In some languages (incl. rust, c), bitwise operators have precedence:
1724            //   or < xor < and < shift
1725            // But in PostgreSQL, they are just left to right. So `2 | 3 & 4` is 0.
1726            Token::Pipe => Ok(P::Other),
1727            Token::Plus | Token::Minus => Ok(P::PlusMinus),
1728            Token::Mul | Token::Div | Token::Mod => Ok(P::MulDiv),
1729            Token::Caret => Ok(P::Exp),
1730            Token::LBracket => Ok(P::Array),
1731            Token::DoubleColon => Ok(P::DoubleColon),
1732            _ => Ok(P::Zero),
1733        }
1734    }
1735
1736    /// Return the first non-whitespace token that has not yet been processed
1737    /// (or None if reached end-of-file)
1738    pub fn peek_token(&self) -> TokenWithLocation {
1739        self.peek_nth_token(0)
1740    }
1741
1742    /// Return nth non-whitespace token that has not yet been processed
1743    pub fn peek_nth_token(&self, mut n: usize) -> TokenWithLocation {
1744        let mut index = 0;
1745        loop {
1746            let token = self.0.get(index);
1747            index += 1;
1748            match token.map(|x| &x.token) {
1749                Some(Token::Whitespace(_)) => continue,
1750                _ => {
1751                    if n == 0 {
1752                        return token.cloned().unwrap_or(TokenWithLocation::eof());
1753                    }
1754                    n -= 1;
1755                }
1756            }
1757        }
1758    }
1759
1760    /// Return the first non-whitespace token that has not yet been processed
1761    /// (or None if reached end-of-file) and mark it as processed. OK to call
1762    /// repeatedly after reaching EOF.
1763    pub fn next_token(&mut self) -> TokenWithLocation {
1764        loop {
1765            let Some(token) = self.0.first() else {
1766                return TokenWithLocation::eof();
1767            };
1768            self.0 = &self.0[1..];
1769            match token.token {
1770                Token::Whitespace(_) => continue,
1771                _ => return token.clone(),
1772            }
1773        }
1774    }
1775
1776    /// Return the first unprocessed token, possibly whitespace.
1777    pub fn next_token_no_skip(&mut self) -> Option<&TokenWithLocation> {
1778        if self.0.is_empty() {
1779            None
1780        } else {
1781            let (first, rest) = self.0.split_at(1);
1782            self.0 = rest;
1783            Some(&first[0])
1784        }
1785    }
1786
1787    /// Report an expected error at the current position.
1788    pub fn expected<T>(&self, expected: &str) -> ModalResult<T> {
1789        parser_err!("expected {}, found: {}", expected, self.peek_token().token)
1790    }
1791
1792    /// Revert the parser to a previous position and report an expected error.
1793    pub fn expected_at<T>(&mut self, checkpoint: Self, expected: &str) -> ModalResult<T> {
1794        *self = checkpoint;
1795        self.expected(expected)
1796    }
1797
1798    /// Check if the expected match is the next token.
1799    /// The equality check is case-insensitive, and only an UNQUOTED word matches: a quoted word
1800    /// is an identifier by definition, so it must never be taken as a contextual grammar word
1801    /// (`PATTERN ("PERMUTE")` names a pattern variable, not the `PERMUTE(...)` form).
1802    pub fn parse_word(&mut self, expected: &str) -> bool {
1803        match self.peek_token().token {
1804            Token::Word(w) if w.quote_style.is_none() && w.value.to_uppercase() == expected => {
1805                self.next_token();
1806                true
1807            }
1808            _ => false,
1809        }
1810    }
1811
1812    pub fn expect_word(&mut self, expected: &str) -> ModalResult<()> {
1813        if self.parse_word(expected) {
1814            Ok(())
1815        } else {
1816            self.expected(expected)
1817        }
1818    }
1819
1820    /// Like [`Parser::parse_keywords`], but over contextual words: each element is matched
1821    /// case-insensitively against the next word token (keyword or not), and the parser is reset on
1822    /// the first miss. This is what lets `MATCH_RECOGNIZE`'s clause markers (`MEASURES`, `PATTERN`,
1823    /// `DEFINE`, ...) avoid the keyword table entirely — a global keyword changes identifier
1824    /// parsing and quoting everywhere (`UPDATE t SET per = 1` stopped parsing when `PER` was
1825    /// briefly a keyword), while inside the parenthesized clause the grammar owns the context.
1826    #[must_use]
1827    pub fn parse_words(&mut self, words: &[&str]) -> bool {
1828        let checkpoint = *self;
1829        for w in words {
1830            if !self.parse_word(w) {
1831                *self = checkpoint;
1832                return false;
1833            }
1834        }
1835        true
1836    }
1837
1838    /// Look for an expected keyword and consume it if it exists
1839    #[must_use]
1840    pub fn parse_keyword(&mut self, expected: Keyword) -> bool {
1841        match self.peek_token().token {
1842            Token::Word(w) if expected == w.keyword => {
1843                self.next_token();
1844                true
1845            }
1846            _ => false,
1847        }
1848    }
1849
1850    /// Look for an expected sequence of keywords and consume them if they exist
1851    #[must_use]
1852    pub fn parse_keywords(&mut self, keywords: &[Keyword]) -> bool {
1853        let checkpoint = *self;
1854        for &keyword in keywords {
1855            if !self.parse_keyword(keyword) {
1856                // println!("parse_keywords aborting .. did not find {:?}", keyword);
1857                // reset index and return immediately
1858                *self = checkpoint;
1859                return false;
1860            }
1861        }
1862        true
1863    }
1864
1865    /// Look for one of the given keywords and return the one that matches.
1866    #[must_use]
1867    pub fn parse_one_of_keywords(&mut self, keywords: &[Keyword]) -> Option<Keyword> {
1868        match self.peek_token().token {
1869            Token::Word(w) => {
1870                keywords
1871                    .iter()
1872                    .find(|keyword| **keyword == w.keyword)
1873                    .map(|keyword| {
1874                        self.next_token();
1875                        *keyword
1876                    })
1877            }
1878            _ => None,
1879        }
1880    }
1881
1882    pub fn peek_nth_any_of_keywords(&mut self, n: usize, keywords: &[Keyword]) -> bool {
1883        match self.peek_nth_token(n).token {
1884            Token::Word(w) => keywords.contains(&w.keyword),
1885            _ => false,
1886        }
1887    }
1888
1889    /// Bail out if the current token is not one of the expected keywords, or consume it if it is
1890    pub fn expect_one_of_keywords(&mut self, keywords: &[Keyword]) -> ModalResult<Keyword> {
1891        if let Some(keyword) = self.parse_one_of_keywords(keywords) {
1892            Ok(keyword)
1893        } else {
1894            let keywords: Vec<String> = keywords.iter().map(|x| format!("{:?}", x)).collect();
1895            self.expected(&format!("one of {}", keywords.join(" or ")))
1896        }
1897    }
1898
1899    /// Bail out if the current token is not an expected keyword, or consume it if it is
1900    pub fn expect_keyword(&mut self, expected: Keyword) -> ModalResult<()> {
1901        if self.parse_keyword(expected) {
1902            Ok(())
1903        } else {
1904            self.expected(format!("{:?}", expected).as_str())
1905        }
1906    }
1907
1908    /// Bail out if the following tokens are not the expected sequence of
1909    /// keywords, or consume them if they are.
1910    pub fn expect_keywords(&mut self, expected: &[Keyword]) -> ModalResult<()> {
1911        for &kw in expected {
1912            self.expect_keyword(kw)?;
1913        }
1914        Ok(())
1915    }
1916
1917    /// Consume the next token if it matches the expected token, otherwise return false
1918    #[must_use]
1919    pub fn consume_token(&mut self, expected: &Token) -> bool {
1920        if self.peek_token() == *expected {
1921            self.next_token();
1922            true
1923        } else {
1924            false
1925        }
1926    }
1927
1928    /// Bail out if the current token is not an expected keyword, or consume it if it is
1929    pub fn expect_token(&mut self, expected: &Token) -> ModalResult<()> {
1930        if self.consume_token(expected) {
1931            Ok(())
1932        } else {
1933            self.expected(&expected.to_string())
1934        }
1935    }
1936
1937    /// Parse a comma-separated list of 1+ items accepted by `F`
1938    pub fn parse_comma_separated<T, F>(&mut self, mut f: F) -> ModalResult<Vec<T>>
1939    where
1940        F: FnMut(&mut Self) -> ModalResult<T>,
1941    {
1942        let mut values = vec![];
1943        loop {
1944            values.push(f(self)?);
1945            if !self.consume_token(&Token::Comma) {
1946                break;
1947            }
1948        }
1949        Ok(values)
1950    }
1951
1952    /// Run a parser method `f`, reverting back to the current position
1953    /// if unsuccessful.
1954    #[must_use]
1955    fn maybe_parse<T, F>(&mut self, mut f: F) -> Option<T>
1956    where
1957        F: FnMut(&mut Self) -> ModalResult<T>,
1958    {
1959        let checkpoint = *self;
1960        match f(self) {
1961            Ok(t) => Some(t),
1962            _ => {
1963                *self = checkpoint;
1964                None
1965            }
1966        }
1967    }
1968
1969    /// Parse either `ALL` or `DISTINCT`. Returns `true` if `DISTINCT` is parsed and results in a
1970    /// `ParserError` if both `ALL` and `DISTINCT` are fround.
1971    pub fn parse_all_or_distinct(&mut self) -> ModalResult<bool> {
1972        let all = self.parse_keyword(Keyword::ALL);
1973        let distinct = self.parse_keyword(Keyword::DISTINCT);
1974        if all && distinct {
1975            parser_err!("Cannot specify both ALL and DISTINCT")
1976        } else {
1977            Ok(distinct)
1978        }
1979    }
1980
1981    /// Parse either `ALL` or `DISTINCT` or `DISTINCT ON (<expr>)`.
1982    pub fn parse_all_or_distinct_on(&mut self) -> ModalResult<Distinct> {
1983        if self.parse_keywords(&[Keyword::DISTINCT, Keyword::ON]) {
1984            self.expect_token(&Token::LParen)?;
1985            let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1986            self.expect_token(&Token::RParen)?;
1987            return Ok(Distinct::DistinctOn(exprs));
1988        } else if self.parse_keyword(Keyword::DISTINCT) {
1989            return Ok(Distinct::Distinct);
1990        };
1991        _ = self.parse_keyword(Keyword::ALL);
1992        Ok(Distinct::All)
1993    }
1994
1995    /// Parse a SQL CREATE statement
1996    pub fn parse_create(&mut self) -> ModalResult<Statement> {
1997        let or_replace = self.parse_keywords(&[Keyword::OR, Keyword::REPLACE]);
1998        let temporary = self
1999            .parse_one_of_keywords(&[Keyword::TEMP, Keyword::TEMPORARY])
2000            .is_some();
2001        if self.parse_keyword(Keyword::TABLE) {
2002            self.parse_create_table(or_replace, temporary)
2003        } else if self.parse_keyword(Keyword::VIEW) {
2004            self.parse_create_view(false, or_replace)
2005        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
2006            self.parse_create_view(true, or_replace)
2007        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::SOURCE]) {
2008            parser_err!("CREATE MATERIALIZED SOURCE has been deprecated, use CREATE TABLE instead")
2009        } else if self.parse_keyword(Keyword::SOURCE) {
2010            self.parse_create_source(or_replace, temporary)
2011        } else if self.parse_keyword(Keyword::SINK) {
2012            if or_replace {
2013                parser_err!("REPLACE SINK should be used instead of CREATE OR REPLACE SINK");
2014            }
2015            self.parse_create_sink(or_replace)
2016        } else if self.parse_keyword(Keyword::SUBSCRIPTION) {
2017            self.parse_create_subscription(or_replace)
2018        } else if self.parse_keyword(Keyword::CONNECTION) {
2019            self.parse_create_connection()
2020        } else if self.parse_keyword(Keyword::FUNCTION) {
2021            self.parse_create_function(or_replace, temporary)
2022        } else if self.parse_keyword(Keyword::AGGREGATE) {
2023            self.parse_create_aggregate(or_replace)
2024        } else if or_replace {
2025            self.expected(
2026                "[EXTERNAL] TABLE or [MATERIALIZED] VIEW or [MATERIALIZED] SOURCE or SINK or FUNCTION after CREATE OR REPLACE",
2027            )
2028        } else if self.parse_keyword(Keyword::INDEX) {
2029            self.parse_create_index(false)
2030        } else if self.parse_keywords(&[Keyword::UNIQUE, Keyword::INDEX]) {
2031            self.parse_create_index(true)
2032        } else if self.parse_keyword(Keyword::SCHEMA) {
2033            self.parse_create_schema()
2034        } else if self.parse_keyword(Keyword::DATABASE) {
2035            self.parse_create_database()
2036        } else if self.parse_keyword(Keyword::USER) {
2037            self.parse_create_user()
2038        } else if self.parse_keyword(Keyword::SECRET) {
2039            self.parse_create_secret()
2040        } else {
2041            self.expected("an object type after CREATE")
2042        }
2043    }
2044
2045    pub fn parse_create_schema(&mut self) -> ModalResult<Statement> {
2046        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2047        let (schema_name, owner) = if self.parse_keyword(Keyword::AUTHORIZATION) {
2048            let owner = self.parse_object_name()?;
2049            (owner.clone(), Some(owner))
2050        } else {
2051            let schema_name = self.parse_object_name()?;
2052            let owner = if self.parse_keyword(Keyword::AUTHORIZATION) {
2053                Some(self.parse_object_name()?)
2054            } else {
2055                None
2056            };
2057            (schema_name, owner)
2058        };
2059        Ok(Statement::CreateSchema {
2060            schema_name,
2061            if_not_exists,
2062            owner,
2063        })
2064    }
2065
2066    pub fn parse_create_database(&mut self) -> ModalResult<Statement> {
2067        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2068        let db_name = self.parse_object_name()?;
2069        let _ = self.parse_keyword(Keyword::WITH);
2070
2071        let mut owner = None;
2072        let mut resource_group = None;
2073        let mut barrier_interval_ms = None;
2074        let mut checkpoint_frequency = None;
2075
2076        loop {
2077            if let Some(keyword) =
2078                self.parse_one_of_keywords(&[Keyword::OWNER, Keyword::RESOURCE_GROUP])
2079            {
2080                match keyword {
2081                    Keyword::OWNER => {
2082                        if owner.is_some() {
2083                            parser_err!("duplicate OWNER clause in CREATE DATABASE");
2084                        }
2085
2086                        let _ = self.consume_token(&Token::Eq);
2087                        owner = Some(self.parse_object_name()?);
2088                    }
2089                    Keyword::RESOURCE_GROUP => {
2090                        if resource_group.is_some() {
2091                            parser_err!("duplicate RESOURCE_GROUP clause in CREATE DATABASE");
2092                        }
2093
2094                        let _ = self.consume_token(&Token::Eq);
2095                        resource_group = Some(self.parse_set_variable()?);
2096                    }
2097                    _ => unreachable!(),
2098                }
2099            } else if self.parse_word("BARRIER_INTERVAL_MS") {
2100                if barrier_interval_ms.is_some() {
2101                    parser_err!("duplicate BARRIER_INTERVAL_MS clause in CREATE DATABASE");
2102                }
2103
2104                let _ = self.consume_token(&Token::Eq);
2105                barrier_interval_ms = Some(self.parse_literal_u32()?);
2106            } else if self.parse_word("CHECKPOINT_FREQUENCY") {
2107                if checkpoint_frequency.is_some() {
2108                    parser_err!("duplicate CHECKPOINT_FREQUENCY clause in CREATE DATABASE");
2109                }
2110
2111                let _ = self.consume_token(&Token::Eq);
2112                checkpoint_frequency = Some(self.parse_literal_u64()?);
2113            } else {
2114                break;
2115            }
2116        }
2117
2118        Ok(Statement::CreateDatabase {
2119            db_name,
2120            if_not_exists,
2121            owner,
2122            resource_group,
2123            barrier_interval_ms,
2124            checkpoint_frequency,
2125        })
2126    }
2127
2128    pub fn parse_create_view(
2129        &mut self,
2130        materialized: bool,
2131        or_replace: bool,
2132    ) -> ModalResult<Statement> {
2133        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2134        // Many dialects support `OR ALTER` right after `CREATE`, but we don't (yet).
2135        // ANSI SQL and Postgres support RECURSIVE here, but we don't support it either.
2136        let name = self.parse_object_name()?;
2137        let columns = self.parse_parenthesized_column_list(Optional)?;
2138        let with_options = self.parse_options_with_preceding_keyword(Keyword::WITH)?;
2139        self.expect_keyword(Keyword::AS)?;
2140        let query = Box::new(self.parse_query()?);
2141        let emit_mode = if materialized {
2142            self.parse_emit_mode()?
2143        } else {
2144            None
2145        };
2146        // Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
2147        Ok(Statement::CreateView {
2148            if_not_exists,
2149            name,
2150            columns,
2151            query,
2152            materialized,
2153            or_replace,
2154            with_options,
2155            emit_mode,
2156        })
2157    }
2158
2159    // CREATE [OR REPLACE]?
2160    // [TEMPORARY] SOURCE
2161    // [IF NOT EXISTS]?
2162    // <source_name: Ident>
2163    // [COLUMNS]?
2164    // [WITH (properties)]?
2165    // ROW FORMAT <row_format: Ident>
2166    // [ROW SCHEMA LOCATION <row_schema_location: String>]?
2167    pub fn parse_create_source(
2168        &mut self,
2169        _or_replace: bool,
2170        temporary: bool,
2171    ) -> ModalResult<Statement> {
2172        impl_parse_to!(if_not_exists => [Keyword::IF, Keyword::NOT, Keyword::EXISTS], self);
2173        impl_parse_to!(source_name: ObjectName, self);
2174
2175        // parse columns
2176        let (columns, constraints, source_watermarks, wildcard_idx) =
2177            self.parse_columns_with_watermark()?;
2178        let include_options = self.parse_include_options()?;
2179
2180        let with_options = self.parse_with_properties()?;
2181        let option = with_options
2182            .iter()
2183            .find(|&opt| opt.name.real_value() == UPSTREAM_SOURCE_KEY);
2184        let connector: String = option.map(|opt| opt.value.to_string()).unwrap_or_default();
2185        let cdc_source_job = connector.contains("-cdc");
2186        if cdc_source_job && (!columns.is_empty() || !constraints.is_empty()) {
2187            parser_err!("CDC source cannot define columns and constraints");
2188        }
2189
2190        let cdc_table_info = if self.parse_keyword(Keyword::FROM) {
2191            let source_name = self.parse_object_name()?;
2192            self.expect_keyword(Keyword::TABLE)?;
2193            let external_table_name = self.parse_literal_string()?;
2194            Some(CdcTableInfo {
2195                source_name,
2196                external_table_name,
2197            })
2198        } else {
2199            None
2200        };
2201
2202        // A CDC table source reuses the schema of an upstream shared CDC source and therefore has
2203        // no FORMAT/ENCODE clause. Keep a native placeholder to avoid making the existing AST field
2204        // optional; the frontend ignores it for this source kind.
2205        let format_encode = if cdc_table_info.is_some() {
2206            FormatEncodeOptions::native().into()
2207        } else {
2208            // row format for nexmark source must be native
2209            // default row format for datagen source is native
2210            self.parse_format_encode_with_connector(&connector, cdc_source_job)?
2211        };
2212
2213        let stmt = CreateSourceStatement {
2214            temporary,
2215            if_not_exists,
2216            columns,
2217            wildcard_idx,
2218            constraints,
2219            source_name,
2220            with_properties: WithProperties(with_options),
2221            format_encode,
2222            source_watermarks,
2223            include_column_options: include_options,
2224            cdc_table_info,
2225        };
2226
2227        Ok(Statement::CreateSource { stmt })
2228    }
2229
2230    /// Parse a SQL REPLACE statement.
2231    pub fn parse_replace(&mut self) -> ModalResult<Statement> {
2232        if self.parse_keyword(Keyword::SINK) {
2233            self.parse_create_sink(true)
2234        } else {
2235            self.expected("SINK after REPLACE")
2236        }
2237    }
2238
2239    // CREATE SINK / REPLACE SINK
2240    // [IF NOT EXISTS]?
2241    // <sink_name: Ident>
2242    // FROM
2243    // <materialized_view: Ident>
2244    // [WITH (properties)]?
2245    pub fn parse_create_sink(&mut self, or_replace: bool) -> ModalResult<Statement> {
2246        Ok(Statement::CreateSink {
2247            stmt: CreateSinkStatement::parse_to_with_or_replace(self, or_replace)?,
2248        })
2249    }
2250
2251    // CREATE
2252    // SUBSCRIPTION
2253    // [IF NOT EXISTS]?
2254    // <subscription_name: Ident>
2255    // FROM
2256    // <materialized_view: Ident>
2257    // [WITH (properties)]?
2258    pub fn parse_create_subscription(&mut self, _or_replace: bool) -> ModalResult<Statement> {
2259        Ok(Statement::CreateSubscription {
2260            stmt: CreateSubscriptionStatement::parse_to(self)?,
2261        })
2262    }
2263
2264    // CREATE
2265    // CONNECTION
2266    // [IF NOT EXISTS]?
2267    // <connection_name: Ident>
2268    // [WITH (properties)]?
2269    pub fn parse_create_connection(&mut self) -> ModalResult<Statement> {
2270        Ok(Statement::CreateConnection {
2271            stmt: CreateConnectionStatement::parse_to(self)?,
2272        })
2273    }
2274
2275    pub fn parse_create_function(
2276        &mut self,
2277        or_replace: bool,
2278        temporary: bool,
2279    ) -> ModalResult<Statement> {
2280        impl_parse_to!(if_not_exists => [Keyword::IF, Keyword::NOT, Keyword::EXISTS], self);
2281
2282        let FunctionDesc { name, args } = self.parse_function_desc()?;
2283
2284        let return_type = if self.parse_keyword(Keyword::RETURNS) {
2285            if self.parse_keyword(Keyword::TABLE) {
2286                self.expect_token(&Token::LParen)?;
2287                let mut values = vec![];
2288                loop {
2289                    values.push(self.parse_table_column_def()?);
2290                    let comma = self.consume_token(&Token::Comma);
2291                    if self.consume_token(&Token::RParen) {
2292                        // allow a trailing comma, even though it's not in standard
2293                        break;
2294                    } else if !comma {
2295                        return self.expected("',' or ')'");
2296                    }
2297                }
2298                Some(CreateFunctionReturns::Table(values))
2299            } else {
2300                Some(CreateFunctionReturns::Value(self.parse_data_type()?))
2301            }
2302        } else {
2303            None
2304        };
2305
2306        let params = self.parse_create_function_body()?;
2307        let with_options = self.parse_options_with_preceding_keyword(Keyword::WITH)?;
2308        let with_options = with_options.try_into()?;
2309        Ok(Statement::CreateFunction {
2310            or_replace,
2311            temporary,
2312            if_not_exists,
2313            name,
2314            args,
2315            returns: return_type,
2316            params,
2317            with_options,
2318        })
2319    }
2320
2321    fn parse_create_aggregate(&mut self, or_replace: bool) -> ModalResult<Statement> {
2322        impl_parse_to!(if_not_exists => [Keyword::IF, Keyword::NOT, Keyword::EXISTS], self);
2323
2324        let name = self.parse_object_name()?;
2325        self.expect_token(&Token::LParen)?;
2326        let args = self.parse_comma_separated(Parser::parse_function_arg)?;
2327        self.expect_token(&Token::RParen)?;
2328
2329        self.expect_keyword(Keyword::RETURNS)?;
2330        let returns = self.parse_data_type()?;
2331
2332        let append_only = self.parse_keywords(&[Keyword::APPEND, Keyword::ONLY]);
2333        let params = self.parse_create_function_body()?;
2334
2335        Ok(Statement::CreateAggregate {
2336            or_replace,
2337            if_not_exists,
2338            name,
2339            args,
2340            returns,
2341            append_only,
2342            params,
2343        })
2344    }
2345
2346    pub fn parse_declare(&mut self) -> ModalResult<Statement> {
2347        Ok(Statement::DeclareCursor {
2348            stmt: DeclareCursorStatement::parse_to(self)?,
2349        })
2350    }
2351
2352    pub fn parse_fetch_cursor(&mut self) -> ModalResult<Statement> {
2353        Ok(Statement::FetchCursor {
2354            stmt: FetchCursorStatement::parse_to(self)?,
2355        })
2356    }
2357
2358    pub fn parse_close_cursor(&mut self) -> ModalResult<Statement> {
2359        Ok(Statement::CloseCursor {
2360            stmt: CloseCursorStatement::parse_to(self)?,
2361        })
2362    }
2363
2364    fn parse_table_column_def(&mut self) -> ModalResult<TableColumnDef> {
2365        Ok(TableColumnDef {
2366            name: self.parse_identifier_non_reserved()?,
2367            data_type: self.parse_data_type()?,
2368        })
2369    }
2370
2371    fn parse_function_arg(&mut self) -> ModalResult<OperateFunctionArg> {
2372        let mode = if self.parse_keyword(Keyword::IN) {
2373            Some(ArgMode::In)
2374        } else if self.parse_keyword(Keyword::OUT) {
2375            Some(ArgMode::Out)
2376        } else if self.parse_keyword(Keyword::INOUT) {
2377            Some(ArgMode::InOut)
2378        } else {
2379            None
2380        };
2381
2382        // parse: [ argname ] argtype
2383        let mut name = None;
2384        let mut data_type = self.parse_data_type()?;
2385        if let DataType::Custom(n) = &data_type
2386            && !matches!(self.peek_token().token, Token::Comma | Token::RParen)
2387        {
2388            // the first token is actually a name
2389            name = Some(n.0[0].clone());
2390            data_type = self.parse_data_type()?;
2391        }
2392
2393        let default_expr = if self.parse_keyword(Keyword::DEFAULT) || self.consume_token(&Token::Eq)
2394        {
2395            Some(self.parse_expr()?)
2396        } else {
2397            None
2398        };
2399        Ok(OperateFunctionArg {
2400            mode,
2401            name,
2402            data_type,
2403            default_expr,
2404        })
2405    }
2406
2407    fn parse_create_function_body(&mut self) -> ModalResult<CreateFunctionBody> {
2408        let mut body = CreateFunctionBody::default();
2409        loop {
2410            fn ensure_not_set<T>(field: &Option<T>, name: &str) -> ModalResult<()> {
2411                if field.is_some() {
2412                    parser_err!("{name} specified more than once");
2413                }
2414                Ok(())
2415            }
2416            if self.parse_keyword(Keyword::AS) {
2417                ensure_not_set(&body.as_, "AS")?;
2418                body.as_ = Some(self.parse_function_definition()?);
2419            } else if self.parse_keyword(Keyword::LANGUAGE) {
2420                ensure_not_set(&body.language, "LANGUAGE")?;
2421                body.language = Some(self.parse_identifier()?);
2422            } else if self.parse_keyword(Keyword::RUNTIME) {
2423                ensure_not_set(&body.runtime, "RUNTIME")?;
2424                body.runtime = Some(self.parse_identifier()?);
2425            } else if self.parse_keyword(Keyword::IMMUTABLE) {
2426                ensure_not_set(&body.behavior, "IMMUTABLE | STABLE | VOLATILE")?;
2427                body.behavior = Some(FunctionBehavior::Immutable);
2428            } else if self.parse_keyword(Keyword::STABLE) {
2429                ensure_not_set(&body.behavior, "IMMUTABLE | STABLE | VOLATILE")?;
2430                body.behavior = Some(FunctionBehavior::Stable);
2431            } else if self.parse_keyword(Keyword::VOLATILE) {
2432                ensure_not_set(&body.behavior, "IMMUTABLE | STABLE | VOLATILE")?;
2433                body.behavior = Some(FunctionBehavior::Volatile);
2434            } else if self.parse_keyword(Keyword::RETURN) {
2435                ensure_not_set(&body.return_, "RETURN")?;
2436                body.return_ = Some(self.parse_expr()?);
2437            } else if self.parse_keyword(Keyword::USING) {
2438                ensure_not_set(&body.using, "USING")?;
2439                body.using = Some(self.parse_create_function_using()?);
2440            } else {
2441                return Ok(body);
2442            }
2443        }
2444    }
2445
2446    fn parse_create_function_using(&mut self) -> ModalResult<CreateFunctionUsing> {
2447        let keyword = self.expect_one_of_keywords(&[Keyword::LINK, Keyword::BASE64])?;
2448
2449        match keyword {
2450            Keyword::LINK => {
2451                let uri = self.parse_literal_string()?;
2452                Ok(CreateFunctionUsing::Link(uri))
2453            }
2454            Keyword::BASE64 => {
2455                let base64 = self.parse_literal_string()?;
2456                Ok(CreateFunctionUsing::Base64(base64))
2457            }
2458            _ => unreachable!("{}", keyword),
2459        }
2460    }
2461
2462    // CREATE USER name [ [ WITH ] option [ ... ] ]
2463    // where option can be:
2464    //       SUPERUSER | NOSUPERUSER
2465    //     | CREATEDB | NOCREATEDB
2466    //     | CREATEUSER | NOCREATEUSER
2467    //     | LOGIN | NOLOGIN
2468    //     | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | OAUTH
2469    fn parse_create_user(&mut self) -> ModalResult<Statement> {
2470        Ok(Statement::CreateUser(CreateUserStatement::parse_to(self)?))
2471    }
2472
2473    fn parse_create_secret(&mut self) -> ModalResult<Statement> {
2474        Ok(Statement::CreateSecret {
2475            stmt: CreateSecretStatement::parse_to(self)?,
2476        })
2477    }
2478
2479    pub fn parse_with_properties(&mut self) -> ModalResult<Vec<SqlOption>> {
2480        self.parse_options_with_preceding_keyword(Keyword::WITH)
2481    }
2482
2483    pub fn parse_discard(&mut self) -> ModalResult<Statement> {
2484        self.expect_keyword(Keyword::ALL)?;
2485        Ok(Statement::Discard(DiscardType::All))
2486    }
2487
2488    pub fn parse_drop(&mut self) -> ModalResult<Statement> {
2489        if self.parse_keyword(Keyword::FUNCTION) {
2490            return self.parse_drop_function();
2491        } else if self.parse_keyword(Keyword::AGGREGATE) {
2492            return self.parse_drop_aggregate();
2493        }
2494        Ok(Statement::Drop(DropStatement::parse_to(self)?))
2495    }
2496
2497    /// ```sql
2498    /// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
2499    /// [ CASCADE | RESTRICT ]
2500    /// ```
2501    fn parse_drop_function(&mut self) -> ModalResult<Statement> {
2502        let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
2503        let func_desc = self.parse_comma_separated(Parser::parse_function_desc)?;
2504        let option = match self.parse_one_of_keywords(&[Keyword::CASCADE, Keyword::RESTRICT]) {
2505            Some(Keyword::CASCADE) => Some(ReferentialAction::Cascade),
2506            Some(Keyword::RESTRICT) => Some(ReferentialAction::Restrict),
2507            _ => None,
2508        };
2509        Ok(Statement::DropFunction {
2510            if_exists,
2511            func_desc,
2512            option,
2513        })
2514    }
2515
2516    /// ```sql
2517    /// DROP AGGREGATE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
2518    /// [ CASCADE | RESTRICT ]
2519    /// ```
2520    fn parse_drop_aggregate(&mut self) -> ModalResult<Statement> {
2521        let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
2522        let func_desc = self.parse_comma_separated(Parser::parse_function_desc)?;
2523        let option = match self.parse_one_of_keywords(&[Keyword::CASCADE, Keyword::RESTRICT]) {
2524            Some(Keyword::CASCADE) => Some(ReferentialAction::Cascade),
2525            Some(Keyword::RESTRICT) => Some(ReferentialAction::Restrict),
2526            _ => None,
2527        };
2528        Ok(Statement::DropAggregate {
2529            if_exists,
2530            func_desc,
2531            option,
2532        })
2533    }
2534
2535    fn parse_function_desc(&mut self) -> ModalResult<FunctionDesc> {
2536        let name = self.parse_object_name()?;
2537
2538        let args = if self.consume_token(&Token::LParen) {
2539            if self.consume_token(&Token::RParen) {
2540                Some(vec![])
2541            } else {
2542                let args = self.parse_comma_separated(Parser::parse_function_arg)?;
2543                self.expect_token(&Token::RParen)?;
2544                Some(args)
2545            }
2546        } else {
2547            None
2548        };
2549
2550        Ok(FunctionDesc { name, args })
2551    }
2552
2553    pub fn parse_create_index(&mut self, unique: bool) -> ModalResult<Statement> {
2554        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2555        let index_name = self.parse_object_name()?;
2556        self.expect_keyword(Keyword::ON)?;
2557        let table_name = self.parse_object_name()?;
2558        let method = if self.parse_keyword(Keyword::USING) {
2559            let method = self.parse_identifier()?;
2560            Some(method)
2561        } else {
2562            None
2563        };
2564        self.expect_token(&Token::LParen)?;
2565        let columns = self.parse_comma_separated(Parser::parse_order_by_expr)?;
2566        self.expect_token(&Token::RParen)?;
2567        let mut include = vec![];
2568        if self.parse_keyword(Keyword::INCLUDE) {
2569            self.expect_token(&Token::LParen)?;
2570            include = self.parse_comma_separated(Parser::parse_identifier_non_reserved)?;
2571            self.expect_token(&Token::RParen)?;
2572        }
2573        let mut distributed_by = vec![];
2574        if self.parse_keywords(&[Keyword::DISTRIBUTED, Keyword::BY]) {
2575            self.expect_token(&Token::LParen)?;
2576            distributed_by = self.parse_comma_separated(Parser::parse_expr)?;
2577            self.expect_token(&Token::RParen)?;
2578        }
2579        let with_properties = WithProperties(self.parse_with_properties()?);
2580
2581        Ok(Statement::CreateIndex {
2582            name: index_name,
2583            table_name,
2584            method,
2585            columns,
2586            include,
2587            distributed_by,
2588            unique,
2589            if_not_exists,
2590            with_properties,
2591        })
2592    }
2593
2594    pub fn parse_with_version_columns(&mut self) -> ModalResult<Vec<Ident>> {
2595        if self.parse_keywords(&[Keyword::WITH, Keyword::VERSION, Keyword::COLUMN]) {
2596            self.expect_token(&Token::LParen)?;
2597            let columns =
2598                self.parse_comma_separated(|parser| parser.parse_identifier_non_reserved())?;
2599            self.expect_token(&Token::RParen)?;
2600            Ok(columns)
2601        } else {
2602            Ok(Vec::new())
2603        }
2604    }
2605
2606    pub fn parse_on_conflict(&mut self) -> ModalResult<Option<OnConflict>> {
2607        if self.parse_keywords(&[Keyword::ON, Keyword::CONFLICT]) {
2608            self.parse_handle_conflict_behavior()
2609        } else {
2610            Ok(None)
2611        }
2612    }
2613
2614    pub fn parse_create_table(
2615        &mut self,
2616        or_replace: bool,
2617        temporary: bool,
2618    ) -> ModalResult<Statement> {
2619        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2620        let table_name = self.parse_object_name()?;
2621        // parse optional column list (schema) and watermarks on source.
2622        let (columns, constraints, source_watermarks, wildcard_idx) =
2623            self.parse_columns_with_watermark()?;
2624
2625        let append_only = if self.parse_keyword(Keyword::APPEND) {
2626            self.expect_keyword(Keyword::ONLY)?;
2627            true
2628        } else {
2629            false
2630        };
2631
2632        let on_conflict = self.parse_on_conflict()?;
2633
2634        let with_version_columns = self.parse_with_version_columns()?;
2635        let include_options = self.parse_include_options()?;
2636
2637        // PostgreSQL supports `WITH ( options )`, before `AS`
2638        let with_options = self.parse_with_properties()?;
2639
2640        let option = with_options
2641            .iter()
2642            .find(|&opt| opt.name.real_value() == UPSTREAM_SOURCE_KEY);
2643        let connector = option.map(|opt| opt.value.to_string());
2644        let contain_webhook =
2645            connector.is_some() && connector.as_ref().unwrap().contains(WEBHOOK_CONNECTOR);
2646
2647        // webhook connector does not require row format
2648        let format_encode = if let Some(connector) = connector
2649            && !contain_webhook
2650        {
2651            Some(self.parse_format_encode_with_connector(&connector, false)?)
2652        } else {
2653            None // Table is NOT created with an external connector.
2654        };
2655        // Parse optional `AS ( query )`
2656        let query = if self.parse_keyword(Keyword::AS) {
2657            if !source_watermarks.is_empty() {
2658                parser_err!("Watermarks can't be defined on table created by CREATE TABLE AS");
2659            }
2660            Some(Box::new(self.parse_query()?))
2661        } else {
2662            None
2663        };
2664
2665        let cdc_table_info = if self.parse_keyword(Keyword::FROM) {
2666            let source_name = self.parse_object_name()?;
2667            self.expect_keyword(Keyword::TABLE)?;
2668            let external_table_name = self.parse_literal_string()?;
2669            Some(CdcTableInfo {
2670                source_name,
2671                external_table_name,
2672            })
2673        } else {
2674            None
2675        };
2676
2677        let webhook_wait_for_persistence = with_options
2678            .iter()
2679            .find(|&opt| opt.name.real_value() == WEBHOOK_WAIT_FOR_PERSISTENCE)
2680            .map(|opt| opt.value.to_string().eq_ignore_ascii_case("true"))
2681            .unwrap_or(true);
2682        let webhook_is_batched = with_options
2683            .iter()
2684            .find(|&opt| opt.name.real_value() == WEBHOOK_IS_BATCHED)
2685            .map(|opt| opt.value.to_string().eq_ignore_ascii_case("true"))
2686            .unwrap_or(false);
2687
2688        let webhook_info = if self.parse_keyword(Keyword::VALIDATE) {
2689            if !contain_webhook {
2690                parser_err!("VALIDATE is only supported for tables created with webhook source");
2691            }
2692
2693            let secret_ref = if self.parse_keyword(Keyword::SECRET) {
2694                let secret_ref = self.parse_secret_ref()?;
2695                if secret_ref.ref_as == SecretRefAsType::File {
2696                    parser_err!("Secret for SECURE_COMPARE() does not support AS FILE");
2697                };
2698                Some(secret_ref)
2699            } else {
2700                None
2701            };
2702
2703            self.expect_keyword(Keyword::AS)?;
2704            let signature_expr = self.parse_function()?;
2705
2706            Some(WebhookSourceInfo {
2707                secret_ref,
2708                signature_expr: Some(signature_expr),
2709                wait_for_persistence: webhook_wait_for_persistence,
2710                is_batched: webhook_is_batched,
2711            })
2712        } else if contain_webhook {
2713            Some(WebhookSourceInfo {
2714                secret_ref: None,
2715                signature_expr: None,
2716                wait_for_persistence: webhook_wait_for_persistence,
2717                is_batched: webhook_is_batched,
2718            })
2719        } else {
2720            None
2721        };
2722
2723        let engine = if self.parse_keyword(Keyword::ENGINE) {
2724            self.expect_token(&Token::Eq)?;
2725            let engine_name = self.parse_object_name()?;
2726            if "iceberg".eq_ignore_ascii_case(&engine_name.real_value()) {
2727                Engine::Iceberg
2728            } else if "hummock".eq_ignore_ascii_case(&engine_name.real_value()) {
2729                Engine::Hummock
2730            } else {
2731                parser_err!("Unsupported engine: {}", engine_name);
2732            }
2733        } else {
2734            Engine::Hummock
2735        };
2736
2737        Ok(Statement::CreateTable {
2738            name: table_name,
2739            temporary,
2740            columns,
2741            wildcard_idx,
2742            constraints,
2743            with_options,
2744            or_replace,
2745            if_not_exists,
2746            format_encode,
2747            source_watermarks,
2748            append_only,
2749            on_conflict,
2750            with_version_columns,
2751            query,
2752            cdc_table_info,
2753            include_column_options: include_options,
2754            webhook_info,
2755            engine,
2756        })
2757    }
2758
2759    pub fn parse_include_options(&mut self) -> ModalResult<IncludeOption> {
2760        let mut options = vec![];
2761        while self.parse_keyword(Keyword::INCLUDE) {
2762            let column_type = self.parse_identifier()?;
2763
2764            let mut column_inner_field = None;
2765            let mut header_inner_expect_type = None;
2766            if let Token::SingleQuotedString(inner_field) = self.peek_token().token {
2767                self.next_token();
2768                column_inner_field = Some(inner_field);
2769
2770                // `verify` rejects `DataType::Custom` so that a following `INCLUDE` (or even `WITH`)
2771                // will not be misrecognized as a DataType.
2772                //
2773                // For example, the following look structurally the same because `INCLUDE` is not a
2774                // reserved keyword. (`AS` is reserved.)
2775                // * `INCLUDE header 'foo' varchar`
2776                // * `INCLUDE header 'foo' INCLUDE`
2777                //
2778                // To be honest `bytea` shall be a `DataType::Custom` rather than a keyword, and the
2779                // logic here shall be:
2780                // ```
2781                // match dt {
2782                //     DataType::Custom(name) => allowed.contains(name.real_value()),
2783                //     _ => true,
2784                // }
2785                // ```
2786                // An allowlist is better than a denylist, as the following token may be other than
2787                // `INCLUDE` or `WITH` in the future.
2788                //
2789                // If this sounds too complicated - it means we should have designed this extension
2790                // syntax differently to make ambiguity handling easier.
2791                header_inner_expect_type =
2792                    opt(parser_v2::data_type.verify(|dt| !matches!(dt, DataType::Custom(_))))
2793                        .parse_next(self)?;
2794            }
2795
2796            let mut column_alias = None;
2797            if self.parse_keyword(Keyword::AS) {
2798                column_alias = Some(self.parse_identifier()?);
2799            }
2800
2801            options.push(IncludeOptionItem {
2802                column_type,
2803                inner_field: column_inner_field,
2804                column_alias,
2805                header_inner_expect_type,
2806            });
2807
2808            // tolerate previous bug #18800 of displaying with comma separation
2809            let _ = self.consume_token(&Token::Comma);
2810        }
2811        Ok(options)
2812    }
2813
2814    pub fn parse_columns_with_watermark(&mut self) -> ModalResult<ColumnsDefTuple> {
2815        let mut columns = vec![];
2816        let mut constraints = vec![];
2817        let mut watermarks = vec![];
2818        let mut wildcard_idx = None;
2819        if !self.consume_token(&Token::LParen) || self.consume_token(&Token::RParen) {
2820            return Ok((columns, constraints, watermarks, wildcard_idx));
2821        }
2822
2823        loop {
2824            if self.consume_token(&Token::Mul) {
2825                if wildcard_idx.is_none() {
2826                    wildcard_idx = Some(columns.len());
2827                } else {
2828                    parser_err!("At most 1 wildcard is allowed in source definition");
2829                }
2830            } else if let Some(constraint) = self.parse_optional_table_constraint()? {
2831                constraints.push(constraint);
2832            } else if let Some(watermark) = self.parse_optional_watermark()? {
2833                watermarks.push(watermark);
2834                if watermarks.len() > 1 {
2835                    // TODO(yuhao): allow multiple watermark on source.
2836                    parser_err!("Only 1 watermark is allowed to be defined on source.");
2837                }
2838            } else if let Token::Word(_) = self.peek_token().token {
2839                columns.push(self.parse_column_def()?);
2840            } else {
2841                return self.expected("column name or constraint definition");
2842            }
2843            let comma = self.consume_token(&Token::Comma);
2844            if self.consume_token(&Token::RParen) {
2845                // allow a trailing comma, even though it's not in standard
2846                break;
2847            } else if !comma {
2848                return self.expected("',' or ')' after column definition");
2849            }
2850        }
2851
2852        Ok((columns, constraints, watermarks, wildcard_idx))
2853    }
2854
2855    fn parse_column_def(&mut self) -> ModalResult<ColumnDef> {
2856        let name = self.parse_identifier_non_reserved()?;
2857        let data_type = if let Token::Word(_) = self.peek_token().token {
2858            Some(self.parse_data_type()?)
2859        } else {
2860            None
2861        };
2862
2863        let collation = if self.parse_keyword(Keyword::COLLATE) {
2864            Some(self.parse_object_name()?)
2865        } else {
2866            None
2867        };
2868        let mut options = vec![];
2869        loop {
2870            if self.parse_keyword(Keyword::CONSTRAINT) {
2871                let name = Some(self.parse_identifier_non_reserved()?);
2872                if let Some(option) = self.parse_optional_column_option()? {
2873                    options.push(ColumnOptionDef { name, option });
2874                } else {
2875                    return self.expected("constraint details after CONSTRAINT <name>");
2876                }
2877            } else if let Some(option) = self.parse_optional_column_option()? {
2878                options.push(ColumnOptionDef { name: None, option });
2879            } else {
2880                break;
2881            };
2882        }
2883        Ok(ColumnDef {
2884            name,
2885            data_type,
2886            collation,
2887            options,
2888        })
2889    }
2890
2891    pub fn parse_optional_column_option(&mut self) -> ModalResult<Option<ColumnOption>> {
2892        if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) {
2893            Ok(Some(ColumnOption::NotNull))
2894        } else if self.parse_keyword(Keyword::NULL) {
2895            Ok(Some(ColumnOption::Null))
2896        } else if self.parse_keyword(Keyword::DEFAULT) {
2897            if self.parse_keyword(Keyword::INTERNAL) {
2898                Ok(Some(ColumnOption::DefaultValueInternal {
2899                    // Placeholder. Will fill during definition purification for schema change.
2900                    persisted: Default::default(),
2901                    expr: None,
2902                }))
2903            } else {
2904                Ok(Some(ColumnOption::DefaultValue(self.parse_expr()?)))
2905            }
2906        } else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) {
2907            Ok(Some(ColumnOption::Unique { is_primary: true }))
2908        } else if self.parse_keyword(Keyword::UNIQUE) {
2909            Ok(Some(ColumnOption::Unique { is_primary: false }))
2910        } else if self.parse_keyword(Keyword::REFERENCES) {
2911            let foreign_table = self.parse_object_name()?;
2912            // PostgreSQL allows omitting the column list and
2913            // uses the primary key column of the foreign table by default
2914            let referred_columns = self.parse_parenthesized_column_list(Optional)?;
2915            let mut on_delete = None;
2916            let mut on_update = None;
2917            loop {
2918                if on_delete.is_none() && self.parse_keywords(&[Keyword::ON, Keyword::DELETE]) {
2919                    on_delete = Some(self.parse_referential_action()?);
2920                } else if on_update.is_none()
2921                    && self.parse_keywords(&[Keyword::ON, Keyword::UPDATE])
2922                {
2923                    on_update = Some(self.parse_referential_action()?);
2924                } else {
2925                    break;
2926                }
2927            }
2928            Ok(Some(ColumnOption::ForeignKey {
2929                foreign_table,
2930                referred_columns,
2931                on_delete,
2932                on_update,
2933            }))
2934        } else if self.parse_keyword(Keyword::CHECK) {
2935            self.expect_token(&Token::LParen)?;
2936            let expr = self.parse_expr()?;
2937            self.expect_token(&Token::RParen)?;
2938            Ok(Some(ColumnOption::Check(expr)))
2939        } else if self.parse_keyword(Keyword::AS) {
2940            Ok(Some(ColumnOption::GeneratedColumns(self.parse_expr()?)))
2941        } else {
2942            Ok(None)
2943        }
2944    }
2945
2946    pub fn parse_handle_conflict_behavior(&mut self) -> ModalResult<Option<OnConflict>> {
2947        if self.parse_keyword(Keyword::OVERWRITE) {
2948            // compatible with v1.9 - v2.0
2949            Ok(Some(OnConflict::UpdateFull))
2950        } else if self.parse_keyword(Keyword::IGNORE) {
2951            // compatible with v1.9 - v2.0
2952            Ok(Some(OnConflict::Nothing))
2953        } else if self.parse_keywords(&[
2954            Keyword::DO,
2955            Keyword::UPDATE,
2956            Keyword::IF,
2957            Keyword::NOT,
2958            Keyword::NULL,
2959        ]) {
2960            Ok(Some(OnConflict::UpdateIfNotNull))
2961        } else if self.parse_keywords(&[Keyword::DO, Keyword::UPDATE, Keyword::FULL]) {
2962            Ok(Some(OnConflict::UpdateFull))
2963        } else if self.parse_keywords(&[Keyword::DO, Keyword::NOTHING]) {
2964            Ok(Some(OnConflict::Nothing))
2965        } else {
2966            Ok(None)
2967        }
2968    }
2969
2970    pub fn parse_referential_action(&mut self) -> ModalResult<ReferentialAction> {
2971        if self.parse_keyword(Keyword::RESTRICT) {
2972            Ok(ReferentialAction::Restrict)
2973        } else if self.parse_keyword(Keyword::CASCADE) {
2974            Ok(ReferentialAction::Cascade)
2975        } else if self.parse_keywords(&[Keyword::SET, Keyword::NULL]) {
2976            Ok(ReferentialAction::SetNull)
2977        } else if self.parse_keywords(&[Keyword::NO, Keyword::ACTION]) {
2978            Ok(ReferentialAction::NoAction)
2979        } else if self.parse_keywords(&[Keyword::SET, Keyword::DEFAULT]) {
2980            Ok(ReferentialAction::SetDefault)
2981        } else {
2982            self.expected("one of RESTRICT, CASCADE, SET NULL, NO ACTION or SET DEFAULT")
2983        }
2984    }
2985
2986    pub fn parse_optional_watermark(&mut self) -> ModalResult<Option<SourceWatermark>> {
2987        if self.parse_keyword(Keyword::WATERMARK) {
2988            self.expect_keyword(Keyword::FOR)?;
2989            let column = self.parse_identifier_non_reserved()?;
2990            self.expect_keyword(Keyword::AS)?;
2991            let expr = self.parse_expr()?;
2992            let with_ttl = self.parse_keywords(&[Keyword::WITH, Keyword::TTL]);
2993            Ok(Some(SourceWatermark {
2994                column,
2995                expr,
2996                with_ttl,
2997            }))
2998        } else {
2999            Ok(None)
3000        }
3001    }
3002
3003    pub fn parse_optional_table_constraint(&mut self) -> ModalResult<Option<TableConstraint>> {
3004        let name = if self.parse_keyword(Keyword::CONSTRAINT) {
3005            Some(self.parse_identifier_non_reserved()?)
3006        } else {
3007            None
3008        };
3009        let checkpoint = *self;
3010        let token = self.next_token();
3011        match token.token {
3012            Token::Word(w) if w.keyword == Keyword::PRIMARY || w.keyword == Keyword::UNIQUE => {
3013                let is_primary = w.keyword == Keyword::PRIMARY;
3014                if is_primary {
3015                    self.expect_keyword(Keyword::KEY)?;
3016                }
3017                let columns = self.parse_parenthesized_column_list(Mandatory)?;
3018                Ok(Some(TableConstraint::Unique {
3019                    name,
3020                    columns,
3021                    is_primary,
3022                }))
3023            }
3024            Token::Word(w) if w.keyword == Keyword::FOREIGN => {
3025                self.expect_keyword(Keyword::KEY)?;
3026                let columns = self.parse_parenthesized_column_list(Mandatory)?;
3027                self.expect_keyword(Keyword::REFERENCES)?;
3028                let foreign_table = self.parse_object_name()?;
3029                let referred_columns = self.parse_parenthesized_column_list(Mandatory)?;
3030                let mut on_delete = None;
3031                let mut on_update = None;
3032                loop {
3033                    if on_delete.is_none() && self.parse_keywords(&[Keyword::ON, Keyword::DELETE]) {
3034                        on_delete = Some(self.parse_referential_action()?);
3035                    } else if on_update.is_none()
3036                        && self.parse_keywords(&[Keyword::ON, Keyword::UPDATE])
3037                    {
3038                        on_update = Some(self.parse_referential_action()?);
3039                    } else {
3040                        break;
3041                    }
3042                }
3043                Ok(Some(TableConstraint::ForeignKey {
3044                    name,
3045                    columns,
3046                    foreign_table,
3047                    referred_columns,
3048                    on_delete,
3049                    on_update,
3050                }))
3051            }
3052            Token::Word(w) if w.keyword == Keyword::CHECK => {
3053                self.expect_token(&Token::LParen)?;
3054                let expr = Box::new(self.parse_expr()?);
3055                self.expect_token(&Token::RParen)?;
3056                Ok(Some(TableConstraint::Check { name, expr }))
3057            }
3058            _ => {
3059                *self = checkpoint;
3060                if name.is_some() {
3061                    self.expected("PRIMARY, UNIQUE, FOREIGN, or CHECK")
3062                } else {
3063                    Ok(None)
3064                }
3065            }
3066        }
3067    }
3068
3069    pub fn parse_options_with_preceding_keyword(
3070        &mut self,
3071        keyword: Keyword,
3072    ) -> ModalResult<Vec<SqlOption>> {
3073        if self.parse_keyword(keyword) {
3074            self.expect_token(&Token::LParen)?;
3075            self.parse_options_inner()
3076        } else {
3077            Ok(vec![])
3078        }
3079    }
3080
3081    pub fn parse_options(&mut self) -> ModalResult<Vec<SqlOption>> {
3082        if self.peek_token() == Token::LParen {
3083            self.next_token();
3084            self.parse_options_inner()
3085        } else {
3086            Ok(vec![])
3087        }
3088    }
3089
3090    // has parsed a LParen
3091    pub fn parse_options_inner(&mut self) -> ModalResult<Vec<SqlOption>> {
3092        let mut values = vec![];
3093        loop {
3094            values.push(Parser::parse_sql_option(self)?);
3095            let comma = self.consume_token(&Token::Comma);
3096            if self.consume_token(&Token::RParen) {
3097                // allow a trailing comma, even though it's not in standard
3098                break;
3099            } else if !comma {
3100                return self.expected("',' or ')' after option definition");
3101            }
3102        }
3103        Ok(values)
3104    }
3105
3106    pub fn parse_sql_option(&mut self) -> ModalResult<SqlOption> {
3107        const CONNECTION_REF_KEY: &str = "connection";
3108        const BACKFILL_ORDER: &str = "backfill_order";
3109
3110        let name = self.parse_object_name()?;
3111        self.expect_token(&Token::Eq)?;
3112        let value = {
3113            if name.real_value().eq_ignore_ascii_case(CONNECTION_REF_KEY) {
3114                let connection_name = self.parse_object_name()?;
3115                // tolerate previous buggy Display that outputs `connection = connection foo`
3116                let connection_name = match connection_name.0.as_slice() {
3117                    [ident] if ident.real_value() == CONNECTION_REF_KEY => {
3118                        self.parse_object_name()?
3119                    }
3120                    _ => connection_name,
3121                };
3122                SqlOptionValue::ConnectionRef(ConnectionRefValue { connection_name })
3123            } else if name.real_value().eq_ignore_ascii_case(BACKFILL_ORDER) {
3124                let order = self.parse_backfill_order_strategy()?;
3125                SqlOptionValue::BackfillOrder(order)
3126            } else {
3127                self.parse_value_and_obj_ref::<false>()?
3128            }
3129        };
3130        Ok(SqlOption { name, value })
3131    }
3132
3133    // <config_param> { TO | = } { <value> | DEFAULT }
3134    // <config_param> is not a keyword, but an identifier
3135    pub fn parse_config_param(&mut self) -> ModalResult<ConfigParam> {
3136        self.parse_config_param_inner(Self::parse_set_variable)
3137    }
3138
3139    fn parse_config_param_inner(
3140        &mut self,
3141        parse_value: fn(&mut Self) -> ModalResult<SetVariableValue>,
3142    ) -> ModalResult<ConfigParam> {
3143        let param = self.parse_identifier()?;
3144        if !self.consume_token(&Token::Eq) && !self.parse_keyword(Keyword::TO) {
3145            return self.expected("'=' or 'TO' after config parameter");
3146        }
3147        let value = parse_value(self)?;
3148        Ok(ConfigParam { param, value })
3149    }
3150
3151    /// Parse a single-value config param.
3152    ///
3153    /// This differs from [`Self::parse_config_param`] in that it does **not** allow a comma-separated
3154    /// list on the RHS, so it can be safely used in constructs where comma separates multiple
3155    /// assignments (e.g. `... SET a = 1, b = 2`).
3156    fn parse_config_param_no_list(&mut self) -> ModalResult<ConfigParam> {
3157        self.parse_config_param_inner(Self::parse_set_variable_no_list)
3158    }
3159
3160    fn parse_set_variable_no_list(&mut self) -> ModalResult<SetVariableValue> {
3161        alt((
3162            Keyword::DEFAULT.value(SetVariableValue::Default),
3163            alt((
3164                Self::ensure_parse_value.map(SetVariableValueSingle::Literal),
3165                |parser: &mut Self| {
3166                    let checkpoint = *parser;
3167                    let ident = parser.parse_identifier()?;
3168                    if ident.value == "default" {
3169                        *parser = checkpoint;
3170                        return parser.expected("parameter list value").map_err(|e| e.cut());
3171                    }
3172                    Ok(SetVariableValueSingle::Ident(ident))
3173                },
3174                fail.expect("parameter value"),
3175            ))
3176            .map(|single: SetVariableValueSingle| SetVariableValue::Single(single)),
3177        ))
3178        .parse_next(self)
3179    }
3180
3181    pub fn parse_since(&mut self) -> ModalResult<Since> {
3182        if self.parse_keyword(Keyword::SINCE) {
3183            let checkpoint = *self;
3184            let token = self.next_token();
3185            match token.token {
3186                Token::Word(w) => {
3187                    let ident = w.to_ident()?;
3188                    // Backward compatibility for now.
3189                    if ident.real_value() == "proctime" || ident.real_value() == "now" {
3190                        self.expect_token(&Token::LParen)?;
3191                        self.expect_token(&Token::RParen)?;
3192                        Ok(Since::ProcessTime)
3193                    } else if ident.real_value() == "begin" {
3194                        self.expect_token(&Token::LParen)?;
3195                        self.expect_token(&Token::RParen)?;
3196                        Ok(Since::Begin)
3197                    } else {
3198                        parser_err!(
3199                            "Expected proctime(), begin() or now(), found: {}",
3200                            ident.real_value()
3201                        )
3202                    }
3203                }
3204                Token::Number(s) => {
3205                    let num = s
3206                        .parse::<u64>()
3207                        .map_err(|e| StrError(format!("Could not parse '{}' as u64: {}", s, e)))?;
3208                    Ok(Since::TimestampMsNum(num))
3209                }
3210                _ => self.expected_at(checkpoint, "proctime(), begin() , now(), Number"),
3211            }
3212        } else if self.parse_word("FULL") {
3213            Ok(Since::Full)
3214        } else {
3215            Ok(Since::ProcessTime)
3216        }
3217    }
3218
3219    pub fn parse_emit_mode(&mut self) -> ModalResult<Option<EmitMode>> {
3220        if self.parse_keyword(Keyword::EMIT) {
3221            match self.parse_one_of_keywords(&[Keyword::IMMEDIATELY, Keyword::ON]) {
3222                Some(Keyword::IMMEDIATELY) => Ok(Some(EmitMode::Immediately)),
3223                Some(Keyword::ON) => {
3224                    self.expect_keywords(&[Keyword::WINDOW, Keyword::CLOSE])?;
3225                    Ok(Some(EmitMode::OnWindowClose))
3226                }
3227                Some(_) => unreachable!(),
3228                None => self.expected("IMMEDIATELY or ON WINDOW CLOSE after EMIT"),
3229            }
3230        } else {
3231            Ok(None)
3232        }
3233    }
3234
3235    pub fn parse_alter(&mut self) -> ModalResult<Statement> {
3236        if self.parse_keyword(Keyword::DATABASE) {
3237            self.parse_alter_database()
3238        } else if self.parse_keyword(Keyword::SCHEMA) {
3239            self.parse_alter_schema()
3240        } else if self.parse_keyword(Keyword::TABLE) {
3241            self.parse_alter_table()
3242        } else if self.parse_keyword(Keyword::INDEX) {
3243            self.parse_alter_index()
3244        } else if self.parse_keyword(Keyword::VIEW) {
3245            self.parse_alter_view(false)
3246        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
3247            self.parse_alter_view(true)
3248        } else if self.parse_keyword(Keyword::SINK) {
3249            self.parse_alter_sink()
3250        } else if self.parse_keyword(Keyword::SOURCE) {
3251            self.parse_alter_source()
3252        } else if self.parse_keyword(Keyword::FUNCTION) {
3253            self.parse_alter_function()
3254        } else if self.parse_keyword(Keyword::CONNECTION) {
3255            self.parse_alter_connection()
3256        } else if self.parse_keyword(Keyword::USER) {
3257            self.parse_alter_user()
3258        } else if self.parse_keyword(Keyword::SYSTEM) {
3259            self.parse_alter_system()
3260        } else if self.parse_keyword(Keyword::SUBSCRIPTION) {
3261            self.parse_alter_subscription()
3262        } else if self.parse_keyword(Keyword::SECRET) {
3263            self.parse_alter_secret()
3264        } else if self.parse_word("FRAGMENT") {
3265            self.parse_alter_fragment()
3266        } else if self.parse_keyword(Keyword::COMPACTION) {
3267            self.parse_alter_compaction_group()
3268        } else if self.parse_keywords(&[Keyword::DEFAULT, Keyword::PRIVILEGES]) {
3269            self.parse_alter_default_privileges()
3270        } else {
3271            self.expected(
3272                "COMPACTION, DATABASE, FRAGMENT, SCHEMA, TABLE, INDEX, MATERIALIZED, VIEW, SINK, SUBSCRIPTION, SOURCE, FUNCTION, USER, SECRET or SYSTEM after ALTER"
3273            )
3274        }
3275    }
3276
3277    pub fn parse_alter_database(&mut self) -> ModalResult<Statement> {
3278        let database_name = self.parse_object_name()?;
3279        let operation = if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3280            let owner_name: Ident = self.parse_identifier()?;
3281            AlterDatabaseOperation::ChangeOwner {
3282                new_owner_name: owner_name,
3283            }
3284        } else if self.parse_keyword(Keyword::RENAME) {
3285            if self.parse_keyword(Keyword::TO) {
3286                let database_name = self.parse_object_name()?;
3287                AlterDatabaseOperation::RenameDatabase { database_name }
3288            } else {
3289                return self.expected("TO after RENAME");
3290            }
3291        } else if self.parse_keyword(Keyword::SET) {
3292            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3293                if self.expect_keyword(Keyword::TO).is_err()
3294                    && self.expect_token(&Token::Eq).is_err()
3295                {
3296                    return self.expected("TO or = after ALTER DATABASE SET RESOURCE_GROUP");
3297                }
3298                let value = self.parse_set_variable()?;
3299                if !self.parse_keyword(Keyword::DEFERRED) {
3300                    return self.expected("DEFERRED after ALTER DATABASE SET RESOURCE_GROUP");
3301                }
3302
3303                AlterDatabaseOperation::SetResourceGroup {
3304                    resource_group: Some(value),
3305                    deferred: true,
3306                }
3307            } else {
3308                // check will be delayed to frontend
3309                AlterDatabaseOperation::SetParam(self.parse_config_param()?)
3310            }
3311        } else if self.parse_keyword(Keyword::RESET) {
3312            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3313                if !self.parse_keyword(Keyword::DEFERRED) {
3314                    return self.expected("DEFERRED after ALTER DATABASE RESET RESOURCE_GROUP");
3315                }
3316
3317                AlterDatabaseOperation::SetResourceGroup {
3318                    resource_group: None,
3319                    deferred: true,
3320                }
3321            } else {
3322                return self.expected("RESOURCE_GROUP after RESET");
3323            }
3324        } else {
3325            return self.expected("RENAME, OWNER TO, SET, OR RESET after ALTER DATABASE");
3326        };
3327
3328        Ok(Statement::AlterDatabase {
3329            name: database_name,
3330            operation,
3331        })
3332    }
3333
3334    pub fn parse_alter_schema(&mut self) -> ModalResult<Statement> {
3335        let schema_name = self.parse_object_name()?;
3336        let operation = if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3337            let owner_name: Ident = self.parse_identifier()?;
3338            AlterSchemaOperation::ChangeOwner {
3339                new_owner_name: owner_name,
3340            }
3341        } else if self.parse_keyword(Keyword::RENAME) {
3342            self.expect_keyword(Keyword::TO)?;
3343            let schema_name = self.parse_object_name()?;
3344            AlterSchemaOperation::RenameSchema { schema_name }
3345        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3346            let target_schema = self.parse_object_name()?;
3347            AlterSchemaOperation::SwapRenameSchema { target_schema }
3348        } else {
3349            return self.expected("RENAME, OWNER TO, OR SWAP WITH after ALTER SCHEMA");
3350        };
3351
3352        Ok(Statement::AlterSchema {
3353            name: schema_name,
3354            operation,
3355        })
3356    }
3357
3358    pub fn parse_alter_user(&mut self) -> ModalResult<Statement> {
3359        Ok(Statement::AlterUser(AlterUserStatement::parse_to(self)?))
3360    }
3361
3362    pub fn parse_alter_table(&mut self) -> ModalResult<Statement> {
3363        let _ = self.parse_keyword(Keyword::ONLY);
3364        let table_name = self.parse_object_name()?;
3365        let operation = if self.parse_keyword(Keyword::ADD) {
3366            if let Some(constraint) = self.parse_optional_table_constraint()? {
3367                AlterTableOperation::AddConstraint(constraint)
3368            } else {
3369                let _ = self.parse_keyword(Keyword::COLUMN);
3370                let _if_not_exists =
3371                    self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
3372                let column_def = self.parse_column_def()?;
3373                AlterTableOperation::AddColumn { column_def }
3374            }
3375        } else if self.parse_keywords(&[Keyword::DROP, Keyword::CONNECTOR]) {
3376            AlterTableOperation::DropConnector
3377        } else if self.parse_keyword(Keyword::RENAME) {
3378            if self.parse_keyword(Keyword::CONSTRAINT) {
3379                let old_name = self.parse_identifier_non_reserved()?;
3380                self.expect_keyword(Keyword::TO)?;
3381                let new_name = self.parse_identifier_non_reserved()?;
3382                AlterTableOperation::RenameConstraint { old_name, new_name }
3383            } else if self.parse_keyword(Keyword::TO) {
3384                let table_name = self.parse_object_name()?;
3385                AlterTableOperation::RenameTable { table_name }
3386            } else {
3387                let _ = self.parse_keyword(Keyword::COLUMN);
3388                let old_column_name = self.parse_identifier_non_reserved()?;
3389                self.expect_keyword(Keyword::TO)?;
3390                let new_column_name = self.parse_identifier_non_reserved()?;
3391                AlterTableOperation::RenameColumn {
3392                    old_column_name,
3393                    new_column_name,
3394                }
3395            }
3396        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3397            let owner_name: Ident = self.parse_identifier()?;
3398            AlterTableOperation::ChangeOwner {
3399                new_owner_name: owner_name,
3400            }
3401        } else if self.parse_keyword(Keyword::SET) {
3402            if self.parse_keyword(Keyword::SCHEMA) {
3403                let schema_name = self.parse_object_name()?;
3404                AlterTableOperation::SetSchema {
3405                    new_schema_name: schema_name,
3406                }
3407            } else if self.parse_keyword(Keyword::PARALLELISM) {
3408                if self.expect_keyword(Keyword::TO).is_err()
3409                    && self.expect_token(&Token::Eq).is_err()
3410                {
3411                    return self.expected("TO or = after ALTER TABLE SET PARALLELISM");
3412                }
3413
3414                let value = self.parse_set_variable()?;
3415
3416                let deferred = self.parse_keyword(Keyword::DEFERRED);
3417
3418                AlterTableOperation::SetParallelism {
3419                    parallelism: value,
3420                    deferred,
3421                }
3422            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) {
3423                if self.expect_keyword(Keyword::TO).is_err()
3424                    && self.expect_token(&Token::Eq).is_err()
3425                {
3426                    return self.expected("TO or = after ALTER TABLE SET BACKFILL_PARALLELISM");
3427                }
3428
3429                let value = self.parse_set_variable()?;
3430
3431                let deferred = self.parse_keyword(Keyword::DEFERRED);
3432
3433                AlterTableOperation::SetBackfillParallelism {
3434                    parallelism: value,
3435                    deferred,
3436                }
3437            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3438                AlterTableOperation::AlterRateLimit(rate_limit)
3439            } else if self.parse_keyword(Keyword::CONFIG) {
3440                let entries = self.parse_options()?;
3441                AlterTableOperation::SetConfig { entries }
3442            } else {
3443                return self.expected(
3444                    "SCHEMA/PARALLELISM/BACKFILL_PARALLELISM/SOURCE_RATE_LIMIT/DML_RATE_LIMIT/CONFIG after SET",
3445                );
3446            }
3447        } else if self.parse_keyword(Keyword::RESET) {
3448            if self.parse_keyword(Keyword::CONFIG) {
3449                let keys = self.parse_parenthesized_object_name_list()?;
3450                AlterTableOperation::ResetConfig { keys }
3451            } else {
3452                return self.expected("CONFIG after RESET");
3453            }
3454        } else if self.parse_keyword(Keyword::DROP) {
3455            let _ = self.parse_keyword(Keyword::COLUMN);
3456            let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
3457            let column_name = self.parse_identifier_non_reserved()?;
3458            let cascade = self.parse_keyword(Keyword::CASCADE);
3459            AlterTableOperation::DropColumn {
3460                column_name,
3461                if_exists,
3462                cascade,
3463            }
3464        } else if self.parse_keyword(Keyword::ALTER) {
3465            // `WATERMARK` is non-reserved; require `FOR` so `ALTER <col>` on a
3466            // column named `watermark` still falls through to ALTER COLUMN.
3467            if self.parse_keywords(&[Keyword::WATERMARK, Keyword::FOR]) {
3468                let column_name = self.parse_identifier_non_reserved()?;
3469                self.expect_keyword(Keyword::AS)?;
3470                let expr = self.parse_expr()?;
3471                let with_ttl = self.parse_keywords(&[Keyword::WITH, Keyword::TTL]);
3472                return Ok(Statement::AlterTable {
3473                    name: table_name,
3474                    operation: AlterTableOperation::AlterWatermark {
3475                        column_name,
3476                        expr,
3477                        with_ttl,
3478                    },
3479                });
3480            }
3481            let _ = self.parse_keyword(Keyword::COLUMN);
3482            let column_name = self.parse_identifier_non_reserved()?;
3483
3484            let op = if self.parse_keywords(&[Keyword::SET, Keyword::NOT, Keyword::NULL]) {
3485                AlterColumnOperation::SetNotNull {}
3486            } else if self.parse_keywords(&[Keyword::DROP, Keyword::NOT, Keyword::NULL]) {
3487                AlterColumnOperation::DropNotNull {}
3488            } else if self.parse_keywords(&[Keyword::SET, Keyword::DEFAULT]) {
3489                AlterColumnOperation::SetDefault {
3490                    value: self.parse_expr()?,
3491                }
3492            } else if self.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) {
3493                AlterColumnOperation::DropDefault {}
3494            } else if self.parse_keywords(&[Keyword::SET, Keyword::DATA, Keyword::TYPE])
3495                || (self.parse_keyword(Keyword::TYPE))
3496            {
3497                let data_type = self.parse_data_type()?;
3498                let using = if self.parse_keyword(Keyword::USING) {
3499                    Some(self.parse_expr()?)
3500                } else {
3501                    None
3502                };
3503                AlterColumnOperation::SetDataType { data_type, using }
3504            } else {
3505                return self
3506                    .expected("SET/DROP NOT NULL, SET DEFAULT, SET DATA TYPE after ALTER COLUMN");
3507            };
3508            AlterTableOperation::AlterColumn { column_name, op }
3509        } else if self.parse_keywords(&[Keyword::REFRESH, Keyword::SCHEMA]) {
3510            AlterTableOperation::RefreshSchema
3511        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3512            let target_table = self.parse_object_name()?;
3513            AlterTableOperation::SwapRenameTable { target_table }
3514        } else if self.parse_keyword(Keyword::CONNECTOR) {
3515            let with_options = self.parse_with_properties()?;
3516            AlterTableOperation::AlterConnectorProps {
3517                alter_props: with_options,
3518            }
3519        } else {
3520            return self.expected(
3521                "ADD or RENAME or OWNER TO or SET or RESET or DROP or SWAP or CONNECTOR after ALTER TABLE",
3522            );
3523        };
3524        Ok(Statement::AlterTable {
3525            name: table_name,
3526            operation,
3527        })
3528    }
3529
3530    fn parse_rate_limit_value(&mut self) -> ModalResult<i32> {
3531        if self.expect_keyword(Keyword::TO).is_err() && self.expect_token(&Token::Eq).is_err() {
3532            return self.expected("TO or = after rate limit");
3533        }
3534        if self.parse_keyword(Keyword::DEFAULT) {
3535            return Ok(-1);
3536        }
3537        let s = self.parse_number_value()?;
3538        if let Ok(n) = s.parse::<i32>() {
3539            Ok(n)
3540        } else {
3541            self.expected("number or DEFAULT")
3542        }
3543    }
3544
3545    pub fn parse_alter_rate_limit(&mut self) -> ModalResult<Option<AlterRateLimit>> {
3546        for rate_limit_type in [
3547            AlterRateLimitType::Source,
3548            AlterRateLimitType::Backfill,
3549            AlterRateLimitType::Dml,
3550            AlterRateLimitType::Sink,
3551        ] {
3552            if self.parse_word(rate_limit_type.as_str()) {
3553                let rate_limit = self.parse_rate_limit_value()?;
3554                return Ok(Some(AlterRateLimit {
3555                    rate_limit_type,
3556                    rate_limit,
3557                }));
3558            }
3559        }
3560        Ok(None)
3561    }
3562
3563    pub fn parse_alter_index(&mut self) -> ModalResult<Statement> {
3564        let index_name = self.parse_object_name()?;
3565        let operation = if self.parse_keyword(Keyword::RENAME) {
3566            if self.parse_keyword(Keyword::TO) {
3567                let index_name = self.parse_object_name()?;
3568                AlterIndexOperation::RenameIndex { index_name }
3569            } else {
3570                return self.expected("TO after RENAME");
3571            }
3572        } else if self.parse_keyword(Keyword::SET) {
3573            if self.parse_keyword(Keyword::PARALLELISM) {
3574                if self.expect_keyword(Keyword::TO).is_err()
3575                    && self.expect_token(&Token::Eq).is_err()
3576                {
3577                    return self.expected("TO or = after ALTER INDEX SET PARALLELISM");
3578                }
3579
3580                let value = self.parse_set_variable()?;
3581
3582                let deferred = self.parse_keyword(Keyword::DEFERRED);
3583
3584                AlterIndexOperation::SetParallelism {
3585                    parallelism: value,
3586                    deferred,
3587                }
3588            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) {
3589                if self.expect_keyword(Keyword::TO).is_err()
3590                    && self.expect_token(&Token::Eq).is_err()
3591                {
3592                    return self.expected("TO or = after ALTER INDEX SET BACKFILL_PARALLELISM");
3593                }
3594
3595                let value = self.parse_set_variable()?;
3596
3597                let deferred = self.parse_keyword(Keyword::DEFERRED);
3598
3599                AlterIndexOperation::SetBackfillParallelism {
3600                    parallelism: value,
3601                    deferred,
3602                }
3603            } else if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3604                if self.expect_keyword(Keyword::TO).is_err()
3605                    && self.expect_token(&Token::Eq).is_err()
3606                {
3607                    return self.expected("TO or = after ALTER INDEX SET RESOURCE_GROUP");
3608                }
3609                let value = self.parse_set_variable()?;
3610                let deferred = self.parse_keyword(Keyword::DEFERRED);
3611
3612                AlterIndexOperation::SetResourceGroup {
3613                    resource_group: Some(value),
3614                    deferred,
3615                }
3616            } else if self.parse_keyword(Keyword::CONFIG) {
3617                let entries = self.parse_options()?;
3618                AlterIndexOperation::SetConfig { entries }
3619            } else {
3620                return self.expected(
3621                    "PARALLELISM/BACKFILL_PARALLELISM/RESOURCE_GROUP or CONFIG after SET",
3622                );
3623            }
3624        } else if self.parse_keyword(Keyword::RESET) {
3625            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3626                let deferred = self.parse_keyword(Keyword::DEFERRED);
3627
3628                AlterIndexOperation::SetResourceGroup {
3629                    resource_group: None,
3630                    deferred,
3631                }
3632            } else if self.parse_keyword(Keyword::CONFIG) {
3633                let keys = self.parse_parenthesized_object_name_list()?;
3634                AlterIndexOperation::ResetConfig { keys }
3635            } else {
3636                return self.expected("RESOURCE_GROUP or CONFIG after RESET");
3637            }
3638        } else {
3639            return self.expected("RENAME, SET, or RESET after ALTER INDEX");
3640        };
3641
3642        Ok(Statement::AlterIndex {
3643            name: index_name,
3644            operation,
3645        })
3646    }
3647
3648    pub fn parse_alter_view(&mut self, materialized: bool) -> ModalResult<Statement> {
3649        let view_name = self.parse_object_name()?;
3650        let operation = if self.parse_keyword(Keyword::AS) {
3651            let query = Box::new(self.parse_query()?);
3652            AlterViewOperation::AsQuery { query }
3653        } else if self.parse_keyword(Keyword::RENAME) {
3654            if self.parse_keyword(Keyword::TO) {
3655                let view_name = self.parse_object_name()?;
3656                AlterViewOperation::RenameView { view_name }
3657            } else {
3658                return self.expected("TO after RENAME");
3659            }
3660        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3661            let owner_name: Ident = self.parse_identifier()?;
3662            AlterViewOperation::ChangeOwner {
3663                new_owner_name: owner_name,
3664            }
3665        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3666            let target_view = self.parse_object_name()?;
3667            AlterViewOperation::SwapRenameView { target_view }
3668        } else if self.parse_keyword(Keyword::SET) {
3669            if self.parse_keyword(Keyword::SCHEMA) {
3670                let schema_name = self.parse_object_name()?;
3671                AlterViewOperation::SetSchema {
3672                    new_schema_name: schema_name,
3673                }
3674            } else if self.parse_word("STREAMING_ENABLE_UNALIGNED_JOIN") {
3675                if self.expect_keyword(Keyword::TO).is_err()
3676                    && self.expect_token(&Token::Eq).is_err()
3677                {
3678                    return self
3679                        .expected("TO or = after ALTER TABLE SET STREAMING_ENABLE_UNALIGNED_JOIN");
3680                }
3681                let value = self.parse_boolean()?;
3682                AlterViewOperation::SetStreamingEnableUnalignedJoin { enable: value }
3683            } else if self.parse_keyword(Keyword::PARALLELISM) && materialized {
3684                if self.expect_keyword(Keyword::TO).is_err()
3685                    && self.expect_token(&Token::Eq).is_err()
3686                {
3687                    return self.expected("TO or = after ALTER MATERIALIZED VIEW SET PARALLELISM");
3688                }
3689
3690                let value = self.parse_set_variable()?;
3691
3692                let deferred = self.parse_keyword(Keyword::DEFERRED);
3693
3694                AlterViewOperation::SetParallelism {
3695                    parallelism: value,
3696                    deferred,
3697                }
3698            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) && materialized {
3699                if self.expect_keyword(Keyword::TO).is_err()
3700                    && self.expect_token(&Token::Eq).is_err()
3701                {
3702                    return self.expected(
3703                        "TO or = after ALTER MATERIALIZED VIEW SET BACKFILL_PARALLELISM",
3704                    );
3705                }
3706
3707                let value = self.parse_set_variable()?;
3708
3709                let deferred = self.parse_keyword(Keyword::DEFERRED);
3710
3711                AlterViewOperation::SetBackfillParallelism {
3712                    parallelism: value,
3713                    deferred,
3714                }
3715            } else if self.parse_keyword(Keyword::RESOURCE_GROUP) && materialized {
3716                if self.expect_keyword(Keyword::TO).is_err()
3717                    && self.expect_token(&Token::Eq).is_err()
3718                {
3719                    return self
3720                        .expected("TO or = after ALTER MATERIALIZED VIEW SET RESOURCE_GROUP");
3721                }
3722                let value = self.parse_set_variable()?;
3723                let deferred = self.parse_keyword(Keyword::DEFERRED);
3724
3725                AlterViewOperation::SetResourceGroup {
3726                    resource_group: Some(value),
3727                    deferred,
3728                }
3729            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3730                AlterViewOperation::AlterRateLimit(rate_limit)
3731            } else if self.parse_keyword(Keyword::CONFIG) && materialized {
3732                let entries = self.parse_options()?;
3733                AlterViewOperation::SetConfig { entries }
3734            } else {
3735                return self.expected(
3736                    "SCHEMA/PARALLELISM/BACKFILL_PARALLELISM/BACKFILL_RATE_LIMIT/CONFIG after SET",
3737                );
3738            }
3739        } else if self.parse_keyword(Keyword::RESET) {
3740            if self.parse_keyword(Keyword::RESOURCE_GROUP) && materialized {
3741                let deferred = self.parse_keyword(Keyword::DEFERRED);
3742
3743                AlterViewOperation::SetResourceGroup {
3744                    resource_group: None,
3745                    deferred,
3746                }
3747            } else if self.parse_keyword(Keyword::CONFIG) && materialized {
3748                let keys = self.parse_parenthesized_object_name_list()?;
3749                AlterViewOperation::ResetConfig { keys }
3750            } else {
3751                return self.expected("RESOURCE_GROUP or CONFIG after RESET");
3752            }
3753        } else {
3754            return self.expected(&format!(
3755                "AS, RENAME, OWNER TO, SET, or SWAP after ALTER {}VIEW",
3756                if materialized { "MATERIALIZED " } else { "" }
3757            ));
3758        };
3759
3760        Ok(Statement::AlterView {
3761            materialized,
3762            name: view_name,
3763            operation,
3764        })
3765    }
3766
3767    pub fn parse_alter_sink(&mut self) -> ModalResult<Statement> {
3768        let sink_name = self.parse_object_name()?;
3769        let operation = if self.parse_keyword(Keyword::RENAME) {
3770            if self.parse_keyword(Keyword::TO) {
3771                let sink_name = self.parse_object_name()?;
3772                AlterSinkOperation::RenameSink { sink_name }
3773            } else {
3774                return self.expected("TO after RENAME");
3775            }
3776        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3777            let owner_name: Ident = self.parse_identifier()?;
3778            AlterSinkOperation::ChangeOwner {
3779                new_owner_name: owner_name,
3780            }
3781        } else if self.parse_keyword(Keyword::SET) {
3782            if self.parse_keyword(Keyword::SCHEMA) {
3783                let schema_name = self.parse_object_name()?;
3784                AlterSinkOperation::SetSchema {
3785                    new_schema_name: schema_name,
3786                }
3787            } else if self.parse_word("STREAMING_ENABLE_UNALIGNED_JOIN") {
3788                self.expect_keyword(Keyword::TO)?;
3789                let value = self.parse_boolean()?;
3790                AlterSinkOperation::SetStreamingEnableUnalignedJoin { enable: value }
3791            } else if self.parse_keyword(Keyword::PARALLELISM) {
3792                if self.expect_keyword(Keyword::TO).is_err()
3793                    && self.expect_token(&Token::Eq).is_err()
3794                {
3795                    return self.expected("TO or = after ALTER SINK SET PARALLELISM");
3796                }
3797
3798                let value = self.parse_set_variable()?;
3799                let deferred = self.parse_keyword(Keyword::DEFERRED);
3800
3801                AlterSinkOperation::SetParallelism {
3802                    parallelism: value,
3803                    deferred,
3804                }
3805            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) {
3806                if self.expect_keyword(Keyword::TO).is_err()
3807                    && self.expect_token(&Token::Eq).is_err()
3808                {
3809                    return self.expected("TO or = after ALTER SINK SET BACKFILL_PARALLELISM");
3810                }
3811
3812                let value = self.parse_set_variable()?;
3813                let deferred = self.parse_keyword(Keyword::DEFERRED);
3814
3815                AlterSinkOperation::SetBackfillParallelism {
3816                    parallelism: value,
3817                    deferred,
3818                }
3819            } else if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3820                if self.expect_keyword(Keyword::TO).is_err()
3821                    && self.expect_token(&Token::Eq).is_err()
3822                {
3823                    return self.expected("TO or = after ALTER SINK SET RESOURCE_GROUP");
3824                }
3825                let value = self.parse_set_variable()?;
3826                let deferred = self.parse_keyword(Keyword::DEFERRED);
3827
3828                AlterSinkOperation::SetResourceGroup {
3829                    resource_group: Some(value),
3830                    deferred,
3831                }
3832            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3833                AlterSinkOperation::AlterRateLimit(rate_limit)
3834            } else if self.parse_keyword(Keyword::CONFIG) {
3835                let entries = self.parse_options()?;
3836                AlterSinkOperation::SetConfig { entries }
3837            } else {
3838                return self.expected(
3839                    "SCHEMA/PARALLELISM/BACKFILL_PARALLELISM/RESOURCE_GROUP/SINK_RATE_LIMIT/BACKFILL_RATE_LIMIT/STREAMING_ENABLE_UNALIGNED_JOIN/CONFIG after SET",
3840                );
3841            }
3842        } else if self.parse_keyword(Keyword::RESET) {
3843            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3844                let deferred = self.parse_keyword(Keyword::DEFERRED);
3845
3846                AlterSinkOperation::SetResourceGroup {
3847                    resource_group: None,
3848                    deferred,
3849                }
3850            } else if self.parse_keyword(Keyword::CONFIG) {
3851                let keys = self.parse_parenthesized_object_name_list()?;
3852                AlterSinkOperation::ResetConfig { keys }
3853            } else {
3854                return self.expected("RESOURCE_GROUP or CONFIG after RESET");
3855            }
3856        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3857            let target_sink = self.parse_object_name()?;
3858            AlterSinkOperation::SwapRenameSink { target_sink }
3859        } else if self.parse_keyword(Keyword::CONNECTOR) {
3860            let changed_props = self.parse_with_properties()?;
3861            AlterSinkOperation::AlterConnectorProps {
3862                alter_props: changed_props,
3863            }
3864        } else {
3865            return self
3866                .expected("RENAME or OWNER TO or SET or RESET or CONNECTOR WITH after ALTER SINK");
3867        };
3868
3869        Ok(Statement::AlterSink {
3870            name: sink_name,
3871            operation,
3872        })
3873    }
3874
3875    pub fn parse_alter_subscription(&mut self) -> ModalResult<Statement> {
3876        let subscription_name = self.parse_object_name()?;
3877        let operation = if self.parse_keyword(Keyword::RENAME) {
3878            if self.parse_keyword(Keyword::TO) {
3879                let subscription_name = self.parse_object_name()?;
3880                AlterSubscriptionOperation::RenameSubscription { subscription_name }
3881            } else {
3882                return self.expected("TO after RENAME");
3883            }
3884        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3885            let owner_name: Ident = self.parse_identifier()?;
3886            AlterSubscriptionOperation::ChangeOwner {
3887                new_owner_name: owner_name,
3888            }
3889        } else if self.parse_keyword(Keyword::SET) {
3890            if self.parse_keyword(Keyword::SCHEMA) {
3891                let schema_name = self.parse_object_name()?;
3892                AlterSubscriptionOperation::SetSchema {
3893                    new_schema_name: schema_name,
3894                }
3895            } else if self.parse_keyword(Keyword::RETENTION) {
3896                if self.expect_keyword(Keyword::TO).is_err()
3897                    && self.expect_token(&Token::Eq).is_err()
3898                {
3899                    return self.expected("TO or = after ALTER SUBSCRIPTION SET RETENTION");
3900                }
3901                let retention = self.ensure_parse_value()?;
3902                AlterSubscriptionOperation::SetRetention { retention }
3903            } else {
3904                return self.expected("SCHEMA or RETENTION after SET");
3905            }
3906        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3907            let target_subscription = self.parse_object_name()?;
3908            AlterSubscriptionOperation::SwapRenameSubscription {
3909                target_subscription,
3910            }
3911        } else {
3912            return self.expected("RENAME or OWNER TO or SET or SWAP after ALTER SUBSCRIPTION");
3913        };
3914
3915        Ok(Statement::AlterSubscription {
3916            name: subscription_name,
3917            operation,
3918        })
3919    }
3920
3921    pub fn parse_alter_source(&mut self) -> ModalResult<Statement> {
3922        let source_name = self.parse_object_name()?;
3923        let operation = if self.parse_keyword(Keyword::RENAME) {
3924            if self.parse_keyword(Keyword::TO) {
3925                let source_name = self.parse_object_name()?;
3926                AlterSourceOperation::RenameSource { source_name }
3927            } else {
3928                return self.expected("TO after RENAME");
3929            }
3930        } else if self.parse_keyword(Keyword::ADD) {
3931            let _ = self.parse_keyword(Keyword::COLUMN);
3932            let _if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
3933            let column_def = self.parse_column_def()?;
3934            AlterSourceOperation::AddColumn { column_def }
3935        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3936            let owner_name: Ident = self.parse_identifier()?;
3937            AlterSourceOperation::ChangeOwner {
3938                new_owner_name: owner_name,
3939            }
3940        } else if self.parse_keyword(Keyword::SET) {
3941            if self.parse_keyword(Keyword::SCHEMA) {
3942                let schema_name = self.parse_object_name()?;
3943                AlterSourceOperation::SetSchema {
3944                    new_schema_name: schema_name,
3945                }
3946            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3947                AlterSourceOperation::AlterRateLimit(rate_limit)
3948            } else if self.parse_keyword(Keyword::PARALLELISM) {
3949                if self.expect_keyword(Keyword::TO).is_err()
3950                    && self.expect_token(&Token::Eq).is_err()
3951                {
3952                    return self.expected("TO or = after ALTER SOURCE SET PARALLELISM");
3953                }
3954
3955                let value = self.parse_set_variable()?;
3956                let deferred = self.parse_keyword(Keyword::DEFERRED);
3957
3958                AlterSourceOperation::SetParallelism {
3959                    parallelism: value,
3960                    deferred,
3961                }
3962            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) {
3963                if self.expect_keyword(Keyword::TO).is_err()
3964                    && self.expect_token(&Token::Eq).is_err()
3965                {
3966                    return self.expected("TO or = after ALTER SOURCE SET BACKFILL_PARALLELISM");
3967                }
3968
3969                let value = self.parse_set_variable()?;
3970                let deferred = self.parse_keyword(Keyword::DEFERRED);
3971
3972                AlterSourceOperation::SetBackfillParallelism {
3973                    parallelism: value,
3974                    deferred,
3975                }
3976            } else if self.parse_keyword(Keyword::CONFIG) {
3977                let entries = self.parse_options()?;
3978                AlterSourceOperation::SetConfig { entries }
3979            } else {
3980                return self.expected(
3981                    "SCHEMA, SOURCE_RATE_LIMIT, PARALLELISM, BACKFILL_PARALLELISM or CONFIG after SET",
3982                );
3983            }
3984        } else if self.parse_keyword(Keyword::RESET) {
3985            if self.parse_keyword(Keyword::CONFIG) {
3986                let keys = self.parse_parenthesized_object_name_list()?;
3987                AlterSourceOperation::ResetConfig { keys }
3988            } else {
3989                // RESET without CONFIG means reset CDC source offset to latest
3990                AlterSourceOperation::ResetSource
3991            }
3992        } else if self.peek_nth_any_of_keywords(0, &[Keyword::FORMAT]) {
3993            let format_encode = self.parse_schema()?.unwrap();
3994            if format_encode.key_encode.is_some() {
3995                parser_err!("key encode clause is not supported in source schema");
3996            }
3997            AlterSourceOperation::FormatEncode { format_encode }
3998        } else if self.parse_keywords(&[Keyword::REFRESH, Keyword::SCHEMA]) {
3999            AlterSourceOperation::RefreshSchema
4000        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
4001            let target_source = self.parse_object_name()?;
4002            AlterSourceOperation::SwapRenameSource { target_source }
4003        } else if self.parse_keyword(Keyword::CONNECTOR) {
4004            let with_options = self.parse_with_properties()?;
4005            AlterSourceOperation::AlterConnectorProps {
4006                alter_props: with_options,
4007            }
4008        } else {
4009            return self.expected(
4010                "RENAME, ADD COLUMN, OWNER TO, CONNECTOR, SET or RESET after ALTER SOURCE",
4011            );
4012        };
4013
4014        Ok(Statement::AlterSource {
4015            name: source_name,
4016            operation,
4017        })
4018    }
4019
4020    pub fn parse_alter_function(&mut self) -> ModalResult<Statement> {
4021        let FunctionDesc { name, args } = self.parse_function_desc()?;
4022
4023        let operation = if self.parse_keyword(Keyword::SET) {
4024            if self.parse_keyword(Keyword::SCHEMA) {
4025                let schema_name = self.parse_object_name()?;
4026                AlterFunctionOperation::SetSchema {
4027                    new_schema_name: schema_name,
4028                }
4029            } else {
4030                return self.expected("SCHEMA after SET");
4031            }
4032        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
4033            let owner_name: Ident = self.parse_identifier()?;
4034            AlterFunctionOperation::ChangeOwner {
4035                new_owner_name: owner_name,
4036            }
4037        } else {
4038            return self.expected("SET or OWNER TO after ALTER FUNCTION");
4039        };
4040
4041        Ok(Statement::AlterFunction {
4042            name,
4043            args,
4044            operation,
4045        })
4046    }
4047
4048    pub fn parse_alter_connection(&mut self) -> ModalResult<Statement> {
4049        let connection_name = self.parse_object_name()?;
4050        let operation = if self.parse_keyword(Keyword::SET) {
4051            if self.parse_keyword(Keyword::SCHEMA) {
4052                let schema_name = self.parse_object_name()?;
4053                AlterConnectionOperation::SetSchema {
4054                    new_schema_name: schema_name,
4055                }
4056            } else {
4057                return self.expected("SCHEMA after SET");
4058            }
4059        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
4060            let owner_name: Ident = self.parse_identifier()?;
4061            AlterConnectionOperation::ChangeOwner {
4062                new_owner_name: owner_name,
4063            }
4064        } else if self.parse_keyword(Keyword::CONNECTOR) {
4065            let with_options = self.parse_with_properties()?;
4066            AlterConnectionOperation::AlterConnectorProps {
4067                alter_props: with_options,
4068            }
4069        } else {
4070            return self.expected("SET, OWNER TO, or CONNECTOR WITH after ALTER CONNECTION");
4071        };
4072
4073        Ok(Statement::AlterConnection {
4074            name: connection_name,
4075            operation,
4076        })
4077    }
4078
4079    pub fn parse_alter_system(&mut self) -> ModalResult<Statement> {
4080        if self.parse_word("CLEAR") {
4081            self.expect_keywords(&[Keyword::FILE, Keyword::CACHE])?;
4082            let cache_type = if self.parse_keyword(Keyword::META) {
4083                FileCacheType::Meta
4084            } else if self.parse_keyword(Keyword::DATA) {
4085                FileCacheType::Data
4086            } else if self.parse_keyword(Keyword::ALL) {
4087                FileCacheType::All
4088            } else {
4089                return self.expected("META, DATA, or ALL after ALTER SYSTEM CLEAR FILE CACHE");
4090            };
4091            return Ok(Statement::AlterSystemClearFileCache { cache_type });
4092        }
4093
4094        self.expect_keyword(Keyword::SET)?;
4095        let param = self.parse_identifier()?;
4096        if self.expect_keyword(Keyword::TO).is_err() && self.expect_token(&Token::Eq).is_err() {
4097            return self.expected("TO or = after ALTER SYSTEM SET");
4098        }
4099        let value = self.parse_set_variable()?;
4100        Ok(Statement::AlterSystem { param, value })
4101    }
4102
4103    pub fn parse_alter_secret(&mut self) -> ModalResult<Statement> {
4104        let secret_name = self.parse_object_name()?;
4105        let operation = if self.parse_keyword(Keyword::WITH) {
4106            let with_options = self.parse_options()?;
4107            if self.parse_keyword(Keyword::AS) {
4108                let new_credential = self.ensure_parse_value()?;
4109                AlterSecretOperation::ChangeCredential {
4110                    with_options,
4111                    new_credential,
4112                }
4113            } else {
4114                return self.expected("Keyword AS after Options");
4115            }
4116        } else if self.parse_keyword(Keyword::AS) {
4117            let new_credential = self.ensure_parse_value()?;
4118            AlterSecretOperation::ChangeCredential {
4119                with_options: vec![],
4120                new_credential,
4121            }
4122        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
4123            let owner_name: Ident = self.parse_identifier()?;
4124            AlterSecretOperation::ChangeOwner {
4125                new_owner_name: owner_name,
4126            }
4127        } else {
4128            return self.expected("WITH, AS or OWNER TO after ALTER SECRET");
4129        };
4130        Ok(Statement::AlterSecret {
4131            name: secret_name,
4132            operation,
4133        })
4134    }
4135
4136    pub fn parse_alter_fragment(&mut self) -> ModalResult<Statement> {
4137        let mut fragment_ids = vec![self.parse_literal_u32()?];
4138        while self.consume_token(&Token::Comma) {
4139            fragment_ids.push(self.parse_literal_u32()?);
4140        }
4141        if !self.parse_keyword(Keyword::SET) {
4142            return self.expected("SET after ALTER FRAGMENT");
4143        }
4144        let operation = if self.parse_keyword(Keyword::PARALLELISM) {
4145            if self.expect_keyword(Keyword::TO).is_err() && self.expect_token(&Token::Eq).is_err() {
4146                return self.expected("TO or = after ALTER FRAGMENT SET PARALLELISM");
4147            }
4148            let parallelism = self.parse_set_variable()?;
4149            AlterFragmentOperation::SetParallelism { parallelism }
4150        } else {
4151            let rate_limit = self.parse_alter_fragment_rate_limit()?;
4152            AlterFragmentOperation::AlterRateLimit(rate_limit)
4153        };
4154        Ok(Statement::AlterFragment {
4155            fragment_ids,
4156            operation,
4157        })
4158    }
4159
4160    pub fn parse_alter_compaction_group(&mut self) -> ModalResult<Statement> {
4161        if !self.parse_keyword(Keyword::GROUP) {
4162            return self.expected("GROUP after ALTER COMPACTION");
4163        }
4164        let mut group_ids = vec![self.parse_literal_u64()?];
4165        while self.consume_token(&Token::Comma) {
4166            group_ids.push(self.parse_literal_u64()?);
4167        }
4168        if !self.parse_keyword(Keyword::SET) {
4169            return self.expected("SET after ALTER COMPACTION GROUP <id>");
4170        }
4171        // NOTE: use the `no_list` variant here, because `parse_set_variable` allows comma-separated
4172        // lists (e.g., `SET foo = 1,2,3`), which would conflict with our use of comma to separate
4173        // multiple config assignments.
4174        let configs = self.parse_comma_separated(Parser::parse_config_param_no_list)?;
4175        let operation = AlterCompactionGroupOperation::Set { configs };
4176        Ok(Statement::AlterCompactionGroup {
4177            group_ids,
4178            operation,
4179        })
4180    }
4181
4182    fn parse_alter_fragment_rate_limit(&mut self) -> ModalResult<AlterRateLimit> {
4183        if self.parse_word("RATE_LIMIT") {
4184            let rate_limit = self.parse_rate_limit_value()?;
4185            return Ok(AlterRateLimit {
4186                rate_limit_type: AlterRateLimitType::Backfill,
4187                rate_limit,
4188            });
4189        }
4190        if let Some(rate_limit) = self.parse_alter_rate_limit()? {
4191            Ok(rate_limit)
4192        } else {
4193            self.expected("expected rate limit after SET")
4194        }
4195    }
4196
4197    /// Parse a copy statement
4198    pub fn parse_copy(&mut self) -> ModalResult<Statement> {
4199        let entity = if self.consume_token(&Token::LParen) {
4200            let query = self.parse_query()?;
4201            self.expect_token(&Token::RParen)?;
4202            CopyEntity::Query(query.into())
4203        } else {
4204            let table_name = self.parse_object_name()?;
4205            let columns = self.parse_parenthesized_column_list(Optional)?;
4206            CopyEntity::Table {
4207                table_name,
4208                columns,
4209            }
4210        };
4211
4212        let target = if self.parse_keywords(&[Keyword::FROM, Keyword::STDIN]) {
4213            self.expect_token(&Token::SemiColon)?;
4214            let values = self.parse_tsv();
4215            CopyTarget::Stdin { values }
4216        } else if self.parse_keywords(&[Keyword::TO, Keyword::STDOUT]) {
4217            CopyTarget::Stdout
4218        } else {
4219            return self.expected("FROM STDIN or TO STDOUT");
4220        };
4221
4222        Ok(Statement::Copy { entity, target })
4223    }
4224
4225    /// Parse a tab separated values in
4226    /// COPY payload
4227    fn parse_tsv(&mut self) -> Vec<Option<String>> {
4228        self.parse_tab_value()
4229    }
4230
4231    fn parse_tab_value(&mut self) -> Vec<Option<String>> {
4232        let mut values = vec![];
4233        let mut content = String::from("");
4234        while let Some(t) = self.next_token_no_skip() {
4235            match t.token {
4236                Token::Whitespace(Whitespace::Tab) => {
4237                    values.push(Some(content.clone()));
4238                    content.clear();
4239                }
4240                Token::Whitespace(Whitespace::Newline) => {
4241                    values.push(Some(content.clone()));
4242                    content.clear();
4243                }
4244                Token::Backslash => {
4245                    if self.consume_token(&Token::Period) {
4246                        return values;
4247                    }
4248                    if let Token::Word(w) = self.next_token().token
4249                        && w.value == "N"
4250                    {
4251                        values.push(None);
4252                    }
4253                }
4254                _ => {
4255                    content.push_str(&t.to_string());
4256                }
4257            }
4258        }
4259        values
4260    }
4261
4262    pub fn ensure_parse_value(&mut self) -> ModalResult<Value> {
4263        match self.parse_value_and_obj_ref::<true>()? {
4264            SqlOptionValue::Value(value) => Ok(value),
4265            SqlOptionValue::SecretRef(_)
4266            | SqlOptionValue::ConnectionRef(_)
4267            | SqlOptionValue::BackfillOrder(_) => unreachable!(),
4268        }
4269    }
4270
4271    /// Parse a literal value (numbers, strings, date/time, booleans)
4272    pub fn parse_value_and_obj_ref<const FORBID_OBJ_REF: bool>(
4273        &mut self,
4274    ) -> ModalResult<SqlOptionValue> {
4275        let checkpoint = *self;
4276        let token = self.next_token();
4277        match token.token {
4278            Token::Word(w) => match w.keyword {
4279                Keyword::TRUE => Ok(Value::Boolean(true).into()),
4280                Keyword::FALSE => Ok(Value::Boolean(false).into()),
4281                Keyword::NULL => Ok(Value::Null.into()),
4282                Keyword::NoKeyword if w.quote_style.is_some() => match w.quote_style {
4283                    Some('"') => Ok(Value::DoubleQuotedString(w.value).into()),
4284                    Some('\'') => Ok(Value::SingleQuotedString(w.value).into()),
4285                    _ => self.expected_at(checkpoint, "A value")?,
4286                },
4287                Keyword::SECRET => {
4288                    if FORBID_OBJ_REF {
4289                        return self.expected_at(
4290                            checkpoint,
4291                            "a concrete value rather than a secret reference",
4292                        );
4293                    }
4294                    let secret = self.parse_secret_ref()?;
4295                    Ok(SqlOptionValue::SecretRef(secret))
4296                }
4297                _ => self.expected_at(checkpoint, "a concrete value"),
4298            },
4299            Token::Number(ref n) => Ok(Value::Number(n.clone()).into()),
4300            Token::SingleQuotedString(ref s) => Ok(Value::SingleQuotedString(s.clone()).into()),
4301            Token::DollarQuotedString(ref s) => Ok(Value::DollarQuotedString(s.clone()).into()),
4302            Token::CstyleEscapesString(ref s) => Ok(Value::CstyleEscapedString(s.clone()).into()),
4303            Token::NationalStringLiteral(ref s) => {
4304                Ok(Value::NationalStringLiteral(s.clone()).into())
4305            }
4306            Token::HexStringLiteral(ref s) => Ok(Value::HexStringLiteral(s.clone()).into()),
4307            _ => self.expected_at(checkpoint, "a value"),
4308        }
4309    }
4310
4311    fn parse_secret_ref(&mut self) -> ModalResult<SecretRefValue> {
4312        let secret_name = self.parse_object_name()?;
4313        let ref_as = if self.parse_keywords(&[Keyword::AS, Keyword::FILE]) {
4314            SecretRefAsType::File
4315        } else {
4316            SecretRefAsType::Text
4317        };
4318        Ok(SecretRefValue {
4319            secret_name,
4320            ref_as,
4321        })
4322    }
4323
4324    fn parse_set_variable(&mut self) -> ModalResult<SetVariableValue> {
4325        alt((
4326            Keyword::DEFAULT.value(SetVariableValue::Default),
4327            separated(
4328                1..,
4329                alt((
4330                    Self::ensure_parse_value.map(SetVariableValueSingle::Literal),
4331                    |parser: &mut Self| {
4332                        let checkpoint = *parser;
4333                        let ident = parser.parse_identifier()?;
4334                        if parser.consume_token(&Token::LParen) {
4335                            let args = parser.parse_comma_separated(Parser::ensure_parse_value)?;
4336                            parser.expect_token(&Token::RParen)?;
4337                            let raw = format!(
4338                                "{}({})",
4339                                ident,
4340                                args.iter().map(ToString::to_string).join(", ")
4341                            );
4342                            return Ok(SetVariableValueSingle::Raw(raw));
4343                        }
4344                        if ident.value == "default" {
4345                            *parser = checkpoint;
4346                            return parser.expected("parameter list value").map_err(|e| e.cut());
4347                        }
4348                        Ok(SetVariableValueSingle::Ident(ident))
4349                    },
4350                    fail.expect("parameter value"),
4351                )),
4352                Token::Comma,
4353            )
4354            .map(|list: Vec<SetVariableValueSingle>| {
4355                if list.len() == 1 {
4356                    SetVariableValue::Single(list[0].clone())
4357                } else {
4358                    SetVariableValue::List(list)
4359                }
4360            }),
4361        ))
4362        .parse_next(self)
4363    }
4364
4365    fn parse_backfill_order_strategy(&mut self) -> ModalResult<BackfillOrderStrategy> {
4366        alt((
4367            Keyword::DEFAULT.value(BackfillOrderStrategy::Default),
4368            Keyword::NONE.value(BackfillOrderStrategy::None),
4369            Keyword::AUTO.value(BackfillOrderStrategy::Auto),
4370            Self::parse_fixed_backfill_order.map(BackfillOrderStrategy::Fixed),
4371            fail.expect("backfill order strategy"),
4372        ))
4373        .parse_next(self)
4374    }
4375
4376    fn parse_fixed_backfill_order(&mut self) -> ModalResult<Vec<(ObjectName, ObjectName)>> {
4377        self.expect_word("FIXED")?;
4378        self.expect_token(&Token::LParen)?;
4379        let edges = separated(
4380            0..,
4381            separated_pair(
4382                Self::parse_object_name,
4383                Token::Op("->".to_owned()),
4384                Self::parse_object_name,
4385            ),
4386            Token::Comma,
4387        )
4388        .parse_next(self)?;
4389        self.expect_token(&Token::RParen)?;
4390        Ok(edges)
4391    }
4392
4393    pub fn parse_number_value(&mut self) -> ModalResult<String> {
4394        let checkpoint = *self;
4395        match self.ensure_parse_value()? {
4396            Value::Number(v) => Ok(v),
4397            _ => self.expected_at(checkpoint, "literal number"),
4398        }
4399    }
4400
4401    pub fn parse_literal_u32(&mut self) -> ModalResult<u32> {
4402        literal_u32(self)
4403    }
4404
4405    pub fn parse_literal_u64(&mut self) -> ModalResult<u64> {
4406        literal_u64(self)
4407    }
4408
4409    pub fn parse_function_definition(&mut self) -> ModalResult<FunctionDefinition> {
4410        alt((
4411            single_quoted_string.map(FunctionDefinition::SingleQuotedDef),
4412            dollar_quoted_string.map(FunctionDefinition::DoubleDollarDef),
4413            Self::parse_identifier.map(|i| FunctionDefinition::Identifier(i.value)),
4414            fail.expect("function definition"),
4415        ))
4416        .parse_next(self)
4417    }
4418
4419    /// Parse a literal string
4420    pub fn parse_literal_string(&mut self) -> ModalResult<String> {
4421        let checkpoint = *self;
4422        let token = self.next_token();
4423        match token.token {
4424            Token::SingleQuotedString(s) => Ok(s),
4425            Token::DollarQuotedString(s) => Ok(s.value),
4426            _ => self.expected_at(checkpoint, "literal string"),
4427        }
4428    }
4429
4430    /// Parse a SQL datatype (in the context of a CREATE TABLE statement for example)
4431    pub fn parse_data_type(&mut self) -> ModalResult<DataType> {
4432        parser_v2::data_type(self)
4433    }
4434
4435    /// Parse `AS identifier` (or simply `identifier` if it's not a reserved keyword)
4436    /// Some examples with aliases: `SELECT 1 foo`, `SELECT COUNT(*) AS cnt`,
4437    /// `SELECT ... FROM t1 foo, t2 bar`, `SELECT ... FROM (...) AS bar`
4438    pub fn parse_optional_alias(
4439        &mut self,
4440        reserved_kwds: &[Keyword],
4441    ) -> ModalResult<Option<Ident>> {
4442        let after_as = self.parse_keyword(Keyword::AS);
4443        let checkpoint = *self;
4444        let token = self.next_token();
4445        match token.token {
4446            // Accept any identifier after `AS` (though many dialects have restrictions on
4447            // keywords that may appear here). If there's no `AS`: don't parse keywords,
4448            // which may start a construct allowed in this position, to be parsed as aliases.
4449            // (For example, in `FROM t1 JOIN` the `JOIN` will always be parsed as a keyword,
4450            // not an alias.)
4451            Token::Word(w) if after_as || (!reserved_kwds.contains(&w.keyword)) => {
4452                // Contextual reservation: `MATCH_RECOGNIZE` is deliberately NOT a keyword (a
4453                // stored definition may use it as a bare alias from before the clause existed,
4454                // and keywords change quoting and identifier parsing globally), so the clause is
4455                // recognised here instead — a bare `match_recognize` immediately followed by `(`
4456                // opens the clause and must not be taken as an implicit alias. With an explicit
4457                // `AS`, or quoted, or not followed by `(`, it stays a perfectly good alias.
4458                if !after_as
4459                    && w.quote_style.is_none()
4460                    && w.value.eq_ignore_ascii_case("MATCH_RECOGNIZE")
4461                    && self.peek_token() == Token::LParen
4462                {
4463                    *self = checkpoint;
4464                    return Ok(None);
4465                }
4466                Ok(Some(w.to_ident()?))
4467            }
4468            _ => {
4469                *self = checkpoint;
4470                if after_as {
4471                    return self.expected("an identifier after AS");
4472                }
4473                Ok(None) // no alias found
4474            }
4475        }
4476    }
4477
4478    /// Parse `AS identifier` when the AS is describing a table-valued object,
4479    /// like in `... FROM generate_series(1, 10) AS t (col)`. In this case
4480    /// the alias is allowed to optionally name the columns in the table, in
4481    /// addition to the table itself.
4482    pub fn parse_optional_table_alias(
4483        &mut self,
4484        reserved_kwds: &[Keyword],
4485    ) -> ModalResult<Option<TableAlias>> {
4486        if self.peek_broadcast_join() {
4487            return Ok(None);
4488        }
4489        match self.parse_optional_alias(reserved_kwds)? {
4490            Some(name) => {
4491                let columns = self.parse_parenthesized_column_list(Optional)?;
4492                Ok(Some(TableAlias { name, columns }))
4493            }
4494            None => Ok(None),
4495        }
4496    }
4497
4498    /// syntax `FOR SYSTEM_TIME AS OF PROCTIME()` is used for temporal join.
4499    pub fn parse_as_of(&mut self) -> ModalResult<AsOf> {
4500        Keyword::FOR.parse_next(self)?;
4501        alt((
4502            preceded(
4503                (Keyword::SYSTEM_TIME, Keyword::AS, Keyword::OF),
4504                cut_err(
4505                    alt((
4506                        preceded(
4507                            (
4508                                Self::parse_identifier.verify(|ident| ident.real_value() == "now"),
4509                                cut_err(Token::LParen),
4510                                cut_err(Token::RParen),
4511                                Token::Minus,
4512                            ),
4513                            Self::parse_literal_interval.try_map(|e| match e {
4514                                Expr::Value(v) => match v {
4515                                    Value::Interval {
4516                                        value,
4517                                        leading_field,
4518                                        ..
4519                                    } => {
4520                                        let Some(leading_field) = leading_field else {
4521                                            return Err(StrError("expect duration unit".into()));
4522                                        };
4523                                        Ok(AsOf::ProcessTimeWithInterval((value, leading_field)))
4524                                    }
4525                                    _ => Err(StrError("expect Value::Interval".into())),
4526                                },
4527                                _ => Err(StrError("expect Expr::Value".into())),
4528                            }),
4529                        ),
4530                        (
4531                            Self::parse_identifier.verify(|ident| ident.real_value() == "now"),
4532                            cut_err(Token::LParen),
4533                            cut_err(Token::RParen),
4534                        )
4535                            .value(AsOf::ProcessTimeWithInterval((
4536                                "0".to_owned(),
4537                                DateTimeField::Second,
4538                            ))),
4539                        (
4540                            Self::parse_identifier.verify(|ident| ident.real_value() == "proctime"),
4541                            cut_err(Token::LParen),
4542                            cut_err(Token::RParen),
4543                        )
4544                            .value(AsOf::ProcessTime),
4545                        literal_i64.map(AsOf::TimestampNum),
4546                        single_quoted_string.map(AsOf::TimestampString),
4547                    ))
4548                    .expect("proctime(), now(), number or string"),
4549                ),
4550            ),
4551            preceded(
4552                (Keyword::SYSTEM_VERSION, Keyword::AS, Keyword::OF),
4553                cut_err(
4554                    alt((
4555                        literal_i64.map(AsOf::VersionNum),
4556                        single_quoted_string.map(AsOf::VersionString),
4557                    ))
4558                    .expect("number or string"),
4559                ),
4560            ),
4561        ))
4562        .parse_next(self)
4563    }
4564
4565    /// Parse a possibly qualified, possibly quoted identifier, e.g.
4566    /// `foo` or `myschema."table"
4567    pub fn parse_object_name(&mut self) -> ModalResult<ObjectName> {
4568        let mut idents = vec![];
4569        loop {
4570            idents.push(self.parse_identifier()?);
4571            if !self.consume_token(&Token::Period) {
4572                break;
4573            }
4574        }
4575        Ok(ObjectName(idents))
4576    }
4577
4578    /// Parse a parenthesized comma-separated list of object names
4579    pub fn parse_parenthesized_object_name_list(&mut self) -> ModalResult<Vec<ObjectName>> {
4580        if self.consume_token(&Token::LParen) {
4581            let names = self.parse_comma_separated(Parser::parse_object_name)?;
4582            self.expect_token(&Token::RParen)?;
4583            Ok(names)
4584        } else {
4585            self.expected("a list of object names in parentheses")
4586        }
4587    }
4588
4589    /// Parse identifiers strictly i.e. don't parse keywords
4590    pub fn parse_identifiers_non_keywords(&mut self) -> ModalResult<Vec<Ident>> {
4591        let mut idents = vec![];
4592        loop {
4593            match self.peek_token().token {
4594                Token::Word(w) => {
4595                    if w.keyword != Keyword::NoKeyword {
4596                        break;
4597                    }
4598
4599                    idents.push(w.to_ident()?);
4600                }
4601                Token::EOF | Token::Eq => break,
4602                _ => {}
4603            }
4604
4605            self.next_token();
4606        }
4607
4608        Ok(idents)
4609    }
4610
4611    /// Parse identifiers
4612    pub fn parse_identifiers(&mut self) -> ModalResult<Vec<Ident>> {
4613        let mut idents = vec![];
4614        loop {
4615            let token = self.next_token();
4616            match token.token {
4617                Token::Word(w) => {
4618                    idents.push(w.to_ident()?);
4619                }
4620                Token::EOF => break,
4621                _ => {}
4622            }
4623        }
4624
4625        Ok(idents)
4626    }
4627
4628    /// Parse a simple one-word identifier (possibly quoted, possibly a keyword)
4629    pub fn parse_identifier(&mut self) -> ModalResult<Ident> {
4630        let checkpoint = *self;
4631        let token = self.next_token();
4632        match token.token {
4633            Token::Word(w) => Ok(w.to_ident()?),
4634            _ => self.expected_at(checkpoint, "identifier"),
4635        }
4636    }
4637
4638    /// Parse a simple one-word identifier (possibly quoted, possibly a non-reserved keyword)
4639    pub fn parse_identifier_non_reserved(&mut self) -> ModalResult<Ident> {
4640        let checkpoint = *self;
4641        let token = self.next_token();
4642        match token.token {
4643            Token::Word(w) => {
4644                match keywords::RESERVED_FOR_COLUMN_OR_TABLE_NAME.contains(&w.keyword) {
4645                    true => parser_err!("syntax error at or near {w}"),
4646                    false => Ok(w.to_ident()?),
4647                }
4648            }
4649            _ => self.expected_at(checkpoint, "identifier"),
4650        }
4651    }
4652
4653    /// Parse a parenthesized comma-separated list of unqualified, possibly quoted identifiers
4654    pub fn parse_parenthesized_column_list(
4655        &mut self,
4656        optional: IsOptional,
4657    ) -> ModalResult<Vec<Ident>> {
4658        if self.consume_token(&Token::LParen) {
4659            let cols = self.parse_comma_separated(Parser::parse_identifier_non_reserved)?;
4660            self.expect_token(&Token::RParen)?;
4661            Ok(cols)
4662        } else if optional == Optional {
4663            Ok(vec![])
4664        } else {
4665            self.expected("a list of columns in parentheses")
4666        }
4667    }
4668
4669    pub fn parse_returning(&mut self, optional: IsOptional) -> ModalResult<Vec<SelectItem>> {
4670        if self.parse_keyword(Keyword::RETURNING) {
4671            let cols = self.parse_comma_separated(Parser::parse_select_item)?;
4672            Ok(cols)
4673        } else if optional == Optional {
4674            Ok(vec![])
4675        } else {
4676            self.expected("a list of columns or * after returning")
4677        }
4678    }
4679
4680    pub fn parse_row_expr(&mut self) -> ModalResult<Expr> {
4681        Ok(Expr::Row(self.parse_token_wrapped_exprs(
4682            &Token::LParen,
4683            &Token::RParen,
4684        )?))
4685    }
4686
4687    /// Parse a comma-separated list (maybe empty) from a wrapped expression
4688    pub fn parse_token_wrapped_exprs(
4689        &mut self,
4690        left: &Token,
4691        right: &Token,
4692    ) -> ModalResult<Vec<Expr>> {
4693        if self.consume_token(left) {
4694            let exprs = if self.consume_token(right) {
4695                vec![]
4696            } else {
4697                let exprs = self.parse_comma_separated(Parser::parse_expr)?;
4698                self.expect_token(right)?;
4699                exprs
4700            };
4701            Ok(exprs)
4702        } else {
4703            self.expected(left.to_string().as_str())
4704        }
4705    }
4706
4707    pub fn parse_optional_precision(&mut self) -> ModalResult<Option<u64>> {
4708        if self.consume_token(&Token::LParen) {
4709            let n = self.parse_literal_u64()?;
4710            self.expect_token(&Token::RParen)?;
4711            Ok(Some(n))
4712        } else {
4713            Ok(None)
4714        }
4715    }
4716
4717    pub fn parse_optional_precision_scale(&mut self) -> ModalResult<(Option<u64>, Option<u64>)> {
4718        if self.consume_token(&Token::LParen) {
4719            let n = self.parse_literal_u64()?;
4720            let scale = if self.consume_token(&Token::Comma) {
4721                Some(self.parse_literal_u64()?)
4722            } else {
4723                None
4724            };
4725            self.expect_token(&Token::RParen)?;
4726            Ok((Some(n), scale))
4727        } else {
4728            Ok((None, None))
4729        }
4730    }
4731
4732    pub fn parse_delete(&mut self) -> ModalResult<Statement> {
4733        if self.parse_keyword(Keyword::META) {
4734            let Some(_) = self.parse_one_of_keywords(&[Keyword::SNAPSHOT, Keyword::SNAPSHOTS])
4735            else {
4736                return self.expected("SNAPSHOT or SNAPSHOTS");
4737            };
4738            let snapshot_ids = self.parse_comma_separated(Parser::parse_literal_u64)?;
4739            return Ok(Statement::DeleteMetaSnapshots { snapshot_ids });
4740        }
4741
4742        self.expect_keyword(Keyword::FROM)?;
4743        let table_name = self.parse_object_name()?;
4744        let selection = if self.parse_keyword(Keyword::WHERE) {
4745            Some(self.parse_expr()?)
4746        } else {
4747            None
4748        };
4749        let returning = self.parse_returning(Optional)?;
4750
4751        Ok(Statement::Delete {
4752            table_name,
4753            selection,
4754            returning,
4755        })
4756    }
4757
4758    pub fn parse_boolean(&mut self) -> ModalResult<bool> {
4759        if let Some(keyword) = self.parse_one_of_keywords(&[Keyword::TRUE, Keyword::FALSE]) {
4760            match keyword {
4761                Keyword::TRUE => Ok(true),
4762                Keyword::FALSE => Ok(false),
4763                _ => unreachable!(),
4764            }
4765        } else {
4766            self.expected("TRUE or FALSE")
4767        }
4768    }
4769
4770    pub fn parse_optional_boolean(&mut self, default: bool) -> bool {
4771        self.parse_boolean().unwrap_or(default)
4772    }
4773
4774    fn parse_explain_options(&mut self) -> ModalResult<(ExplainOptions, Option<u64>)> {
4775        let mut options = ExplainOptions::default();
4776        let mut analyze_duration = None;
4777
4778        const BACKFILL: &str = "backfill";
4779        const VERBOSE: &str = "verbose";
4780        const TRACE: &str = "trace";
4781        const TYPE: &str = "type";
4782        const LOGICAL: &str = "logical";
4783        const PHYSICAL: &str = "physical";
4784        const DISTSQL: &str = "distsql";
4785        const FORMAT: &str = "format";
4786        const DURATION_SECS: &str = "duration_secs";
4787
4788        let explain_options_identifiers = [
4789            BACKFILL,
4790            VERBOSE,
4791            TRACE,
4792            TYPE,
4793            LOGICAL,
4794            PHYSICAL,
4795            DISTSQL,
4796            FORMAT,
4797            DURATION_SECS,
4798        ];
4799
4800        let parse_explain_option = |parser: &mut Parser<'_>| -> ModalResult<()> {
4801            match parser.parse_identifier()?.real_value().as_str() {
4802                VERBOSE => options.verbose = parser.parse_optional_boolean(true),
4803                TRACE => options.trace = parser.parse_optional_boolean(true),
4804                BACKFILL => options.backfill = parser.parse_optional_boolean(true),
4805                TYPE => {
4806                    let explain_type = parser.parse_identifier()?.real_value();
4807                    match explain_type.as_str() {
4808                        LOGICAL => options.explain_type = ExplainType::Logical,
4809                        PHYSICAL => options.explain_type = ExplainType::Physical,
4810                        DISTSQL => options.explain_type = ExplainType::DistSql,
4811                        unexpected => {
4812                            parser_err!("unexpected explain type: [{unexpected}]")
4813                        }
4814                    }
4815                }
4816                LOGICAL => options.explain_type = ExplainType::Logical,
4817                PHYSICAL => options.explain_type = ExplainType::Physical,
4818                DISTSQL => options.explain_type = ExplainType::DistSql,
4819                FORMAT => {
4820                    options.explain_format = {
4821                        let format = parser.parse_identifier()?.real_value();
4822                        match format.as_str() {
4823                            "text" => ExplainFormat::Text,
4824                            "json" => ExplainFormat::Json,
4825                            "xml" => ExplainFormat::Xml,
4826                            "yaml" => ExplainFormat::Yaml,
4827                            "dot" => ExplainFormat::Dot,
4828                            unexpected => {
4829                                parser_err!("unexpected explain format [{unexpected}]")
4830                            }
4831                        }
4832                    }
4833                }
4834                DURATION_SECS => {
4835                    analyze_duration = Some(parser.parse_literal_u64()?);
4836                }
4837                unexpected => {
4838                    parser_err!("unexpected explain options: [{unexpected}]")
4839                }
4840            };
4841            Ok(())
4842        };
4843
4844        // In order to support following statement, we need to peek before consume.
4845        // explain (select 1) union (select 1)
4846        if self.peek_token() == Token::LParen
4847            && let Token::Word(word) = self.peek_nth_token(1).token
4848            && let Ok(ident) = word.to_ident()
4849            && explain_options_identifiers.contains(&ident.real_value().as_str())
4850        {
4851            assert!(self.consume_token(&Token::LParen));
4852            self.parse_comma_separated(parse_explain_option)?;
4853            self.expect_token(&Token::RParen)?;
4854        }
4855
4856        Ok((options, analyze_duration))
4857    }
4858
4859    pub fn parse_explain(&mut self) -> ModalResult<Statement> {
4860        let analyze = self.parse_keyword(Keyword::ANALYZE);
4861        let (options, analyze_duration) = self.parse_explain_options()?;
4862
4863        if analyze {
4864            fn parse_analyze_target(parser: &mut Parser<'_>) -> ModalResult<Option<AnalyzeTarget>> {
4865                if parser.parse_keyword(Keyword::TABLE) {
4866                    let table_name = parser.parse_object_name()?;
4867                    Ok(Some(AnalyzeTarget::Table(table_name)))
4868                } else if parser.parse_keyword(Keyword::INDEX) {
4869                    let index_name = parser.parse_object_name()?;
4870                    Ok(Some(AnalyzeTarget::Index(index_name)))
4871                } else if parser.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
4872                    let view_name = parser.parse_object_name()?;
4873                    Ok(Some(AnalyzeTarget::MaterializedView(view_name)))
4874                } else if parser.parse_keyword(Keyword::INDEX) {
4875                    let index_name = parser.parse_object_name()?;
4876                    Ok(Some(AnalyzeTarget::Index(index_name)))
4877                } else if parser.parse_keyword(Keyword::SINK) {
4878                    let sink_name = parser.parse_object_name()?;
4879                    Ok(Some(AnalyzeTarget::Sink(sink_name)))
4880                } else if parser.parse_word("ID") {
4881                    let job_id = parser.parse_literal_u32()?;
4882                    Ok(Some(AnalyzeTarget::Id(job_id)))
4883                } else {
4884                    Ok(None)
4885                }
4886            }
4887            if let Some(target) = parse_analyze_target(self)? {
4888                let statement = Statement::ExplainAnalyzeStreamJob {
4889                    target,
4890                    duration_secs: analyze_duration,
4891                };
4892                return Ok(statement);
4893            }
4894        }
4895
4896        let statement = match self.parse_statement() {
4897            Ok(statement) => statement,
4898            error @ Err(_) => {
4899                return if analyze {
4900                    self.expected_at(
4901                        *self,
4902                        "SINK, TABLE, MATERIALIZED VIEW, INDEX or a statement after ANALYZE",
4903                    )
4904                } else {
4905                    error
4906                };
4907            }
4908        };
4909        Ok(Statement::Explain {
4910            analyze,
4911            statement: Box::new(statement),
4912            options,
4913        })
4914    }
4915
4916    pub fn parse_describe(&mut self) -> ModalResult<Statement> {
4917        let kind = match self.parse_one_of_keywords(&[Keyword::FRAGMENT, Keyword::FRAGMENTS]) {
4918            Some(Keyword::FRAGMENT) => {
4919                let fragment_id = self.parse_literal_u32()?;
4920                return Ok(Statement::DescribeFragment { fragment_id });
4921            }
4922            Some(Keyword::FRAGMENTS) => DescribeKind::Fragments,
4923            None => DescribeKind::Plain,
4924            Some(_) => unreachable!(),
4925        };
4926        let name = self.parse_object_name()?;
4927        Ok(Statement::Describe { name, kind })
4928    }
4929
4930    /// Parse a query expression, i.e. a `SELECT` statement optionally
4931    /// preceded with some `WITH` CTE declarations and optionally followed
4932    /// by `ORDER BY`. Unlike some other parse_... methods, this one doesn't
4933    /// expect the initial keyword to be already consumed
4934    pub fn parse_query(&mut self) -> ModalResult<Query> {
4935        let with = if self.parse_keyword(Keyword::WITH) {
4936            Some(With {
4937                recursive: self.parse_keyword(Keyword::RECURSIVE),
4938                cte_tables: self.parse_comma_separated(Parser::parse_cte)?,
4939            })
4940        } else {
4941            None
4942        };
4943
4944        let body = self.parse_query_body(0)?;
4945
4946        let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
4947            self.parse_comma_separated(Parser::parse_order_by_expr)?
4948        } else {
4949            vec![]
4950        };
4951
4952        let mut limit = None;
4953        let mut offset = None;
4954        for _x in 0..2 {
4955            if limit.is_none() && self.parse_keyword(Keyword::LIMIT) {
4956                limit = self.parse_limit()?
4957            }
4958
4959            if offset.is_none() && self.parse_keyword(Keyword::OFFSET) {
4960                offset = Some(self.parse_offset()?)
4961            }
4962        }
4963
4964        let fetch = if self.parse_keyword(Keyword::FETCH) {
4965            if limit.is_some() {
4966                parser_err!("Cannot specify both LIMIT and FETCH");
4967            }
4968            let fetch = self.parse_fetch()?;
4969            if fetch.with_ties && order_by.is_empty() {
4970                parser_err!("WITH TIES cannot be specified without ORDER BY clause");
4971            }
4972            Some(fetch)
4973        } else {
4974            None
4975        };
4976
4977        Ok(Query {
4978            with,
4979            body,
4980            order_by,
4981            limit,
4982            offset,
4983            fetch,
4984        })
4985    }
4986
4987    /// Parse a CTE (`alias [( col1, col2, ... )] AS (subquery)`)
4988    fn parse_cte(&mut self) -> ModalResult<Cte> {
4989        let name = self.parse_identifier_non_reserved()?;
4990        let cte = if self.parse_keyword(Keyword::AS) {
4991            let cte_inner = self.parse_cte_inner()?;
4992            let alias = TableAlias {
4993                name,
4994                columns: vec![],
4995            };
4996            Cte { alias, cte_inner }
4997        } else {
4998            let columns = self.parse_parenthesized_column_list(Optional)?;
4999            self.expect_keyword(Keyword::AS)?;
5000            let cte_inner = self.parse_cte_inner()?;
5001            let alias = TableAlias { name, columns };
5002            Cte { alias, cte_inner }
5003        };
5004        Ok(cte)
5005    }
5006
5007    fn parse_cte_inner(&mut self) -> ModalResult<CteInner> {
5008        match self.expect_token(&Token::LParen) {
5009            Ok(()) => {
5010                let query = self.parse_query()?;
5011                self.expect_token(&Token::RParen)?;
5012                Ok(CteInner::Query(Box::new(query)))
5013            }
5014            _ => {
5015                let changelog = self.parse_identifier_non_reserved()?;
5016                if changelog.to_string().to_lowercase() != "changelog" {
5017                    parser_err!("Expected 'changelog' but found '{}'", changelog);
5018                }
5019                self.expect_keyword(Keyword::FROM)?;
5020                let from = self.parse_object_name()?;
5021                let key = self
5022                    .parse_keyword(Keyword::KEY)
5023                    .then(|| self.parse_parenthesized_column_list(Mandatory))
5024                    .transpose()?;
5025                let distributed_by = if self.parse_keyword(Keyword::DISTRIBUTED) {
5026                    self.expect_keyword(Keyword::BY)?;
5027                    Some(self.parse_parenthesized_column_list(Mandatory)?)
5028                } else {
5029                    None
5030                };
5031
5032                Ok(CteInner::ChangeLog {
5033                    from,
5034                    key,
5035                    distributed_by,
5036                })
5037            }
5038        }
5039    }
5040
5041    /// Parse a "query body", which is an expression with roughly the
5042    /// following grammar:
5043    /// ```text
5044    ///   query_body ::= restricted_select | '(' subquery ')' | set_operation
5045    ///   restricted_select ::= 'SELECT' [expr_list] [ from ] [ where ] [ groupby_having ]
5046    ///   subquery ::= query_body [ order_by_limit ]
5047    ///   set_operation ::= query_body { 'UNION' | 'EXCEPT' | 'INTERSECT' } [ 'ALL' ] query_body
5048    /// ```
5049    fn parse_query_body(&mut self, precedence: u8) -> ModalResult<SetExpr> {
5050        // We parse the expression using a Pratt parser, as in `parse_expr()`.
5051        // Start by parsing a restricted SELECT or a `(subquery)`:
5052        let mut expr = if self.parse_keyword(Keyword::SELECT) {
5053            SetExpr::Select(Box::new(self.parse_select()?))
5054        } else if self.consume_token(&Token::LParen) {
5055            // CTEs are not allowed here, but the parser currently accepts them
5056            let subquery = self.parse_query()?;
5057            self.expect_token(&Token::RParen)?;
5058            SetExpr::Query(Box::new(subquery))
5059        } else if self.parse_keyword(Keyword::VALUES) {
5060            SetExpr::Values(self.parse_values()?)
5061        } else {
5062            return self.expected("SELECT, VALUES, or a subquery in the query body");
5063        };
5064
5065        loop {
5066            // The query can be optionally followed by a set operator:
5067            let op = self.parse_set_operator(&self.peek_token().token);
5068            let next_precedence = match op {
5069                // UNION and EXCEPT have the same binding power and evaluate left-to-right
5070                Some(SetOperator::Union) | Some(SetOperator::Except) => 10,
5071                // INTERSECT has higher precedence than UNION/EXCEPT
5072                Some(SetOperator::Intersect) => 20,
5073                // Unexpected token or EOF => stop parsing the query body
5074                None => break,
5075            };
5076            if precedence >= next_precedence {
5077                break;
5078            }
5079            self.next_token(); // skip past the set operator
5080
5081            let all = self.parse_keyword(Keyword::ALL);
5082            let corresponding = self.parse_corresponding()?;
5083
5084            expr = SetExpr::SetOperation {
5085                left: Box::new(expr),
5086                op: op.unwrap(),
5087                corresponding,
5088                all,
5089                right: Box::new(self.parse_query_body(next_precedence)?),
5090            };
5091        }
5092
5093        Ok(expr)
5094    }
5095
5096    fn parse_set_operator(&mut self, token: &Token) -> Option<SetOperator> {
5097        match token {
5098            Token::Word(w) if w.keyword == Keyword::UNION => Some(SetOperator::Union),
5099            Token::Word(w) if w.keyword == Keyword::EXCEPT => Some(SetOperator::Except),
5100            Token::Word(w) if w.keyword == Keyword::INTERSECT => Some(SetOperator::Intersect),
5101            _ => None,
5102        }
5103    }
5104
5105    fn parse_corresponding(&mut self) -> ModalResult<Corresponding> {
5106        let corresponding = if self.parse_keyword(Keyword::CORRESPONDING) {
5107            let column_list = if self.parse_keyword(Keyword::BY) {
5108                Some(self.parse_parenthesized_column_list(IsOptional::Mandatory)?)
5109            } else {
5110                None
5111            };
5112            Corresponding::with_column_list(column_list)
5113        } else {
5114            Corresponding::none()
5115        };
5116        Ok(corresponding)
5117    }
5118
5119    /// Parse a restricted `SELECT` statement (no CTEs / `UNION` / `ORDER BY`),
5120    /// assuming the initial `SELECT` was already consumed
5121    pub fn parse_select(&mut self) -> ModalResult<Select> {
5122        let distinct = self.parse_all_or_distinct_on()?;
5123
5124        let projection = self.parse_comma_separated(Parser::parse_select_item)?;
5125
5126        // Note that for keywords to be properly handled here, they need to be
5127        // added to `RESERVED_FOR_COLUMN_ALIAS` / `RESERVED_FOR_TABLE_ALIAS`,
5128        // otherwise they may be parsed as an alias as part of the `projection`
5129        // or `from`.
5130
5131        let from = if self.parse_keyword(Keyword::FROM) {
5132            self.parse_comma_separated(Parser::parse_table_and_joins)?
5133        } else {
5134            vec![]
5135        };
5136        let mut lateral_views = vec![];
5137        loop {
5138            if self.parse_keywords(&[Keyword::LATERAL, Keyword::VIEW]) {
5139                let outer = self.parse_keyword(Keyword::OUTER);
5140                let lateral_view = self.parse_expr()?;
5141                let lateral_view_name = self.parse_object_name()?;
5142                let lateral_col_alias = self
5143                    .parse_comma_separated(|parser| {
5144                        parser.parse_optional_alias(&[
5145                            Keyword::WHERE,
5146                            Keyword::GROUP,
5147                            Keyword::CLUSTER,
5148                            Keyword::HAVING,
5149                            Keyword::LATERAL,
5150                        ]) // This couldn't possibly be a bad idea
5151                    })?
5152                    .into_iter()
5153                    .flatten()
5154                    .collect();
5155
5156                lateral_views.push(LateralView {
5157                    lateral_view,
5158                    lateral_view_name,
5159                    lateral_col_alias,
5160                    outer,
5161                });
5162            } else {
5163                break;
5164            }
5165        }
5166
5167        let selection = if self.parse_keyword(Keyword::WHERE) {
5168            Some(self.parse_expr()?)
5169        } else {
5170            None
5171        };
5172
5173        let group_by = if self.parse_keywords(&[Keyword::GROUP, Keyword::BY]) {
5174            self.parse_comma_separated(Parser::parse_group_by_expr)?
5175        } else {
5176            vec![]
5177        };
5178
5179        let having = if self.parse_keyword(Keyword::HAVING) {
5180            Some(self.parse_expr()?)
5181        } else {
5182            None
5183        };
5184
5185        let window = if self.parse_keyword(Keyword::WINDOW) {
5186            self.parse_comma_separated(Parser::parse_named_window)?
5187        } else {
5188            vec![]
5189        };
5190
5191        Ok(Select {
5192            distinct,
5193            projection,
5194            from,
5195            lateral_views,
5196            selection,
5197            group_by,
5198            having,
5199            window,
5200        })
5201    }
5202
5203    pub fn parse_set(&mut self) -> ModalResult<Statement> {
5204        let modifier = self.parse_one_of_keywords(&[Keyword::SESSION, Keyword::LOCAL]);
5205        if self.parse_keywords(&[Keyword::TIME, Keyword::ZONE]) {
5206            let value = alt((
5207                Keyword::DEFAULT.value(SetTimeZoneValue::Default),
5208                Keyword::LOCAL.value(SetTimeZoneValue::Local),
5209                preceded(
5210                    Keyword::INTERVAL,
5211                    cut_err(Self::parse_literal_interval.try_map(|e| match e {
5212                        // support a special case for clients which would send when initializing the connection
5213                        // like: SET TIME ZONE INTERVAL '+00:00' HOUR TO MINUTE;
5214                        Expr::Value(v) => match v {
5215                            Value::Interval { value, .. } => {
5216                                if value != "+00:00" {
5217                                    return Err(StrError("only support \"+00:00\" ".into()));
5218                                }
5219                                Ok(SetTimeZoneValue::Ident(Ident::with_quote_unchecked(
5220                                    '\'',
5221                                    "UTC".to_owned(),
5222                                )))
5223                            }
5224                            _ => Err(StrError("expect Value::Interval".into())),
5225                        },
5226                        _ => Err(StrError("expect Expr::Value".into())),
5227                    })),
5228                ),
5229                Self::parse_identifier.map(SetTimeZoneValue::Ident),
5230                Self::ensure_parse_value.map(SetTimeZoneValue::Literal),
5231            ))
5232            .expect("variable")
5233            .parse_next(self)?;
5234
5235            Ok(Statement::SetTimeZone {
5236                local: modifier == Some(Keyword::LOCAL),
5237                value,
5238            })
5239        } else if self.parse_keyword(Keyword::CHARACTERISTICS) && modifier == Some(Keyword::SESSION)
5240        {
5241            self.expect_keywords(&[Keyword::AS, Keyword::TRANSACTION])?;
5242            Ok(Statement::SetTransaction {
5243                modes: self.parse_transaction_modes()?,
5244                snapshot: None,
5245                session: true,
5246            })
5247        } else if self.parse_keyword(Keyword::TRANSACTION) && modifier.is_none() {
5248            if self.parse_keyword(Keyword::SNAPSHOT) {
5249                let snapshot_id = self.ensure_parse_value()?;
5250                return Ok(Statement::SetTransaction {
5251                    modes: vec![],
5252                    snapshot: Some(snapshot_id),
5253                    session: false,
5254                });
5255            }
5256            Ok(Statement::SetTransaction {
5257                modes: self.parse_transaction_modes()?,
5258                snapshot: None,
5259                session: false,
5260            })
5261        } else {
5262            let config_param = self.parse_config_param()?;
5263            Ok(Statement::SetVariable {
5264                local: modifier == Some(Keyword::LOCAL),
5265                variable: config_param.param,
5266                value: config_param.value,
5267            })
5268        }
5269    }
5270
5271    /// If have `databases`,`tables`,`columns`,`schemas` and `materialized views` after show,
5272    /// return `Statement::ShowCommand` or `Statement::ShowColumn`,
5273    /// otherwise, return `Statement::ShowVariable`.
5274    pub fn parse_show(&mut self) -> ModalResult<Statement> {
5275        let checkpoint = *self;
5276        if let Token::Word(w) = self.next_token().token {
5277            match w.keyword {
5278                Keyword::TABLES => {
5279                    return Ok(Statement::ShowObjects {
5280                        object: ShowObject::Table {
5281                            schema: self.parse_from_and_identifier()?,
5282                        },
5283                        filter: self.parse_show_statement_filter()?,
5284                    });
5285                }
5286                Keyword::INTERNAL => {
5287                    self.expect_keyword(Keyword::TABLES)?;
5288                    return Ok(Statement::ShowObjects {
5289                        object: ShowObject::InternalTable {
5290                            schema: self.parse_from_and_identifier()?,
5291                        },
5292                        filter: self.parse_show_statement_filter()?,
5293                    });
5294                }
5295                Keyword::SOURCES => {
5296                    return Ok(Statement::ShowObjects {
5297                        object: ShowObject::Source {
5298                            schema: self.parse_from_and_identifier()?,
5299                        },
5300                        filter: self.parse_show_statement_filter()?,
5301                    });
5302                }
5303                Keyword::SINKS => {
5304                    return Ok(Statement::ShowObjects {
5305                        object: ShowObject::Sink {
5306                            schema: self.parse_from_and_identifier()?,
5307                        },
5308                        filter: self.parse_show_statement_filter()?,
5309                    });
5310                }
5311                Keyword::SUBSCRIPTIONS => {
5312                    return Ok(Statement::ShowObjects {
5313                        object: ShowObject::Subscription {
5314                            schema: self.parse_from_and_identifier()?,
5315                        },
5316                        filter: self.parse_show_statement_filter()?,
5317                    });
5318                }
5319                Keyword::DATABASES => {
5320                    return Ok(Statement::ShowObjects {
5321                        object: ShowObject::Database,
5322                        filter: self.parse_show_statement_filter()?,
5323                    });
5324                }
5325                Keyword::SCHEMAS => {
5326                    return Ok(Statement::ShowObjects {
5327                        object: ShowObject::Schema,
5328                        filter: self.parse_show_statement_filter()?,
5329                    });
5330                }
5331                Keyword::VIEWS => {
5332                    return Ok(Statement::ShowObjects {
5333                        object: ShowObject::View {
5334                            schema: self.parse_from_and_identifier()?,
5335                        },
5336                        filter: self.parse_show_statement_filter()?,
5337                    });
5338                }
5339                Keyword::MATERIALIZED => {
5340                    if self.parse_keyword(Keyword::VIEWS) {
5341                        return Ok(Statement::ShowObjects {
5342                            object: ShowObject::MaterializedView {
5343                                schema: self.parse_from_and_identifier()?,
5344                            },
5345                            filter: self.parse_show_statement_filter()?,
5346                        });
5347                    } else {
5348                        return self.expected("VIEWS after MATERIALIZED");
5349                    }
5350                }
5351                Keyword::COLUMNS => {
5352                    if self.parse_keyword(Keyword::FROM) {
5353                        return Ok(Statement::ShowObjects {
5354                            object: ShowObject::Columns {
5355                                table: self.parse_object_name()?,
5356                            },
5357                            filter: self.parse_show_statement_filter()?,
5358                        });
5359                    } else {
5360                        return self.expected("from after columns");
5361                    }
5362                }
5363                Keyword::SECRETS => {
5364                    return Ok(Statement::ShowObjects {
5365                        object: ShowObject::Secret {
5366                            schema: self.parse_from_and_identifier()?,
5367                        },
5368                        filter: self.parse_show_statement_filter()?,
5369                    });
5370                }
5371                Keyword::CONNECTIONS => {
5372                    return Ok(Statement::ShowObjects {
5373                        object: ShowObject::Connection {
5374                            schema: self.parse_from_and_identifier()?,
5375                        },
5376                        filter: self.parse_show_statement_filter()?,
5377                    });
5378                }
5379                Keyword::FUNCTIONS => {
5380                    return Ok(Statement::ShowObjects {
5381                        object: ShowObject::Function {
5382                            schema: self.parse_from_and_identifier()?,
5383                        },
5384                        filter: self.parse_show_statement_filter()?,
5385                    });
5386                }
5387                Keyword::INDEXES => {
5388                    if self.parse_keyword(Keyword::FROM) {
5389                        return Ok(Statement::ShowObjects {
5390                            object: ShowObject::Indexes {
5391                                table: self.parse_object_name()?,
5392                            },
5393                            filter: self.parse_show_statement_filter()?,
5394                        });
5395                    } else {
5396                        return self.expected("from after indexes");
5397                    }
5398                }
5399                Keyword::CLUSTER => {
5400                    return Ok(Statement::ShowObjects {
5401                        object: ShowObject::Cluster,
5402                        filter: self.parse_show_statement_filter()?,
5403                    });
5404                }
5405                Keyword::JOBS => {
5406                    return Ok(Statement::ShowObjects {
5407                        object: ShowObject::Jobs,
5408                        filter: self.parse_show_statement_filter()?,
5409                    });
5410                }
5411                Keyword::PROCESSLIST => {
5412                    return Ok(Statement::ShowObjects {
5413                        object: ShowObject::ProcessList,
5414                        filter: self.parse_show_statement_filter()?,
5415                    });
5416                }
5417                Keyword::TRANSACTION => {
5418                    self.expect_keywords(&[Keyword::ISOLATION, Keyword::LEVEL])?;
5419                    return Ok(Statement::ShowTransactionIsolationLevel);
5420                }
5421                Keyword::CURSORS => {
5422                    return Ok(Statement::ShowObjects {
5423                        object: ShowObject::Cursor,
5424                        filter: None,
5425                    });
5426                }
5427                Keyword::SUBSCRIPTION => {
5428                    self.expect_keyword(Keyword::CURSORS)?;
5429                    return Ok(Statement::ShowObjects {
5430                        object: ShowObject::SubscriptionCursor,
5431                        filter: None,
5432                    });
5433                }
5434                _ => {}
5435            }
5436        }
5437        *self = checkpoint;
5438        Ok(Statement::ShowVariable {
5439            variable: self.parse_identifiers()?,
5440        })
5441    }
5442
5443    pub fn parse_cancel_job(&mut self) -> ModalResult<Statement> {
5444        // CANCEL [JOBS|JOB] job_ids
5445        match self.peek_token().token {
5446            Token::Word(w) if Keyword::JOBS == w.keyword || Keyword::JOB == w.keyword => {
5447                self.next_token();
5448            }
5449            _ => return self.expected("JOBS or JOB after CANCEL"),
5450        }
5451
5452        let mut job_ids = vec![];
5453        loop {
5454            job_ids.push(self.parse_literal_u32()?);
5455            if !self.consume_token(&Token::Comma) {
5456                break;
5457            }
5458        }
5459        Ok(Statement::CancelJobs(JobIdents(job_ids)))
5460    }
5461
5462    pub fn parse_kill_process(&mut self) -> ModalResult<Statement> {
5463        let worker_process_id = self.parse_literal_string()?;
5464        Ok(Statement::Kill(worker_process_id))
5465    }
5466
5467    /// Parser `from schema` after `show tables` and `show materialized views`, if not conclude
5468    /// `from` then use default schema name.
5469    pub fn parse_from_and_identifier(&mut self) -> ModalResult<Option<Ident>> {
5470        if self.parse_keyword(Keyword::FROM) {
5471            Ok(Some(self.parse_identifier_non_reserved()?))
5472        } else {
5473            Ok(None)
5474        }
5475    }
5476
5477    /// Parse object type and name after `show create`.
5478    pub fn parse_show_create(&mut self) -> ModalResult<Statement> {
5479        if let Token::Word(w) = self.next_token().token {
5480            let show_type = match w.keyword {
5481                Keyword::TABLE => ShowCreateType::Table,
5482                Keyword::MATERIALIZED => {
5483                    if self.parse_keyword(Keyword::VIEW) {
5484                        ShowCreateType::MaterializedView
5485                    } else {
5486                        return self.expected("VIEW after MATERIALIZED");
5487                    }
5488                }
5489                Keyword::VIEW => ShowCreateType::View,
5490                Keyword::INDEX => ShowCreateType::Index,
5491                Keyword::SOURCE => ShowCreateType::Source,
5492                Keyword::SINK => ShowCreateType::Sink,
5493                Keyword::SUBSCRIPTION => ShowCreateType::Subscription,
5494                Keyword::FUNCTION => ShowCreateType::Function,
5495                _ => return self.expected(
5496                    "TABLE, MATERIALIZED VIEW, VIEW, INDEX, FUNCTION, SOURCE, SUBSCRIPTION or SINK",
5497                ),
5498            };
5499            return Ok(Statement::ShowCreateObject {
5500                create_type: show_type,
5501                name: self.parse_object_name()?,
5502            });
5503        }
5504        self.expected(
5505            "TABLE, MATERIALIZED VIEW, VIEW, INDEX, FUNCTION, SOURCE, SUBSCRIPTION or SINK",
5506        )
5507    }
5508
5509    pub fn parse_show_statement_filter(&mut self) -> ModalResult<Option<ShowStatementFilter>> {
5510        if self.parse_keyword(Keyword::LIKE) {
5511            Ok(Some(ShowStatementFilter::Like(
5512                self.parse_literal_string()?,
5513            )))
5514        } else if self.parse_keyword(Keyword::ILIKE) {
5515            Ok(Some(ShowStatementFilter::ILike(
5516                self.parse_literal_string()?,
5517            )))
5518        } else if self.parse_keyword(Keyword::WHERE) {
5519            Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
5520        } else {
5521            Ok(None)
5522        }
5523    }
5524
5525    pub fn parse_table_and_joins(&mut self) -> ModalResult<TableWithJoins> {
5526        let relation = self.parse_table_factor()?;
5527
5528        // Note that for keywords to be properly handled here, they need to be
5529        // added to `RESERVED_FOR_TABLE_ALIAS`, otherwise they may be parsed as
5530        // a table alias.
5531        let mut joins = vec![];
5532        loop {
5533            let join_checkpoint = *self;
5534            let join = if self.parse_keyword(Keyword::CROSS) {
5535                let join_operator = if self.parse_keyword(Keyword::JOIN) {
5536                    JoinOperator::CrossJoin
5537                } else {
5538                    return self.expected("JOIN after CROSS");
5539                };
5540                Join {
5541                    relation: self.parse_table_factor()?,
5542                    join_operator,
5543                }
5544            } else {
5545                let broadcast = self.peek_broadcast_join();
5546                if broadcast {
5547                    let _ = self.next_token();
5548                }
5549                let (natural, asof) =
5550                    match self.parse_one_of_keywords(&[Keyword::NATURAL, Keyword::ASOF]) {
5551                        Some(Keyword::NATURAL) => (true, false),
5552                        Some(Keyword::ASOF) => (false, true),
5553                        Some(_) => unreachable!(),
5554                        None => (false, false),
5555                    };
5556                let peek_keyword = if let Token::Word(w) = self.peek_token().token {
5557                    w.keyword
5558                } else {
5559                    Keyword::NoKeyword
5560                };
5561
5562                let join_operator_type = match peek_keyword {
5563                    Keyword::INNER | Keyword::JOIN => {
5564                        let _ = self.parse_keyword(Keyword::INNER);
5565                        self.expect_keyword(Keyword::JOIN)?;
5566                        if asof {
5567                            JoinOperator::AsOfInner
5568                        } else {
5569                            JoinOperator::Inner
5570                        }
5571                    }
5572                    kw @ Keyword::LEFT | kw @ Keyword::RIGHT | kw @ Keyword::FULL => {
5573                        let checkpoint = *self;
5574                        let _ = self.next_token();
5575                        let _ = self.parse_keyword(Keyword::OUTER);
5576                        self.expect_keyword(Keyword::JOIN)?;
5577                        if asof {
5578                            if Keyword::LEFT == kw {
5579                                JoinOperator::AsOfLeft
5580                            } else {
5581                                return self.expected_at(
5582                                    checkpoint,
5583                                    "LEFT after ASOF. RIGHT or FULL are not supported",
5584                                );
5585                            }
5586                        } else {
5587                            match kw {
5588                                Keyword::LEFT => JoinOperator::LeftOuter,
5589                                Keyword::RIGHT => JoinOperator::RightOuter,
5590                                Keyword::FULL => JoinOperator::FullOuter,
5591                                _ => unreachable!(),
5592                            }
5593                        }
5594                    }
5595                    Keyword::OUTER => {
5596                        return self.expected("LEFT, RIGHT, or FULL");
5597                    }
5598                    _ if natural => {
5599                        return self.expected("a join type after NATURAL");
5600                    }
5601                    _ if asof => {
5602                        return self.expected("a join type after ASOF");
5603                    }
5604                    _ if broadcast => {
5605                        return self.expected_at(join_checkpoint, "a join type after BROADCAST");
5606                    }
5607                    _ => break,
5608                };
5609                let mut relation = self.parse_table_factor()?;
5610                let join_constraint = self.parse_join_constraint(natural)?;
5611                let join_operator = join_operator_type(join_constraint);
5612                if broadcast {
5613                    if !matches!(
5614                        join_operator,
5615                        JoinOperator::Inner(_) | JoinOperator::LeftOuter(_)
5616                    ) {
5617                        return self.expected_at(
5618                            join_checkpoint,
5619                            "INNER or LEFT temporal join after BROADCAST",
5620                        );
5621                    }
5622                    match &mut relation {
5623                        TableFactor::Table {
5624                            as_of: Some(as_of), ..
5625                        } if matches!(as_of, AsOf::ProcessTime) => {
5626                            *as_of = AsOf::ProcessTimeBroadcast;
5627                        }
5628                        _ => {
5629                            return self.expected_at(
5630                                join_checkpoint,
5631                                "a table with FOR SYSTEM_TIME AS OF PROCTIME() after BROADCAST JOIN",
5632                            );
5633                        }
5634                    }
5635                }
5636                let need_constraint = match join_operator {
5637                    JoinOperator::Inner(JoinConstraint::None) => Some("INNER JOIN"),
5638                    JoinOperator::AsOfInner(JoinConstraint::None) => Some("ASOF INNER JOIN"),
5639                    JoinOperator::AsOfLeft(JoinConstraint::None) => Some("ASOF LEFT JOIN"),
5640                    _ => None,
5641                };
5642                if let Some(join_type) = need_constraint {
5643                    return self.expected(&format!("join constraint after {join_type}"));
5644                }
5645
5646                Join {
5647                    relation,
5648                    join_operator,
5649                }
5650            };
5651            joins.push(join);
5652        }
5653        Ok(TableWithJoins { relation, joins })
5654    }
5655
5656    /// Whether the next tokens start a supported broadcast join.
5657    ///
5658    /// `BROADCAST` remains a regular identifier outside this exact position so that existing
5659    /// table aliases and identifier formatting remain compatible.
5660    fn peek_broadcast_join(&self) -> bool {
5661        matches!(
5662            self.peek_nth_token(0).token,
5663            Token::Word(word)
5664                if word.quote_style.is_none() && word.value.eq_ignore_ascii_case("BROADCAST")
5665        ) && matches!(
5666            self.peek_nth_token(1).token,
5667            Token::Word(word)
5668                if matches!(word.keyword, Keyword::INNER | Keyword::JOIN | Keyword::LEFT)
5669        )
5670    }
5671
5672    /// A table name or a parenthesized subquery, followed by optional `[AS] alias`
5673    pub fn parse_table_factor(&mut self) -> ModalResult<TableFactor> {
5674        let relation = self.parse_table_factor_inner()?;
5675        // Contextual, not a keyword: only `MATCH_RECOGNIZE (` opens the clause (the alias parser
5676        // above declines exactly that shape), so a bare `match_recognize` elsewhere remains an
5677        // ordinary identifier.
5678        let checkpoint = *self;
5679        if self.parse_word("MATCH_RECOGNIZE") {
5680            if self.peek_token() == Token::LParen {
5681                return self.parse_match_recognize(relation);
5682            }
5683            *self = checkpoint;
5684        }
5685        Ok(relation)
5686    }
5687
5688    fn parse_table_factor_inner(&mut self) -> ModalResult<TableFactor> {
5689        if self.parse_keyword(Keyword::LATERAL) {
5690            // LATERAL must always be followed by a subquery.
5691            if !self.consume_token(&Token::LParen) {
5692                self.expected("subquery after LATERAL")?;
5693            }
5694            self.parse_derived_table_factor(Lateral)
5695        } else if self.consume_token(&Token::LParen) {
5696            // A left paren introduces either a derived table (i.e., a subquery)
5697            // or a nested join. It's nearly impossible to determine ahead of
5698            // time which it is... so we just try to parse both.
5699            //
5700            // Here's an example that demonstrates the complexity:
5701            //                     /-------------------------------------------------------\
5702            //                     | /-----------------------------------\                 |
5703            //     SELECT * FROM ( ( ( (SELECT 1) UNION (SELECT 2) ) AS t1 NATURAL JOIN t2 ) )
5704            //                   ^ ^ ^ ^
5705            //                   | | | |
5706            //                   | | | |
5707            //                   | | | (4) belongs to a SetExpr::Query inside the subquery
5708            //                   | | (3) starts a derived table (subquery)
5709            //                   | (2) starts a nested join
5710            //                   (1) an additional set of parens around a nested join
5711            //
5712
5713            // It can only be a subquery. We don't use `maybe_parse` so that a meaningful error can
5714            // be returned.
5715            match self.peek_token().token {
5716                Token::Word(w)
5717                    if [Keyword::SELECT, Keyword::WITH, Keyword::VALUES].contains(&w.keyword) =>
5718                {
5719                    return self.parse_derived_table_factor(NotLateral);
5720                }
5721                _ => {}
5722            };
5723            // It can still be a subquery, e.g., the case (3) in the example above:
5724            // (SELECT 1) UNION (SELECT 2)
5725            // TODO: how to produce a good error message here?
5726            if self.peek_token() == Token::LParen {
5727                return_ok_if_some!(
5728                    self.maybe_parse(|parser| parser.parse_derived_table_factor(NotLateral))
5729                );
5730            }
5731
5732            // A parsing error from `parse_derived_table_factor` indicates that the '(' we've
5733            // recently consumed does not start a derived table (cases 1, 2, or 4).
5734            // `maybe_parse` will ignore such an error and rewind to be after the opening '('.
5735
5736            // Inside the parentheses we expect to find an (A) table factor
5737            // followed by some joins or (B) another level of nesting.
5738            let table_and_joins = self.parse_table_and_joins()?;
5739
5740            if !table_and_joins.joins.is_empty() {
5741                self.expect_token(&Token::RParen)?;
5742                Ok(TableFactor::NestedJoin(Box::new(table_and_joins))) // (A)
5743            } else if let TableFactor::NestedJoin(_) = &table_and_joins.relation {
5744                // (B): `table_and_joins` (what we found inside the parentheses)
5745                // is a nested join `(foo JOIN bar)`, not followed by other joins.
5746                self.expect_token(&Token::RParen)?;
5747                Ok(TableFactor::NestedJoin(Box::new(table_and_joins)))
5748            } else {
5749                // The SQL spec prohibits derived tables and bare tables from
5750                // appearing alone in parentheses (e.g. `FROM (mytable)`)
5751                parser_err!(
5752                    "Expected joined table, found: {table_and_joins}, next_token: {}",
5753                    self.peek_token()
5754                );
5755            }
5756        } else {
5757            let name = self.parse_object_name()?;
5758            if self.peek_token() == Token::LParen {
5759                // table-valued function
5760
5761                let arg_list = self.parse_argument_list()?;
5762                if arg_list.distinct {
5763                    parser_err!("DISTINCT is not supported in table-valued function calls");
5764                }
5765                if !arg_list.order_by.is_empty() {
5766                    parser_err!("ORDER BY is not supported in table-valued function calls");
5767                }
5768                if arg_list.ignore_nulls {
5769                    parser_err!("IGNORE NULLS is not supported in table-valued function calls");
5770                }
5771
5772                let args = arg_list.args;
5773                let with_ordinality = self.parse_keywords(&[Keyword::WITH, Keyword::ORDINALITY]);
5774                let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5775
5776                Ok(TableFactor::TableFunction {
5777                    name,
5778                    alias,
5779                    args,
5780                    with_ordinality,
5781                })
5782            } else {
5783                let as_of = opt(Self::parse_as_of).parse_next(self)?;
5784                let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5785                Ok(TableFactor::Table { name, alias, as_of })
5786            }
5787        }
5788    }
5789
5790    pub fn parse_derived_table_factor(&mut self, lateral: IsLateral) -> ModalResult<TableFactor> {
5791        let subquery = Box::new(self.parse_query()?);
5792        self.expect_token(&Token::RParen)?;
5793        let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5794        Ok(TableFactor::Derived {
5795            lateral: match lateral {
5796                Lateral => true,
5797                NotLateral => false,
5798            },
5799            subquery,
5800            alias,
5801        })
5802    }
5803
5804    /// Parse the body of a `MATCH_RECOGNIZE (...)` clause applied to the already-parsed
5805    /// input `table`. Assumes the `MATCH_RECOGNIZE` keyword has just been consumed.
5806    ///
5807    /// Supported in this version: `PARTITION BY`, `ORDER BY`, `MEASURES`, rows-per-match,
5808    /// `AFTER MATCH SKIP`, `PATTERN` (named symbols, grouping, concatenation, alternation,
5809    /// `PERMUTE`, and the quantifiers `*` `+` `?` `{n}` `{n,}` `{,m}` `{n,m}`), and `DEFINE`.
5810    /// Row-pattern anchors (`^`, `$`) and exclusions (`{- -}`) are not yet parsed.
5811    fn parse_match_recognize(&mut self, table: TableFactor) -> ModalResult<TableFactor> {
5812        self.expect_token(&Token::LParen)?;
5813
5814        let partition_by = if self.parse_keywords(&[Keyword::PARTITION, Keyword::BY]) {
5815            self.parse_comma_separated(Parser::parse_expr)?
5816        } else {
5817            vec![]
5818        };
5819
5820        let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
5821            self.parse_comma_separated(Parser::parse_match_recognize_order_by_expr)?
5822        } else {
5823            vec![]
5824        };
5825
5826        let measures = if self.parse_word("MEASURES") {
5827            self.parse_comma_separated(Parser::parse_measure)?
5828        } else {
5829            vec![]
5830        };
5831
5832        let rows_per_match = if self.parse_words(&["ONE", "ROW", "PER", "MATCH"]) {
5833            Some(RowsPerMatch::OneRow)
5834        } else if self.parse_words(&["ALL", "ROWS", "PER", "MATCH"]) {
5835            Some(RowsPerMatch::AllRows)
5836        } else {
5837            None
5838        };
5839
5840        let after_match_skip = if self.parse_words(&["AFTER", "MATCH", "SKIP"]) {
5841            Some(self.parse_after_match_skip()?)
5842        } else {
5843            None
5844        };
5845
5846        self.expect_word("PATTERN")?;
5847        self.expect_token(&Token::LParen)?;
5848        let pattern = self.parse_pattern()?;
5849        self.expect_token(&Token::RParen)?;
5850
5851        // `WITHIN <interval>` bounds the time span of a match (streaming extension).
5852        let within = if self.parse_keyword(Keyword::WITHIN) {
5853            Some(self.parse_expr()?)
5854        } else {
5855            None
5856        };
5857
5858        let subsets = if self.parse_word("SUBSET") {
5859            self.parse_comma_separated(Parser::parse_subset_definition)?
5860        } else {
5861            vec![]
5862        };
5863
5864        self.expect_word("DEFINE")?;
5865        let symbols = self.parse_comma_separated(Parser::parse_symbol_definition)?;
5866
5867        self.expect_token(&Token::RParen)?;
5868
5869        let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5870
5871        Ok(TableFactor::MatchRecognize {
5872            table: Box::new(table),
5873            partition_by,
5874            order_by,
5875            measures,
5876            rows_per_match,
5877            after_match_skip,
5878            pattern,
5879            within,
5880            subsets,
5881            symbols,
5882            alias,
5883        })
5884    }
5885
5886    /// Parse a `SUBSET` item: `<name> = ( <var>, ... )`.
5887    fn parse_subset_definition(&mut self) -> ModalResult<SubsetDefinition> {
5888        let name = self.parse_identifier()?;
5889        self.expect_token(&Token::Eq)?;
5890        self.expect_token(&Token::LParen)?;
5891        let members = self.parse_comma_separated(Parser::parse_identifier)?;
5892        self.expect_token(&Token::RParen)?;
5893        Ok(SubsetDefinition { name, members })
5894    }
5895
5896    fn parse_after_match_skip(&mut self) -> ModalResult<AfterMatchSkip> {
5897        if self.parse_words(&["PAST", "LAST", "ROW"]) {
5898            Ok(AfterMatchSkip::PastLastRow)
5899        } else if self.parse_keywords(&[Keyword::TO, Keyword::NEXT, Keyword::ROW]) {
5900            Ok(AfterMatchSkip::ToNextRow)
5901        } else if self.parse_keywords(&[Keyword::TO, Keyword::FIRST]) {
5902            Ok(AfterMatchSkip::ToFirst(self.parse_identifier()?))
5903        } else if self.parse_keywords(&[Keyword::TO, Keyword::LAST]) {
5904            Ok(AfterMatchSkip::ToLast(self.parse_identifier()?))
5905        } else {
5906            self.expected(
5907                "PAST LAST ROW, TO NEXT ROW, TO FIRST <symbol>, or TO LAST <symbol> after AFTER MATCH SKIP",
5908            )
5909        }
5910    }
5911
5912    /// Parse an `ORDER BY` item inside `MATCH_RECOGNIZE`. The sort key is parsed with a
5913    /// `Precedence::Other` floor so a trailing `ALL` (as in `ALL ROWS PER MATCH`) is not
5914    /// swallowed by the `<expr> ALL (...)` quantified-comparison grammar. Arithmetic still
5915    /// binds; a comparison/logical sort key must be parenthesized.
5916    fn parse_match_recognize_order_by_expr(&mut self) -> ModalResult<OrderByExpr> {
5917        let expr = self.parse_subexpr(Precedence::Other)?;
5918
5919        let asc = if self.parse_keyword(Keyword::ASC) {
5920            Some(true)
5921        } else if self.parse_keyword(Keyword::DESC) {
5922            Some(false)
5923        } else {
5924            None
5925        };
5926
5927        let nulls_first = if self.parse_keywords(&[Keyword::NULLS, Keyword::FIRST]) {
5928            Some(true)
5929        } else if self.parse_keywords(&[Keyword::NULLS, Keyword::LAST]) {
5930            Some(false)
5931        } else {
5932            None
5933        };
5934
5935        Ok(OrderByExpr {
5936            expr,
5937            asc,
5938            nulls_first,
5939        })
5940    }
5941
5942    fn parse_measure(&mut self) -> ModalResult<Measure> {
5943        let expr = self.parse_expr()?;
5944        self.expect_keyword(Keyword::AS)?;
5945        let alias = self.parse_identifier()?;
5946        Ok(Measure { expr, alias })
5947    }
5948
5949    fn parse_symbol_definition(&mut self) -> ModalResult<SymbolDefinition> {
5950        let symbol = self.parse_identifier()?;
5951        self.expect_keyword(Keyword::AS)?;
5952        let definition = self.parse_expr()?;
5953        Ok(SymbolDefinition { symbol, definition })
5954    }
5955
5956    /// A row pattern: alternation of concatenations (alternation has the lowest precedence).
5957    fn parse_pattern(&mut self) -> ModalResult<MatchRecognizePattern> {
5958        // The tokenizer greedily fuses adjacent operator characters, so `a+|b` arrives as
5959        // `Op("+|")`: a quantifier carrying the alternation pipe in the same token. The quantifier
5960        // parser strips and reports that trailing pipe (it cannot be pushed back), and this loop
5961        // treats it exactly like a free-standing one.
5962        let (first, mut fused_pipe) = self.parse_pattern_concat()?;
5963        let mut alternatives = vec![first];
5964        while fused_pipe || self.consume_pattern_pipe() {
5965            let (next, fp) = self.parse_pattern_concat()?;
5966            alternatives.push(next);
5967            fused_pipe = fp;
5968        }
5969        if alternatives.len() == 1 {
5970            Ok(alternatives.pop().unwrap())
5971        } else {
5972            Ok(MatchRecognizePattern::Alternation(alternatives))
5973        }
5974    }
5975
5976    /// A concatenation of quantified primaries, terminated by `)`, `|` (possibly fused into the
5977    /// preceding quantifier's token), or end of input. The bool reports that fused pipe.
5978    fn parse_pattern_concat(&mut self) -> ModalResult<(MatchRecognizePattern, bool)> {
5979        let (first, mut fused_pipe) = self.parse_pattern_repetition()?;
5980        let mut terms = vec![first];
5981        while !fused_pipe
5982            && !matches!(self.peek_token().token, Token::RParen | Token::EOF)
5983            && !self.peek_is_pattern_pipe()
5984        {
5985            let (next, fp) = self.parse_pattern_repetition()?;
5986            terms.push(next);
5987            fused_pipe = fp;
5988        }
5989        let pattern = if terms.len() == 1 {
5990            terms.pop().unwrap()
5991        } else {
5992            MatchRecognizePattern::Concat(terms)
5993        };
5994        Ok((pattern, fused_pipe))
5995    }
5996
5997    /// A pattern primary with an optional trailing quantifier. The bool reports an alternation
5998    /// pipe fused into the quantifier's own token (`a+|b`), which the caller must honour.
5999    fn parse_pattern_repetition(&mut self) -> ModalResult<(MatchRecognizePattern, bool)> {
6000        let primary = self.parse_pattern_primary()?;
6001        if let Some((quantifier, reluctant, fused_pipe)) =
6002            self.parse_optional_pattern_quantifier()?
6003        {
6004            Ok((
6005                MatchRecognizePattern::Repetition(Box::new(primary), quantifier, reluctant),
6006                fused_pipe,
6007            ))
6008        } else {
6009            Ok((primary, false))
6010        }
6011    }
6012
6013    /// Consume a trailing reluctant marker `?`. The alternation pipe may be fused into the same
6014    /// operator token (`{2}?|b` tokenizes the `?|` as one `Op`), so the second bool reports a
6015    /// consumed pipe for the caller to honour.
6016    fn consume_pattern_reluctant_mark(&mut self) -> (bool, bool) {
6017        match &self.peek_token().token {
6018            Token::Op(op) if op == "?" => {
6019                self.next_token();
6020                (true, false)
6021            }
6022            Token::Op(op) if op == "?|" => {
6023                self.next_token();
6024                (true, true)
6025            }
6026            _ => (false, false),
6027        }
6028    }
6029
6030    /// A pattern primary: a parenthesized sub-pattern, `PERMUTE(...)`, or a named symbol.
6031    fn parse_pattern_primary(&mut self) -> ModalResult<MatchRecognizePattern> {
6032        if self.consume_token(&Token::LParen) {
6033            let inner = self.parse_pattern()?;
6034            self.expect_token(&Token::RParen)?;
6035            Ok(MatchRecognizePattern::Group(Box::new(inner)))
6036        } else if self.parse_word("PERMUTE") {
6037            self.expect_token(&Token::LParen)?;
6038            let symbols = self.parse_comma_separated(Parser::parse_pattern_symbol)?;
6039            self.expect_token(&Token::RParen)?;
6040            Ok(MatchRecognizePattern::Permute(symbols))
6041        } else {
6042            Ok(MatchRecognizePattern::Symbol(self.parse_pattern_symbol()?))
6043        }
6044    }
6045
6046    fn parse_pattern_symbol(&mut self) -> ModalResult<MatchRecognizeSymbol> {
6047        Ok(MatchRecognizeSymbol::Named(self.parse_identifier()?))
6048    }
6049
6050    /// Parse an optional pattern quantifier: `*`, `+`, `?`, or a `{...}` range.
6051    /// Returns `(quantifier, reluctant, fused_pipe)` — the last reporting an alternation `|` the
6052    /// tokenizer fused into the quantifier's own operator token, which the caller must honour.
6053    fn parse_optional_pattern_quantifier(
6054        &mut self,
6055    ) -> ModalResult<Option<(RepetitionQuantifier, bool, bool)>> {
6056        if self.consume_token(&Token::LBrace) {
6057            // The quantifier bounds are `u32` in the AST, so parse them as `u32`: a `u64` parse plus
6058            // an `as u32` cast would silently wrap (`{4294967296}` to `{0}`, a pattern that matches
6059            // nothing) instead of reporting the out-of-range bound.
6060            let lower = if matches!(self.peek_token().token, Token::Comma) {
6061                None
6062            } else {
6063                Some(self.parse_literal_u32()?)
6064            };
6065            let quantifier = if self.consume_token(&Token::Comma) {
6066                let upper = if matches!(self.peek_token().token, Token::RBrace) {
6067                    None
6068                } else {
6069                    Some(self.parse_literal_u32()?)
6070                };
6071                match (lower, upper) {
6072                    (Some(n), None) => RepetitionQuantifier::AtLeast(n),
6073                    (None, Some(m)) => RepetitionQuantifier::AtMost(m),
6074                    (Some(n), Some(m)) => RepetitionQuantifier::Range(n, m),
6075                    (None, None) => {
6076                        return self.expected("at least one bound in a {min,max} quantifier");
6077                    }
6078                }
6079            } else {
6080                match lower {
6081                    Some(n) => RepetitionQuantifier::Exactly(n),
6082                    None => return self.expected("a number in a {n} quantifier"),
6083                }
6084            };
6085            self.expect_token(&Token::RBrace)?;
6086            let (reluctant, fused_pipe) = self.consume_pattern_reluctant_mark();
6087            return Ok(Some((quantifier, reluctant, fused_pipe)));
6088        }
6089        // `*`, `+`, `?` may arrive as dedicated tokens or as `Token::Op(_)` depending on surrounding
6090        // operator characters, so accept both spellings. A trailing `?` makes the quantifier
6091        // reluctant, and both the `?` and an alternation `|` may be fused into the operator token —
6092        // `a+?|b` arrives with `Op("+?|")` carrying the quantifier, the reluctant marker AND the
6093        // pipe. The pipe cannot be pushed back, so it is reported to the caller instead.
6094        let (quantifier, fused_reluctant, fused_pipe) = match &self.peek_token().token {
6095            Token::Mul => (RepetitionQuantifier::ZeroOrMore, false, false),
6096            Token::Plus => (RepetitionQuantifier::OneOrMore, false, false),
6097            Token::Op(op) if op == "*" => (RepetitionQuantifier::ZeroOrMore, false, false),
6098            Token::Op(op) if op == "+" => (RepetitionQuantifier::OneOrMore, false, false),
6099            Token::Op(op) if op == "?" => (RepetitionQuantifier::AtMostOne, false, false),
6100            Token::Op(op) if op == "*?" => (RepetitionQuantifier::ZeroOrMore, true, false),
6101            Token::Op(op) if op == "+?" => (RepetitionQuantifier::OneOrMore, true, false),
6102            Token::Op(op) if op == "??" => (RepetitionQuantifier::AtMostOne, true, false),
6103            Token::Op(op) if op == "*|" => (RepetitionQuantifier::ZeroOrMore, false, true),
6104            Token::Op(op) if op == "+|" => (RepetitionQuantifier::OneOrMore, false, true),
6105            Token::Op(op) if op == "?|" => (RepetitionQuantifier::AtMostOne, false, true),
6106            Token::Op(op) if op == "*?|" => (RepetitionQuantifier::ZeroOrMore, true, true),
6107            Token::Op(op) if op == "+?|" => (RepetitionQuantifier::OneOrMore, true, true),
6108            Token::Op(op) if op == "??|" => (RepetitionQuantifier::AtMostOne, true, true),
6109            _ => return Ok(None),
6110        };
6111        self.next_token();
6112        let (reluctant, fused_pipe) = if fused_pipe {
6113            // The pipe was the token's last character; nothing can follow it in the same token.
6114            (fused_reluctant, true)
6115        } else {
6116            let (marker, pipe) = if fused_reluctant {
6117                (false, false)
6118            } else {
6119                self.consume_pattern_reluctant_mark()
6120            };
6121            (fused_reluctant || marker, pipe)
6122        };
6123        Ok(Some((quantifier, reluctant, fused_pipe)))
6124    }
6125
6126    fn peek_is_pattern_pipe(&mut self) -> bool {
6127        match &self.peek_token().token {
6128            Token::Pipe => true,
6129            Token::Op(op) if op == "|" => true,
6130            _ => false,
6131        }
6132    }
6133
6134    fn consume_pattern_pipe(&mut self) -> bool {
6135        if self.peek_is_pattern_pipe() {
6136            self.next_token();
6137            true
6138        } else {
6139            false
6140        }
6141    }
6142
6143    fn parse_join_constraint(&mut self, natural: bool) -> ModalResult<JoinConstraint> {
6144        if natural {
6145            Ok(JoinConstraint::Natural)
6146        } else if self.parse_keyword(Keyword::ON) {
6147            let constraint = self.parse_expr()?;
6148            Ok(JoinConstraint::On(constraint))
6149        } else if self.parse_keyword(Keyword::USING) {
6150            let columns = self.parse_parenthesized_column_list(Mandatory)?;
6151            Ok(JoinConstraint::Using(columns))
6152        } else {
6153            Ok(JoinConstraint::None)
6154            // self.expected("ON, or USING after JOIN")
6155        }
6156    }
6157
6158    /// Parse a GRANT statement.
6159    pub fn parse_grant(&mut self) -> ModalResult<Statement> {
6160        let (privileges, objects) = self.parse_grant_revoke_privileges_objects()?;
6161
6162        self.expect_keyword(Keyword::TO)?;
6163        let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6164
6165        let with_grant_option =
6166            self.parse_keywords(&[Keyword::WITH, Keyword::GRANT, Keyword::OPTION]);
6167
6168        let granted_by = self
6169            .parse_keywords(&[Keyword::GRANTED, Keyword::BY])
6170            .then(|| self.parse_identifier().unwrap());
6171
6172        Ok(Statement::Grant {
6173            privileges,
6174            objects,
6175            grantees,
6176            with_grant_option,
6177            granted_by,
6178        })
6179    }
6180
6181    fn parse_privileges(&mut self) -> ModalResult<Privileges> {
6182        let privileges = if self.parse_keyword(Keyword::ALL) {
6183            Privileges::All {
6184                with_privileges_keyword: self.parse_keyword(Keyword::PRIVILEGES),
6185            }
6186        } else {
6187            Privileges::Actions(
6188                self.parse_comma_separated(Parser::parse_grant_permission)?
6189                    .into_iter()
6190                    .map(|(kw, columns)| match kw {
6191                        Keyword::CONNECT => Action::Connect,
6192                        Keyword::CREATE => Action::Create,
6193                        Keyword::DELETE => Action::Delete,
6194                        Keyword::EXECUTE => Action::Execute,
6195                        Keyword::INSERT => Action::Insert { columns },
6196                        Keyword::REFERENCES => Action::References { columns },
6197                        Keyword::SELECT => Action::Select { columns },
6198                        Keyword::TEMPORARY => Action::Temporary,
6199                        Keyword::TRIGGER => Action::Trigger,
6200                        Keyword::TRUNCATE => Action::Truncate,
6201                        Keyword::UPDATE => Action::Update { columns },
6202                        Keyword::USAGE => Action::Usage,
6203                        _ => unreachable!(),
6204                    })
6205                    .collect(),
6206            )
6207        };
6208
6209        Ok(privileges)
6210    }
6211
6212    fn parse_grant_revoke_privileges_objects(&mut self) -> ModalResult<(Privileges, GrantObjects)> {
6213        let privileges = self.parse_privileges()?;
6214
6215        self.expect_keyword(Keyword::ON)?;
6216
6217        let objects = if self.parse_keywords(&[
6218            Keyword::ALL,
6219            Keyword::TABLES,
6220            Keyword::IN,
6221            Keyword::SCHEMA,
6222        ]) {
6223            GrantObjects::AllTablesInSchema {
6224                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6225            }
6226        } else if self.parse_keywords(&[
6227            Keyword::ALL,
6228            Keyword::SEQUENCES,
6229            Keyword::IN,
6230            Keyword::SCHEMA,
6231        ]) {
6232            GrantObjects::AllSequencesInSchema {
6233                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6234            }
6235        } else if self.parse_keywords(&[
6236            Keyword::ALL,
6237            Keyword::SOURCES,
6238            Keyword::IN,
6239            Keyword::SCHEMA,
6240        ]) {
6241            GrantObjects::AllSourcesInSchema {
6242                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6243            }
6244        } else if self.parse_keywords(&[Keyword::ALL, Keyword::SINKS, Keyword::IN, Keyword::SCHEMA])
6245        {
6246            GrantObjects::AllSinksInSchema {
6247                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6248            }
6249        } else if self.parse_keywords(&[
6250            Keyword::ALL,
6251            Keyword::MATERIALIZED,
6252            Keyword::VIEWS,
6253            Keyword::IN,
6254            Keyword::SCHEMA,
6255        ]) {
6256            GrantObjects::AllMviewsInSchema {
6257                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6258            }
6259        } else if self.parse_keywords(&[Keyword::ALL, Keyword::VIEWS, Keyword::IN, Keyword::SCHEMA])
6260        {
6261            GrantObjects::AllViewsInSchema {
6262                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6263            }
6264        } else if self.parse_keywords(&[
6265            Keyword::ALL,
6266            Keyword::FUNCTIONS,
6267            Keyword::IN,
6268            Keyword::SCHEMA,
6269        ]) {
6270            GrantObjects::AllFunctionsInSchema {
6271                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6272            }
6273        } else if self.parse_keywords(&[
6274            Keyword::ALL,
6275            Keyword::SECRETS,
6276            Keyword::IN,
6277            Keyword::SCHEMA,
6278        ]) {
6279            GrantObjects::AllSecretsInSchema {
6280                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6281            }
6282        } else if self.parse_keywords(&[
6283            Keyword::ALL,
6284            Keyword::CONNECTIONS,
6285            Keyword::IN,
6286            Keyword::SCHEMA,
6287        ]) {
6288            GrantObjects::AllConnectionsInSchema {
6289                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6290            }
6291        } else if self.parse_keywords(&[
6292            Keyword::ALL,
6293            Keyword::SUBSCRIPTIONS,
6294            Keyword::IN,
6295            Keyword::SCHEMA,
6296        ]) {
6297            GrantObjects::AllSubscriptionsInSchema {
6298                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6299            }
6300        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
6301            GrantObjects::Mviews(self.parse_comma_separated(Parser::parse_object_name)?)
6302        } else {
6303            let object_type = self.parse_one_of_keywords(&[
6304                Keyword::SEQUENCE,
6305                Keyword::DATABASE,
6306                Keyword::SCHEMA,
6307                Keyword::TABLE,
6308                Keyword::SOURCE,
6309                Keyword::SINK,
6310                Keyword::VIEW,
6311                Keyword::SUBSCRIPTION,
6312                Keyword::FUNCTION,
6313                Keyword::CONNECTION,
6314                Keyword::SECRET,
6315            ]);
6316            if let Some(Keyword::FUNCTION) = object_type {
6317                let func_descs = self.parse_comma_separated(Parser::parse_function_desc)?;
6318                GrantObjects::Functions(func_descs)
6319            } else {
6320                let objects = self.parse_comma_separated(Parser::parse_object_name);
6321                match object_type {
6322                    Some(Keyword::DATABASE) => GrantObjects::Databases(objects?),
6323                    Some(Keyword::SCHEMA) => GrantObjects::Schemas(objects?),
6324                    Some(Keyword::SEQUENCE) => GrantObjects::Sequences(objects?),
6325                    Some(Keyword::SOURCE) => GrantObjects::Sources(objects?),
6326                    Some(Keyword::SINK) => GrantObjects::Sinks(objects?),
6327                    Some(Keyword::VIEW) => GrantObjects::Views(objects?),
6328                    Some(Keyword::SUBSCRIPTION) => GrantObjects::Subscriptions(objects?),
6329                    Some(Keyword::CONNECTION) => GrantObjects::Connections(objects?),
6330                    Some(Keyword::SECRET) => GrantObjects::Secrets(objects?),
6331                    Some(Keyword::TABLE) | None => GrantObjects::Tables(objects?),
6332                    _ => unreachable!(),
6333                }
6334            }
6335        };
6336
6337        Ok((privileges, objects))
6338    }
6339
6340    fn parse_grant_permission(&mut self) -> ModalResult<(Keyword, Option<Vec<Ident>>)> {
6341        let kw = self.expect_one_of_keywords(&[
6342            Keyword::CONNECT,
6343            Keyword::CREATE,
6344            Keyword::DELETE,
6345            Keyword::EXECUTE,
6346            Keyword::INSERT,
6347            Keyword::REFERENCES,
6348            Keyword::SELECT,
6349            Keyword::TEMPORARY,
6350            Keyword::TRIGGER,
6351            Keyword::TRUNCATE,
6352            Keyword::UPDATE,
6353            Keyword::USAGE,
6354        ])?;
6355        let columns = match kw {
6356            Keyword::INSERT | Keyword::REFERENCES | Keyword::SELECT | Keyword::UPDATE => {
6357                let columns = self.parse_parenthesized_column_list(Optional)?;
6358                if columns.is_empty() {
6359                    None
6360                } else {
6361                    Some(columns)
6362                }
6363            }
6364            _ => None,
6365        };
6366        Ok((kw, columns))
6367    }
6368
6369    /// Parse a REVOKE statement
6370    pub fn parse_revoke(&mut self) -> ModalResult<Statement> {
6371        let revoke_grant_option =
6372            self.parse_keywords(&[Keyword::GRANT, Keyword::OPTION, Keyword::FOR]);
6373        let (privileges, objects) = self.parse_grant_revoke_privileges_objects()?;
6374
6375        self.expect_keyword(Keyword::FROM)?;
6376        let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6377
6378        let granted_by = self
6379            .parse_keywords(&[Keyword::GRANTED, Keyword::BY])
6380            .then(|| self.parse_identifier().unwrap());
6381
6382        let cascade = self.parse_keyword(Keyword::CASCADE);
6383        let restrict = self.parse_keyword(Keyword::RESTRICT);
6384        if cascade && restrict {
6385            parser_err!("Cannot specify both CASCADE and RESTRICT in REVOKE");
6386        }
6387
6388        Ok(Statement::Revoke {
6389            privileges,
6390            objects,
6391            grantees,
6392            granted_by,
6393            revoke_grant_option,
6394            cascade,
6395        })
6396    }
6397
6398    fn parse_privilege_object_types(&mut self) -> ModalResult<PrivilegeObjectType> {
6399        let object_type = if self.parse_keyword(Keyword::TABLES) {
6400            PrivilegeObjectType::Tables
6401        } else if self.parse_keyword(Keyword::SOURCES) {
6402            PrivilegeObjectType::Sources
6403        } else if self.parse_keyword(Keyword::SINKS) {
6404            PrivilegeObjectType::Sinks
6405        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEWS]) {
6406            PrivilegeObjectType::Mviews
6407        } else if self.parse_keyword(Keyword::VIEWS) {
6408            PrivilegeObjectType::Views
6409        } else if self.parse_keyword(Keyword::FUNCTIONS) {
6410            PrivilegeObjectType::Functions
6411        } else if self.parse_keyword(Keyword::SECRETS) {
6412            PrivilegeObjectType::Secrets
6413        } else if self.parse_keyword(Keyword::CONNECTIONS) {
6414            PrivilegeObjectType::Connections
6415        } else if self.parse_keyword(Keyword::SUBSCRIPTIONS) {
6416            PrivilegeObjectType::Subscriptions
6417        } else if self.parse_keyword(Keyword::SCHEMAS) {
6418            PrivilegeObjectType::Schemas
6419        } else {
6420            return self.expected("TABLES, SOURCES, SINKS, MATERIALIZED VIEWS, VIEWS, FUNCTIONS, SECRETS, CONNECTIONS, SUBSCRIPTIONS or SCHEMAS");
6421        };
6422
6423        Ok(object_type)
6424    }
6425
6426    pub fn parse_alter_default_privileges(&mut self) -> ModalResult<Statement> {
6427        // [ FOR USER target_user [, ...] ]
6428        let target_users = if self.parse_keyword(Keyword::FOR) {
6429            self.expect_keyword(Keyword::USER)?;
6430            Some(self.parse_comma_separated(Parser::parse_identifier)?)
6431        } else {
6432            None
6433        };
6434
6435        // [ IN SCHEMA schema_name [, ...] ]
6436        let schema_names = if self.parse_keywords(&[Keyword::IN, Keyword::SCHEMA]) {
6437            Some(self.parse_comma_separated(Parser::parse_object_name)?)
6438        } else {
6439            None
6440        };
6441        let keyword = self.expect_one_of_keywords(&[Keyword::GRANT, Keyword::REVOKE])?;
6442        let for_grant = keyword == Keyword::GRANT;
6443        if for_grant {
6444            let privileges = self.parse_privileges()?;
6445            self.expect_keyword(Keyword::ON)?;
6446            let object_type = self.parse_privilege_object_types()?;
6447            if schema_names.is_some() && object_type == PrivilegeObjectType::Schemas {
6448                parser_err!("cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS");
6449            }
6450            self.expect_keyword(Keyword::TO)?;
6451            let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6452
6453            let with_grant_option =
6454                self.parse_keywords(&[Keyword::WITH, Keyword::GRANT, Keyword::OPTION]);
6455
6456            Ok(Statement::AlterDefaultPrivileges {
6457                target_users,
6458                schema_names,
6459                operation: DefaultPrivilegeOperation::Grant {
6460                    privileges,
6461                    object_type,
6462                    grantees,
6463                    with_grant_option,
6464                },
6465            })
6466        } else {
6467            let revoke_grant_option =
6468                self.parse_keywords(&[Keyword::GRANT, Keyword::OPTION, Keyword::FOR]);
6469            let privileges = self.parse_privileges()?;
6470            self.expect_keyword(Keyword::ON)?;
6471            let object_type = self.parse_privilege_object_types()?;
6472            if schema_names.is_some() && object_type == PrivilegeObjectType::Schemas {
6473                parser_err!("cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS");
6474            }
6475            self.expect_keyword(Keyword::FROM)?;
6476            let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6477            let cascade = self.parse_keyword(Keyword::CASCADE);
6478            let restrict = self.parse_keyword(Keyword::RESTRICT);
6479            if cascade && restrict {
6480                parser_err!("Cannot specify both CASCADE and RESTRICT in REVOKE");
6481            }
6482
6483            Ok(Statement::AlterDefaultPrivileges {
6484                target_users,
6485                schema_names,
6486                operation: DefaultPrivilegeOperation::Revoke {
6487                    privileges,
6488                    object_type,
6489                    grantees,
6490                    revoke_grant_option,
6491                    cascade,
6492                },
6493            })
6494        }
6495    }
6496
6497    /// Parse an INSERT statement
6498    pub fn parse_insert(&mut self) -> ModalResult<Statement> {
6499        self.expect_keyword(Keyword::INTO)?;
6500
6501        let table_name = self.parse_object_name()?;
6502        let columns = self.parse_parenthesized_column_list(Optional)?;
6503
6504        let source = Box::new(self.parse_query()?);
6505        let returning = self.parse_returning(Optional)?;
6506        Ok(Statement::Insert {
6507            table_name,
6508            columns,
6509            source,
6510            returning,
6511        })
6512    }
6513
6514    pub fn parse_update(&mut self) -> ModalResult<Statement> {
6515        let table_name = self.parse_object_name()?;
6516
6517        self.expect_keyword(Keyword::SET)?;
6518        let assignments = self.parse_comma_separated(Parser::parse_assignment)?;
6519        let selection = if self.parse_keyword(Keyword::WHERE) {
6520            Some(self.parse_expr()?)
6521        } else {
6522            None
6523        };
6524        let returning = self.parse_returning(Optional)?;
6525        Ok(Statement::Update {
6526            table_name,
6527            assignments,
6528            selection,
6529            returning,
6530        })
6531    }
6532
6533    /// Parse a `var = expr` assignment, used in an UPDATE statement
6534    pub fn parse_assignment(&mut self) -> ModalResult<Assignment> {
6535        let id = self.parse_identifiers_non_keywords()?;
6536        self.expect_token(&Token::Eq)?;
6537
6538        let value = if self.parse_keyword(Keyword::DEFAULT) {
6539            AssignmentValue::Default
6540        } else {
6541            AssignmentValue::Expr(self.parse_expr()?)
6542        };
6543
6544        Ok(Assignment { id, value })
6545    }
6546
6547    /// Parse a `[VARIADIC] name => expr`.
6548    fn parse_function_args(&mut self) -> ModalResult<(bool, FunctionArg)> {
6549        let variadic = self.parse_keyword(Keyword::VARIADIC);
6550        let arg = if self.peek_nth_token(1) == Token::RArrow {
6551            let name = self.parse_identifier()?;
6552
6553            self.expect_token(&Token::RArrow)?;
6554            let arg = if self.parse_keyword(Keyword::SECRET) {
6555                FunctionArgExpr::SecretRef(self.parse_secret_ref()?)
6556            } else {
6557                self.parse_wildcard_or_expr()?.into()
6558            };
6559
6560            FunctionArg::Named { name, arg }
6561        } else if self.parse_keyword(Keyword::SECRET) {
6562            FunctionArg::Unnamed(FunctionArgExpr::SecretRef(self.parse_secret_ref()?))
6563        } else {
6564            FunctionArg::Unnamed(self.parse_wildcard_or_expr()?.into())
6565        };
6566        Ok((variadic, arg))
6567    }
6568
6569    pub fn parse_argument_list(&mut self) -> ModalResult<FunctionArgList> {
6570        self.expect_token(&Token::LParen)?;
6571        if self.consume_token(&Token::RParen) {
6572            Ok(FunctionArgList::empty())
6573        } else {
6574            let distinct = self.parse_all_or_distinct()?;
6575            let args = self.parse_comma_separated(Parser::parse_function_args)?;
6576            if args
6577                .iter()
6578                .take(args.len() - 1)
6579                .any(|(variadic, _)| *variadic)
6580            {
6581                parser_err!("VARIADIC argument must be the last");
6582            }
6583            let variadic = args.last().map(|(variadic, _)| *variadic).unwrap_or(false);
6584            let args = args.into_iter().map(|(_, arg)| arg).collect();
6585
6586            let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
6587                self.parse_comma_separated(Parser::parse_order_by_expr)?
6588            } else {
6589                vec![]
6590            };
6591
6592            let ignore_nulls = self.parse_keywords(&[Keyword::IGNORE, Keyword::NULLS]);
6593
6594            let arg_list = FunctionArgList {
6595                distinct,
6596                args,
6597                variadic,
6598                order_by,
6599                ignore_nulls,
6600            };
6601
6602            self.expect_token(&Token::RParen)?;
6603            Ok(arg_list)
6604        }
6605    }
6606
6607    /// Parse a comma-delimited list of projections after SELECT
6608    pub fn parse_select_item(&mut self) -> ModalResult<SelectItem> {
6609        match self.parse_wildcard_or_expr()? {
6610            WildcardOrExpr::Expr(expr) => self
6611                .parse_optional_alias(keywords::RESERVED_FOR_COLUMN_ALIAS)
6612                .map(|alias| match alias {
6613                    Some(alias) => SelectItem::ExprWithAlias { expr, alias },
6614                    None => SelectItem::UnnamedExpr(expr),
6615                }),
6616            WildcardOrExpr::QualifiedWildcard(prefix, except) => {
6617                Ok(SelectItem::QualifiedWildcard(prefix, except))
6618            }
6619            WildcardOrExpr::ExprQualifiedWildcard(expr, prefix) => {
6620                Ok(SelectItem::ExprQualifiedWildcard(expr, prefix))
6621            }
6622            WildcardOrExpr::Wildcard(except) => Ok(SelectItem::Wildcard(except)),
6623        }
6624    }
6625
6626    /// Parse an expression, optionally followed by ASC or DESC (used in ORDER BY)
6627    pub fn parse_order_by_expr(&mut self) -> ModalResult<OrderByExpr> {
6628        let expr = self.parse_expr()?;
6629
6630        let asc = if self.parse_keyword(Keyword::ASC) {
6631            Some(true)
6632        } else if self.parse_keyword(Keyword::DESC) {
6633            Some(false)
6634        } else {
6635            None
6636        };
6637
6638        let nulls_first = if self.parse_keywords(&[Keyword::NULLS, Keyword::FIRST]) {
6639            Some(true)
6640        } else if self.parse_keywords(&[Keyword::NULLS, Keyword::LAST]) {
6641            Some(false)
6642        } else {
6643            None
6644        };
6645
6646        Ok(OrderByExpr {
6647            expr,
6648            asc,
6649            nulls_first,
6650        })
6651    }
6652
6653    /// Parse a LIMIT clause
6654    pub fn parse_limit(&mut self) -> ModalResult<Option<Expr>> {
6655        if self.parse_keyword(Keyword::ALL) {
6656            Ok(None)
6657        } else {
6658            let expr = self.parse_expr()?;
6659            Ok(Some(expr))
6660        }
6661    }
6662
6663    /// Parse an OFFSET clause
6664    pub fn parse_offset(&mut self) -> ModalResult<String> {
6665        let value = self.parse_number_value()?;
6666        // TODO(Kexiang): support LIMIT expr
6667        if self.consume_token(&Token::DoubleColon) {
6668            self.expect_keyword(Keyword::BIGINT)?;
6669        }
6670        _ = self.parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS]);
6671        Ok(value)
6672    }
6673
6674    /// Parse a FETCH clause
6675    pub fn parse_fetch(&mut self) -> ModalResult<Fetch> {
6676        self.expect_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT])?;
6677        let quantity = if self
6678            .parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS])
6679            .is_some()
6680        {
6681            None
6682        } else {
6683            let quantity = self.parse_number_value()?;
6684            self.expect_one_of_keywords(&[Keyword::ROW, Keyword::ROWS])?;
6685            Some(quantity)
6686        };
6687        let with_ties = if self.parse_keyword(Keyword::ONLY) {
6688            false
6689        } else if self.parse_keywords(&[Keyword::WITH, Keyword::TIES]) {
6690            true
6691        } else {
6692            return self.expected("one of ONLY or WITH TIES");
6693        };
6694        Ok(Fetch {
6695            with_ties,
6696            quantity,
6697        })
6698    }
6699
6700    pub fn parse_values(&mut self) -> ModalResult<Values> {
6701        let values = self.parse_comma_separated(|parser| {
6702            parser.expect_token(&Token::LParen)?;
6703            let exprs = parser.parse_comma_separated(Parser::parse_expr)?;
6704            parser.expect_token(&Token::RParen)?;
6705            Ok(exprs)
6706        })?;
6707        Ok(Values(values))
6708    }
6709
6710    pub fn parse_start_transaction(&mut self) -> ModalResult<Statement> {
6711        self.expect_keyword(Keyword::TRANSACTION)?;
6712        Ok(Statement::StartTransaction {
6713            modes: self.parse_transaction_modes()?,
6714        })
6715    }
6716
6717    pub fn parse_begin(&mut self) -> ModalResult<Statement> {
6718        let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]);
6719        Ok(Statement::Begin {
6720            modes: self.parse_transaction_modes()?,
6721        })
6722    }
6723
6724    pub fn parse_transaction_modes(&mut self) -> ModalResult<Vec<TransactionMode>> {
6725        let mut modes = vec![];
6726        let mut required = false;
6727        loop {
6728            let mode = if self.parse_keywords(&[Keyword::ISOLATION, Keyword::LEVEL]) {
6729                let iso_level = if self.parse_keywords(&[Keyword::READ, Keyword::UNCOMMITTED]) {
6730                    TransactionIsolationLevel::ReadUncommitted
6731                } else if self.parse_keywords(&[Keyword::READ, Keyword::COMMITTED]) {
6732                    TransactionIsolationLevel::ReadCommitted
6733                } else if self.parse_keywords(&[Keyword::REPEATABLE, Keyword::READ]) {
6734                    TransactionIsolationLevel::RepeatableRead
6735                } else if self.parse_keyword(Keyword::SERIALIZABLE) {
6736                    TransactionIsolationLevel::Serializable
6737                } else {
6738                    self.expected("isolation level")?
6739                };
6740                TransactionMode::IsolationLevel(iso_level)
6741            } else if self.parse_keywords(&[Keyword::READ, Keyword::ONLY]) {
6742                TransactionMode::AccessMode(TransactionAccessMode::ReadOnly)
6743            } else if self.parse_keywords(&[Keyword::READ, Keyword::WRITE]) {
6744                TransactionMode::AccessMode(TransactionAccessMode::ReadWrite)
6745            } else if required {
6746                self.expected("transaction mode")?
6747            } else {
6748                break;
6749            };
6750            modes.push(mode);
6751            // ANSI requires a comma after each transaction mode, but
6752            // PostgreSQL, for historical reasons, does not. We follow
6753            // PostgreSQL in making the comma optional, since that is strictly
6754            // more general.
6755            required = self.consume_token(&Token::Comma);
6756        }
6757        Ok(modes)
6758    }
6759
6760    pub fn parse_commit(&mut self) -> ModalResult<Statement> {
6761        Ok(Statement::Commit {
6762            chain: self.parse_commit_rollback_chain()?,
6763        })
6764    }
6765
6766    pub fn parse_rollback(&mut self) -> ModalResult<Statement> {
6767        Ok(Statement::Rollback {
6768            chain: self.parse_commit_rollback_chain()?,
6769        })
6770    }
6771
6772    pub fn parse_commit_rollback_chain(&mut self) -> ModalResult<bool> {
6773        let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]);
6774        if self.parse_keyword(Keyword::AND) {
6775            let chain = !self.parse_keyword(Keyword::NO);
6776            self.expect_keyword(Keyword::CHAIN)?;
6777            Ok(chain)
6778        } else {
6779            Ok(false)
6780        }
6781    }
6782
6783    fn parse_deallocate(&mut self) -> ModalResult<Statement> {
6784        let prepare = self.parse_keyword(Keyword::PREPARE);
6785        let name = if self.parse_keyword(Keyword::ALL) {
6786            None
6787        } else {
6788            Some(self.parse_identifier()?)
6789        };
6790        Ok(Statement::Deallocate { name, prepare })
6791    }
6792
6793    fn parse_execute(&mut self) -> ModalResult<Statement> {
6794        let name = self.parse_identifier()?;
6795
6796        let mut parameters = vec![];
6797        if self.consume_token(&Token::LParen) {
6798            parameters = self.parse_comma_separated(Parser::parse_expr)?;
6799            self.expect_token(&Token::RParen)?;
6800        }
6801
6802        Ok(Statement::Execute { name, parameters })
6803    }
6804
6805    fn parse_prepare(&mut self) -> ModalResult<Statement> {
6806        let name = self.parse_identifier()?;
6807
6808        let mut data_types = vec![];
6809        if self.consume_token(&Token::LParen) {
6810            data_types = self.parse_comma_separated(Parser::parse_data_type)?;
6811            self.expect_token(&Token::RParen)?;
6812        }
6813
6814        self.expect_keyword(Keyword::AS)?;
6815        let statement = Box::new(self.parse_statement()?);
6816        Ok(Statement::Prepare {
6817            name,
6818            data_types,
6819            statement,
6820        })
6821    }
6822
6823    fn parse_comment(&mut self) -> ModalResult<Statement> {
6824        self.expect_keyword(Keyword::ON)?;
6825        let checkpoint = *self;
6826        let token = self.next_token();
6827
6828        let (object_type, object_name) = match token.token {
6829            Token::Word(w) if w.keyword == Keyword::COLUMN => {
6830                let object_name = self.parse_object_name()?;
6831                (CommentObject::Column, object_name)
6832            }
6833            Token::Word(w) if w.keyword == Keyword::TABLE => {
6834                let object_name = self.parse_object_name()?;
6835                (CommentObject::Table, object_name)
6836            }
6837            _ => self.expected_at(checkpoint, "comment object_type")?,
6838        };
6839
6840        self.expect_keyword(Keyword::IS)?;
6841        let comment = if self.parse_keyword(Keyword::NULL) {
6842            None
6843        } else {
6844            Some(self.parse_literal_string()?)
6845        };
6846        Ok(Statement::Comment {
6847            object_type,
6848            object_name,
6849            comment,
6850        })
6851    }
6852
6853    fn parse_use(&mut self) -> ModalResult<Statement> {
6854        let db_name = self.parse_object_name()?;
6855        Ok(Statement::Use { db_name })
6856    }
6857
6858    /// Parse a named window definition for the WINDOW clause
6859    pub fn parse_named_window(&mut self) -> ModalResult<NamedWindow> {
6860        let name = self.parse_identifier()?;
6861        self.expect_keywords(&[Keyword::AS])?;
6862        self.expect_token(&Token::LParen)?;
6863        let window_spec = self.parse_window_spec()?;
6864        self.expect_token(&Token::RParen)?;
6865        Ok(NamedWindow { name, window_spec })
6866    }
6867
6868    /// Parse a window specification (contents of OVER clause or WINDOW clause)
6869    pub fn parse_window_spec(&mut self) -> ModalResult<WindowSpec> {
6870        let partition_by = if self.parse_keywords(&[Keyword::PARTITION, Keyword::BY]) {
6871            self.parse_comma_separated(Parser::parse_expr)?
6872        } else {
6873            vec![]
6874        };
6875        let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
6876            self.parse_comma_separated(Parser::parse_order_by_expr)?
6877        } else {
6878            vec![]
6879        };
6880        let window_frame = if !self.peek_token().eq(&Token::RParen) {
6881            Some(self.parse_window_frame()?)
6882        } else {
6883            None
6884        };
6885        Ok(WindowSpec {
6886            partition_by,
6887            order_by,
6888            window_frame,
6889        })
6890    }
6891
6892    pub fn parse_wait(&mut self) -> ModalResult<Statement> {
6893        let target = if self.parse_keyword(Keyword::TABLE) {
6894            WaitTarget::Table(self.parse_object_name()?)
6895        } else if self.parse_keyword(Keyword::MATERIALIZED) {
6896            self.expect_keyword(Keyword::VIEW)?;
6897            WaitTarget::MaterializedView(self.parse_object_name()?)
6898        } else if self.parse_keyword(Keyword::SINK) {
6899            WaitTarget::Sink(self.parse_object_name()?)
6900        } else if self.parse_keyword(Keyword::INDEX) {
6901            WaitTarget::Index(self.parse_object_name()?)
6902        } else {
6903            WaitTarget::All
6904        };
6905
6906        Ok(Statement::Wait(target))
6907    }
6908}
6909
6910impl Word {
6911    /// Convert a Word to a Identifier, return ParserError when the Word's value is a empty string.
6912    pub fn to_ident(&self) -> ModalResult<Ident> {
6913        if self.value.is_empty() {
6914            parser_err!("zero-length delimited identifier at or near \"{self}\"")
6915        } else {
6916            Ok(Ident {
6917                value: self.value.clone(),
6918                quote_style: self.quote_style,
6919            })
6920        }
6921    }
6922}
6923
6924#[cfg(test)]
6925mod tests {
6926    use super::*;
6927    use crate::test_utils::run_parser_method;
6928
6929    #[test]
6930    fn test_parse_integer_min() {
6931        let min_bigint = "-9223372036854775808";
6932        run_parser_method(min_bigint, |parser| {
6933            assert_eq!(
6934                parser.parse_expr().unwrap(),
6935                Expr::Value(Value::Number("-9223372036854775808".to_owned()))
6936            )
6937        });
6938    }
6939
6940    #[test]
6941    fn test_parse_function_arg_secret_ref() {
6942        use crate::ast::{FunctionArg, FunctionArgExpr, SecretRefAsType, SecretRefValue};
6943
6944        // Unnamed secret argument
6945        run_parser_method("SECRET my_secret", |parser| {
6946            let (_variadic, arg) = parser.parse_function_args().unwrap();
6947            assert_eq!(
6948                arg,
6949                FunctionArg::Unnamed(FunctionArgExpr::SecretRef(SecretRefValue {
6950                    secret_name: ObjectName(vec![Ident::new_unchecked("my_secret")]),
6951                    ref_as: SecretRefAsType::Text,
6952                }))
6953            );
6954        });
6955
6956        // Unnamed secret argument with AS FILE
6957        run_parser_method("SECRET my_secret AS FILE", |parser| {
6958            let (_variadic, arg) = parser.parse_function_args().unwrap();
6959            assert_eq!(
6960                arg,
6961                FunctionArg::Unnamed(FunctionArgExpr::SecretRef(SecretRefValue {
6962                    secret_name: ObjectName(vec![Ident::new_unchecked("my_secret")]),
6963                    ref_as: SecretRefAsType::File,
6964                }))
6965            );
6966        });
6967
6968        // Named secret argument
6969        run_parser_method("header => SECRET my_secret", |parser| {
6970            let (_variadic, arg) = parser.parse_function_args().unwrap();
6971            assert_eq!(
6972                arg,
6973                FunctionArg::Named {
6974                    name: Ident::new_unchecked("header"),
6975                    arg: FunctionArgExpr::SecretRef(SecretRefValue {
6976                        secret_name: ObjectName(vec![Ident::new_unchecked("my_secret")]),
6977                        ref_as: SecretRefAsType::Text,
6978                    }),
6979                }
6980            );
6981        });
6982    }
6983}