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