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