vibesql/parser/
expr.rs

1//! Expression parser.
2//!
3//! Implements expression parsing using a Pratt parser (precedence climbing)
4//! for handling operator precedence correctly.
5
6use crate::ast::*;
7use crate::error::{Error, Result, Span};
8use crate::lexer::{Keyword, TokenKind};
9
10use super::Parser;
11
12impl<'a> Parser<'a> {
13    /// Parse an expression.
14    pub fn parse_expression(&mut self) -> Result<Box<Expr>> {
15        self.parse_expression_with_precedence(0)
16    }
17
18    /// Parse an expression with a minimum precedence.
19    fn parse_expression_with_precedence(&mut self, min_precedence: u8) -> Result<Box<Expr>> {
20        let mut left = self.parse_unary_expression()?;
21
22        loop {
23            // Clone the token kind to avoid borrow issues
24            let token_kind = self.peek()?.kind.clone();
25
26            // Check for binary operator
27            if let Some((op, precedence)) = self.get_binary_op(&token_kind) {
28                if precedence < min_precedence {
29                    break;
30                }
31
32                self.advance()?;
33                let next_precedence = if op.is_left_associative() {
34                    precedence + 1
35                } else {
36                    precedence
37                };
38
39                let right = self.parse_expression_with_precedence(next_precedence)?;
40                let span = left.span.merge(right.span);
41
42                left = Expr::boxed(ExprKind::BinaryOp { op, left, right }, span);
43            }
44            // Check for AND
45            else if self.check_keyword(Keyword::And)? {
46                if BinaryOp::And.precedence() < min_precedence {
47                    break;
48                }
49                self.advance()?;
50                let right =
51                    self.parse_expression_with_precedence(BinaryOp::And.precedence() + 1)?;
52                let span = left.span.merge(right.span);
53                left = Expr::boxed(
54                    ExprKind::BinaryOp {
55                        op: BinaryOp::And,
56                        left,
57                        right,
58                    },
59                    span,
60                );
61            }
62            // Check for OR
63            else if self.check_keyword(Keyword::Or)? {
64                if BinaryOp::Or.precedence() < min_precedence {
65                    break;
66                }
67                self.advance()?;
68                let right = self.parse_expression_with_precedence(BinaryOp::Or.precedence() + 1)?;
69                let span = left.span.merge(right.span);
70                left = Expr::boxed(
71                    ExprKind::BinaryOp {
72                        op: BinaryOp::Or,
73                        left,
74                        right,
75                    },
76                    span,
77                );
78            }
79            // Check for postfix operators and special expressions
80            else if let Some(new_left) = self.try_parse_postfix_expression(left.clone())? {
81                left = new_left;
82            } else {
83                break;
84            }
85        }
86
87        Ok(left)
88    }
89
90    /// Parse a unary expression (NOT, -, +, ~).
91    fn parse_unary_expression(&mut self) -> Result<Box<Expr>> {
92        // Clone token info to avoid borrow issues
93        let (start, token_kind) = {
94            let token = self.peek()?;
95            (token.span.start, token.kind.clone())
96        };
97
98        // NOT
99        if self.check_keyword(Keyword::Not)? {
100            self.advance()?;
101            let expr = self.parse_unary_expression()?;
102            let span = Span::new(start, expr.span.end);
103            return Ok(Expr::boxed(
104                ExprKind::UnaryOp {
105                    op: UnaryOp::Not,
106                    expr,
107                },
108                span,
109            ));
110        }
111
112        // EXISTS
113        if self.check_keyword(Keyword::Exists)? {
114            return self.parse_exists_expression();
115        }
116
117        // CASE
118        if self.check_keyword(Keyword::Case)? {
119            return self.parse_case_expression();
120        }
121
122        // CAST / SAFE_CAST
123        if self.check_keyword(Keyword::Cast)? || self.check_keyword(Keyword::SafeCast)? {
124            return self.parse_cast_expression();
125        }
126
127        // EXTRACT
128        if self.check_keyword(Keyword::Extract)? {
129            return self.parse_extract_expression();
130        }
131
132        // INTERVAL
133        if self.check_keyword(Keyword::Interval)? {
134            return self.parse_interval_expression();
135        }
136
137        // ARRAY
138        if self.check_keyword(Keyword::Array)? {
139            return self.parse_array_expression();
140        }
141
142        // STRUCT
143        if self.check_keyword(Keyword::Struct)? {
144            return self.parse_struct_expression();
145        }
146
147        // IF
148        if self.check_keyword(Keyword::If)? {
149            return self.parse_if_expression();
150        }
151
152        // Unary + and -
153        match &token_kind {
154            TokenKind::Plus => {
155                self.advance()?;
156                let expr = self.parse_unary_expression()?;
157                let span = Span::new(start, expr.span.end);
158                return Ok(Expr::boxed(
159                    ExprKind::UnaryOp {
160                        op: UnaryOp::Plus,
161                        expr,
162                    },
163                    span,
164                ));
165            }
166            TokenKind::Minus => {
167                self.advance()?;
168                let expr = self.parse_unary_expression()?;
169                let span = Span::new(start, expr.span.end);
170                return Ok(Expr::boxed(
171                    ExprKind::UnaryOp {
172                        op: UnaryOp::Minus,
173                        expr,
174                    },
175                    span,
176                ));
177            }
178            TokenKind::Tilde => {
179                self.advance()?;
180                let expr = self.parse_unary_expression()?;
181                let span = Span::new(start, expr.span.end);
182                return Ok(Expr::boxed(
183                    ExprKind::UnaryOp {
184                        op: UnaryOp::BitwiseNot,
185                        expr,
186                    },
187                    span,
188                ));
189            }
190            _ => {}
191        }
192
193        self.parse_primary_expression()
194    }
195
196    /// Parse a primary expression (atoms: literals, identifiers, function calls, etc.).
197    fn parse_primary_expression(&mut self) -> Result<Box<Expr>> {
198        // Clone token info to avoid borrow conflicts
199        let (span, token_kind) = {
200            let token = self.peek()?;
201            (token.span, token.kind.clone())
202        };
203
204        match token_kind {
205            // Literals
206            TokenKind::Null => {
207                self.advance()?;
208                Ok(Expr::boxed(ExprKind::Null, span))
209            }
210            TokenKind::Boolean(value) => {
211                self.advance()?;
212                Ok(Expr::boxed(ExprKind::Boolean(value), span))
213            }
214            TokenKind::Integer(value) => {
215                self.advance()?;
216                Ok(Expr::boxed(ExprKind::Integer(value), span))
217            }
218            TokenKind::Float(value) => {
219                self.advance()?;
220                Ok(Expr::boxed(ExprKind::Float(value), span))
221            }
222            TokenKind::String(value) => {
223                self.advance()?;
224                Ok(Expr::boxed(ExprKind::String(value), span))
225            }
226            TokenKind::Bytes(value) => {
227                self.advance()?;
228                Ok(Expr::boxed(ExprKind::Bytes(value), span))
229            }
230
231            // Typed literals (DATE, TIME, TIMESTAMP, JSON, etc.)
232            TokenKind::Keyword(kw) => {
233                if let Some(lit_type) = self.keyword_to_typed_literal(kw) {
234                    self.advance()?;
235                    let string_token = self.advance()?;
236                    if let TokenKind::String(value) = string_token.kind {
237                        let end_span = string_token.span;
238                        return Ok(Expr::boxed(
239                            ExprKind::TypedLiteral {
240                                data_type: lit_type,
241                                value,
242                            },
243                            Span::new(span.start, end_span.end),
244                        ));
245                    } else {
246                        return Err(Error::unexpected_token(
247                            "string literal",
248                            format!("{}", string_token.kind),
249                            string_token.span,
250                        ));
251                    }
252                }
253
254                // Function call or identifier
255                if kw.is_reserved() {
256                    return Err(Error::unexpected_token(
257                        "expression",
258                        format!("keyword {}", kw),
259                        span,
260                    ));
261                }
262
263                self.parse_identifier_or_function()
264            }
265
266            // Identifiers and function calls
267            TokenKind::Identifier(_) | TokenKind::QuotedIdentifier(_) => {
268                self.parse_identifier_or_function()
269            }
270
271            // Parameters
272            TokenKind::At => {
273                self.advance()?;
274                let name_token = self.advance()?;
275                let name = match name_token.kind {
276                    TokenKind::Identifier(s) => s,
277                    _ => return Err(Error::expected_identifier(name_token.span)),
278                };
279                let end_span = name_token.span;
280                Ok(Expr::boxed(
281                    ExprKind::Parameter(Parameter::Named(name)),
282                    Span::new(span.start, end_span.end),
283                ))
284            }
285            TokenKind::Question => {
286                self.advance()?;
287                Ok(Expr::boxed(
288                    ExprKind::Parameter(Parameter::Positional(0)),
289                    span,
290                ))
291            }
292
293            // Parenthesized expression or subquery
294            TokenKind::LeftParen => self.parse_parenthesized_expression(),
295
296            // Array literal
297            TokenKind::LeftBracket => self.parse_array_literal(),
298
299            _ => Err(Error::expected_expression(span)),
300        }
301    }
302
303    /// Try to parse postfix expressions (field access, array subscript, etc.).
304    fn try_parse_postfix_expression(&mut self, left: Box<Expr>) -> Result<Option<Box<Expr>>> {
305        // Clone token kind to avoid borrow issues
306        let token_kind = self.peek()?.kind.clone();
307
308        match token_kind {
309            // Field access: expr.field
310            TokenKind::Dot => {
311                self.advance()?;
312                let field = self.parse_identifier()?;
313                let span = left.span.merge(field.span);
314                Ok(Some(Expr::boxed(
315                    ExprKind::FieldAccess { expr: left, field },
316                    span,
317                )))
318            }
319
320            // Array subscript: expr[index]
321            TokenKind::LeftBracket => {
322                self.advance()?;
323                let index = self.parse_array_subscript_index()?;
324                let end_token = self.expect(&TokenKind::RightBracket)?;
325                let span = left.span.merge(end_token.span);
326                Ok(Some(Expr::boxed(
327                    ExprKind::ArraySubscript { array: left, index },
328                    span,
329                )))
330            }
331
332            // BETWEEN
333            TokenKind::Keyword(Keyword::Between) => {
334                self.advance()?;
335                let low = self.parse_expression_with_precedence(10)?;
336                self.expect_keyword(Keyword::And)?;
337                let high = self.parse_expression_with_precedence(10)?;
338                let span = left.span.merge(high.span);
339                Ok(Some(Expr::boxed(
340                    ExprKind::Between {
341                        expr: left,
342                        low,
343                        high,
344                        negated: false,
345                    },
346                    span,
347                )))
348            }
349
350            // NOT BETWEEN
351            TokenKind::Keyword(Keyword::Not) => {
352                let next = self.peek_nth(1)?;
353                if next.is_keyword(Keyword::Between) {
354                    self.advance()?; // NOT
355                    self.advance()?; // BETWEEN
356                    let low = self.parse_expression_with_precedence(10)?;
357                    self.expect_keyword(Keyword::And)?;
358                    let high = self.parse_expression_with_precedence(10)?;
359                    let span = left.span.merge(high.span);
360                    return Ok(Some(Expr::boxed(
361                        ExprKind::Between {
362                            expr: left,
363                            low,
364                            high,
365                            negated: true,
366                        },
367                        span,
368                    )));
369                }
370                if next.is_keyword(Keyword::In) {
371                    self.advance()?; // NOT
372                    self.advance()?; // IN
373                    return self.parse_in_expression(left, true);
374                }
375                if next.is_keyword(Keyword::Like) {
376                    self.advance()?; // NOT
377                    self.advance()?; // LIKE
378                    return self.parse_like_expression(left, true);
379                }
380                Ok(None)
381            }
382
383            // IN
384            TokenKind::Keyword(Keyword::In) => {
385                self.advance()?;
386                self.parse_in_expression(left, false)
387            }
388
389            // LIKE
390            TokenKind::Keyword(Keyword::Like) => {
391                self.advance()?;
392                self.parse_like_expression(left, false)
393            }
394
395            // IS
396            TokenKind::Keyword(Keyword::Is) => {
397                self.advance()?;
398                self.parse_is_expression(left)
399            }
400
401            _ => Ok(None),
402        }
403    }
404
405    /// Parse an identifier or function call.
406    fn parse_identifier_or_function(&mut self) -> Result<Box<Expr>> {
407        let name = self.parse_object_name()?;
408
409        // Check for function call
410        if self.check(&TokenKind::LeftParen)? {
411            self.parse_function_call(name)
412        } else {
413            // Simple identifier or qualified identifier
414            let span = name.span;
415            if name.parts.len() == 1 {
416                Ok(Expr::boxed(
417                    ExprKind::Identifier(name.parts.into_iter().next().unwrap()),
418                    span,
419                ))
420            } else {
421                Ok(Expr::boxed(ExprKind::CompoundIdentifier(name.parts), span))
422            }
423        }
424    }
425
426    /// Parse a function call.
427    fn parse_function_call(&mut self, name: ObjectName) -> Result<Box<Expr>> {
428        let start = name.span.start;
429        self.expect(&TokenKind::LeftParen)?;
430
431        // Check for COUNT(*) or similar
432        let mut args = Vec::new();
433        let mut distinct = false;
434
435        if self.check(&TokenKind::Star)? {
436            self.advance()?;
437            args.push(FunctionArg::Star);
438        } else if !self.check(&TokenKind::RightParen)? {
439            // Check for DISTINCT
440            if self.consume_keyword(Keyword::Distinct)?.is_some() {
441                distinct = true;
442            }
443
444            // Parse arguments
445            args = self.parse_comma_separated(|p| p.parse_function_arg())?;
446        }
447
448        // Check for ORDER BY in aggregate functions
449        let order_by = if self.consume_keyword(Keyword::Order)?.is_some() {
450            self.expect_keyword(Keyword::By)?;
451            self.parse_comma_separated(|p| p.parse_order_by_expr())?
452        } else {
453            Vec::new()
454        };
455
456        // Check for LIMIT in aggregate functions
457        let limit = if self.consume_keyword(Keyword::Limit)?.is_some() {
458            Some(self.parse_expression()?)
459        } else {
460            None
461        };
462
463        let end_token = self.expect(&TokenKind::RightParen)?;
464
465        // Check for OVER clause (window function)
466        if self.consume_keyword(Keyword::Over)?.is_some() {
467            let window = self.parse_window_spec_or_ref()?;
468            let span = Span::new(start, self.current_position());
469            return Ok(Expr::boxed(
470                ExprKind::WindowFunction(WindowFunctionCall {
471                    function: FunctionCall {
472                        name,
473                        args,
474                        distinct,
475                        null_treatment: None,
476                        order_by,
477                        limit,
478                    },
479                    window,
480                }),
481                span,
482            ));
483        }
484
485        let span = Span::new(start, end_token.span.end);
486        Ok(Expr::boxed(
487            ExprKind::Function(FunctionCall {
488                name,
489                args,
490                distinct,
491                null_treatment: None,
492                order_by,
493                limit,
494            }),
495            span,
496        ))
497    }
498
499    /// Parse a window specification or reference.
500    fn parse_window_spec_or_ref(&mut self) -> Result<WindowSpecOrRef> {
501        if self.check(&TokenKind::LeftParen)? {
502            self.expect(&TokenKind::LeftParen)?;
503            let spec = self.parse_window_spec()?;
504            self.expect(&TokenKind::RightParen)?;
505            Ok(WindowSpecOrRef::Spec(spec))
506        } else {
507            let name = self.parse_identifier()?;
508            Ok(WindowSpecOrRef::Ref(name))
509        }
510    }
511
512    /// Parse a window specification.
513    pub(super) fn parse_window_spec(&mut self) -> Result<WindowSpec> {
514        let partition_by = if self.consume_keyword(Keyword::Partition)?.is_some() {
515            self.expect_keyword(Keyword::By)?;
516            self.parse_comma_separated(|p| p.parse_expression())?
517        } else {
518            Vec::new()
519        };
520
521        let order_by = if self.consume_keyword(Keyword::Order)?.is_some() {
522            self.expect_keyword(Keyword::By)?;
523            self.parse_comma_separated(|p| p.parse_order_by_expr())?
524        } else {
525            Vec::new()
526        };
527
528        let frame = self.parse_optional_window_frame()?;
529
530        Ok(WindowSpec {
531            partition_by,
532            order_by,
533            frame,
534        })
535    }
536
537    /// Parse an optional window frame.
538    fn parse_optional_window_frame(&mut self) -> Result<Option<WindowFrame>> {
539        let unit = if self.consume_keyword(Keyword::Rows)?.is_some() {
540            WindowFrameUnit::Rows
541        } else if self.consume_keyword(Keyword::Range)?.is_some() {
542            WindowFrameUnit::Range
543        } else if self.consume_keyword(Keyword::Groups)?.is_some() {
544            WindowFrameUnit::Groups
545        } else {
546            return Ok(None);
547        };
548
549        let (start, end) = if self.consume_keyword(Keyword::Between)?.is_some() {
550            let start = self.parse_window_frame_bound()?;
551            self.expect_keyword(Keyword::And)?;
552            let end = self.parse_window_frame_bound()?;
553            (start, Some(end))
554        } else {
555            (self.parse_window_frame_bound()?, None)
556        };
557
558        Ok(Some(WindowFrame { unit, start, end }))
559    }
560
561    /// Parse a window frame bound.
562    fn parse_window_frame_bound(&mut self) -> Result<WindowFrameBound> {
563        if self.consume_keyword(Keyword::Current)?.is_some() {
564            self.expect_keyword(Keyword::Row)?;
565            return Ok(WindowFrameBound::CurrentRow);
566        }
567
568        if self.consume_keyword(Keyword::Unbounded)?.is_some() {
569            if self.consume_keyword(Keyword::Preceding)?.is_some() {
570                return Ok(WindowFrameBound::Preceding(None));
571            } else {
572                self.expect_keyword(Keyword::Following)?;
573                return Ok(WindowFrameBound::Following(None));
574            }
575        }
576
577        let expr = self.parse_expression()?;
578
579        if self.consume_keyword(Keyword::Preceding)?.is_some() {
580            Ok(WindowFrameBound::Preceding(Some(expr)))
581        } else {
582            self.expect_keyword(Keyword::Following)?;
583            Ok(WindowFrameBound::Following(Some(expr)))
584        }
585    }
586
587    /// Parse an array subscript index.
588    ///
589    /// Supports:
590    /// - Simple index: `array[0]`
591    /// - OFFSET: `array[OFFSET(0)]`
592    /// - ORDINAL: `array[ORDINAL(1)]`
593    /// - SAFE_OFFSET: `array[SAFE_OFFSET(0)]`
594    /// - SAFE_ORDINAL: `array[SAFE_ORDINAL(1)]`
595    fn parse_array_subscript_index(&mut self) -> Result<ArraySubscriptKind> {
596        // Check for OFFSET
597        if self.consume_keyword(Keyword::Offset)?.is_some() {
598            self.expect(&TokenKind::LeftParen)?;
599            let idx = self.parse_expression()?;
600            self.expect(&TokenKind::RightParen)?;
601            return Ok(ArraySubscriptKind::Offset(idx));
602        }
603
604        // Check for ORDINAL
605        if self.consume_keyword(Keyword::Ordinal)?.is_some() {
606            self.expect(&TokenKind::LeftParen)?;
607            let idx = self.parse_expression()?;
608            self.expect(&TokenKind::RightParen)?;
609            return Ok(ArraySubscriptKind::Ordinal(idx));
610        }
611
612        // Check for SAFE_OFFSET or SAFE_ORDINAL (as single keywords)
613        if self.consume_keyword(Keyword::SafeOffset)?.is_some() {
614            self.expect(&TokenKind::LeftParen)?;
615            let idx = self.parse_expression()?;
616            self.expect(&TokenKind::RightParen)?;
617            return Ok(ArraySubscriptKind::SafeOffset(idx));
618        }
619
620        if self.consume_keyword(Keyword::SafeOrdinal)?.is_some() {
621            self.expect(&TokenKind::LeftParen)?;
622            let idx = self.parse_expression()?;
623            self.expect(&TokenKind::RightParen)?;
624            return Ok(ArraySubscriptKind::SafeOrdinal(idx));
625        }
626
627        // Simple index
628        let idx = self.parse_expression()?;
629        Ok(ArraySubscriptKind::Index(idx))
630    }
631
632    /// Parse a parenthesized expression or subquery.
633    fn parse_parenthesized_expression(&mut self) -> Result<Box<Expr>> {
634        let start = self.expect(&TokenKind::LeftParen)?.span.start;
635
636        // Check if this is a subquery
637        if self.check_keyword(Keyword::Select)? || self.check_keyword(Keyword::With)? {
638            let query = self.parse_query()?;
639            let end = self.expect(&TokenKind::RightParen)?.span.end;
640            return Ok(Expr::boxed(
641                ExprKind::Subquery(Box::new(query)),
642                Span::new(start, end),
643            ));
644        }
645
646        let expr = self.parse_expression()?;
647
648        // Check for tuple/struct: (expr1, expr2, ...)
649        if self.check(&TokenKind::Comma)? {
650            let mut fields = vec![StructField {
651                name: None,
652                value: expr,
653            }];
654            while self.consume(&TokenKind::Comma)?.is_some() {
655                let value = self.parse_expression()?;
656                fields.push(StructField { name: None, value });
657            }
658            let end = self.expect(&TokenKind::RightParen)?.span.end;
659            return Ok(Expr::boxed(
660                ExprKind::Struct { fields },
661                Span::new(start, end),
662            ));
663        }
664
665        let end = self.expect(&TokenKind::RightParen)?.span.end;
666        Ok(Expr::boxed(
667            ExprKind::Parenthesized(expr),
668            Span::new(start, end),
669        ))
670    }
671
672    /// Parse an array literal: [1, 2, 3].
673    fn parse_array_literal(&mut self) -> Result<Box<Expr>> {
674        let start = self.expect(&TokenKind::LeftBracket)?.span.start;
675
676        let elements = if self.check(&TokenKind::RightBracket)? {
677            Vec::new()
678        } else {
679            self.parse_comma_separated(|p| p.parse_expression())?
680        };
681
682        let end = self.expect(&TokenKind::RightBracket)?.span.end;
683
684        Ok(Expr::boxed(
685            ExprKind::Array {
686                element_type: None,
687                elements,
688            },
689            Span::new(start, end),
690        ))
691    }
692
693    /// Parse an ARRAY expression: ARRAY[1, 2, 3] or ARRAY<type>[...].
694    fn parse_array_expression(&mut self) -> Result<Box<Expr>> {
695        let start = self.expect_keyword(Keyword::Array)?.span.start;
696
697        // Check for type parameter: ARRAY<type>
698        let element_type = if self.consume(&TokenKind::Lt)?.is_some() {
699            let data_type = self.parse_data_type()?;
700            self.expect(&TokenKind::Gt)?;
701            Some(Box::new(data_type))
702        } else {
703            None
704        };
705
706        // Parse array elements or subquery
707        if self.check(&TokenKind::LeftParen)? {
708            // ARRAY(subquery)
709            self.advance()?;
710            let query = self.parse_query()?;
711            let end = self.expect(&TokenKind::RightParen)?.span.end;
712            return Ok(Expr::boxed(
713                ExprKind::Subquery(Box::new(query)),
714                Span::new(start, end),
715            ));
716        }
717
718        self.expect(&TokenKind::LeftBracket)?;
719        let elements = if self.check(&TokenKind::RightBracket)? {
720            Vec::new()
721        } else {
722            self.parse_comma_separated(|p| p.parse_expression())?
723        };
724        let end = self.expect(&TokenKind::RightBracket)?.span.end;
725
726        Ok(Expr::boxed(
727            ExprKind::Array {
728                element_type,
729                elements,
730            },
731            Span::new(start, end),
732        ))
733    }
734
735    /// Parse a STRUCT expression.
736    fn parse_struct_expression(&mut self) -> Result<Box<Expr>> {
737        let start = self.expect_keyword(Keyword::Struct)?.span.start;
738
739        // Check for type parameter: STRUCT<...>
740        if self.check(&TokenKind::Lt)? {
741            // STRUCT<field_type, ...>(values)
742            // For now, skip type parameters
743            self.advance()?;
744            let mut depth = 1;
745            while depth > 0 {
746                let token = self.advance()?;
747                match token.kind {
748                    TokenKind::Lt => depth += 1,
749                    TokenKind::Gt => depth -= 1,
750                    TokenKind::Eof => return Err(Error::unexpected_eof(token.span.start)),
751                    _ => {}
752                }
753            }
754        }
755
756        self.expect(&TokenKind::LeftParen)?;
757
758        let fields = if self.check(&TokenKind::RightParen)? {
759            Vec::new()
760        } else {
761            self.parse_comma_separated(|p| p.parse_struct_field())?
762        };
763
764        let end = self.expect(&TokenKind::RightParen)?.span.end;
765
766        Ok(Expr::boxed(
767            ExprKind::Struct { fields },
768            Span::new(start, end),
769        ))
770    }
771
772    /// Parse a struct field: [name AS] expr.
773    fn parse_struct_field(&mut self) -> Result<StructField> {
774        let expr = self.parse_expression()?;
775
776        // Check for AS alias
777        if self.consume_keyword(Keyword::As)?.is_some() {
778            let name = self.parse_identifier()?;
779            return Ok(StructField {
780                name: Some(name),
781                value: expr,
782            });
783        }
784
785        // No alias
786        Ok(StructField {
787            name: None,
788            value: expr,
789        })
790    }
791
792    /// Parse CASE expression.
793    fn parse_case_expression(&mut self) -> Result<Box<Expr>> {
794        let start = self.expect_keyword(Keyword::Case)?.span.start;
795
796        // Check for simple CASE (CASE expr WHEN ...)
797        let operand = if !self.check_keyword(Keyword::When)? {
798            Some(self.parse_expression()?)
799        } else {
800            None
801        };
802
803        let mut conditions = Vec::new();
804        while self.consume_keyword(Keyword::When)?.is_some() {
805            let condition = self.parse_expression()?;
806            self.expect_keyword(Keyword::Then)?;
807            let result = self.parse_expression()?;
808            conditions.push((condition, result));
809        }
810
811        let else_result = if self.consume_keyword(Keyword::Else)?.is_some() {
812            Some(self.parse_expression()?)
813        } else {
814            None
815        };
816
817        let end = self.expect_keyword(Keyword::End)?.span.end;
818
819        Ok(Expr::boxed(
820            ExprKind::Case {
821                operand,
822                conditions,
823                else_result,
824            },
825            Span::new(start, end),
826        ))
827    }
828
829    /// Parse CAST or SAFE_CAST expression.
830    fn parse_cast_expression(&mut self) -> Result<Box<Expr>> {
831        let start = self.peek()?.span.start;
832        let safe = self.consume_keyword(Keyword::SafeCast)?.is_some();
833        if !safe {
834            self.expect_keyword(Keyword::Cast)?;
835        }
836
837        self.expect(&TokenKind::LeftParen)?;
838        let expr = self.parse_expression()?;
839        self.expect_keyword(Keyword::As)?;
840        let data_type = self.parse_data_type()?;
841        let end = self.expect(&TokenKind::RightParen)?.span.end;
842
843        Ok(Expr::boxed(
844            ExprKind::Cast {
845                expr,
846                data_type,
847                safe,
848            },
849            Span::new(start, end),
850        ))
851    }
852
853    /// Parse EXTRACT expression.
854    fn parse_extract_expression(&mut self) -> Result<Box<Expr>> {
855        let start = self.expect_keyword(Keyword::Extract)?.span.start;
856        self.expect(&TokenKind::LeftParen)?;
857
858        let field_token = self.advance()?;
859        let field = match DateTimePart::parse(&field_token.text) {
860            Some(f) => f,
861            None => {
862                return Err(Error::invalid_syntax(
863                    format!("invalid EXTRACT field: {}", field_token.text),
864                    field_token.span,
865                ))
866            }
867        };
868
869        self.expect_keyword(Keyword::From)?;
870        let from = self.parse_expression()?;
871        let end = self.expect(&TokenKind::RightParen)?.span.end;
872
873        Ok(Expr::boxed(
874            ExprKind::Extract { field, from },
875            Span::new(start, end),
876        ))
877    }
878
879    /// Parse INTERVAL expression.
880    fn parse_interval_expression(&mut self) -> Result<Box<Expr>> {
881        let start = self.expect_keyword(Keyword::Interval)?.span.start;
882
883        let value = self.parse_expression_with_precedence(10)?;
884
885        let unit_token = self.advance()?;
886        let unit = match IntervalUnit::parse(&unit_token.text) {
887            Some(u) => u,
888            None => {
889                return Err(Error::invalid_syntax(
890                    format!("invalid INTERVAL unit: {}", unit_token.text),
891                    unit_token.span,
892                ))
893            }
894        };
895
896        let span = Span::new(start, unit_token.span.end);
897        Ok(Expr::boxed(ExprKind::Interval { value, unit }, span))
898    }
899
900    /// Parse IF expression.
901    fn parse_if_expression(&mut self) -> Result<Box<Expr>> {
902        let start = self.expect_keyword(Keyword::If)?.span.start;
903        self.expect(&TokenKind::LeftParen)?;
904
905        let condition = self.parse_expression()?;
906        self.expect(&TokenKind::Comma)?;
907        let then_expr = self.parse_expression()?;
908        self.expect(&TokenKind::Comma)?;
909        let else_expr = self.parse_expression()?;
910
911        let end = self.expect(&TokenKind::RightParen)?.span.end;
912
913        Ok(Expr::boxed(
914            ExprKind::If {
915                condition,
916                then_expr,
917                else_expr,
918            },
919            Span::new(start, end),
920        ))
921    }
922
923    /// Parse EXISTS expression.
924    fn parse_exists_expression(&mut self) -> Result<Box<Expr>> {
925        let start = self.expect_keyword(Keyword::Exists)?.span.start;
926        self.expect(&TokenKind::LeftParen)?;
927        let query = self.parse_query()?;
928        let end = self.expect(&TokenKind::RightParen)?.span.end;
929
930        Ok(Expr::boxed(
931            ExprKind::Exists {
932                subquery: Box::new(query),
933                negated: false,
934            },
935            Span::new(start, end),
936        ))
937    }
938
939    /// Parse IN expression.
940    fn parse_in_expression(&mut self, left: Box<Expr>, negated: bool) -> Result<Option<Box<Expr>>> {
941        self.expect(&TokenKind::LeftParen)?;
942
943        let list = if self.check_keyword(Keyword::Select)? || self.check_keyword(Keyword::With)? {
944            let query = self.parse_query()?;
945            InList::Subquery(Box::new(query))
946        } else {
947            let values = self.parse_comma_separated(|p| p.parse_expression())?;
948            InList::Values(values)
949        };
950
951        let end = self.expect(&TokenKind::RightParen)?.span.end;
952        let span = left.span.merge(Span::new(end - 1, end));
953
954        Ok(Some(Expr::boxed(
955            ExprKind::In {
956                expr: left,
957                list,
958                negated,
959            },
960            span,
961        )))
962    }
963
964    /// Parse LIKE expression.
965    fn parse_like_expression(
966        &mut self,
967        left: Box<Expr>,
968        negated: bool,
969    ) -> Result<Option<Box<Expr>>> {
970        let pattern = self.parse_expression_with_precedence(10)?;
971
972        let escape = if self.consume_keyword(Keyword::Escape)?.is_some() {
973            Some(self.parse_expression_with_precedence(10)?)
974        } else {
975            None
976        };
977
978        let span = left.span.merge(pattern.span);
979
980        Ok(Some(Expr::boxed(
981            ExprKind::Like {
982                expr: left,
983                pattern,
984                escape,
985                negated,
986            },
987            span,
988        )))
989    }
990
991    /// Parse IS expression (IS NULL, IS NOT NULL, IS TRUE, etc.).
992    fn parse_is_expression(&mut self, left: Box<Expr>) -> Result<Option<Box<Expr>>> {
993        let negated = self.consume_keyword(Keyword::Not)?.is_some();
994
995        // Note: NULL, TRUE, FALSE are special tokens, not keywords
996        let test = if self.consume(&TokenKind::Null)?.is_some() {
997            IsTest::Null
998        } else if self.consume(&TokenKind::Boolean(true))?.is_some() {
999            IsTest::True
1000        } else if self.consume(&TokenKind::Boolean(false))?.is_some() {
1001            IsTest::False
1002        } else {
1003            let token = self.advance()?;
1004            return Err(Error::unexpected_token(
1005                "NULL, TRUE, FALSE, or UNKNOWN",
1006                format!("{}", token.kind),
1007                token.span,
1008            ));
1009        };
1010
1011        let span = Span::new(left.span.start, self.current_position());
1012
1013        Ok(Some(Expr::boxed(
1014            ExprKind::IsExpr {
1015                expr: left,
1016                test,
1017                negated,
1018            },
1019            span,
1020        )))
1021    }
1022
1023    /// Get binary operator and its precedence from token.
1024    fn get_binary_op(&self, kind: &TokenKind) -> Option<(BinaryOp, u8)> {
1025        match kind {
1026            TokenKind::Plus => Some((BinaryOp::Plus, 7)),
1027            TokenKind::Minus => Some((BinaryOp::Minus, 7)),
1028            TokenKind::Star => Some((BinaryOp::Multiply, 8)),
1029            TokenKind::Slash => Some((BinaryOp::Divide, 8)),
1030            TokenKind::Percent => Some((BinaryOp::Modulo, 8)),
1031            TokenKind::Eq => Some((BinaryOp::Eq, 9)),
1032            TokenKind::NotEq | TokenKind::LtGt => Some((BinaryOp::NotEq, 9)),
1033            TokenKind::Lt => Some((BinaryOp::Lt, 9)),
1034            TokenKind::LtEq => Some((BinaryOp::LtEq, 9)),
1035            TokenKind::Gt => Some((BinaryOp::Gt, 9)),
1036            TokenKind::GtEq => Some((BinaryOp::GtEq, 9)),
1037            TokenKind::Ampersand => Some((BinaryOp::BitwiseAnd, 5)),
1038            TokenKind::Pipe => Some((BinaryOp::BitwiseOr, 3)),
1039            TokenKind::Caret => Some((BinaryOp::BitwiseXor, 4)),
1040            TokenKind::LeftShift => Some((BinaryOp::LeftShift, 6)),
1041            TokenKind::RightShift => Some((BinaryOp::RightShift, 6)),
1042            TokenKind::DoublePipe => Some((BinaryOp::Concat, 8)),
1043            _ => None,
1044        }
1045    }
1046
1047    /// Convert keyword to typed literal type.
1048    fn keyword_to_typed_literal(&self, kw: Keyword) -> Option<TypedLiteralType> {
1049        match kw {
1050            Keyword::Date => Some(TypedLiteralType::Date),
1051            Keyword::Time => Some(TypedLiteralType::Time),
1052            Keyword::Timestamp => Some(TypedLiteralType::Timestamp),
1053            Keyword::Datetime => Some(TypedLiteralType::Datetime),
1054            Keyword::Json => Some(TypedLiteralType::Json),
1055            Keyword::Numeric | Keyword::Decimal => Some(TypedLiteralType::Numeric),
1056            _ => None,
1057        }
1058    }
1059
1060    /// Parse a data type specification.
1061    pub fn parse_data_type(&mut self) -> Result<DataTypeSpec> {
1062        let token = self.advance()?;
1063        let start = token.span.start;
1064
1065        let kind = match &token.kind {
1066            TokenKind::Keyword(kw) => self.parse_data_type_from_keyword(*kw, token.span)?,
1067            TokenKind::Identifier(name) => {
1068                // Named type or alias
1069                let upper = name.to_uppercase();
1070                self.parse_data_type_from_name(&upper, token.span)?
1071            }
1072            _ => {
1073                return Err(Error::unexpected_token(
1074                    "data type",
1075                    format!("{}", token.kind),
1076                    token.span,
1077                ))
1078            }
1079        };
1080
1081        let end = self.current_position();
1082        Ok(DataTypeSpec::new(kind, Span::new(start, end)))
1083    }
1084
1085    fn parse_data_type_from_keyword(&mut self, kw: Keyword, span: Span) -> Result<DataTypeKind> {
1086        match kw {
1087            // Boolean
1088            Keyword::Bool | Keyword::Boolean => Ok(DataTypeKind::Bool),
1089
1090            // 32-bit integer (INTEGER, INT, INT32, SMALLINT)
1091            Keyword::Int32 | Keyword::Int | Keyword::Integer | Keyword::Smallint => {
1092                Ok(DataTypeKind::Int32)
1093            }
1094
1095            // 64-bit integer (BIGINT, INT64)
1096            Keyword::Int64 | Keyword::Bigint => Ok(DataTypeKind::Int64),
1097
1098            // Unsigned integers
1099            Keyword::Uint32 => Ok(DataTypeKind::Uint32),
1100            Keyword::Uint64 => Ok(DataTypeKind::Uint64),
1101
1102            // 32-bit float (REAL, FLOAT32)
1103            Keyword::Float32 | Keyword::Real => Ok(DataTypeKind::Float32),
1104
1105            // 64-bit float (DOUBLE, DOUBLE PRECISION, FLOAT, FLOAT64)
1106            Keyword::Float64 | Keyword::Float | Keyword::Double => Ok(DataTypeKind::Float64),
1107
1108            // Fixed precision decimal (NUMERIC, DECIMAL)
1109            Keyword::Numeric | Keyword::Decimal => self.parse_numeric_type(),
1110
1111            // String types (VARCHAR, TEXT, STRING, CHAR)
1112            Keyword::String | Keyword::Text | Keyword::Varchar | Keyword::Char => {
1113                self.parse_varchar_type()
1114            }
1115
1116            // Binary types (VARBINARY, BYTES, BLOB, BINARY)
1117            Keyword::Bytes | Keyword::Varbinary | Keyword::Binary | Keyword::Blob => {
1118                self.parse_varbinary_type()
1119            }
1120
1121            // Date/time
1122            Keyword::Date => Ok(DataTypeKind::Date),
1123            Keyword::Time => Ok(DataTypeKind::Time),
1124            Keyword::Datetime => Ok(DataTypeKind::Datetime),
1125            Keyword::Timestamp => Ok(DataTypeKind::Timestamp),
1126            Keyword::Interval => Ok(DataTypeKind::Interval),
1127
1128            // Other types
1129            Keyword::Json => Ok(DataTypeKind::Json),
1130            Keyword::Uuid => Ok(DataTypeKind::Uuid),
1131
1132            // Complex types
1133            Keyword::Array => self.parse_array_type(),
1134            Keyword::Struct => self.parse_struct_type(),
1135            Keyword::Range => self.parse_range_type(),
1136
1137            _ => Err(Error::unexpected_token(
1138                "data type",
1139                format!("{}", kw),
1140                span,
1141            )),
1142        }
1143    }
1144
1145    fn parse_data_type_from_name(&mut self, name: &str, span: Span) -> Result<DataTypeKind> {
1146        match name {
1147            // Boolean
1148            "BOOL" | "BOOLEAN" => Ok(DataTypeKind::Bool),
1149
1150            // 32-bit integer
1151            "INT32" | "INT" | "INTEGER" | "SMALLINT" | "INT4" => Ok(DataTypeKind::Int32),
1152
1153            // 64-bit integer
1154            "INT64" | "BIGINT" | "INT8" => Ok(DataTypeKind::Int64),
1155
1156            // Unsigned integers
1157            "UINT32" | "UINTEGER" => Ok(DataTypeKind::Uint32),
1158            "UINT64" | "UBIGINT" => Ok(DataTypeKind::Uint64),
1159
1160            // 32-bit float
1161            "FLOAT32" | "REAL" | "FLOAT4" => Ok(DataTypeKind::Float32),
1162
1163            // 64-bit float
1164            "FLOAT64" | "FLOAT" | "DOUBLE" | "FLOAT8" => Ok(DataTypeKind::Float64),
1165
1166            // Fixed precision decimal
1167            "NUMERIC" | "DECIMAL" | "DEC" => self.parse_numeric_type(),
1168
1169            // String types
1170            "STRING" | "TEXT" | "VARCHAR" | "CHAR" | "CHARACTER" | "NVARCHAR" | "NCHAR" => {
1171                self.parse_varchar_type()
1172            }
1173
1174            // Binary types
1175            "BYTES" | "VARBINARY" | "BYTEA" | "BLOB" | "BINARY" => self.parse_varbinary_type(),
1176
1177            // Date/time
1178            "DATE" => Ok(DataTypeKind::Date),
1179            "TIME" => Ok(DataTypeKind::Time),
1180            "DATETIME" => Ok(DataTypeKind::Datetime),
1181            "TIMESTAMP" => Ok(DataTypeKind::Timestamp),
1182            "INTERVAL" => Ok(DataTypeKind::Interval),
1183
1184            // Other types
1185            "JSON" | "JSONB" => Ok(DataTypeKind::Json),
1186            "UUID" => Ok(DataTypeKind::Uuid),
1187
1188            _ => Err(Error::unexpected_token("data type", name, span)),
1189        }
1190    }
1191
1192    fn parse_numeric_type(&mut self) -> Result<DataTypeKind> {
1193        let (precision, scale) = if self.consume(&TokenKind::LeftParen)?.is_some() {
1194            let p = self.parse_integer_literal()? as u8;
1195            let s = if self.consume(&TokenKind::Comma)?.is_some() {
1196                Some(self.parse_integer_literal()? as u8)
1197            } else {
1198                None
1199            };
1200            self.expect(&TokenKind::RightParen)?;
1201            (Some(p), s)
1202        } else {
1203            (None, None)
1204        };
1205
1206        Ok(DataTypeKind::Numeric { precision, scale })
1207    }
1208
1209    fn parse_varchar_type(&mut self) -> Result<DataTypeKind> {
1210        let max_length = if self.consume(&TokenKind::LeftParen)?.is_some() {
1211            let len = self.parse_integer_literal()? as u64;
1212            self.expect(&TokenKind::RightParen)?;
1213            Some(len)
1214        } else {
1215            None
1216        };
1217        Ok(DataTypeKind::Varchar { max_length })
1218    }
1219
1220    fn parse_varbinary_type(&mut self) -> Result<DataTypeKind> {
1221        let max_length = if self.consume(&TokenKind::LeftParen)?.is_some() {
1222            let len = self.parse_integer_literal()? as u64;
1223            self.expect(&TokenKind::RightParen)?;
1224            Some(len)
1225        } else {
1226            None
1227        };
1228        Ok(DataTypeKind::Varbinary { max_length })
1229    }
1230
1231    fn parse_array_type(&mut self) -> Result<DataTypeKind> {
1232        self.expect(&TokenKind::Lt)?;
1233        let element_type = self.parse_data_type()?;
1234        self.expect(&TokenKind::Gt)?;
1235        Ok(DataTypeKind::Array(Box::new(element_type)))
1236    }
1237
1238    fn parse_struct_type(&mut self) -> Result<DataTypeKind> {
1239        self.expect(&TokenKind::Lt)?;
1240
1241        let fields = if self.check(&TokenKind::Gt)? {
1242            Vec::new()
1243        } else {
1244            self.parse_comma_separated(|p| p.parse_struct_type_field())?
1245        };
1246
1247        self.expect(&TokenKind::Gt)?;
1248        Ok(DataTypeKind::Struct(fields))
1249    }
1250
1251    fn parse_struct_type_field(&mut self) -> Result<TypeStructField> {
1252        // Check if there's a name before the type
1253        let token = self.peek()?;
1254        let has_name = matches!(
1255            &token.kind,
1256            TokenKind::Identifier(_) | TokenKind::QuotedIdentifier(_)
1257        );
1258
1259        let (name, data_type) = if has_name {
1260            let maybe_name = self.parse_identifier()?;
1261            // Check if this was actually a type name
1262            if self.check(&TokenKind::Comma)? || self.check(&TokenKind::Gt)? {
1263                // It was a type, not a field name
1264                // Need to reparse as a type - for simplicity, treat as named type
1265                let dt = DataTypeSpec::new(
1266                    DataTypeKind::Named(vec![maybe_name.clone()]),
1267                    maybe_name.span,
1268                );
1269                (None, dt)
1270            } else {
1271                let dt = self.parse_data_type()?;
1272                (Some(maybe_name), dt)
1273            }
1274        } else {
1275            let dt = self.parse_data_type()?;
1276            (None, dt)
1277        };
1278
1279        Ok(TypeStructField { name, data_type })
1280    }
1281
1282    fn parse_range_type(&mut self) -> Result<DataTypeKind> {
1283        self.expect(&TokenKind::Lt)?;
1284        let element_type = self.parse_data_type()?;
1285        self.expect(&TokenKind::Gt)?;
1286        Ok(DataTypeKind::Range(Box::new(element_type)))
1287    }
1288
1289    fn parse_integer_literal(&mut self) -> Result<i64> {
1290        let token = self.advance()?;
1291        match token.kind {
1292            TokenKind::Integer(n) => Ok(n),
1293            _ => Err(Error::unexpected_token(
1294                "integer",
1295                format!("{}", token.kind),
1296                token.span,
1297            )),
1298        }
1299    }
1300}
1301
1302#[cfg(test)]
1303mod tests {
1304    use super::*;
1305
1306    fn parse_expr(sql: &str) -> Box<Expr> {
1307        let mut parser = Parser::new(sql);
1308        parser
1309            .parse_expression()
1310            .expect("Failed to parse expression")
1311    }
1312
1313    #[test]
1314    fn test_literals() {
1315        let expr = parse_expr("42");
1316        assert!(matches!(expr.kind, ExprKind::Integer(42)));
1317
1318        let expr = parse_expr("3.14");
1319        assert!(matches!(expr.kind, ExprKind::Float(f) if (f - 3.14).abs() < 0.001));
1320
1321        let expr = parse_expr("'hello'");
1322        assert!(matches!(expr.kind, ExprKind::String(s) if s == "hello"));
1323
1324        let expr = parse_expr("TRUE");
1325        assert!(matches!(expr.kind, ExprKind::Boolean(true)));
1326
1327        let expr = parse_expr("NULL");
1328        assert!(matches!(expr.kind, ExprKind::Null));
1329    }
1330
1331    #[test]
1332    fn test_binary_operations() {
1333        let expr = parse_expr("1 + 2");
1334        assert!(matches!(
1335            expr.kind,
1336            ExprKind::BinaryOp {
1337                op: BinaryOp::Plus,
1338                ..
1339            }
1340        ));
1341
1342        let expr = parse_expr("1 + 2 * 3");
1343        // Should parse as 1 + (2 * 3) due to precedence
1344        if let ExprKind::BinaryOp { op, left: _, right } = &expr.kind {
1345            assert_eq!(*op, BinaryOp::Plus);
1346            assert!(matches!(
1347                right.kind,
1348                ExprKind::BinaryOp {
1349                    op: BinaryOp::Multiply,
1350                    ..
1351                }
1352            ));
1353        } else {
1354            panic!("Expected BinaryOp");
1355        }
1356    }
1357
1358    #[test]
1359    fn test_comparison() {
1360        let expr = parse_expr("a > b");
1361        assert!(matches!(
1362            expr.kind,
1363            ExprKind::BinaryOp {
1364                op: BinaryOp::Gt,
1365                ..
1366            }
1367        ));
1368
1369        let expr = parse_expr("x = 10");
1370        assert!(matches!(
1371            expr.kind,
1372            ExprKind::BinaryOp {
1373                op: BinaryOp::Eq,
1374                ..
1375            }
1376        ));
1377    }
1378
1379    #[test]
1380    fn test_logical_operations() {
1381        let expr = parse_expr("a AND b");
1382        assert!(matches!(
1383            expr.kind,
1384            ExprKind::BinaryOp {
1385                op: BinaryOp::And,
1386                ..
1387            }
1388        ));
1389
1390        let expr = parse_expr("a OR b");
1391        assert!(matches!(
1392            expr.kind,
1393            ExprKind::BinaryOp {
1394                op: BinaryOp::Or,
1395                ..
1396            }
1397        ));
1398
1399        let expr = parse_expr("NOT a");
1400        assert!(matches!(
1401            expr.kind,
1402            ExprKind::UnaryOp {
1403                op: UnaryOp::Not,
1404                ..
1405            }
1406        ));
1407    }
1408
1409    #[test]
1410    fn test_function_call() {
1411        let expr = parse_expr("COUNT(*)");
1412        if let ExprKind::Function(f) = &expr.kind {
1413            assert_eq!(f.name.parts.len(), 1);
1414            assert!(matches!(&f.args[0], FunctionArg::Star));
1415        } else {
1416            panic!("Expected Function");
1417        }
1418
1419        let expr = parse_expr("UPPER('hello')");
1420        assert!(matches!(expr.kind, ExprKind::Function(_)));
1421    }
1422
1423    #[test]
1424    fn test_case_expression() {
1425        let expr = parse_expr("CASE WHEN x > 0 THEN 'positive' ELSE 'non-positive' END");
1426        assert!(matches!(expr.kind, ExprKind::Case { .. }));
1427    }
1428
1429    #[test]
1430    fn test_cast() {
1431        let expr = parse_expr("CAST(x AS INT64)");
1432        if let ExprKind::Cast { safe, .. } = &expr.kind {
1433            assert!(!safe);
1434        } else {
1435            panic!("Expected Cast");
1436        }
1437    }
1438
1439    #[test]
1440    fn test_between() {
1441        let expr = parse_expr("x BETWEEN 1 AND 10");
1442        assert!(matches!(
1443            expr.kind,
1444            ExprKind::Between { negated: false, .. }
1445        ));
1446
1447        let expr = parse_expr("x NOT BETWEEN 1 AND 10");
1448        assert!(matches!(expr.kind, ExprKind::Between { negated: true, .. }));
1449    }
1450
1451    #[test]
1452    fn test_in_list() {
1453        let expr = parse_expr("x IN (1, 2, 3)");
1454        assert!(matches!(expr.kind, ExprKind::In { negated: false, .. }));
1455    }
1456
1457    #[test]
1458    fn test_like() {
1459        let expr = parse_expr("name LIKE 'John%'");
1460        assert!(matches!(expr.kind, ExprKind::Like { negated: false, .. }));
1461    }
1462
1463    #[test]
1464    fn test_is_null() {
1465        let expr = parse_expr("x IS NULL");
1466        assert!(matches!(
1467            expr.kind,
1468            ExprKind::IsExpr {
1469                test: IsTest::Null,
1470                negated: false,
1471                ..
1472            }
1473        ));
1474
1475        let expr = parse_expr("x IS NOT NULL");
1476        assert!(matches!(
1477            expr.kind,
1478            ExprKind::IsExpr {
1479                test: IsTest::Null,
1480                negated: true,
1481                ..
1482            }
1483        ));
1484    }
1485
1486    #[test]
1487    fn test_array_literal() {
1488        let expr = parse_expr("[1, 2, 3]");
1489        if let ExprKind::Array { elements, .. } = &expr.kind {
1490            assert_eq!(elements.len(), 3);
1491        } else {
1492            panic!("Expected Array");
1493        }
1494    }
1495
1496    #[test]
1497    fn test_parenthesized() {
1498        let expr = parse_expr("(1 + 2) * 3");
1499        if let ExprKind::BinaryOp {
1500            op: BinaryOp::Multiply,
1501            left,
1502            ..
1503        } = &expr.kind
1504        {
1505            assert!(matches!(left.kind, ExprKind::Parenthesized(_)));
1506        } else {
1507            panic!("Expected BinaryOp");
1508        }
1509    }
1510}