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