Skip to main content

sqlglot_rust/parser/
sql_parser.rs

1use crate::ast::*;
2use crate::errors::{Result, SqlglotError};
3use crate::tokens::{Token, TokenType, Tokenizer};
4
5/// Convert a token's `quote_char` into a `QuoteStyle`.
6fn quote_style_from_char(c: char) -> QuoteStyle {
7    match c {
8        '"' => QuoteStyle::DoubleQuote,
9        '`' => QuoteStyle::Backtick,
10        '[' => QuoteStyle::Bracket,
11        _ => QuoteStyle::None,
12    }
13}
14
15/// A recursive-descent SQL parser.
16///
17/// Supports CTEs (WITH), subqueries, UNION/INTERSECT/EXCEPT, CAST,
18/// window functions (OVER), EXISTS, EXTRACT, INTERVAL, and more.
19pub struct Parser {
20    tokens: Vec<Token>,
21    pos: usize,
22    /// Whether to preserve comments during parsing.
23    #[allow(dead_code)]
24    preserve_comments: bool,
25    /// Accumulated comments pending attachment to the next AST node.
26    pending_comments: Vec<String>,
27}
28
29impl Parser {
30    /// Create a new parser from a SQL string.
31    pub fn new(sql: &str) -> Result<Self> {
32        let mut tokenizer = Tokenizer::new(sql);
33        let tokens = tokenizer.tokenize()?;
34        Ok(Self {
35            tokens,
36            pos: 0,
37            preserve_comments: false,
38            pending_comments: Vec::new(),
39        })
40    }
41
42    /// Create a new parser that preserves SQL comments in the AST.
43    pub fn new_with_comments(sql: &str) -> Result<Self> {
44        let mut tokenizer = Tokenizer::with_comments(sql);
45        let tokens = tokenizer.tokenize()?;
46        Ok(Self {
47            tokens,
48            pos: 0,
49            preserve_comments: true,
50            pending_comments: Vec::new(),
51        })
52    }
53
54    // ── Comment helpers ────────────────────────────────────────────
55
56    /// Consume any comment tokens at the current position, accumulating
57    /// their text into `pending_comments`.
58    fn collect_comments(&mut self) {
59        while self.pos < self.tokens.len() {
60            match self.tokens[self.pos].token_type {
61                TokenType::LineComment | TokenType::BlockComment => {
62                    let token = &self.tokens[self.pos];
63                    self.pending_comments.push(token.value.clone());
64                    self.pos += 1;
65                }
66                _ => break,
67            }
68        }
69    }
70
71    /// Take all pending comments, leaving the buffer empty.
72    fn take_comments(&mut self) -> Vec<String> {
73        std::mem::take(&mut self.pending_comments)
74    }
75
76    // ── Token helpers ──────────────────────────────────────────────
77
78    fn peek(&self) -> &Token {
79        &self.tokens[self.pos.min(self.tokens.len() - 1)]
80    }
81
82    fn peek_type(&self) -> &TokenType {
83        &self.peek().token_type
84    }
85
86    fn advance(&mut self) -> &Token {
87        let token = &self.tokens[self.pos.min(self.tokens.len() - 1)];
88        if self.pos < self.tokens.len() {
89            self.pos += 1;
90        }
91        token
92    }
93
94    fn expect(&mut self, expected: TokenType) -> Result<Token> {
95        let token = self.peek().clone();
96        if token.token_type == expected {
97            self.advance();
98            Ok(token)
99        } else {
100            Err(SqlglotError::ParserError {
101                message: format!(
102                    "Expected {expected:?}, got {:?} ('{}') at line {} col {}",
103                    token.token_type, token.value, token.line, token.col
104                ),
105            })
106        }
107    }
108
109    fn match_token(&mut self, expected: TokenType) -> bool {
110        if self.peek().token_type == expected {
111            self.advance();
112            true
113        } else {
114            false
115        }
116    }
117
118    /// Check if the current token's uppercased value matches a keyword string.
119    fn check_keyword(&self, keyword: &str) -> bool {
120        self.peek().value.to_uppercase() == keyword
121    }
122
123    /// Check if the token at `current + offset` matches a keyword string.
124    fn check_keyword_offset(&self, keyword: &str, offset: usize) -> bool {
125        let idx = self.pos + offset;
126        if idx < self.tokens.len() {
127            self.tokens[idx].value.to_uppercase() == keyword
128        } else {
129            false
130        }
131    }
132
133    /// Match a keyword by string value (for multi-word context-sensitive keywords).
134    fn match_keyword(&mut self, keyword: &str) -> bool {
135        if self.check_keyword(keyword) {
136            self.advance();
137            true
138        } else {
139            false
140        }
141    }
142
143    /// Expect a keyword by string value, returning an error if not found.
144    fn expect_keyword(&mut self, keyword: &str) -> Result<()> {
145        if self.check_keyword(keyword) {
146            self.advance();
147            Ok(())
148        } else {
149            let token = self.peek().clone();
150            Err(SqlglotError::ParserError {
151                message: format!(
152                    "Expected keyword '{keyword}', got '{value}' at line {line} col {col}",
153                    value = token.value,
154                    line = token.line,
155                    col = token.col
156                ),
157            })
158        }
159    }
160
161    /// Reconstruct a single token's surface representation for raw command
162    /// preservation. String literals are wrapped in their original quotes;
163    /// identifiers may carry a quote_char from the tokenizer.
164    fn token_text(token: &Token) -> String {
165        match token.token_type {
166            TokenType::String => format!("'{}'", token.value.replace('\'', "''")),
167            TokenType::Identifier if token.quote_char != '\0' => {
168                let (l, r) = match token.quote_char {
169                    '[' => ('[', ']'),
170                    c => (c, c),
171                };
172                format!("{l}{}{r}", token.value)
173            }
174            _ => token.value.clone(),
175        }
176    }
177
178    /// Join a slice of tokens with whitespace tuned for SQL — no space
179    /// before `,` `)` `;` `.`, no space after `(` or `.`.
180    fn join_tokens_for_raw(tokens: &[Token]) -> String {
181        let mut out = String::new();
182        let mut prev_no_space_after = true; // suppress leading space
183        for t in tokens {
184            let no_space_before = matches!(
185                t.token_type,
186                TokenType::Comma
187                    | TokenType::RParen
188                    | TokenType::Semicolon
189                    | TokenType::Dot
190                    | TokenType::RBracket
191            );
192            if !out.is_empty() && !prev_no_space_after && !no_space_before {
193                out.push(' ');
194            }
195            out.push_str(&Self::token_text(t));
196            prev_no_space_after = matches!(
197                t.token_type,
198                TokenType::LParen | TokenType::Dot | TokenType::LBracket
199            );
200        }
201        out
202    }
203
204    /// Consume tokens up to (but not including) the next top-level `;` or EOF,
205    /// returning the raw text of the consumed tokens with whitespace
206    /// reconstructed by [`join_tokens_for_raw`]. Honors parenthesis depth so
207    /// embedded `;` inside `(...)` does not terminate the statement.
208    fn consume_raw_to_statement_end(&mut self) -> String {
209        let start = self.pos;
210        let mut depth: i32 = 0;
211        while self.pos < self.tokens.len() {
212            let tt = &self.tokens[self.pos].token_type;
213            match tt {
214                TokenType::Eof => break,
215                TokenType::Semicolon if depth == 0 => break,
216                TokenType::LParen | TokenType::LBracket => {
217                    depth += 1;
218                    self.pos += 1;
219                }
220                TokenType::RParen | TokenType::RBracket => {
221                    depth = (depth - 1).max(0);
222                    self.pos += 1;
223                }
224                _ => self.pos += 1,
225            }
226        }
227        Self::join_tokens_for_raw(&self.tokens[start..self.pos])
228    }
229
230    /// Helper for the dispatcher: consume one verb token (already known) and
231    /// then capture the entire tail as a [`CommandStatement`].
232    fn parse_command_kind(&mut self, kind: &str) -> Result<Statement> {
233        self.advance(); // consume the verb token
234        let body = self.consume_raw_to_statement_end();
235        Ok(Statement::Command(CommandStatement {
236            comments: vec![],
237            kind: kind.to_string(),
238            body,
239        }))
240    }
241
242    /// `COMMENT ON {TABLE|COLUMN|...} <name> IS '...'` — preserved as raw.
243    /// `COMMENT` can also appear inside `CREATE TABLE` column definitions and
244    /// in other positions; only the standalone DDL form lands here because
245    /// the dispatcher peeks at the *first* token.
246    fn parse_comment_on_command(&mut self) -> Result<Statement> {
247        // Look ahead for "COMMENT ON" — if not "ON", fall back to parser error
248        // (the COMMENT token would otherwise have been consumed inside an
249        // expression / column-def parser, not at statement boundary).
250        if self.peek_offset(1).map(|t| t.value.to_uppercase()) != Some("ON".to_string()) {
251            return Err(SqlglotError::UnexpectedToken {
252                token: self.peek().clone(),
253            });
254        }
255        self.advance(); // COMMENT
256        let body = self.consume_raw_to_statement_end();
257        Ok(Statement::Command(CommandStatement {
258            comments: vec![],
259            kind: "COMMENT".to_string(),
260            body,
261        }))
262    }
263
264    /// Returns `true` when the current Identifier token is a known
265    /// statement-starting verb that we preserve verbatim.
266    fn match_command_keyword(&self) -> bool {
267        let v = self.peek().value.to_uppercase();
268        matches!(
269            v.as_str(),
270            "GO" | "DECLARE"
271                | "LOAD"
272                | "REM"
273                | "REMARK"
274                | "RESET"
275                | "PRAGMA"
276                | "VACUUM"
277                | "REINDEX"
278                | "CALL"
279                | "LOCK"
280                | "UNLOCK"
281                | "CLUSTER"
282                | "REFRESH"
283                | "CHECKPOINT"
284                | "LISTEN"
285                | "NOTIFY"
286                | "PREPARE"
287                | "EXECUTE"
288                | "DEALLOCATE"
289                | "DISCARD"
290                | "COPY"
291                | "ATTACH"
292                | "DETACH"
293                | "COMMENT"
294        )
295    }
296
297    /// Variant of [`parse_command_kind`] for verbs that arrive as an
298    /// Identifier token (no dedicated TokenType).
299    fn parse_command_from_identifier(&mut self) -> Result<Statement> {
300        let verb = self.peek().value.to_uppercase();
301        self.advance();
302        let body = self.consume_raw_to_statement_end();
303        Ok(Statement::Command(CommandStatement {
304            comments: vec![],
305            kind: verb,
306            body,
307        }))
308    }
309
310    /// Look at the token `offset` positions ahead of the current one,
311    /// returning `None` if past EOF.
312    fn peek_offset(&self, offset: usize) -> Option<&Token> {
313        self.tokens.get(self.pos + offset)
314    }
315
316    /// Helper to check if current token is an identifier or keyword that can serve as a name.
317    fn is_name_token(&self) -> bool {
318        matches!(
319            self.peek_type(),
320            TokenType::Identifier
321                | TokenType::Year
322                | TokenType::Month
323                | TokenType::Day
324                | TokenType::Hour
325                | TokenType::Minute
326                | TokenType::Second
327                | TokenType::Key
328                | TokenType::Filter
329                | TokenType::First
330                | TokenType::Next
331                | TokenType::Only
332                | TokenType::Respect
333                | TokenType::Epoch
334                | TokenType::Schema
335                | TokenType::Database
336                | TokenType::View
337                | TokenType::Collate
338                | TokenType::Comment
339                | TokenType::Left
340                | TokenType::Right
341                | TokenType::Replace
342                | TokenType::Cube
343                | TokenType::Rollup
344                | TokenType::Grouping
345                | TokenType::Pivot
346                | TokenType::Unpivot
347                | TokenType::Sets
348                | TokenType::Range
349                | TokenType::Conflict
350                | TokenType::Unnest
351                | TokenType::Text
352                | TokenType::Show
353                | TokenType::Describe
354                | TokenType::Analyze
355                | TokenType::Index
356        )
357    }
358
359    /// Consume a name token (identifier or unreserved keyword used as identifier).
360    fn expect_name(&mut self) -> Result<String> {
361        let (name, _) = self.expect_name_with_quote()?;
362        Ok(name)
363    }
364
365    /// Like `expect_name` but also returns the quote style of the token.
366    fn expect_name_with_quote(&mut self) -> Result<(String, QuoteStyle)> {
367        if self.is_name_token() {
368            let token = self.advance().clone();
369            let qs = quote_style_from_char(token.quote_char);
370            return Ok((token.value.clone(), qs));
371        }
372        // Also accept any keyword-like identifier
373        let token = self.peek().clone();
374        if matches!(
375            token.token_type,
376            TokenType::Identifier
377                | TokenType::Int
378                | TokenType::Integer
379                | TokenType::BigInt
380                | TokenType::SmallInt
381                | TokenType::TinyInt
382                | TokenType::Float
383                | TokenType::Double
384                | TokenType::Decimal
385                | TokenType::Numeric
386                | TokenType::Real
387                | TokenType::Varchar
388                | TokenType::Char
389                | TokenType::Text
390                | TokenType::Boolean
391                | TokenType::Date
392                | TokenType::Timestamp
393                | TokenType::TimestampTz
394                | TokenType::Time
395                | TokenType::Interval
396                | TokenType::Blob
397                | TokenType::Bytea
398                | TokenType::Json
399                | TokenType::Jsonb
400                | TokenType::Uuid
401                | TokenType::Array
402                | TokenType::Map
403                | TokenType::Struct
404        ) {
405            let t = self.advance().clone();
406            let qs = quote_style_from_char(t.quote_char);
407            Ok((t.value.clone(), qs))
408        } else {
409            Err(SqlglotError::ParserError {
410                message: format!(
411                    "Expected identifier, got {:?} ('{}') at line {} col {}",
412                    token.token_type, token.value, token.line, token.col
413                ),
414            })
415        }
416    }
417
418    // ── Top-level parsing ──────────────────────────────────────────
419
420    /// Parse a single SQL statement.
421    pub fn parse_statement(&mut self) -> Result<Statement> {
422        self.collect_comments();
423        let stmt = self.parse_statement_inner()?;
424        // Consume trailing semicolons
425        while self.match_token(TokenType::Semicolon) {}
426        Ok(stmt)
427    }
428
429    fn parse_statement_inner(&mut self) -> Result<Statement> {
430        self.collect_comments();
431        let comments = self.take_comments();
432        let mut stmt = match self.peek_type() {
433            TokenType::With => self.parse_with_statement(),
434            TokenType::Select => {
435                let select = self.parse_select_body(vec![])?;
436                self.maybe_parse_set_operation(Statement::Select(select))
437            }
438            TokenType::LParen => {
439                // Could be a parenthesized SELECT
440                let saved_pos = self.pos;
441                self.advance(); // consume '('
442                if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
443                    let inner = self.parse_statement_inner()?;
444                    self.expect(TokenType::RParen)?;
445                    self.maybe_parse_set_operation(inner)
446                } else {
447                    self.pos = saved_pos;
448                    Err(SqlglotError::ParserError {
449                        message: "Expected statement".into(),
450                    })
451                }
452            }
453            TokenType::Insert => self.parse_insert().map(Statement::Insert),
454            TokenType::Update => self.parse_update().map(Statement::Update),
455            TokenType::Delete => self.parse_delete().map(Statement::Delete),
456            TokenType::Merge => self.parse_merge().map(Statement::Merge),
457            TokenType::Create => self.parse_create_or_command(),
458            TokenType::Drop => self.parse_drop(),
459            TokenType::Alter => self.parse_alter_or_command(),
460            TokenType::Truncate => self.parse_truncate().map(Statement::Truncate),
461            TokenType::Begin | TokenType::Commit | TokenType::Rollback | TokenType::Savepoint => {
462                self.parse_transaction().map(Statement::Transaction)
463            }
464            TokenType::Explain => self.parse_explain().map(Statement::Explain),
465            TokenType::Use => self.parse_use().map(Statement::Use),
466            // Raw-tail command statements: SET / SHOW / DESCRIBE / ANALYZE
467            // (when standalone, not as part of EXPLAIN) / COMMENT ON ... .
468            // We preserve the verb plus the entire remainder up to `;` or EOF
469            // so the AST round-trips even though we don't model these in detail.
470            TokenType::Set => self.parse_command_kind("SET"),
471            TokenType::Show => self.parse_command_kind("SHOW"),
472            TokenType::Describe => self.parse_command_kind("DESCRIBE"),
473            TokenType::Analyze => self.parse_command_kind("ANALYZE"),
474            TokenType::Comment => self.parse_comment_on_command(),
475            TokenType::Grant => self.parse_command_kind("GRANT"),
476            TokenType::Revoke => self.parse_command_kind("REVOKE"),
477            // Vendor-specific verbs that tokenize as plain identifiers:
478            //   GO (T-SQL batch separator), DECLARE (T-SQL/PL-pgSQL),
479            //   LOAD (PG / MySQL extensions), REM / REMARK (SQL*Plus),
480            //   RESET / PRAGMA / VACUUM / REINDEX (PG / SQLite), CALL (PSM).
481            TokenType::Identifier if self.match_command_keyword() => {
482                self.parse_command_from_identifier()
483            }
484            _ => Err(SqlglotError::UnexpectedToken {
485                token: self.peek().clone(),
486            }),
487        }?;
488        if !comments.is_empty() {
489            attach_comments_to_statement(&mut stmt, comments);
490        }
491        Ok(stmt)
492    }
493
494    /// Parse multiple statements separated by semicolons.
495    pub fn parse_statements(&mut self) -> Result<Vec<Statement>> {
496        let mut stmts = Vec::new();
497        while !matches!(self.peek_type(), TokenType::Eof) {
498            while self.match_token(TokenType::Semicolon) {}
499            if matches!(self.peek_type(), TokenType::Eof) {
500                break;
501            }
502            stmts.push(self.parse_statement()?);
503        }
504        Ok(stmts)
505    }
506
507    // ── WITH / CTE parsing ─────────────────────────────────────────
508
509    fn parse_with_statement(&mut self) -> Result<Statement> {
510        self.expect(TokenType::With)?;
511        let recursive = self.match_token(TokenType::Recursive);
512        let mut ctes = vec![self.parse_cte(recursive)?];
513        while self.match_token(TokenType::Comma) {
514            ctes.push(self.parse_cte(recursive)?);
515        }
516
517        // Now parse the main query
518        match self.peek_type() {
519            TokenType::Select => {
520                let select = self.parse_select_body(ctes)?;
521                self.maybe_parse_set_operation(Statement::Select(select))
522            }
523            TokenType::Insert => {
524                // WITH ... INSERT is supported in some dialects
525                let ins = self.parse_insert()?;
526                // Attach CTEs if needed (simplification)
527                let _ = ctes; // CTEs with INSERT - we'll handle this later
528                Ok(Statement::Insert(ins))
529            }
530            _ => Err(SqlglotError::ParserError {
531                message: "Expected SELECT or INSERT after WITH clause".into(),
532            }),
533        }
534    }
535
536    fn parse_cte(&mut self, recursive: bool) -> Result<Cte> {
537        let (name, name_quote_style) = self.expect_name_with_quote()?;
538
539        let columns = if self.match_token(TokenType::LParen) {
540            let mut cols = vec![self.expect_name()?];
541            while self.match_token(TokenType::Comma) {
542                cols.push(self.expect_name()?);
543            }
544            self.expect(TokenType::RParen)?;
545            cols
546        } else {
547            vec![]
548        };
549
550        self.expect(TokenType::As)?;
551
552        let materialized = if self.match_keyword("MATERIALIZED") {
553            Some(true)
554        } else if self.check_keyword("NOT") {
555            let saved = self.pos;
556            self.advance();
557            if self.match_keyword("MATERIALIZED") {
558                Some(false)
559            } else {
560                self.pos = saved;
561                None
562            }
563        } else {
564            None
565        };
566
567        self.expect(TokenType::LParen)?;
568        let query = self.parse_statement_inner()?;
569        self.expect(TokenType::RParen)?;
570
571        Ok(Cte {
572            name,
573            name_quote_style,
574            columns,
575            query: Box::new(query),
576            materialized,
577            recursive,
578        })
579    }
580
581    // ── SELECT ──────────────────────────────────────────────────────
582
583    fn parse_select_body(&mut self, ctes: Vec<Cte>) -> Result<SelectStatement> {
584        self.expect(TokenType::Select)?;
585
586        let distinct = self.match_token(TokenType::Distinct);
587        // SQL-standard `SELECT ALL` quantifier (§7.12). Equivalent to omitting
588        // the quantifier; consume it so it does not get mis-parsed as a column.
589        if !distinct {
590            let _ = self.match_token(TokenType::All);
591        }
592
593        // TOP N (SQL Server style)
594        // Use parse_primary() instead of parse_expr() to prevent the parser
595        // from consuming `*` (SELECT all columns) as a multiplication operator.
596        // This correctly handles: TOP 5, TOP 100, TOP (expr), TOP (@var)
597        let top = if self.match_token(TokenType::Top) {
598            Some(Box::new(self.parse_primary()?))
599        } else {
600            None
601        };
602
603        let columns = self.parse_select_items()?;
604
605        let from = if self.match_token(TokenType::From) {
606            Some(FromClause {
607                source: self.parse_table_source()?,
608            })
609        } else {
610            None
611        };
612
613        let joins = self.parse_joins()?;
614
615        let where_clause = if self.match_token(TokenType::Where) {
616            Some(self.parse_expr()?)
617        } else {
618            None
619        };
620
621        let group_by = if self.match_token(TokenType::Group) {
622            self.expect(TokenType::By)?;
623            self.parse_group_by_list()?
624        } else {
625            vec![]
626        };
627
628        let having = if self.match_token(TokenType::Having) {
629            Some(self.parse_expr()?)
630        } else {
631            None
632        };
633
634        let qualify = if self.match_token(TokenType::Qualify) {
635            Some(self.parse_expr()?)
636        } else {
637            None
638        };
639
640        // Named WINDOW definitions
641        let window_definitions = if self.match_token(TokenType::Window) {
642            self.parse_window_definitions()?
643        } else {
644            vec![]
645        };
646
647        let order_by = if self.match_token(TokenType::Order) {
648            self.expect(TokenType::By)?;
649            self.parse_order_by_items()?
650        } else {
651            vec![]
652        };
653
654        let limit = if self.match_token(TokenType::Limit) {
655            Some(self.parse_expr()?)
656        } else {
657            None
658        };
659
660        let offset = if self.match_token(TokenType::Offset) {
661            let expr = self.parse_expr()?;
662            // T-SQL / ANSI SQL:2008 form: OFFSET n ROWS [FETCH …].
663            // Consume the optional ROWS/ROW keyword so FETCH can match next.
664            let _ = self.match_token(TokenType::Rows) || self.match_keyword("ROW");
665            Some(expr)
666        } else {
667            None
668        };
669
670        // FETCH FIRST|NEXT n ROWS ONLY (Oracle / ANSI SQL:2008 / T-SQL)
671        let fetch_first = if self.match_token(TokenType::Fetch) {
672            // consume FIRST or NEXT
673            let _ = self.match_token(TokenType::First) || self.match_token(TokenType::Next);
674            let count = self.parse_expr()?;
675            // consume ROWS or ROW
676            let _ = self.match_keyword("ROWS") || self.match_keyword("ROW");
677            // consume ONLY
678            let _ = self.match_token(TokenType::Only);
679            Some(count)
680        } else {
681            None
682        };
683
684        Ok(SelectStatement {
685            comments: vec![],
686            ctes,
687            distinct,
688            top,
689            columns,
690            from,
691            joins,
692            where_clause,
693            group_by,
694            having,
695            order_by,
696            limit,
697            offset,
698            fetch_first,
699            qualify,
700            window_definitions,
701        })
702    }
703
704    fn parse_window_definitions(&mut self) -> Result<Vec<WindowDefinition>> {
705        let mut defs = Vec::new();
706        loop {
707            let name = self.expect_name()?;
708            self.expect(TokenType::As)?;
709            self.expect(TokenType::LParen)?;
710            let spec = self.parse_window_spec()?;
711            self.expect(TokenType::RParen)?;
712            defs.push(WindowDefinition { name, spec });
713            if !self.match_token(TokenType::Comma) {
714                break;
715            }
716        }
717        Ok(defs)
718    }
719
720    /// Check if we should parse a set operation (UNION / INTERSECT / EXCEPT)
721    fn maybe_parse_set_operation(&mut self, left: Statement) -> Result<Statement> {
722        let op = match self.peek_type() {
723            TokenType::Union => SetOperationType::Union,
724            TokenType::Intersect => SetOperationType::Intersect,
725            TokenType::Except => SetOperationType::Except,
726            _ => return Ok(left),
727        };
728        self.advance();
729
730        let all = self.match_token(TokenType::All);
731        let _ = self.match_token(TokenType::Distinct); // UNION DISTINCT
732
733        let right = self.parse_statement_inner()?;
734
735        // Check for further set operations chaining
736        let combined = Statement::SetOperation(SetOperationStatement {
737            comments: vec![],
738            op,
739            all,
740            left: Box::new(left),
741            right: Box::new(right),
742            order_by: vec![],
743            limit: None,
744            offset: None,
745        });
746
747        // Parse trailing ORDER BY / LIMIT / OFFSET that applies to the whole set operation
748        if matches!(
749            self.peek_type(),
750            TokenType::Union | TokenType::Intersect | TokenType::Except
751        ) {
752            self.maybe_parse_set_operation(combined)
753        } else {
754            // Check for global ORDER BY / LIMIT
755            if let Statement::SetOperation(mut sop) = combined {
756                if self.match_token(TokenType::Order) {
757                    self.expect(TokenType::By)?;
758                    sop.order_by = self.parse_order_by_items()?;
759                }
760                if self.match_token(TokenType::Limit) {
761                    sop.limit = Some(self.parse_expr()?);
762                }
763                if self.match_token(TokenType::Offset) {
764                    sop.offset = Some(self.parse_expr()?);
765                }
766                Ok(Statement::SetOperation(sop))
767            } else {
768                Ok(combined)
769            }
770        }
771    }
772
773    fn parse_select_items(&mut self) -> Result<Vec<SelectItem>> {
774        let mut items = vec![self.parse_select_item()?];
775        while self.match_token(TokenType::Comma) {
776            items.push(self.parse_select_item()?);
777        }
778        Ok(items)
779    }
780
781    fn parse_select_item(&mut self) -> Result<SelectItem> {
782        if self.peek().token_type == TokenType::Star {
783            self.advance();
784            return Ok(SelectItem::Wildcard);
785        }
786
787        let expr = self.parse_expr()?;
788
789        // Check for table.* pattern
790        if let Expr::QualifiedWildcard { ref table } = expr {
791            return Ok(SelectItem::QualifiedWildcard {
792                table: table.clone(),
793            });
794        }
795
796        let (alias, alias_quote_style) = match self.parse_optional_alias()? {
797            Some((name, qs)) => (Some(name), qs),
798            None => (None, QuoteStyle::None),
799        };
800
801        Ok(SelectItem::Expr {
802            expr,
803            alias,
804            alias_quote_style,
805        })
806    }
807
808    fn parse_optional_alias(&mut self) -> Result<Option<(String, QuoteStyle)>> {
809        if self.match_token(TokenType::As) {
810            return Ok(Some(self.expect_name_with_quote()?));
811        }
812        // Implicit alias
813        if self.is_name_token() {
814            let peeked_upper = self.peek().value.to_uppercase();
815            if !matches!(
816                peeked_upper.as_str(),
817                "FROM"
818                    | "WHERE"
819                    | "GROUP"
820                    | "ORDER"
821                    | "LIMIT"
822                    | "HAVING"
823                    | "UNION"
824                    | "INTERSECT"
825                    | "EXCEPT"
826                    | "JOIN"
827                    | "INNER"
828                    | "LEFT"
829                    | "RIGHT"
830                    | "FULL"
831                    | "CROSS"
832                    | "ON"
833                    | "WINDOW"
834                    | "QUALIFY"
835                    | "INTO"
836                    | "SET"
837                    | "RETURNING"
838                    | "PIVOT"
839                    | "UNPIVOT"
840            ) {
841                let token = self.advance().clone();
842                let qs = quote_style_from_char(token.quote_char);
843                return Ok(Some((token.value.clone(), qs)));
844            }
845        }
846        Ok(None)
847    }
848
849    fn parse_table_source(&mut self) -> Result<TableSource> {
850        let source = self.parse_base_table_source()?;
851        // Check for trailing PIVOT / UNPIVOT
852        self.parse_pivot_or_unpivot(source)
853    }
854
855    fn parse_base_table_source(&mut self) -> Result<TableSource> {
856        // LATERAL
857        if self.match_token(TokenType::Lateral) {
858            let source = self.parse_table_source()?;
859            return Ok(TableSource::Lateral {
860                source: Box::new(source),
861            });
862        }
863
864        // UNNEST(expr)
865        if self.match_token(TokenType::Unnest) {
866            self.expect(TokenType::LParen)?;
867            let expr = self.parse_expr()?;
868            self.expect(TokenType::RParen)?;
869            let (alias, alias_quote_style) = match self.parse_optional_alias()? {
870                Some((name, qs)) => (Some(name), qs),
871                None => (None, QuoteStyle::None),
872            };
873            let with_offset = self.match_keyword("WITH") && self.match_keyword("OFFSET");
874            return Ok(TableSource::Unnest {
875                expr: Box::new(expr),
876                alias,
877                alias_quote_style,
878                with_offset,
879            });
880        }
881
882        // Subquery: (SELECT ...)
883        if self.peek_type() == &TokenType::LParen {
884            let saved = self.pos;
885            self.advance();
886            if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
887                let query = self.parse_statement_inner()?;
888                self.expect(TokenType::RParen)?;
889                let (alias, alias_quote_style) = match self.parse_optional_alias()? {
890                    Some((name, qs)) => (Some(name), qs),
891                    None => (None, QuoteStyle::None),
892                };
893                return Ok(TableSource::Subquery {
894                    query: Box::new(query),
895                    alias,
896                    alias_quote_style,
897                });
898            }
899            self.pos = saved;
900        }
901
902        // Regular table reference (possibly with function syntax)
903        let table_ref = self.parse_table_ref()?;
904
905        // Check if it's actually a table function: name(args...)
906        if self.peek_type() == &TokenType::LParen && table_ref.schema.is_none() {
907            self.advance();
908            let args = if self.peek_type() != &TokenType::RParen {
909                self.parse_expr_list()?
910            } else {
911                vec![]
912            };
913            self.expect(TokenType::RParen)?;
914            let (alias, alias_quote_style) = match self.parse_optional_alias()? {
915                Some((name, qs)) => (Some(name), qs),
916                None => (None, QuoteStyle::None),
917            };
918            return Ok(TableSource::TableFunction {
919                name: table_ref.name,
920                args,
921                alias,
922                alias_quote_style,
923            });
924        }
925
926        Ok(TableSource::Table(table_ref))
927    }
928
929    /// After parsing a base table source, check if PIVOT or UNPIVOT follows.
930    fn parse_pivot_or_unpivot(&mut self, source: TableSource) -> Result<TableSource> {
931        if self.match_token(TokenType::Pivot) {
932            self.expect(TokenType::LParen)?;
933            let aggregate = self.parse_expr()?;
934            self.expect_keyword("FOR")?;
935            let for_column = self.expect_name()?;
936            self.expect(TokenType::In)?;
937            self.expect(TokenType::LParen)?;
938            let in_values = self.parse_pivot_values()?;
939            self.expect(TokenType::RParen)?;
940            self.expect(TokenType::RParen)?;
941            let (alias, alias_quote_style) = match self.parse_optional_alias()? {
942                Some((name, qs)) => (Some(name), qs),
943                None => (None, QuoteStyle::None),
944            };
945            return Ok(TableSource::Pivot {
946                source: Box::new(source),
947                aggregate: Box::new(aggregate),
948                for_column,
949                in_values,
950                alias,
951                alias_quote_style,
952            });
953        }
954        if self.match_token(TokenType::Unpivot) {
955            self.expect(TokenType::LParen)?;
956            let value_column = self.expect_name()?;
957            self.expect_keyword("FOR")?;
958            let for_column = self.expect_name()?;
959            self.expect(TokenType::In)?;
960            self.expect(TokenType::LParen)?;
961            let in_columns = self.parse_pivot_values()?;
962            self.expect(TokenType::RParen)?;
963            self.expect(TokenType::RParen)?;
964            let (alias, alias_quote_style) = match self.parse_optional_alias()? {
965                Some((name, qs)) => (Some(name), qs),
966                None => (None, QuoteStyle::None),
967            };
968            return Ok(TableSource::Unpivot {
969                source: Box::new(source),
970                value_column,
971                for_column,
972                in_columns,
973                alias,
974                alias_quote_style,
975            });
976        }
977        Ok(source)
978    }
979
980    /// Parse comma-separated pivot values, each optionally aliased.
981    fn parse_pivot_values(&mut self) -> Result<Vec<PivotValue>> {
982        let mut values = Vec::new();
983        loop {
984            let value = self.parse_expr()?;
985            let (alias, alias_quote_style) = match self.parse_optional_alias()? {
986                Some((name, qs)) => (Some(name), qs),
987                None => (None, QuoteStyle::None),
988            };
989            values.push(PivotValue {
990                value,
991                alias,
992                alias_quote_style,
993            });
994            if !self.match_token(TokenType::Comma) {
995                break;
996            }
997        }
998        Ok(values)
999    }
1000
1001    fn parse_table_ref(&mut self) -> Result<TableRef> {
1002        let (first, first_qs) = self.expect_name_with_quote()?;
1003
1004        // Check for schema.table or catalog.schema.table
1005        let (catalog, schema, name, name_qs) = if self.match_token(TokenType::Dot) {
1006            let (second, second_qs) = self.expect_name_with_quote()?;
1007            if self.match_token(TokenType::Dot) {
1008                let (third, third_qs) = self.expect_name_with_quote()?;
1009                (Some(first), Some(second), third, third_qs)
1010            } else {
1011                (None, Some(first), second, second_qs)
1012            }
1013        } else {
1014            (None, None, first, first_qs)
1015        };
1016
1017        let (alias, alias_quote_style) = match self.parse_optional_alias()? {
1018            Some((name, qs)) => (Some(name), qs),
1019            None => (None, QuoteStyle::None),
1020        };
1021
1022        Ok(TableRef {
1023            catalog,
1024            schema,
1025            name,
1026            alias,
1027            name_quote_style: name_qs,
1028            alias_quote_style,
1029        })
1030    }
1031
1032    /// Like `parse_table_ref` but does not consume an alias.
1033    fn parse_table_ref_no_alias(&mut self) -> Result<TableRef> {
1034        let (first, first_qs) = self.expect_name_with_quote()?;
1035
1036        let (catalog, schema, name, name_qs) = if self.match_token(TokenType::Dot) {
1037            let (second, second_qs) = self.expect_name_with_quote()?;
1038            if self.match_token(TokenType::Dot) {
1039                let (third, third_qs) = self.expect_name_with_quote()?;
1040                (Some(first), Some(second), third, third_qs)
1041            } else {
1042                (None, Some(first), second, second_qs)
1043            }
1044        } else {
1045            (None, None, first, first_qs)
1046        };
1047
1048        Ok(TableRef {
1049            catalog,
1050            schema,
1051            name,
1052            alias: None,
1053            name_quote_style: name_qs,
1054            alias_quote_style: QuoteStyle::None,
1055        })
1056    }
1057
1058    fn parse_joins(&mut self) -> Result<Vec<JoinClause>> {
1059        let mut joins = Vec::new();
1060        loop {
1061            let join_type = match self.peek_type() {
1062                // `FROM a, b` is treated as `FROM a CROSS JOIN b`. Note the
1063                // SQL standard gives comma a lower precedence than explicit
1064                // JOIN operators (so `FROM a, b JOIN c ON ...` should be
1065                // `a CROSS JOIN (b JOIN c ...)`), but we flatten everything
1066                // into a left-deep chain. Column resolution still works for
1067                // the common cases since the join order is associative when
1068                // ON-clauses only reference adjacent tables.
1069                TokenType::Comma => {
1070                    self.advance();
1071                    JoinType::Cross
1072                }
1073                TokenType::Join => {
1074                    self.advance();
1075                    JoinType::Inner
1076                }
1077                TokenType::Inner => {
1078                    self.advance();
1079                    self.expect(TokenType::Join)?;
1080                    JoinType::Inner
1081                }
1082                TokenType::Left => {
1083                    self.advance();
1084                    let _ = self.match_token(TokenType::Outer);
1085                    self.expect(TokenType::Join)?;
1086                    JoinType::Left
1087                }
1088                TokenType::Right => {
1089                    self.advance();
1090                    let _ = self.match_token(TokenType::Outer);
1091                    self.expect(TokenType::Join)?;
1092                    JoinType::Right
1093                }
1094                TokenType::Full => {
1095                    self.advance();
1096                    let _ = self.match_token(TokenType::Outer);
1097                    self.expect(TokenType::Join)?;
1098                    JoinType::Full
1099                }
1100                TokenType::Cross => {
1101                    self.advance();
1102                    self.expect(TokenType::Join)?;
1103                    JoinType::Cross
1104                }
1105                _ => break,
1106            };
1107
1108            let table = self.parse_table_source()?;
1109            let mut on = None;
1110            let mut using = vec![];
1111
1112            if self.match_token(TokenType::On) {
1113                on = Some(self.parse_expr()?);
1114            } else if self.match_token(TokenType::Using) {
1115                self.expect(TokenType::LParen)?;
1116                using = vec![self.expect_name()?];
1117                while self.match_token(TokenType::Comma) {
1118                    using.push(self.expect_name()?);
1119                }
1120                self.expect(TokenType::RParen)?;
1121            }
1122
1123            joins.push(JoinClause {
1124                join_type,
1125                table,
1126                on,
1127                using,
1128            });
1129        }
1130        Ok(joins)
1131    }
1132
1133    fn parse_order_by_items(&mut self) -> Result<Vec<OrderByItem>> {
1134        let mut items = Vec::new();
1135        loop {
1136            let expr = self.parse_expr()?;
1137            let ascending = if self.match_token(TokenType::Desc) {
1138                false
1139            } else {
1140                let _ = self.match_token(TokenType::Asc);
1141                true
1142            };
1143
1144            let nulls_first = if self.match_token(TokenType::Nulls) {
1145                if self.match_token(TokenType::First) {
1146                    Some(true)
1147                } else {
1148                    self.expect(TokenType::Identifier)?; // LAST
1149                    Some(false)
1150                }
1151            } else {
1152                None
1153            };
1154
1155            items.push(OrderByItem {
1156                expr,
1157                ascending,
1158                nulls_first,
1159            });
1160            if !self.match_token(TokenType::Comma) {
1161                break;
1162            }
1163        }
1164        Ok(items)
1165    }
1166
1167    fn parse_expr_list(&mut self) -> Result<Vec<Expr>> {
1168        let mut exprs = vec![self.parse_expr()?];
1169        while self.match_token(TokenType::Comma) {
1170            exprs.push(self.parse_expr()?);
1171        }
1172        Ok(exprs)
1173    }
1174
1175    /// Parse a GROUP BY list, which may contain regular expressions,
1176    /// CUBE(...), ROLLUP(...), and GROUPING SETS(...).
1177    fn parse_group_by_list(&mut self) -> Result<Vec<Expr>> {
1178        let mut items = vec![self.parse_group_by_item()?];
1179        while self.match_token(TokenType::Comma) {
1180            items.push(self.parse_group_by_item()?);
1181        }
1182        Ok(items)
1183    }
1184
1185    /// Parse a single GROUP BY item: a CUBE, ROLLUP, GROUPING SETS, or regular expression.
1186    fn parse_group_by_item(&mut self) -> Result<Expr> {
1187        match self.peek_type() {
1188            TokenType::Cube => {
1189                self.advance();
1190                self.expect(TokenType::LParen)?;
1191                let exprs = if self.peek_type() == &TokenType::RParen {
1192                    vec![]
1193                } else {
1194                    self.parse_group_by_element_list()?
1195                };
1196                self.expect(TokenType::RParen)?;
1197                Ok(Expr::Cube { exprs })
1198            }
1199            TokenType::Rollup => {
1200                self.advance();
1201                self.expect(TokenType::LParen)?;
1202                let exprs = if self.peek_type() == &TokenType::RParen {
1203                    vec![]
1204                } else {
1205                    self.parse_group_by_element_list()?
1206                };
1207                self.expect(TokenType::RParen)?;
1208                Ok(Expr::Rollup { exprs })
1209            }
1210            TokenType::Grouping => {
1211                // Could be GROUPING SETS or GROUPING() function
1212                let saved = self.pos;
1213                self.advance();
1214                if self.peek_type() == &TokenType::Sets {
1215                    // GROUPING SETS (...)
1216                    self.advance();
1217                    self.expect(TokenType::LParen)?;
1218                    let sets = self.parse_grouping_sets_elements()?;
1219                    self.expect(TokenType::RParen)?;
1220                    Ok(Expr::GroupingSets { sets })
1221                } else {
1222                    // It's the GROUPING() function, backtrack and parse as expression
1223                    self.pos = saved;
1224                    self.parse_expr()
1225                }
1226            }
1227            _ => self.parse_expr(),
1228        }
1229    }
1230
1231    /// Parse elements inside CUBE(...) or ROLLUP(...).
1232    /// Each element can be a single expression or a parenthesized tuple of expressions.
1233    fn parse_group_by_element_list(&mut self) -> Result<Vec<Expr>> {
1234        let mut items = vec![self.parse_group_by_element()?];
1235        while self.match_token(TokenType::Comma) {
1236            items.push(self.parse_group_by_element()?);
1237        }
1238        Ok(items)
1239    }
1240
1241    /// Parse a single element inside CUBE/ROLLUP: either `expr` or `(expr, expr, ...)`.
1242    fn parse_group_by_element(&mut self) -> Result<Expr> {
1243        if self.peek_type() == &TokenType::LParen {
1244            self.advance();
1245            let exprs = self.parse_expr_list()?;
1246            self.expect(TokenType::RParen)?;
1247            if exprs.len() == 1 {
1248                Ok(Expr::Nested(Box::new(exprs.into_iter().next().unwrap())))
1249            } else {
1250                Ok(Expr::Tuple(exprs))
1251            }
1252        } else {
1253            self.parse_expr()
1254        }
1255    }
1256
1257    /// Parse elements inside GROUPING SETS (...).
1258    /// Each element can be: (), (expr, ...), CUBE(...), ROLLUP(...), or a single expr.
1259    fn parse_grouping_sets_elements(&mut self) -> Result<Vec<Expr>> {
1260        let mut items = vec![self.parse_grouping_sets_element()?];
1261        while self.match_token(TokenType::Comma) {
1262            items.push(self.parse_grouping_sets_element()?);
1263        }
1264        Ok(items)
1265    }
1266
1267    /// Parse a single GROUPING SETS element.
1268    fn parse_grouping_sets_element(&mut self) -> Result<Expr> {
1269        match self.peek_type() {
1270            TokenType::Cube => {
1271                self.advance();
1272                self.expect(TokenType::LParen)?;
1273                let exprs = if self.peek_type() == &TokenType::RParen {
1274                    vec![]
1275                } else {
1276                    self.parse_group_by_element_list()?
1277                };
1278                self.expect(TokenType::RParen)?;
1279                Ok(Expr::Cube { exprs })
1280            }
1281            TokenType::Rollup => {
1282                self.advance();
1283                self.expect(TokenType::LParen)?;
1284                let exprs = if self.peek_type() == &TokenType::RParen {
1285                    vec![]
1286                } else {
1287                    self.parse_group_by_element_list()?
1288                };
1289                self.expect(TokenType::RParen)?;
1290                Ok(Expr::Rollup { exprs })
1291            }
1292            TokenType::LParen => {
1293                self.advance();
1294                if self.peek_type() == &TokenType::RParen {
1295                    // Empty grouping set: ()
1296                    self.advance();
1297                    Ok(Expr::Tuple(vec![]))
1298                } else {
1299                    let exprs = self.parse_expr_list()?;
1300                    self.expect(TokenType::RParen)?;
1301                    if exprs.len() == 1 {
1302                        Ok(Expr::Nested(Box::new(exprs.into_iter().next().unwrap())))
1303                    } else {
1304                        Ok(Expr::Tuple(exprs))
1305                    }
1306                }
1307            }
1308            _ => self.parse_expr(),
1309        }
1310    }
1311
1312    // ── INSERT ──────────────────────────────────────────────────────
1313
1314    fn parse_insert(&mut self) -> Result<InsertStatement> {
1315        self.expect(TokenType::Insert)?;
1316        let _ = self.match_token(TokenType::Into);
1317        let table = self.parse_table_ref()?;
1318
1319        let columns = if self.match_token(TokenType::LParen) {
1320            let mut cols = vec![self.expect_name()?];
1321            while self.match_token(TokenType::Comma) {
1322                cols.push(self.expect_name()?);
1323            }
1324            self.expect(TokenType::RParen)?;
1325            cols
1326        } else {
1327            vec![]
1328        };
1329
1330        let source = if self.match_token(TokenType::Values) {
1331            let mut rows = Vec::new();
1332            loop {
1333                self.expect(TokenType::LParen)?;
1334                let row = self.parse_expr_list()?;
1335                self.expect(TokenType::RParen)?;
1336                rows.push(row);
1337                if !self.match_token(TokenType::Comma) {
1338                    break;
1339                }
1340            }
1341            InsertSource::Values(rows)
1342        } else if matches!(
1343            self.peek_type(),
1344            TokenType::Select | TokenType::With | TokenType::LParen
1345        ) {
1346            InsertSource::Query(Box::new(self.parse_statement_inner()?))
1347        } else if self.match_token(TokenType::Default) {
1348            self.expect(TokenType::Values)?;
1349            InsertSource::Default
1350        } else {
1351            return Err(SqlglotError::ParserError {
1352                message: "Expected VALUES, SELECT, or DEFAULT VALUES after INSERT".into(),
1353            });
1354        };
1355
1356        // ON CONFLICT
1357        let on_conflict = if self.match_token(TokenType::On) {
1358            if self.match_token(TokenType::Conflict) {
1359                let columns = if self.match_token(TokenType::LParen) {
1360                    let mut cols = vec![self.expect_name()?];
1361                    while self.match_token(TokenType::Comma) {
1362                        cols.push(self.expect_name()?);
1363                    }
1364                    self.expect(TokenType::RParen)?;
1365                    cols
1366                } else {
1367                    vec![]
1368                };
1369                self.expect(TokenType::Do)?;
1370                let action = if self.match_token(TokenType::Nothing) {
1371                    ConflictAction::DoNothing
1372                } else {
1373                    self.expect(TokenType::Update)?;
1374                    self.expect(TokenType::Set)?;
1375                    let mut assignments = Vec::new();
1376                    loop {
1377                        let col = self.expect_name()?;
1378                        self.expect(TokenType::Eq)?;
1379                        let val = self.parse_expr()?;
1380                        assignments.push((col, val));
1381                        if !self.match_token(TokenType::Comma) {
1382                            break;
1383                        }
1384                    }
1385                    ConflictAction::DoUpdate(assignments)
1386                };
1387                Some(OnConflict { columns, action })
1388            } else {
1389                None
1390            }
1391        } else {
1392            None
1393        };
1394
1395        let returning = if self.match_token(TokenType::Returning) {
1396            self.parse_select_items()?
1397        } else {
1398            vec![]
1399        };
1400
1401        Ok(InsertStatement {
1402            comments: vec![],
1403            table,
1404            columns,
1405            source,
1406            on_conflict,
1407            returning,
1408        })
1409    }
1410
1411    // ── UPDATE ──────────────────────────────────────────────────────
1412
1413    fn parse_update(&mut self) -> Result<UpdateStatement> {
1414        self.expect(TokenType::Update)?;
1415        let table = self.parse_table_ref()?;
1416        self.expect(TokenType::Set)?;
1417
1418        let mut assignments = Vec::new();
1419        loop {
1420            // Accept qualified LHS like `alias.col` (Oracle, T-SQL idiom).
1421            let mut col = self.expect_name()?;
1422            while self.match_token(TokenType::Dot) {
1423                col.push('.');
1424                col.push_str(&self.expect_name()?);
1425            }
1426            self.expect(TokenType::Eq)?;
1427            let val = self.parse_expr()?;
1428            assignments.push((col, val));
1429            if !self.match_token(TokenType::Comma) {
1430                break;
1431            }
1432        }
1433
1434        let from = if self.match_token(TokenType::From) {
1435            Some(FromClause {
1436                source: self.parse_table_source()?,
1437            })
1438        } else {
1439            None
1440        };
1441
1442        let where_clause = if self.match_token(TokenType::Where) {
1443            Some(self.parse_expr()?)
1444        } else {
1445            None
1446        };
1447
1448        let returning = if self.match_token(TokenType::Returning) {
1449            self.parse_select_items()?
1450        } else {
1451            vec![]
1452        };
1453
1454        Ok(UpdateStatement {
1455            comments: vec![],
1456            table,
1457            assignments,
1458            from,
1459            where_clause,
1460            returning,
1461        })
1462    }
1463
1464    // ── DELETE ──────────────────────────────────────────────────────
1465
1466    fn parse_delete(&mut self) -> Result<DeleteStatement> {
1467        self.expect(TokenType::Delete)?;
1468        self.expect(TokenType::From)?;
1469        let table = self.parse_table_ref()?;
1470
1471        let using = if self.match_token(TokenType::Using) {
1472            Some(FromClause {
1473                source: self.parse_table_source()?,
1474            })
1475        } else {
1476            None
1477        };
1478
1479        let where_clause = if self.match_token(TokenType::Where) {
1480            Some(self.parse_expr()?)
1481        } else {
1482            None
1483        };
1484
1485        let returning = if self.match_token(TokenType::Returning) {
1486            self.parse_select_items()?
1487        } else {
1488            vec![]
1489        };
1490
1491        Ok(DeleteStatement {
1492            comments: vec![],
1493            table,
1494            using,
1495            where_clause,
1496            returning,
1497        })
1498    }
1499
1500    // ── MERGE ───────────────────────────────────────────────────────
1501
1502    fn parse_merge(&mut self) -> Result<MergeStatement> {
1503        self.expect(TokenType::Merge)?;
1504        let _ = self.match_token(TokenType::Into);
1505        let target = self.parse_table_ref()?;
1506
1507        self.expect(TokenType::Using)?;
1508        let source = self.parse_table_source()?;
1509
1510        self.expect(TokenType::On)?;
1511        let on = self.parse_expr()?;
1512
1513        let mut clauses = Vec::new();
1514        while self.match_token(TokenType::When) {
1515            clauses.push(self.parse_merge_clause()?);
1516        }
1517
1518        if clauses.is_empty() {
1519            return Err(SqlglotError::ParserError {
1520                message: "MERGE requires at least one WHEN clause".into(),
1521            });
1522        }
1523
1524        // OUTPUT clause (T-SQL extension)
1525        let output = if self.match_keyword("OUTPUT") {
1526            self.parse_select_items()?
1527        } else {
1528            vec![]
1529        };
1530
1531        Ok(MergeStatement {
1532            comments: vec![],
1533            target,
1534            source,
1535            on,
1536            clauses,
1537            output,
1538        })
1539    }
1540
1541    fn parse_merge_clause(&mut self) -> Result<MergeClause> {
1542        let kind = if self.match_token(TokenType::Not) {
1543            self.expect(TokenType::Matched)?;
1544            if self.match_keyword("BY") {
1545                if self.match_keyword("SOURCE") {
1546                    MergeClauseKind::NotMatchedBySource
1547                } else {
1548                    // BY TARGET is the default / explicit form
1549                    let _ = self.match_keyword("TARGET");
1550                    MergeClauseKind::NotMatched
1551                }
1552            } else {
1553                MergeClauseKind::NotMatched
1554            }
1555        } else {
1556            self.expect(TokenType::Matched)?;
1557            MergeClauseKind::Matched
1558        };
1559
1560        let condition = if self.match_token(TokenType::And) {
1561            Some(self.parse_expr()?)
1562        } else {
1563            None
1564        };
1565
1566        self.expect(TokenType::Then)?;
1567
1568        let action = self.parse_merge_action(&kind)?;
1569
1570        Ok(MergeClause {
1571            kind,
1572            condition,
1573            action,
1574        })
1575    }
1576
1577    fn parse_merge_action(&mut self, kind: &MergeClauseKind) -> Result<MergeAction> {
1578        if self.match_token(TokenType::Update) {
1579            self.expect(TokenType::Set)?;
1580            let mut assignments = Vec::new();
1581            loop {
1582                let mut col = self.expect_name()?;
1583                // Support dotted column names like target.col
1584                while self.match_token(TokenType::Dot) {
1585                    col.push('.');
1586                    col.push_str(&self.expect_name()?);
1587                }
1588                self.expect(TokenType::Eq)?;
1589                let val = self.parse_expr()?;
1590                assignments.push((col, val));
1591                if !self.match_token(TokenType::Comma) {
1592                    break;
1593                }
1594            }
1595            Ok(MergeAction::Update(assignments))
1596        } else if self.match_token(TokenType::Insert) {
1597            // INSERT ROW (BigQuery)
1598            if self.match_keyword("ROW") {
1599                return Ok(MergeAction::InsertRow);
1600            }
1601
1602            let columns = if self.match_token(TokenType::LParen) {
1603                let mut cols = vec![self.expect_name()?];
1604                while self.match_token(TokenType::Comma) {
1605                    cols.push(self.expect_name()?);
1606                }
1607                self.expect(TokenType::RParen)?;
1608                cols
1609            } else {
1610                vec![]
1611            };
1612
1613            self.expect(TokenType::Values)?;
1614            self.expect(TokenType::LParen)?;
1615            let values = self.parse_expr_list()?;
1616            self.expect(TokenType::RParen)?;
1617
1618            Ok(MergeAction::Insert { columns, values })
1619        } else if self.match_token(TokenType::Delete) {
1620            Ok(MergeAction::Delete)
1621        } else {
1622            Err(SqlglotError::ParserError {
1623                message: format!(
1624                    "Expected UPDATE, INSERT, or DELETE after WHEN {} THEN",
1625                    match kind {
1626                        MergeClauseKind::Matched => "MATCHED",
1627                        MergeClauseKind::NotMatched => "NOT MATCHED",
1628                        MergeClauseKind::NotMatchedBySource => "NOT MATCHED BY SOURCE",
1629                    }
1630                ),
1631            })
1632        }
1633    }
1634
1635    // ── CREATE ──────────────────────────────────────────────────────
1636
1637    fn parse_create(&mut self) -> Result<Statement> {
1638        self.expect(TokenType::Create)?;
1639
1640        let or_replace = if self.check_keyword("OR") {
1641            self.advance();
1642            self.expect(TokenType::Replace)?;
1643            true
1644        } else {
1645            false
1646        };
1647
1648        let temporary = self.match_token(TokenType::Temporary) || self.match_token(TokenType::Temp);
1649
1650        let materialized = self.match_token(TokenType::Materialized);
1651
1652        if self.match_token(TokenType::View) {
1653            return self
1654                .parse_create_view(or_replace, materialized)
1655                .map(Statement::CreateView);
1656        }
1657
1658        self.expect(TokenType::Table)?;
1659
1660        let if_not_exists = if self.match_token(TokenType::If) {
1661            self.expect(TokenType::Not)?;
1662            self.expect(TokenType::Exists)?;
1663            true
1664        } else {
1665            false
1666        };
1667
1668        let table = self.parse_table_ref_no_alias()?;
1669
1670        // CREATE TABLE ... AS SELECT ...
1671        if self.match_token(TokenType::As) {
1672            let query = self.parse_statement_inner()?;
1673            return Ok(Statement::CreateTable(CreateTableStatement {
1674                comments: vec![],
1675                if_not_exists,
1676                temporary,
1677                table,
1678                columns: vec![],
1679                constraints: vec![],
1680                as_select: Some(Box::new(query)),
1681            }));
1682        }
1683
1684        self.expect(TokenType::LParen)?;
1685
1686        let mut columns = Vec::new();
1687        let mut constraints = Vec::new();
1688
1689        loop {
1690            // Check for table-level constraints
1691            if matches!(
1692                self.peek_type(),
1693                TokenType::Primary
1694                    | TokenType::Unique
1695                    | TokenType::Foreign
1696                    | TokenType::Check
1697                    | TokenType::Constraint
1698            ) {
1699                constraints.push(self.parse_table_constraint()?);
1700            } else if self.peek_type() != &TokenType::RParen {
1701                columns.push(self.parse_column_def()?);
1702            }
1703
1704            if !self.match_token(TokenType::Comma) {
1705                break;
1706            }
1707        }
1708        self.expect(TokenType::RParen)?;
1709
1710        Ok(Statement::CreateTable(CreateTableStatement {
1711            comments: vec![],
1712            if_not_exists,
1713            temporary,
1714            table,
1715            columns,
1716            constraints,
1717            as_select: None,
1718        }))
1719    }
1720
1721    fn parse_create_view(
1722        &mut self,
1723        or_replace: bool,
1724        materialized: bool,
1725    ) -> Result<CreateViewStatement> {
1726        let if_not_exists = if self.match_token(TokenType::If) {
1727            self.expect(TokenType::Not)?;
1728            self.expect(TokenType::Exists)?;
1729            true
1730        } else {
1731            false
1732        };
1733
1734        // Parse name without alias (so AS is not consumed as an alias)
1735        let name = self.parse_table_ref_no_alias()?;
1736
1737        let columns = if self.match_token(TokenType::LParen) {
1738            let mut cols = vec![self.expect_name()?];
1739            while self.match_token(TokenType::Comma) {
1740                cols.push(self.expect_name()?);
1741            }
1742            self.expect(TokenType::RParen)?;
1743            cols
1744        } else {
1745            vec![]
1746        };
1747
1748        self.expect(TokenType::As)?;
1749        let query = self.parse_statement_inner()?;
1750
1751        Ok(CreateViewStatement {
1752            comments: vec![],
1753            name,
1754            columns,
1755            query: Box::new(query),
1756            or_replace,
1757            materialized,
1758            if_not_exists,
1759        })
1760    }
1761
1762    fn parse_table_constraint(&mut self) -> Result<TableConstraint> {
1763        let name = if self.match_token(TokenType::Constraint) {
1764            Some(self.expect_name()?)
1765        } else {
1766            None
1767        };
1768
1769        if self.match_token(TokenType::Primary) {
1770            self.expect(TokenType::Key)?;
1771            self.expect(TokenType::LParen)?;
1772            let columns = self.parse_name_list()?;
1773            self.expect(TokenType::RParen)?;
1774            Ok(TableConstraint::PrimaryKey { name, columns })
1775        } else if self.match_token(TokenType::Unique) {
1776            self.expect(TokenType::LParen)?;
1777            let columns = self.parse_name_list()?;
1778            self.expect(TokenType::RParen)?;
1779            Ok(TableConstraint::Unique { name, columns })
1780        } else if self.match_token(TokenType::Foreign) {
1781            self.expect(TokenType::Key)?;
1782            self.expect(TokenType::LParen)?;
1783            let columns = self.parse_name_list()?;
1784            self.expect(TokenType::RParen)?;
1785            self.expect(TokenType::References)?;
1786            let ref_table = self.parse_table_ref()?;
1787            self.expect(TokenType::LParen)?;
1788            let ref_columns = self.parse_name_list()?;
1789            self.expect(TokenType::RParen)?;
1790
1791            let on_delete =
1792                if self.match_token(TokenType::On) && self.match_token(TokenType::Delete) {
1793                    Some(self.parse_referential_action()?)
1794                } else {
1795                    None
1796                };
1797            let on_update =
1798                if self.match_token(TokenType::On) && self.match_token(TokenType::Update) {
1799                    Some(self.parse_referential_action()?)
1800                } else {
1801                    None
1802                };
1803
1804            Ok(TableConstraint::ForeignKey {
1805                name,
1806                columns,
1807                ref_table,
1808                ref_columns,
1809                on_delete,
1810                on_update,
1811            })
1812        } else if self.match_token(TokenType::Check) {
1813            self.expect(TokenType::LParen)?;
1814            let expr = self.parse_expr()?;
1815            self.expect(TokenType::RParen)?;
1816            Ok(TableConstraint::Check { name, expr })
1817        } else {
1818            Err(SqlglotError::ParserError {
1819                message: "Expected constraint type".into(),
1820            })
1821        }
1822    }
1823
1824    fn parse_referential_action(&mut self) -> Result<ReferentialAction> {
1825        if self.match_token(TokenType::Cascade) {
1826            Ok(ReferentialAction::Cascade)
1827        } else if self.match_token(TokenType::Restrict) {
1828            Ok(ReferentialAction::Restrict)
1829        } else if self.match_token(TokenType::Set) {
1830            if self.match_token(TokenType::Null) {
1831                Ok(ReferentialAction::SetNull)
1832            } else if self.match_token(TokenType::Default) {
1833                Ok(ReferentialAction::SetDefault)
1834            } else {
1835                Err(SqlglotError::ParserError {
1836                    message: "Expected NULL or DEFAULT after SET".into(),
1837                })
1838            }
1839        } else if self.check_keyword("NO") {
1840            self.advance();
1841            self.expect(TokenType::Identifier)?; // ACTION
1842            Ok(ReferentialAction::NoAction)
1843        } else {
1844            Err(SqlglotError::ParserError {
1845                message: "Expected referential action (CASCADE, RESTRICT, SET NULL, SET DEFAULT, NO ACTION)".into(),
1846            })
1847        }
1848    }
1849
1850    fn parse_name_list(&mut self) -> Result<Vec<String>> {
1851        let mut names = vec![self.expect_name()?];
1852        while self.match_token(TokenType::Comma) {
1853            names.push(self.expect_name()?);
1854        }
1855        Ok(names)
1856    }
1857
1858    fn parse_column_def(&mut self) -> Result<ColumnDef> {
1859        let name = self.expect_name()?;
1860        let data_type = self.parse_data_type()?;
1861
1862        let mut nullable = None;
1863        let mut default = None;
1864        let mut primary_key = false;
1865        let mut unique = false;
1866        let mut auto_increment = false;
1867        let mut collation = None;
1868        let mut comment = None;
1869
1870        loop {
1871            if self.match_token(TokenType::Not) {
1872                self.expect(TokenType::Null)?;
1873                nullable = Some(false);
1874            } else if self.peek_type() == &TokenType::Null {
1875                self.advance();
1876                nullable = Some(true);
1877            } else if self.match_token(TokenType::Default) {
1878                default = Some(self.parse_expr()?);
1879            } else if self.match_token(TokenType::Primary) {
1880                self.expect(TokenType::Key)?;
1881                primary_key = true;
1882            } else if self.match_token(TokenType::Unique) {
1883                unique = true;
1884            } else if self.match_token(TokenType::AutoIncrement) {
1885                auto_increment = true;
1886            } else if self.match_token(TokenType::Collate) {
1887                collation = Some(self.expect_name()?);
1888            } else if self.match_token(TokenType::Comment) {
1889                let tok = self.expect(TokenType::String)?;
1890                comment = Some(tok.value);
1891            } else if self.match_token(TokenType::References) {
1892                // Inline foreign key — skip for now
1893                let _ = self.parse_table_ref()?;
1894                if self.match_token(TokenType::LParen) {
1895                    while !self.match_token(TokenType::RParen) {
1896                        self.advance();
1897                    }
1898                }
1899            } else {
1900                break;
1901            }
1902        }
1903
1904        Ok(ColumnDef {
1905            name,
1906            data_type,
1907            nullable,
1908            default,
1909            primary_key,
1910            unique,
1911            auto_increment,
1912            collation,
1913            comment,
1914        })
1915    }
1916
1917    fn parse_data_type(&mut self) -> Result<DataType> {
1918        let token = self.peek().clone();
1919        let type_result = match &token.token_type {
1920            TokenType::Int | TokenType::Integer => {
1921                self.advance();
1922                Ok(DataType::Int)
1923            }
1924            TokenType::BigInt => {
1925                self.advance();
1926                Ok(DataType::BigInt)
1927            }
1928            TokenType::SmallInt => {
1929                self.advance();
1930                Ok(DataType::SmallInt)
1931            }
1932            TokenType::TinyInt => {
1933                self.advance();
1934                Ok(DataType::TinyInt)
1935            }
1936            TokenType::Float => {
1937                self.advance();
1938                Ok(DataType::Float)
1939            }
1940            TokenType::Double => {
1941                self.advance();
1942                let _ = self.match_keyword("PRECISION");
1943                Ok(DataType::Double)
1944            }
1945            TokenType::Real => {
1946                self.advance();
1947                Ok(DataType::Real)
1948            }
1949            TokenType::Decimal | TokenType::Numeric => {
1950                let is_numeric = token.token_type == TokenType::Numeric;
1951                self.advance();
1952                let (precision, scale) = self.parse_type_params()?;
1953                if is_numeric {
1954                    Ok(DataType::Numeric { precision, scale })
1955                } else {
1956                    Ok(DataType::Decimal { precision, scale })
1957                }
1958            }
1959            TokenType::Varchar => {
1960                self.advance();
1961                let len = self.parse_single_type_param()?;
1962                Ok(DataType::Varchar(len))
1963            }
1964            TokenType::Char => {
1965                self.advance();
1966                let len = self.parse_single_type_param()?;
1967                Ok(DataType::Char(len))
1968            }
1969            TokenType::Text => {
1970                self.advance();
1971                Ok(DataType::Text)
1972            }
1973            TokenType::Boolean => {
1974                self.advance();
1975                Ok(DataType::Boolean)
1976            }
1977            TokenType::Date => {
1978                self.advance();
1979                Ok(DataType::Date)
1980            }
1981            TokenType::Timestamp => {
1982                self.advance();
1983                let precision = self.parse_single_type_param()?;
1984                let with_tz = if self.match_keyword("WITH") {
1985                    let _ = self.match_keyword("TIME");
1986                    let _ = self.match_keyword("ZONE");
1987                    true
1988                } else if self.match_keyword("WITHOUT") {
1989                    let _ = self.match_keyword("TIME");
1990                    let _ = self.match_keyword("ZONE");
1991                    false
1992                } else {
1993                    false
1994                };
1995                Ok(DataType::Timestamp { precision, with_tz })
1996            }
1997            TokenType::TimestampTz => {
1998                self.advance();
1999                let precision = self.parse_single_type_param()?;
2000                Ok(DataType::Timestamp {
2001                    precision,
2002                    with_tz: true,
2003                })
2004            }
2005            TokenType::Time => {
2006                self.advance();
2007                let precision = self.parse_single_type_param()?;
2008                Ok(DataType::Time { precision })
2009            }
2010            TokenType::Interval => {
2011                self.advance();
2012                Ok(DataType::Interval)
2013            }
2014            TokenType::Blob => {
2015                self.advance();
2016                Ok(DataType::Blob)
2017            }
2018            TokenType::Bytea => {
2019                self.advance();
2020                Ok(DataType::Bytea)
2021            }
2022            TokenType::Json => {
2023                self.advance();
2024                Ok(DataType::Json)
2025            }
2026            TokenType::Jsonb => {
2027                self.advance();
2028                Ok(DataType::Jsonb)
2029            }
2030            TokenType::Uuid => {
2031                self.advance();
2032                Ok(DataType::Uuid)
2033            }
2034            TokenType::Array => {
2035                self.advance();
2036                if self.match_token(TokenType::Lt) {
2037                    let inner = self.parse_data_type()?;
2038                    self.expect(TokenType::Gt)?;
2039                    Ok(DataType::Array(Some(Box::new(inner))))
2040                } else {
2041                    Ok(DataType::Array(None))
2042                }
2043            }
2044            TokenType::Identifier => {
2045                let name = token.value.to_uppercase();
2046                self.advance();
2047                match name.as_str() {
2048                    "STRING" => Ok(DataType::String),
2049                    "BINARY" => {
2050                        let len = self.parse_single_type_param()?;
2051                        Ok(DataType::Binary(len))
2052                    }
2053                    "VARBINARY" => {
2054                        let len = self.parse_single_type_param()?;
2055                        Ok(DataType::Varbinary(len))
2056                    }
2057                    "DATETIME" => Ok(DataType::DateTime),
2058                    "BYTES" => Ok(DataType::Bytes),
2059                    "VARIANT" => Ok(DataType::Variant),
2060                    "OBJECT" => Ok(DataType::Object),
2061                    "XML" => Ok(DataType::Xml),
2062                    "INET" => Ok(DataType::Inet),
2063                    "CIDR" => Ok(DataType::Cidr),
2064                    "MACADDR" => Ok(DataType::Macaddr),
2065                    "BIT" => {
2066                        let len = self.parse_single_type_param()?;
2067                        Ok(DataType::Bit(len))
2068                    }
2069                    "MONEY" => Ok(DataType::Money),
2070                    "SERIAL" => Ok(DataType::Serial),
2071                    "BIGSERIAL" => Ok(DataType::BigSerial),
2072                    "SMALLSERIAL" => Ok(DataType::SmallSerial),
2073                    "REGCLASS" => Ok(DataType::Regclass),
2074                    "REGTYPE" => Ok(DataType::Regtype),
2075                    "HSTORE" => Ok(DataType::Hstore),
2076                    "GEOGRAPHY" => Ok(DataType::Geography),
2077                    "GEOMETRY" => Ok(DataType::Geometry),
2078                    "SUPER" => Ok(DataType::Super),
2079                    _ => Ok(DataType::Unknown(name)),
2080                }
2081            }
2082            _ => Err(SqlglotError::ParserError {
2083                message: format!("Expected data type, got {:?}", token.token_type),
2084            }),
2085        };
2086
2087        // PostgreSQL opt_array_bounds: typename[], typename[N], typename[][]...
2088        let mut dt = type_result?;
2089        while self.match_token(TokenType::LBracket) {
2090            // Consume optional integer bound (PostgreSQL ignores it but accepts it)
2091            let _ = self.match_token(TokenType::Number);
2092            self.expect(TokenType::RBracket)?;
2093            dt = DataType::Array(Some(Box::new(dt)));
2094        }
2095        Ok(dt)
2096    }
2097
2098    fn parse_type_params(&mut self) -> Result<(Option<u32>, Option<u32>)> {
2099        if self.match_token(TokenType::LParen) {
2100            let p: Option<u32> = self.expect(TokenType::Number)?.value.parse().ok();
2101            let s = if self.match_token(TokenType::Comma) {
2102                self.expect(TokenType::Number)?.value.parse().ok()
2103            } else {
2104                None
2105            };
2106            self.expect(TokenType::RParen)?;
2107            Ok((p, s))
2108        } else {
2109            Ok((None, None))
2110        }
2111    }
2112
2113    fn parse_single_type_param(&mut self) -> Result<Option<u32>> {
2114        if self.match_token(TokenType::LParen) {
2115            // Handle TSQL MAX keyword (e.g. VARBINARY(MAX), VARCHAR(MAX))
2116            if self.check_keyword("MAX") {
2117                self.advance(); // consume MAX
2118                self.expect(TokenType::RParen)?;
2119                return Ok(None);
2120            }
2121            let n: Option<u32> = self.expect(TokenType::Number)?.value.parse().ok();
2122            self.expect(TokenType::RParen)?;
2123            Ok(n)
2124        } else {
2125            Ok(None)
2126        }
2127    }
2128
2129    // ── DROP ────────────────────────────────────────────────────────
2130
2131    fn parse_drop(&mut self) -> Result<Statement> {
2132        self.expect(TokenType::Drop)?;
2133
2134        if self.match_token(TokenType::Materialized) {
2135            self.expect(TokenType::View)?;
2136            let if_exists = if self.match_token(TokenType::If) {
2137                self.expect(TokenType::Exists)?;
2138                true
2139            } else {
2140                false
2141            };
2142            let name = self.parse_table_ref()?;
2143            return Ok(Statement::DropView(DropViewStatement {
2144                comments: vec![],
2145                name,
2146                if_exists,
2147                materialized: true,
2148            }));
2149        }
2150
2151        if self.match_token(TokenType::View) {
2152            let if_exists = if self.match_token(TokenType::If) {
2153                self.expect(TokenType::Exists)?;
2154                true
2155            } else {
2156                false
2157            };
2158            let name = self.parse_table_ref()?;
2159            return Ok(Statement::DropView(DropViewStatement {
2160                comments: vec![],
2161                name,
2162                if_exists,
2163                materialized: false,
2164            }));
2165        }
2166
2167        self.expect(TokenType::Table)?;
2168
2169        let if_exists = if self.match_token(TokenType::If) {
2170            self.expect(TokenType::Exists)?;
2171            true
2172        } else {
2173            false
2174        };
2175
2176        let table = self.parse_table_ref()?;
2177        let cascade = self.match_token(TokenType::Cascade);
2178
2179        Ok(Statement::DropTable(DropTableStatement {
2180            comments: vec![],
2181            if_exists,
2182            table,
2183            cascade,
2184        }))
2185    }
2186
2187    // ── ALTER TABLE ─────────────────────────────────────────────────
2188
2189    fn parse_alter_table(&mut self) -> Result<AlterTableStatement> {
2190        self.expect(TokenType::Alter)?;
2191        self.expect(TokenType::Table)?;
2192        let table = self.parse_table_ref_no_alias()?;
2193
2194        let mut actions = Vec::new();
2195        loop {
2196            let action = self.parse_alter_action()?;
2197            actions.push(action);
2198            if !self.match_token(TokenType::Comma) {
2199                break;
2200            }
2201        }
2202
2203        Ok(AlterTableStatement {
2204            comments: vec![],
2205            table,
2206            actions,
2207        })
2208    }
2209
2210    fn parse_alter_action(&mut self) -> Result<AlterTableAction> {
2211        if self.match_keyword("ADD") {
2212            if matches!(
2213                self.peek_type(),
2214                TokenType::Constraint
2215                    | TokenType::Primary
2216                    | TokenType::Unique
2217                    | TokenType::Foreign
2218                    | TokenType::Check
2219            ) {
2220                let constraint = self.parse_table_constraint()?;
2221                Ok(AlterTableAction::AddConstraint(constraint))
2222            } else {
2223                let _ = self.match_keyword("COLUMN");
2224                let col = self.parse_column_def()?;
2225                Ok(AlterTableAction::AddColumn(col))
2226            }
2227        } else if self.match_token(TokenType::Drop) {
2228            let _ = self.match_keyword("COLUMN");
2229            let if_exists = if self.match_token(TokenType::If) {
2230                self.expect(TokenType::Exists)?;
2231                true
2232            } else {
2233                false
2234            };
2235            let name = self.expect_name()?;
2236            Ok(AlterTableAction::DropColumn { name, if_exists })
2237        } else if self.match_keyword("RENAME") {
2238            if self.match_keyword("COLUMN") {
2239                let old_name = self.expect_name()?;
2240                self.expect(TokenType::Identifier)?; // TO
2241                let new_name = self.expect_name()?;
2242                Ok(AlterTableAction::RenameColumn { old_name, new_name })
2243            } else if self.match_keyword("TO") {
2244                let new_name = self.expect_name()?;
2245                Ok(AlterTableAction::RenameTable { new_name })
2246            } else {
2247                Err(SqlglotError::ParserError {
2248                    message: "Expected COLUMN or TO after RENAME".into(),
2249                })
2250            }
2251        } else {
2252            Err(SqlglotError::ParserError {
2253                message: "Expected ADD, DROP, or RENAME in ALTER TABLE".into(),
2254            })
2255        }
2256    }
2257
2258    /// Try [`parse_alter_table`]; on failure, rewind and capture the entire
2259    /// `ALTER …` statement verbatim as a [`Statement::Command`]. This covers
2260    /// the long tail of vendor-specific ALTER forms — MySQL `ALTER TABLE …
2261    /// CONVERT TO CHARACTER SET … COLLATE …`, Hive `ALTER TABLE … PARTITION
2262    /// (…) COMPACT 'major'`, T-SQL `ALTER TABLE … WITH (…) CHECK CONSTRAINT
2263    /// …`, etc. (Gap 5)
2264    fn parse_alter_or_command(&mut self) -> Result<Statement> {
2265        let saved = self.pos;
2266        let saved_comments = self.pending_comments.clone();
2267        match self.parse_alter_table() {
2268            Ok(stmt) => Ok(Statement::AlterTable(stmt)),
2269            Err(_) => {
2270                self.pos = saved;
2271                self.pending_comments = saved_comments;
2272                self.parse_command_kind("ALTER")
2273            }
2274        }
2275    }
2276
2277    /// Try [`parse_create`]; on failure, rewind and capture the entire
2278    /// `CREATE …` statement verbatim as a [`Statement::Command`]. Also
2279    /// handles the `CREATE TABLE t AS VALUES (…)` form (Gap 7) and rarer
2280    /// `CREATE OPERATOR / AGGREGATE / SEQUENCE / FUNCTION / TEXT SEARCH
2281    /// CONFIGURATION / …` (Gap 4).
2282    fn parse_create_or_command(&mut self) -> Result<Statement> {
2283        let saved = self.pos;
2284        let saved_comments = self.pending_comments.clone();
2285        match self.parse_create() {
2286            Ok(stmt) => Ok(stmt),
2287            Err(_) => {
2288                self.pos = saved;
2289                self.pending_comments = saved_comments;
2290                self.parse_command_kind("CREATE")
2291            }
2292        }
2293    }
2294
2295    // ── TRUNCATE ────────────────────────────────────────────────────
2296
2297    fn parse_truncate(&mut self) -> Result<TruncateStatement> {
2298        self.expect(TokenType::Truncate)?;
2299        let _ = self.match_token(TokenType::Table);
2300        let table = self.parse_table_ref()?;
2301        Ok(TruncateStatement {
2302            comments: vec![],
2303            table,
2304        })
2305    }
2306
2307    // ── Transaction ─────────────────────────────────────────────────
2308
2309    fn parse_transaction(&mut self) -> Result<TransactionStatement> {
2310        match self.peek_type() {
2311            TokenType::Begin => {
2312                self.advance();
2313                let _ = self.match_token(TokenType::Transaction);
2314                Ok(TransactionStatement::Begin)
2315            }
2316            TokenType::Commit => {
2317                self.advance();
2318                let _ = self.match_token(TokenType::Transaction);
2319                Ok(TransactionStatement::Commit)
2320            }
2321            TokenType::Rollback => {
2322                self.advance();
2323                let _ = self.match_token(TokenType::Transaction);
2324                if self.match_keyword("TO") {
2325                    let _ = self.match_token(TokenType::Savepoint);
2326                    let name = self.expect_name()?;
2327                    Ok(TransactionStatement::RollbackTo(name))
2328                } else {
2329                    Ok(TransactionStatement::Rollback)
2330                }
2331            }
2332            TokenType::Savepoint => {
2333                self.advance();
2334                let name = self.expect_name()?;
2335                Ok(TransactionStatement::Savepoint(name))
2336            }
2337            _ => Err(SqlglotError::ParserError {
2338                message: "Expected transaction statement".into(),
2339            }),
2340        }
2341    }
2342
2343    // ── EXPLAIN ─────────────────────────────────────────────────────
2344
2345    fn parse_explain(&mut self) -> Result<ExplainStatement> {
2346        self.expect(TokenType::Explain)?;
2347        let analyze = self.match_token(TokenType::Analyze);
2348        let statement = self.parse_statement_inner()?;
2349        Ok(ExplainStatement {
2350            comments: vec![],
2351            analyze,
2352            statement: Box::new(statement),
2353        })
2354    }
2355
2356    // ── USE ─────────────────────────────────────────────────────────
2357
2358    fn parse_use(&mut self) -> Result<UseStatement> {
2359        self.expect(TokenType::Use)?;
2360        let name = self.expect_name()?;
2361        Ok(UseStatement {
2362            comments: vec![],
2363            name,
2364        })
2365    }
2366
2367    // ══════════════════════════════════════════════════════════════
2368    // Expression parsing (precedence climbing)
2369    // ══════════════════════════════════════════════════════════════
2370
2371    fn parse_expr(&mut self) -> Result<Expr> {
2372        self.parse_or_expr()
2373    }
2374
2375    fn parse_or_expr(&mut self) -> Result<Expr> {
2376        let mut left = self.parse_and_expr()?;
2377        while self.match_token(TokenType::Or) {
2378            let right = self.parse_and_expr()?;
2379            left = Expr::BinaryOp {
2380                left: Box::new(left),
2381                op: BinaryOperator::Or,
2382                right: Box::new(right),
2383            };
2384        }
2385        Ok(left)
2386    }
2387
2388    fn parse_and_expr(&mut self) -> Result<Expr> {
2389        let mut left = self.parse_not_expr()?;
2390        while self.match_token(TokenType::And) {
2391            let right = self.parse_not_expr()?;
2392            left = Expr::BinaryOp {
2393                left: Box::new(left),
2394                op: BinaryOperator::And,
2395                right: Box::new(right),
2396            };
2397        }
2398        Ok(left)
2399    }
2400
2401    fn parse_not_expr(&mut self) -> Result<Expr> {
2402        if self.match_token(TokenType::Not) {
2403            let expr = self.parse_not_expr()?;
2404            Ok(Expr::UnaryOp {
2405                op: UnaryOperator::Not,
2406                expr: Box::new(expr),
2407            })
2408        } else {
2409            self.parse_comparison()
2410        }
2411    }
2412
2413    fn parse_comparison(&mut self) -> Result<Expr> {
2414        let mut left = self.parse_addition()?;
2415
2416        loop {
2417            let op = match self.peek_type() {
2418                TokenType::Eq => Some(BinaryOperator::Eq),
2419                TokenType::Neq => Some(BinaryOperator::Neq),
2420                TokenType::Lt => Some(BinaryOperator::Lt),
2421                TokenType::Gt => Some(BinaryOperator::Gt),
2422                TokenType::LtEq => Some(BinaryOperator::LtEq),
2423                TokenType::GtEq => Some(BinaryOperator::GtEq),
2424                TokenType::AtArrow => Some(BinaryOperator::AtArrow),
2425                TokenType::ArrowAt => Some(BinaryOperator::ArrowAt),
2426                _ => None,
2427            };
2428
2429            if let Some(op) = op {
2430                self.advance();
2431                if matches!(self.peek_type(), TokenType::Any | TokenType::Some) {
2432                    self.advance();
2433                    self.expect(TokenType::LParen)?;
2434                    let right = if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
2435                        Expr::Subquery(Box::new(self.parse_statement_inner()?))
2436                    } else {
2437                        self.parse_expr()?
2438                    };
2439                    self.expect(TokenType::RParen)?;
2440                    left = Expr::AnyOp {
2441                        expr: Box::new(left),
2442                        op,
2443                        right: Box::new(right),
2444                    };
2445                } else if self.peek_type() == &TokenType::All {
2446                    self.advance();
2447                    self.expect(TokenType::LParen)?;
2448                    let right = if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
2449                        Expr::Subquery(Box::new(self.parse_statement_inner()?))
2450                    } else {
2451                        self.parse_expr()?
2452                    };
2453                    self.expect(TokenType::RParen)?;
2454                    left = Expr::AllOp {
2455                        expr: Box::new(left),
2456                        op,
2457                        right: Box::new(right),
2458                    };
2459                } else {
2460                    let right = self.parse_addition()?;
2461                    left = Expr::BinaryOp {
2462                        left: Box::new(left),
2463                        op,
2464                        right: Box::new(right),
2465                    };
2466                }
2467            } else if self.peek_type() == &TokenType::Is {
2468                self.advance();
2469                let negated = self.match_token(TokenType::Not);
2470                if self.match_token(TokenType::True) {
2471                    left = Expr::IsBool {
2472                        expr: Box::new(left),
2473                        value: true,
2474                        negated,
2475                    };
2476                } else if self.match_token(TokenType::False) {
2477                    left = Expr::IsBool {
2478                        expr: Box::new(left),
2479                        value: false,
2480                        negated,
2481                    };
2482                } else {
2483                    self.expect(TokenType::Null)?;
2484                    left = Expr::IsNull {
2485                        expr: Box::new(left),
2486                        negated,
2487                    };
2488                }
2489            } else if matches!(
2490                self.peek_type(),
2491                TokenType::Not
2492                    | TokenType::In
2493                    | TokenType::Like
2494                    | TokenType::ILike
2495                    | TokenType::Between
2496            ) {
2497                // Peek ahead: if NOT, only consume it if followed by IN/LIKE/ILIKE/BETWEEN
2498                if self.peek_type() == &TokenType::Not {
2499                    let saved_pos = self.pos;
2500                    self.advance(); // consume NOT
2501                    if !matches!(
2502                        self.peek_type(),
2503                        TokenType::In | TokenType::Like | TokenType::ILike | TokenType::Between
2504                    ) {
2505                        // NOT is not part of a comparison predicate — restore position
2506                        self.pos = saved_pos;
2507                        break;
2508                    }
2509                    // NOT was consumed, negated = true
2510                }
2511                let negated =
2512                    self.pos > 0 && self.tokens[self.pos - 1].token_type == TokenType::Not;
2513
2514                if self.match_token(TokenType::In) {
2515                    self.expect(TokenType::LParen)?;
2516                    // Check for subquery
2517                    if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
2518                        let subquery = self.parse_statement_inner()?;
2519                        self.expect(TokenType::RParen)?;
2520                        left = Expr::InSubquery {
2521                            expr: Box::new(left),
2522                            subquery: Box::new(subquery),
2523                            negated,
2524                        };
2525                    } else {
2526                        let list = self.parse_expr_list()?;
2527                        self.expect(TokenType::RParen)?;
2528                        left = Expr::InList {
2529                            expr: Box::new(left),
2530                            list,
2531                            negated,
2532                        };
2533                    }
2534                } else if self.match_token(TokenType::Like) {
2535                    let pattern = self.parse_addition()?;
2536                    let escape = if self.match_token(TokenType::Escape) {
2537                        Some(Box::new(self.parse_primary()?))
2538                    } else {
2539                        None
2540                    };
2541                    left = Expr::Like {
2542                        expr: Box::new(left),
2543                        pattern: Box::new(pattern),
2544                        negated,
2545                        escape,
2546                    };
2547                } else if self.match_token(TokenType::ILike) {
2548                    let pattern = self.parse_addition()?;
2549                    let escape = if self.match_token(TokenType::Escape) {
2550                        Some(Box::new(self.parse_primary()?))
2551                    } else {
2552                        None
2553                    };
2554                    left = Expr::ILike {
2555                        expr: Box::new(left),
2556                        pattern: Box::new(pattern),
2557                        negated,
2558                        escape,
2559                    };
2560                } else if self.match_token(TokenType::Between) {
2561                    let low = self.parse_addition()?;
2562                    self.expect(TokenType::And)?;
2563                    let high = self.parse_addition()?;
2564                    left = Expr::Between {
2565                        expr: Box::new(left),
2566                        low: Box::new(low),
2567                        high: Box::new(high),
2568                        negated,
2569                    };
2570                } else {
2571                    break;
2572                }
2573            } else if self.check_keyword("SIMILAR") {
2574                // SIMILAR TO pattern [ESCAPE escape_char]
2575                self.advance(); // consume SIMILAR
2576                self.expect_keyword("TO")?;
2577                let pattern = self.parse_addition()?;
2578                let escape = if self.match_token(TokenType::Escape) {
2579                    Some(Box::new(self.parse_primary()?))
2580                } else {
2581                    None
2582                };
2583                left = Expr::SimilarTo {
2584                    expr: Box::new(left),
2585                    pattern: Box::new(pattern),
2586                    negated: false,
2587                    escape,
2588                };
2589            } else if self.peek_type() == &TokenType::Not && self.check_keyword_offset("SIMILAR", 1)
2590            {
2591                // NOT SIMILAR TO pattern [ESCAPE escape_char]
2592                self.advance(); // consume NOT
2593                self.advance(); // consume SIMILAR
2594                self.expect_keyword("TO")?;
2595                let pattern = self.parse_addition()?;
2596                let escape = if self.match_token(TokenType::Escape) {
2597                    Some(Box::new(self.parse_primary()?))
2598                } else {
2599                    None
2600                };
2601                left = Expr::SimilarTo {
2602                    expr: Box::new(left),
2603                    pattern: Box::new(pattern),
2604                    negated: true,
2605                    escape,
2606                };
2607            } else {
2608                break;
2609            }
2610        }
2611
2612        Ok(left)
2613    }
2614
2615    fn parse_addition(&mut self) -> Result<Expr> {
2616        let mut left = self.parse_multiplication()?;
2617        loop {
2618            let op = match self.peek_type() {
2619                TokenType::Plus => Some(BinaryOperator::Plus),
2620                TokenType::Minus => Some(BinaryOperator::Minus),
2621                TokenType::Concat => Some(BinaryOperator::Concat),
2622                TokenType::BitwiseOr => Some(BinaryOperator::BitwiseOr),
2623                TokenType::BitwiseXor => Some(BinaryOperator::BitwiseXor),
2624                TokenType::ShiftLeft => Some(BinaryOperator::ShiftLeft),
2625                TokenType::ShiftRight => Some(BinaryOperator::ShiftRight),
2626                _ => None,
2627            };
2628            if let Some(op) = op {
2629                self.advance();
2630                let right = self.parse_multiplication()?;
2631                left = Expr::BinaryOp {
2632                    left: Box::new(left),
2633                    op,
2634                    right: Box::new(right),
2635                };
2636            } else {
2637                break;
2638            }
2639        }
2640        Ok(left)
2641    }
2642
2643    fn parse_multiplication(&mut self) -> Result<Expr> {
2644        let mut left = self.parse_unary()?;
2645        loop {
2646            let op = match self.peek_type() {
2647                TokenType::Star => Some(BinaryOperator::Multiply),
2648                TokenType::Slash => Some(BinaryOperator::Divide),
2649                TokenType::Percent2 => Some(BinaryOperator::Modulo),
2650                TokenType::BitwiseAnd => Some(BinaryOperator::BitwiseAnd),
2651                _ => None,
2652            };
2653            if let Some(op) = op {
2654                self.advance();
2655                let right = self.parse_unary()?;
2656                left = Expr::BinaryOp {
2657                    left: Box::new(left),
2658                    op,
2659                    right: Box::new(right),
2660                };
2661            } else {
2662                break;
2663            }
2664        }
2665        Ok(left)
2666    }
2667
2668    fn parse_unary(&mut self) -> Result<Expr> {
2669        match self.peek_type() {
2670            TokenType::Minus => {
2671                self.advance();
2672                let expr = self.parse_postfix()?;
2673                Ok(Expr::UnaryOp {
2674                    op: UnaryOperator::Minus,
2675                    expr: Box::new(expr),
2676                })
2677            }
2678            TokenType::Plus => {
2679                self.advance();
2680                let expr = self.parse_postfix()?;
2681                Ok(Expr::UnaryOp {
2682                    op: UnaryOperator::Plus,
2683                    expr: Box::new(expr),
2684                })
2685            }
2686            TokenType::BitwiseNot => {
2687                self.advance();
2688                let expr = self.parse_postfix()?;
2689                Ok(Expr::UnaryOp {
2690                    op: UnaryOperator::BitwiseNot,
2691                    expr: Box::new(expr),
2692                })
2693            }
2694            _ => self.parse_postfix(),
2695        }
2696    }
2697
2698    /// Parse postfix operators: `::type`, `[index]`, `->`, `->>`
2699    fn parse_postfix(&mut self) -> Result<Expr> {
2700        let mut expr = self.parse_primary()?;
2701
2702        loop {
2703            if self.match_token(TokenType::DoubleColon) {
2704                // PostgreSQL-style cast: expr::type
2705                let data_type = self.parse_data_type()?;
2706                expr = Expr::Cast {
2707                    expr: Box::new(expr),
2708                    data_type,
2709                };
2710            } else if self.match_token(TokenType::LBracket) {
2711                // Array index: expr[index]
2712                let index = self.parse_expr()?;
2713                self.expect(TokenType::RBracket)?;
2714                expr = Expr::ArrayIndex {
2715                    expr: Box::new(expr),
2716                    index: Box::new(index),
2717                };
2718            } else if self.match_token(TokenType::Arrow) {
2719                let path = self.parse_primary()?;
2720                expr = Expr::JsonAccess {
2721                    expr: Box::new(expr),
2722                    path: Box::new(path),
2723                    as_text: false,
2724                };
2725            } else if self.match_token(TokenType::DoubleArrow) {
2726                let path = self.parse_primary()?;
2727                expr = Expr::JsonAccess {
2728                    expr: Box::new(expr),
2729                    path: Box::new(path),
2730                    as_text: true,
2731                };
2732            } else {
2733                break;
2734            }
2735        }
2736
2737        // Check for window function: expr OVER (...)
2738        if self.match_token(TokenType::Over) {
2739            let spec = if self.match_token(TokenType::LParen) {
2740                let ws = self.parse_window_spec()?;
2741                self.expect(TokenType::RParen)?;
2742                ws
2743            } else {
2744                // Named window reference
2745                let wref = self.expect_name()?;
2746                WindowSpec {
2747                    window_ref: Some(wref),
2748                    partition_by: vec![],
2749                    order_by: vec![],
2750                    frame: None,
2751                }
2752            };
2753            match expr {
2754                Expr::Function {
2755                    name,
2756                    args,
2757                    distinct,
2758                    filter,
2759                    order_by,
2760                    within_group,
2761                    ..
2762                } => {
2763                    expr = Expr::Function {
2764                        name,
2765                        args,
2766                        distinct,
2767                        filter,
2768                        over: Some(spec),
2769                        order_by,
2770                        within_group,
2771                    };
2772                }
2773                Expr::TypedFunction { func, filter, .. } => {
2774                    expr = Expr::TypedFunction {
2775                        func,
2776                        filter,
2777                        over: Some(spec),
2778                    };
2779                }
2780                _ => {}
2781            }
2782        }
2783
2784        // FILTER (WHERE ...) for aggregate functions
2785        if self.match_token(TokenType::Filter) {
2786            self.expect(TokenType::LParen)?;
2787            self.expect(TokenType::Where)?;
2788            let filter_expr = self.parse_expr()?;
2789            self.expect(TokenType::RParen)?;
2790            match expr {
2791                Expr::Function {
2792                    name,
2793                    args,
2794                    distinct,
2795                    over,
2796                    order_by,
2797                    within_group,
2798                    ..
2799                } => {
2800                    expr = Expr::Function {
2801                        name,
2802                        args,
2803                        distinct,
2804                        filter: Some(Box::new(filter_expr)),
2805                        over,
2806                        order_by,
2807                        within_group,
2808                    };
2809                }
2810                Expr::TypedFunction { func, over, .. } => {
2811                    expr = Expr::TypedFunction {
2812                        func,
2813                        filter: Some(Box::new(filter_expr)),
2814                        over,
2815                    };
2816                }
2817                _ => {}
2818            }
2819        }
2820
2821        Ok(expr)
2822    }
2823
2824    fn parse_window_spec(&mut self) -> Result<WindowSpec> {
2825        let window_ref = if self.is_name_token()
2826            && !matches!(
2827                self.peek_type(),
2828                TokenType::Partition | TokenType::Order | TokenType::Rows | TokenType::Range
2829            ) {
2830            let saved = self.pos;
2831            let name = self.expect_name()?;
2832            // Check if it's actually a keyword we need
2833            if matches!(
2834                self.peek_type(),
2835                TokenType::RParen
2836                    | TokenType::Partition
2837                    | TokenType::Order
2838                    | TokenType::Rows
2839                    | TokenType::Range
2840            ) {
2841                Some(name)
2842            } else {
2843                self.pos = saved;
2844                None
2845            }
2846        } else {
2847            None
2848        };
2849
2850        let partition_by = if self.match_token(TokenType::Partition) {
2851            self.expect(TokenType::By)?;
2852            self.parse_expr_list()?
2853        } else {
2854            vec![]
2855        };
2856
2857        let order_by = if self.match_token(TokenType::Order) {
2858            self.expect(TokenType::By)?;
2859            self.parse_order_by_items()?
2860        } else {
2861            vec![]
2862        };
2863
2864        let frame = if matches!(self.peek_type(), TokenType::Rows | TokenType::Range) {
2865            Some(self.parse_window_frame()?)
2866        } else {
2867            None
2868        };
2869
2870        Ok(WindowSpec {
2871            window_ref,
2872            partition_by,
2873            order_by,
2874            frame,
2875        })
2876    }
2877
2878    fn parse_window_frame(&mut self) -> Result<WindowFrame> {
2879        let kind = if self.match_token(TokenType::Rows) {
2880            WindowFrameKind::Rows
2881        } else if self.match_token(TokenType::Range) {
2882            WindowFrameKind::Range
2883        } else {
2884            WindowFrameKind::Rows
2885        };
2886
2887        if self.match_keyword("BETWEEN") {
2888            let start = self.parse_window_frame_bound()?;
2889            self.expect(TokenType::And)?;
2890            let end = self.parse_window_frame_bound()?;
2891            Ok(WindowFrame {
2892                kind,
2893                start,
2894                end: Some(end),
2895            })
2896        } else {
2897            let start = self.parse_window_frame_bound()?;
2898            Ok(WindowFrame {
2899                kind,
2900                start,
2901                end: None,
2902            })
2903        }
2904    }
2905
2906    fn parse_window_frame_bound(&mut self) -> Result<WindowFrameBound> {
2907        if self.check_keyword("CURRENT") {
2908            self.advance();
2909            let _ = self.match_keyword("ROW");
2910            Ok(WindowFrameBound::CurrentRow)
2911        } else if self.match_token(TokenType::Unbounded) {
2912            if self.match_token(TokenType::Preceding) {
2913                Ok(WindowFrameBound::Preceding(None))
2914            } else {
2915                self.expect(TokenType::Following)?;
2916                Ok(WindowFrameBound::Following(None))
2917            }
2918        } else {
2919            let n = self.parse_expr()?;
2920            if self.match_token(TokenType::Preceding) {
2921                Ok(WindowFrameBound::Preceding(Some(Box::new(n))))
2922            } else {
2923                self.expect(TokenType::Following)?;
2924                Ok(WindowFrameBound::Following(Some(Box::new(n))))
2925            }
2926        }
2927    }
2928
2929    fn parse_primary(&mut self) -> Result<Expr> {
2930        let token = self.peek().clone();
2931
2932        match &token.token_type {
2933            TokenType::Number => {
2934                self.advance();
2935                Ok(Expr::Number(token.value))
2936            }
2937            TokenType::String => {
2938                self.advance();
2939                Ok(Expr::StringLiteral(token.value))
2940            }
2941            TokenType::NationalString => {
2942                self.advance();
2943                Ok(Expr::NationalStringLiteral(token.value))
2944            }
2945            TokenType::True => {
2946                self.advance();
2947                Ok(Expr::Boolean(true))
2948            }
2949            TokenType::False => {
2950                self.advance();
2951                Ok(Expr::Boolean(false))
2952            }
2953            TokenType::Null => {
2954                self.advance();
2955                Ok(Expr::Null)
2956            }
2957            TokenType::Default => {
2958                self.advance();
2959                Ok(Expr::Default)
2960            }
2961            TokenType::Star => {
2962                self.advance();
2963                Ok(Expr::Wildcard)
2964            }
2965            TokenType::Parameter => {
2966                self.advance();
2967                Ok(Expr::Parameter(token.value))
2968            }
2969
2970            // ── CAST ────────────────────────────────────────────────
2971            TokenType::Cast => {
2972                self.advance();
2973                self.expect(TokenType::LParen)?;
2974                let expr = self.parse_expr()?;
2975                self.expect(TokenType::As)?;
2976                let data_type = self.parse_data_type()?;
2977                self.expect(TokenType::RParen)?;
2978                Ok(Expr::Cast {
2979                    expr: Box::new(expr),
2980                    data_type,
2981                })
2982            }
2983
2984            // ── EXTRACT ─────────────────────────────────────────────
2985            TokenType::Extract => {
2986                self.advance();
2987                self.expect(TokenType::LParen)?;
2988                let field = self.parse_datetime_field()?;
2989                self.expect(TokenType::From)?;
2990                let expr = self.parse_expr()?;
2991                self.expect(TokenType::RParen)?;
2992                Ok(Expr::Extract {
2993                    field,
2994                    expr: Box::new(expr),
2995                })
2996            }
2997
2998            // ── CASE ────────────────────────────────────────────────
2999            TokenType::Case => self.parse_case_expr(),
3000
3001            // ── EXISTS ──────────────────────────────────────────────
3002            TokenType::Exists => {
3003                self.advance();
3004                self.expect(TokenType::LParen)?;
3005                let subquery = self.parse_statement_inner()?;
3006                self.expect(TokenType::RParen)?;
3007                Ok(Expr::Exists {
3008                    subquery: Box::new(subquery),
3009                    negated: false,
3010                })
3011            }
3012
3013            // ── NOT EXISTS ──────────────────────────────────────────
3014            TokenType::Not
3015                if {
3016                    let next_pos = self.pos + 1;
3017                    next_pos < self.tokens.len()
3018                        && self.tokens[next_pos].token_type == TokenType::Exists
3019                } =>
3020            {
3021                self.advance(); // NOT
3022                self.advance(); // EXISTS
3023                self.expect(TokenType::LParen)?;
3024                let subquery = self.parse_statement_inner()?;
3025                self.expect(TokenType::RParen)?;
3026                Ok(Expr::Exists {
3027                    subquery: Box::new(subquery),
3028                    negated: true,
3029                })
3030            }
3031
3032            // ── INTERVAL ────────────────────────────────────────────
3033            TokenType::Interval => {
3034                self.advance();
3035                let value = self.parse_primary()?;
3036                let unit = self.try_parse_datetime_field();
3037                Ok(Expr::Interval {
3038                    value: Box::new(value),
3039                    unit,
3040                })
3041            }
3042
3043            // ── Parenthesized expression or subquery ────────────────
3044            TokenType::LParen => {
3045                self.advance();
3046                // Check for subquery
3047                if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
3048                    let subquery = self.parse_statement_inner()?;
3049                    self.expect(TokenType::RParen)?;
3050                    Ok(Expr::Subquery(Box::new(subquery)))
3051                } else {
3052                    let expr = self.parse_expr()?;
3053                    // Tuple: (a, b, c)
3054                    if self.match_token(TokenType::Comma) {
3055                        let mut items = vec![expr];
3056                        items.push(self.parse_expr()?);
3057                        while self.match_token(TokenType::Comma) {
3058                            items.push(self.parse_expr()?);
3059                        }
3060                        self.expect(TokenType::RParen)?;
3061                        Ok(Expr::Tuple(items))
3062                    } else {
3063                        self.expect(TokenType::RParen)?;
3064                        Ok(Expr::Nested(Box::new(expr)))
3065                    }
3066                }
3067            }
3068
3069            // ── Array literal: ARRAY[...] ──────────────────────────
3070            TokenType::Array => {
3071                self.advance();
3072                if self.match_token(TokenType::LBracket) {
3073                    let items = if self.peek_type() != &TokenType::RBracket {
3074                        self.parse_expr_list()?
3075                    } else {
3076                        vec![]
3077                    };
3078                    self.expect(TokenType::RBracket)?;
3079                    Ok(Expr::ArrayLiteral(items))
3080                } else if self.match_token(TokenType::LParen) {
3081                    // ARRAY(SELECT ...)
3082                    let subquery = self.parse_statement_inner()?;
3083                    self.expect(TokenType::RParen)?;
3084                    Ok(Expr::Subquery(Box::new(subquery)))
3085                } else {
3086                    Ok(Expr::Column {
3087                        table: None,
3088                        name: "ARRAY".to_string(),
3089                        quote_style: QuoteStyle::None,
3090                        table_quote_style: QuoteStyle::None,
3091                    })
3092                }
3093            }
3094
3095            // ── Bracket array literal: [...] ────────────────────────
3096            TokenType::LBracket => {
3097                self.advance();
3098                let items = if self.peek_type() != &TokenType::RBracket {
3099                    self.parse_expr_list()?
3100                } else {
3101                    vec![]
3102                };
3103                self.expect(TokenType::RBracket)?;
3104                Ok(Expr::ArrayLiteral(items))
3105            }
3106
3107            // ── Identifier: column ref, function call, or qualified name ─
3108            _ if self.is_name_token() || self.is_data_type_token() => {
3109                let name_token = self.advance().clone();
3110                let name = name_token.value.clone();
3111                let name_qs = quote_style_from_char(name_token.quote_char);
3112
3113                // ── ANSI typed string literals: DATE 'x', TIMESTAMP 'x', TIME 'x' ──
3114                if matches!(
3115                    name_token.token_type,
3116                    TokenType::Date
3117                        | TokenType::Timestamp
3118                        | TokenType::TimestampTz
3119                        | TokenType::Time
3120                ) && self.peek_type() == &TokenType::String
3121                {
3122                    let value_token = self.advance().clone();
3123                    let data_type = match name_token.token_type {
3124                        TokenType::Date => DataType::Date,
3125                        TokenType::Timestamp => DataType::Timestamp {
3126                            precision: None,
3127                            with_tz: false,
3128                        },
3129                        TokenType::TimestampTz => DataType::Timestamp {
3130                            precision: None,
3131                            with_tz: true,
3132                        },
3133                        TokenType::Time => DataType::Time { precision: None },
3134                        _ => unreachable!(),
3135                    };
3136                    return Ok(Expr::Cast {
3137                        expr: Box::new(Expr::StringLiteral(value_token.value)),
3138                        data_type,
3139                    });
3140                }
3141
3142                // ── Bare niladic temporal keywords: CURRENT_TIME, CURRENT_DATE,
3143                //    CURRENT_TIMESTAMP, LOCALTIMESTAMP (no parens) ──
3144                // ANSI SQL allows these without parentheses. Materialize them
3145                // as typed functions so the generator can emit dialect-specific
3146                // forms (e.g. TSQL requires CAST(GETDATE() AS TIME) rather than
3147                // a bare CURRENT_TIME reserved word).
3148                if name_qs == QuoteStyle::None && self.peek_type() != &TokenType::LParen {
3149                    let upper = name.to_ascii_uppercase();
3150                    let typed = match upper.as_str() {
3151                        "CURRENT_DATE" => Some(TypedFunction::CurrentDate),
3152                        "CURRENT_TIME" => Some(TypedFunction::CurrentTime),
3153                        "CURRENT_TIMESTAMP" | "LOCALTIMESTAMP" => {
3154                            Some(TypedFunction::CurrentTimestamp)
3155                        }
3156                        _ => None,
3157                    };
3158                    if let Some(tf) = typed {
3159                        return Ok(Expr::TypedFunction {
3160                            func: tf,
3161                            filter: None,
3162                            over: None,
3163                        });
3164                    }
3165                }
3166
3167                // Function call: name(...)
3168                if self.peek_type() == &TokenType::LParen {
3169                    self.advance();
3170
3171                    // Special: COUNT(*), COUNT(DISTINCT x)
3172                    let distinct = self.match_token(TokenType::Distinct);
3173
3174                    // MySQL's GROUP_CONCAT has bespoke grammar
3175                    // (ORDER BY ..., SEPARATOR ...) — parse it into a typed
3176                    // expression so the structure is preserved across dialects.
3177                    if name.eq_ignore_ascii_case("GROUP_CONCAT") {
3178                        let expr = self.parse_group_concat_call(distinct)?;
3179                        self.expect(TokenType::RParen)?;
3180                        return Ok(expr);
3181                    }
3182
3183                    let args = if self.peek_type() == &TokenType::RParen {
3184                        vec![]
3185                    } else if self.peek_type() == &TokenType::Star {
3186                        self.advance();
3187                        vec![Expr::Wildcard]
3188                    } else {
3189                        self.parse_expr_list()?
3190                    };
3191
3192                    // Optional aggregate ORDER BY inside arg list (Postgres / Spark):
3193                    //   array_agg(x ORDER BY y DESC)
3194                    //   string_agg(x, ',' ORDER BY y)
3195                    let mut agg_order_by: Vec<OrderByItem> = vec![];
3196                    if self.peek_type() == &TokenType::Order {
3197                        self.advance();
3198                        self.expect(TokenType::By)?;
3199                        agg_order_by = self.parse_order_by_items()?;
3200                    }
3201                    self.expect(TokenType::RParen)?;
3202
3203                    // Optional WITHIN GROUP (ORDER BY ...) — ordered-set aggregates
3204                    //   percentile_cont(0.5) WITHIN GROUP (ORDER BY x)
3205                    //   listagg(x, ',') WITHIN GROUP (ORDER BY x)
3206                    let mut within_group = false;
3207                    let mut wg_order_by: Vec<OrderByItem> = vec![];
3208                    if self.check_keyword("WITHIN") {
3209                        self.advance();
3210                        self.expect_keyword("GROUP")?;
3211                        self.expect(TokenType::LParen)?;
3212                        self.expect(TokenType::Order)?;
3213                        self.expect(TokenType::By)?;
3214                        wg_order_by = self.parse_order_by_items()?;
3215                        self.expect(TokenType::RParen)?;
3216                        within_group = true;
3217                    }
3218
3219                    let final_order_by = if within_group { wg_order_by } else { agg_order_by };
3220
3221                    // Try to construct a typed function variant only when there are no
3222                    // aggregate-specific clauses (otherwise we lose them).
3223                    if final_order_by.is_empty()
3224                        && !within_group
3225                        && let Some(typed) = Self::try_typed_function(&name, args.clone(), distinct)
3226                    {
3227                        return Ok(typed);
3228                    }
3229
3230                    Ok(Expr::Function {
3231                        name,
3232                        args,
3233                        distinct,
3234                        filter: None,
3235                        over: None,
3236                        order_by: final_order_by,
3237                        within_group,
3238                    })
3239                }
3240                // Qualified column: table.column or table.*
3241                else if self.match_token(TokenType::Dot) {
3242                    if self.peek_type() == &TokenType::Star {
3243                        self.advance();
3244                        Ok(Expr::QualifiedWildcard { table: name })
3245                    } else {
3246                        let (col, col_qs) = self.expect_name_with_quote()?;
3247                        Ok(Expr::Column {
3248                            table: Some(name),
3249                            name: col,
3250                            quote_style: col_qs,
3251                            table_quote_style: name_qs,
3252                        })
3253                    }
3254                } else {
3255                    Ok(Expr::Column {
3256                        table: None,
3257                        name,
3258                        quote_style: name_qs,
3259                        table_quote_style: QuoteStyle::None,
3260                    })
3261                }
3262            }
3263
3264            _ => Err(SqlglotError::UnexpectedToken { token }),
3265        }
3266    }
3267
3268    fn is_data_type_token(&self) -> bool {
3269        matches!(
3270            self.peek_type(),
3271            TokenType::Int
3272                | TokenType::Integer
3273                | TokenType::BigInt
3274                | TokenType::SmallInt
3275                | TokenType::TinyInt
3276                | TokenType::Float
3277                | TokenType::Double
3278                | TokenType::Decimal
3279                | TokenType::Numeric
3280                | TokenType::Real
3281                | TokenType::Varchar
3282                | TokenType::Char
3283                | TokenType::Text
3284                | TokenType::Boolean
3285                | TokenType::Date
3286                | TokenType::Timestamp
3287                | TokenType::TimestampTz
3288                | TokenType::Time
3289                | TokenType::Interval
3290                | TokenType::Blob
3291                | TokenType::Bytea
3292                | TokenType::Json
3293                | TokenType::Jsonb
3294                | TokenType::Uuid
3295                | TokenType::Array
3296                | TokenType::Map
3297                | TokenType::Struct
3298        )
3299    }
3300
3301    fn parse_datetime_field(&mut self) -> Result<DateTimeField> {
3302        let token = self.peek().clone();
3303        let field = match &token.token_type {
3304            TokenType::Year => DateTimeField::Year,
3305            TokenType::Month => DateTimeField::Month,
3306            TokenType::Day => DateTimeField::Day,
3307            TokenType::Hour => DateTimeField::Hour,
3308            TokenType::Minute => DateTimeField::Minute,
3309            TokenType::Second => DateTimeField::Second,
3310            TokenType::Epoch => DateTimeField::Epoch,
3311            _ => {
3312                let name = token.value.to_uppercase();
3313                match name.as_str() {
3314                    "YEAR" => DateTimeField::Year,
3315                    "QUARTER" => DateTimeField::Quarter,
3316                    "MONTH" => DateTimeField::Month,
3317                    "WEEK" => DateTimeField::Week,
3318                    "DAY" => DateTimeField::Day,
3319                    "DOW" | "DAYOFWEEK" => DateTimeField::DayOfWeek,
3320                    "DOY" | "DAYOFYEAR" => DateTimeField::DayOfYear,
3321                    "HOUR" => DateTimeField::Hour,
3322                    "MINUTE" => DateTimeField::Minute,
3323                    "SECOND" => DateTimeField::Second,
3324                    "MILLISECOND" => DateTimeField::Millisecond,
3325                    "MICROSECOND" => DateTimeField::Microsecond,
3326                    "NANOSECOND" => DateTimeField::Nanosecond,
3327                    "EPOCH" => DateTimeField::Epoch,
3328                    "TIMEZONE" => DateTimeField::Timezone,
3329                    "TIMEZONE_HOUR" => DateTimeField::TimezoneHour,
3330                    "TIMEZONE_MINUTE" => DateTimeField::TimezoneMinute,
3331                    _ => {
3332                        return Err(SqlglotError::ParserError {
3333                            message: format!("Unknown datetime field: {name}"),
3334                        });
3335                    }
3336                }
3337            }
3338        };
3339        self.advance();
3340        Ok(field)
3341    }
3342
3343    fn try_parse_datetime_field(&mut self) -> Option<DateTimeField> {
3344        let saved = self.pos;
3345        match self.parse_datetime_field() {
3346            Ok(field) => Some(field),
3347            Err(_) => {
3348                self.pos = saved;
3349                None
3350            }
3351        }
3352    }
3353
3354    /// Parse the inside of `GROUP_CONCAT(...)` (caller has already consumed
3355    /// the `(` and optional `DISTINCT`). Returns a typed `GroupConcat`
3356    /// expression. Does NOT consume the trailing `)`.
3357    fn parse_group_concat_call(&mut self, distinct: bool) -> Result<Expr> {
3358        let mut exprs: Vec<Expr> = Vec::new();
3359        let mut order_by: Vec<OrderByItem> = Vec::new();
3360        let mut separator: Option<Box<Expr>> = None;
3361
3362        if self.peek_type() != &TokenType::RParen {
3363            exprs.push(self.parse_expr()?);
3364            while self.peek_type() == &TokenType::Comma {
3365                // ORDER BY / SEPARATOR are alternative terminators, not args.
3366                // Peek one past the comma to disambiguate `f(a, b)` from
3367                // `f(a, b ORDER BY ...)` — but comma here always introduces
3368                // another positional arg, so just keep consuming.
3369                self.advance();
3370                exprs.push(self.parse_expr()?);
3371            }
3372
3373            if self.match_token(TokenType::Order) {
3374                self.expect(TokenType::By)?;
3375                order_by = self.parse_order_by_items()?;
3376            }
3377
3378            if self.match_keyword("SEPARATOR") {
3379                separator = Some(Box::new(self.parse_expr()?));
3380            }
3381        }
3382
3383        Ok(Expr::TypedFunction {
3384            func: TypedFunction::GroupConcat {
3385                exprs,
3386                separator,
3387                order_by,
3388                distinct,
3389            },
3390            filter: None,
3391            over: None,
3392        })
3393    }
3394
3395    /// Try to construct a typed function expression from a parsed function call.
3396    /// Returns `None` if the function name is not recognized, falling back to
3397    /// the generic `Expr::Function`.
3398    fn try_typed_function(name: &str, args: Vec<Expr>, distinct: bool) -> Option<Expr> {
3399        let upper = name.to_uppercase();
3400        let tf = match upper.as_str() {
3401            // ── Date/Time ──────────────────────────────────────────
3402            "DATE_ADD" | "DATEADD" | "TIMESTAMPADD" => {
3403                let mut it = args.into_iter();
3404                let first = it.next()?;
3405                let second = it.next()?;
3406                let third = it.next();
3407                // Handle DATEADD(unit, interval, expr) — TSQL/Snowflake arg order
3408                if upper == "DATEADD" {
3409                    if let Some(third_arg) = third {
3410                        // 3-arg: DATEADD(unit, interval, expr)
3411                        let unit = Self::expr_to_datetime_field(&first);
3412                        TypedFunction::DateAdd {
3413                            expr: Box::new(third_arg),
3414                            interval: Box::new(second),
3415                            unit,
3416                        }
3417                    } else {
3418                        TypedFunction::DateAdd {
3419                            expr: Box::new(first),
3420                            interval: Box::new(second),
3421                            unit: None,
3422                        }
3423                    }
3424                } else {
3425                    // DATE_ADD(expr, interval [, unit])
3426                    let unit = third.as_ref().and_then(Self::expr_to_datetime_field);
3427                    TypedFunction::DateAdd {
3428                        expr: Box::new(first),
3429                        interval: Box::new(second),
3430                        unit,
3431                    }
3432                }
3433            }
3434            "DATE_DIFF" | "DATEDIFF" | "TIMESTAMPDIFF" => {
3435                let mut it = args.into_iter();
3436                let first = it.next()?;
3437                let second = it.next()?;
3438                let third = it.next();
3439                if let Some(third_arg) = third {
3440                    if upper == "DATEDIFF" {
3441                        // DATEDIFF(unit, start, end) — TSQL/Snowflake
3442                        let unit = Self::expr_to_datetime_field(&first);
3443                        TypedFunction::DateDiff {
3444                            start: Box::new(second),
3445                            end: Box::new(third_arg),
3446                            unit,
3447                        }
3448                    } else {
3449                        let unit = Self::expr_to_datetime_field(&third_arg);
3450                        TypedFunction::DateDiff {
3451                            start: Box::new(first),
3452                            end: Box::new(second),
3453                            unit,
3454                        }
3455                    }
3456                } else {
3457                    TypedFunction::DateDiff {
3458                        start: Box::new(first),
3459                        end: Box::new(second),
3460                        unit: None,
3461                    }
3462                }
3463            }
3464            "DATE_TRUNC" | "DATETRUNC" => {
3465                let mut it = args.into_iter();
3466                let first = it.next()?;
3467                let second = it.next()?;
3468                // DATE_TRUNC('unit', expr) or DATE_TRUNC(unit, expr)
3469                let (unit, expr) = if let Some(u) = Self::expr_to_datetime_field(&first) {
3470                    (u, second)
3471                } else if let Some(u) = Self::expr_to_datetime_field(&second) {
3472                    (u, first)
3473                } else {
3474                    // Default: first = unit string, second = expr
3475                    return None;
3476                };
3477                TypedFunction::DateTrunc {
3478                    unit,
3479                    expr: Box::new(expr),
3480                }
3481            }
3482            "DATE_SUB" | "DATESUB" => {
3483                let mut it = args.into_iter();
3484                let first = it.next()?;
3485                let second = it.next()?;
3486                let third = it.next();
3487                let unit = third.as_ref().and_then(Self::expr_to_datetime_field);
3488                TypedFunction::DateSub {
3489                    expr: Box::new(first),
3490                    interval: Box::new(second),
3491                    unit,
3492                }
3493            }
3494            "CURRENT_DATE" => TypedFunction::CurrentDate,
3495            "CURRENT_TIME" | "CURTIME" => TypedFunction::CurrentTime,
3496            "CURRENT_TIMESTAMP" | "NOW" | "GETDATE" | "SYSDATE" => TypedFunction::CurrentTimestamp,
3497            "STR_TO_TIME" | "STR_TO_DATE" | "TO_TIMESTAMP" | "PARSE_TIMESTAMP"
3498            | "PARSE_DATETIME" => {
3499                let mut it = args.into_iter();
3500                let expr = it.next()?;
3501                let format = it.next()?;
3502                TypedFunction::StrToTime {
3503                    expr: Box::new(expr),
3504                    format: Box::new(format),
3505                }
3506            }
3507            "TIME_TO_STR" | "DATE_FORMAT" | "FORMAT_TIMESTAMP" | "FORMAT_DATETIME" | "TO_CHAR" => {
3508                let mut it = args.into_iter();
3509                let expr = it.next()?;
3510                let format = it.next()?;
3511                TypedFunction::TimeToStr {
3512                    expr: Box::new(expr),
3513                    format: Box::new(format),
3514                }
3515            }
3516            "TS_OR_DS_TO_DATE" => {
3517                let mut it = args.into_iter();
3518                TypedFunction::TsOrDsToDate {
3519                    expr: Box::new(it.next()?),
3520                }
3521            }
3522            "YEAR" => {
3523                let mut it = args.into_iter();
3524                TypedFunction::Year {
3525                    expr: Box::new(it.next()?),
3526                }
3527            }
3528            "MONTH" => {
3529                let mut it = args.into_iter();
3530                TypedFunction::Month {
3531                    expr: Box::new(it.next()?),
3532                }
3533            }
3534            "DAY" | "DAYOFMONTH" => {
3535                let mut it = args.into_iter();
3536                TypedFunction::Day {
3537                    expr: Box::new(it.next()?),
3538                }
3539            }
3540
3541            // ── String ─────────────────────────────────────────────
3542            "TRIM" => {
3543                let mut it = args.into_iter();
3544                let expr = it.next()?;
3545                TypedFunction::Trim {
3546                    expr: Box::new(expr),
3547                    trim_type: TrimType::Both,
3548                    trim_chars: None,
3549                }
3550            }
3551            "LTRIM" => {
3552                let mut it = args.into_iter();
3553                let expr = it.next()?;
3554                TypedFunction::Trim {
3555                    expr: Box::new(expr),
3556                    trim_type: TrimType::Leading,
3557                    trim_chars: None,
3558                }
3559            }
3560            "RTRIM" => {
3561                let mut it = args.into_iter();
3562                let expr = it.next()?;
3563                TypedFunction::Trim {
3564                    expr: Box::new(expr),
3565                    trim_type: TrimType::Trailing,
3566                    trim_chars: None,
3567                }
3568            }
3569            "SUBSTRING" | "SUBSTR" => {
3570                let mut it = args.into_iter();
3571                let expr = it.next()?;
3572                let start = it.next()?;
3573                let length = it.next();
3574                TypedFunction::Substring {
3575                    expr: Box::new(expr),
3576                    start: Box::new(start),
3577                    length: length.map(Box::new),
3578                }
3579            }
3580            "UPPER" | "UCASE" => {
3581                let mut it = args.into_iter();
3582                TypedFunction::Upper {
3583                    expr: Box::new(it.next()?),
3584                }
3585            }
3586            "LOWER" | "LCASE" => {
3587                let mut it = args.into_iter();
3588                TypedFunction::Lower {
3589                    expr: Box::new(it.next()?),
3590                }
3591            }
3592            "REGEXP_LIKE" | "RLIKE" => {
3593                let mut it = args.into_iter();
3594                let expr = it.next()?;
3595                let pattern = it.next()?;
3596                let flags = it.next();
3597                TypedFunction::RegexpLike {
3598                    expr: Box::new(expr),
3599                    pattern: Box::new(pattern),
3600                    flags: flags.map(Box::new),
3601                }
3602            }
3603            "REGEXP_EXTRACT" | "REGEXP_SUBSTR" => {
3604                let mut it = args.into_iter();
3605                let expr = it.next()?;
3606                let pattern = it.next()?;
3607                let group_index = it.next();
3608                TypedFunction::RegexpExtract {
3609                    expr: Box::new(expr),
3610                    pattern: Box::new(pattern),
3611                    group_index: group_index.map(Box::new),
3612                }
3613            }
3614            "REGEXP_REPLACE" => {
3615                let mut it = args.into_iter();
3616                let expr = it.next()?;
3617                let pattern = it.next()?;
3618                let replacement = it.next()?;
3619                let flags = it.next();
3620                TypedFunction::RegexpReplace {
3621                    expr: Box::new(expr),
3622                    pattern: Box::new(pattern),
3623                    replacement: Box::new(replacement),
3624                    flags: flags.map(Box::new),
3625                }
3626            }
3627            "CONCAT_WS" => {
3628                let mut it = args.into_iter();
3629                let separator = it.next()?;
3630                let exprs: Vec<Expr> = it.collect();
3631                TypedFunction::ConcatWs {
3632                    separator: Box::new(separator),
3633                    exprs,
3634                }
3635            }
3636            "SPLIT" | "STRING_SPLIT" => {
3637                let mut it = args.into_iter();
3638                let expr = it.next()?;
3639                let delimiter = it.next()?;
3640                TypedFunction::Split {
3641                    expr: Box::new(expr),
3642                    delimiter: Box::new(delimiter),
3643                }
3644            }
3645            "INITCAP" => {
3646                let mut it = args.into_iter();
3647                TypedFunction::Initcap {
3648                    expr: Box::new(it.next()?),
3649                }
3650            }
3651            "LENGTH" | "LEN" | "CHAR_LENGTH" | "CHARACTER_LENGTH" => {
3652                let mut it = args.into_iter();
3653                TypedFunction::Length {
3654                    expr: Box::new(it.next()?),
3655                }
3656            }
3657            "REPLACE" => {
3658                let mut it = args.into_iter();
3659                let expr = it.next()?;
3660                let from = it.next()?;
3661                let to = it.next()?;
3662                TypedFunction::Replace {
3663                    expr: Box::new(expr),
3664                    from: Box::new(from),
3665                    to: Box::new(to),
3666                }
3667            }
3668            "REVERSE" => {
3669                let mut it = args.into_iter();
3670                TypedFunction::Reverse {
3671                    expr: Box::new(it.next()?),
3672                }
3673            }
3674            "LEFT" => {
3675                let mut it = args.into_iter();
3676                let expr = it.next()?;
3677                let n = it.next()?;
3678                TypedFunction::Left {
3679                    expr: Box::new(expr),
3680                    n: Box::new(n),
3681                }
3682            }
3683            "RIGHT" => {
3684                let mut it = args.into_iter();
3685                let expr = it.next()?;
3686                let n = it.next()?;
3687                TypedFunction::Right {
3688                    expr: Box::new(expr),
3689                    n: Box::new(n),
3690                }
3691            }
3692            "LPAD" => {
3693                let mut it = args.into_iter();
3694                let expr = it.next()?;
3695                let length = it.next()?;
3696                let pad = it.next();
3697                TypedFunction::Lpad {
3698                    expr: Box::new(expr),
3699                    length: Box::new(length),
3700                    pad: pad.map(Box::new),
3701                }
3702            }
3703            "RPAD" => {
3704                let mut it = args.into_iter();
3705                let expr = it.next()?;
3706                let length = it.next()?;
3707                let pad = it.next();
3708                TypedFunction::Rpad {
3709                    expr: Box::new(expr),
3710                    length: Box::new(length),
3711                    pad: pad.map(Box::new),
3712                }
3713            }
3714
3715            // ── Aggregate ──────────────────────────────────────────
3716            "COUNT" => {
3717                let mut it = args.into_iter();
3718                let expr = it.next().unwrap_or(Expr::Wildcard);
3719                TypedFunction::Count {
3720                    expr: Box::new(expr),
3721                    distinct,
3722                }
3723            }
3724            "SUM" => {
3725                let mut it = args.into_iter();
3726                TypedFunction::Sum {
3727                    expr: Box::new(it.next()?),
3728                    distinct,
3729                }
3730            }
3731            "AVG" => {
3732                let mut it = args.into_iter();
3733                TypedFunction::Avg {
3734                    expr: Box::new(it.next()?),
3735                    distinct,
3736                }
3737            }
3738            "MIN" => {
3739                let mut it = args.into_iter();
3740                TypedFunction::Min {
3741                    expr: Box::new(it.next()?),
3742                }
3743            }
3744            "MAX" => {
3745                let mut it = args.into_iter();
3746                TypedFunction::Max {
3747                    expr: Box::new(it.next()?),
3748                }
3749            }
3750            "ARRAY_AGG" | "LIST" | "COLLECT_LIST" => {
3751                let mut it = args.into_iter();
3752                TypedFunction::ArrayAgg {
3753                    expr: Box::new(it.next()?),
3754                    distinct,
3755                }
3756            }
3757            "APPROX_DISTINCT" | "APPROX_COUNT_DISTINCT" => {
3758                let mut it = args.into_iter();
3759                TypedFunction::ApproxDistinct {
3760                    expr: Box::new(it.next()?),
3761                }
3762            }
3763            "VARIANCE" | "VAR_SAMP" | "VAR" => {
3764                let mut it = args.into_iter();
3765                TypedFunction::Variance {
3766                    expr: Box::new(it.next()?),
3767                }
3768            }
3769            "STDDEV" | "STDDEV_SAMP" => {
3770                let mut it = args.into_iter();
3771                TypedFunction::Stddev {
3772                    expr: Box::new(it.next()?),
3773                }
3774            }
3775
3776            // ── Array ──────────────────────────────────────────────
3777            "ARRAY_CONCAT" | "ARRAY_CAT" => TypedFunction::ArrayConcat { arrays: args },
3778            "ARRAY_CONTAINS" => {
3779                let mut it = args.into_iter();
3780                let array = it.next()?;
3781                let element = it.next()?;
3782                TypedFunction::ArrayContains {
3783                    array: Box::new(array),
3784                    element: Box::new(element),
3785                }
3786            }
3787            "ARRAY_SIZE" | "ARRAY_LENGTH" | "CARDINALITY" => {
3788                let mut it = args.into_iter();
3789                TypedFunction::ArraySize {
3790                    expr: Box::new(it.next()?),
3791                }
3792            }
3793            "EXPLODE" => {
3794                let mut it = args.into_iter();
3795                TypedFunction::Explode {
3796                    expr: Box::new(it.next()?),
3797                }
3798            }
3799            "GENERATE_SERIES" | "SEQUENCE" => {
3800                let mut it = args.into_iter();
3801                let start = it.next()?;
3802                let stop = it.next()?;
3803                let step = it.next();
3804                TypedFunction::GenerateSeries {
3805                    start: Box::new(start),
3806                    stop: Box::new(stop),
3807                    step: step.map(Box::new),
3808                }
3809            }
3810            "FLATTEN" => {
3811                let mut it = args.into_iter();
3812                TypedFunction::Flatten {
3813                    expr: Box::new(it.next()?),
3814                }
3815            }
3816
3817            // ── JSON ───────────────────────────────────────────────
3818            "JSON_EXTRACT" | "JSON_VALUE" => {
3819                let mut it = args.into_iter();
3820                let expr = it.next()?;
3821                let path = it.next()?;
3822                TypedFunction::JSONExtract {
3823                    expr: Box::new(expr),
3824                    path: Box::new(path),
3825                }
3826            }
3827            "JSON_EXTRACT_SCALAR" => {
3828                let mut it = args.into_iter();
3829                let expr = it.next()?;
3830                let path = it.next()?;
3831                TypedFunction::JSONExtractScalar {
3832                    expr: Box::new(expr),
3833                    path: Box::new(path),
3834                }
3835            }
3836            "PARSE_JSON" | "JSON_PARSE" => {
3837                let mut it = args.into_iter();
3838                TypedFunction::ParseJSON {
3839                    expr: Box::new(it.next()?),
3840                }
3841            }
3842            "JSON_FORMAT" | "TO_JSON" | "TO_JSON_STRING" => {
3843                let mut it = args.into_iter();
3844                TypedFunction::JSONFormat {
3845                    expr: Box::new(it.next()?),
3846                }
3847            }
3848
3849            // ── Window ─────────────────────────────────────────────
3850            "ROW_NUMBER" => TypedFunction::RowNumber,
3851            "RANK" => TypedFunction::Rank,
3852            "DENSE_RANK" => TypedFunction::DenseRank,
3853            "NTILE" => {
3854                let mut it = args.into_iter();
3855                TypedFunction::NTile {
3856                    n: Box::new(it.next()?),
3857                }
3858            }
3859            "LEAD" => {
3860                let mut it = args.into_iter();
3861                let expr = it.next()?;
3862                let offset = it.next();
3863                let default = it.next();
3864                TypedFunction::Lead {
3865                    expr: Box::new(expr),
3866                    offset: offset.map(Box::new),
3867                    default: default.map(Box::new),
3868                }
3869            }
3870            "LAG" => {
3871                let mut it = args.into_iter();
3872                let expr = it.next()?;
3873                let offset = it.next();
3874                let default = it.next();
3875                TypedFunction::Lag {
3876                    expr: Box::new(expr),
3877                    offset: offset.map(Box::new),
3878                    default: default.map(Box::new),
3879                }
3880            }
3881            "FIRST_VALUE" => {
3882                let mut it = args.into_iter();
3883                TypedFunction::FirstValue {
3884                    expr: Box::new(it.next()?),
3885                }
3886            }
3887            "LAST_VALUE" => {
3888                let mut it = args.into_iter();
3889                TypedFunction::LastValue {
3890                    expr: Box::new(it.next()?),
3891                }
3892            }
3893
3894            // ── Math ───────────────────────────────────────────────
3895            "ABS" => {
3896                let mut it = args.into_iter();
3897                TypedFunction::Abs {
3898                    expr: Box::new(it.next()?),
3899                }
3900            }
3901            "CEIL" | "CEILING" => {
3902                let mut it = args.into_iter();
3903                TypedFunction::Ceil {
3904                    expr: Box::new(it.next()?),
3905                }
3906            }
3907            "FLOOR" => {
3908                let mut it = args.into_iter();
3909                TypedFunction::Floor {
3910                    expr: Box::new(it.next()?),
3911                }
3912            }
3913            "ROUND" => {
3914                let mut it = args.into_iter();
3915                let expr = it.next()?;
3916                let decimals = it.next();
3917                TypedFunction::Round {
3918                    expr: Box::new(expr),
3919                    decimals: decimals.map(Box::new),
3920                }
3921            }
3922            "LOG" => {
3923                let mut it = args.into_iter();
3924                let expr = it.next()?;
3925                let base = it.next();
3926                TypedFunction::Log {
3927                    expr: Box::new(expr),
3928                    base: base.map(Box::new),
3929                }
3930            }
3931            "LN" => {
3932                let mut it = args.into_iter();
3933                TypedFunction::Ln {
3934                    expr: Box::new(it.next()?),
3935                }
3936            }
3937            "POW" | "POWER" => {
3938                let mut it = args.into_iter();
3939                let base = it.next()?;
3940                let exponent = it.next()?;
3941                TypedFunction::Pow {
3942                    base: Box::new(base),
3943                    exponent: Box::new(exponent),
3944                }
3945            }
3946            "SQRT" => {
3947                let mut it = args.into_iter();
3948                TypedFunction::Sqrt {
3949                    expr: Box::new(it.next()?),
3950                }
3951            }
3952            "GREATEST" => TypedFunction::Greatest { exprs: args },
3953            "LEAST" => TypedFunction::Least { exprs: args },
3954            "MOD" => {
3955                let mut it = args.into_iter();
3956                let left = it.next()?;
3957                let right = it.next()?;
3958                TypedFunction::Mod {
3959                    left: Box::new(left),
3960                    right: Box::new(right),
3961                }
3962            }
3963
3964            // ── Conversion ─────────────────────────────────────────
3965            "HEX" | "TO_HEX" => {
3966                let mut it = args.into_iter();
3967                TypedFunction::Hex {
3968                    expr: Box::new(it.next()?),
3969                }
3970            }
3971            "UNHEX" | "FROM_HEX" => {
3972                let mut it = args.into_iter();
3973                TypedFunction::Unhex {
3974                    expr: Box::new(it.next()?),
3975                }
3976            }
3977            "MD5" => {
3978                let mut it = args.into_iter();
3979                TypedFunction::Md5 {
3980                    expr: Box::new(it.next()?),
3981                }
3982            }
3983            "SHA" | "SHA1" => {
3984                let mut it = args.into_iter();
3985                TypedFunction::Sha {
3986                    expr: Box::new(it.next()?),
3987                }
3988            }
3989            "SHA2" | "SHA256" | "SHA512" => {
3990                let mut it = args.into_iter();
3991                let expr = it.next()?;
3992                let bit_length = it.next().unwrap_or(Expr::Number("256".to_string()));
3993                TypedFunction::Sha2 {
3994                    expr: Box::new(expr),
3995                    bit_length: Box::new(bit_length),
3996                }
3997            }
3998
3999            // Not a recognized typed function
4000            _ => return None,
4001        };
4002
4003        Some(Expr::TypedFunction {
4004            func: tf,
4005            filter: None,
4006            over: None,
4007        })
4008    }
4009
4010    /// Try to extract a DateTimeField from a column-name expression.
4011    fn expr_to_datetime_field(expr: &Expr) -> Option<DateTimeField> {
4012        match expr {
4013            Expr::Column {
4014                name, table: None, ..
4015            } => match name.to_uppercase().as_str() {
4016                "YEAR" => Some(DateTimeField::Year),
4017                "QUARTER" => Some(DateTimeField::Quarter),
4018                "MONTH" => Some(DateTimeField::Month),
4019                "WEEK" => Some(DateTimeField::Week),
4020                "DAY" => Some(DateTimeField::Day),
4021                "HOUR" => Some(DateTimeField::Hour),
4022                "MINUTE" => Some(DateTimeField::Minute),
4023                "SECOND" => Some(DateTimeField::Second),
4024                "MILLISECOND" => Some(DateTimeField::Millisecond),
4025                "MICROSECOND" => Some(DateTimeField::Microsecond),
4026                _ => None,
4027            },
4028            Expr::StringLiteral(s) | Expr::NationalStringLiteral(s) => {
4029                match s.to_uppercase().as_str() {
4030                    "YEAR" => Some(DateTimeField::Year),
4031                    "QUARTER" => Some(DateTimeField::Quarter),
4032                    "MONTH" => Some(DateTimeField::Month),
4033                    "WEEK" => Some(DateTimeField::Week),
4034                    "DAY" => Some(DateTimeField::Day),
4035                    "HOUR" => Some(DateTimeField::Hour),
4036                    "MINUTE" => Some(DateTimeField::Minute),
4037                    "SECOND" => Some(DateTimeField::Second),
4038                    "MILLISECOND" => Some(DateTimeField::Millisecond),
4039                    "MICROSECOND" => Some(DateTimeField::Microsecond),
4040                    _ => None,
4041                }
4042            }
4043            _ => None,
4044        }
4045    }
4046
4047    fn parse_case_expr(&mut self) -> Result<Expr> {
4048        self.expect(TokenType::Case)?;
4049
4050        let operand = if self.peek_type() != &TokenType::When {
4051            Some(Box::new(self.parse_expr()?))
4052        } else {
4053            None
4054        };
4055
4056        let mut when_clauses = Vec::new();
4057        while self.match_token(TokenType::When) {
4058            let condition = self.parse_expr()?;
4059            self.expect(TokenType::Then)?;
4060            let result = self.parse_expr()?;
4061            when_clauses.push((condition, result));
4062        }
4063
4064        let else_clause = if self.match_token(TokenType::Else) {
4065            Some(Box::new(self.parse_expr()?))
4066        } else {
4067            None
4068        };
4069
4070        self.expect(TokenType::End)?;
4071
4072        Ok(Expr::Case {
4073            operand,
4074            when_clauses,
4075            else_clause,
4076        })
4077    }
4078}
4079
4080#[cfg(test)]
4081mod tests {
4082    use super::*;
4083
4084    #[test]
4085    fn test_parse_simple_select() {
4086        let stmt = Parser::new("SELECT a, b FROM t")
4087            .unwrap()
4088            .parse_statement()
4089            .unwrap();
4090        match stmt {
4091            Statement::Select(sel) => {
4092                assert_eq!(sel.columns.len(), 2);
4093                assert!(sel.from.is_some());
4094            }
4095            _ => panic!("Expected SELECT"),
4096        }
4097    }
4098
4099    #[test]
4100    fn test_parse_select_with_where() {
4101        let stmt = Parser::new("SELECT x FROM t WHERE x > 10")
4102            .unwrap()
4103            .parse_statement()
4104            .unwrap();
4105        match stmt {
4106            Statement::Select(sel) => assert!(sel.where_clause.is_some()),
4107            _ => panic!("Expected SELECT"),
4108        }
4109    }
4110
4111    #[test]
4112    fn test_parse_select_wildcard() {
4113        let stmt = Parser::new("SELECT * FROM users")
4114            .unwrap()
4115            .parse_statement()
4116            .unwrap();
4117        match stmt {
4118            Statement::Select(sel) => {
4119                assert_eq!(sel.columns.len(), 1);
4120                assert!(matches!(sel.columns[0], SelectItem::Wildcard));
4121            }
4122            _ => panic!("Expected SELECT"),
4123        }
4124    }
4125
4126    #[test]
4127    fn test_parse_insert() {
4128        let stmt = Parser::new("INSERT INTO t (a, b) VALUES (1, 'hello')")
4129            .unwrap()
4130            .parse_statement()
4131            .unwrap();
4132        match stmt {
4133            Statement::Insert(ins) => {
4134                assert_eq!(ins.table.name, "t");
4135                assert_eq!(ins.columns, vec!["a", "b"]);
4136                match &ins.source {
4137                    InsertSource::Values(rows) => {
4138                        assert_eq!(rows.len(), 1);
4139                        assert_eq!(rows[0].len(), 2);
4140                    }
4141                    _ => panic!("Expected VALUES"),
4142                }
4143            }
4144            _ => panic!("Expected INSERT"),
4145        }
4146    }
4147
4148    #[test]
4149    fn test_parse_delete() {
4150        let stmt = Parser::new("DELETE FROM users WHERE id = 1")
4151            .unwrap()
4152            .parse_statement()
4153            .unwrap();
4154        match stmt {
4155            Statement::Delete(del) => {
4156                assert_eq!(del.table.name, "users");
4157                assert!(del.where_clause.is_some());
4158            }
4159            _ => panic!("Expected DELETE"),
4160        }
4161    }
4162
4163    #[test]
4164    fn test_parse_join() {
4165        let stmt = Parser::new("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id")
4166            .unwrap()
4167            .parse_statement()
4168            .unwrap();
4169        match stmt {
4170            Statement::Select(sel) => {
4171                assert_eq!(sel.joins.len(), 1);
4172                assert_eq!(sel.joins[0].join_type, JoinType::Inner);
4173            }
4174            _ => panic!("Expected SELECT"),
4175        }
4176    }
4177
4178    #[test]
4179    fn test_parse_cte() {
4180        let stmt = Parser::new("WITH cte AS (SELECT 1 AS x) SELECT x FROM cte")
4181            .unwrap()
4182            .parse_statement()
4183            .unwrap();
4184        match stmt {
4185            Statement::Select(sel) => {
4186                assert_eq!(sel.ctes.len(), 1);
4187                assert_eq!(sel.ctes[0].name, "cte");
4188            }
4189            _ => panic!("Expected SELECT"),
4190        }
4191    }
4192
4193    #[test]
4194    fn test_parse_union() {
4195        let stmt = Parser::new("SELECT 1 UNION ALL SELECT 2")
4196            .unwrap()
4197            .parse_statement()
4198            .unwrap();
4199        match stmt {
4200            Statement::SetOperation(sop) => {
4201                assert_eq!(sop.op, SetOperationType::Union);
4202                assert!(sop.all);
4203            }
4204            _ => panic!("Expected SetOperation"),
4205        }
4206    }
4207
4208    #[test]
4209    fn test_parse_cast() {
4210        let stmt = Parser::new("SELECT CAST(x AS INT) FROM t")
4211            .unwrap()
4212            .parse_statement()
4213            .unwrap();
4214        match stmt {
4215            Statement::Select(sel) => {
4216                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
4217                    assert!(matches!(expr, Expr::Cast { .. }));
4218                }
4219            }
4220            _ => panic!("Expected SELECT"),
4221        }
4222    }
4223
4224    #[test]
4225    fn test_parse_subquery() {
4226        let stmt = Parser::new("SELECT * FROM (SELECT 1 AS x) AS sub")
4227            .unwrap()
4228            .parse_statement()
4229            .unwrap();
4230        match stmt {
4231            Statement::Select(sel) => {
4232                if let Some(from) = &sel.from {
4233                    assert!(matches!(from.source, TableSource::Subquery { .. }));
4234                }
4235            }
4236            _ => panic!("Expected SELECT"),
4237        }
4238    }
4239
4240    #[test]
4241    fn test_parse_exists() {
4242        let stmt = Parser::new("SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)")
4243            .unwrap()
4244            .parse_statement()
4245            .unwrap();
4246        match stmt {
4247            Statement::Select(sel) => {
4248                assert!(sel.where_clause.is_some());
4249            }
4250            _ => panic!("Expected SELECT"),
4251        }
4252    }
4253
4254    #[test]
4255    fn test_parse_window_function() {
4256        let stmt = Parser::new(
4257            "SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp",
4258        )
4259        .unwrap()
4260        .parse_statement()
4261        .unwrap();
4262        match stmt {
4263            Statement::Select(sel) => {
4264                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
4265                    match expr {
4266                        Expr::TypedFunction { over, .. } => {
4267                            assert!(over.is_some());
4268                        }
4269                        Expr::Function { over, .. } => {
4270                            assert!(over.is_some());
4271                        }
4272                        _ => panic!("Expected function"),
4273                    }
4274                }
4275            }
4276            _ => panic!("Expected SELECT"),
4277        }
4278    }
4279
4280    #[test]
4281    fn test_parse_multiple_statements() {
4282        let stmts = Parser::new("SELECT 1; SELECT 2;")
4283            .unwrap()
4284            .parse_statements()
4285            .unwrap();
4286        assert_eq!(stmts.len(), 2);
4287    }
4288
4289    #[test]
4290    fn test_parse_insert_select() {
4291        let stmt = Parser::new("INSERT INTO t SELECT * FROM s")
4292            .unwrap()
4293            .parse_statement()
4294            .unwrap();
4295        match stmt {
4296            Statement::Insert(ins) => {
4297                assert!(matches!(ins.source, InsertSource::Query(_)));
4298            }
4299            _ => panic!("Expected INSERT"),
4300        }
4301    }
4302
4303    #[test]
4304    fn test_parse_create_table_constraints() {
4305        let stmt =
4306            Parser::new("CREATE TABLE t (id INT PRIMARY KEY, name VARCHAR(100) NOT NULL UNIQUE)")
4307                .unwrap()
4308                .parse_statement()
4309                .unwrap();
4310        match stmt {
4311            Statement::CreateTable(ct) => {
4312                assert_eq!(ct.columns.len(), 2);
4313                assert!(ct.columns[0].primary_key);
4314                assert!(ct.columns[1].unique);
4315            }
4316            _ => panic!("Expected CREATE TABLE"),
4317        }
4318    }
4319
4320    #[test]
4321    fn test_parse_extract() {
4322        let stmt = Parser::new("SELECT EXTRACT(YEAR FROM created_at) FROM t")
4323            .unwrap()
4324            .parse_statement()
4325            .unwrap();
4326        match stmt {
4327            Statement::Select(sel) => {
4328                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
4329                    assert!(matches!(expr, Expr::Extract { .. }));
4330                }
4331            }
4332            _ => panic!("Expected SELECT"),
4333        }
4334    }
4335
4336    #[test]
4337    fn test_parse_postgres_cast() {
4338        let stmt = Parser::new("SELECT x::int FROM t")
4339            .unwrap()
4340            .parse_statement()
4341            .unwrap();
4342        match stmt {
4343            Statement::Select(sel) => {
4344                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
4345                    assert!(matches!(expr, Expr::Cast { .. }));
4346                }
4347            }
4348            _ => panic!("Expected SELECT"),
4349        }
4350    }
4351}
4352
4353/// Attach comments to the appropriate field on a parsed statement.
4354fn attach_comments_to_statement(stmt: &mut Statement, comments: Vec<String>) {
4355    match stmt {
4356        Statement::Select(s) => s.comments = comments,
4357        Statement::Insert(s) => s.comments = comments,
4358        Statement::Update(s) => s.comments = comments,
4359        Statement::Delete(s) => s.comments = comments,
4360        Statement::CreateTable(s) => s.comments = comments,
4361        Statement::DropTable(s) => s.comments = comments,
4362        Statement::SetOperation(s) => s.comments = comments,
4363        Statement::AlterTable(s) => s.comments = comments,
4364        Statement::CreateView(s) => s.comments = comments,
4365        Statement::DropView(s) => s.comments = comments,
4366        Statement::Truncate(s) => s.comments = comments,
4367        Statement::Explain(s) => s.comments = comments,
4368        Statement::Use(s) => s.comments = comments,
4369        Statement::Merge(s) => s.comments = comments,
4370        Statement::Command(s) => s.comments = comments,
4371        // Transaction and Expression don't have comment fields
4372        Statement::Transaction(_) | Statement::Expression(_) => {}
4373    }
4374}