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