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