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_expr()?;
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_expr()?;
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 optional constraints following the `IS [NOT] JSON` predicate
1579    pub fn parse_is_json(&mut self, expr: Expr, negated: bool) -> ModalResult<Expr> {
1580        let item_type = match self.peek_token().token {
1581            Token::Word(w) => match w.keyword {
1582                Keyword::VALUE => Some(JsonPredicateType::Value),
1583                Keyword::ARRAY => Some(JsonPredicateType::Array),
1584                Keyword::OBJECT => Some(JsonPredicateType::Object),
1585                Keyword::SCALAR => Some(JsonPredicateType::Scalar),
1586                _ => None,
1587            },
1588            _ => None,
1589        };
1590        if item_type.is_some() {
1591            self.next_token();
1592        }
1593        let item_type = item_type.unwrap_or_default();
1594
1595        let unique_keys = self.parse_one_of_keywords(&[Keyword::WITH, Keyword::WITHOUT]);
1596        if unique_keys.is_some() {
1597            self.expect_keyword(Keyword::UNIQUE)?;
1598            _ = self.parse_keyword(Keyword::KEYS);
1599        }
1600        let unique_keys = unique_keys.is_some_and(|w| w == Keyword::WITH);
1601
1602        Ok(Expr::IsJson {
1603            expr: Box::new(expr),
1604            negated,
1605            item_type,
1606            unique_keys,
1607        })
1608    }
1609
1610    /// Parses the parens following the `[ NOT ] IN` operator
1611    pub fn parse_in(&mut self, expr: Expr, negated: bool) -> ModalResult<Expr> {
1612        self.expect_token(&Token::LParen)?;
1613        let in_op = if matches!(self.peek_token().token, Token::Word(w) if w.keyword == Keyword::SELECT || w.keyword == Keyword::WITH)
1614        {
1615            Expr::InSubquery {
1616                expr: Box::new(expr),
1617                subquery: Box::new(self.parse_query()?),
1618                negated,
1619            }
1620        } else {
1621            Expr::InList {
1622                expr: Box::new(expr),
1623                list: self.parse_comma_separated(Parser::parse_expr)?,
1624                negated,
1625            }
1626        };
1627        self.expect_token(&Token::RParen)?;
1628        Ok(in_op)
1629    }
1630
1631    /// Parses `BETWEEN <low> AND <high>`, assuming the `BETWEEN` keyword was already consumed
1632    pub fn parse_between(&mut self, expr: Expr, negated: bool) -> ModalResult<Expr> {
1633        // Stop parsing subexpressions for <low> and <high> on tokens with
1634        // precedence lower than that of `BETWEEN`, such as `AND`, `IS`, etc.
1635        let low = self.parse_subexpr(Precedence::Between)?;
1636        self.expect_keyword(Keyword::AND)?;
1637        let high = self.parse_subexpr(Precedence::Between)?;
1638        Ok(Expr::Between {
1639            expr: Box::new(expr),
1640            negated,
1641            low: Box::new(low),
1642            high: Box::new(high),
1643        })
1644    }
1645
1646    /// Parse a postgresql casting style which is in the form of `expr::datatype`
1647    pub fn parse_pg_cast(&mut self, expr: Expr) -> ModalResult<Expr> {
1648        Ok(Expr::Cast {
1649            expr: Box::new(expr),
1650            data_type: self.parse_data_type()?,
1651        })
1652    }
1653
1654    /// Get the precedence of the next token
1655    pub fn get_next_precedence(&self) -> ModalResult<Precedence> {
1656        use Precedence as P;
1657
1658        let token = self.peek_token();
1659        debug!("get_next_precedence() {:?}", token);
1660        match token.token {
1661            Token::Word(w) if w.keyword == Keyword::OR => Ok(P::LogicalOr),
1662            Token::Word(w) if w.keyword == Keyword::XOR => Ok(P::LogicalXor),
1663            Token::Word(w) if w.keyword == Keyword::AND => Ok(P::LogicalAnd),
1664            Token::Word(w) if w.keyword == Keyword::AT => {
1665                match (self.peek_nth_token(1).token, self.peek_nth_token(2).token) {
1666                    (Token::Word(w), Token::Word(w2))
1667                        if w.keyword == Keyword::TIME && w2.keyword == Keyword::ZONE =>
1668                    {
1669                        Ok(P::At)
1670                    }
1671                    _ => Ok(P::Zero),
1672                }
1673            }
1674
1675            Token::Word(w) if w.keyword == Keyword::NOT => match self.peek_nth_token(1).token {
1676                // The precedence of NOT varies depending on keyword that
1677                // follows it. If it is followed by IN, BETWEEN, or LIKE,
1678                // it takes on the precedence of those tokens. Otherwise it
1679                // is not an infix operator, and therefore has zero
1680                // precedence.
1681                Token::Word(w) if w.keyword == Keyword::BETWEEN => Ok(P::Between),
1682                Token::Word(w) if w.keyword == Keyword::IN => Ok(P::Between),
1683                Token::Word(w) if w.keyword == Keyword::LIKE => Ok(P::Like),
1684                Token::Word(w) if w.keyword == Keyword::ILIKE => Ok(P::Like),
1685                Token::Word(w) if w.keyword == Keyword::SIMILAR => Ok(P::Like),
1686                _ => Ok(P::Zero),
1687            },
1688
1689            Token::Word(w) if w.keyword == Keyword::IS => Ok(P::Is),
1690            Token::Word(w) if w.keyword == Keyword::ISNULL => Ok(P::Is),
1691            Token::Word(w) if w.keyword == Keyword::NOTNULL => Ok(P::Is),
1692            Token::Eq | Token::Lt | Token::LtEq | Token::Neq | Token::Gt | Token::GtEq => {
1693                Ok(P::Cmp)
1694            }
1695            Token::Word(w) if w.keyword == Keyword::IN => Ok(P::Between),
1696            Token::Word(w) if w.keyword == Keyword::BETWEEN => 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            Token::Word(w) if w.keyword == Keyword::ALL => Ok(P::Other),
1701            Token::Word(w) if w.keyword == Keyword::ANY => Ok(P::Other),
1702            Token::Word(w) if w.keyword == Keyword::SOME => Ok(P::Other),
1703            Token::Op(_) => Ok(P::Other),
1704            Token::Word(w)
1705                if w.keyword == Keyword::OPERATOR && self.peek_nth_token(1) == Token::LParen =>
1706            {
1707                Ok(P::Other)
1708            }
1709            // In some languages (incl. rust, c), bitwise operators have precedence:
1710            //   or < xor < and < shift
1711            // But in PostgreSQL, they are just left to right. So `2 | 3 & 4` is 0.
1712            Token::Pipe => Ok(P::Other),
1713            Token::Plus | Token::Minus => Ok(P::PlusMinus),
1714            Token::Mul | Token::Div | Token::Mod => Ok(P::MulDiv),
1715            Token::Caret => Ok(P::Exp),
1716            Token::LBracket => Ok(P::Array),
1717            Token::DoubleColon => Ok(P::DoubleColon),
1718            _ => Ok(P::Zero),
1719        }
1720    }
1721
1722    /// Return the first non-whitespace token that has not yet been processed
1723    /// (or None if reached end-of-file)
1724    pub fn peek_token(&self) -> TokenWithLocation {
1725        self.peek_nth_token(0)
1726    }
1727
1728    /// Return nth non-whitespace token that has not yet been processed
1729    pub fn peek_nth_token(&self, mut n: usize) -> TokenWithLocation {
1730        let mut index = 0;
1731        loop {
1732            let token = self.0.get(index);
1733            index += 1;
1734            match token.map(|x| &x.token) {
1735                Some(Token::Whitespace(_)) => continue,
1736                _ => {
1737                    if n == 0 {
1738                        return token.cloned().unwrap_or(TokenWithLocation::eof());
1739                    }
1740                    n -= 1;
1741                }
1742            }
1743        }
1744    }
1745
1746    /// Return the first non-whitespace token that has not yet been processed
1747    /// (or None if reached end-of-file) and mark it as processed. OK to call
1748    /// repeatedly after reaching EOF.
1749    pub fn next_token(&mut self) -> TokenWithLocation {
1750        loop {
1751            let Some(token) = self.0.first() else {
1752                return TokenWithLocation::eof();
1753            };
1754            self.0 = &self.0[1..];
1755            match token.token {
1756                Token::Whitespace(_) => continue,
1757                _ => return token.clone(),
1758            }
1759        }
1760    }
1761
1762    /// Return the first unprocessed token, possibly whitespace.
1763    pub fn next_token_no_skip(&mut self) -> Option<&TokenWithLocation> {
1764        if self.0.is_empty() {
1765            None
1766        } else {
1767            let (first, rest) = self.0.split_at(1);
1768            self.0 = rest;
1769            Some(&first[0])
1770        }
1771    }
1772
1773    /// Report an expected error at the current position.
1774    pub fn expected<T>(&self, expected: &str) -> ModalResult<T> {
1775        parser_err!("expected {}, found: {}", expected, self.peek_token().token)
1776    }
1777
1778    /// Revert the parser to a previous position and report an expected error.
1779    pub fn expected_at<T>(&mut self, checkpoint: Self, expected: &str) -> ModalResult<T> {
1780        *self = checkpoint;
1781        self.expected(expected)
1782    }
1783
1784    /// Check if the expected match is the next token.
1785    /// The equality check is case-insensitive, and only an UNQUOTED word matches: a quoted word
1786    /// is an identifier by definition, so it must never be taken as a contextual grammar word
1787    /// (`PATTERN ("PERMUTE")` names a pattern variable, not the `PERMUTE(...)` form).
1788    pub fn parse_word(&mut self, expected: &str) -> bool {
1789        match self.peek_token().token {
1790            Token::Word(w) if w.quote_style.is_none() && w.value.to_uppercase() == expected => {
1791                self.next_token();
1792                true
1793            }
1794            _ => false,
1795        }
1796    }
1797
1798    pub fn expect_word(&mut self, expected: &str) -> ModalResult<()> {
1799        if self.parse_word(expected) {
1800            Ok(())
1801        } else {
1802            self.expected(expected)
1803        }
1804    }
1805
1806    /// Like [`Parser::parse_keywords`], but over contextual words: each element is matched
1807    /// case-insensitively against the next word token (keyword or not), and the parser is reset on
1808    /// the first miss. This is what lets `MATCH_RECOGNIZE`'s clause markers (`MEASURES`, `PATTERN`,
1809    /// `DEFINE`, ...) avoid the keyword table entirely — a global keyword changes identifier
1810    /// parsing and quoting everywhere (`UPDATE t SET per = 1` stopped parsing when `PER` was
1811    /// briefly a keyword), while inside the parenthesized clause the grammar owns the context.
1812    #[must_use]
1813    pub fn parse_words(&mut self, words: &[&str]) -> bool {
1814        let checkpoint = *self;
1815        for w in words {
1816            if !self.parse_word(w) {
1817                *self = checkpoint;
1818                return false;
1819            }
1820        }
1821        true
1822    }
1823
1824    /// Look for an expected keyword and consume it if it exists
1825    #[must_use]
1826    pub fn parse_keyword(&mut self, expected: Keyword) -> bool {
1827        match self.peek_token().token {
1828            Token::Word(w) if expected == w.keyword => {
1829                self.next_token();
1830                true
1831            }
1832            _ => false,
1833        }
1834    }
1835
1836    /// Look for an expected sequence of keywords and consume them if they exist
1837    #[must_use]
1838    pub fn parse_keywords(&mut self, keywords: &[Keyword]) -> bool {
1839        let checkpoint = *self;
1840        for &keyword in keywords {
1841            if !self.parse_keyword(keyword) {
1842                // println!("parse_keywords aborting .. did not find {:?}", keyword);
1843                // reset index and return immediately
1844                *self = checkpoint;
1845                return false;
1846            }
1847        }
1848        true
1849    }
1850
1851    /// Look for one of the given keywords and return the one that matches.
1852    #[must_use]
1853    pub fn parse_one_of_keywords(&mut self, keywords: &[Keyword]) -> Option<Keyword> {
1854        match self.peek_token().token {
1855            Token::Word(w) => {
1856                keywords
1857                    .iter()
1858                    .find(|keyword| **keyword == w.keyword)
1859                    .map(|keyword| {
1860                        self.next_token();
1861                        *keyword
1862                    })
1863            }
1864            _ => None,
1865        }
1866    }
1867
1868    pub fn peek_nth_any_of_keywords(&mut self, n: usize, keywords: &[Keyword]) -> bool {
1869        match self.peek_nth_token(n).token {
1870            Token::Word(w) => keywords.contains(&w.keyword),
1871            _ => false,
1872        }
1873    }
1874
1875    /// Bail out if the current token is not one of the expected keywords, or consume it if it is
1876    pub fn expect_one_of_keywords(&mut self, keywords: &[Keyword]) -> ModalResult<Keyword> {
1877        if let Some(keyword) = self.parse_one_of_keywords(keywords) {
1878            Ok(keyword)
1879        } else {
1880            let keywords: Vec<String> = keywords.iter().map(|x| format!("{:?}", x)).collect();
1881            self.expected(&format!("one of {}", keywords.join(" or ")))
1882        }
1883    }
1884
1885    /// Bail out if the current token is not an expected keyword, or consume it if it is
1886    pub fn expect_keyword(&mut self, expected: Keyword) -> ModalResult<()> {
1887        if self.parse_keyword(expected) {
1888            Ok(())
1889        } else {
1890            self.expected(format!("{:?}", expected).as_str())
1891        }
1892    }
1893
1894    /// Bail out if the following tokens are not the expected sequence of
1895    /// keywords, or consume them if they are.
1896    pub fn expect_keywords(&mut self, expected: &[Keyword]) -> ModalResult<()> {
1897        for &kw in expected {
1898            self.expect_keyword(kw)?;
1899        }
1900        Ok(())
1901    }
1902
1903    /// Consume the next token if it matches the expected token, otherwise return false
1904    #[must_use]
1905    pub fn consume_token(&mut self, expected: &Token) -> bool {
1906        if self.peek_token() == *expected {
1907            self.next_token();
1908            true
1909        } else {
1910            false
1911        }
1912    }
1913
1914    /// Bail out if the current token is not an expected keyword, or consume it if it is
1915    pub fn expect_token(&mut self, expected: &Token) -> ModalResult<()> {
1916        if self.consume_token(expected) {
1917            Ok(())
1918        } else {
1919            self.expected(&expected.to_string())
1920        }
1921    }
1922
1923    /// Parse a comma-separated list of 1+ items accepted by `F`
1924    pub fn parse_comma_separated<T, F>(&mut self, mut f: F) -> ModalResult<Vec<T>>
1925    where
1926        F: FnMut(&mut Self) -> ModalResult<T>,
1927    {
1928        let mut values = vec![];
1929        loop {
1930            values.push(f(self)?);
1931            if !self.consume_token(&Token::Comma) {
1932                break;
1933            }
1934        }
1935        Ok(values)
1936    }
1937
1938    /// Run a parser method `f`, reverting back to the current position
1939    /// if unsuccessful.
1940    #[must_use]
1941    fn maybe_parse<T, F>(&mut self, mut f: F) -> Option<T>
1942    where
1943        F: FnMut(&mut Self) -> ModalResult<T>,
1944    {
1945        let checkpoint = *self;
1946        match f(self) {
1947            Ok(t) => Some(t),
1948            _ => {
1949                *self = checkpoint;
1950                None
1951            }
1952        }
1953    }
1954
1955    /// Parse either `ALL` or `DISTINCT`. Returns `true` if `DISTINCT` is parsed and results in a
1956    /// `ParserError` if both `ALL` and `DISTINCT` are fround.
1957    pub fn parse_all_or_distinct(&mut self) -> ModalResult<bool> {
1958        let all = self.parse_keyword(Keyword::ALL);
1959        let distinct = self.parse_keyword(Keyword::DISTINCT);
1960        if all && distinct {
1961            parser_err!("Cannot specify both ALL and DISTINCT")
1962        } else {
1963            Ok(distinct)
1964        }
1965    }
1966
1967    /// Parse either `ALL` or `DISTINCT` or `DISTINCT ON (<expr>)`.
1968    pub fn parse_all_or_distinct_on(&mut self) -> ModalResult<Distinct> {
1969        if self.parse_keywords(&[Keyword::DISTINCT, Keyword::ON]) {
1970            self.expect_token(&Token::LParen)?;
1971            let exprs = self.parse_comma_separated(Parser::parse_expr)?;
1972            self.expect_token(&Token::RParen)?;
1973            return Ok(Distinct::DistinctOn(exprs));
1974        } else if self.parse_keyword(Keyword::DISTINCT) {
1975            return Ok(Distinct::Distinct);
1976        };
1977        _ = self.parse_keyword(Keyword::ALL);
1978        Ok(Distinct::All)
1979    }
1980
1981    /// Parse a SQL CREATE statement
1982    pub fn parse_create(&mut self) -> ModalResult<Statement> {
1983        let or_replace = self.parse_keywords(&[Keyword::OR, Keyword::REPLACE]);
1984        let temporary = self
1985            .parse_one_of_keywords(&[Keyword::TEMP, Keyword::TEMPORARY])
1986            .is_some();
1987        if self.parse_keyword(Keyword::TABLE) {
1988            self.parse_create_table(or_replace, temporary)
1989        } else if self.parse_keyword(Keyword::VIEW) {
1990            self.parse_create_view(false, or_replace)
1991        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
1992            self.parse_create_view(true, or_replace)
1993        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::SOURCE]) {
1994            parser_err!("CREATE MATERIALIZED SOURCE has been deprecated, use CREATE TABLE instead")
1995        } else if self.parse_keyword(Keyword::SOURCE) {
1996            self.parse_create_source(or_replace, temporary)
1997        } else if self.parse_keyword(Keyword::SINK) {
1998            if or_replace {
1999                parser_err!("REPLACE SINK should be used instead of CREATE OR REPLACE SINK");
2000            }
2001            self.parse_create_sink(or_replace)
2002        } else if self.parse_keyword(Keyword::SUBSCRIPTION) {
2003            self.parse_create_subscription(or_replace)
2004        } else if self.parse_keyword(Keyword::CONNECTION) {
2005            self.parse_create_connection()
2006        } else if self.parse_keyword(Keyword::FUNCTION) {
2007            self.parse_create_function(or_replace, temporary)
2008        } else if self.parse_keyword(Keyword::AGGREGATE) {
2009            self.parse_create_aggregate(or_replace)
2010        } else if or_replace {
2011            self.expected(
2012                "[EXTERNAL] TABLE or [MATERIALIZED] VIEW or [MATERIALIZED] SOURCE or SINK or FUNCTION after CREATE OR REPLACE",
2013            )
2014        } else if self.parse_keyword(Keyword::INDEX) {
2015            self.parse_create_index(false)
2016        } else if self.parse_keywords(&[Keyword::UNIQUE, Keyword::INDEX]) {
2017            self.parse_create_index(true)
2018        } else if self.parse_keyword(Keyword::SCHEMA) {
2019            self.parse_create_schema()
2020        } else if self.parse_keyword(Keyword::DATABASE) {
2021            self.parse_create_database()
2022        } else if self.parse_keyword(Keyword::USER) {
2023            self.parse_create_user()
2024        } else if self.parse_keyword(Keyword::SECRET) {
2025            self.parse_create_secret()
2026        } else {
2027            self.expected("an object type after CREATE")
2028        }
2029    }
2030
2031    pub fn parse_create_schema(&mut self) -> ModalResult<Statement> {
2032        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2033        let (schema_name, owner) = if self.parse_keyword(Keyword::AUTHORIZATION) {
2034            let owner = self.parse_object_name()?;
2035            (owner.clone(), Some(owner))
2036        } else {
2037            let schema_name = self.parse_object_name()?;
2038            let owner = if self.parse_keyword(Keyword::AUTHORIZATION) {
2039                Some(self.parse_object_name()?)
2040            } else {
2041                None
2042            };
2043            (schema_name, owner)
2044        };
2045        Ok(Statement::CreateSchema {
2046            schema_name,
2047            if_not_exists,
2048            owner,
2049        })
2050    }
2051
2052    pub fn parse_create_database(&mut self) -> ModalResult<Statement> {
2053        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2054        let db_name = self.parse_object_name()?;
2055        let _ = self.parse_keyword(Keyword::WITH);
2056
2057        let mut owner = None;
2058        let mut resource_group = None;
2059        let mut barrier_interval_ms = None;
2060        let mut checkpoint_frequency = None;
2061
2062        loop {
2063            if let Some(keyword) =
2064                self.parse_one_of_keywords(&[Keyword::OWNER, Keyword::RESOURCE_GROUP])
2065            {
2066                match keyword {
2067                    Keyword::OWNER => {
2068                        if owner.is_some() {
2069                            parser_err!("duplicate OWNER clause in CREATE DATABASE");
2070                        }
2071
2072                        let _ = self.consume_token(&Token::Eq);
2073                        owner = Some(self.parse_object_name()?);
2074                    }
2075                    Keyword::RESOURCE_GROUP => {
2076                        if resource_group.is_some() {
2077                            parser_err!("duplicate RESOURCE_GROUP clause in CREATE DATABASE");
2078                        }
2079
2080                        let _ = self.consume_token(&Token::Eq);
2081                        resource_group = Some(self.parse_set_variable()?);
2082                    }
2083                    _ => unreachable!(),
2084                }
2085            } else if self.parse_word("BARRIER_INTERVAL_MS") {
2086                if barrier_interval_ms.is_some() {
2087                    parser_err!("duplicate BARRIER_INTERVAL_MS clause in CREATE DATABASE");
2088                }
2089
2090                let _ = self.consume_token(&Token::Eq);
2091                barrier_interval_ms = Some(self.parse_literal_u32()?);
2092            } else if self.parse_word("CHECKPOINT_FREQUENCY") {
2093                if checkpoint_frequency.is_some() {
2094                    parser_err!("duplicate CHECKPOINT_FREQUENCY clause in CREATE DATABASE");
2095                }
2096
2097                let _ = self.consume_token(&Token::Eq);
2098                checkpoint_frequency = Some(self.parse_literal_u64()?);
2099            } else {
2100                break;
2101            }
2102        }
2103
2104        Ok(Statement::CreateDatabase {
2105            db_name,
2106            if_not_exists,
2107            owner,
2108            resource_group,
2109            barrier_interval_ms,
2110            checkpoint_frequency,
2111        })
2112    }
2113
2114    pub fn parse_create_view(
2115        &mut self,
2116        materialized: bool,
2117        or_replace: bool,
2118    ) -> ModalResult<Statement> {
2119        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2120        // Many dialects support `OR ALTER` right after `CREATE`, but we don't (yet).
2121        // ANSI SQL and Postgres support RECURSIVE here, but we don't support it either.
2122        let name = self.parse_object_name()?;
2123        let columns = self.parse_parenthesized_column_list(Optional)?;
2124        let with_options = self.parse_options_with_preceding_keyword(Keyword::WITH)?;
2125        self.expect_keyword(Keyword::AS)?;
2126        let query = Box::new(self.parse_query()?);
2127        let emit_mode = if materialized {
2128            self.parse_emit_mode()?
2129        } else {
2130            None
2131        };
2132        // Optional `WITH [ CASCADED | LOCAL ] CHECK OPTION` is widely supported here.
2133        Ok(Statement::CreateView {
2134            if_not_exists,
2135            name,
2136            columns,
2137            query,
2138            materialized,
2139            or_replace,
2140            with_options,
2141            emit_mode,
2142        })
2143    }
2144
2145    // CREATE [OR REPLACE]?
2146    // [TEMPORARY] SOURCE
2147    // [IF NOT EXISTS]?
2148    // <source_name: Ident>
2149    // [COLUMNS]?
2150    // [WITH (properties)]?
2151    // ROW FORMAT <row_format: Ident>
2152    // [ROW SCHEMA LOCATION <row_schema_location: String>]?
2153    pub fn parse_create_source(
2154        &mut self,
2155        _or_replace: bool,
2156        temporary: bool,
2157    ) -> ModalResult<Statement> {
2158        impl_parse_to!(if_not_exists => [Keyword::IF, Keyword::NOT, Keyword::EXISTS], self);
2159        impl_parse_to!(source_name: ObjectName, self);
2160
2161        // parse columns
2162        let (columns, constraints, source_watermarks, wildcard_idx) =
2163            self.parse_columns_with_watermark()?;
2164        let include_options = self.parse_include_options()?;
2165
2166        let with_options = self.parse_with_properties()?;
2167        let option = with_options
2168            .iter()
2169            .find(|&opt| opt.name.real_value() == UPSTREAM_SOURCE_KEY);
2170        let connector: String = option.map(|opt| opt.value.to_string()).unwrap_or_default();
2171        let cdc_source_job = connector.contains("-cdc");
2172        if cdc_source_job && (!columns.is_empty() || !constraints.is_empty()) {
2173            parser_err!("CDC source cannot define columns and constraints");
2174        }
2175
2176        let cdc_table_info = if self.parse_keyword(Keyword::FROM) {
2177            let source_name = self.parse_object_name()?;
2178            self.expect_keyword(Keyword::TABLE)?;
2179            let external_table_name = self.parse_literal_string()?;
2180            Some(CdcTableInfo {
2181                source_name,
2182                external_table_name,
2183            })
2184        } else {
2185            None
2186        };
2187
2188        // A CDC table source reuses the schema of an upstream shared CDC source and therefore has
2189        // no FORMAT/ENCODE clause. Keep a native placeholder to avoid making the existing AST field
2190        // optional; the frontend ignores it for this source kind.
2191        let format_encode = if cdc_table_info.is_some() {
2192            FormatEncodeOptions::native().into()
2193        } else {
2194            // row format for nexmark source must be native
2195            // default row format for datagen source is native
2196            self.parse_format_encode_with_connector(&connector, cdc_source_job)?
2197        };
2198
2199        let stmt = CreateSourceStatement {
2200            temporary,
2201            if_not_exists,
2202            columns,
2203            wildcard_idx,
2204            constraints,
2205            source_name,
2206            with_properties: WithProperties(with_options),
2207            format_encode,
2208            source_watermarks,
2209            include_column_options: include_options,
2210            cdc_table_info,
2211        };
2212
2213        Ok(Statement::CreateSource { stmt })
2214    }
2215
2216    /// Parse a SQL REPLACE statement.
2217    pub fn parse_replace(&mut self) -> ModalResult<Statement> {
2218        if self.parse_keyword(Keyword::SINK) {
2219            self.parse_create_sink(true)
2220        } else {
2221            self.expected("SINK after REPLACE")
2222        }
2223    }
2224
2225    // CREATE SINK / REPLACE SINK
2226    // [IF NOT EXISTS]?
2227    // <sink_name: Ident>
2228    // FROM
2229    // <materialized_view: Ident>
2230    // [WITH (properties)]?
2231    pub fn parse_create_sink(&mut self, or_replace: bool) -> ModalResult<Statement> {
2232        Ok(Statement::CreateSink {
2233            stmt: CreateSinkStatement::parse_to_with_or_replace(self, or_replace)?,
2234        })
2235    }
2236
2237    // CREATE
2238    // SUBSCRIPTION
2239    // [IF NOT EXISTS]?
2240    // <subscription_name: Ident>
2241    // FROM
2242    // <materialized_view: Ident>
2243    // [WITH (properties)]?
2244    pub fn parse_create_subscription(&mut self, _or_replace: bool) -> ModalResult<Statement> {
2245        Ok(Statement::CreateSubscription {
2246            stmt: CreateSubscriptionStatement::parse_to(self)?,
2247        })
2248    }
2249
2250    // CREATE
2251    // CONNECTION
2252    // [IF NOT EXISTS]?
2253    // <connection_name: Ident>
2254    // [WITH (properties)]?
2255    pub fn parse_create_connection(&mut self) -> ModalResult<Statement> {
2256        Ok(Statement::CreateConnection {
2257            stmt: CreateConnectionStatement::parse_to(self)?,
2258        })
2259    }
2260
2261    pub fn parse_create_function(
2262        &mut self,
2263        or_replace: bool,
2264        temporary: bool,
2265    ) -> ModalResult<Statement> {
2266        impl_parse_to!(if_not_exists => [Keyword::IF, Keyword::NOT, Keyword::EXISTS], self);
2267
2268        let FunctionDesc { name, args } = self.parse_function_desc()?;
2269
2270        let return_type = if self.parse_keyword(Keyword::RETURNS) {
2271            if self.parse_keyword(Keyword::TABLE) {
2272                self.expect_token(&Token::LParen)?;
2273                let mut values = vec![];
2274                loop {
2275                    values.push(self.parse_table_column_def()?);
2276                    let comma = self.consume_token(&Token::Comma);
2277                    if self.consume_token(&Token::RParen) {
2278                        // allow a trailing comma, even though it's not in standard
2279                        break;
2280                    } else if !comma {
2281                        return self.expected("',' or ')'");
2282                    }
2283                }
2284                Some(CreateFunctionReturns::Table(values))
2285            } else {
2286                Some(CreateFunctionReturns::Value(self.parse_data_type()?))
2287            }
2288        } else {
2289            None
2290        };
2291
2292        let params = self.parse_create_function_body()?;
2293        let with_options = self.parse_options_with_preceding_keyword(Keyword::WITH)?;
2294        let with_options = with_options.try_into()?;
2295        Ok(Statement::CreateFunction {
2296            or_replace,
2297            temporary,
2298            if_not_exists,
2299            name,
2300            args,
2301            returns: return_type,
2302            params,
2303            with_options,
2304        })
2305    }
2306
2307    fn parse_create_aggregate(&mut self, or_replace: bool) -> ModalResult<Statement> {
2308        impl_parse_to!(if_not_exists => [Keyword::IF, Keyword::NOT, Keyword::EXISTS], self);
2309
2310        let name = self.parse_object_name()?;
2311        self.expect_token(&Token::LParen)?;
2312        let args = self.parse_comma_separated(Parser::parse_function_arg)?;
2313        self.expect_token(&Token::RParen)?;
2314
2315        self.expect_keyword(Keyword::RETURNS)?;
2316        let returns = self.parse_data_type()?;
2317
2318        let append_only = self.parse_keywords(&[Keyword::APPEND, Keyword::ONLY]);
2319        let params = self.parse_create_function_body()?;
2320
2321        Ok(Statement::CreateAggregate {
2322            or_replace,
2323            if_not_exists,
2324            name,
2325            args,
2326            returns,
2327            append_only,
2328            params,
2329        })
2330    }
2331
2332    pub fn parse_declare(&mut self) -> ModalResult<Statement> {
2333        Ok(Statement::DeclareCursor {
2334            stmt: DeclareCursorStatement::parse_to(self)?,
2335        })
2336    }
2337
2338    pub fn parse_fetch_cursor(&mut self) -> ModalResult<Statement> {
2339        Ok(Statement::FetchCursor {
2340            stmt: FetchCursorStatement::parse_to(self)?,
2341        })
2342    }
2343
2344    pub fn parse_close_cursor(&mut self) -> ModalResult<Statement> {
2345        Ok(Statement::CloseCursor {
2346            stmt: CloseCursorStatement::parse_to(self)?,
2347        })
2348    }
2349
2350    fn parse_table_column_def(&mut self) -> ModalResult<TableColumnDef> {
2351        Ok(TableColumnDef {
2352            name: self.parse_identifier_non_reserved()?,
2353            data_type: self.parse_data_type()?,
2354        })
2355    }
2356
2357    fn parse_function_arg(&mut self) -> ModalResult<OperateFunctionArg> {
2358        let mode = if self.parse_keyword(Keyword::IN) {
2359            Some(ArgMode::In)
2360        } else if self.parse_keyword(Keyword::OUT) {
2361            Some(ArgMode::Out)
2362        } else if self.parse_keyword(Keyword::INOUT) {
2363            Some(ArgMode::InOut)
2364        } else {
2365            None
2366        };
2367
2368        // parse: [ argname ] argtype
2369        let mut name = None;
2370        let mut data_type = self.parse_data_type()?;
2371        if let DataType::Custom(n) = &data_type
2372            && !matches!(self.peek_token().token, Token::Comma | Token::RParen)
2373        {
2374            // the first token is actually a name
2375            name = Some(n.0[0].clone());
2376            data_type = self.parse_data_type()?;
2377        }
2378
2379        let default_expr = if self.parse_keyword(Keyword::DEFAULT) || self.consume_token(&Token::Eq)
2380        {
2381            Some(self.parse_expr()?)
2382        } else {
2383            None
2384        };
2385        Ok(OperateFunctionArg {
2386            mode,
2387            name,
2388            data_type,
2389            default_expr,
2390        })
2391    }
2392
2393    fn parse_create_function_body(&mut self) -> ModalResult<CreateFunctionBody> {
2394        let mut body = CreateFunctionBody::default();
2395        loop {
2396            fn ensure_not_set<T>(field: &Option<T>, name: &str) -> ModalResult<()> {
2397                if field.is_some() {
2398                    parser_err!("{name} specified more than once");
2399                }
2400                Ok(())
2401            }
2402            if self.parse_keyword(Keyword::AS) {
2403                ensure_not_set(&body.as_, "AS")?;
2404                body.as_ = Some(self.parse_function_definition()?);
2405            } else if self.parse_keyword(Keyword::LANGUAGE) {
2406                ensure_not_set(&body.language, "LANGUAGE")?;
2407                body.language = Some(self.parse_identifier()?);
2408            } else if self.parse_keyword(Keyword::RUNTIME) {
2409                ensure_not_set(&body.runtime, "RUNTIME")?;
2410                body.runtime = Some(self.parse_identifier()?);
2411            } else if self.parse_keyword(Keyword::IMMUTABLE) {
2412                ensure_not_set(&body.behavior, "IMMUTABLE | STABLE | VOLATILE")?;
2413                body.behavior = Some(FunctionBehavior::Immutable);
2414            } else if self.parse_keyword(Keyword::STABLE) {
2415                ensure_not_set(&body.behavior, "IMMUTABLE | STABLE | VOLATILE")?;
2416                body.behavior = Some(FunctionBehavior::Stable);
2417            } else if self.parse_keyword(Keyword::VOLATILE) {
2418                ensure_not_set(&body.behavior, "IMMUTABLE | STABLE | VOLATILE")?;
2419                body.behavior = Some(FunctionBehavior::Volatile);
2420            } else if self.parse_keyword(Keyword::RETURN) {
2421                ensure_not_set(&body.return_, "RETURN")?;
2422                body.return_ = Some(self.parse_expr()?);
2423            } else if self.parse_keyword(Keyword::USING) {
2424                ensure_not_set(&body.using, "USING")?;
2425                body.using = Some(self.parse_create_function_using()?);
2426            } else {
2427                return Ok(body);
2428            }
2429        }
2430    }
2431
2432    fn parse_create_function_using(&mut self) -> ModalResult<CreateFunctionUsing> {
2433        let keyword = self.expect_one_of_keywords(&[Keyword::LINK, Keyword::BASE64])?;
2434
2435        match keyword {
2436            Keyword::LINK => {
2437                let uri = self.parse_literal_string()?;
2438                Ok(CreateFunctionUsing::Link(uri))
2439            }
2440            Keyword::BASE64 => {
2441                let base64 = self.parse_literal_string()?;
2442                Ok(CreateFunctionUsing::Base64(base64))
2443            }
2444            _ => unreachable!("{}", keyword),
2445        }
2446    }
2447
2448    // CREATE USER name [ [ WITH ] option [ ... ] ]
2449    // where option can be:
2450    //       SUPERUSER | NOSUPERUSER
2451    //     | CREATEDB | NOCREATEDB
2452    //     | CREATEUSER | NOCREATEUSER
2453    //     | LOGIN | NOLOGIN
2454    //     | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | OAUTH
2455    fn parse_create_user(&mut self) -> ModalResult<Statement> {
2456        Ok(Statement::CreateUser(CreateUserStatement::parse_to(self)?))
2457    }
2458
2459    fn parse_create_secret(&mut self) -> ModalResult<Statement> {
2460        Ok(Statement::CreateSecret {
2461            stmt: CreateSecretStatement::parse_to(self)?,
2462        })
2463    }
2464
2465    pub fn parse_with_properties(&mut self) -> ModalResult<Vec<SqlOption>> {
2466        self.parse_options_with_preceding_keyword(Keyword::WITH)
2467    }
2468
2469    pub fn parse_discard(&mut self) -> ModalResult<Statement> {
2470        self.expect_keyword(Keyword::ALL)?;
2471        Ok(Statement::Discard(DiscardType::All))
2472    }
2473
2474    pub fn parse_drop(&mut self) -> ModalResult<Statement> {
2475        if self.parse_keyword(Keyword::FUNCTION) {
2476            return self.parse_drop_function();
2477        } else if self.parse_keyword(Keyword::AGGREGATE) {
2478            return self.parse_drop_aggregate();
2479        }
2480        Ok(Statement::Drop(DropStatement::parse_to(self)?))
2481    }
2482
2483    /// ```sql
2484    /// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
2485    /// [ CASCADE | RESTRICT ]
2486    /// ```
2487    fn parse_drop_function(&mut self) -> ModalResult<Statement> {
2488        let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
2489        let func_desc = self.parse_comma_separated(Parser::parse_function_desc)?;
2490        let option = match self.parse_one_of_keywords(&[Keyword::CASCADE, Keyword::RESTRICT]) {
2491            Some(Keyword::CASCADE) => Some(ReferentialAction::Cascade),
2492            Some(Keyword::RESTRICT) => Some(ReferentialAction::Restrict),
2493            _ => None,
2494        };
2495        Ok(Statement::DropFunction {
2496            if_exists,
2497            func_desc,
2498            option,
2499        })
2500    }
2501
2502    /// ```sql
2503    /// DROP AGGREGATE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
2504    /// [ CASCADE | RESTRICT ]
2505    /// ```
2506    fn parse_drop_aggregate(&mut self) -> ModalResult<Statement> {
2507        let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
2508        let func_desc = self.parse_comma_separated(Parser::parse_function_desc)?;
2509        let option = match self.parse_one_of_keywords(&[Keyword::CASCADE, Keyword::RESTRICT]) {
2510            Some(Keyword::CASCADE) => Some(ReferentialAction::Cascade),
2511            Some(Keyword::RESTRICT) => Some(ReferentialAction::Restrict),
2512            _ => None,
2513        };
2514        Ok(Statement::DropAggregate {
2515            if_exists,
2516            func_desc,
2517            option,
2518        })
2519    }
2520
2521    fn parse_function_desc(&mut self) -> ModalResult<FunctionDesc> {
2522        let name = self.parse_object_name()?;
2523
2524        let args = if self.consume_token(&Token::LParen) {
2525            if self.consume_token(&Token::RParen) {
2526                Some(vec![])
2527            } else {
2528                let args = self.parse_comma_separated(Parser::parse_function_arg)?;
2529                self.expect_token(&Token::RParen)?;
2530                Some(args)
2531            }
2532        } else {
2533            None
2534        };
2535
2536        Ok(FunctionDesc { name, args })
2537    }
2538
2539    pub fn parse_create_index(&mut self, unique: bool) -> ModalResult<Statement> {
2540        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2541        let index_name = self.parse_object_name()?;
2542        self.expect_keyword(Keyword::ON)?;
2543        let table_name = self.parse_object_name()?;
2544        let method = if self.parse_keyword(Keyword::USING) {
2545            let method = self.parse_identifier()?;
2546            Some(method)
2547        } else {
2548            None
2549        };
2550        self.expect_token(&Token::LParen)?;
2551        let columns = self.parse_comma_separated(Parser::parse_order_by_expr)?;
2552        self.expect_token(&Token::RParen)?;
2553        let mut include = vec![];
2554        if self.parse_keyword(Keyword::INCLUDE) {
2555            self.expect_token(&Token::LParen)?;
2556            include = self.parse_comma_separated(Parser::parse_identifier_non_reserved)?;
2557            self.expect_token(&Token::RParen)?;
2558        }
2559        let mut distributed_by = vec![];
2560        if self.parse_keywords(&[Keyword::DISTRIBUTED, Keyword::BY]) {
2561            self.expect_token(&Token::LParen)?;
2562            distributed_by = self.parse_comma_separated(Parser::parse_expr)?;
2563            self.expect_token(&Token::RParen)?;
2564        }
2565        let with_properties = WithProperties(self.parse_with_properties()?);
2566
2567        Ok(Statement::CreateIndex {
2568            name: index_name,
2569            table_name,
2570            method,
2571            columns,
2572            include,
2573            distributed_by,
2574            unique,
2575            if_not_exists,
2576            with_properties,
2577        })
2578    }
2579
2580    pub fn parse_with_version_columns(&mut self) -> ModalResult<Vec<Ident>> {
2581        if self.parse_keywords(&[Keyword::WITH, Keyword::VERSION, Keyword::COLUMN]) {
2582            self.expect_token(&Token::LParen)?;
2583            let columns =
2584                self.parse_comma_separated(|parser| parser.parse_identifier_non_reserved())?;
2585            self.expect_token(&Token::RParen)?;
2586            Ok(columns)
2587        } else {
2588            Ok(Vec::new())
2589        }
2590    }
2591
2592    pub fn parse_on_conflict(&mut self) -> ModalResult<Option<OnConflict>> {
2593        if self.parse_keywords(&[Keyword::ON, Keyword::CONFLICT]) {
2594            self.parse_handle_conflict_behavior()
2595        } else {
2596            Ok(None)
2597        }
2598    }
2599
2600    pub fn parse_create_table(
2601        &mut self,
2602        or_replace: bool,
2603        temporary: bool,
2604    ) -> ModalResult<Statement> {
2605        let if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
2606        let table_name = self.parse_object_name()?;
2607        // parse optional column list (schema) and watermarks on source.
2608        let (columns, constraints, source_watermarks, wildcard_idx) =
2609            self.parse_columns_with_watermark()?;
2610
2611        let append_only = if self.parse_keyword(Keyword::APPEND) {
2612            self.expect_keyword(Keyword::ONLY)?;
2613            true
2614        } else {
2615            false
2616        };
2617
2618        let on_conflict = self.parse_on_conflict()?;
2619
2620        let with_version_columns = self.parse_with_version_columns()?;
2621        let include_options = self.parse_include_options()?;
2622
2623        // PostgreSQL supports `WITH ( options )`, before `AS`
2624        let with_options = self.parse_with_properties()?;
2625
2626        let option = with_options
2627            .iter()
2628            .find(|&opt| opt.name.real_value() == UPSTREAM_SOURCE_KEY);
2629        let connector = option.map(|opt| opt.value.to_string());
2630        let contain_webhook =
2631            connector.is_some() && connector.as_ref().unwrap().contains(WEBHOOK_CONNECTOR);
2632
2633        // webhook connector does not require row format
2634        let format_encode = if let Some(connector) = connector
2635            && !contain_webhook
2636        {
2637            Some(self.parse_format_encode_with_connector(&connector, false)?)
2638        } else {
2639            None // Table is NOT created with an external connector.
2640        };
2641        // Parse optional `AS ( query )`
2642        let query = if self.parse_keyword(Keyword::AS) {
2643            if !source_watermarks.is_empty() {
2644                parser_err!("Watermarks can't be defined on table created by CREATE TABLE AS");
2645            }
2646            Some(Box::new(self.parse_query()?))
2647        } else {
2648            None
2649        };
2650
2651        let cdc_table_info = if self.parse_keyword(Keyword::FROM) {
2652            let source_name = self.parse_object_name()?;
2653            self.expect_keyword(Keyword::TABLE)?;
2654            let external_table_name = self.parse_literal_string()?;
2655            Some(CdcTableInfo {
2656                source_name,
2657                external_table_name,
2658            })
2659        } else {
2660            None
2661        };
2662
2663        let webhook_wait_for_persistence = with_options
2664            .iter()
2665            .find(|&opt| opt.name.real_value() == WEBHOOK_WAIT_FOR_PERSISTENCE)
2666            .map(|opt| opt.value.to_string().eq_ignore_ascii_case("true"))
2667            .unwrap_or(true);
2668        let webhook_is_batched = with_options
2669            .iter()
2670            .find(|&opt| opt.name.real_value() == WEBHOOK_IS_BATCHED)
2671            .map(|opt| opt.value.to_string().eq_ignore_ascii_case("true"))
2672            .unwrap_or(false);
2673
2674        let webhook_info = if self.parse_keyword(Keyword::VALIDATE) {
2675            if !contain_webhook {
2676                parser_err!("VALIDATE is only supported for tables created with webhook source");
2677            }
2678
2679            let secret_ref = if self.parse_keyword(Keyword::SECRET) {
2680                let secret_ref = self.parse_secret_ref()?;
2681                if secret_ref.ref_as == SecretRefAsType::File {
2682                    parser_err!("Secret for SECURE_COMPARE() does not support AS FILE");
2683                };
2684                Some(secret_ref)
2685            } else {
2686                None
2687            };
2688
2689            self.expect_keyword(Keyword::AS)?;
2690            let signature_expr = self.parse_function()?;
2691
2692            Some(WebhookSourceInfo {
2693                secret_ref,
2694                signature_expr: Some(signature_expr),
2695                wait_for_persistence: webhook_wait_for_persistence,
2696                is_batched: webhook_is_batched,
2697            })
2698        } else if contain_webhook {
2699            Some(WebhookSourceInfo {
2700                secret_ref: None,
2701                signature_expr: None,
2702                wait_for_persistence: webhook_wait_for_persistence,
2703                is_batched: webhook_is_batched,
2704            })
2705        } else {
2706            None
2707        };
2708
2709        let engine = if self.parse_keyword(Keyword::ENGINE) {
2710            self.expect_token(&Token::Eq)?;
2711            let engine_name = self.parse_object_name()?;
2712            if "iceberg".eq_ignore_ascii_case(&engine_name.real_value()) {
2713                Engine::Iceberg
2714            } else if "hummock".eq_ignore_ascii_case(&engine_name.real_value()) {
2715                Engine::Hummock
2716            } else {
2717                parser_err!("Unsupported engine: {}", engine_name);
2718            }
2719        } else {
2720            Engine::Hummock
2721        };
2722
2723        Ok(Statement::CreateTable {
2724            name: table_name,
2725            temporary,
2726            columns,
2727            wildcard_idx,
2728            constraints,
2729            with_options,
2730            or_replace,
2731            if_not_exists,
2732            format_encode,
2733            source_watermarks,
2734            append_only,
2735            on_conflict,
2736            with_version_columns,
2737            query,
2738            cdc_table_info,
2739            include_column_options: include_options,
2740            webhook_info,
2741            engine,
2742        })
2743    }
2744
2745    pub fn parse_include_options(&mut self) -> ModalResult<IncludeOption> {
2746        let mut options = vec![];
2747        while self.parse_keyword(Keyword::INCLUDE) {
2748            let column_type = self.parse_identifier()?;
2749
2750            let mut column_inner_field = None;
2751            let mut header_inner_expect_type = None;
2752            if let Token::SingleQuotedString(inner_field) = self.peek_token().token {
2753                self.next_token();
2754                column_inner_field = Some(inner_field);
2755
2756                // `verify` rejects `DataType::Custom` so that a following `INCLUDE` (or even `WITH`)
2757                // will not be misrecognized as a DataType.
2758                //
2759                // For example, the following look structurally the same because `INCLUDE` is not a
2760                // reserved keyword. (`AS` is reserved.)
2761                // * `INCLUDE header 'foo' varchar`
2762                // * `INCLUDE header 'foo' INCLUDE`
2763                //
2764                // To be honest `bytea` shall be a `DataType::Custom` rather than a keyword, and the
2765                // logic here shall be:
2766                // ```
2767                // match dt {
2768                //     DataType::Custom(name) => allowed.contains(name.real_value()),
2769                //     _ => true,
2770                // }
2771                // ```
2772                // An allowlist is better than a denylist, as the following token may be other than
2773                // `INCLUDE` or `WITH` in the future.
2774                //
2775                // If this sounds too complicated - it means we should have designed this extension
2776                // syntax differently to make ambiguity handling easier.
2777                header_inner_expect_type =
2778                    opt(parser_v2::data_type.verify(|dt| !matches!(dt, DataType::Custom(_))))
2779                        .parse_next(self)?;
2780            }
2781
2782            let mut column_alias = None;
2783            if self.parse_keyword(Keyword::AS) {
2784                column_alias = Some(self.parse_identifier()?);
2785            }
2786
2787            options.push(IncludeOptionItem {
2788                column_type,
2789                inner_field: column_inner_field,
2790                column_alias,
2791                header_inner_expect_type,
2792            });
2793
2794            // tolerate previous bug #18800 of displaying with comma separation
2795            let _ = self.consume_token(&Token::Comma);
2796        }
2797        Ok(options)
2798    }
2799
2800    pub fn parse_columns_with_watermark(&mut self) -> ModalResult<ColumnsDefTuple> {
2801        let mut columns = vec![];
2802        let mut constraints = vec![];
2803        let mut watermarks = vec![];
2804        let mut wildcard_idx = None;
2805        if !self.consume_token(&Token::LParen) || self.consume_token(&Token::RParen) {
2806            return Ok((columns, constraints, watermarks, wildcard_idx));
2807        }
2808
2809        loop {
2810            if self.consume_token(&Token::Mul) {
2811                if wildcard_idx.is_none() {
2812                    wildcard_idx = Some(columns.len());
2813                } else {
2814                    parser_err!("At most 1 wildcard is allowed in source definition");
2815                }
2816            } else if let Some(constraint) = self.parse_optional_table_constraint()? {
2817                constraints.push(constraint);
2818            } else if let Some(watermark) = self.parse_optional_watermark()? {
2819                watermarks.push(watermark);
2820                if watermarks.len() > 1 {
2821                    // TODO(yuhao): allow multiple watermark on source.
2822                    parser_err!("Only 1 watermark is allowed to be defined on source.");
2823                }
2824            } else if let Token::Word(_) = self.peek_token().token {
2825                columns.push(self.parse_column_def()?);
2826            } else {
2827                return self.expected("column name or constraint definition");
2828            }
2829            let comma = self.consume_token(&Token::Comma);
2830            if self.consume_token(&Token::RParen) {
2831                // allow a trailing comma, even though it's not in standard
2832                break;
2833            } else if !comma {
2834                return self.expected("',' or ')' after column definition");
2835            }
2836        }
2837
2838        Ok((columns, constraints, watermarks, wildcard_idx))
2839    }
2840
2841    fn parse_column_def(&mut self) -> ModalResult<ColumnDef> {
2842        let name = self.parse_identifier_non_reserved()?;
2843        let data_type = if let Token::Word(_) = self.peek_token().token {
2844            Some(self.parse_data_type()?)
2845        } else {
2846            None
2847        };
2848
2849        let collation = if self.parse_keyword(Keyword::COLLATE) {
2850            Some(self.parse_object_name()?)
2851        } else {
2852            None
2853        };
2854        let mut options = vec![];
2855        loop {
2856            if self.parse_keyword(Keyword::CONSTRAINT) {
2857                let name = Some(self.parse_identifier_non_reserved()?);
2858                if let Some(option) = self.parse_optional_column_option()? {
2859                    options.push(ColumnOptionDef { name, option });
2860                } else {
2861                    return self.expected("constraint details after CONSTRAINT <name>");
2862                }
2863            } else if let Some(option) = self.parse_optional_column_option()? {
2864                options.push(ColumnOptionDef { name: None, option });
2865            } else {
2866                break;
2867            };
2868        }
2869        Ok(ColumnDef {
2870            name,
2871            data_type,
2872            collation,
2873            options,
2874        })
2875    }
2876
2877    pub fn parse_optional_column_option(&mut self) -> ModalResult<Option<ColumnOption>> {
2878        if self.parse_keywords(&[Keyword::NOT, Keyword::NULL]) {
2879            Ok(Some(ColumnOption::NotNull))
2880        } else if self.parse_keyword(Keyword::NULL) {
2881            Ok(Some(ColumnOption::Null))
2882        } else if self.parse_keyword(Keyword::DEFAULT) {
2883            if self.parse_keyword(Keyword::INTERNAL) {
2884                Ok(Some(ColumnOption::DefaultValueInternal {
2885                    // Placeholder. Will fill during definition purification for schema change.
2886                    persisted: Default::default(),
2887                    expr: None,
2888                }))
2889            } else {
2890                Ok(Some(ColumnOption::DefaultValue(self.parse_expr()?)))
2891            }
2892        } else if self.parse_keywords(&[Keyword::PRIMARY, Keyword::KEY]) {
2893            Ok(Some(ColumnOption::Unique { is_primary: true }))
2894        } else if self.parse_keyword(Keyword::UNIQUE) {
2895            Ok(Some(ColumnOption::Unique { is_primary: false }))
2896        } else if self.parse_keyword(Keyword::REFERENCES) {
2897            let foreign_table = self.parse_object_name()?;
2898            // PostgreSQL allows omitting the column list and
2899            // uses the primary key column of the foreign table by default
2900            let referred_columns = self.parse_parenthesized_column_list(Optional)?;
2901            let mut on_delete = None;
2902            let mut on_update = None;
2903            loop {
2904                if on_delete.is_none() && self.parse_keywords(&[Keyword::ON, Keyword::DELETE]) {
2905                    on_delete = Some(self.parse_referential_action()?);
2906                } else if on_update.is_none()
2907                    && self.parse_keywords(&[Keyword::ON, Keyword::UPDATE])
2908                {
2909                    on_update = Some(self.parse_referential_action()?);
2910                } else {
2911                    break;
2912                }
2913            }
2914            Ok(Some(ColumnOption::ForeignKey {
2915                foreign_table,
2916                referred_columns,
2917                on_delete,
2918                on_update,
2919            }))
2920        } else if self.parse_keyword(Keyword::CHECK) {
2921            self.expect_token(&Token::LParen)?;
2922            let expr = self.parse_expr()?;
2923            self.expect_token(&Token::RParen)?;
2924            Ok(Some(ColumnOption::Check(expr)))
2925        } else if self.parse_keyword(Keyword::AS) {
2926            Ok(Some(ColumnOption::GeneratedColumns(self.parse_expr()?)))
2927        } else {
2928            Ok(None)
2929        }
2930    }
2931
2932    pub fn parse_handle_conflict_behavior(&mut self) -> ModalResult<Option<OnConflict>> {
2933        if self.parse_keyword(Keyword::OVERWRITE) {
2934            // compatible with v1.9 - v2.0
2935            Ok(Some(OnConflict::UpdateFull))
2936        } else if self.parse_keyword(Keyword::IGNORE) {
2937            // compatible with v1.9 - v2.0
2938            Ok(Some(OnConflict::Nothing))
2939        } else if self.parse_keywords(&[
2940            Keyword::DO,
2941            Keyword::UPDATE,
2942            Keyword::IF,
2943            Keyword::NOT,
2944            Keyword::NULL,
2945        ]) {
2946            Ok(Some(OnConflict::UpdateIfNotNull))
2947        } else if self.parse_keywords(&[Keyword::DO, Keyword::UPDATE, Keyword::FULL]) {
2948            Ok(Some(OnConflict::UpdateFull))
2949        } else if self.parse_keywords(&[Keyword::DO, Keyword::NOTHING]) {
2950            Ok(Some(OnConflict::Nothing))
2951        } else {
2952            Ok(None)
2953        }
2954    }
2955
2956    pub fn parse_referential_action(&mut self) -> ModalResult<ReferentialAction> {
2957        if self.parse_keyword(Keyword::RESTRICT) {
2958            Ok(ReferentialAction::Restrict)
2959        } else if self.parse_keyword(Keyword::CASCADE) {
2960            Ok(ReferentialAction::Cascade)
2961        } else if self.parse_keywords(&[Keyword::SET, Keyword::NULL]) {
2962            Ok(ReferentialAction::SetNull)
2963        } else if self.parse_keywords(&[Keyword::NO, Keyword::ACTION]) {
2964            Ok(ReferentialAction::NoAction)
2965        } else if self.parse_keywords(&[Keyword::SET, Keyword::DEFAULT]) {
2966            Ok(ReferentialAction::SetDefault)
2967        } else {
2968            self.expected("one of RESTRICT, CASCADE, SET NULL, NO ACTION or SET DEFAULT")
2969        }
2970    }
2971
2972    pub fn parse_optional_watermark(&mut self) -> ModalResult<Option<SourceWatermark>> {
2973        if self.parse_keyword(Keyword::WATERMARK) {
2974            self.expect_keyword(Keyword::FOR)?;
2975            let column = self.parse_identifier_non_reserved()?;
2976            self.expect_keyword(Keyword::AS)?;
2977            let expr = self.parse_expr()?;
2978            let with_ttl = self.parse_keywords(&[Keyword::WITH, Keyword::TTL]);
2979            Ok(Some(SourceWatermark {
2980                column,
2981                expr,
2982                with_ttl,
2983            }))
2984        } else {
2985            Ok(None)
2986        }
2987    }
2988
2989    pub fn parse_optional_table_constraint(&mut self) -> ModalResult<Option<TableConstraint>> {
2990        let name = if self.parse_keyword(Keyword::CONSTRAINT) {
2991            Some(self.parse_identifier_non_reserved()?)
2992        } else {
2993            None
2994        };
2995        let checkpoint = *self;
2996        let token = self.next_token();
2997        match token.token {
2998            Token::Word(w) if w.keyword == Keyword::PRIMARY || w.keyword == Keyword::UNIQUE => {
2999                let is_primary = w.keyword == Keyword::PRIMARY;
3000                if is_primary {
3001                    self.expect_keyword(Keyword::KEY)?;
3002                }
3003                let columns = self.parse_parenthesized_column_list(Mandatory)?;
3004                Ok(Some(TableConstraint::Unique {
3005                    name,
3006                    columns,
3007                    is_primary,
3008                }))
3009            }
3010            Token::Word(w) if w.keyword == Keyword::FOREIGN => {
3011                self.expect_keyword(Keyword::KEY)?;
3012                let columns = self.parse_parenthesized_column_list(Mandatory)?;
3013                self.expect_keyword(Keyword::REFERENCES)?;
3014                let foreign_table = self.parse_object_name()?;
3015                let referred_columns = self.parse_parenthesized_column_list(Mandatory)?;
3016                let mut on_delete = None;
3017                let mut on_update = None;
3018                loop {
3019                    if on_delete.is_none() && self.parse_keywords(&[Keyword::ON, Keyword::DELETE]) {
3020                        on_delete = Some(self.parse_referential_action()?);
3021                    } else if on_update.is_none()
3022                        && self.parse_keywords(&[Keyword::ON, Keyword::UPDATE])
3023                    {
3024                        on_update = Some(self.parse_referential_action()?);
3025                    } else {
3026                        break;
3027                    }
3028                }
3029                Ok(Some(TableConstraint::ForeignKey {
3030                    name,
3031                    columns,
3032                    foreign_table,
3033                    referred_columns,
3034                    on_delete,
3035                    on_update,
3036                }))
3037            }
3038            Token::Word(w) if w.keyword == Keyword::CHECK => {
3039                self.expect_token(&Token::LParen)?;
3040                let expr = Box::new(self.parse_expr()?);
3041                self.expect_token(&Token::RParen)?;
3042                Ok(Some(TableConstraint::Check { name, expr }))
3043            }
3044            _ => {
3045                *self = checkpoint;
3046                if name.is_some() {
3047                    self.expected("PRIMARY, UNIQUE, FOREIGN, or CHECK")
3048                } else {
3049                    Ok(None)
3050                }
3051            }
3052        }
3053    }
3054
3055    pub fn parse_options_with_preceding_keyword(
3056        &mut self,
3057        keyword: Keyword,
3058    ) -> ModalResult<Vec<SqlOption>> {
3059        if self.parse_keyword(keyword) {
3060            self.expect_token(&Token::LParen)?;
3061            self.parse_options_inner()
3062        } else {
3063            Ok(vec![])
3064        }
3065    }
3066
3067    pub fn parse_options(&mut self) -> ModalResult<Vec<SqlOption>> {
3068        if self.peek_token() == Token::LParen {
3069            self.next_token();
3070            self.parse_options_inner()
3071        } else {
3072            Ok(vec![])
3073        }
3074    }
3075
3076    // has parsed a LParen
3077    pub fn parse_options_inner(&mut self) -> ModalResult<Vec<SqlOption>> {
3078        let mut values = vec![];
3079        loop {
3080            values.push(Parser::parse_sql_option(self)?);
3081            let comma = self.consume_token(&Token::Comma);
3082            if self.consume_token(&Token::RParen) {
3083                // allow a trailing comma, even though it's not in standard
3084                break;
3085            } else if !comma {
3086                return self.expected("',' or ')' after option definition");
3087            }
3088        }
3089        Ok(values)
3090    }
3091
3092    pub fn parse_sql_option(&mut self) -> ModalResult<SqlOption> {
3093        const CONNECTION_REF_KEY: &str = "connection";
3094        const BACKFILL_ORDER: &str = "backfill_order";
3095
3096        let name = self.parse_object_name()?;
3097        self.expect_token(&Token::Eq)?;
3098        let value = {
3099            if name.real_value().eq_ignore_ascii_case(CONNECTION_REF_KEY) {
3100                let connection_name = self.parse_object_name()?;
3101                // tolerate previous buggy Display that outputs `connection = connection foo`
3102                let connection_name = match connection_name.0.as_slice() {
3103                    [ident] if ident.real_value() == CONNECTION_REF_KEY => {
3104                        self.parse_object_name()?
3105                    }
3106                    _ => connection_name,
3107                };
3108                SqlOptionValue::ConnectionRef(ConnectionRefValue { connection_name })
3109            } else if name.real_value().eq_ignore_ascii_case(BACKFILL_ORDER) {
3110                let order = self.parse_backfill_order_strategy()?;
3111                SqlOptionValue::BackfillOrder(order)
3112            } else {
3113                self.parse_value_and_obj_ref::<false>()?
3114            }
3115        };
3116        Ok(SqlOption { name, value })
3117    }
3118
3119    // <config_param> { TO | = } { <value> | DEFAULT }
3120    // <config_param> is not a keyword, but an identifier
3121    pub fn parse_config_param(&mut self) -> ModalResult<ConfigParam> {
3122        self.parse_config_param_inner(Self::parse_set_variable)
3123    }
3124
3125    fn parse_config_param_inner(
3126        &mut self,
3127        parse_value: fn(&mut Self) -> ModalResult<SetVariableValue>,
3128    ) -> ModalResult<ConfigParam> {
3129        let param = self.parse_identifier()?;
3130        if !self.consume_token(&Token::Eq) && !self.parse_keyword(Keyword::TO) {
3131            return self.expected("'=' or 'TO' after config parameter");
3132        }
3133        let value = parse_value(self)?;
3134        Ok(ConfigParam { param, value })
3135    }
3136
3137    /// Parse a single-value config param.
3138    ///
3139    /// This differs from [`Self::parse_config_param`] in that it does **not** allow a comma-separated
3140    /// list on the RHS, so it can be safely used in constructs where comma separates multiple
3141    /// assignments (e.g. `... SET a = 1, b = 2`).
3142    fn parse_config_param_no_list(&mut self) -> ModalResult<ConfigParam> {
3143        self.parse_config_param_inner(Self::parse_set_variable_no_list)
3144    }
3145
3146    fn parse_set_variable_no_list(&mut self) -> ModalResult<SetVariableValue> {
3147        alt((
3148            Keyword::DEFAULT.value(SetVariableValue::Default),
3149            alt((
3150                Self::ensure_parse_value.map(SetVariableValueSingle::Literal),
3151                |parser: &mut Self| {
3152                    let checkpoint = *parser;
3153                    let ident = parser.parse_identifier()?;
3154                    if ident.value == "default" {
3155                        *parser = checkpoint;
3156                        return parser.expected("parameter list value").map_err(|e| e.cut());
3157                    }
3158                    Ok(SetVariableValueSingle::Ident(ident))
3159                },
3160                fail.expect("parameter value"),
3161            ))
3162            .map(|single: SetVariableValueSingle| SetVariableValue::Single(single)),
3163        ))
3164        .parse_next(self)
3165    }
3166
3167    pub fn parse_since(&mut self) -> ModalResult<Since> {
3168        if self.parse_keyword(Keyword::SINCE) {
3169            let checkpoint = *self;
3170            let token = self.next_token();
3171            match token.token {
3172                Token::Word(w) => {
3173                    let ident = w.to_ident()?;
3174                    // Backward compatibility for now.
3175                    if ident.real_value() == "proctime" || ident.real_value() == "now" {
3176                        self.expect_token(&Token::LParen)?;
3177                        self.expect_token(&Token::RParen)?;
3178                        Ok(Since::ProcessTime)
3179                    } else if ident.real_value() == "begin" {
3180                        self.expect_token(&Token::LParen)?;
3181                        self.expect_token(&Token::RParen)?;
3182                        Ok(Since::Begin)
3183                    } else {
3184                        parser_err!(
3185                            "Expected proctime(), begin() or now(), found: {}",
3186                            ident.real_value()
3187                        )
3188                    }
3189                }
3190                Token::Number(s) => {
3191                    let num = s
3192                        .parse::<u64>()
3193                        .map_err(|e| StrError(format!("Could not parse '{}' as u64: {}", s, e)))?;
3194                    Ok(Since::TimestampMsNum(num))
3195                }
3196                _ => self.expected_at(checkpoint, "proctime(), begin() , now(), Number"),
3197            }
3198        } else if self.parse_word("FULL") {
3199            Ok(Since::Full)
3200        } else {
3201            Ok(Since::ProcessTime)
3202        }
3203    }
3204
3205    pub fn parse_emit_mode(&mut self) -> ModalResult<Option<EmitMode>> {
3206        if self.parse_keyword(Keyword::EMIT) {
3207            match self.parse_one_of_keywords(&[Keyword::IMMEDIATELY, Keyword::ON]) {
3208                Some(Keyword::IMMEDIATELY) => Ok(Some(EmitMode::Immediately)),
3209                Some(Keyword::ON) => {
3210                    self.expect_keywords(&[Keyword::WINDOW, Keyword::CLOSE])?;
3211                    Ok(Some(EmitMode::OnWindowClose))
3212                }
3213                Some(_) => unreachable!(),
3214                None => self.expected("IMMEDIATELY or ON WINDOW CLOSE after EMIT"),
3215            }
3216        } else {
3217            Ok(None)
3218        }
3219    }
3220
3221    pub fn parse_alter(&mut self) -> ModalResult<Statement> {
3222        if self.parse_keyword(Keyword::DATABASE) {
3223            self.parse_alter_database()
3224        } else if self.parse_keyword(Keyword::SCHEMA) {
3225            self.parse_alter_schema()
3226        } else if self.parse_keyword(Keyword::TABLE) {
3227            self.parse_alter_table()
3228        } else if self.parse_keyword(Keyword::INDEX) {
3229            self.parse_alter_index()
3230        } else if self.parse_keyword(Keyword::VIEW) {
3231            self.parse_alter_view(false)
3232        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
3233            self.parse_alter_view(true)
3234        } else if self.parse_keyword(Keyword::SINK) {
3235            self.parse_alter_sink()
3236        } else if self.parse_keyword(Keyword::SOURCE) {
3237            self.parse_alter_source()
3238        } else if self.parse_keyword(Keyword::FUNCTION) {
3239            self.parse_alter_function()
3240        } else if self.parse_keyword(Keyword::CONNECTION) {
3241            self.parse_alter_connection()
3242        } else if self.parse_keyword(Keyword::USER) {
3243            self.parse_alter_user()
3244        } else if self.parse_keyword(Keyword::SYSTEM) {
3245            self.parse_alter_system()
3246        } else if self.parse_keyword(Keyword::SUBSCRIPTION) {
3247            self.parse_alter_subscription()
3248        } else if self.parse_keyword(Keyword::SECRET) {
3249            self.parse_alter_secret()
3250        } else if self.parse_word("FRAGMENT") {
3251            self.parse_alter_fragment()
3252        } else if self.parse_keyword(Keyword::COMPACTION) {
3253            self.parse_alter_compaction_group()
3254        } else if self.parse_keywords(&[Keyword::DEFAULT, Keyword::PRIVILEGES]) {
3255            self.parse_alter_default_privileges()
3256        } else {
3257            self.expected(
3258                "COMPACTION, DATABASE, FRAGMENT, SCHEMA, TABLE, INDEX, MATERIALIZED, VIEW, SINK, SUBSCRIPTION, SOURCE, FUNCTION, USER, SECRET or SYSTEM after ALTER"
3259            )
3260        }
3261    }
3262
3263    pub fn parse_alter_database(&mut self) -> ModalResult<Statement> {
3264        let database_name = self.parse_object_name()?;
3265        let operation = if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3266            let owner_name: Ident = self.parse_identifier()?;
3267            AlterDatabaseOperation::ChangeOwner {
3268                new_owner_name: owner_name,
3269            }
3270        } else if self.parse_keyword(Keyword::RENAME) {
3271            if self.parse_keyword(Keyword::TO) {
3272                let database_name = self.parse_object_name()?;
3273                AlterDatabaseOperation::RenameDatabase { database_name }
3274            } else {
3275                return self.expected("TO after RENAME");
3276            }
3277        } else if self.parse_keyword(Keyword::SET) {
3278            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3279                if self.expect_keyword(Keyword::TO).is_err()
3280                    && self.expect_token(&Token::Eq).is_err()
3281                {
3282                    return self.expected("TO or = after ALTER DATABASE SET RESOURCE_GROUP");
3283                }
3284                let value = self.parse_set_variable()?;
3285                if !self.parse_keyword(Keyword::DEFERRED) {
3286                    return self.expected("DEFERRED after ALTER DATABASE SET RESOURCE_GROUP");
3287                }
3288
3289                AlterDatabaseOperation::SetResourceGroup {
3290                    resource_group: Some(value),
3291                    deferred: true,
3292                }
3293            } else {
3294                // check will be delayed to frontend
3295                AlterDatabaseOperation::SetParam(self.parse_config_param()?)
3296            }
3297        } else if self.parse_keyword(Keyword::RESET) {
3298            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3299                if !self.parse_keyword(Keyword::DEFERRED) {
3300                    return self.expected("DEFERRED after ALTER DATABASE RESET RESOURCE_GROUP");
3301                }
3302
3303                AlterDatabaseOperation::SetResourceGroup {
3304                    resource_group: None,
3305                    deferred: true,
3306                }
3307            } else {
3308                return self.expected("RESOURCE_GROUP after RESET");
3309            }
3310        } else {
3311            return self.expected("RENAME, OWNER TO, SET, OR RESET after ALTER DATABASE");
3312        };
3313
3314        Ok(Statement::AlterDatabase {
3315            name: database_name,
3316            operation,
3317        })
3318    }
3319
3320    pub fn parse_alter_schema(&mut self) -> ModalResult<Statement> {
3321        let schema_name = self.parse_object_name()?;
3322        let operation = if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3323            let owner_name: Ident = self.parse_identifier()?;
3324            AlterSchemaOperation::ChangeOwner {
3325                new_owner_name: owner_name,
3326            }
3327        } else if self.parse_keyword(Keyword::RENAME) {
3328            self.expect_keyword(Keyword::TO)?;
3329            let schema_name = self.parse_object_name()?;
3330            AlterSchemaOperation::RenameSchema { schema_name }
3331        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3332            let target_schema = self.parse_object_name()?;
3333            AlterSchemaOperation::SwapRenameSchema { target_schema }
3334        } else {
3335            return self.expected("RENAME, OWNER TO, OR SWAP WITH after ALTER SCHEMA");
3336        };
3337
3338        Ok(Statement::AlterSchema {
3339            name: schema_name,
3340            operation,
3341        })
3342    }
3343
3344    pub fn parse_alter_user(&mut self) -> ModalResult<Statement> {
3345        Ok(Statement::AlterUser(AlterUserStatement::parse_to(self)?))
3346    }
3347
3348    pub fn parse_alter_table(&mut self) -> ModalResult<Statement> {
3349        let _ = self.parse_keyword(Keyword::ONLY);
3350        let table_name = self.parse_object_name()?;
3351        let operation = if self.parse_keyword(Keyword::ADD) {
3352            if let Some(constraint) = self.parse_optional_table_constraint()? {
3353                AlterTableOperation::AddConstraint(constraint)
3354            } else {
3355                let _ = self.parse_keyword(Keyword::COLUMN);
3356                let _if_not_exists =
3357                    self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
3358                let column_def = self.parse_column_def()?;
3359                AlterTableOperation::AddColumn { column_def }
3360            }
3361        } else if self.parse_keywords(&[Keyword::DROP, Keyword::CONNECTOR]) {
3362            AlterTableOperation::DropConnector
3363        } else if self.parse_keyword(Keyword::RENAME) {
3364            if self.parse_keyword(Keyword::CONSTRAINT) {
3365                let old_name = self.parse_identifier_non_reserved()?;
3366                self.expect_keyword(Keyword::TO)?;
3367                let new_name = self.parse_identifier_non_reserved()?;
3368                AlterTableOperation::RenameConstraint { old_name, new_name }
3369            } else if self.parse_keyword(Keyword::TO) {
3370                let table_name = self.parse_object_name()?;
3371                AlterTableOperation::RenameTable { table_name }
3372            } else {
3373                let _ = self.parse_keyword(Keyword::COLUMN);
3374                let old_column_name = self.parse_identifier_non_reserved()?;
3375                self.expect_keyword(Keyword::TO)?;
3376                let new_column_name = self.parse_identifier_non_reserved()?;
3377                AlterTableOperation::RenameColumn {
3378                    old_column_name,
3379                    new_column_name,
3380                }
3381            }
3382        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3383            let owner_name: Ident = self.parse_identifier()?;
3384            AlterTableOperation::ChangeOwner {
3385                new_owner_name: owner_name,
3386            }
3387        } else if self.parse_keyword(Keyword::SET) {
3388            if self.parse_keyword(Keyword::SCHEMA) {
3389                let schema_name = self.parse_object_name()?;
3390                AlterTableOperation::SetSchema {
3391                    new_schema_name: schema_name,
3392                }
3393            } else if self.parse_keyword(Keyword::PARALLELISM) {
3394                if self.expect_keyword(Keyword::TO).is_err()
3395                    && self.expect_token(&Token::Eq).is_err()
3396                {
3397                    return self.expected("TO or = after ALTER TABLE SET PARALLELISM");
3398                }
3399
3400                let value = self.parse_set_variable()?;
3401
3402                let deferred = self.parse_keyword(Keyword::DEFERRED);
3403
3404                AlterTableOperation::SetParallelism {
3405                    parallelism: value,
3406                    deferred,
3407                }
3408            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) {
3409                if self.expect_keyword(Keyword::TO).is_err()
3410                    && self.expect_token(&Token::Eq).is_err()
3411                {
3412                    return self.expected("TO or = after ALTER TABLE SET BACKFILL_PARALLELISM");
3413                }
3414
3415                let value = self.parse_set_variable()?;
3416
3417                let deferred = self.parse_keyword(Keyword::DEFERRED);
3418
3419                AlterTableOperation::SetBackfillParallelism {
3420                    parallelism: value,
3421                    deferred,
3422                }
3423            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3424                AlterTableOperation::AlterRateLimit(rate_limit)
3425            } else if self.parse_keyword(Keyword::CONFIG) {
3426                let entries = self.parse_options()?;
3427                AlterTableOperation::SetConfig { entries }
3428            } else {
3429                return self.expected(
3430                    "SCHEMA/PARALLELISM/BACKFILL_PARALLELISM/SOURCE_RATE_LIMIT/DML_RATE_LIMIT/CONFIG after SET",
3431                );
3432            }
3433        } else if self.parse_keyword(Keyword::RESET) {
3434            if self.parse_keyword(Keyword::CONFIG) {
3435                let keys = self.parse_parenthesized_object_name_list()?;
3436                AlterTableOperation::ResetConfig { keys }
3437            } else {
3438                return self.expected("CONFIG after RESET");
3439            }
3440        } else if self.parse_keyword(Keyword::DROP) {
3441            let _ = self.parse_keyword(Keyword::COLUMN);
3442            let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
3443            let column_name = self.parse_identifier_non_reserved()?;
3444            let cascade = self.parse_keyword(Keyword::CASCADE);
3445            AlterTableOperation::DropColumn {
3446                column_name,
3447                if_exists,
3448                cascade,
3449            }
3450        } else if self.parse_keyword(Keyword::ALTER) {
3451            // `WATERMARK` is non-reserved; require `FOR` so `ALTER <col>` on a
3452            // column named `watermark` still falls through to ALTER COLUMN.
3453            if self.parse_keywords(&[Keyword::WATERMARK, Keyword::FOR]) {
3454                let column_name = self.parse_identifier_non_reserved()?;
3455                self.expect_keyword(Keyword::AS)?;
3456                let expr = self.parse_expr()?;
3457                let with_ttl = self.parse_keywords(&[Keyword::WITH, Keyword::TTL]);
3458                return Ok(Statement::AlterTable {
3459                    name: table_name,
3460                    operation: AlterTableOperation::AlterWatermark {
3461                        column_name,
3462                        expr,
3463                        with_ttl,
3464                    },
3465                });
3466            }
3467            let _ = self.parse_keyword(Keyword::COLUMN);
3468            let column_name = self.parse_identifier_non_reserved()?;
3469
3470            let op = if self.parse_keywords(&[Keyword::SET, Keyword::NOT, Keyword::NULL]) {
3471                AlterColumnOperation::SetNotNull {}
3472            } else if self.parse_keywords(&[Keyword::DROP, Keyword::NOT, Keyword::NULL]) {
3473                AlterColumnOperation::DropNotNull {}
3474            } else if self.parse_keywords(&[Keyword::SET, Keyword::DEFAULT]) {
3475                AlterColumnOperation::SetDefault {
3476                    value: self.parse_expr()?,
3477                }
3478            } else if self.parse_keywords(&[Keyword::DROP, Keyword::DEFAULT]) {
3479                AlterColumnOperation::DropDefault {}
3480            } else if self.parse_keywords(&[Keyword::SET, Keyword::DATA, Keyword::TYPE])
3481                || (self.parse_keyword(Keyword::TYPE))
3482            {
3483                let data_type = self.parse_data_type()?;
3484                let using = if self.parse_keyword(Keyword::USING) {
3485                    Some(self.parse_expr()?)
3486                } else {
3487                    None
3488                };
3489                AlterColumnOperation::SetDataType { data_type, using }
3490            } else {
3491                return self
3492                    .expected("SET/DROP NOT NULL, SET DEFAULT, SET DATA TYPE after ALTER COLUMN");
3493            };
3494            AlterTableOperation::AlterColumn { column_name, op }
3495        } else if self.parse_keywords(&[Keyword::REFRESH, Keyword::SCHEMA]) {
3496            AlterTableOperation::RefreshSchema
3497        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3498            let target_table = self.parse_object_name()?;
3499            AlterTableOperation::SwapRenameTable { target_table }
3500        } else if self.parse_keyword(Keyword::CONNECTOR) {
3501            let with_options = self.parse_with_properties()?;
3502            AlterTableOperation::AlterConnectorProps {
3503                alter_props: with_options,
3504            }
3505        } else {
3506            return self.expected(
3507                "ADD or RENAME or OWNER TO or SET or RESET or DROP or SWAP or CONNECTOR after ALTER TABLE",
3508            );
3509        };
3510        Ok(Statement::AlterTable {
3511            name: table_name,
3512            operation,
3513        })
3514    }
3515
3516    fn parse_rate_limit_value(&mut self) -> ModalResult<i32> {
3517        if self.expect_keyword(Keyword::TO).is_err() && self.expect_token(&Token::Eq).is_err() {
3518            return self.expected("TO or = after rate limit");
3519        }
3520        if self.parse_keyword(Keyword::DEFAULT) {
3521            return Ok(-1);
3522        }
3523        let s = self.parse_number_value()?;
3524        if let Ok(n) = s.parse::<i32>() {
3525            Ok(n)
3526        } else {
3527            self.expected("number or DEFAULT")
3528        }
3529    }
3530
3531    pub fn parse_alter_rate_limit(&mut self) -> ModalResult<Option<AlterRateLimit>> {
3532        for rate_limit_type in [
3533            AlterRateLimitType::Source,
3534            AlterRateLimitType::Backfill,
3535            AlterRateLimitType::Dml,
3536            AlterRateLimitType::Sink,
3537        ] {
3538            if self.parse_word(rate_limit_type.as_str()) {
3539                let rate_limit = self.parse_rate_limit_value()?;
3540                return Ok(Some(AlterRateLimit {
3541                    rate_limit_type,
3542                    rate_limit,
3543                }));
3544            }
3545        }
3546        Ok(None)
3547    }
3548
3549    pub fn parse_alter_index(&mut self) -> ModalResult<Statement> {
3550        let index_name = self.parse_object_name()?;
3551        let operation = if self.parse_keyword(Keyword::RENAME) {
3552            if self.parse_keyword(Keyword::TO) {
3553                let index_name = self.parse_object_name()?;
3554                AlterIndexOperation::RenameIndex { index_name }
3555            } else {
3556                return self.expected("TO after RENAME");
3557            }
3558        } else if self.parse_keyword(Keyword::SET) {
3559            if self.parse_keyword(Keyword::PARALLELISM) {
3560                if self.expect_keyword(Keyword::TO).is_err()
3561                    && self.expect_token(&Token::Eq).is_err()
3562                {
3563                    return self.expected("TO or = after ALTER INDEX SET PARALLELISM");
3564                }
3565
3566                let value = self.parse_set_variable()?;
3567
3568                let deferred = self.parse_keyword(Keyword::DEFERRED);
3569
3570                AlterIndexOperation::SetParallelism {
3571                    parallelism: value,
3572                    deferred,
3573                }
3574            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) {
3575                if self.expect_keyword(Keyword::TO).is_err()
3576                    && self.expect_token(&Token::Eq).is_err()
3577                {
3578                    return self.expected("TO or = after ALTER INDEX SET BACKFILL_PARALLELISM");
3579                }
3580
3581                let value = self.parse_set_variable()?;
3582
3583                let deferred = self.parse_keyword(Keyword::DEFERRED);
3584
3585                AlterIndexOperation::SetBackfillParallelism {
3586                    parallelism: value,
3587                    deferred,
3588                }
3589            } else if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3590                if self.expect_keyword(Keyword::TO).is_err()
3591                    && self.expect_token(&Token::Eq).is_err()
3592                {
3593                    return self.expected("TO or = after ALTER INDEX SET RESOURCE_GROUP");
3594                }
3595                let value = self.parse_set_variable()?;
3596                let deferred = self.parse_keyword(Keyword::DEFERRED);
3597
3598                AlterIndexOperation::SetResourceGroup {
3599                    resource_group: Some(value),
3600                    deferred,
3601                }
3602            } else if self.parse_keyword(Keyword::CONFIG) {
3603                let entries = self.parse_options()?;
3604                AlterIndexOperation::SetConfig { entries }
3605            } else {
3606                return self.expected(
3607                    "PARALLELISM/BACKFILL_PARALLELISM/RESOURCE_GROUP or CONFIG after SET",
3608                );
3609            }
3610        } else if self.parse_keyword(Keyword::RESET) {
3611            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3612                let deferred = self.parse_keyword(Keyword::DEFERRED);
3613
3614                AlterIndexOperation::SetResourceGroup {
3615                    resource_group: None,
3616                    deferred,
3617                }
3618            } else if self.parse_keyword(Keyword::CONFIG) {
3619                let keys = self.parse_parenthesized_object_name_list()?;
3620                AlterIndexOperation::ResetConfig { keys }
3621            } else {
3622                return self.expected("RESOURCE_GROUP or CONFIG after RESET");
3623            }
3624        } else {
3625            return self.expected("RENAME, SET, or RESET after ALTER INDEX");
3626        };
3627
3628        Ok(Statement::AlterIndex {
3629            name: index_name,
3630            operation,
3631        })
3632    }
3633
3634    pub fn parse_alter_view(&mut self, materialized: bool) -> ModalResult<Statement> {
3635        let view_name = self.parse_object_name()?;
3636        let operation = if self.parse_keyword(Keyword::AS) {
3637            let query = Box::new(self.parse_query()?);
3638            AlterViewOperation::AsQuery { query }
3639        } else if self.parse_keyword(Keyword::RENAME) {
3640            if self.parse_keyword(Keyword::TO) {
3641                let view_name = self.parse_object_name()?;
3642                AlterViewOperation::RenameView { view_name }
3643            } else {
3644                return self.expected("TO after RENAME");
3645            }
3646        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3647            let owner_name: Ident = self.parse_identifier()?;
3648            AlterViewOperation::ChangeOwner {
3649                new_owner_name: owner_name,
3650            }
3651        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3652            let target_view = self.parse_object_name()?;
3653            AlterViewOperation::SwapRenameView { target_view }
3654        } else if self.parse_keyword(Keyword::SET) {
3655            if self.parse_keyword(Keyword::SCHEMA) {
3656                let schema_name = self.parse_object_name()?;
3657                AlterViewOperation::SetSchema {
3658                    new_schema_name: schema_name,
3659                }
3660            } else if self.parse_word("STREAMING_ENABLE_UNALIGNED_JOIN") {
3661                if self.expect_keyword(Keyword::TO).is_err()
3662                    && self.expect_token(&Token::Eq).is_err()
3663                {
3664                    return self
3665                        .expected("TO or = after ALTER TABLE SET STREAMING_ENABLE_UNALIGNED_JOIN");
3666                }
3667                let value = self.parse_boolean()?;
3668                AlterViewOperation::SetStreamingEnableUnalignedJoin { enable: value }
3669            } else if self.parse_keyword(Keyword::PARALLELISM) && materialized {
3670                if self.expect_keyword(Keyword::TO).is_err()
3671                    && self.expect_token(&Token::Eq).is_err()
3672                {
3673                    return self.expected("TO or = after ALTER MATERIALIZED VIEW SET PARALLELISM");
3674                }
3675
3676                let value = self.parse_set_variable()?;
3677
3678                let deferred = self.parse_keyword(Keyword::DEFERRED);
3679
3680                AlterViewOperation::SetParallelism {
3681                    parallelism: value,
3682                    deferred,
3683                }
3684            } else if self.parse_keyword(Keyword::BACKFILL_PARALLELISM) && materialized {
3685                if self.expect_keyword(Keyword::TO).is_err()
3686                    && self.expect_token(&Token::Eq).is_err()
3687                {
3688                    return self.expected(
3689                        "TO or = after ALTER MATERIALIZED VIEW SET BACKFILL_PARALLELISM",
3690                    );
3691                }
3692
3693                let value = self.parse_set_variable()?;
3694
3695                let deferred = self.parse_keyword(Keyword::DEFERRED);
3696
3697                AlterViewOperation::SetBackfillParallelism {
3698                    parallelism: value,
3699                    deferred,
3700                }
3701            } else if self.parse_keyword(Keyword::RESOURCE_GROUP) && materialized {
3702                if self.expect_keyword(Keyword::TO).is_err()
3703                    && self.expect_token(&Token::Eq).is_err()
3704                {
3705                    return self
3706                        .expected("TO or = after ALTER MATERIALIZED VIEW SET RESOURCE_GROUP");
3707                }
3708                let value = self.parse_set_variable()?;
3709                let deferred = self.parse_keyword(Keyword::DEFERRED);
3710
3711                AlterViewOperation::SetResourceGroup {
3712                    resource_group: Some(value),
3713                    deferred,
3714                }
3715            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3716                AlterViewOperation::AlterRateLimit(rate_limit)
3717            } else if self.parse_keyword(Keyword::CONFIG) && materialized {
3718                let entries = self.parse_options()?;
3719                AlterViewOperation::SetConfig { entries }
3720            } else {
3721                return self.expected(
3722                    "SCHEMA/PARALLELISM/BACKFILL_PARALLELISM/BACKFILL_RATE_LIMIT/CONFIG after SET",
3723                );
3724            }
3725        } else if self.parse_keyword(Keyword::RESET) {
3726            if self.parse_keyword(Keyword::RESOURCE_GROUP) && materialized {
3727                let deferred = self.parse_keyword(Keyword::DEFERRED);
3728
3729                AlterViewOperation::SetResourceGroup {
3730                    resource_group: None,
3731                    deferred,
3732                }
3733            } else if self.parse_keyword(Keyword::CONFIG) && materialized {
3734                let keys = self.parse_parenthesized_object_name_list()?;
3735                AlterViewOperation::ResetConfig { keys }
3736            } else {
3737                return self.expected("RESOURCE_GROUP or CONFIG after RESET");
3738            }
3739        } else {
3740            return self.expected(&format!(
3741                "AS, RENAME, OWNER TO, SET, or SWAP after ALTER {}VIEW",
3742                if materialized { "MATERIALIZED " } else { "" }
3743            ));
3744        };
3745
3746        Ok(Statement::AlterView {
3747            materialized,
3748            name: view_name,
3749            operation,
3750        })
3751    }
3752
3753    pub fn parse_alter_sink(&mut self) -> ModalResult<Statement> {
3754        let sink_name = self.parse_object_name()?;
3755        let operation = if self.parse_keyword(Keyword::RENAME) {
3756            if self.parse_keyword(Keyword::TO) {
3757                let sink_name = self.parse_object_name()?;
3758                AlterSinkOperation::RenameSink { sink_name }
3759            } else {
3760                return self.expected("TO after RENAME");
3761            }
3762        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3763            let owner_name: Ident = self.parse_identifier()?;
3764            AlterSinkOperation::ChangeOwner {
3765                new_owner_name: owner_name,
3766            }
3767        } else if self.parse_keyword(Keyword::SET) {
3768            if self.parse_keyword(Keyword::SCHEMA) {
3769                let schema_name = self.parse_object_name()?;
3770                AlterSinkOperation::SetSchema {
3771                    new_schema_name: schema_name,
3772                }
3773            } else if self.parse_word("STREAMING_ENABLE_UNALIGNED_JOIN") {
3774                self.expect_keyword(Keyword::TO)?;
3775                let value = self.parse_boolean()?;
3776                AlterSinkOperation::SetStreamingEnableUnalignedJoin { enable: value }
3777            } else if self.parse_keyword(Keyword::PARALLELISM) {
3778                if self.expect_keyword(Keyword::TO).is_err()
3779                    && self.expect_token(&Token::Eq).is_err()
3780                {
3781                    return self.expected("TO or = after ALTER SINK SET PARALLELISM");
3782                }
3783
3784                let value = self.parse_set_variable()?;
3785                let deferred = self.parse_keyword(Keyword::DEFERRED);
3786
3787                AlterSinkOperation::SetParallelism {
3788                    parallelism: value,
3789                    deferred,
3790                }
3791            } else if self.parse_keyword(Keyword::BACKFILL_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 BACKFILL_PARALLELISM");
3796                }
3797
3798                let value = self.parse_set_variable()?;
3799                let deferred = self.parse_keyword(Keyword::DEFERRED);
3800
3801                AlterSinkOperation::SetBackfillParallelism {
3802                    parallelism: value,
3803                    deferred,
3804                }
3805            } else if self.parse_keyword(Keyword::RESOURCE_GROUP) {
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 RESOURCE_GROUP");
3810                }
3811                let value = self.parse_set_variable()?;
3812                let deferred = self.parse_keyword(Keyword::DEFERRED);
3813
3814                AlterSinkOperation::SetResourceGroup {
3815                    resource_group: Some(value),
3816                    deferred,
3817                }
3818            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3819                AlterSinkOperation::AlterRateLimit(rate_limit)
3820            } else if self.parse_keyword(Keyword::CONFIG) {
3821                let entries = self.parse_options()?;
3822                AlterSinkOperation::SetConfig { entries }
3823            } else {
3824                return self.expected(
3825                    "SCHEMA/PARALLELISM/BACKFILL_PARALLELISM/RESOURCE_GROUP/SINK_RATE_LIMIT/BACKFILL_RATE_LIMIT/STREAMING_ENABLE_UNALIGNED_JOIN/CONFIG after SET",
3826                );
3827            }
3828        } else if self.parse_keyword(Keyword::RESET) {
3829            if self.parse_keyword(Keyword::RESOURCE_GROUP) {
3830                let deferred = self.parse_keyword(Keyword::DEFERRED);
3831
3832                AlterSinkOperation::SetResourceGroup {
3833                    resource_group: None,
3834                    deferred,
3835                }
3836            } else if self.parse_keyword(Keyword::CONFIG) {
3837                let keys = self.parse_parenthesized_object_name_list()?;
3838                AlterSinkOperation::ResetConfig { keys }
3839            } else {
3840                return self.expected("RESOURCE_GROUP or CONFIG after RESET");
3841            }
3842        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3843            let target_sink = self.parse_object_name()?;
3844            AlterSinkOperation::SwapRenameSink { target_sink }
3845        } else if self.parse_keyword(Keyword::CONNECTOR) {
3846            let changed_props = self.parse_with_properties()?;
3847            AlterSinkOperation::AlterConnectorProps {
3848                alter_props: changed_props,
3849            }
3850        } else {
3851            return self
3852                .expected("RENAME or OWNER TO or SET or RESET or CONNECTOR WITH after ALTER SINK");
3853        };
3854
3855        Ok(Statement::AlterSink {
3856            name: sink_name,
3857            operation,
3858        })
3859    }
3860
3861    pub fn parse_alter_subscription(&mut self) -> ModalResult<Statement> {
3862        let subscription_name = self.parse_object_name()?;
3863        let operation = if self.parse_keyword(Keyword::RENAME) {
3864            if self.parse_keyword(Keyword::TO) {
3865                let subscription_name = self.parse_object_name()?;
3866                AlterSubscriptionOperation::RenameSubscription { subscription_name }
3867            } else {
3868                return self.expected("TO after RENAME");
3869            }
3870        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3871            let owner_name: Ident = self.parse_identifier()?;
3872            AlterSubscriptionOperation::ChangeOwner {
3873                new_owner_name: owner_name,
3874            }
3875        } else if self.parse_keyword(Keyword::SET) {
3876            if self.parse_keyword(Keyword::SCHEMA) {
3877                let schema_name = self.parse_object_name()?;
3878                AlterSubscriptionOperation::SetSchema {
3879                    new_schema_name: schema_name,
3880                }
3881            } else if self.parse_keyword(Keyword::RETENTION) {
3882                if self.expect_keyword(Keyword::TO).is_err()
3883                    && self.expect_token(&Token::Eq).is_err()
3884                {
3885                    return self.expected("TO or = after ALTER SUBSCRIPTION SET RETENTION");
3886                }
3887                let retention = self.ensure_parse_value()?;
3888                AlterSubscriptionOperation::SetRetention { retention }
3889            } else {
3890                return self.expected("SCHEMA or RETENTION after SET");
3891            }
3892        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3893            let target_subscription = self.parse_object_name()?;
3894            AlterSubscriptionOperation::SwapRenameSubscription {
3895                target_subscription,
3896            }
3897        } else {
3898            return self.expected("RENAME or OWNER TO or SET or SWAP after ALTER SUBSCRIPTION");
3899        };
3900
3901        Ok(Statement::AlterSubscription {
3902            name: subscription_name,
3903            operation,
3904        })
3905    }
3906
3907    pub fn parse_alter_source(&mut self) -> ModalResult<Statement> {
3908        let source_name = self.parse_object_name()?;
3909        let operation = if self.parse_keyword(Keyword::RENAME) {
3910            if self.parse_keyword(Keyword::TO) {
3911                let source_name = self.parse_object_name()?;
3912                AlterSourceOperation::RenameSource { source_name }
3913            } else {
3914                return self.expected("TO after RENAME");
3915            }
3916        } else if self.parse_keyword(Keyword::ADD) {
3917            let _ = self.parse_keyword(Keyword::COLUMN);
3918            let _if_not_exists = self.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
3919            let column_def = self.parse_column_def()?;
3920            AlterSourceOperation::AddColumn { column_def }
3921        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
3922            let owner_name: Ident = self.parse_identifier()?;
3923            AlterSourceOperation::ChangeOwner {
3924                new_owner_name: owner_name,
3925            }
3926        } else if self.parse_keyword(Keyword::SET) {
3927            if self.parse_keyword(Keyword::SCHEMA) {
3928                let schema_name = self.parse_object_name()?;
3929                AlterSourceOperation::SetSchema {
3930                    new_schema_name: schema_name,
3931                }
3932            } else if let Some(rate_limit) = self.parse_alter_rate_limit()? {
3933                AlterSourceOperation::AlterRateLimit(rate_limit)
3934            } else if self.parse_keyword(Keyword::PARALLELISM) {
3935                if self.expect_keyword(Keyword::TO).is_err()
3936                    && self.expect_token(&Token::Eq).is_err()
3937                {
3938                    return self.expected("TO or = after ALTER SOURCE SET PARALLELISM");
3939                }
3940
3941                let value = self.parse_set_variable()?;
3942                let deferred = self.parse_keyword(Keyword::DEFERRED);
3943
3944                AlterSourceOperation::SetParallelism {
3945                    parallelism: value,
3946                    deferred,
3947                }
3948            } else if self.parse_keyword(Keyword::BACKFILL_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 BACKFILL_PARALLELISM");
3953                }
3954
3955                let value = self.parse_set_variable()?;
3956                let deferred = self.parse_keyword(Keyword::DEFERRED);
3957
3958                AlterSourceOperation::SetBackfillParallelism {
3959                    parallelism: value,
3960                    deferred,
3961                }
3962            } else if self.parse_keyword(Keyword::CONFIG) {
3963                let entries = self.parse_options()?;
3964                AlterSourceOperation::SetConfig { entries }
3965            } else {
3966                return self.expected(
3967                    "SCHEMA, SOURCE_RATE_LIMIT, PARALLELISM, BACKFILL_PARALLELISM or CONFIG after SET",
3968                );
3969            }
3970        } else if self.parse_keyword(Keyword::RESET) {
3971            if self.parse_keyword(Keyword::CONFIG) {
3972                let keys = self.parse_parenthesized_object_name_list()?;
3973                AlterSourceOperation::ResetConfig { keys }
3974            } else {
3975                // RESET without CONFIG means reset CDC source offset to latest
3976                AlterSourceOperation::ResetSource
3977            }
3978        } else if self.peek_nth_any_of_keywords(0, &[Keyword::FORMAT]) {
3979            let format_encode = self.parse_schema()?.unwrap();
3980            if format_encode.key_encode.is_some() {
3981                parser_err!("key encode clause is not supported in source schema");
3982            }
3983            AlterSourceOperation::FormatEncode { format_encode }
3984        } else if self.parse_keywords(&[Keyword::REFRESH, Keyword::SCHEMA]) {
3985            AlterSourceOperation::RefreshSchema
3986        } else if self.parse_keywords(&[Keyword::SWAP, Keyword::WITH]) {
3987            let target_source = self.parse_object_name()?;
3988            AlterSourceOperation::SwapRenameSource { target_source }
3989        } else if self.parse_keyword(Keyword::CONNECTOR) {
3990            let with_options = self.parse_with_properties()?;
3991            AlterSourceOperation::AlterConnectorProps {
3992                alter_props: with_options,
3993            }
3994        } else {
3995            return self.expected(
3996                "RENAME, ADD COLUMN, OWNER TO, CONNECTOR, SET or RESET after ALTER SOURCE",
3997            );
3998        };
3999
4000        Ok(Statement::AlterSource {
4001            name: source_name,
4002            operation,
4003        })
4004    }
4005
4006    pub fn parse_alter_function(&mut self) -> ModalResult<Statement> {
4007        let FunctionDesc { name, args } = self.parse_function_desc()?;
4008
4009        let operation = if self.parse_keyword(Keyword::SET) {
4010            if self.parse_keyword(Keyword::SCHEMA) {
4011                let schema_name = self.parse_object_name()?;
4012                AlterFunctionOperation::SetSchema {
4013                    new_schema_name: schema_name,
4014                }
4015            } else {
4016                return self.expected("SCHEMA after SET");
4017            }
4018        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
4019            let owner_name: Ident = self.parse_identifier()?;
4020            AlterFunctionOperation::ChangeOwner {
4021                new_owner_name: owner_name,
4022            }
4023        } else {
4024            return self.expected("SET or OWNER TO after ALTER FUNCTION");
4025        };
4026
4027        Ok(Statement::AlterFunction {
4028            name,
4029            args,
4030            operation,
4031        })
4032    }
4033
4034    pub fn parse_alter_connection(&mut self) -> ModalResult<Statement> {
4035        let connection_name = self.parse_object_name()?;
4036        let operation = if self.parse_keyword(Keyword::SET) {
4037            if self.parse_keyword(Keyword::SCHEMA) {
4038                let schema_name = self.parse_object_name()?;
4039                AlterConnectionOperation::SetSchema {
4040                    new_schema_name: schema_name,
4041                }
4042            } else {
4043                return self.expected("SCHEMA after SET");
4044            }
4045        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
4046            let owner_name: Ident = self.parse_identifier()?;
4047            AlterConnectionOperation::ChangeOwner {
4048                new_owner_name: owner_name,
4049            }
4050        } else if self.parse_keyword(Keyword::CONNECTOR) {
4051            let with_options = self.parse_with_properties()?;
4052            AlterConnectionOperation::AlterConnectorProps {
4053                alter_props: with_options,
4054            }
4055        } else {
4056            return self.expected("SET, OWNER TO, or CONNECTOR WITH after ALTER CONNECTION");
4057        };
4058
4059        Ok(Statement::AlterConnection {
4060            name: connection_name,
4061            operation,
4062        })
4063    }
4064
4065    pub fn parse_alter_system(&mut self) -> ModalResult<Statement> {
4066        if self.parse_word("CLEAR") {
4067            self.expect_keywords(&[Keyword::FILE, Keyword::CACHE])?;
4068            let cache_type = if self.parse_keyword(Keyword::META) {
4069                FileCacheType::Meta
4070            } else if self.parse_keyword(Keyword::DATA) {
4071                FileCacheType::Data
4072            } else if self.parse_keyword(Keyword::ALL) {
4073                FileCacheType::All
4074            } else {
4075                return self.expected("META, DATA, or ALL after ALTER SYSTEM CLEAR FILE CACHE");
4076            };
4077            return Ok(Statement::AlterSystemClearFileCache { cache_type });
4078        }
4079
4080        self.expect_keyword(Keyword::SET)?;
4081        let param = self.parse_identifier()?;
4082        if self.expect_keyword(Keyword::TO).is_err() && self.expect_token(&Token::Eq).is_err() {
4083            return self.expected("TO or = after ALTER SYSTEM SET");
4084        }
4085        let value = self.parse_set_variable()?;
4086        Ok(Statement::AlterSystem { param, value })
4087    }
4088
4089    pub fn parse_alter_secret(&mut self) -> ModalResult<Statement> {
4090        let secret_name = self.parse_object_name()?;
4091        let operation = if self.parse_keyword(Keyword::WITH) {
4092            let with_options = self.parse_options()?;
4093            if self.parse_keyword(Keyword::AS) {
4094                let new_credential = self.ensure_parse_value()?;
4095                AlterSecretOperation::ChangeCredential {
4096                    with_options,
4097                    new_credential,
4098                }
4099            } else {
4100                return self.expected("Keyword AS after Options");
4101            }
4102        } else if self.parse_keyword(Keyword::AS) {
4103            let new_credential = self.ensure_parse_value()?;
4104            AlterSecretOperation::ChangeCredential {
4105                with_options: vec![],
4106                new_credential,
4107            }
4108        } else if self.parse_keywords(&[Keyword::OWNER, Keyword::TO]) {
4109            let owner_name: Ident = self.parse_identifier()?;
4110            AlterSecretOperation::ChangeOwner {
4111                new_owner_name: owner_name,
4112            }
4113        } else {
4114            return self.expected("WITH, AS or OWNER TO after ALTER SECRET");
4115        };
4116        Ok(Statement::AlterSecret {
4117            name: secret_name,
4118            operation,
4119        })
4120    }
4121
4122    pub fn parse_alter_fragment(&mut self) -> ModalResult<Statement> {
4123        let mut fragment_ids = vec![self.parse_literal_u32()?];
4124        while self.consume_token(&Token::Comma) {
4125            fragment_ids.push(self.parse_literal_u32()?);
4126        }
4127        if !self.parse_keyword(Keyword::SET) {
4128            return self.expected("SET after ALTER FRAGMENT");
4129        }
4130        let operation = if self.parse_keyword(Keyword::PARALLELISM) {
4131            if self.expect_keyword(Keyword::TO).is_err() && self.expect_token(&Token::Eq).is_err() {
4132                return self.expected("TO or = after ALTER FRAGMENT SET PARALLELISM");
4133            }
4134            let parallelism = self.parse_set_variable()?;
4135            AlterFragmentOperation::SetParallelism { parallelism }
4136        } else {
4137            let rate_limit = self.parse_alter_fragment_rate_limit()?;
4138            AlterFragmentOperation::AlterRateLimit(rate_limit)
4139        };
4140        Ok(Statement::AlterFragment {
4141            fragment_ids,
4142            operation,
4143        })
4144    }
4145
4146    pub fn parse_alter_compaction_group(&mut self) -> ModalResult<Statement> {
4147        if !self.parse_keyword(Keyword::GROUP) {
4148            return self.expected("GROUP after ALTER COMPACTION");
4149        }
4150        let mut group_ids = vec![self.parse_literal_u64()?];
4151        while self.consume_token(&Token::Comma) {
4152            group_ids.push(self.parse_literal_u64()?);
4153        }
4154        if !self.parse_keyword(Keyword::SET) {
4155            return self.expected("SET after ALTER COMPACTION GROUP <id>");
4156        }
4157        // NOTE: use the `no_list` variant here, because `parse_set_variable` allows comma-separated
4158        // lists (e.g., `SET foo = 1,2,3`), which would conflict with our use of comma to separate
4159        // multiple config assignments.
4160        let configs = self.parse_comma_separated(Parser::parse_config_param_no_list)?;
4161        let operation = AlterCompactionGroupOperation::Set { configs };
4162        Ok(Statement::AlterCompactionGroup {
4163            group_ids,
4164            operation,
4165        })
4166    }
4167
4168    fn parse_alter_fragment_rate_limit(&mut self) -> ModalResult<AlterRateLimit> {
4169        if self.parse_word("RATE_LIMIT") {
4170            let rate_limit = self.parse_rate_limit_value()?;
4171            return Ok(AlterRateLimit {
4172                rate_limit_type: AlterRateLimitType::Backfill,
4173                rate_limit,
4174            });
4175        }
4176        if let Some(rate_limit) = self.parse_alter_rate_limit()? {
4177            Ok(rate_limit)
4178        } else {
4179            self.expected("expected rate limit after SET")
4180        }
4181    }
4182
4183    /// Parse a copy statement
4184    pub fn parse_copy(&mut self) -> ModalResult<Statement> {
4185        let entity = if self.consume_token(&Token::LParen) {
4186            let query = self.parse_query()?;
4187            self.expect_token(&Token::RParen)?;
4188            CopyEntity::Query(query.into())
4189        } else {
4190            let table_name = self.parse_object_name()?;
4191            let columns = self.parse_parenthesized_column_list(Optional)?;
4192            CopyEntity::Table {
4193                table_name,
4194                columns,
4195            }
4196        };
4197
4198        let target = if self.parse_keywords(&[Keyword::FROM, Keyword::STDIN]) {
4199            self.expect_token(&Token::SemiColon)?;
4200            let values = self.parse_tsv();
4201            CopyTarget::Stdin { values }
4202        } else if self.parse_keywords(&[Keyword::TO, Keyword::STDOUT]) {
4203            CopyTarget::Stdout
4204        } else {
4205            return self.expected("FROM STDIN or TO STDOUT");
4206        };
4207
4208        Ok(Statement::Copy { entity, target })
4209    }
4210
4211    /// Parse a tab separated values in
4212    /// COPY payload
4213    fn parse_tsv(&mut self) -> Vec<Option<String>> {
4214        self.parse_tab_value()
4215    }
4216
4217    fn parse_tab_value(&mut self) -> Vec<Option<String>> {
4218        let mut values = vec![];
4219        let mut content = String::from("");
4220        while let Some(t) = self.next_token_no_skip() {
4221            match t.token {
4222                Token::Whitespace(Whitespace::Tab) => {
4223                    values.push(Some(content.clone()));
4224                    content.clear();
4225                }
4226                Token::Whitespace(Whitespace::Newline) => {
4227                    values.push(Some(content.clone()));
4228                    content.clear();
4229                }
4230                Token::Backslash => {
4231                    if self.consume_token(&Token::Period) {
4232                        return values;
4233                    }
4234                    if let Token::Word(w) = self.next_token().token
4235                        && w.value == "N"
4236                    {
4237                        values.push(None);
4238                    }
4239                }
4240                _ => {
4241                    content.push_str(&t.to_string());
4242                }
4243            }
4244        }
4245        values
4246    }
4247
4248    pub fn ensure_parse_value(&mut self) -> ModalResult<Value> {
4249        match self.parse_value_and_obj_ref::<true>()? {
4250            SqlOptionValue::Value(value) => Ok(value),
4251            SqlOptionValue::SecretRef(_)
4252            | SqlOptionValue::ConnectionRef(_)
4253            | SqlOptionValue::BackfillOrder(_) => unreachable!(),
4254        }
4255    }
4256
4257    /// Parse a literal value (numbers, strings, date/time, booleans)
4258    pub fn parse_value_and_obj_ref<const FORBID_OBJ_REF: bool>(
4259        &mut self,
4260    ) -> ModalResult<SqlOptionValue> {
4261        let checkpoint = *self;
4262        let token = self.next_token();
4263        match token.token {
4264            Token::Word(w) => match w.keyword {
4265                Keyword::TRUE => Ok(Value::Boolean(true).into()),
4266                Keyword::FALSE => Ok(Value::Boolean(false).into()),
4267                Keyword::NULL => Ok(Value::Null.into()),
4268                Keyword::NoKeyword if w.quote_style.is_some() => match w.quote_style {
4269                    Some('"') => Ok(Value::DoubleQuotedString(w.value).into()),
4270                    Some('\'') => Ok(Value::SingleQuotedString(w.value).into()),
4271                    _ => self.expected_at(checkpoint, "A value")?,
4272                },
4273                Keyword::SECRET => {
4274                    if FORBID_OBJ_REF {
4275                        return self.expected_at(
4276                            checkpoint,
4277                            "a concrete value rather than a secret reference",
4278                        );
4279                    }
4280                    let secret = self.parse_secret_ref()?;
4281                    Ok(SqlOptionValue::SecretRef(secret))
4282                }
4283                _ => self.expected_at(checkpoint, "a concrete value"),
4284            },
4285            Token::Number(ref n) => Ok(Value::Number(n.clone()).into()),
4286            Token::SingleQuotedString(ref s) => Ok(Value::SingleQuotedString(s.clone()).into()),
4287            Token::DollarQuotedString(ref s) => Ok(Value::DollarQuotedString(s.clone()).into()),
4288            Token::CstyleEscapesString(ref s) => Ok(Value::CstyleEscapedString(s.clone()).into()),
4289            Token::NationalStringLiteral(ref s) => {
4290                Ok(Value::NationalStringLiteral(s.clone()).into())
4291            }
4292            Token::HexStringLiteral(ref s) => Ok(Value::HexStringLiteral(s.clone()).into()),
4293            _ => self.expected_at(checkpoint, "a value"),
4294        }
4295    }
4296
4297    fn parse_secret_ref(&mut self) -> ModalResult<SecretRefValue> {
4298        let secret_name = self.parse_object_name()?;
4299        let ref_as = if self.parse_keywords(&[Keyword::AS, Keyword::FILE]) {
4300            SecretRefAsType::File
4301        } else {
4302            SecretRefAsType::Text
4303        };
4304        Ok(SecretRefValue {
4305            secret_name,
4306            ref_as,
4307        })
4308    }
4309
4310    fn parse_set_variable(&mut self) -> ModalResult<SetVariableValue> {
4311        alt((
4312            Keyword::DEFAULT.value(SetVariableValue::Default),
4313            separated(
4314                1..,
4315                alt((
4316                    Self::ensure_parse_value.map(SetVariableValueSingle::Literal),
4317                    |parser: &mut Self| {
4318                        let checkpoint = *parser;
4319                        let ident = parser.parse_identifier()?;
4320                        if parser.consume_token(&Token::LParen) {
4321                            let args = parser.parse_comma_separated(Parser::ensure_parse_value)?;
4322                            parser.expect_token(&Token::RParen)?;
4323                            let raw = format!(
4324                                "{}({})",
4325                                ident,
4326                                args.iter().map(ToString::to_string).join(", ")
4327                            );
4328                            return Ok(SetVariableValueSingle::Raw(raw));
4329                        }
4330                        if ident.value == "default" {
4331                            *parser = checkpoint;
4332                            return parser.expected("parameter list value").map_err(|e| e.cut());
4333                        }
4334                        Ok(SetVariableValueSingle::Ident(ident))
4335                    },
4336                    fail.expect("parameter value"),
4337                )),
4338                Token::Comma,
4339            )
4340            .map(|list: Vec<SetVariableValueSingle>| {
4341                if list.len() == 1 {
4342                    SetVariableValue::Single(list[0].clone())
4343                } else {
4344                    SetVariableValue::List(list)
4345                }
4346            }),
4347        ))
4348        .parse_next(self)
4349    }
4350
4351    fn parse_backfill_order_strategy(&mut self) -> ModalResult<BackfillOrderStrategy> {
4352        alt((
4353            Keyword::DEFAULT.value(BackfillOrderStrategy::Default),
4354            Keyword::NONE.value(BackfillOrderStrategy::None),
4355            Keyword::AUTO.value(BackfillOrderStrategy::Auto),
4356            Self::parse_fixed_backfill_order.map(BackfillOrderStrategy::Fixed),
4357            fail.expect("backfill order strategy"),
4358        ))
4359        .parse_next(self)
4360    }
4361
4362    fn parse_fixed_backfill_order(&mut self) -> ModalResult<Vec<(ObjectName, ObjectName)>> {
4363        self.expect_word("FIXED")?;
4364        self.expect_token(&Token::LParen)?;
4365        let edges = separated(
4366            0..,
4367            separated_pair(
4368                Self::parse_object_name,
4369                Token::Op("->".to_owned()),
4370                Self::parse_object_name,
4371            ),
4372            Token::Comma,
4373        )
4374        .parse_next(self)?;
4375        self.expect_token(&Token::RParen)?;
4376        Ok(edges)
4377    }
4378
4379    pub fn parse_number_value(&mut self) -> ModalResult<String> {
4380        let checkpoint = *self;
4381        match self.ensure_parse_value()? {
4382            Value::Number(v) => Ok(v),
4383            _ => self.expected_at(checkpoint, "literal number"),
4384        }
4385    }
4386
4387    pub fn parse_literal_u32(&mut self) -> ModalResult<u32> {
4388        literal_u32(self)
4389    }
4390
4391    pub fn parse_literal_u64(&mut self) -> ModalResult<u64> {
4392        literal_u64(self)
4393    }
4394
4395    pub fn parse_function_definition(&mut self) -> ModalResult<FunctionDefinition> {
4396        alt((
4397            single_quoted_string.map(FunctionDefinition::SingleQuotedDef),
4398            dollar_quoted_string.map(FunctionDefinition::DoubleDollarDef),
4399            Self::parse_identifier.map(|i| FunctionDefinition::Identifier(i.value)),
4400            fail.expect("function definition"),
4401        ))
4402        .parse_next(self)
4403    }
4404
4405    /// Parse a literal string
4406    pub fn parse_literal_string(&mut self) -> ModalResult<String> {
4407        let checkpoint = *self;
4408        let token = self.next_token();
4409        match token.token {
4410            Token::SingleQuotedString(s) => Ok(s),
4411            Token::DollarQuotedString(s) => Ok(s.value),
4412            _ => self.expected_at(checkpoint, "literal string"),
4413        }
4414    }
4415
4416    /// Parse a SQL datatype (in the context of a CREATE TABLE statement for example)
4417    pub fn parse_data_type(&mut self) -> ModalResult<DataType> {
4418        parser_v2::data_type(self)
4419    }
4420
4421    /// Parse `AS identifier` (or simply `identifier` if it's not a reserved keyword)
4422    /// Some examples with aliases: `SELECT 1 foo`, `SELECT COUNT(*) AS cnt`,
4423    /// `SELECT ... FROM t1 foo, t2 bar`, `SELECT ... FROM (...) AS bar`
4424    pub fn parse_optional_alias(
4425        &mut self,
4426        reserved_kwds: &[Keyword],
4427    ) -> ModalResult<Option<Ident>> {
4428        let after_as = self.parse_keyword(Keyword::AS);
4429        let checkpoint = *self;
4430        let token = self.next_token();
4431        match token.token {
4432            // Accept any identifier after `AS` (though many dialects have restrictions on
4433            // keywords that may appear here). If there's no `AS`: don't parse keywords,
4434            // which may start a construct allowed in this position, to be parsed as aliases.
4435            // (For example, in `FROM t1 JOIN` the `JOIN` will always be parsed as a keyword,
4436            // not an alias.)
4437            Token::Word(w) if after_as || (!reserved_kwds.contains(&w.keyword)) => {
4438                // Contextual reservation: `MATCH_RECOGNIZE` is deliberately NOT a keyword (a
4439                // stored definition may use it as a bare alias from before the clause existed,
4440                // and keywords change quoting and identifier parsing globally), so the clause is
4441                // recognised here instead — a bare `match_recognize` immediately followed by `(`
4442                // opens the clause and must not be taken as an implicit alias. With an explicit
4443                // `AS`, or quoted, or not followed by `(`, it stays a perfectly good alias.
4444                if !after_as
4445                    && w.quote_style.is_none()
4446                    && w.value.eq_ignore_ascii_case("MATCH_RECOGNIZE")
4447                    && self.peek_token() == Token::LParen
4448                {
4449                    *self = checkpoint;
4450                    return Ok(None);
4451                }
4452                Ok(Some(w.to_ident()?))
4453            }
4454            _ => {
4455                *self = checkpoint;
4456                if after_as {
4457                    return self.expected("an identifier after AS");
4458                }
4459                Ok(None) // no alias found
4460            }
4461        }
4462    }
4463
4464    /// Parse `AS identifier` when the AS is describing a table-valued object,
4465    /// like in `... FROM generate_series(1, 10) AS t (col)`. In this case
4466    /// the alias is allowed to optionally name the columns in the table, in
4467    /// addition to the table itself.
4468    pub fn parse_optional_table_alias(
4469        &mut self,
4470        reserved_kwds: &[Keyword],
4471    ) -> ModalResult<Option<TableAlias>> {
4472        if self.peek_broadcast_join() {
4473            return Ok(None);
4474        }
4475        match self.parse_optional_alias(reserved_kwds)? {
4476            Some(name) => {
4477                let columns = self.parse_parenthesized_column_list(Optional)?;
4478                Ok(Some(TableAlias { name, columns }))
4479            }
4480            None => Ok(None),
4481        }
4482    }
4483
4484    /// syntax `FOR SYSTEM_TIME AS OF PROCTIME()` is used for temporal join.
4485    pub fn parse_as_of(&mut self) -> ModalResult<AsOf> {
4486        Keyword::FOR.parse_next(self)?;
4487        alt((
4488            preceded(
4489                (Keyword::SYSTEM_TIME, Keyword::AS, Keyword::OF),
4490                cut_err(
4491                    alt((
4492                        preceded(
4493                            (
4494                                Self::parse_identifier.verify(|ident| ident.real_value() == "now"),
4495                                cut_err(Token::LParen),
4496                                cut_err(Token::RParen),
4497                                Token::Minus,
4498                            ),
4499                            Self::parse_literal_interval.try_map(|e| match e {
4500                                Expr::Value(v) => match v {
4501                                    Value::Interval {
4502                                        value,
4503                                        leading_field,
4504                                        ..
4505                                    } => {
4506                                        let Some(leading_field) = leading_field else {
4507                                            return Err(StrError("expect duration unit".into()));
4508                                        };
4509                                        Ok(AsOf::ProcessTimeWithInterval((value, leading_field)))
4510                                    }
4511                                    _ => Err(StrError("expect Value::Interval".into())),
4512                                },
4513                                _ => Err(StrError("expect Expr::Value".into())),
4514                            }),
4515                        ),
4516                        (
4517                            Self::parse_identifier.verify(|ident| ident.real_value() == "now"),
4518                            cut_err(Token::LParen),
4519                            cut_err(Token::RParen),
4520                        )
4521                            .value(AsOf::ProcessTimeWithInterval((
4522                                "0".to_owned(),
4523                                DateTimeField::Second,
4524                            ))),
4525                        (
4526                            Self::parse_identifier.verify(|ident| ident.real_value() == "proctime"),
4527                            cut_err(Token::LParen),
4528                            cut_err(Token::RParen),
4529                        )
4530                            .value(AsOf::ProcessTime),
4531                        literal_i64.map(AsOf::TimestampNum),
4532                        single_quoted_string.map(AsOf::TimestampString),
4533                    ))
4534                    .expect("proctime(), now(), number or string"),
4535                ),
4536            ),
4537            preceded(
4538                (Keyword::SYSTEM_VERSION, Keyword::AS, Keyword::OF),
4539                cut_err(
4540                    alt((
4541                        literal_i64.map(AsOf::VersionNum),
4542                        single_quoted_string.map(AsOf::VersionString),
4543                    ))
4544                    .expect("number or string"),
4545                ),
4546            ),
4547        ))
4548        .parse_next(self)
4549    }
4550
4551    /// Parse a possibly qualified, possibly quoted identifier, e.g.
4552    /// `foo` or `myschema."table"
4553    pub fn parse_object_name(&mut self) -> ModalResult<ObjectName> {
4554        let mut idents = vec![];
4555        loop {
4556            idents.push(self.parse_identifier()?);
4557            if !self.consume_token(&Token::Period) {
4558                break;
4559            }
4560        }
4561        Ok(ObjectName(idents))
4562    }
4563
4564    /// Parse a parenthesized comma-separated list of object names
4565    pub fn parse_parenthesized_object_name_list(&mut self) -> ModalResult<Vec<ObjectName>> {
4566        if self.consume_token(&Token::LParen) {
4567            let names = self.parse_comma_separated(Parser::parse_object_name)?;
4568            self.expect_token(&Token::RParen)?;
4569            Ok(names)
4570        } else {
4571            self.expected("a list of object names in parentheses")
4572        }
4573    }
4574
4575    /// Parse identifiers strictly i.e. don't parse keywords
4576    pub fn parse_identifiers_non_keywords(&mut self) -> ModalResult<Vec<Ident>> {
4577        let mut idents = vec![];
4578        loop {
4579            match self.peek_token().token {
4580                Token::Word(w) => {
4581                    if w.keyword != Keyword::NoKeyword {
4582                        break;
4583                    }
4584
4585                    idents.push(w.to_ident()?);
4586                }
4587                Token::EOF | Token::Eq => break,
4588                _ => {}
4589            }
4590
4591            self.next_token();
4592        }
4593
4594        Ok(idents)
4595    }
4596
4597    /// Parse identifiers
4598    pub fn parse_identifiers(&mut self) -> ModalResult<Vec<Ident>> {
4599        let mut idents = vec![];
4600        loop {
4601            let token = self.next_token();
4602            match token.token {
4603                Token::Word(w) => {
4604                    idents.push(w.to_ident()?);
4605                }
4606                Token::EOF => break,
4607                _ => {}
4608            }
4609        }
4610
4611        Ok(idents)
4612    }
4613
4614    /// Parse a simple one-word identifier (possibly quoted, possibly a keyword)
4615    pub fn parse_identifier(&mut self) -> ModalResult<Ident> {
4616        let checkpoint = *self;
4617        let token = self.next_token();
4618        match token.token {
4619            Token::Word(w) => Ok(w.to_ident()?),
4620            _ => self.expected_at(checkpoint, "identifier"),
4621        }
4622    }
4623
4624    /// Parse a simple one-word identifier (possibly quoted, possibly a non-reserved keyword)
4625    pub fn parse_identifier_non_reserved(&mut self) -> ModalResult<Ident> {
4626        let checkpoint = *self;
4627        let token = self.next_token();
4628        match token.token {
4629            Token::Word(w) => {
4630                match keywords::RESERVED_FOR_COLUMN_OR_TABLE_NAME.contains(&w.keyword) {
4631                    true => parser_err!("syntax error at or near {w}"),
4632                    false => Ok(w.to_ident()?),
4633                }
4634            }
4635            _ => self.expected_at(checkpoint, "identifier"),
4636        }
4637    }
4638
4639    /// Parse a parenthesized comma-separated list of unqualified, possibly quoted identifiers
4640    pub fn parse_parenthesized_column_list(
4641        &mut self,
4642        optional: IsOptional,
4643    ) -> ModalResult<Vec<Ident>> {
4644        if self.consume_token(&Token::LParen) {
4645            let cols = self.parse_comma_separated(Parser::parse_identifier_non_reserved)?;
4646            self.expect_token(&Token::RParen)?;
4647            Ok(cols)
4648        } else if optional == Optional {
4649            Ok(vec![])
4650        } else {
4651            self.expected("a list of columns in parentheses")
4652        }
4653    }
4654
4655    pub fn parse_returning(&mut self, optional: IsOptional) -> ModalResult<Vec<SelectItem>> {
4656        if self.parse_keyword(Keyword::RETURNING) {
4657            let cols = self.parse_comma_separated(Parser::parse_select_item)?;
4658            Ok(cols)
4659        } else if optional == Optional {
4660            Ok(vec![])
4661        } else {
4662            self.expected("a list of columns or * after returning")
4663        }
4664    }
4665
4666    pub fn parse_row_expr(&mut self) -> ModalResult<Expr> {
4667        Ok(Expr::Row(self.parse_token_wrapped_exprs(
4668            &Token::LParen,
4669            &Token::RParen,
4670        )?))
4671    }
4672
4673    /// Parse a comma-separated list (maybe empty) from a wrapped expression
4674    pub fn parse_token_wrapped_exprs(
4675        &mut self,
4676        left: &Token,
4677        right: &Token,
4678    ) -> ModalResult<Vec<Expr>> {
4679        if self.consume_token(left) {
4680            let exprs = if self.consume_token(right) {
4681                vec![]
4682            } else {
4683                let exprs = self.parse_comma_separated(Parser::parse_expr)?;
4684                self.expect_token(right)?;
4685                exprs
4686            };
4687            Ok(exprs)
4688        } else {
4689            self.expected(left.to_string().as_str())
4690        }
4691    }
4692
4693    pub fn parse_optional_precision(&mut self) -> ModalResult<Option<u64>> {
4694        if self.consume_token(&Token::LParen) {
4695            let n = self.parse_literal_u64()?;
4696            self.expect_token(&Token::RParen)?;
4697            Ok(Some(n))
4698        } else {
4699            Ok(None)
4700        }
4701    }
4702
4703    pub fn parse_optional_precision_scale(&mut self) -> ModalResult<(Option<u64>, Option<u64>)> {
4704        if self.consume_token(&Token::LParen) {
4705            let n = self.parse_literal_u64()?;
4706            let scale = if self.consume_token(&Token::Comma) {
4707                Some(self.parse_literal_u64()?)
4708            } else {
4709                None
4710            };
4711            self.expect_token(&Token::RParen)?;
4712            Ok((Some(n), scale))
4713        } else {
4714            Ok((None, None))
4715        }
4716    }
4717
4718    pub fn parse_delete(&mut self) -> ModalResult<Statement> {
4719        if self.parse_keyword(Keyword::META) {
4720            let Some(_) = self.parse_one_of_keywords(&[Keyword::SNAPSHOT, Keyword::SNAPSHOTS])
4721            else {
4722                return self.expected("SNAPSHOT or SNAPSHOTS");
4723            };
4724            let snapshot_ids = self.parse_comma_separated(Parser::parse_literal_u64)?;
4725            return Ok(Statement::DeleteMetaSnapshots { snapshot_ids });
4726        }
4727
4728        self.expect_keyword(Keyword::FROM)?;
4729        let table_name = self.parse_object_name()?;
4730        let selection = if self.parse_keyword(Keyword::WHERE) {
4731            Some(self.parse_expr()?)
4732        } else {
4733            None
4734        };
4735        let returning = self.parse_returning(Optional)?;
4736
4737        Ok(Statement::Delete {
4738            table_name,
4739            selection,
4740            returning,
4741        })
4742    }
4743
4744    pub fn parse_boolean(&mut self) -> ModalResult<bool> {
4745        if let Some(keyword) = self.parse_one_of_keywords(&[Keyword::TRUE, Keyword::FALSE]) {
4746            match keyword {
4747                Keyword::TRUE => Ok(true),
4748                Keyword::FALSE => Ok(false),
4749                _ => unreachable!(),
4750            }
4751        } else {
4752            self.expected("TRUE or FALSE")
4753        }
4754    }
4755
4756    pub fn parse_optional_boolean(&mut self, default: bool) -> bool {
4757        self.parse_boolean().unwrap_or(default)
4758    }
4759
4760    fn parse_explain_options(&mut self) -> ModalResult<(ExplainOptions, Option<u64>)> {
4761        let mut options = ExplainOptions::default();
4762        let mut analyze_duration = None;
4763
4764        const BACKFILL: &str = "backfill";
4765        const VERBOSE: &str = "verbose";
4766        const TRACE: &str = "trace";
4767        const TYPE: &str = "type";
4768        const LOGICAL: &str = "logical";
4769        const PHYSICAL: &str = "physical";
4770        const DISTSQL: &str = "distsql";
4771        const FORMAT: &str = "format";
4772        const DURATION_SECS: &str = "duration_secs";
4773
4774        let explain_options_identifiers = [
4775            BACKFILL,
4776            VERBOSE,
4777            TRACE,
4778            TYPE,
4779            LOGICAL,
4780            PHYSICAL,
4781            DISTSQL,
4782            FORMAT,
4783            DURATION_SECS,
4784        ];
4785
4786        let parse_explain_option = |parser: &mut Parser<'_>| -> ModalResult<()> {
4787            match parser.parse_identifier()?.real_value().as_str() {
4788                VERBOSE => options.verbose = parser.parse_optional_boolean(true),
4789                TRACE => options.trace = parser.parse_optional_boolean(true),
4790                BACKFILL => options.backfill = parser.parse_optional_boolean(true),
4791                TYPE => {
4792                    let explain_type = parser.parse_identifier()?.real_value();
4793                    match explain_type.as_str() {
4794                        LOGICAL => options.explain_type = ExplainType::Logical,
4795                        PHYSICAL => options.explain_type = ExplainType::Physical,
4796                        DISTSQL => options.explain_type = ExplainType::DistSql,
4797                        unexpected => {
4798                            parser_err!("unexpected explain type: [{unexpected}]")
4799                        }
4800                    }
4801                }
4802                LOGICAL => options.explain_type = ExplainType::Logical,
4803                PHYSICAL => options.explain_type = ExplainType::Physical,
4804                DISTSQL => options.explain_type = ExplainType::DistSql,
4805                FORMAT => {
4806                    options.explain_format = {
4807                        let format = parser.parse_identifier()?.real_value();
4808                        match format.as_str() {
4809                            "text" => ExplainFormat::Text,
4810                            "json" => ExplainFormat::Json,
4811                            "xml" => ExplainFormat::Xml,
4812                            "yaml" => ExplainFormat::Yaml,
4813                            "dot" => ExplainFormat::Dot,
4814                            unexpected => {
4815                                parser_err!("unexpected explain format [{unexpected}]")
4816                            }
4817                        }
4818                    }
4819                }
4820                DURATION_SECS => {
4821                    analyze_duration = Some(parser.parse_literal_u64()?);
4822                }
4823                unexpected => {
4824                    parser_err!("unexpected explain options: [{unexpected}]")
4825                }
4826            };
4827            Ok(())
4828        };
4829
4830        // In order to support following statement, we need to peek before consume.
4831        // explain (select 1) union (select 1)
4832        if self.peek_token() == Token::LParen
4833            && let Token::Word(word) = self.peek_nth_token(1).token
4834            && let Ok(ident) = word.to_ident()
4835            && explain_options_identifiers.contains(&ident.real_value().as_str())
4836        {
4837            assert!(self.consume_token(&Token::LParen));
4838            self.parse_comma_separated(parse_explain_option)?;
4839            self.expect_token(&Token::RParen)?;
4840        }
4841
4842        Ok((options, analyze_duration))
4843    }
4844
4845    pub fn parse_explain(&mut self) -> ModalResult<Statement> {
4846        let analyze = self.parse_keyword(Keyword::ANALYZE);
4847        let (options, analyze_duration) = self.parse_explain_options()?;
4848
4849        if analyze {
4850            fn parse_analyze_target(parser: &mut Parser<'_>) -> ModalResult<Option<AnalyzeTarget>> {
4851                if parser.parse_keyword(Keyword::TABLE) {
4852                    let table_name = parser.parse_object_name()?;
4853                    Ok(Some(AnalyzeTarget::Table(table_name)))
4854                } else if parser.parse_keyword(Keyword::INDEX) {
4855                    let index_name = parser.parse_object_name()?;
4856                    Ok(Some(AnalyzeTarget::Index(index_name)))
4857                } else if parser.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
4858                    let view_name = parser.parse_object_name()?;
4859                    Ok(Some(AnalyzeTarget::MaterializedView(view_name)))
4860                } else if parser.parse_keyword(Keyword::INDEX) {
4861                    let index_name = parser.parse_object_name()?;
4862                    Ok(Some(AnalyzeTarget::Index(index_name)))
4863                } else if parser.parse_keyword(Keyword::SINK) {
4864                    let sink_name = parser.parse_object_name()?;
4865                    Ok(Some(AnalyzeTarget::Sink(sink_name)))
4866                } else if parser.parse_word("ID") {
4867                    let job_id = parser.parse_literal_u32()?;
4868                    Ok(Some(AnalyzeTarget::Id(job_id)))
4869                } else {
4870                    Ok(None)
4871                }
4872            }
4873            if let Some(target) = parse_analyze_target(self)? {
4874                let statement = Statement::ExplainAnalyzeStreamJob {
4875                    target,
4876                    duration_secs: analyze_duration,
4877                };
4878                return Ok(statement);
4879            }
4880        }
4881
4882        let statement = match self.parse_statement() {
4883            Ok(statement) => statement,
4884            error @ Err(_) => {
4885                return if analyze {
4886                    self.expected_at(
4887                        *self,
4888                        "SINK, TABLE, MATERIALIZED VIEW, INDEX or a statement after ANALYZE",
4889                    )
4890                } else {
4891                    error
4892                };
4893            }
4894        };
4895        Ok(Statement::Explain {
4896            analyze,
4897            statement: Box::new(statement),
4898            options,
4899        })
4900    }
4901
4902    pub fn parse_describe(&mut self) -> ModalResult<Statement> {
4903        let kind = match self.parse_one_of_keywords(&[Keyword::FRAGMENT, Keyword::FRAGMENTS]) {
4904            Some(Keyword::FRAGMENT) => {
4905                let fragment_id = self.parse_literal_u32()?;
4906                return Ok(Statement::DescribeFragment { fragment_id });
4907            }
4908            Some(Keyword::FRAGMENTS) => DescribeKind::Fragments,
4909            None => DescribeKind::Plain,
4910            Some(_) => unreachable!(),
4911        };
4912        let name = self.parse_object_name()?;
4913        Ok(Statement::Describe { name, kind })
4914    }
4915
4916    /// Parse a query expression, i.e. a `SELECT` statement optionally
4917    /// preceded with some `WITH` CTE declarations and optionally followed
4918    /// by `ORDER BY`. Unlike some other parse_... methods, this one doesn't
4919    /// expect the initial keyword to be already consumed
4920    pub fn parse_query(&mut self) -> ModalResult<Query> {
4921        let with = if self.parse_keyword(Keyword::WITH) {
4922            Some(With {
4923                recursive: self.parse_keyword(Keyword::RECURSIVE),
4924                cte_tables: self.parse_comma_separated(Parser::parse_cte)?,
4925            })
4926        } else {
4927            None
4928        };
4929
4930        let body = self.parse_query_body(0)?;
4931
4932        let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
4933            self.parse_comma_separated(Parser::parse_order_by_expr)?
4934        } else {
4935            vec![]
4936        };
4937
4938        let mut limit = None;
4939        let mut offset = None;
4940        for _x in 0..2 {
4941            if limit.is_none() && self.parse_keyword(Keyword::LIMIT) {
4942                limit = self.parse_limit()?
4943            }
4944
4945            if offset.is_none() && self.parse_keyword(Keyword::OFFSET) {
4946                offset = Some(self.parse_offset()?)
4947            }
4948        }
4949
4950        let fetch = if self.parse_keyword(Keyword::FETCH) {
4951            if limit.is_some() {
4952                parser_err!("Cannot specify both LIMIT and FETCH");
4953            }
4954            let fetch = self.parse_fetch()?;
4955            if fetch.with_ties && order_by.is_empty() {
4956                parser_err!("WITH TIES cannot be specified without ORDER BY clause");
4957            }
4958            Some(fetch)
4959        } else {
4960            None
4961        };
4962
4963        Ok(Query {
4964            with,
4965            body,
4966            order_by,
4967            limit,
4968            offset,
4969            fetch,
4970        })
4971    }
4972
4973    /// Parse a CTE (`alias [( col1, col2, ... )] AS (subquery)`)
4974    fn parse_cte(&mut self) -> ModalResult<Cte> {
4975        let name = self.parse_identifier_non_reserved()?;
4976        let cte = if self.parse_keyword(Keyword::AS) {
4977            let cte_inner = self.parse_cte_inner()?;
4978            let alias = TableAlias {
4979                name,
4980                columns: vec![],
4981            };
4982            Cte { alias, cte_inner }
4983        } else {
4984            let columns = self.parse_parenthesized_column_list(Optional)?;
4985            self.expect_keyword(Keyword::AS)?;
4986            let cte_inner = self.parse_cte_inner()?;
4987            let alias = TableAlias { name, columns };
4988            Cte { alias, cte_inner }
4989        };
4990        Ok(cte)
4991    }
4992
4993    fn parse_cte_inner(&mut self) -> ModalResult<CteInner> {
4994        match self.expect_token(&Token::LParen) {
4995            Ok(()) => {
4996                let query = self.parse_query()?;
4997                self.expect_token(&Token::RParen)?;
4998                Ok(CteInner::Query(Box::new(query)))
4999            }
5000            _ => {
5001                let changelog = self.parse_identifier_non_reserved()?;
5002                if changelog.to_string().to_lowercase() != "changelog" {
5003                    parser_err!("Expected 'changelog' but found '{}'", changelog);
5004                }
5005                self.expect_keyword(Keyword::FROM)?;
5006                let from = self.parse_object_name()?;
5007                let key = self
5008                    .parse_keyword(Keyword::KEY)
5009                    .then(|| self.parse_parenthesized_column_list(Mandatory))
5010                    .transpose()?;
5011
5012                Ok(CteInner::ChangeLog { from, key })
5013            }
5014        }
5015    }
5016
5017    /// Parse a "query body", which is an expression with roughly the
5018    /// following grammar:
5019    /// ```text
5020    ///   query_body ::= restricted_select | '(' subquery ')' | set_operation
5021    ///   restricted_select ::= 'SELECT' [expr_list] [ from ] [ where ] [ groupby_having ]
5022    ///   subquery ::= query_body [ order_by_limit ]
5023    ///   set_operation ::= query_body { 'UNION' | 'EXCEPT' | 'INTERSECT' } [ 'ALL' ] query_body
5024    /// ```
5025    fn parse_query_body(&mut self, precedence: u8) -> ModalResult<SetExpr> {
5026        // We parse the expression using a Pratt parser, as in `parse_expr()`.
5027        // Start by parsing a restricted SELECT or a `(subquery)`:
5028        let mut expr = if self.parse_keyword(Keyword::SELECT) {
5029            SetExpr::Select(Box::new(self.parse_select()?))
5030        } else if self.consume_token(&Token::LParen) {
5031            // CTEs are not allowed here, but the parser currently accepts them
5032            let subquery = self.parse_query()?;
5033            self.expect_token(&Token::RParen)?;
5034            SetExpr::Query(Box::new(subquery))
5035        } else if self.parse_keyword(Keyword::VALUES) {
5036            SetExpr::Values(self.parse_values()?)
5037        } else {
5038            return self.expected("SELECT, VALUES, or a subquery in the query body");
5039        };
5040
5041        loop {
5042            // The query can be optionally followed by a set operator:
5043            let op = self.parse_set_operator(&self.peek_token().token);
5044            let next_precedence = match op {
5045                // UNION and EXCEPT have the same binding power and evaluate left-to-right
5046                Some(SetOperator::Union) | Some(SetOperator::Except) => 10,
5047                // INTERSECT has higher precedence than UNION/EXCEPT
5048                Some(SetOperator::Intersect) => 20,
5049                // Unexpected token or EOF => stop parsing the query body
5050                None => break,
5051            };
5052            if precedence >= next_precedence {
5053                break;
5054            }
5055            self.next_token(); // skip past the set operator
5056
5057            let all = self.parse_keyword(Keyword::ALL);
5058            let corresponding = self.parse_corresponding()?;
5059
5060            expr = SetExpr::SetOperation {
5061                left: Box::new(expr),
5062                op: op.unwrap(),
5063                corresponding,
5064                all,
5065                right: Box::new(self.parse_query_body(next_precedence)?),
5066            };
5067        }
5068
5069        Ok(expr)
5070    }
5071
5072    fn parse_set_operator(&mut self, token: &Token) -> Option<SetOperator> {
5073        match token {
5074            Token::Word(w) if w.keyword == Keyword::UNION => Some(SetOperator::Union),
5075            Token::Word(w) if w.keyword == Keyword::EXCEPT => Some(SetOperator::Except),
5076            Token::Word(w) if w.keyword == Keyword::INTERSECT => Some(SetOperator::Intersect),
5077            _ => None,
5078        }
5079    }
5080
5081    fn parse_corresponding(&mut self) -> ModalResult<Corresponding> {
5082        let corresponding = if self.parse_keyword(Keyword::CORRESPONDING) {
5083            let column_list = if self.parse_keyword(Keyword::BY) {
5084                Some(self.parse_parenthesized_column_list(IsOptional::Mandatory)?)
5085            } else {
5086                None
5087            };
5088            Corresponding::with_column_list(column_list)
5089        } else {
5090            Corresponding::none()
5091        };
5092        Ok(corresponding)
5093    }
5094
5095    /// Parse a restricted `SELECT` statement (no CTEs / `UNION` / `ORDER BY`),
5096    /// assuming the initial `SELECT` was already consumed
5097    pub fn parse_select(&mut self) -> ModalResult<Select> {
5098        let distinct = self.parse_all_or_distinct_on()?;
5099
5100        let projection = self.parse_comma_separated(Parser::parse_select_item)?;
5101
5102        // Note that for keywords to be properly handled here, they need to be
5103        // added to `RESERVED_FOR_COLUMN_ALIAS` / `RESERVED_FOR_TABLE_ALIAS`,
5104        // otherwise they may be parsed as an alias as part of the `projection`
5105        // or `from`.
5106
5107        let from = if self.parse_keyword(Keyword::FROM) {
5108            self.parse_comma_separated(Parser::parse_table_and_joins)?
5109        } else {
5110            vec![]
5111        };
5112        let mut lateral_views = vec![];
5113        loop {
5114            if self.parse_keywords(&[Keyword::LATERAL, Keyword::VIEW]) {
5115                let outer = self.parse_keyword(Keyword::OUTER);
5116                let lateral_view = self.parse_expr()?;
5117                let lateral_view_name = self.parse_object_name()?;
5118                let lateral_col_alias = self
5119                    .parse_comma_separated(|parser| {
5120                        parser.parse_optional_alias(&[
5121                            Keyword::WHERE,
5122                            Keyword::GROUP,
5123                            Keyword::CLUSTER,
5124                            Keyword::HAVING,
5125                            Keyword::LATERAL,
5126                        ]) // This couldn't possibly be a bad idea
5127                    })?
5128                    .into_iter()
5129                    .flatten()
5130                    .collect();
5131
5132                lateral_views.push(LateralView {
5133                    lateral_view,
5134                    lateral_view_name,
5135                    lateral_col_alias,
5136                    outer,
5137                });
5138            } else {
5139                break;
5140            }
5141        }
5142
5143        let selection = if self.parse_keyword(Keyword::WHERE) {
5144            Some(self.parse_expr()?)
5145        } else {
5146            None
5147        };
5148
5149        let group_by = if self.parse_keywords(&[Keyword::GROUP, Keyword::BY]) {
5150            self.parse_comma_separated(Parser::parse_group_by_expr)?
5151        } else {
5152            vec![]
5153        };
5154
5155        let having = if self.parse_keyword(Keyword::HAVING) {
5156            Some(self.parse_expr()?)
5157        } else {
5158            None
5159        };
5160
5161        let window = if self.parse_keyword(Keyword::WINDOW) {
5162            self.parse_comma_separated(Parser::parse_named_window)?
5163        } else {
5164            vec![]
5165        };
5166
5167        Ok(Select {
5168            distinct,
5169            projection,
5170            from,
5171            lateral_views,
5172            selection,
5173            group_by,
5174            having,
5175            window,
5176        })
5177    }
5178
5179    pub fn parse_set(&mut self) -> ModalResult<Statement> {
5180        let modifier = self.parse_one_of_keywords(&[Keyword::SESSION, Keyword::LOCAL]);
5181        if self.parse_keywords(&[Keyword::TIME, Keyword::ZONE]) {
5182            let value = alt((
5183                Keyword::DEFAULT.value(SetTimeZoneValue::Default),
5184                Keyword::LOCAL.value(SetTimeZoneValue::Local),
5185                preceded(
5186                    Keyword::INTERVAL,
5187                    cut_err(Self::parse_literal_interval.try_map(|e| match e {
5188                        // support a special case for clients which would send when initializing the connection
5189                        // like: SET TIME ZONE INTERVAL '+00:00' HOUR TO MINUTE;
5190                        Expr::Value(v) => match v {
5191                            Value::Interval { value, .. } => {
5192                                if value != "+00:00" {
5193                                    return Err(StrError("only support \"+00:00\" ".into()));
5194                                }
5195                                Ok(SetTimeZoneValue::Ident(Ident::with_quote_unchecked(
5196                                    '\'',
5197                                    "UTC".to_owned(),
5198                                )))
5199                            }
5200                            _ => Err(StrError("expect Value::Interval".into())),
5201                        },
5202                        _ => Err(StrError("expect Expr::Value".into())),
5203                    })),
5204                ),
5205                Self::parse_identifier.map(SetTimeZoneValue::Ident),
5206                Self::ensure_parse_value.map(SetTimeZoneValue::Literal),
5207            ))
5208            .expect("variable")
5209            .parse_next(self)?;
5210
5211            Ok(Statement::SetTimeZone {
5212                local: modifier == Some(Keyword::LOCAL),
5213                value,
5214            })
5215        } else if self.parse_keyword(Keyword::CHARACTERISTICS) && modifier == Some(Keyword::SESSION)
5216        {
5217            self.expect_keywords(&[Keyword::AS, Keyword::TRANSACTION])?;
5218            Ok(Statement::SetTransaction {
5219                modes: self.parse_transaction_modes()?,
5220                snapshot: None,
5221                session: true,
5222            })
5223        } else if self.parse_keyword(Keyword::TRANSACTION) && modifier.is_none() {
5224            if self.parse_keyword(Keyword::SNAPSHOT) {
5225                let snapshot_id = self.ensure_parse_value()?;
5226                return Ok(Statement::SetTransaction {
5227                    modes: vec![],
5228                    snapshot: Some(snapshot_id),
5229                    session: false,
5230                });
5231            }
5232            Ok(Statement::SetTransaction {
5233                modes: self.parse_transaction_modes()?,
5234                snapshot: None,
5235                session: false,
5236            })
5237        } else {
5238            let config_param = self.parse_config_param()?;
5239            Ok(Statement::SetVariable {
5240                local: modifier == Some(Keyword::LOCAL),
5241                variable: config_param.param,
5242                value: config_param.value,
5243            })
5244        }
5245    }
5246
5247    /// If have `databases`,`tables`,`columns`,`schemas` and `materialized views` after show,
5248    /// return `Statement::ShowCommand` or `Statement::ShowColumn`,
5249    /// otherwise, return `Statement::ShowVariable`.
5250    pub fn parse_show(&mut self) -> ModalResult<Statement> {
5251        let checkpoint = *self;
5252        if let Token::Word(w) = self.next_token().token {
5253            match w.keyword {
5254                Keyword::TABLES => {
5255                    return Ok(Statement::ShowObjects {
5256                        object: ShowObject::Table {
5257                            schema: self.parse_from_and_identifier()?,
5258                        },
5259                        filter: self.parse_show_statement_filter()?,
5260                    });
5261                }
5262                Keyword::INTERNAL => {
5263                    self.expect_keyword(Keyword::TABLES)?;
5264                    return Ok(Statement::ShowObjects {
5265                        object: ShowObject::InternalTable {
5266                            schema: self.parse_from_and_identifier()?,
5267                        },
5268                        filter: self.parse_show_statement_filter()?,
5269                    });
5270                }
5271                Keyword::SOURCES => {
5272                    return Ok(Statement::ShowObjects {
5273                        object: ShowObject::Source {
5274                            schema: self.parse_from_and_identifier()?,
5275                        },
5276                        filter: self.parse_show_statement_filter()?,
5277                    });
5278                }
5279                Keyword::SINKS => {
5280                    return Ok(Statement::ShowObjects {
5281                        object: ShowObject::Sink {
5282                            schema: self.parse_from_and_identifier()?,
5283                        },
5284                        filter: self.parse_show_statement_filter()?,
5285                    });
5286                }
5287                Keyword::SUBSCRIPTIONS => {
5288                    return Ok(Statement::ShowObjects {
5289                        object: ShowObject::Subscription {
5290                            schema: self.parse_from_and_identifier()?,
5291                        },
5292                        filter: self.parse_show_statement_filter()?,
5293                    });
5294                }
5295                Keyword::DATABASES => {
5296                    return Ok(Statement::ShowObjects {
5297                        object: ShowObject::Database,
5298                        filter: self.parse_show_statement_filter()?,
5299                    });
5300                }
5301                Keyword::SCHEMAS => {
5302                    return Ok(Statement::ShowObjects {
5303                        object: ShowObject::Schema,
5304                        filter: self.parse_show_statement_filter()?,
5305                    });
5306                }
5307                Keyword::VIEWS => {
5308                    return Ok(Statement::ShowObjects {
5309                        object: ShowObject::View {
5310                            schema: self.parse_from_and_identifier()?,
5311                        },
5312                        filter: self.parse_show_statement_filter()?,
5313                    });
5314                }
5315                Keyword::MATERIALIZED => {
5316                    if self.parse_keyword(Keyword::VIEWS) {
5317                        return Ok(Statement::ShowObjects {
5318                            object: ShowObject::MaterializedView {
5319                                schema: self.parse_from_and_identifier()?,
5320                            },
5321                            filter: self.parse_show_statement_filter()?,
5322                        });
5323                    } else {
5324                        return self.expected("VIEWS after MATERIALIZED");
5325                    }
5326                }
5327                Keyword::COLUMNS => {
5328                    if self.parse_keyword(Keyword::FROM) {
5329                        return Ok(Statement::ShowObjects {
5330                            object: ShowObject::Columns {
5331                                table: self.parse_object_name()?,
5332                            },
5333                            filter: self.parse_show_statement_filter()?,
5334                        });
5335                    } else {
5336                        return self.expected("from after columns");
5337                    }
5338                }
5339                Keyword::SECRETS => {
5340                    return Ok(Statement::ShowObjects {
5341                        object: ShowObject::Secret {
5342                            schema: self.parse_from_and_identifier()?,
5343                        },
5344                        filter: self.parse_show_statement_filter()?,
5345                    });
5346                }
5347                Keyword::CONNECTIONS => {
5348                    return Ok(Statement::ShowObjects {
5349                        object: ShowObject::Connection {
5350                            schema: self.parse_from_and_identifier()?,
5351                        },
5352                        filter: self.parse_show_statement_filter()?,
5353                    });
5354                }
5355                Keyword::FUNCTIONS => {
5356                    return Ok(Statement::ShowObjects {
5357                        object: ShowObject::Function {
5358                            schema: self.parse_from_and_identifier()?,
5359                        },
5360                        filter: self.parse_show_statement_filter()?,
5361                    });
5362                }
5363                Keyword::INDEXES => {
5364                    if self.parse_keyword(Keyword::FROM) {
5365                        return Ok(Statement::ShowObjects {
5366                            object: ShowObject::Indexes {
5367                                table: self.parse_object_name()?,
5368                            },
5369                            filter: self.parse_show_statement_filter()?,
5370                        });
5371                    } else {
5372                        return self.expected("from after indexes");
5373                    }
5374                }
5375                Keyword::CLUSTER => {
5376                    return Ok(Statement::ShowObjects {
5377                        object: ShowObject::Cluster,
5378                        filter: self.parse_show_statement_filter()?,
5379                    });
5380                }
5381                Keyword::JOBS => {
5382                    return Ok(Statement::ShowObjects {
5383                        object: ShowObject::Jobs,
5384                        filter: self.parse_show_statement_filter()?,
5385                    });
5386                }
5387                Keyword::PROCESSLIST => {
5388                    return Ok(Statement::ShowObjects {
5389                        object: ShowObject::ProcessList,
5390                        filter: self.parse_show_statement_filter()?,
5391                    });
5392                }
5393                Keyword::TRANSACTION => {
5394                    self.expect_keywords(&[Keyword::ISOLATION, Keyword::LEVEL])?;
5395                    return Ok(Statement::ShowTransactionIsolationLevel);
5396                }
5397                Keyword::CURSORS => {
5398                    return Ok(Statement::ShowObjects {
5399                        object: ShowObject::Cursor,
5400                        filter: None,
5401                    });
5402                }
5403                Keyword::SUBSCRIPTION => {
5404                    self.expect_keyword(Keyword::CURSORS)?;
5405                    return Ok(Statement::ShowObjects {
5406                        object: ShowObject::SubscriptionCursor,
5407                        filter: None,
5408                    });
5409                }
5410                _ => {}
5411            }
5412        }
5413        *self = checkpoint;
5414        Ok(Statement::ShowVariable {
5415            variable: self.parse_identifiers()?,
5416        })
5417    }
5418
5419    pub fn parse_cancel_job(&mut self) -> ModalResult<Statement> {
5420        // CANCEL [JOBS|JOB] job_ids
5421        match self.peek_token().token {
5422            Token::Word(w) if Keyword::JOBS == w.keyword || Keyword::JOB == w.keyword => {
5423                self.next_token();
5424            }
5425            _ => return self.expected("JOBS or JOB after CANCEL"),
5426        }
5427
5428        let mut job_ids = vec![];
5429        loop {
5430            job_ids.push(self.parse_literal_u32()?);
5431            if !self.consume_token(&Token::Comma) {
5432                break;
5433            }
5434        }
5435        Ok(Statement::CancelJobs(JobIdents(job_ids)))
5436    }
5437
5438    pub fn parse_kill_process(&mut self) -> ModalResult<Statement> {
5439        let worker_process_id = self.parse_literal_string()?;
5440        Ok(Statement::Kill(worker_process_id))
5441    }
5442
5443    /// Parser `from schema` after `show tables` and `show materialized views`, if not conclude
5444    /// `from` then use default schema name.
5445    pub fn parse_from_and_identifier(&mut self) -> ModalResult<Option<Ident>> {
5446        if self.parse_keyword(Keyword::FROM) {
5447            Ok(Some(self.parse_identifier_non_reserved()?))
5448        } else {
5449            Ok(None)
5450        }
5451    }
5452
5453    /// Parse object type and name after `show create`.
5454    pub fn parse_show_create(&mut self) -> ModalResult<Statement> {
5455        if let Token::Word(w) = self.next_token().token {
5456            let show_type = match w.keyword {
5457                Keyword::TABLE => ShowCreateType::Table,
5458                Keyword::MATERIALIZED => {
5459                    if self.parse_keyword(Keyword::VIEW) {
5460                        ShowCreateType::MaterializedView
5461                    } else {
5462                        return self.expected("VIEW after MATERIALIZED");
5463                    }
5464                }
5465                Keyword::VIEW => ShowCreateType::View,
5466                Keyword::INDEX => ShowCreateType::Index,
5467                Keyword::SOURCE => ShowCreateType::Source,
5468                Keyword::SINK => ShowCreateType::Sink,
5469                Keyword::SUBSCRIPTION => ShowCreateType::Subscription,
5470                Keyword::FUNCTION => ShowCreateType::Function,
5471                _ => return self.expected(
5472                    "TABLE, MATERIALIZED VIEW, VIEW, INDEX, FUNCTION, SOURCE, SUBSCRIPTION or SINK",
5473                ),
5474            };
5475            return Ok(Statement::ShowCreateObject {
5476                create_type: show_type,
5477                name: self.parse_object_name()?,
5478            });
5479        }
5480        self.expected(
5481            "TABLE, MATERIALIZED VIEW, VIEW, INDEX, FUNCTION, SOURCE, SUBSCRIPTION or SINK",
5482        )
5483    }
5484
5485    pub fn parse_show_statement_filter(&mut self) -> ModalResult<Option<ShowStatementFilter>> {
5486        if self.parse_keyword(Keyword::LIKE) {
5487            Ok(Some(ShowStatementFilter::Like(
5488                self.parse_literal_string()?,
5489            )))
5490        } else if self.parse_keyword(Keyword::ILIKE) {
5491            Ok(Some(ShowStatementFilter::ILike(
5492                self.parse_literal_string()?,
5493            )))
5494        } else if self.parse_keyword(Keyword::WHERE) {
5495            Ok(Some(ShowStatementFilter::Where(self.parse_expr()?)))
5496        } else {
5497            Ok(None)
5498        }
5499    }
5500
5501    pub fn parse_table_and_joins(&mut self) -> ModalResult<TableWithJoins> {
5502        let relation = self.parse_table_factor()?;
5503
5504        // Note that for keywords to be properly handled here, they need to be
5505        // added to `RESERVED_FOR_TABLE_ALIAS`, otherwise they may be parsed as
5506        // a table alias.
5507        let mut joins = vec![];
5508        loop {
5509            let join_checkpoint = *self;
5510            let join = if self.parse_keyword(Keyword::CROSS) {
5511                let join_operator = if self.parse_keyword(Keyword::JOIN) {
5512                    JoinOperator::CrossJoin
5513                } else {
5514                    return self.expected("JOIN after CROSS");
5515                };
5516                Join {
5517                    relation: self.parse_table_factor()?,
5518                    join_operator,
5519                }
5520            } else {
5521                let broadcast = self.peek_broadcast_join();
5522                if broadcast {
5523                    let _ = self.next_token();
5524                }
5525                let (natural, asof) =
5526                    match self.parse_one_of_keywords(&[Keyword::NATURAL, Keyword::ASOF]) {
5527                        Some(Keyword::NATURAL) => (true, false),
5528                        Some(Keyword::ASOF) => (false, true),
5529                        Some(_) => unreachable!(),
5530                        None => (false, false),
5531                    };
5532                let peek_keyword = if let Token::Word(w) = self.peek_token().token {
5533                    w.keyword
5534                } else {
5535                    Keyword::NoKeyword
5536                };
5537
5538                let join_operator_type = match peek_keyword {
5539                    Keyword::INNER | Keyword::JOIN => {
5540                        let _ = self.parse_keyword(Keyword::INNER);
5541                        self.expect_keyword(Keyword::JOIN)?;
5542                        if asof {
5543                            JoinOperator::AsOfInner
5544                        } else {
5545                            JoinOperator::Inner
5546                        }
5547                    }
5548                    kw @ Keyword::LEFT | kw @ Keyword::RIGHT | kw @ Keyword::FULL => {
5549                        let checkpoint = *self;
5550                        let _ = self.next_token();
5551                        let _ = self.parse_keyword(Keyword::OUTER);
5552                        self.expect_keyword(Keyword::JOIN)?;
5553                        if asof {
5554                            if Keyword::LEFT == kw {
5555                                JoinOperator::AsOfLeft
5556                            } else {
5557                                return self.expected_at(
5558                                    checkpoint,
5559                                    "LEFT after ASOF. RIGHT or FULL are not supported",
5560                                );
5561                            }
5562                        } else {
5563                            match kw {
5564                                Keyword::LEFT => JoinOperator::LeftOuter,
5565                                Keyword::RIGHT => JoinOperator::RightOuter,
5566                                Keyword::FULL => JoinOperator::FullOuter,
5567                                _ => unreachable!(),
5568                            }
5569                        }
5570                    }
5571                    Keyword::OUTER => {
5572                        return self.expected("LEFT, RIGHT, or FULL");
5573                    }
5574                    _ if natural => {
5575                        return self.expected("a join type after NATURAL");
5576                    }
5577                    _ if asof => {
5578                        return self.expected("a join type after ASOF");
5579                    }
5580                    _ if broadcast => {
5581                        return self.expected_at(join_checkpoint, "a join type after BROADCAST");
5582                    }
5583                    _ => break,
5584                };
5585                let mut relation = self.parse_table_factor()?;
5586                let join_constraint = self.parse_join_constraint(natural)?;
5587                let join_operator = join_operator_type(join_constraint);
5588                if broadcast {
5589                    if !matches!(
5590                        join_operator,
5591                        JoinOperator::Inner(_) | JoinOperator::LeftOuter(_)
5592                    ) {
5593                        return self.expected_at(
5594                            join_checkpoint,
5595                            "INNER or LEFT temporal join after BROADCAST",
5596                        );
5597                    }
5598                    match &mut relation {
5599                        TableFactor::Table {
5600                            as_of: Some(as_of), ..
5601                        } if matches!(as_of, AsOf::ProcessTime) => {
5602                            *as_of = AsOf::ProcessTimeBroadcast;
5603                        }
5604                        _ => {
5605                            return self.expected_at(
5606                                join_checkpoint,
5607                                "a table with FOR SYSTEM_TIME AS OF PROCTIME() after BROADCAST JOIN",
5608                            );
5609                        }
5610                    }
5611                }
5612                let need_constraint = match join_operator {
5613                    JoinOperator::Inner(JoinConstraint::None) => Some("INNER JOIN"),
5614                    JoinOperator::AsOfInner(JoinConstraint::None) => Some("ASOF INNER JOIN"),
5615                    JoinOperator::AsOfLeft(JoinConstraint::None) => Some("ASOF LEFT JOIN"),
5616                    _ => None,
5617                };
5618                if let Some(join_type) = need_constraint {
5619                    return self.expected(&format!("join constraint after {join_type}"));
5620                }
5621
5622                Join {
5623                    relation,
5624                    join_operator,
5625                }
5626            };
5627            joins.push(join);
5628        }
5629        Ok(TableWithJoins { relation, joins })
5630    }
5631
5632    /// Whether the next tokens start a supported broadcast join.
5633    ///
5634    /// `BROADCAST` remains a regular identifier outside this exact position so that existing
5635    /// table aliases and identifier formatting remain compatible.
5636    fn peek_broadcast_join(&self) -> bool {
5637        matches!(
5638            self.peek_nth_token(0).token,
5639            Token::Word(word)
5640                if word.quote_style.is_none() && word.value.eq_ignore_ascii_case("BROADCAST")
5641        ) && matches!(
5642            self.peek_nth_token(1).token,
5643            Token::Word(word)
5644                if matches!(word.keyword, Keyword::INNER | Keyword::JOIN | Keyword::LEFT)
5645        )
5646    }
5647
5648    /// A table name or a parenthesized subquery, followed by optional `[AS] alias`
5649    pub fn parse_table_factor(&mut self) -> ModalResult<TableFactor> {
5650        let relation = self.parse_table_factor_inner()?;
5651        // Contextual, not a keyword: only `MATCH_RECOGNIZE (` opens the clause (the alias parser
5652        // above declines exactly that shape), so a bare `match_recognize` elsewhere remains an
5653        // ordinary identifier.
5654        let checkpoint = *self;
5655        if self.parse_word("MATCH_RECOGNIZE") {
5656            if self.peek_token() == Token::LParen {
5657                return self.parse_match_recognize(relation);
5658            }
5659            *self = checkpoint;
5660        }
5661        Ok(relation)
5662    }
5663
5664    fn parse_table_factor_inner(&mut self) -> ModalResult<TableFactor> {
5665        if self.parse_keyword(Keyword::LATERAL) {
5666            // LATERAL must always be followed by a subquery.
5667            if !self.consume_token(&Token::LParen) {
5668                self.expected("subquery after LATERAL")?;
5669            }
5670            self.parse_derived_table_factor(Lateral)
5671        } else if self.consume_token(&Token::LParen) {
5672            // A left paren introduces either a derived table (i.e., a subquery)
5673            // or a nested join. It's nearly impossible to determine ahead of
5674            // time which it is... so we just try to parse both.
5675            //
5676            // Here's an example that demonstrates the complexity:
5677            //                     /-------------------------------------------------------\
5678            //                     | /-----------------------------------\                 |
5679            //     SELECT * FROM ( ( ( (SELECT 1) UNION (SELECT 2) ) AS t1 NATURAL JOIN t2 ) )
5680            //                   ^ ^ ^ ^
5681            //                   | | | |
5682            //                   | | | |
5683            //                   | | | (4) belongs to a SetExpr::Query inside the subquery
5684            //                   | | (3) starts a derived table (subquery)
5685            //                   | (2) starts a nested join
5686            //                   (1) an additional set of parens around a nested join
5687            //
5688
5689            // It can only be a subquery. We don't use `maybe_parse` so that a meaningful error can
5690            // be returned.
5691            match self.peek_token().token {
5692                Token::Word(w)
5693                    if [Keyword::SELECT, Keyword::WITH, Keyword::VALUES].contains(&w.keyword) =>
5694                {
5695                    return self.parse_derived_table_factor(NotLateral);
5696                }
5697                _ => {}
5698            };
5699            // It can still be a subquery, e.g., the case (3) in the example above:
5700            // (SELECT 1) UNION (SELECT 2)
5701            // TODO: how to produce a good error message here?
5702            if self.peek_token() == Token::LParen {
5703                return_ok_if_some!(
5704                    self.maybe_parse(|parser| parser.parse_derived_table_factor(NotLateral))
5705                );
5706            }
5707
5708            // A parsing error from `parse_derived_table_factor` indicates that the '(' we've
5709            // recently consumed does not start a derived table (cases 1, 2, or 4).
5710            // `maybe_parse` will ignore such an error and rewind to be after the opening '('.
5711
5712            // Inside the parentheses we expect to find an (A) table factor
5713            // followed by some joins or (B) another level of nesting.
5714            let table_and_joins = self.parse_table_and_joins()?;
5715
5716            if !table_and_joins.joins.is_empty() {
5717                self.expect_token(&Token::RParen)?;
5718                Ok(TableFactor::NestedJoin(Box::new(table_and_joins))) // (A)
5719            } else if let TableFactor::NestedJoin(_) = &table_and_joins.relation {
5720                // (B): `table_and_joins` (what we found inside the parentheses)
5721                // is a nested join `(foo JOIN bar)`, not followed by other joins.
5722                self.expect_token(&Token::RParen)?;
5723                Ok(TableFactor::NestedJoin(Box::new(table_and_joins)))
5724            } else {
5725                // The SQL spec prohibits derived tables and bare tables from
5726                // appearing alone in parentheses (e.g. `FROM (mytable)`)
5727                parser_err!(
5728                    "Expected joined table, found: {table_and_joins}, next_token: {}",
5729                    self.peek_token()
5730                );
5731            }
5732        } else {
5733            let name = self.parse_object_name()?;
5734            if self.peek_token() == Token::LParen {
5735                // table-valued function
5736
5737                let arg_list = self.parse_argument_list()?;
5738                if arg_list.distinct {
5739                    parser_err!("DISTINCT is not supported in table-valued function calls");
5740                }
5741                if !arg_list.order_by.is_empty() {
5742                    parser_err!("ORDER BY is not supported in table-valued function calls");
5743                }
5744                if arg_list.ignore_nulls {
5745                    parser_err!("IGNORE NULLS is not supported in table-valued function calls");
5746                }
5747
5748                let args = arg_list.args;
5749                let with_ordinality = self.parse_keywords(&[Keyword::WITH, Keyword::ORDINALITY]);
5750                let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5751
5752                Ok(TableFactor::TableFunction {
5753                    name,
5754                    alias,
5755                    args,
5756                    with_ordinality,
5757                })
5758            } else {
5759                let as_of = opt(Self::parse_as_of).parse_next(self)?;
5760                let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5761                Ok(TableFactor::Table { name, alias, as_of })
5762            }
5763        }
5764    }
5765
5766    pub fn parse_derived_table_factor(&mut self, lateral: IsLateral) -> ModalResult<TableFactor> {
5767        let subquery = Box::new(self.parse_query()?);
5768        self.expect_token(&Token::RParen)?;
5769        let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5770        Ok(TableFactor::Derived {
5771            lateral: match lateral {
5772                Lateral => true,
5773                NotLateral => false,
5774            },
5775            subquery,
5776            alias,
5777        })
5778    }
5779
5780    /// Parse the body of a `MATCH_RECOGNIZE (...)` clause applied to the already-parsed
5781    /// input `table`. Assumes the `MATCH_RECOGNIZE` keyword has just been consumed.
5782    ///
5783    /// Supported in this version: `PARTITION BY`, `ORDER BY`, `MEASURES`, rows-per-match,
5784    /// `AFTER MATCH SKIP`, `PATTERN` (named symbols, grouping, concatenation, alternation,
5785    /// `PERMUTE`, and the quantifiers `*` `+` `?` `{n}` `{n,}` `{,m}` `{n,m}`), and `DEFINE`.
5786    /// Row-pattern anchors (`^`, `$`) and exclusions (`{- -}`) are not yet parsed.
5787    fn parse_match_recognize(&mut self, table: TableFactor) -> ModalResult<TableFactor> {
5788        self.expect_token(&Token::LParen)?;
5789
5790        let partition_by = if self.parse_keywords(&[Keyword::PARTITION, Keyword::BY]) {
5791            self.parse_comma_separated(Parser::parse_expr)?
5792        } else {
5793            vec![]
5794        };
5795
5796        let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
5797            self.parse_comma_separated(Parser::parse_match_recognize_order_by_expr)?
5798        } else {
5799            vec![]
5800        };
5801
5802        let measures = if self.parse_word("MEASURES") {
5803            self.parse_comma_separated(Parser::parse_measure)?
5804        } else {
5805            vec![]
5806        };
5807
5808        let rows_per_match = if self.parse_words(&["ONE", "ROW", "PER", "MATCH"]) {
5809            Some(RowsPerMatch::OneRow)
5810        } else if self.parse_words(&["ALL", "ROWS", "PER", "MATCH"]) {
5811            Some(RowsPerMatch::AllRows)
5812        } else {
5813            None
5814        };
5815
5816        let after_match_skip = if self.parse_words(&["AFTER", "MATCH", "SKIP"]) {
5817            Some(self.parse_after_match_skip()?)
5818        } else {
5819            None
5820        };
5821
5822        self.expect_word("PATTERN")?;
5823        self.expect_token(&Token::LParen)?;
5824        let pattern = self.parse_pattern()?;
5825        self.expect_token(&Token::RParen)?;
5826
5827        // `WITHIN <interval>` bounds the time span of a match (streaming extension).
5828        let within = if self.parse_keyword(Keyword::WITHIN) {
5829            Some(self.parse_expr()?)
5830        } else {
5831            None
5832        };
5833
5834        let subsets = if self.parse_word("SUBSET") {
5835            self.parse_comma_separated(Parser::parse_subset_definition)?
5836        } else {
5837            vec![]
5838        };
5839
5840        self.expect_word("DEFINE")?;
5841        let symbols = self.parse_comma_separated(Parser::parse_symbol_definition)?;
5842
5843        self.expect_token(&Token::RParen)?;
5844
5845        let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
5846
5847        Ok(TableFactor::MatchRecognize {
5848            table: Box::new(table),
5849            partition_by,
5850            order_by,
5851            measures,
5852            rows_per_match,
5853            after_match_skip,
5854            pattern,
5855            within,
5856            subsets,
5857            symbols,
5858            alias,
5859        })
5860    }
5861
5862    /// Parse a `SUBSET` item: `<name> = ( <var>, ... )`.
5863    fn parse_subset_definition(&mut self) -> ModalResult<SubsetDefinition> {
5864        let name = self.parse_identifier()?;
5865        self.expect_token(&Token::Eq)?;
5866        self.expect_token(&Token::LParen)?;
5867        let members = self.parse_comma_separated(Parser::parse_identifier)?;
5868        self.expect_token(&Token::RParen)?;
5869        Ok(SubsetDefinition { name, members })
5870    }
5871
5872    fn parse_after_match_skip(&mut self) -> ModalResult<AfterMatchSkip> {
5873        if self.parse_words(&["PAST", "LAST", "ROW"]) {
5874            Ok(AfterMatchSkip::PastLastRow)
5875        } else if self.parse_keywords(&[Keyword::TO, Keyword::NEXT, Keyword::ROW]) {
5876            Ok(AfterMatchSkip::ToNextRow)
5877        } else if self.parse_keywords(&[Keyword::TO, Keyword::FIRST]) {
5878            Ok(AfterMatchSkip::ToFirst(self.parse_identifier()?))
5879        } else if self.parse_keywords(&[Keyword::TO, Keyword::LAST]) {
5880            Ok(AfterMatchSkip::ToLast(self.parse_identifier()?))
5881        } else {
5882            self.expected(
5883                "PAST LAST ROW, TO NEXT ROW, TO FIRST <symbol>, or TO LAST <symbol> after AFTER MATCH SKIP",
5884            )
5885        }
5886    }
5887
5888    /// Parse an `ORDER BY` item inside `MATCH_RECOGNIZE`. The sort key is parsed with a
5889    /// `Precedence::Other` floor so a trailing `ALL` (as in `ALL ROWS PER MATCH`) is not
5890    /// swallowed by the `<expr> ALL (...)` quantified-comparison grammar. Arithmetic still
5891    /// binds; a comparison/logical sort key must be parenthesized.
5892    fn parse_match_recognize_order_by_expr(&mut self) -> ModalResult<OrderByExpr> {
5893        let expr = self.parse_subexpr(Precedence::Other)?;
5894
5895        let asc = if self.parse_keyword(Keyword::ASC) {
5896            Some(true)
5897        } else if self.parse_keyword(Keyword::DESC) {
5898            Some(false)
5899        } else {
5900            None
5901        };
5902
5903        let nulls_first = if self.parse_keywords(&[Keyword::NULLS, Keyword::FIRST]) {
5904            Some(true)
5905        } else if self.parse_keywords(&[Keyword::NULLS, Keyword::LAST]) {
5906            Some(false)
5907        } else {
5908            None
5909        };
5910
5911        Ok(OrderByExpr {
5912            expr,
5913            asc,
5914            nulls_first,
5915        })
5916    }
5917
5918    fn parse_measure(&mut self) -> ModalResult<Measure> {
5919        let expr = self.parse_expr()?;
5920        self.expect_keyword(Keyword::AS)?;
5921        let alias = self.parse_identifier()?;
5922        Ok(Measure { expr, alias })
5923    }
5924
5925    fn parse_symbol_definition(&mut self) -> ModalResult<SymbolDefinition> {
5926        let symbol = self.parse_identifier()?;
5927        self.expect_keyword(Keyword::AS)?;
5928        let definition = self.parse_expr()?;
5929        Ok(SymbolDefinition { symbol, definition })
5930    }
5931
5932    /// A row pattern: alternation of concatenations (alternation has the lowest precedence).
5933    fn parse_pattern(&mut self) -> ModalResult<MatchRecognizePattern> {
5934        // The tokenizer greedily fuses adjacent operator characters, so `a+|b` arrives as
5935        // `Op("+|")`: a quantifier carrying the alternation pipe in the same token. The quantifier
5936        // parser strips and reports that trailing pipe (it cannot be pushed back), and this loop
5937        // treats it exactly like a free-standing one.
5938        let (first, mut fused_pipe) = self.parse_pattern_concat()?;
5939        let mut alternatives = vec![first];
5940        while fused_pipe || self.consume_pattern_pipe() {
5941            let (next, fp) = self.parse_pattern_concat()?;
5942            alternatives.push(next);
5943            fused_pipe = fp;
5944        }
5945        if alternatives.len() == 1 {
5946            Ok(alternatives.pop().unwrap())
5947        } else {
5948            Ok(MatchRecognizePattern::Alternation(alternatives))
5949        }
5950    }
5951
5952    /// A concatenation of quantified primaries, terminated by `)`, `|` (possibly fused into the
5953    /// preceding quantifier's token), or end of input. The bool reports that fused pipe.
5954    fn parse_pattern_concat(&mut self) -> ModalResult<(MatchRecognizePattern, bool)> {
5955        let (first, mut fused_pipe) = self.parse_pattern_repetition()?;
5956        let mut terms = vec![first];
5957        while !fused_pipe
5958            && !matches!(self.peek_token().token, Token::RParen | Token::EOF)
5959            && !self.peek_is_pattern_pipe()
5960        {
5961            let (next, fp) = self.parse_pattern_repetition()?;
5962            terms.push(next);
5963            fused_pipe = fp;
5964        }
5965        let pattern = if terms.len() == 1 {
5966            terms.pop().unwrap()
5967        } else {
5968            MatchRecognizePattern::Concat(terms)
5969        };
5970        Ok((pattern, fused_pipe))
5971    }
5972
5973    /// A pattern primary with an optional trailing quantifier. The bool reports an alternation
5974    /// pipe fused into the quantifier's own token (`a+|b`), which the caller must honour.
5975    fn parse_pattern_repetition(&mut self) -> ModalResult<(MatchRecognizePattern, bool)> {
5976        let primary = self.parse_pattern_primary()?;
5977        if let Some((quantifier, reluctant, fused_pipe)) =
5978            self.parse_optional_pattern_quantifier()?
5979        {
5980            Ok((
5981                MatchRecognizePattern::Repetition(Box::new(primary), quantifier, reluctant),
5982                fused_pipe,
5983            ))
5984        } else {
5985            Ok((primary, false))
5986        }
5987    }
5988
5989    /// Consume a trailing reluctant marker `?`. The alternation pipe may be fused into the same
5990    /// operator token (`{2}?|b` tokenizes the `?|` as one `Op`), so the second bool reports a
5991    /// consumed pipe for the caller to honour.
5992    fn consume_pattern_reluctant_mark(&mut self) -> (bool, bool) {
5993        match &self.peek_token().token {
5994            Token::Op(op) if op == "?" => {
5995                self.next_token();
5996                (true, false)
5997            }
5998            Token::Op(op) if op == "?|" => {
5999                self.next_token();
6000                (true, true)
6001            }
6002            _ => (false, false),
6003        }
6004    }
6005
6006    /// A pattern primary: a parenthesized sub-pattern, `PERMUTE(...)`, or a named symbol.
6007    fn parse_pattern_primary(&mut self) -> ModalResult<MatchRecognizePattern> {
6008        if self.consume_token(&Token::LParen) {
6009            let inner = self.parse_pattern()?;
6010            self.expect_token(&Token::RParen)?;
6011            Ok(MatchRecognizePattern::Group(Box::new(inner)))
6012        } else if self.parse_word("PERMUTE") {
6013            self.expect_token(&Token::LParen)?;
6014            let symbols = self.parse_comma_separated(Parser::parse_pattern_symbol)?;
6015            self.expect_token(&Token::RParen)?;
6016            Ok(MatchRecognizePattern::Permute(symbols))
6017        } else {
6018            Ok(MatchRecognizePattern::Symbol(self.parse_pattern_symbol()?))
6019        }
6020    }
6021
6022    fn parse_pattern_symbol(&mut self) -> ModalResult<MatchRecognizeSymbol> {
6023        Ok(MatchRecognizeSymbol::Named(self.parse_identifier()?))
6024    }
6025
6026    /// Parse an optional pattern quantifier: `*`, `+`, `?`, or a `{...}` range.
6027    /// Returns `(quantifier, reluctant, fused_pipe)` — the last reporting an alternation `|` the
6028    /// tokenizer fused into the quantifier's own operator token, which the caller must honour.
6029    fn parse_optional_pattern_quantifier(
6030        &mut self,
6031    ) -> ModalResult<Option<(RepetitionQuantifier, bool, bool)>> {
6032        if self.consume_token(&Token::LBrace) {
6033            // The quantifier bounds are `u32` in the AST, so parse them as `u32`: a `u64` parse plus
6034            // an `as u32` cast would silently wrap (`{4294967296}` to `{0}`, a pattern that matches
6035            // nothing) instead of reporting the out-of-range bound.
6036            let lower = if matches!(self.peek_token().token, Token::Comma) {
6037                None
6038            } else {
6039                Some(self.parse_literal_u32()?)
6040            };
6041            let quantifier = if self.consume_token(&Token::Comma) {
6042                let upper = if matches!(self.peek_token().token, Token::RBrace) {
6043                    None
6044                } else {
6045                    Some(self.parse_literal_u32()?)
6046                };
6047                match (lower, upper) {
6048                    (Some(n), None) => RepetitionQuantifier::AtLeast(n),
6049                    (None, Some(m)) => RepetitionQuantifier::AtMost(m),
6050                    (Some(n), Some(m)) => RepetitionQuantifier::Range(n, m),
6051                    (None, None) => {
6052                        return self.expected("at least one bound in a {min,max} quantifier");
6053                    }
6054                }
6055            } else {
6056                match lower {
6057                    Some(n) => RepetitionQuantifier::Exactly(n),
6058                    None => return self.expected("a number in a {n} quantifier"),
6059                }
6060            };
6061            self.expect_token(&Token::RBrace)?;
6062            let (reluctant, fused_pipe) = self.consume_pattern_reluctant_mark();
6063            return Ok(Some((quantifier, reluctant, fused_pipe)));
6064        }
6065        // `*`, `+`, `?` may arrive as dedicated tokens or as `Token::Op(_)` depending on surrounding
6066        // operator characters, so accept both spellings. A trailing `?` makes the quantifier
6067        // reluctant, and both the `?` and an alternation `|` may be fused into the operator token —
6068        // `a+?|b` arrives with `Op("+?|")` carrying the quantifier, the reluctant marker AND the
6069        // pipe. The pipe cannot be pushed back, so it is reported to the caller instead.
6070        let (quantifier, fused_reluctant, fused_pipe) = match &self.peek_token().token {
6071            Token::Mul => (RepetitionQuantifier::ZeroOrMore, false, false),
6072            Token::Plus => (RepetitionQuantifier::OneOrMore, false, false),
6073            Token::Op(op) if op == "*" => (RepetitionQuantifier::ZeroOrMore, false, false),
6074            Token::Op(op) if op == "+" => (RepetitionQuantifier::OneOrMore, false, false),
6075            Token::Op(op) if op == "?" => (RepetitionQuantifier::AtMostOne, false, false),
6076            Token::Op(op) if op == "*?" => (RepetitionQuantifier::ZeroOrMore, true, false),
6077            Token::Op(op) if op == "+?" => (RepetitionQuantifier::OneOrMore, true, false),
6078            Token::Op(op) if op == "??" => (RepetitionQuantifier::AtMostOne, true, false),
6079            Token::Op(op) if op == "*|" => (RepetitionQuantifier::ZeroOrMore, false, true),
6080            Token::Op(op) if op == "+|" => (RepetitionQuantifier::OneOrMore, false, true),
6081            Token::Op(op) if op == "?|" => (RepetitionQuantifier::AtMostOne, false, true),
6082            Token::Op(op) if op == "*?|" => (RepetitionQuantifier::ZeroOrMore, true, true),
6083            Token::Op(op) if op == "+?|" => (RepetitionQuantifier::OneOrMore, true, true),
6084            Token::Op(op) if op == "??|" => (RepetitionQuantifier::AtMostOne, true, true),
6085            _ => return Ok(None),
6086        };
6087        self.next_token();
6088        let (reluctant, fused_pipe) = if fused_pipe {
6089            // The pipe was the token's last character; nothing can follow it in the same token.
6090            (fused_reluctant, true)
6091        } else {
6092            let (marker, pipe) = if fused_reluctant {
6093                (false, false)
6094            } else {
6095                self.consume_pattern_reluctant_mark()
6096            };
6097            (fused_reluctant || marker, pipe)
6098        };
6099        Ok(Some((quantifier, reluctant, fused_pipe)))
6100    }
6101
6102    fn peek_is_pattern_pipe(&mut self) -> bool {
6103        match &self.peek_token().token {
6104            Token::Pipe => true,
6105            Token::Op(op) if op == "|" => true,
6106            _ => false,
6107        }
6108    }
6109
6110    fn consume_pattern_pipe(&mut self) -> bool {
6111        if self.peek_is_pattern_pipe() {
6112            self.next_token();
6113            true
6114        } else {
6115            false
6116        }
6117    }
6118
6119    fn parse_join_constraint(&mut self, natural: bool) -> ModalResult<JoinConstraint> {
6120        if natural {
6121            Ok(JoinConstraint::Natural)
6122        } else if self.parse_keyword(Keyword::ON) {
6123            let constraint = self.parse_expr()?;
6124            Ok(JoinConstraint::On(constraint))
6125        } else if self.parse_keyword(Keyword::USING) {
6126            let columns = self.parse_parenthesized_column_list(Mandatory)?;
6127            Ok(JoinConstraint::Using(columns))
6128        } else {
6129            Ok(JoinConstraint::None)
6130            // self.expected("ON, or USING after JOIN")
6131        }
6132    }
6133
6134    /// Parse a GRANT statement.
6135    pub fn parse_grant(&mut self) -> ModalResult<Statement> {
6136        let (privileges, objects) = self.parse_grant_revoke_privileges_objects()?;
6137
6138        self.expect_keyword(Keyword::TO)?;
6139        let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6140
6141        let with_grant_option =
6142            self.parse_keywords(&[Keyword::WITH, Keyword::GRANT, Keyword::OPTION]);
6143
6144        let granted_by = self
6145            .parse_keywords(&[Keyword::GRANTED, Keyword::BY])
6146            .then(|| self.parse_identifier().unwrap());
6147
6148        Ok(Statement::Grant {
6149            privileges,
6150            objects,
6151            grantees,
6152            with_grant_option,
6153            granted_by,
6154        })
6155    }
6156
6157    fn parse_privileges(&mut self) -> ModalResult<Privileges> {
6158        let privileges = if self.parse_keyword(Keyword::ALL) {
6159            Privileges::All {
6160                with_privileges_keyword: self.parse_keyword(Keyword::PRIVILEGES),
6161            }
6162        } else {
6163            Privileges::Actions(
6164                self.parse_comma_separated(Parser::parse_grant_permission)?
6165                    .into_iter()
6166                    .map(|(kw, columns)| match kw {
6167                        Keyword::CONNECT => Action::Connect,
6168                        Keyword::CREATE => Action::Create,
6169                        Keyword::DELETE => Action::Delete,
6170                        Keyword::EXECUTE => Action::Execute,
6171                        Keyword::INSERT => Action::Insert { columns },
6172                        Keyword::REFERENCES => Action::References { columns },
6173                        Keyword::SELECT => Action::Select { columns },
6174                        Keyword::TEMPORARY => Action::Temporary,
6175                        Keyword::TRIGGER => Action::Trigger,
6176                        Keyword::TRUNCATE => Action::Truncate,
6177                        Keyword::UPDATE => Action::Update { columns },
6178                        Keyword::USAGE => Action::Usage,
6179                        _ => unreachable!(),
6180                    })
6181                    .collect(),
6182            )
6183        };
6184
6185        Ok(privileges)
6186    }
6187
6188    fn parse_grant_revoke_privileges_objects(&mut self) -> ModalResult<(Privileges, GrantObjects)> {
6189        let privileges = self.parse_privileges()?;
6190
6191        self.expect_keyword(Keyword::ON)?;
6192
6193        let objects = if self.parse_keywords(&[
6194            Keyword::ALL,
6195            Keyword::TABLES,
6196            Keyword::IN,
6197            Keyword::SCHEMA,
6198        ]) {
6199            GrantObjects::AllTablesInSchema {
6200                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6201            }
6202        } else if self.parse_keywords(&[
6203            Keyword::ALL,
6204            Keyword::SEQUENCES,
6205            Keyword::IN,
6206            Keyword::SCHEMA,
6207        ]) {
6208            GrantObjects::AllSequencesInSchema {
6209                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6210            }
6211        } else if self.parse_keywords(&[
6212            Keyword::ALL,
6213            Keyword::SOURCES,
6214            Keyword::IN,
6215            Keyword::SCHEMA,
6216        ]) {
6217            GrantObjects::AllSourcesInSchema {
6218                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6219            }
6220        } else if self.parse_keywords(&[Keyword::ALL, Keyword::SINKS, Keyword::IN, Keyword::SCHEMA])
6221        {
6222            GrantObjects::AllSinksInSchema {
6223                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6224            }
6225        } else if self.parse_keywords(&[
6226            Keyword::ALL,
6227            Keyword::MATERIALIZED,
6228            Keyword::VIEWS,
6229            Keyword::IN,
6230            Keyword::SCHEMA,
6231        ]) {
6232            GrantObjects::AllMviewsInSchema {
6233                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6234            }
6235        } else if self.parse_keywords(&[Keyword::ALL, Keyword::VIEWS, Keyword::IN, Keyword::SCHEMA])
6236        {
6237            GrantObjects::AllViewsInSchema {
6238                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6239            }
6240        } else if self.parse_keywords(&[
6241            Keyword::ALL,
6242            Keyword::FUNCTIONS,
6243            Keyword::IN,
6244            Keyword::SCHEMA,
6245        ]) {
6246            GrantObjects::AllFunctionsInSchema {
6247                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6248            }
6249        } else if self.parse_keywords(&[
6250            Keyword::ALL,
6251            Keyword::SECRETS,
6252            Keyword::IN,
6253            Keyword::SCHEMA,
6254        ]) {
6255            GrantObjects::AllSecretsInSchema {
6256                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6257            }
6258        } else if self.parse_keywords(&[
6259            Keyword::ALL,
6260            Keyword::CONNECTIONS,
6261            Keyword::IN,
6262            Keyword::SCHEMA,
6263        ]) {
6264            GrantObjects::AllConnectionsInSchema {
6265                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6266            }
6267        } else if self.parse_keywords(&[
6268            Keyword::ALL,
6269            Keyword::SUBSCRIPTIONS,
6270            Keyword::IN,
6271            Keyword::SCHEMA,
6272        ]) {
6273            GrantObjects::AllSubscriptionsInSchema {
6274                schemas: self.parse_comma_separated(Parser::parse_object_name)?,
6275            }
6276        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEW]) {
6277            GrantObjects::Mviews(self.parse_comma_separated(Parser::parse_object_name)?)
6278        } else {
6279            let object_type = self.parse_one_of_keywords(&[
6280                Keyword::SEQUENCE,
6281                Keyword::DATABASE,
6282                Keyword::SCHEMA,
6283                Keyword::TABLE,
6284                Keyword::SOURCE,
6285                Keyword::SINK,
6286                Keyword::VIEW,
6287                Keyword::SUBSCRIPTION,
6288                Keyword::FUNCTION,
6289                Keyword::CONNECTION,
6290                Keyword::SECRET,
6291            ]);
6292            if let Some(Keyword::FUNCTION) = object_type {
6293                let func_descs = self.parse_comma_separated(Parser::parse_function_desc)?;
6294                GrantObjects::Functions(func_descs)
6295            } else {
6296                let objects = self.parse_comma_separated(Parser::parse_object_name);
6297                match object_type {
6298                    Some(Keyword::DATABASE) => GrantObjects::Databases(objects?),
6299                    Some(Keyword::SCHEMA) => GrantObjects::Schemas(objects?),
6300                    Some(Keyword::SEQUENCE) => GrantObjects::Sequences(objects?),
6301                    Some(Keyword::SOURCE) => GrantObjects::Sources(objects?),
6302                    Some(Keyword::SINK) => GrantObjects::Sinks(objects?),
6303                    Some(Keyword::VIEW) => GrantObjects::Views(objects?),
6304                    Some(Keyword::SUBSCRIPTION) => GrantObjects::Subscriptions(objects?),
6305                    Some(Keyword::CONNECTION) => GrantObjects::Connections(objects?),
6306                    Some(Keyword::SECRET) => GrantObjects::Secrets(objects?),
6307                    Some(Keyword::TABLE) | None => GrantObjects::Tables(objects?),
6308                    _ => unreachable!(),
6309                }
6310            }
6311        };
6312
6313        Ok((privileges, objects))
6314    }
6315
6316    fn parse_grant_permission(&mut self) -> ModalResult<(Keyword, Option<Vec<Ident>>)> {
6317        let kw = self.expect_one_of_keywords(&[
6318            Keyword::CONNECT,
6319            Keyword::CREATE,
6320            Keyword::DELETE,
6321            Keyword::EXECUTE,
6322            Keyword::INSERT,
6323            Keyword::REFERENCES,
6324            Keyword::SELECT,
6325            Keyword::TEMPORARY,
6326            Keyword::TRIGGER,
6327            Keyword::TRUNCATE,
6328            Keyword::UPDATE,
6329            Keyword::USAGE,
6330        ])?;
6331        let columns = match kw {
6332            Keyword::INSERT | Keyword::REFERENCES | Keyword::SELECT | Keyword::UPDATE => {
6333                let columns = self.parse_parenthesized_column_list(Optional)?;
6334                if columns.is_empty() {
6335                    None
6336                } else {
6337                    Some(columns)
6338                }
6339            }
6340            _ => None,
6341        };
6342        Ok((kw, columns))
6343    }
6344
6345    /// Parse a REVOKE statement
6346    pub fn parse_revoke(&mut self) -> ModalResult<Statement> {
6347        let revoke_grant_option =
6348            self.parse_keywords(&[Keyword::GRANT, Keyword::OPTION, Keyword::FOR]);
6349        let (privileges, objects) = self.parse_grant_revoke_privileges_objects()?;
6350
6351        self.expect_keyword(Keyword::FROM)?;
6352        let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6353
6354        let granted_by = self
6355            .parse_keywords(&[Keyword::GRANTED, Keyword::BY])
6356            .then(|| self.parse_identifier().unwrap());
6357
6358        let cascade = self.parse_keyword(Keyword::CASCADE);
6359        let restrict = self.parse_keyword(Keyword::RESTRICT);
6360        if cascade && restrict {
6361            parser_err!("Cannot specify both CASCADE and RESTRICT in REVOKE");
6362        }
6363
6364        Ok(Statement::Revoke {
6365            privileges,
6366            objects,
6367            grantees,
6368            granted_by,
6369            revoke_grant_option,
6370            cascade,
6371        })
6372    }
6373
6374    fn parse_privilege_object_types(&mut self) -> ModalResult<PrivilegeObjectType> {
6375        let object_type = if self.parse_keyword(Keyword::TABLES) {
6376            PrivilegeObjectType::Tables
6377        } else if self.parse_keyword(Keyword::SOURCES) {
6378            PrivilegeObjectType::Sources
6379        } else if self.parse_keyword(Keyword::SINKS) {
6380            PrivilegeObjectType::Sinks
6381        } else if self.parse_keywords(&[Keyword::MATERIALIZED, Keyword::VIEWS]) {
6382            PrivilegeObjectType::Mviews
6383        } else if self.parse_keyword(Keyword::VIEWS) {
6384            PrivilegeObjectType::Views
6385        } else if self.parse_keyword(Keyword::FUNCTIONS) {
6386            PrivilegeObjectType::Functions
6387        } else if self.parse_keyword(Keyword::SECRETS) {
6388            PrivilegeObjectType::Secrets
6389        } else if self.parse_keyword(Keyword::CONNECTIONS) {
6390            PrivilegeObjectType::Connections
6391        } else if self.parse_keyword(Keyword::SUBSCRIPTIONS) {
6392            PrivilegeObjectType::Subscriptions
6393        } else if self.parse_keyword(Keyword::SCHEMAS) {
6394            PrivilegeObjectType::Schemas
6395        } else {
6396            return self.expected("TABLES, SOURCES, SINKS, MATERIALIZED VIEWS, VIEWS, FUNCTIONS, SECRETS, CONNECTIONS, SUBSCRIPTIONS or SCHEMAS");
6397        };
6398
6399        Ok(object_type)
6400    }
6401
6402    pub fn parse_alter_default_privileges(&mut self) -> ModalResult<Statement> {
6403        // [ FOR USER target_user [, ...] ]
6404        let target_users = if self.parse_keyword(Keyword::FOR) {
6405            self.expect_keyword(Keyword::USER)?;
6406            Some(self.parse_comma_separated(Parser::parse_identifier)?)
6407        } else {
6408            None
6409        };
6410
6411        // [ IN SCHEMA schema_name [, ...] ]
6412        let schema_names = if self.parse_keywords(&[Keyword::IN, Keyword::SCHEMA]) {
6413            Some(self.parse_comma_separated(Parser::parse_object_name)?)
6414        } else {
6415            None
6416        };
6417        let keyword = self.expect_one_of_keywords(&[Keyword::GRANT, Keyword::REVOKE])?;
6418        let for_grant = keyword == Keyword::GRANT;
6419        if for_grant {
6420            let privileges = self.parse_privileges()?;
6421            self.expect_keyword(Keyword::ON)?;
6422            let object_type = self.parse_privilege_object_types()?;
6423            if schema_names.is_some() && object_type == PrivilegeObjectType::Schemas {
6424                parser_err!("cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS");
6425            }
6426            self.expect_keyword(Keyword::TO)?;
6427            let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6428
6429            let with_grant_option =
6430                self.parse_keywords(&[Keyword::WITH, Keyword::GRANT, Keyword::OPTION]);
6431
6432            Ok(Statement::AlterDefaultPrivileges {
6433                target_users,
6434                schema_names,
6435                operation: DefaultPrivilegeOperation::Grant {
6436                    privileges,
6437                    object_type,
6438                    grantees,
6439                    with_grant_option,
6440                },
6441            })
6442        } else {
6443            let revoke_grant_option =
6444                self.parse_keywords(&[Keyword::GRANT, Keyword::OPTION, Keyword::FOR]);
6445            let privileges = self.parse_privileges()?;
6446            self.expect_keyword(Keyword::ON)?;
6447            let object_type = self.parse_privilege_object_types()?;
6448            if schema_names.is_some() && object_type == PrivilegeObjectType::Schemas {
6449                parser_err!("cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS");
6450            }
6451            self.expect_keyword(Keyword::FROM)?;
6452            let grantees = self.parse_comma_separated(Parser::parse_identifier)?;
6453            let cascade = self.parse_keyword(Keyword::CASCADE);
6454            let restrict = self.parse_keyword(Keyword::RESTRICT);
6455            if cascade && restrict {
6456                parser_err!("Cannot specify both CASCADE and RESTRICT in REVOKE");
6457            }
6458
6459            Ok(Statement::AlterDefaultPrivileges {
6460                target_users,
6461                schema_names,
6462                operation: DefaultPrivilegeOperation::Revoke {
6463                    privileges,
6464                    object_type,
6465                    grantees,
6466                    revoke_grant_option,
6467                    cascade,
6468                },
6469            })
6470        }
6471    }
6472
6473    /// Parse an INSERT statement
6474    pub fn parse_insert(&mut self) -> ModalResult<Statement> {
6475        self.expect_keyword(Keyword::INTO)?;
6476
6477        let table_name = self.parse_object_name()?;
6478        let columns = self.parse_parenthesized_column_list(Optional)?;
6479
6480        let source = Box::new(self.parse_query()?);
6481        let returning = self.parse_returning(Optional)?;
6482        Ok(Statement::Insert {
6483            table_name,
6484            columns,
6485            source,
6486            returning,
6487        })
6488    }
6489
6490    pub fn parse_update(&mut self) -> ModalResult<Statement> {
6491        let table_name = self.parse_object_name()?;
6492
6493        self.expect_keyword(Keyword::SET)?;
6494        let assignments = self.parse_comma_separated(Parser::parse_assignment)?;
6495        let selection = if self.parse_keyword(Keyword::WHERE) {
6496            Some(self.parse_expr()?)
6497        } else {
6498            None
6499        };
6500        let returning = self.parse_returning(Optional)?;
6501        Ok(Statement::Update {
6502            table_name,
6503            assignments,
6504            selection,
6505            returning,
6506        })
6507    }
6508
6509    /// Parse a `var = expr` assignment, used in an UPDATE statement
6510    pub fn parse_assignment(&mut self) -> ModalResult<Assignment> {
6511        let id = self.parse_identifiers_non_keywords()?;
6512        self.expect_token(&Token::Eq)?;
6513
6514        let value = if self.parse_keyword(Keyword::DEFAULT) {
6515            AssignmentValue::Default
6516        } else {
6517            AssignmentValue::Expr(self.parse_expr()?)
6518        };
6519
6520        Ok(Assignment { id, value })
6521    }
6522
6523    /// Parse a `[VARIADIC] name => expr`.
6524    fn parse_function_args(&mut self) -> ModalResult<(bool, FunctionArg)> {
6525        let variadic = self.parse_keyword(Keyword::VARIADIC);
6526        let arg = if self.peek_nth_token(1) == Token::RArrow {
6527            let name = self.parse_identifier()?;
6528
6529            self.expect_token(&Token::RArrow)?;
6530            let arg = if self.parse_keyword(Keyword::SECRET) {
6531                FunctionArgExpr::SecretRef(self.parse_secret_ref()?)
6532            } else {
6533                self.parse_wildcard_or_expr()?.into()
6534            };
6535
6536            FunctionArg::Named { name, arg }
6537        } else if self.parse_keyword(Keyword::SECRET) {
6538            FunctionArg::Unnamed(FunctionArgExpr::SecretRef(self.parse_secret_ref()?))
6539        } else {
6540            FunctionArg::Unnamed(self.parse_wildcard_or_expr()?.into())
6541        };
6542        Ok((variadic, arg))
6543    }
6544
6545    pub fn parse_argument_list(&mut self) -> ModalResult<FunctionArgList> {
6546        self.expect_token(&Token::LParen)?;
6547        if self.consume_token(&Token::RParen) {
6548            Ok(FunctionArgList::empty())
6549        } else {
6550            let distinct = self.parse_all_or_distinct()?;
6551            let args = self.parse_comma_separated(Parser::parse_function_args)?;
6552            if args
6553                .iter()
6554                .take(args.len() - 1)
6555                .any(|(variadic, _)| *variadic)
6556            {
6557                parser_err!("VARIADIC argument must be the last");
6558            }
6559            let variadic = args.last().map(|(variadic, _)| *variadic).unwrap_or(false);
6560            let args = args.into_iter().map(|(_, arg)| arg).collect();
6561
6562            let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
6563                self.parse_comma_separated(Parser::parse_order_by_expr)?
6564            } else {
6565                vec![]
6566            };
6567
6568            let ignore_nulls = self.parse_keywords(&[Keyword::IGNORE, Keyword::NULLS]);
6569
6570            let arg_list = FunctionArgList {
6571                distinct,
6572                args,
6573                variadic,
6574                order_by,
6575                ignore_nulls,
6576            };
6577
6578            self.expect_token(&Token::RParen)?;
6579            Ok(arg_list)
6580        }
6581    }
6582
6583    /// Parse a comma-delimited list of projections after SELECT
6584    pub fn parse_select_item(&mut self) -> ModalResult<SelectItem> {
6585        match self.parse_wildcard_or_expr()? {
6586            WildcardOrExpr::Expr(expr) => self
6587                .parse_optional_alias(keywords::RESERVED_FOR_COLUMN_ALIAS)
6588                .map(|alias| match alias {
6589                    Some(alias) => SelectItem::ExprWithAlias { expr, alias },
6590                    None => SelectItem::UnnamedExpr(expr),
6591                }),
6592            WildcardOrExpr::QualifiedWildcard(prefix, except) => {
6593                Ok(SelectItem::QualifiedWildcard(prefix, except))
6594            }
6595            WildcardOrExpr::ExprQualifiedWildcard(expr, prefix) => {
6596                Ok(SelectItem::ExprQualifiedWildcard(expr, prefix))
6597            }
6598            WildcardOrExpr::Wildcard(except) => Ok(SelectItem::Wildcard(except)),
6599        }
6600    }
6601
6602    /// Parse an expression, optionally followed by ASC or DESC (used in ORDER BY)
6603    pub fn parse_order_by_expr(&mut self) -> ModalResult<OrderByExpr> {
6604        let expr = self.parse_expr()?;
6605
6606        let asc = if self.parse_keyword(Keyword::ASC) {
6607            Some(true)
6608        } else if self.parse_keyword(Keyword::DESC) {
6609            Some(false)
6610        } else {
6611            None
6612        };
6613
6614        let nulls_first = if self.parse_keywords(&[Keyword::NULLS, Keyword::FIRST]) {
6615            Some(true)
6616        } else if self.parse_keywords(&[Keyword::NULLS, Keyword::LAST]) {
6617            Some(false)
6618        } else {
6619            None
6620        };
6621
6622        Ok(OrderByExpr {
6623            expr,
6624            asc,
6625            nulls_first,
6626        })
6627    }
6628
6629    /// Parse a LIMIT clause
6630    pub fn parse_limit(&mut self) -> ModalResult<Option<Expr>> {
6631        if self.parse_keyword(Keyword::ALL) {
6632            Ok(None)
6633        } else {
6634            let expr = self.parse_expr()?;
6635            Ok(Some(expr))
6636        }
6637    }
6638
6639    /// Parse an OFFSET clause
6640    pub fn parse_offset(&mut self) -> ModalResult<String> {
6641        let value = self.parse_number_value()?;
6642        // TODO(Kexiang): support LIMIT expr
6643        if self.consume_token(&Token::DoubleColon) {
6644            self.expect_keyword(Keyword::BIGINT)?;
6645        }
6646        _ = self.parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS]);
6647        Ok(value)
6648    }
6649
6650    /// Parse a FETCH clause
6651    pub fn parse_fetch(&mut self) -> ModalResult<Fetch> {
6652        self.expect_one_of_keywords(&[Keyword::FIRST, Keyword::NEXT])?;
6653        let quantity = if self
6654            .parse_one_of_keywords(&[Keyword::ROW, Keyword::ROWS])
6655            .is_some()
6656        {
6657            None
6658        } else {
6659            let quantity = self.parse_number_value()?;
6660            self.expect_one_of_keywords(&[Keyword::ROW, Keyword::ROWS])?;
6661            Some(quantity)
6662        };
6663        let with_ties = if self.parse_keyword(Keyword::ONLY) {
6664            false
6665        } else if self.parse_keywords(&[Keyword::WITH, Keyword::TIES]) {
6666            true
6667        } else {
6668            return self.expected("one of ONLY or WITH TIES");
6669        };
6670        Ok(Fetch {
6671            with_ties,
6672            quantity,
6673        })
6674    }
6675
6676    pub fn parse_values(&mut self) -> ModalResult<Values> {
6677        let values = self.parse_comma_separated(|parser| {
6678            parser.expect_token(&Token::LParen)?;
6679            let exprs = parser.parse_comma_separated(Parser::parse_expr)?;
6680            parser.expect_token(&Token::RParen)?;
6681            Ok(exprs)
6682        })?;
6683        Ok(Values(values))
6684    }
6685
6686    pub fn parse_start_transaction(&mut self) -> ModalResult<Statement> {
6687        self.expect_keyword(Keyword::TRANSACTION)?;
6688        Ok(Statement::StartTransaction {
6689            modes: self.parse_transaction_modes()?,
6690        })
6691    }
6692
6693    pub fn parse_begin(&mut self) -> ModalResult<Statement> {
6694        let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]);
6695        Ok(Statement::Begin {
6696            modes: self.parse_transaction_modes()?,
6697        })
6698    }
6699
6700    pub fn parse_transaction_modes(&mut self) -> ModalResult<Vec<TransactionMode>> {
6701        let mut modes = vec![];
6702        let mut required = false;
6703        loop {
6704            let mode = if self.parse_keywords(&[Keyword::ISOLATION, Keyword::LEVEL]) {
6705                let iso_level = if self.parse_keywords(&[Keyword::READ, Keyword::UNCOMMITTED]) {
6706                    TransactionIsolationLevel::ReadUncommitted
6707                } else if self.parse_keywords(&[Keyword::READ, Keyword::COMMITTED]) {
6708                    TransactionIsolationLevel::ReadCommitted
6709                } else if self.parse_keywords(&[Keyword::REPEATABLE, Keyword::READ]) {
6710                    TransactionIsolationLevel::RepeatableRead
6711                } else if self.parse_keyword(Keyword::SERIALIZABLE) {
6712                    TransactionIsolationLevel::Serializable
6713                } else {
6714                    self.expected("isolation level")?
6715                };
6716                TransactionMode::IsolationLevel(iso_level)
6717            } else if self.parse_keywords(&[Keyword::READ, Keyword::ONLY]) {
6718                TransactionMode::AccessMode(TransactionAccessMode::ReadOnly)
6719            } else if self.parse_keywords(&[Keyword::READ, Keyword::WRITE]) {
6720                TransactionMode::AccessMode(TransactionAccessMode::ReadWrite)
6721            } else if required {
6722                self.expected("transaction mode")?
6723            } else {
6724                break;
6725            };
6726            modes.push(mode);
6727            // ANSI requires a comma after each transaction mode, but
6728            // PostgreSQL, for historical reasons, does not. We follow
6729            // PostgreSQL in making the comma optional, since that is strictly
6730            // more general.
6731            required = self.consume_token(&Token::Comma);
6732        }
6733        Ok(modes)
6734    }
6735
6736    pub fn parse_commit(&mut self) -> ModalResult<Statement> {
6737        Ok(Statement::Commit {
6738            chain: self.parse_commit_rollback_chain()?,
6739        })
6740    }
6741
6742    pub fn parse_rollback(&mut self) -> ModalResult<Statement> {
6743        Ok(Statement::Rollback {
6744            chain: self.parse_commit_rollback_chain()?,
6745        })
6746    }
6747
6748    pub fn parse_commit_rollback_chain(&mut self) -> ModalResult<bool> {
6749        let _ = self.parse_one_of_keywords(&[Keyword::TRANSACTION, Keyword::WORK]);
6750        if self.parse_keyword(Keyword::AND) {
6751            let chain = !self.parse_keyword(Keyword::NO);
6752            self.expect_keyword(Keyword::CHAIN)?;
6753            Ok(chain)
6754        } else {
6755            Ok(false)
6756        }
6757    }
6758
6759    fn parse_deallocate(&mut self) -> ModalResult<Statement> {
6760        let prepare = self.parse_keyword(Keyword::PREPARE);
6761        let name = if self.parse_keyword(Keyword::ALL) {
6762            None
6763        } else {
6764            Some(self.parse_identifier()?)
6765        };
6766        Ok(Statement::Deallocate { name, prepare })
6767    }
6768
6769    fn parse_execute(&mut self) -> ModalResult<Statement> {
6770        let name = self.parse_identifier()?;
6771
6772        let mut parameters = vec![];
6773        if self.consume_token(&Token::LParen) {
6774            parameters = self.parse_comma_separated(Parser::parse_expr)?;
6775            self.expect_token(&Token::RParen)?;
6776        }
6777
6778        Ok(Statement::Execute { name, parameters })
6779    }
6780
6781    fn parse_prepare(&mut self) -> ModalResult<Statement> {
6782        let name = self.parse_identifier()?;
6783
6784        let mut data_types = vec![];
6785        if self.consume_token(&Token::LParen) {
6786            data_types = self.parse_comma_separated(Parser::parse_data_type)?;
6787            self.expect_token(&Token::RParen)?;
6788        }
6789
6790        self.expect_keyword(Keyword::AS)?;
6791        let statement = Box::new(self.parse_statement()?);
6792        Ok(Statement::Prepare {
6793            name,
6794            data_types,
6795            statement,
6796        })
6797    }
6798
6799    fn parse_comment(&mut self) -> ModalResult<Statement> {
6800        self.expect_keyword(Keyword::ON)?;
6801        let checkpoint = *self;
6802        let token = self.next_token();
6803
6804        let (object_type, object_name) = match token.token {
6805            Token::Word(w) if w.keyword == Keyword::COLUMN => {
6806                let object_name = self.parse_object_name()?;
6807                (CommentObject::Column, object_name)
6808            }
6809            Token::Word(w) if w.keyword == Keyword::TABLE => {
6810                let object_name = self.parse_object_name()?;
6811                (CommentObject::Table, object_name)
6812            }
6813            _ => self.expected_at(checkpoint, "comment object_type")?,
6814        };
6815
6816        self.expect_keyword(Keyword::IS)?;
6817        let comment = if self.parse_keyword(Keyword::NULL) {
6818            None
6819        } else {
6820            Some(self.parse_literal_string()?)
6821        };
6822        Ok(Statement::Comment {
6823            object_type,
6824            object_name,
6825            comment,
6826        })
6827    }
6828
6829    fn parse_use(&mut self) -> ModalResult<Statement> {
6830        let db_name = self.parse_object_name()?;
6831        Ok(Statement::Use { db_name })
6832    }
6833
6834    /// Parse a named window definition for the WINDOW clause
6835    pub fn parse_named_window(&mut self) -> ModalResult<NamedWindow> {
6836        let name = self.parse_identifier()?;
6837        self.expect_keywords(&[Keyword::AS])?;
6838        self.expect_token(&Token::LParen)?;
6839        let window_spec = self.parse_window_spec()?;
6840        self.expect_token(&Token::RParen)?;
6841        Ok(NamedWindow { name, window_spec })
6842    }
6843
6844    /// Parse a window specification (contents of OVER clause or WINDOW clause)
6845    pub fn parse_window_spec(&mut self) -> ModalResult<WindowSpec> {
6846        let partition_by = if self.parse_keywords(&[Keyword::PARTITION, Keyword::BY]) {
6847            self.parse_comma_separated(Parser::parse_expr)?
6848        } else {
6849            vec![]
6850        };
6851        let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
6852            self.parse_comma_separated(Parser::parse_order_by_expr)?
6853        } else {
6854            vec![]
6855        };
6856        let window_frame = if !self.peek_token().eq(&Token::RParen) {
6857            Some(self.parse_window_frame()?)
6858        } else {
6859            None
6860        };
6861        Ok(WindowSpec {
6862            partition_by,
6863            order_by,
6864            window_frame,
6865        })
6866    }
6867
6868    pub fn parse_wait(&mut self) -> ModalResult<Statement> {
6869        let target = if self.parse_keyword(Keyword::TABLE) {
6870            WaitTarget::Table(self.parse_object_name()?)
6871        } else if self.parse_keyword(Keyword::MATERIALIZED) {
6872            self.expect_keyword(Keyword::VIEW)?;
6873            WaitTarget::MaterializedView(self.parse_object_name()?)
6874        } else if self.parse_keyword(Keyword::SINK) {
6875            WaitTarget::Sink(self.parse_object_name()?)
6876        } else if self.parse_keyword(Keyword::INDEX) {
6877            WaitTarget::Index(self.parse_object_name()?)
6878        } else {
6879            WaitTarget::All
6880        };
6881
6882        Ok(Statement::Wait(target))
6883    }
6884}
6885
6886impl Word {
6887    /// Convert a Word to a Identifier, return ParserError when the Word's value is a empty string.
6888    pub fn to_ident(&self) -> ModalResult<Ident> {
6889        if self.value.is_empty() {
6890            parser_err!("zero-length delimited identifier at or near \"{self}\"")
6891        } else {
6892            Ok(Ident {
6893                value: self.value.clone(),
6894                quote_style: self.quote_style,
6895            })
6896        }
6897    }
6898}
6899
6900#[cfg(test)]
6901mod tests {
6902    use super::*;
6903    use crate::test_utils::run_parser_method;
6904
6905    #[test]
6906    fn test_parse_integer_min() {
6907        let min_bigint = "-9223372036854775808";
6908        run_parser_method(min_bigint, |parser| {
6909            assert_eq!(
6910                parser.parse_expr().unwrap(),
6911                Expr::Value(Value::Number("-9223372036854775808".to_owned()))
6912            )
6913        });
6914    }
6915
6916    #[test]
6917    fn test_parse_function_arg_secret_ref() {
6918        use crate::ast::{FunctionArg, FunctionArgExpr, SecretRefAsType, SecretRefValue};
6919
6920        // Unnamed secret argument
6921        run_parser_method("SECRET my_secret", |parser| {
6922            let (_variadic, arg) = parser.parse_function_args().unwrap();
6923            assert_eq!(
6924                arg,
6925                FunctionArg::Unnamed(FunctionArgExpr::SecretRef(SecretRefValue {
6926                    secret_name: ObjectName(vec![Ident::new_unchecked("my_secret")]),
6927                    ref_as: SecretRefAsType::Text,
6928                }))
6929            );
6930        });
6931
6932        // Unnamed secret argument with AS FILE
6933        run_parser_method("SECRET my_secret AS FILE", |parser| {
6934            let (_variadic, arg) = parser.parse_function_args().unwrap();
6935            assert_eq!(
6936                arg,
6937                FunctionArg::Unnamed(FunctionArgExpr::SecretRef(SecretRefValue {
6938                    secret_name: ObjectName(vec![Ident::new_unchecked("my_secret")]),
6939                    ref_as: SecretRefAsType::File,
6940                }))
6941            );
6942        });
6943
6944        // Named secret argument
6945        run_parser_method("header => SECRET my_secret", |parser| {
6946            let (_variadic, arg) = parser.parse_function_args().unwrap();
6947            assert_eq!(
6948                arg,
6949                FunctionArg::Named {
6950                    name: Ident::new_unchecked("header"),
6951                    arg: FunctionArgExpr::SecretRef(SecretRefValue {
6952                        secret_name: ObjectName(vec![Ident::new_unchecked("my_secret")]),
6953                        ref_as: SecretRefAsType::Text,
6954                    }),
6955                }
6956            );
6957        });
6958    }
6959}