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