Skip to main content

sqlglot_rust/parser/
sql_parser.rs

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