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
1829        // PostgreSQL opt_array_bounds: typename[], typename[N], typename[][]...
1830        let mut dt = type_result?;
1831        while self.match_token(TokenType::LBracket) {
1832            // Consume optional integer bound (PostgreSQL ignores it but accepts it)
1833            let _ = self.match_token(TokenType::Number);
1834            self.expect(TokenType::RBracket)?;
1835            dt = DataType::Array(Some(Box::new(dt)));
1836        }
1837        Ok(dt)
1838    }
1839
1840    fn parse_type_params(&mut self) -> Result<(Option<u32>, Option<u32>)> {
1841        if self.match_token(TokenType::LParen) {
1842            let p: Option<u32> = self.expect(TokenType::Number)?.value.parse().ok();
1843            let s = if self.match_token(TokenType::Comma) {
1844                self.expect(TokenType::Number)?.value.parse().ok()
1845            } else {
1846                None
1847            };
1848            self.expect(TokenType::RParen)?;
1849            Ok((p, s))
1850        } else {
1851            Ok((None, None))
1852        }
1853    }
1854
1855    fn parse_single_type_param(&mut self) -> Result<Option<u32>> {
1856        if self.match_token(TokenType::LParen) {
1857            let n: Option<u32> = self.expect(TokenType::Number)?.value.parse().ok();
1858            self.expect(TokenType::RParen)?;
1859            Ok(n)
1860        } else {
1861            Ok(None)
1862        }
1863    }
1864
1865    // ── DROP ────────────────────────────────────────────────────────
1866
1867    fn parse_drop(&mut self) -> Result<Statement> {
1868        self.expect(TokenType::Drop)?;
1869
1870        if self.match_token(TokenType::Materialized) {
1871            self.expect(TokenType::View)?;
1872            let if_exists = if self.match_token(TokenType::If) {
1873                self.expect(TokenType::Exists)?;
1874                true
1875            } else {
1876                false
1877            };
1878            let name = self.parse_table_ref()?;
1879            return Ok(Statement::DropView(DropViewStatement {
1880                comments: vec![],
1881                name,
1882                if_exists,
1883                materialized: true,
1884            }));
1885        }
1886
1887        if self.match_token(TokenType::View) {
1888            let if_exists = if self.match_token(TokenType::If) {
1889                self.expect(TokenType::Exists)?;
1890                true
1891            } else {
1892                false
1893            };
1894            let name = self.parse_table_ref()?;
1895            return Ok(Statement::DropView(DropViewStatement {
1896                comments: vec![],
1897                name,
1898                if_exists,
1899                materialized: false,
1900            }));
1901        }
1902
1903        self.expect(TokenType::Table)?;
1904
1905        let if_exists = if self.match_token(TokenType::If) {
1906            self.expect(TokenType::Exists)?;
1907            true
1908        } else {
1909            false
1910        };
1911
1912        let table = self.parse_table_ref()?;
1913        let cascade = self.match_token(TokenType::Cascade);
1914
1915        Ok(Statement::DropTable(DropTableStatement {
1916            comments: vec![],
1917            if_exists,
1918            table,
1919            cascade,
1920        }))
1921    }
1922
1923    // ── ALTER TABLE ─────────────────────────────────────────────────
1924
1925    fn parse_alter_table(&mut self) -> Result<AlterTableStatement> {
1926        self.expect(TokenType::Alter)?;
1927        self.expect(TokenType::Table)?;
1928        let table = self.parse_table_ref_no_alias()?;
1929
1930        let mut actions = Vec::new();
1931        loop {
1932            let action = self.parse_alter_action()?;
1933            actions.push(action);
1934            if !self.match_token(TokenType::Comma) {
1935                break;
1936            }
1937        }
1938
1939        Ok(AlterTableStatement {
1940            comments: vec![],
1941            table,
1942            actions,
1943        })
1944    }
1945
1946    fn parse_alter_action(&mut self) -> Result<AlterTableAction> {
1947        if self.match_keyword("ADD") {
1948            if matches!(
1949                self.peek_type(),
1950                TokenType::Constraint
1951                    | TokenType::Primary
1952                    | TokenType::Unique
1953                    | TokenType::Foreign
1954                    | TokenType::Check
1955            ) {
1956                let constraint = self.parse_table_constraint()?;
1957                Ok(AlterTableAction::AddConstraint(constraint))
1958            } else {
1959                let _ = self.match_keyword("COLUMN");
1960                let col = self.parse_column_def()?;
1961                Ok(AlterTableAction::AddColumn(col))
1962            }
1963        } else if self.match_token(TokenType::Drop) {
1964            let _ = self.match_keyword("COLUMN");
1965            let if_exists = if self.match_token(TokenType::If) {
1966                self.expect(TokenType::Exists)?;
1967                true
1968            } else {
1969                false
1970            };
1971            let name = self.expect_name()?;
1972            Ok(AlterTableAction::DropColumn { name, if_exists })
1973        } else if self.match_keyword("RENAME") {
1974            if self.match_keyword("COLUMN") {
1975                let old_name = self.expect_name()?;
1976                self.expect(TokenType::Identifier)?; // TO
1977                let new_name = self.expect_name()?;
1978                Ok(AlterTableAction::RenameColumn { old_name, new_name })
1979            } else if self.match_keyword("TO") {
1980                let new_name = self.expect_name()?;
1981                Ok(AlterTableAction::RenameTable { new_name })
1982            } else {
1983                Err(SqlglotError::ParserError {
1984                    message: "Expected COLUMN or TO after RENAME".into(),
1985                })
1986            }
1987        } else {
1988            Err(SqlglotError::ParserError {
1989                message: "Expected ADD, DROP, or RENAME in ALTER TABLE".into(),
1990            })
1991        }
1992    }
1993
1994    // ── TRUNCATE ────────────────────────────────────────────────────
1995
1996    fn parse_truncate(&mut self) -> Result<TruncateStatement> {
1997        self.expect(TokenType::Truncate)?;
1998        let _ = self.match_token(TokenType::Table);
1999        let table = self.parse_table_ref()?;
2000        Ok(TruncateStatement {
2001            comments: vec![],
2002            table,
2003        })
2004    }
2005
2006    // ── Transaction ─────────────────────────────────────────────────
2007
2008    fn parse_transaction(&mut self) -> Result<TransactionStatement> {
2009        match self.peek_type() {
2010            TokenType::Begin => {
2011                self.advance();
2012                let _ = self.match_token(TokenType::Transaction);
2013                Ok(TransactionStatement::Begin)
2014            }
2015            TokenType::Commit => {
2016                self.advance();
2017                let _ = self.match_token(TokenType::Transaction);
2018                Ok(TransactionStatement::Commit)
2019            }
2020            TokenType::Rollback => {
2021                self.advance();
2022                let _ = self.match_token(TokenType::Transaction);
2023                if self.match_keyword("TO") {
2024                    let _ = self.match_token(TokenType::Savepoint);
2025                    let name = self.expect_name()?;
2026                    Ok(TransactionStatement::RollbackTo(name))
2027                } else {
2028                    Ok(TransactionStatement::Rollback)
2029                }
2030            }
2031            TokenType::Savepoint => {
2032                self.advance();
2033                let name = self.expect_name()?;
2034                Ok(TransactionStatement::Savepoint(name))
2035            }
2036            _ => Err(SqlglotError::ParserError {
2037                message: "Expected transaction statement".into(),
2038            }),
2039        }
2040    }
2041
2042    // ── EXPLAIN ─────────────────────────────────────────────────────
2043
2044    fn parse_explain(&mut self) -> Result<ExplainStatement> {
2045        self.expect(TokenType::Explain)?;
2046        let analyze = self.match_token(TokenType::Analyze);
2047        let statement = self.parse_statement_inner()?;
2048        Ok(ExplainStatement {
2049            comments: vec![],
2050            analyze,
2051            statement: Box::new(statement),
2052        })
2053    }
2054
2055    // ── USE ─────────────────────────────────────────────────────────
2056
2057    fn parse_use(&mut self) -> Result<UseStatement> {
2058        self.expect(TokenType::Use)?;
2059        let name = self.expect_name()?;
2060        Ok(UseStatement {
2061            comments: vec![],
2062            name,
2063        })
2064    }
2065
2066    // ══════════════════════════════════════════════════════════════
2067    // Expression parsing (precedence climbing)
2068    // ══════════════════════════════════════════════════════════════
2069
2070    fn parse_expr(&mut self) -> Result<Expr> {
2071        self.parse_or_expr()
2072    }
2073
2074    fn parse_or_expr(&mut self) -> Result<Expr> {
2075        let mut left = self.parse_and_expr()?;
2076        while self.match_token(TokenType::Or) {
2077            let right = self.parse_and_expr()?;
2078            left = Expr::BinaryOp {
2079                left: Box::new(left),
2080                op: BinaryOperator::Or,
2081                right: Box::new(right),
2082            };
2083        }
2084        Ok(left)
2085    }
2086
2087    fn parse_and_expr(&mut self) -> Result<Expr> {
2088        let mut left = self.parse_not_expr()?;
2089        while self.match_token(TokenType::And) {
2090            let right = self.parse_not_expr()?;
2091            left = Expr::BinaryOp {
2092                left: Box::new(left),
2093                op: BinaryOperator::And,
2094                right: Box::new(right),
2095            };
2096        }
2097        Ok(left)
2098    }
2099
2100    fn parse_not_expr(&mut self) -> Result<Expr> {
2101        if self.match_token(TokenType::Not) {
2102            let expr = self.parse_not_expr()?;
2103            Ok(Expr::UnaryOp {
2104                op: UnaryOperator::Not,
2105                expr: Box::new(expr),
2106            })
2107        } else {
2108            self.parse_comparison()
2109        }
2110    }
2111
2112    fn parse_comparison(&mut self) -> Result<Expr> {
2113        let mut left = self.parse_addition()?;
2114
2115        loop {
2116            let op = match self.peek_type() {
2117                TokenType::Eq => Some(BinaryOperator::Eq),
2118                TokenType::Neq => Some(BinaryOperator::Neq),
2119                TokenType::Lt => Some(BinaryOperator::Lt),
2120                TokenType::Gt => Some(BinaryOperator::Gt),
2121                TokenType::LtEq => Some(BinaryOperator::LtEq),
2122                TokenType::GtEq => Some(BinaryOperator::GtEq),
2123                _ => None,
2124            };
2125
2126            if let Some(op) = op {
2127                self.advance();
2128                if matches!(self.peek_type(), TokenType::Any | TokenType::Some) {
2129                    self.advance();
2130                    self.expect(TokenType::LParen)?;
2131                    let right = if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
2132                        Expr::Subquery(Box::new(self.parse_statement_inner()?))
2133                    } else {
2134                        self.parse_expr()?
2135                    };
2136                    self.expect(TokenType::RParen)?;
2137                    left = Expr::AnyOp {
2138                        expr: Box::new(left),
2139                        op,
2140                        right: Box::new(right),
2141                    };
2142                } else if self.peek_type() == &TokenType::All {
2143                    self.advance();
2144                    self.expect(TokenType::LParen)?;
2145                    let right = if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
2146                        Expr::Subquery(Box::new(self.parse_statement_inner()?))
2147                    } else {
2148                        self.parse_expr()?
2149                    };
2150                    self.expect(TokenType::RParen)?;
2151                    left = Expr::AllOp {
2152                        expr: Box::new(left),
2153                        op,
2154                        right: Box::new(right),
2155                    };
2156                } else {
2157                    let right = self.parse_addition()?;
2158                    left = Expr::BinaryOp {
2159                        left: Box::new(left),
2160                        op,
2161                        right: Box::new(right),
2162                    };
2163                }
2164            } else if self.peek_type() == &TokenType::Is {
2165                self.advance();
2166                let negated = self.match_token(TokenType::Not);
2167                if self.match_token(TokenType::True) {
2168                    left = Expr::IsBool {
2169                        expr: Box::new(left),
2170                        value: true,
2171                        negated,
2172                    };
2173                } else if self.match_token(TokenType::False) {
2174                    left = Expr::IsBool {
2175                        expr: Box::new(left),
2176                        value: false,
2177                        negated,
2178                    };
2179                } else {
2180                    self.expect(TokenType::Null)?;
2181                    left = Expr::IsNull {
2182                        expr: Box::new(left),
2183                        negated,
2184                    };
2185                }
2186            } else if matches!(
2187                self.peek_type(),
2188                TokenType::Not
2189                    | TokenType::In
2190                    | TokenType::Like
2191                    | TokenType::ILike
2192                    | TokenType::Between
2193            ) {
2194                // Peek ahead: if NOT, only consume it if followed by IN/LIKE/ILIKE/BETWEEN
2195                if self.peek_type() == &TokenType::Not {
2196                    let saved_pos = self.pos;
2197                    self.advance(); // consume NOT
2198                    if !matches!(
2199                        self.peek_type(),
2200                        TokenType::In | TokenType::Like | TokenType::ILike | TokenType::Between
2201                    ) {
2202                        // NOT is not part of a comparison predicate — restore position
2203                        self.pos = saved_pos;
2204                        break;
2205                    }
2206                    // NOT was consumed, negated = true
2207                }
2208                let negated =
2209                    self.pos > 0 && self.tokens[self.pos - 1].token_type == TokenType::Not;
2210
2211                if self.match_token(TokenType::In) {
2212                    self.expect(TokenType::LParen)?;
2213                    // Check for subquery
2214                    if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
2215                        let subquery = self.parse_statement_inner()?;
2216                        self.expect(TokenType::RParen)?;
2217                        left = Expr::InSubquery {
2218                            expr: Box::new(left),
2219                            subquery: Box::new(subquery),
2220                            negated,
2221                        };
2222                    } else {
2223                        let list = self.parse_expr_list()?;
2224                        self.expect(TokenType::RParen)?;
2225                        left = Expr::InList {
2226                            expr: Box::new(left),
2227                            list,
2228                            negated,
2229                        };
2230                    }
2231                } else if self.match_token(TokenType::Like) {
2232                    let pattern = self.parse_addition()?;
2233                    let escape = if self.match_token(TokenType::Escape) {
2234                        Some(Box::new(self.parse_primary()?))
2235                    } else {
2236                        None
2237                    };
2238                    left = Expr::Like {
2239                        expr: Box::new(left),
2240                        pattern: Box::new(pattern),
2241                        negated,
2242                        escape,
2243                    };
2244                } else if self.match_token(TokenType::ILike) {
2245                    let pattern = self.parse_addition()?;
2246                    let escape = if self.match_token(TokenType::Escape) {
2247                        Some(Box::new(self.parse_primary()?))
2248                    } else {
2249                        None
2250                    };
2251                    left = Expr::ILike {
2252                        expr: Box::new(left),
2253                        pattern: Box::new(pattern),
2254                        negated,
2255                        escape,
2256                    };
2257                } else if self.match_token(TokenType::Between) {
2258                    let low = self.parse_addition()?;
2259                    self.expect(TokenType::And)?;
2260                    let high = self.parse_addition()?;
2261                    left = Expr::Between {
2262                        expr: Box::new(left),
2263                        low: Box::new(low),
2264                        high: Box::new(high),
2265                        negated,
2266                    };
2267                } else {
2268                    break;
2269                }
2270            } else {
2271                break;
2272            }
2273        }
2274
2275        Ok(left)
2276    }
2277
2278    fn parse_addition(&mut self) -> Result<Expr> {
2279        let mut left = self.parse_multiplication()?;
2280        loop {
2281            let op = match self.peek_type() {
2282                TokenType::Plus => Some(BinaryOperator::Plus),
2283                TokenType::Minus => Some(BinaryOperator::Minus),
2284                TokenType::Concat => Some(BinaryOperator::Concat),
2285                TokenType::BitwiseOr => Some(BinaryOperator::BitwiseOr),
2286                TokenType::BitwiseXor => Some(BinaryOperator::BitwiseXor),
2287                TokenType::ShiftLeft => Some(BinaryOperator::ShiftLeft),
2288                TokenType::ShiftRight => Some(BinaryOperator::ShiftRight),
2289                _ => None,
2290            };
2291            if let Some(op) = op {
2292                self.advance();
2293                let right = self.parse_multiplication()?;
2294                left = Expr::BinaryOp {
2295                    left: Box::new(left),
2296                    op,
2297                    right: Box::new(right),
2298                };
2299            } else {
2300                break;
2301            }
2302        }
2303        Ok(left)
2304    }
2305
2306    fn parse_multiplication(&mut self) -> Result<Expr> {
2307        let mut left = self.parse_unary()?;
2308        loop {
2309            let op = match self.peek_type() {
2310                TokenType::Star => Some(BinaryOperator::Multiply),
2311                TokenType::Slash => Some(BinaryOperator::Divide),
2312                TokenType::Percent2 => Some(BinaryOperator::Modulo),
2313                TokenType::BitwiseAnd => Some(BinaryOperator::BitwiseAnd),
2314                _ => None,
2315            };
2316            if let Some(op) = op {
2317                self.advance();
2318                let right = self.parse_unary()?;
2319                left = Expr::BinaryOp {
2320                    left: Box::new(left),
2321                    op,
2322                    right: Box::new(right),
2323                };
2324            } else {
2325                break;
2326            }
2327        }
2328        Ok(left)
2329    }
2330
2331    fn parse_unary(&mut self) -> Result<Expr> {
2332        match self.peek_type() {
2333            TokenType::Minus => {
2334                self.advance();
2335                let expr = self.parse_postfix()?;
2336                Ok(Expr::UnaryOp {
2337                    op: UnaryOperator::Minus,
2338                    expr: Box::new(expr),
2339                })
2340            }
2341            TokenType::Plus => {
2342                self.advance();
2343                let expr = self.parse_postfix()?;
2344                Ok(Expr::UnaryOp {
2345                    op: UnaryOperator::Plus,
2346                    expr: Box::new(expr),
2347                })
2348            }
2349            TokenType::BitwiseNot => {
2350                self.advance();
2351                let expr = self.parse_postfix()?;
2352                Ok(Expr::UnaryOp {
2353                    op: UnaryOperator::BitwiseNot,
2354                    expr: Box::new(expr),
2355                })
2356            }
2357            _ => self.parse_postfix(),
2358        }
2359    }
2360
2361    /// Parse postfix operators: `::type`, `[index]`, `->`, `->>`
2362    fn parse_postfix(&mut self) -> Result<Expr> {
2363        let mut expr = self.parse_primary()?;
2364
2365        loop {
2366            if self.match_token(TokenType::DoubleColon) {
2367                // PostgreSQL-style cast: expr::type
2368                let data_type = self.parse_data_type()?;
2369                expr = Expr::Cast {
2370                    expr: Box::new(expr),
2371                    data_type,
2372                };
2373            } else if self.match_token(TokenType::LBracket) {
2374                // Array index: expr[index]
2375                let index = self.parse_expr()?;
2376                self.expect(TokenType::RBracket)?;
2377                expr = Expr::ArrayIndex {
2378                    expr: Box::new(expr),
2379                    index: Box::new(index),
2380                };
2381            } else if self.match_token(TokenType::Arrow) {
2382                let path = self.parse_primary()?;
2383                expr = Expr::JsonAccess {
2384                    expr: Box::new(expr),
2385                    path: Box::new(path),
2386                    as_text: false,
2387                };
2388            } else if self.match_token(TokenType::DoubleArrow) {
2389                let path = self.parse_primary()?;
2390                expr = Expr::JsonAccess {
2391                    expr: Box::new(expr),
2392                    path: Box::new(path),
2393                    as_text: true,
2394                };
2395            } else {
2396                break;
2397            }
2398        }
2399
2400        // Check for window function: expr OVER (...)
2401        if self.match_token(TokenType::Over) {
2402            let spec = if self.match_token(TokenType::LParen) {
2403                let ws = self.parse_window_spec()?;
2404                self.expect(TokenType::RParen)?;
2405                ws
2406            } else {
2407                // Named window reference
2408                let wref = self.expect_name()?;
2409                WindowSpec {
2410                    window_ref: Some(wref),
2411                    partition_by: vec![],
2412                    order_by: vec![],
2413                    frame: None,
2414                }
2415            };
2416            match expr {
2417                Expr::Function {
2418                    name,
2419                    args,
2420                    distinct,
2421                    filter,
2422                    ..
2423                } => {
2424                    expr = Expr::Function {
2425                        name,
2426                        args,
2427                        distinct,
2428                        filter,
2429                        over: Some(spec),
2430                    };
2431                }
2432                Expr::TypedFunction { func, filter, .. } => {
2433                    expr = Expr::TypedFunction {
2434                        func,
2435                        filter,
2436                        over: Some(spec),
2437                    };
2438                }
2439                _ => {}
2440            }
2441        }
2442
2443        // FILTER (WHERE ...) for aggregate functions
2444        if self.match_token(TokenType::Filter) {
2445            self.expect(TokenType::LParen)?;
2446            self.expect(TokenType::Where)?;
2447            let filter_expr = self.parse_expr()?;
2448            self.expect(TokenType::RParen)?;
2449            match expr {
2450                Expr::Function {
2451                    name,
2452                    args,
2453                    distinct,
2454                    over,
2455                    ..
2456                } => {
2457                    expr = Expr::Function {
2458                        name,
2459                        args,
2460                        distinct,
2461                        filter: Some(Box::new(filter_expr)),
2462                        over,
2463                    };
2464                }
2465                Expr::TypedFunction { func, over, .. } => {
2466                    expr = Expr::TypedFunction {
2467                        func,
2468                        filter: Some(Box::new(filter_expr)),
2469                        over,
2470                    };
2471                }
2472                _ => {}
2473            }
2474        }
2475
2476        Ok(expr)
2477    }
2478
2479    fn parse_window_spec(&mut self) -> Result<WindowSpec> {
2480        let window_ref = if self.is_name_token()
2481            && !matches!(
2482                self.peek_type(),
2483                TokenType::Partition | TokenType::Order | TokenType::Rows | TokenType::Range
2484            ) {
2485            let saved = self.pos;
2486            let name = self.expect_name()?;
2487            // Check if it's actually a keyword we need
2488            if matches!(
2489                self.peek_type(),
2490                TokenType::RParen
2491                    | TokenType::Partition
2492                    | TokenType::Order
2493                    | TokenType::Rows
2494                    | TokenType::Range
2495            ) {
2496                Some(name)
2497            } else {
2498                self.pos = saved;
2499                None
2500            }
2501        } else {
2502            None
2503        };
2504
2505        let partition_by = if self.match_token(TokenType::Partition) {
2506            self.expect(TokenType::By)?;
2507            self.parse_expr_list()?
2508        } else {
2509            vec![]
2510        };
2511
2512        let order_by = if self.match_token(TokenType::Order) {
2513            self.expect(TokenType::By)?;
2514            self.parse_order_by_items()?
2515        } else {
2516            vec![]
2517        };
2518
2519        let frame = if matches!(self.peek_type(), TokenType::Rows | TokenType::Range) {
2520            Some(self.parse_window_frame()?)
2521        } else {
2522            None
2523        };
2524
2525        Ok(WindowSpec {
2526            window_ref,
2527            partition_by,
2528            order_by,
2529            frame,
2530        })
2531    }
2532
2533    fn parse_window_frame(&mut self) -> Result<WindowFrame> {
2534        let kind = if self.match_token(TokenType::Rows) {
2535            WindowFrameKind::Rows
2536        } else if self.match_token(TokenType::Range) {
2537            WindowFrameKind::Range
2538        } else {
2539            WindowFrameKind::Rows
2540        };
2541
2542        if self.match_keyword("BETWEEN") {
2543            let start = self.parse_window_frame_bound()?;
2544            self.expect(TokenType::And)?;
2545            let end = self.parse_window_frame_bound()?;
2546            Ok(WindowFrame {
2547                kind,
2548                start,
2549                end: Some(end),
2550            })
2551        } else {
2552            let start = self.parse_window_frame_bound()?;
2553            Ok(WindowFrame {
2554                kind,
2555                start,
2556                end: None,
2557            })
2558        }
2559    }
2560
2561    fn parse_window_frame_bound(&mut self) -> Result<WindowFrameBound> {
2562        if self.check_keyword("CURRENT") {
2563            self.advance();
2564            let _ = self.match_keyword("ROW");
2565            Ok(WindowFrameBound::CurrentRow)
2566        } else if self.match_token(TokenType::Unbounded) {
2567            if self.match_token(TokenType::Preceding) {
2568                Ok(WindowFrameBound::Preceding(None))
2569            } else {
2570                self.expect(TokenType::Following)?;
2571                Ok(WindowFrameBound::Following(None))
2572            }
2573        } else {
2574            let n = self.parse_expr()?;
2575            if self.match_token(TokenType::Preceding) {
2576                Ok(WindowFrameBound::Preceding(Some(Box::new(n))))
2577            } else {
2578                self.expect(TokenType::Following)?;
2579                Ok(WindowFrameBound::Following(Some(Box::new(n))))
2580            }
2581        }
2582    }
2583
2584    fn parse_primary(&mut self) -> Result<Expr> {
2585        let token = self.peek().clone();
2586
2587        match &token.token_type {
2588            TokenType::Number => {
2589                self.advance();
2590                Ok(Expr::Number(token.value))
2591            }
2592            TokenType::String => {
2593                self.advance();
2594                Ok(Expr::StringLiteral(token.value))
2595            }
2596            TokenType::True => {
2597                self.advance();
2598                Ok(Expr::Boolean(true))
2599            }
2600            TokenType::False => {
2601                self.advance();
2602                Ok(Expr::Boolean(false))
2603            }
2604            TokenType::Null => {
2605                self.advance();
2606                Ok(Expr::Null)
2607            }
2608            TokenType::Default => {
2609                self.advance();
2610                Ok(Expr::Default)
2611            }
2612            TokenType::Star => {
2613                self.advance();
2614                Ok(Expr::Wildcard)
2615            }
2616            TokenType::Parameter => {
2617                self.advance();
2618                Ok(Expr::Parameter(token.value))
2619            }
2620
2621            // ── CAST ────────────────────────────────────────────────
2622            TokenType::Cast => {
2623                self.advance();
2624                self.expect(TokenType::LParen)?;
2625                let expr = self.parse_expr()?;
2626                self.expect(TokenType::As)?;
2627                let data_type = self.parse_data_type()?;
2628                self.expect(TokenType::RParen)?;
2629                Ok(Expr::Cast {
2630                    expr: Box::new(expr),
2631                    data_type,
2632                })
2633            }
2634
2635            // ── EXTRACT ─────────────────────────────────────────────
2636            TokenType::Extract => {
2637                self.advance();
2638                self.expect(TokenType::LParen)?;
2639                let field = self.parse_datetime_field()?;
2640                self.expect(TokenType::From)?;
2641                let expr = self.parse_expr()?;
2642                self.expect(TokenType::RParen)?;
2643                Ok(Expr::Extract {
2644                    field,
2645                    expr: Box::new(expr),
2646                })
2647            }
2648
2649            // ── CASE ────────────────────────────────────────────────
2650            TokenType::Case => self.parse_case_expr(),
2651
2652            // ── EXISTS ──────────────────────────────────────────────
2653            TokenType::Exists => {
2654                self.advance();
2655                self.expect(TokenType::LParen)?;
2656                let subquery = self.parse_statement_inner()?;
2657                self.expect(TokenType::RParen)?;
2658                Ok(Expr::Exists {
2659                    subquery: Box::new(subquery),
2660                    negated: false,
2661                })
2662            }
2663
2664            // ── NOT EXISTS ──────────────────────────────────────────
2665            TokenType::Not
2666                if {
2667                    let next_pos = self.pos + 1;
2668                    next_pos < self.tokens.len()
2669                        && self.tokens[next_pos].token_type == TokenType::Exists
2670                } =>
2671            {
2672                self.advance(); // NOT
2673                self.advance(); // EXISTS
2674                self.expect(TokenType::LParen)?;
2675                let subquery = self.parse_statement_inner()?;
2676                self.expect(TokenType::RParen)?;
2677                Ok(Expr::Exists {
2678                    subquery: Box::new(subquery),
2679                    negated: true,
2680                })
2681            }
2682
2683            // ── INTERVAL ────────────────────────────────────────────
2684            TokenType::Interval => {
2685                self.advance();
2686                let value = self.parse_primary()?;
2687                let unit = self.try_parse_datetime_field();
2688                Ok(Expr::Interval {
2689                    value: Box::new(value),
2690                    unit,
2691                })
2692            }
2693
2694            // ── Parenthesized expression or subquery ────────────────
2695            TokenType::LParen => {
2696                self.advance();
2697                // Check for subquery
2698                if matches!(self.peek_type(), TokenType::Select | TokenType::With) {
2699                    let subquery = self.parse_statement_inner()?;
2700                    self.expect(TokenType::RParen)?;
2701                    Ok(Expr::Subquery(Box::new(subquery)))
2702                } else {
2703                    let expr = self.parse_expr()?;
2704                    // Tuple: (a, b, c)
2705                    if self.match_token(TokenType::Comma) {
2706                        let mut items = vec![expr];
2707                        items.push(self.parse_expr()?);
2708                        while self.match_token(TokenType::Comma) {
2709                            items.push(self.parse_expr()?);
2710                        }
2711                        self.expect(TokenType::RParen)?;
2712                        Ok(Expr::Tuple(items))
2713                    } else {
2714                        self.expect(TokenType::RParen)?;
2715                        Ok(Expr::Nested(Box::new(expr)))
2716                    }
2717                }
2718            }
2719
2720            // ── Array literal: ARRAY[...] ──────────────────────────
2721            TokenType::Array => {
2722                self.advance();
2723                if self.match_token(TokenType::LBracket) {
2724                    let items = if self.peek_type() != &TokenType::RBracket {
2725                        self.parse_expr_list()?
2726                    } else {
2727                        vec![]
2728                    };
2729                    self.expect(TokenType::RBracket)?;
2730                    Ok(Expr::ArrayLiteral(items))
2731                } else if self.match_token(TokenType::LParen) {
2732                    // ARRAY(SELECT ...)
2733                    let subquery = self.parse_statement_inner()?;
2734                    self.expect(TokenType::RParen)?;
2735                    Ok(Expr::Subquery(Box::new(subquery)))
2736                } else {
2737                    Ok(Expr::Column {
2738                        table: None,
2739                        name: "ARRAY".to_string(),
2740                        quote_style: QuoteStyle::None,
2741                        table_quote_style: QuoteStyle::None,
2742                    })
2743                }
2744            }
2745
2746            // ── Bracket array literal: [...] ────────────────────────
2747            TokenType::LBracket => {
2748                self.advance();
2749                let items = if self.peek_type() != &TokenType::RBracket {
2750                    self.parse_expr_list()?
2751                } else {
2752                    vec![]
2753                };
2754                self.expect(TokenType::RBracket)?;
2755                Ok(Expr::ArrayLiteral(items))
2756            }
2757
2758            // ── Identifier: column ref, function call, or qualified name ─
2759            _ if self.is_name_token() || self.is_data_type_token() => {
2760                let name_token = self.advance().clone();
2761                let name = name_token.value.clone();
2762                let name_qs = quote_style_from_char(name_token.quote_char);
2763
2764                // Function call: name(...)
2765                if self.peek_type() == &TokenType::LParen {
2766                    self.advance();
2767
2768                    // Special: COUNT(*), COUNT(DISTINCT x)
2769                    let distinct = self.match_token(TokenType::Distinct);
2770
2771                    let args = if self.peek_type() == &TokenType::RParen {
2772                        vec![]
2773                    } else if self.peek_type() == &TokenType::Star {
2774                        self.advance();
2775                        vec![Expr::Wildcard]
2776                    } else {
2777                        self.parse_expr_list()?
2778                    };
2779                    self.expect(TokenType::RParen)?;
2780
2781                    // Try to construct a typed function variant
2782                    if let Some(typed) = Self::try_typed_function(&name, args.clone(), distinct) {
2783                        Ok(typed)
2784                    } else {
2785                        Ok(Expr::Function {
2786                            name,
2787                            args,
2788                            distinct,
2789                            filter: None,
2790                            over: None,
2791                        })
2792                    }
2793                }
2794                // Qualified column: table.column or table.*
2795                else if self.match_token(TokenType::Dot) {
2796                    if self.peek_type() == &TokenType::Star {
2797                        self.advance();
2798                        Ok(Expr::QualifiedWildcard { table: name })
2799                    } else {
2800                        let (col, col_qs) = self.expect_name_with_quote()?;
2801                        Ok(Expr::Column {
2802                            table: Some(name),
2803                            name: col,
2804                            quote_style: col_qs,
2805                            table_quote_style: name_qs,
2806                        })
2807                    }
2808                } else {
2809                    Ok(Expr::Column {
2810                        table: None,
2811                        name,
2812                        quote_style: name_qs,
2813                        table_quote_style: QuoteStyle::None,
2814                    })
2815                }
2816            }
2817
2818            _ => Err(SqlglotError::UnexpectedToken { token }),
2819        }
2820    }
2821
2822    fn is_data_type_token(&self) -> bool {
2823        matches!(
2824            self.peek_type(),
2825            TokenType::Int
2826                | TokenType::Integer
2827                | TokenType::BigInt
2828                | TokenType::SmallInt
2829                | TokenType::TinyInt
2830                | TokenType::Float
2831                | TokenType::Double
2832                | TokenType::Decimal
2833                | TokenType::Numeric
2834                | TokenType::Real
2835                | TokenType::Varchar
2836                | TokenType::Char
2837                | TokenType::Text
2838                | TokenType::Boolean
2839                | TokenType::Date
2840                | TokenType::Timestamp
2841                | TokenType::TimestampTz
2842                | TokenType::Time
2843                | TokenType::Interval
2844                | TokenType::Blob
2845                | TokenType::Bytea
2846                | TokenType::Json
2847                | TokenType::Jsonb
2848                | TokenType::Uuid
2849                | TokenType::Array
2850                | TokenType::Map
2851                | TokenType::Struct
2852        )
2853    }
2854
2855    fn parse_datetime_field(&mut self) -> Result<DateTimeField> {
2856        let token = self.peek().clone();
2857        let field = match &token.token_type {
2858            TokenType::Year => DateTimeField::Year,
2859            TokenType::Month => DateTimeField::Month,
2860            TokenType::Day => DateTimeField::Day,
2861            TokenType::Hour => DateTimeField::Hour,
2862            TokenType::Minute => DateTimeField::Minute,
2863            TokenType::Second => DateTimeField::Second,
2864            TokenType::Epoch => DateTimeField::Epoch,
2865            _ => {
2866                let name = token.value.to_uppercase();
2867                match name.as_str() {
2868                    "YEAR" => DateTimeField::Year,
2869                    "QUARTER" => DateTimeField::Quarter,
2870                    "MONTH" => DateTimeField::Month,
2871                    "WEEK" => DateTimeField::Week,
2872                    "DAY" => DateTimeField::Day,
2873                    "DOW" | "DAYOFWEEK" => DateTimeField::DayOfWeek,
2874                    "DOY" | "DAYOFYEAR" => DateTimeField::DayOfYear,
2875                    "HOUR" => DateTimeField::Hour,
2876                    "MINUTE" => DateTimeField::Minute,
2877                    "SECOND" => DateTimeField::Second,
2878                    "MILLISECOND" => DateTimeField::Millisecond,
2879                    "MICROSECOND" => DateTimeField::Microsecond,
2880                    "NANOSECOND" => DateTimeField::Nanosecond,
2881                    "EPOCH" => DateTimeField::Epoch,
2882                    "TIMEZONE" => DateTimeField::Timezone,
2883                    "TIMEZONE_HOUR" => DateTimeField::TimezoneHour,
2884                    "TIMEZONE_MINUTE" => DateTimeField::TimezoneMinute,
2885                    _ => {
2886                        return Err(SqlglotError::ParserError {
2887                            message: format!("Unknown datetime field: {name}"),
2888                        });
2889                    }
2890                }
2891            }
2892        };
2893        self.advance();
2894        Ok(field)
2895    }
2896
2897    fn try_parse_datetime_field(&mut self) -> Option<DateTimeField> {
2898        let saved = self.pos;
2899        match self.parse_datetime_field() {
2900            Ok(field) => Some(field),
2901            Err(_) => {
2902                self.pos = saved;
2903                None
2904            }
2905        }
2906    }
2907
2908    /// Try to construct a typed function expression from a parsed function call.
2909    /// Returns `None` if the function name is not recognized, falling back to
2910    /// the generic `Expr::Function`.
2911    fn try_typed_function(name: &str, args: Vec<Expr>, distinct: bool) -> Option<Expr> {
2912        let upper = name.to_uppercase();
2913        let tf = match upper.as_str() {
2914            // ── Date/Time ──────────────────────────────────────────
2915            "DATE_ADD" | "DATEADD" | "TIMESTAMPADD" => {
2916                let mut it = args.into_iter();
2917                let first = it.next()?;
2918                let second = it.next()?;
2919                let third = it.next();
2920                // Handle DATEADD(unit, interval, expr) — TSQL/Snowflake arg order
2921                if upper == "DATEADD" {
2922                    if let Some(third_arg) = third {
2923                        // 3-arg: DATEADD(unit, interval, expr)
2924                        let unit = Self::expr_to_datetime_field(&first);
2925                        TypedFunction::DateAdd {
2926                            expr: Box::new(third_arg),
2927                            interval: Box::new(second),
2928                            unit,
2929                        }
2930                    } else {
2931                        TypedFunction::DateAdd {
2932                            expr: Box::new(first),
2933                            interval: Box::new(second),
2934                            unit: None,
2935                        }
2936                    }
2937                } else {
2938                    // DATE_ADD(expr, interval [, unit])
2939                    let unit = third.as_ref().and_then(Self::expr_to_datetime_field);
2940                    TypedFunction::DateAdd {
2941                        expr: Box::new(first),
2942                        interval: Box::new(second),
2943                        unit,
2944                    }
2945                }
2946            }
2947            "DATE_DIFF" | "DATEDIFF" | "TIMESTAMPDIFF" => {
2948                let mut it = args.into_iter();
2949                let first = it.next()?;
2950                let second = it.next()?;
2951                let third = it.next();
2952                if let Some(third_arg) = third {
2953                    if upper == "DATEDIFF" {
2954                        // DATEDIFF(unit, start, end) — TSQL/Snowflake
2955                        let unit = Self::expr_to_datetime_field(&first);
2956                        TypedFunction::DateDiff {
2957                            start: Box::new(second),
2958                            end: Box::new(third_arg),
2959                            unit,
2960                        }
2961                    } else {
2962                        let unit = Self::expr_to_datetime_field(&third_arg);
2963                        TypedFunction::DateDiff {
2964                            start: Box::new(first),
2965                            end: Box::new(second),
2966                            unit,
2967                        }
2968                    }
2969                } else {
2970                    TypedFunction::DateDiff {
2971                        start: Box::new(first),
2972                        end: Box::new(second),
2973                        unit: None,
2974                    }
2975                }
2976            }
2977            "DATE_TRUNC" | "DATETRUNC" => {
2978                let mut it = args.into_iter();
2979                let first = it.next()?;
2980                let second = it.next()?;
2981                // DATE_TRUNC('unit', expr) or DATE_TRUNC(unit, expr)
2982                let (unit, expr) = if let Some(u) = Self::expr_to_datetime_field(&first) {
2983                    (u, second)
2984                } else if let Some(u) = Self::expr_to_datetime_field(&second) {
2985                    (u, first)
2986                } else {
2987                    // Default: first = unit string, second = expr
2988                    return None;
2989                };
2990                TypedFunction::DateTrunc {
2991                    unit,
2992                    expr: Box::new(expr),
2993                }
2994            }
2995            "DATE_SUB" | "DATESUB" => {
2996                let mut it = args.into_iter();
2997                let first = it.next()?;
2998                let second = it.next()?;
2999                let third = it.next();
3000                let unit = third.as_ref().and_then(Self::expr_to_datetime_field);
3001                TypedFunction::DateSub {
3002                    expr: Box::new(first),
3003                    interval: Box::new(second),
3004                    unit,
3005                }
3006            }
3007            "CURRENT_DATE" => TypedFunction::CurrentDate,
3008            "CURRENT_TIMESTAMP" | "NOW" | "GETDATE" | "SYSDATE" => TypedFunction::CurrentTimestamp,
3009            "STR_TO_TIME" | "STR_TO_DATE" | "TO_TIMESTAMP" | "PARSE_TIMESTAMP"
3010            | "PARSE_DATETIME" => {
3011                let mut it = args.into_iter();
3012                let expr = it.next()?;
3013                let format = it.next()?;
3014                TypedFunction::StrToTime {
3015                    expr: Box::new(expr),
3016                    format: Box::new(format),
3017                }
3018            }
3019            "TIME_TO_STR" | "DATE_FORMAT" | "FORMAT_TIMESTAMP" | "FORMAT_DATETIME" | "TO_CHAR" => {
3020                let mut it = args.into_iter();
3021                let expr = it.next()?;
3022                let format = it.next()?;
3023                TypedFunction::TimeToStr {
3024                    expr: Box::new(expr),
3025                    format: Box::new(format),
3026                }
3027            }
3028            "TS_OR_DS_TO_DATE" => {
3029                let mut it = args.into_iter();
3030                TypedFunction::TsOrDsToDate {
3031                    expr: Box::new(it.next()?),
3032                }
3033            }
3034            "YEAR" => {
3035                let mut it = args.into_iter();
3036                TypedFunction::Year {
3037                    expr: Box::new(it.next()?),
3038                }
3039            }
3040            "MONTH" => {
3041                let mut it = args.into_iter();
3042                TypedFunction::Month {
3043                    expr: Box::new(it.next()?),
3044                }
3045            }
3046            "DAY" | "DAYOFMONTH" => {
3047                let mut it = args.into_iter();
3048                TypedFunction::Day {
3049                    expr: Box::new(it.next()?),
3050                }
3051            }
3052
3053            // ── String ─────────────────────────────────────────────
3054            "TRIM" => {
3055                let mut it = args.into_iter();
3056                let expr = it.next()?;
3057                TypedFunction::Trim {
3058                    expr: Box::new(expr),
3059                    trim_type: TrimType::Both,
3060                    trim_chars: None,
3061                }
3062            }
3063            "LTRIM" => {
3064                let mut it = args.into_iter();
3065                let expr = it.next()?;
3066                TypedFunction::Trim {
3067                    expr: Box::new(expr),
3068                    trim_type: TrimType::Leading,
3069                    trim_chars: None,
3070                }
3071            }
3072            "RTRIM" => {
3073                let mut it = args.into_iter();
3074                let expr = it.next()?;
3075                TypedFunction::Trim {
3076                    expr: Box::new(expr),
3077                    trim_type: TrimType::Trailing,
3078                    trim_chars: None,
3079                }
3080            }
3081            "SUBSTRING" | "SUBSTR" => {
3082                let mut it = args.into_iter();
3083                let expr = it.next()?;
3084                let start = it.next()?;
3085                let length = it.next();
3086                TypedFunction::Substring {
3087                    expr: Box::new(expr),
3088                    start: Box::new(start),
3089                    length: length.map(Box::new),
3090                }
3091            }
3092            "UPPER" | "UCASE" => {
3093                let mut it = args.into_iter();
3094                TypedFunction::Upper {
3095                    expr: Box::new(it.next()?),
3096                }
3097            }
3098            "LOWER" | "LCASE" => {
3099                let mut it = args.into_iter();
3100                TypedFunction::Lower {
3101                    expr: Box::new(it.next()?),
3102                }
3103            }
3104            "REGEXP_LIKE" | "RLIKE" => {
3105                let mut it = args.into_iter();
3106                let expr = it.next()?;
3107                let pattern = it.next()?;
3108                let flags = it.next();
3109                TypedFunction::RegexpLike {
3110                    expr: Box::new(expr),
3111                    pattern: Box::new(pattern),
3112                    flags: flags.map(Box::new),
3113                }
3114            }
3115            "REGEXP_EXTRACT" | "REGEXP_SUBSTR" => {
3116                let mut it = args.into_iter();
3117                let expr = it.next()?;
3118                let pattern = it.next()?;
3119                let group_index = it.next();
3120                TypedFunction::RegexpExtract {
3121                    expr: Box::new(expr),
3122                    pattern: Box::new(pattern),
3123                    group_index: group_index.map(Box::new),
3124                }
3125            }
3126            "REGEXP_REPLACE" => {
3127                let mut it = args.into_iter();
3128                let expr = it.next()?;
3129                let pattern = it.next()?;
3130                let replacement = it.next()?;
3131                let flags = it.next();
3132                TypedFunction::RegexpReplace {
3133                    expr: Box::new(expr),
3134                    pattern: Box::new(pattern),
3135                    replacement: Box::new(replacement),
3136                    flags: flags.map(Box::new),
3137                }
3138            }
3139            "CONCAT_WS" => {
3140                let mut it = args.into_iter();
3141                let separator = it.next()?;
3142                let exprs: Vec<Expr> = it.collect();
3143                TypedFunction::ConcatWs {
3144                    separator: Box::new(separator),
3145                    exprs,
3146                }
3147            }
3148            "SPLIT" | "STRING_SPLIT" => {
3149                let mut it = args.into_iter();
3150                let expr = it.next()?;
3151                let delimiter = it.next()?;
3152                TypedFunction::Split {
3153                    expr: Box::new(expr),
3154                    delimiter: Box::new(delimiter),
3155                }
3156            }
3157            "INITCAP" => {
3158                let mut it = args.into_iter();
3159                TypedFunction::Initcap {
3160                    expr: Box::new(it.next()?),
3161                }
3162            }
3163            "LENGTH" | "LEN" | "CHAR_LENGTH" | "CHARACTER_LENGTH" => {
3164                let mut it = args.into_iter();
3165                TypedFunction::Length {
3166                    expr: Box::new(it.next()?),
3167                }
3168            }
3169            "REPLACE" => {
3170                let mut it = args.into_iter();
3171                let expr = it.next()?;
3172                let from = it.next()?;
3173                let to = it.next()?;
3174                TypedFunction::Replace {
3175                    expr: Box::new(expr),
3176                    from: Box::new(from),
3177                    to: Box::new(to),
3178                }
3179            }
3180            "REVERSE" => {
3181                let mut it = args.into_iter();
3182                TypedFunction::Reverse {
3183                    expr: Box::new(it.next()?),
3184                }
3185            }
3186            "LEFT" => {
3187                let mut it = args.into_iter();
3188                let expr = it.next()?;
3189                let n = it.next()?;
3190                TypedFunction::Left {
3191                    expr: Box::new(expr),
3192                    n: Box::new(n),
3193                }
3194            }
3195            "RIGHT" => {
3196                let mut it = args.into_iter();
3197                let expr = it.next()?;
3198                let n = it.next()?;
3199                TypedFunction::Right {
3200                    expr: Box::new(expr),
3201                    n: Box::new(n),
3202                }
3203            }
3204            "LPAD" => {
3205                let mut it = args.into_iter();
3206                let expr = it.next()?;
3207                let length = it.next()?;
3208                let pad = it.next();
3209                TypedFunction::Lpad {
3210                    expr: Box::new(expr),
3211                    length: Box::new(length),
3212                    pad: pad.map(Box::new),
3213                }
3214            }
3215            "RPAD" => {
3216                let mut it = args.into_iter();
3217                let expr = it.next()?;
3218                let length = it.next()?;
3219                let pad = it.next();
3220                TypedFunction::Rpad {
3221                    expr: Box::new(expr),
3222                    length: Box::new(length),
3223                    pad: pad.map(Box::new),
3224                }
3225            }
3226
3227            // ── Aggregate ──────────────────────────────────────────
3228            "COUNT" => {
3229                let mut it = args.into_iter();
3230                let expr = it.next().unwrap_or(Expr::Wildcard);
3231                TypedFunction::Count {
3232                    expr: Box::new(expr),
3233                    distinct,
3234                }
3235            }
3236            "SUM" => {
3237                let mut it = args.into_iter();
3238                TypedFunction::Sum {
3239                    expr: Box::new(it.next()?),
3240                    distinct,
3241                }
3242            }
3243            "AVG" => {
3244                let mut it = args.into_iter();
3245                TypedFunction::Avg {
3246                    expr: Box::new(it.next()?),
3247                    distinct,
3248                }
3249            }
3250            "MIN" => {
3251                let mut it = args.into_iter();
3252                TypedFunction::Min {
3253                    expr: Box::new(it.next()?),
3254                }
3255            }
3256            "MAX" => {
3257                let mut it = args.into_iter();
3258                TypedFunction::Max {
3259                    expr: Box::new(it.next()?),
3260                }
3261            }
3262            "ARRAY_AGG" | "LIST" | "COLLECT_LIST" => {
3263                let mut it = args.into_iter();
3264                TypedFunction::ArrayAgg {
3265                    expr: Box::new(it.next()?),
3266                    distinct,
3267                }
3268            }
3269            "APPROX_DISTINCT" | "APPROX_COUNT_DISTINCT" => {
3270                let mut it = args.into_iter();
3271                TypedFunction::ApproxDistinct {
3272                    expr: Box::new(it.next()?),
3273                }
3274            }
3275            "VARIANCE" | "VAR_SAMP" | "VAR" => {
3276                let mut it = args.into_iter();
3277                TypedFunction::Variance {
3278                    expr: Box::new(it.next()?),
3279                }
3280            }
3281            "STDDEV" | "STDDEV_SAMP" => {
3282                let mut it = args.into_iter();
3283                TypedFunction::Stddev {
3284                    expr: Box::new(it.next()?),
3285                }
3286            }
3287
3288            // ── Array ──────────────────────────────────────────────
3289            "ARRAY_CONCAT" | "ARRAY_CAT" => TypedFunction::ArrayConcat { arrays: args },
3290            "ARRAY_CONTAINS" => {
3291                let mut it = args.into_iter();
3292                let array = it.next()?;
3293                let element = it.next()?;
3294                TypedFunction::ArrayContains {
3295                    array: Box::new(array),
3296                    element: Box::new(element),
3297                }
3298            }
3299            "ARRAY_SIZE" | "ARRAY_LENGTH" | "CARDINALITY" => {
3300                let mut it = args.into_iter();
3301                TypedFunction::ArraySize {
3302                    expr: Box::new(it.next()?),
3303                }
3304            }
3305            "EXPLODE" => {
3306                let mut it = args.into_iter();
3307                TypedFunction::Explode {
3308                    expr: Box::new(it.next()?),
3309                }
3310            }
3311            "GENERATE_SERIES" | "SEQUENCE" => {
3312                let mut it = args.into_iter();
3313                let start = it.next()?;
3314                let stop = it.next()?;
3315                let step = it.next();
3316                TypedFunction::GenerateSeries {
3317                    start: Box::new(start),
3318                    stop: Box::new(stop),
3319                    step: step.map(Box::new),
3320                }
3321            }
3322            "FLATTEN" => {
3323                let mut it = args.into_iter();
3324                TypedFunction::Flatten {
3325                    expr: Box::new(it.next()?),
3326                }
3327            }
3328
3329            // ── JSON ───────────────────────────────────────────────
3330            "JSON_EXTRACT" | "JSON_VALUE" => {
3331                let mut it = args.into_iter();
3332                let expr = it.next()?;
3333                let path = it.next()?;
3334                TypedFunction::JSONExtract {
3335                    expr: Box::new(expr),
3336                    path: Box::new(path),
3337                }
3338            }
3339            "JSON_EXTRACT_SCALAR" => {
3340                let mut it = args.into_iter();
3341                let expr = it.next()?;
3342                let path = it.next()?;
3343                TypedFunction::JSONExtractScalar {
3344                    expr: Box::new(expr),
3345                    path: Box::new(path),
3346                }
3347            }
3348            "PARSE_JSON" | "JSON_PARSE" => {
3349                let mut it = args.into_iter();
3350                TypedFunction::ParseJSON {
3351                    expr: Box::new(it.next()?),
3352                }
3353            }
3354            "JSON_FORMAT" | "TO_JSON" | "TO_JSON_STRING" => {
3355                let mut it = args.into_iter();
3356                TypedFunction::JSONFormat {
3357                    expr: Box::new(it.next()?),
3358                }
3359            }
3360
3361            // ── Window ─────────────────────────────────────────────
3362            "ROW_NUMBER" => TypedFunction::RowNumber,
3363            "RANK" => TypedFunction::Rank,
3364            "DENSE_RANK" => TypedFunction::DenseRank,
3365            "NTILE" => {
3366                let mut it = args.into_iter();
3367                TypedFunction::NTile {
3368                    n: Box::new(it.next()?),
3369                }
3370            }
3371            "LEAD" => {
3372                let mut it = args.into_iter();
3373                let expr = it.next()?;
3374                let offset = it.next();
3375                let default = it.next();
3376                TypedFunction::Lead {
3377                    expr: Box::new(expr),
3378                    offset: offset.map(Box::new),
3379                    default: default.map(Box::new),
3380                }
3381            }
3382            "LAG" => {
3383                let mut it = args.into_iter();
3384                let expr = it.next()?;
3385                let offset = it.next();
3386                let default = it.next();
3387                TypedFunction::Lag {
3388                    expr: Box::new(expr),
3389                    offset: offset.map(Box::new),
3390                    default: default.map(Box::new),
3391                }
3392            }
3393            "FIRST_VALUE" => {
3394                let mut it = args.into_iter();
3395                TypedFunction::FirstValue {
3396                    expr: Box::new(it.next()?),
3397                }
3398            }
3399            "LAST_VALUE" => {
3400                let mut it = args.into_iter();
3401                TypedFunction::LastValue {
3402                    expr: Box::new(it.next()?),
3403                }
3404            }
3405
3406            // ── Math ───────────────────────────────────────────────
3407            "ABS" => {
3408                let mut it = args.into_iter();
3409                TypedFunction::Abs {
3410                    expr: Box::new(it.next()?),
3411                }
3412            }
3413            "CEIL" | "CEILING" => {
3414                let mut it = args.into_iter();
3415                TypedFunction::Ceil {
3416                    expr: Box::new(it.next()?),
3417                }
3418            }
3419            "FLOOR" => {
3420                let mut it = args.into_iter();
3421                TypedFunction::Floor {
3422                    expr: Box::new(it.next()?),
3423                }
3424            }
3425            "ROUND" => {
3426                let mut it = args.into_iter();
3427                let expr = it.next()?;
3428                let decimals = it.next();
3429                TypedFunction::Round {
3430                    expr: Box::new(expr),
3431                    decimals: decimals.map(Box::new),
3432                }
3433            }
3434            "LOG" => {
3435                let mut it = args.into_iter();
3436                let expr = it.next()?;
3437                let base = it.next();
3438                TypedFunction::Log {
3439                    expr: Box::new(expr),
3440                    base: base.map(Box::new),
3441                }
3442            }
3443            "LN" => {
3444                let mut it = args.into_iter();
3445                TypedFunction::Ln {
3446                    expr: Box::new(it.next()?),
3447                }
3448            }
3449            "POW" | "POWER" => {
3450                let mut it = args.into_iter();
3451                let base = it.next()?;
3452                let exponent = it.next()?;
3453                TypedFunction::Pow {
3454                    base: Box::new(base),
3455                    exponent: Box::new(exponent),
3456                }
3457            }
3458            "SQRT" => {
3459                let mut it = args.into_iter();
3460                TypedFunction::Sqrt {
3461                    expr: Box::new(it.next()?),
3462                }
3463            }
3464            "GREATEST" => TypedFunction::Greatest { exprs: args },
3465            "LEAST" => TypedFunction::Least { exprs: args },
3466            "MOD" => {
3467                let mut it = args.into_iter();
3468                let left = it.next()?;
3469                let right = it.next()?;
3470                TypedFunction::Mod {
3471                    left: Box::new(left),
3472                    right: Box::new(right),
3473                }
3474            }
3475
3476            // ── Conversion ─────────────────────────────────────────
3477            "HEX" | "TO_HEX" => {
3478                let mut it = args.into_iter();
3479                TypedFunction::Hex {
3480                    expr: Box::new(it.next()?),
3481                }
3482            }
3483            "UNHEX" | "FROM_HEX" => {
3484                let mut it = args.into_iter();
3485                TypedFunction::Unhex {
3486                    expr: Box::new(it.next()?),
3487                }
3488            }
3489            "MD5" => {
3490                let mut it = args.into_iter();
3491                TypedFunction::Md5 {
3492                    expr: Box::new(it.next()?),
3493                }
3494            }
3495            "SHA" | "SHA1" => {
3496                let mut it = args.into_iter();
3497                TypedFunction::Sha {
3498                    expr: Box::new(it.next()?),
3499                }
3500            }
3501            "SHA2" | "SHA256" | "SHA512" => {
3502                let mut it = args.into_iter();
3503                let expr = it.next()?;
3504                let bit_length = it.next().unwrap_or(Expr::Number("256".to_string()));
3505                TypedFunction::Sha2 {
3506                    expr: Box::new(expr),
3507                    bit_length: Box::new(bit_length),
3508                }
3509            }
3510
3511            // Not a recognized typed function
3512            _ => return None,
3513        };
3514
3515        Some(Expr::TypedFunction {
3516            func: tf,
3517            filter: None,
3518            over: None,
3519        })
3520    }
3521
3522    /// Try to extract a DateTimeField from a column-name expression.
3523    fn expr_to_datetime_field(expr: &Expr) -> Option<DateTimeField> {
3524        match expr {
3525            Expr::Column {
3526                name, table: None, ..
3527            } => match name.to_uppercase().as_str() {
3528                "YEAR" => Some(DateTimeField::Year),
3529                "QUARTER" => Some(DateTimeField::Quarter),
3530                "MONTH" => Some(DateTimeField::Month),
3531                "WEEK" => Some(DateTimeField::Week),
3532                "DAY" => Some(DateTimeField::Day),
3533                "HOUR" => Some(DateTimeField::Hour),
3534                "MINUTE" => Some(DateTimeField::Minute),
3535                "SECOND" => Some(DateTimeField::Second),
3536                "MILLISECOND" => Some(DateTimeField::Millisecond),
3537                "MICROSECOND" => Some(DateTimeField::Microsecond),
3538                _ => None,
3539            },
3540            Expr::StringLiteral(s) => match s.to_uppercase().as_str() {
3541                "YEAR" => Some(DateTimeField::Year),
3542                "QUARTER" => Some(DateTimeField::Quarter),
3543                "MONTH" => Some(DateTimeField::Month),
3544                "WEEK" => Some(DateTimeField::Week),
3545                "DAY" => Some(DateTimeField::Day),
3546                "HOUR" => Some(DateTimeField::Hour),
3547                "MINUTE" => Some(DateTimeField::Minute),
3548                "SECOND" => Some(DateTimeField::Second),
3549                "MILLISECOND" => Some(DateTimeField::Millisecond),
3550                "MICROSECOND" => Some(DateTimeField::Microsecond),
3551                _ => None,
3552            },
3553            _ => None,
3554        }
3555    }
3556
3557    fn parse_case_expr(&mut self) -> Result<Expr> {
3558        self.expect(TokenType::Case)?;
3559
3560        let operand = if self.peek_type() != &TokenType::When {
3561            Some(Box::new(self.parse_expr()?))
3562        } else {
3563            None
3564        };
3565
3566        let mut when_clauses = Vec::new();
3567        while self.match_token(TokenType::When) {
3568            let condition = self.parse_expr()?;
3569            self.expect(TokenType::Then)?;
3570            let result = self.parse_expr()?;
3571            when_clauses.push((condition, result));
3572        }
3573
3574        let else_clause = if self.match_token(TokenType::Else) {
3575            Some(Box::new(self.parse_expr()?))
3576        } else {
3577            None
3578        };
3579
3580        self.expect(TokenType::End)?;
3581
3582        Ok(Expr::Case {
3583            operand,
3584            when_clauses,
3585            else_clause,
3586        })
3587    }
3588}
3589
3590#[cfg(test)]
3591mod tests {
3592    use super::*;
3593
3594    #[test]
3595    fn test_parse_simple_select() {
3596        let stmt = Parser::new("SELECT a, b FROM t")
3597            .unwrap()
3598            .parse_statement()
3599            .unwrap();
3600        match stmt {
3601            Statement::Select(sel) => {
3602                assert_eq!(sel.columns.len(), 2);
3603                assert!(sel.from.is_some());
3604            }
3605            _ => panic!("Expected SELECT"),
3606        }
3607    }
3608
3609    #[test]
3610    fn test_parse_select_with_where() {
3611        let stmt = Parser::new("SELECT x FROM t WHERE x > 10")
3612            .unwrap()
3613            .parse_statement()
3614            .unwrap();
3615        match stmt {
3616            Statement::Select(sel) => assert!(sel.where_clause.is_some()),
3617            _ => panic!("Expected SELECT"),
3618        }
3619    }
3620
3621    #[test]
3622    fn test_parse_select_wildcard() {
3623        let stmt = Parser::new("SELECT * FROM users")
3624            .unwrap()
3625            .parse_statement()
3626            .unwrap();
3627        match stmt {
3628            Statement::Select(sel) => {
3629                assert_eq!(sel.columns.len(), 1);
3630                assert!(matches!(sel.columns[0], SelectItem::Wildcard));
3631            }
3632            _ => panic!("Expected SELECT"),
3633        }
3634    }
3635
3636    #[test]
3637    fn test_parse_insert() {
3638        let stmt = Parser::new("INSERT INTO t (a, b) VALUES (1, 'hello')")
3639            .unwrap()
3640            .parse_statement()
3641            .unwrap();
3642        match stmt {
3643            Statement::Insert(ins) => {
3644                assert_eq!(ins.table.name, "t");
3645                assert_eq!(ins.columns, vec!["a", "b"]);
3646                match &ins.source {
3647                    InsertSource::Values(rows) => {
3648                        assert_eq!(rows.len(), 1);
3649                        assert_eq!(rows[0].len(), 2);
3650                    }
3651                    _ => panic!("Expected VALUES"),
3652                }
3653            }
3654            _ => panic!("Expected INSERT"),
3655        }
3656    }
3657
3658    #[test]
3659    fn test_parse_delete() {
3660        let stmt = Parser::new("DELETE FROM users WHERE id = 1")
3661            .unwrap()
3662            .parse_statement()
3663            .unwrap();
3664        match stmt {
3665            Statement::Delete(del) => {
3666                assert_eq!(del.table.name, "users");
3667                assert!(del.where_clause.is_some());
3668            }
3669            _ => panic!("Expected DELETE"),
3670        }
3671    }
3672
3673    #[test]
3674    fn test_parse_join() {
3675        let stmt = Parser::new("SELECT a.id, b.name FROM a INNER JOIN b ON a.id = b.a_id")
3676            .unwrap()
3677            .parse_statement()
3678            .unwrap();
3679        match stmt {
3680            Statement::Select(sel) => {
3681                assert_eq!(sel.joins.len(), 1);
3682                assert_eq!(sel.joins[0].join_type, JoinType::Inner);
3683            }
3684            _ => panic!("Expected SELECT"),
3685        }
3686    }
3687
3688    #[test]
3689    fn test_parse_cte() {
3690        let stmt = Parser::new("WITH cte AS (SELECT 1 AS x) SELECT x FROM cte")
3691            .unwrap()
3692            .parse_statement()
3693            .unwrap();
3694        match stmt {
3695            Statement::Select(sel) => {
3696                assert_eq!(sel.ctes.len(), 1);
3697                assert_eq!(sel.ctes[0].name, "cte");
3698            }
3699            _ => panic!("Expected SELECT"),
3700        }
3701    }
3702
3703    #[test]
3704    fn test_parse_union() {
3705        let stmt = Parser::new("SELECT 1 UNION ALL SELECT 2")
3706            .unwrap()
3707            .parse_statement()
3708            .unwrap();
3709        match stmt {
3710            Statement::SetOperation(sop) => {
3711                assert_eq!(sop.op, SetOperationType::Union);
3712                assert!(sop.all);
3713            }
3714            _ => panic!("Expected SetOperation"),
3715        }
3716    }
3717
3718    #[test]
3719    fn test_parse_cast() {
3720        let stmt = Parser::new("SELECT CAST(x AS INT) FROM t")
3721            .unwrap()
3722            .parse_statement()
3723            .unwrap();
3724        match stmt {
3725            Statement::Select(sel) => {
3726                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
3727                    assert!(matches!(expr, Expr::Cast { .. }));
3728                }
3729            }
3730            _ => panic!("Expected SELECT"),
3731        }
3732    }
3733
3734    #[test]
3735    fn test_parse_subquery() {
3736        let stmt = Parser::new("SELECT * FROM (SELECT 1 AS x) AS sub")
3737            .unwrap()
3738            .parse_statement()
3739            .unwrap();
3740        match stmt {
3741            Statement::Select(sel) => {
3742                if let Some(from) = &sel.from {
3743                    assert!(matches!(from.source, TableSource::Subquery { .. }));
3744                }
3745            }
3746            _ => panic!("Expected SELECT"),
3747        }
3748    }
3749
3750    #[test]
3751    fn test_parse_exists() {
3752        let stmt = Parser::new("SELECT * FROM t WHERE EXISTS (SELECT 1 FROM t2)")
3753            .unwrap()
3754            .parse_statement()
3755            .unwrap();
3756        match stmt {
3757            Statement::Select(sel) => {
3758                assert!(sel.where_clause.is_some());
3759            }
3760            _ => panic!("Expected SELECT"),
3761        }
3762    }
3763
3764    #[test]
3765    fn test_parse_window_function() {
3766        let stmt = Parser::new(
3767            "SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) FROM emp",
3768        )
3769        .unwrap()
3770        .parse_statement()
3771        .unwrap();
3772        match stmt {
3773            Statement::Select(sel) => {
3774                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
3775                    match expr {
3776                        Expr::TypedFunction { over, .. } => {
3777                            assert!(over.is_some());
3778                        }
3779                        Expr::Function { over, .. } => {
3780                            assert!(over.is_some());
3781                        }
3782                        _ => panic!("Expected function"),
3783                    }
3784                }
3785            }
3786            _ => panic!("Expected SELECT"),
3787        }
3788    }
3789
3790    #[test]
3791    fn test_parse_multiple_statements() {
3792        let stmts = Parser::new("SELECT 1; SELECT 2;")
3793            .unwrap()
3794            .parse_statements()
3795            .unwrap();
3796        assert_eq!(stmts.len(), 2);
3797    }
3798
3799    #[test]
3800    fn test_parse_insert_select() {
3801        let stmt = Parser::new("INSERT INTO t SELECT * FROM s")
3802            .unwrap()
3803            .parse_statement()
3804            .unwrap();
3805        match stmt {
3806            Statement::Insert(ins) => {
3807                assert!(matches!(ins.source, InsertSource::Query(_)));
3808            }
3809            _ => panic!("Expected INSERT"),
3810        }
3811    }
3812
3813    #[test]
3814    fn test_parse_create_table_constraints() {
3815        let stmt =
3816            Parser::new("CREATE TABLE t (id INT PRIMARY KEY, name VARCHAR(100) NOT NULL UNIQUE)")
3817                .unwrap()
3818                .parse_statement()
3819                .unwrap();
3820        match stmt {
3821            Statement::CreateTable(ct) => {
3822                assert_eq!(ct.columns.len(), 2);
3823                assert!(ct.columns[0].primary_key);
3824                assert!(ct.columns[1].unique);
3825            }
3826            _ => panic!("Expected CREATE TABLE"),
3827        }
3828    }
3829
3830    #[test]
3831    fn test_parse_extract() {
3832        let stmt = Parser::new("SELECT EXTRACT(YEAR FROM created_at) FROM t")
3833            .unwrap()
3834            .parse_statement()
3835            .unwrap();
3836        match stmt {
3837            Statement::Select(sel) => {
3838                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
3839                    assert!(matches!(expr, Expr::Extract { .. }));
3840                }
3841            }
3842            _ => panic!("Expected SELECT"),
3843        }
3844    }
3845
3846    #[test]
3847    fn test_parse_postgres_cast() {
3848        let stmt = Parser::new("SELECT x::int FROM t")
3849            .unwrap()
3850            .parse_statement()
3851            .unwrap();
3852        match stmt {
3853            Statement::Select(sel) => {
3854                if let SelectItem::Expr { expr, .. } = &sel.columns[0] {
3855                    assert!(matches!(expr, Expr::Cast { .. }));
3856                }
3857            }
3858            _ => panic!("Expected SELECT"),
3859        }
3860    }
3861}
3862
3863/// Attach comments to the appropriate field on a parsed statement.
3864fn attach_comments_to_statement(stmt: &mut Statement, comments: Vec<String>) {
3865    match stmt {
3866        Statement::Select(s) => s.comments = comments,
3867        Statement::Insert(s) => s.comments = comments,
3868        Statement::Update(s) => s.comments = comments,
3869        Statement::Delete(s) => s.comments = comments,
3870        Statement::CreateTable(s) => s.comments = comments,
3871        Statement::DropTable(s) => s.comments = comments,
3872        Statement::SetOperation(s) => s.comments = comments,
3873        Statement::AlterTable(s) => s.comments = comments,
3874        Statement::CreateView(s) => s.comments = comments,
3875        Statement::DropView(s) => s.comments = comments,
3876        Statement::Truncate(s) => s.comments = comments,
3877        Statement::Explain(s) => s.comments = comments,
3878        Statement::Use(s) => s.comments = comments,
3879        Statement::Merge(s) => s.comments = comments,
3880        // Transaction and Expression don't have comment fields
3881        Statement::Transaction(_) | Statement::Expression(_) => {}
3882    }
3883}