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