1use super::ast::*;
24use super::lexer::Lexer;
25use super::token::{Span, Token, TokenKind};
26
27#[derive(Debug, Clone)]
29pub struct ParseError {
30 pub message: String,
31 pub span: Span,
32 pub expected: Vec<String>,
33}
34
35impl ParseError {
36 pub fn new(message: impl Into<String>, span: Span) -> Self {
37 Self {
38 message: message.into(),
39 span,
40 expected: Vec::new(),
41 }
42 }
43
44 pub fn expected(mut self, expected: impl Into<String>) -> Self {
45 self.expected.push(expected.into());
46 self
47 }
48}
49
50impl std::fmt::Display for ParseError {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 write!(
53 f,
54 "Parse error at line {}, column {}: {}",
55 self.span.line, self.span.column, self.message
56 )?;
57 if !self.expected.is_empty() {
58 write!(f, " (expected: {})", self.expected.join(", "))?;
59 }
60 Ok(())
61 }
62}
63
64impl std::error::Error for ParseError {}
65
66const MAX_EXPR_DEPTH: usize = 256;
74
75pub struct Parser<'a> {
77 tokens: Vec<Token<'a>>,
78 pos: usize,
79 depth: usize,
81}
82
83impl<'a> Parser<'a> {
84 pub fn new(tokens: Vec<Token<'a>>) -> Self {
86 Self {
87 tokens,
88 pos: 0,
89 depth: 0,
90 }
91 }
92
93 pub fn parse(sql: &str) -> Result<Statement, Vec<ParseError>> {
95 let tokens = Lexer::new(sql).tokenize().map_err(|lex_errors| {
96 lex_errors
97 .into_iter()
98 .map(|e| ParseError::new(e.message, e.span))
99 .collect::<Vec<_>>()
100 })?;
101
102 let mut parser = Parser::new(tokens);
103 parser.parse_statement()
104 }
105
106 pub fn parse_statements(sql: &str) -> Result<Vec<Statement>, Vec<ParseError>> {
108 let tokens = Lexer::new(sql).tokenize().map_err(|lex_errors| {
109 lex_errors
110 .into_iter()
111 .map(|e| ParseError::new(e.message, e.span))
112 .collect::<Vec<_>>()
113 })?;
114
115 let mut parser = Parser::new(tokens);
116 let mut statements = Vec::new();
117
118 while !parser.is_at_end() {
119 match parser.parse_statement() {
120 Ok(stmt) => {
121 statements.push(stmt);
122 parser.match_token(&TokenKind::Semicolon);
124 }
125 Err(errors) => return Err(errors),
126 }
127 }
128
129 Ok(statements)
130 }
131
132 fn is_at_end(&self) -> bool {
135 matches!(self.peek().kind, TokenKind::Eof)
136 }
137
138 fn peek(&self) -> &Token<'a> {
139 self.tokens
140 .get(self.pos)
141 .unwrap_or(&self.tokens[self.tokens.len() - 1])
142 }
143
144 fn peek_nth(&self, n: usize) -> &Token<'a> {
145 self.tokens
146 .get(self.pos + n)
147 .unwrap_or(&self.tokens[self.tokens.len() - 1])
148 }
149
150 fn advance(&mut self) -> Token<'a> {
151 if !self.is_at_end() {
152 self.pos += 1;
153 }
154 self.tokens.get(self.pos - 1).cloned().unwrap()
155 }
156
157 fn check(&self, kind: &TokenKind<'a>) -> bool {
158 std::mem::discriminant(&self.peek().kind) == std::mem::discriminant(kind)
159 }
160
161 fn check_keyword(&self, kw: &TokenKind<'a>) -> bool {
162 self.peek().kind == *kw
163 }
164
165 fn match_token(&mut self, kind: &TokenKind<'a>) -> bool {
166 if self.check(kind) {
167 self.advance();
168 true
169 } else {
170 false
171 }
172 }
173
174 fn expect(&mut self, kind: &TokenKind<'a>, message: &str) -> Result<Token<'a>, ParseError> {
175 if self.check(kind) {
176 Ok(self.advance())
177 } else {
178 Err(ParseError::new(message, self.peek().span).expected(format!("{:?}", kind)))
179 }
180 }
181
182 fn expect_identifier(&mut self, message: &str) -> Result<String, ParseError> {
183 match &self.peek().kind {
184 TokenKind::Identifier(name) => {
185 let name = name.to_string();
186 self.advance();
187 Ok(name)
188 }
189 TokenKind::QuotedIdentifier(name) => {
190 let name = name.to_string();
191 self.advance();
192 Ok(name)
193 }
194 _ => Err(ParseError::new(message, self.peek().span).expected("identifier")),
195 }
196 }
197
198 fn current_span(&self) -> Span {
199 self.peek().span
200 }
201
202 fn parse_statement(&mut self) -> Result<Statement, Vec<ParseError>> {
205 let result = match &self.peek().kind {
206 TokenKind::Select => self.parse_select().map(Statement::Select),
207 TokenKind::Insert => self.parse_insert().map(Statement::Insert),
208 TokenKind::Update => self.parse_update().map(Statement::Update),
209 TokenKind::Delete => self.parse_delete().map(Statement::Delete),
210 TokenKind::Create => self.parse_create(),
211 TokenKind::Drop => self.parse_drop(),
212 TokenKind::Alter => self.parse_alter(),
213 TokenKind::Define => self.parse_define(),
214 TokenKind::Remove => self.parse_remove(),
215 TokenKind::Begin => self.parse_begin().map(Statement::Begin),
216 TokenKind::Commit => {
217 self.advance();
218 Ok(Statement::Commit)
219 }
220 TokenKind::Rollback => self.parse_rollback(),
221 TokenKind::Savepoint => self.parse_savepoint(),
222 TokenKind::Release => self.parse_release(),
223 TokenKind::Relate => self.parse_relate().map(Statement::Relate),
225 TokenKind::Live => self.parse_live_select().map(Statement::LiveSelect),
226 _ => Err(ParseError::new(
227 format!("Unexpected token: {:?}", self.peek().kind),
228 self.peek().span,
229 )),
230 };
231
232 result.map_err(|e| vec![e])
233 }
234
235 fn parse_select(&mut self) -> Result<SelectStmt, ParseError> {
238 let start_span = self.current_span();
239 self.expect(&TokenKind::Select, "Expected SELECT")?;
240
241 let distinct = self.match_token(&TokenKind::Distinct);
243 if !distinct {
244 self.match_token(&TokenKind::All);
245 }
246
247 let columns = self.parse_select_list()?;
249
250 let from = if self.match_token(&TokenKind::From) {
252 Some(self.parse_from_clause()?)
253 } else {
254 None
255 };
256
257 let where_clause = if self.match_token(&TokenKind::Where) {
259 Some(self.parse_expr()?)
260 } else {
261 None
262 };
263
264 let group_by = if self.check_keyword(&TokenKind::Group) {
266 self.advance();
267 self.expect(&TokenKind::By, "Expected BY after GROUP")?;
268 self.parse_expr_list()?
269 } else {
270 Vec::new()
271 };
272
273 let having = if self.match_token(&TokenKind::Having) {
275 Some(self.parse_expr()?)
276 } else {
277 None
278 };
279
280 let order_by = if self.check_keyword(&TokenKind::Order) {
282 self.advance();
283 self.expect(&TokenKind::By, "Expected BY after ORDER")?;
284 self.parse_order_by_list()?
285 } else {
286 Vec::new()
287 };
288
289 let limit = if self.match_token(&TokenKind::Limit) {
291 Some(self.parse_expr()?)
292 } else {
293 None
294 };
295
296 let offset = if self.match_token(&TokenKind::Offset) {
298 Some(self.parse_expr()?)
299 } else {
300 None
301 };
302
303 let mut unions = Vec::new();
305 loop {
306 let set_op = if self.match_token(&TokenKind::Union) {
307 if self.match_token(&TokenKind::All) {
308 SetOp::UnionAll
309 } else {
310 SetOp::Union
311 }
312 } else if self.match_token(&TokenKind::Intersect) {
313 if self.match_token(&TokenKind::All) {
314 SetOp::IntersectAll
315 } else {
316 SetOp::Intersect
317 }
318 } else if self.match_token(&TokenKind::Except) {
319 if self.match_token(&TokenKind::All) {
320 SetOp::ExceptAll
321 } else {
322 SetOp::Except
323 }
324 } else {
325 break;
326 };
327
328 let right = self.parse_select()?;
329 unions.push((set_op, Box::new(right)));
330 }
331
332 Ok(SelectStmt {
333 span: start_span.merge(self.current_span()),
334 distinct,
335 columns,
336 from,
337 where_clause,
338 group_by,
339 having,
340 order_by,
341 limit,
342 offset,
343 unions,
344 })
345 }
346
347 fn parse_select_list(&mut self) -> Result<Vec<SelectItem>, ParseError> {
348 let mut items = Vec::new();
349
350 loop {
351 items.push(self.parse_select_item()?);
352
353 if !self.match_token(&TokenKind::Comma) {
354 break;
355 }
356 }
357
358 Ok(items)
359 }
360
361 fn parse_select_item(&mut self) -> Result<SelectItem, ParseError> {
362 if self.match_token(&TokenKind::Star) {
364 return Ok(SelectItem::Wildcard);
365 }
366
367 if let TokenKind::Identifier(name) = &self.peek().kind
369 && self.peek_nth(1).kind == TokenKind::Dot
370 && self.peek_nth(2).kind == TokenKind::Star
371 {
372 let table = name.to_string();
373 self.advance(); self.advance(); self.advance(); return Ok(SelectItem::QualifiedWildcard(table));
377 }
378
379 let expr = self.parse_expr()?;
381
382 let alias = if self.match_token(&TokenKind::As) {
383 Some(self.expect_identifier("Expected alias after AS")?)
384 } else if let TokenKind::Identifier(name) = &self.peek().kind {
385 if !self.check_keyword(&TokenKind::From)
387 && !self.check_keyword(&TokenKind::Where)
388 && !self.check(&TokenKind::Comma)
389 && !self.check_keyword(&TokenKind::Order)
390 && !self.check_keyword(&TokenKind::Group)
391 && !self.check_keyword(&TokenKind::Limit)
392 && !self.is_at_end()
393 {
394 let name = name.to_string();
395 self.advance();
396 Some(name)
397 } else {
398 None
399 }
400 } else {
401 None
402 };
403
404 Ok(SelectItem::Expr { expr, alias })
405 }
406
407 fn parse_from_clause(&mut self) -> Result<FromClause, ParseError> {
408 let mut tables = vec![self.parse_table_ref()?];
409
410 while self.match_token(&TokenKind::Comma) {
411 tables.push(self.parse_table_ref()?);
412 }
413
414 Ok(FromClause { tables })
415 }
416
417 fn parse_table_ref(&mut self) -> Result<TableRef, ParseError> {
418 let mut table = self.parse_table_primary()?;
419
420 loop {
422 let join_type = if self.match_token(&TokenKind::Cross) {
423 self.expect(&TokenKind::Join, "Expected JOIN after CROSS")?;
424 JoinType::Cross
425 } else if self.match_token(&TokenKind::Inner) {
426 self.expect(&TokenKind::Join, "Expected JOIN after INNER")?;
427 JoinType::Inner
428 } else if self.match_token(&TokenKind::Left) {
429 self.match_token(&TokenKind::Outer);
430 self.expect(&TokenKind::Join, "Expected JOIN after LEFT")?;
431 JoinType::Left
432 } else if self.match_token(&TokenKind::Right) {
433 self.match_token(&TokenKind::Outer);
434 self.expect(&TokenKind::Join, "Expected JOIN after RIGHT")?;
435 JoinType::Right
436 } else if self.match_token(&TokenKind::Join) {
437 JoinType::Inner } else {
439 break;
440 };
441
442 let right = self.parse_table_primary()?;
443
444 let condition = if join_type == JoinType::Cross {
445 None
446 } else if self.match_token(&TokenKind::On) {
447 Some(JoinCondition::On(self.parse_expr()?))
448 } else if self.match_token(&TokenKind::Using) {
449 self.expect(&TokenKind::LParen, "Expected '(' after USING")?;
450 let columns = self.parse_identifier_list()?;
451 self.expect(&TokenKind::RParen, "Expected ')' after USING columns")?;
452 Some(JoinCondition::Using(columns))
453 } else {
454 return Err(ParseError::new(
455 "Expected ON or USING clause for JOIN",
456 self.current_span(),
457 ));
458 };
459
460 table = TableRef::Join {
461 left: Box::new(table),
462 join_type,
463 right: Box::new(right),
464 condition,
465 };
466 }
467
468 Ok(table)
469 }
470
471 fn parse_table_primary(&mut self) -> Result<TableRef, ParseError> {
472 if self.match_token(&TokenKind::LParen) {
474 let query = self.parse_select()?;
475 self.expect(&TokenKind::RParen, "Expected ')' after subquery")?;
476
477 self.match_token(&TokenKind::As);
478 let alias = self.expect_identifier("Subquery requires an alias")?;
479
480 return Ok(TableRef::Subquery {
481 query: Box::new(query),
482 alias,
483 });
484 }
485
486 let name = self.parse_object_name()?;
488
489 let alias = if self.match_token(&TokenKind::As) {
491 Some(self.expect_identifier("Expected alias after AS")?)
492 } else if let TokenKind::Identifier(id) = &self.peek().kind {
493 if !self.peek().kind.is_keyword() {
495 let alias = id.to_string();
496 self.advance();
497 Some(alias)
498 } else {
499 None
500 }
501 } else {
502 None
503 };
504
505 Ok(TableRef::Table { name, alias })
506 }
507
508 fn parse_insert(&mut self) -> Result<InsertStmt, ParseError> {
511 let start_span = self.current_span();
512 self.expect(&TokenKind::Insert, "Expected INSERT")?;
513
514 let mysql_ignore = self.match_token(&TokenKind::Ignore);
516
517 let sqlite_conflict_action = if self.match_token(&TokenKind::Or) {
519 if self.match_token(&TokenKind::Ignore) {
520 Some(ConflictAction::DoNothing)
521 } else if self.match_token(&TokenKind::Replace) {
522 Some(ConflictAction::DoReplace)
523 } else if self.match_token(&TokenKind::Abort) {
524 Some(ConflictAction::DoAbort)
525 } else if self.match_token(&TokenKind::Fail) {
526 Some(ConflictAction::DoFail)
527 } else {
528 return Err(ParseError::new(
529 "Expected IGNORE, REPLACE, ABORT, or FAIL after OR",
530 self.current_span(),
531 ));
532 }
533 } else {
534 None
535 };
536
537 self.expect(&TokenKind::Into, "Expected INTO")?;
538
539 let table = self.parse_object_name()?;
540
541 let columns = if self.match_token(&TokenKind::LParen) {
543 let cols = self.parse_identifier_list()?;
544 self.expect(&TokenKind::RParen, "Expected ')' after column list")?;
545 Some(cols)
546 } else {
547 None
548 };
549
550 let source = if self.match_token(&TokenKind::Values) {
552 InsertSource::Values(self.parse_values_list()?)
553 } else if self.check_keyword(&TokenKind::Select) {
554 InsertSource::Query(Box::new(self.parse_select()?))
555 } else if self.match_token(&TokenKind::Default) {
556 self.expect(&TokenKind::Values, "Expected VALUES after DEFAULT")?;
557 InsertSource::Default
558 } else {
559 return Err(ParseError::new(
560 "Expected VALUES or SELECT",
561 self.current_span(),
562 ));
563 };
564
565 let on_conflict = if self.match_token(&TokenKind::On) {
567 if self.match_token(&TokenKind::Conflict) {
568 Some(self.parse_on_conflict()?)
570 } else if self.match_token(&TokenKind::Duplicate) {
571 self.expect(&TokenKind::Key, "Expected KEY after DUPLICATE")?;
573 self.expect(&TokenKind::Update, "Expected UPDATE after KEY")?;
574 let assignments = self.parse_assignments()?;
575 Some(OnConflict {
576 target: None,
577 action: ConflictAction::DoUpdate(assignments),
578 })
579 } else {
580 return Err(ParseError::new(
581 "Expected CONFLICT or DUPLICATE after ON",
582 self.current_span(),
583 ));
584 }
585 } else if mysql_ignore {
586 Some(OnConflict {
588 target: None,
589 action: ConflictAction::DoNothing,
590 })
591 } else {
592 sqlite_conflict_action.map(|action| OnConflict {
594 target: None,
595 action,
596 })
597 };
598
599 let returning = if self.match_token(&TokenKind::Returning) {
601 Some(self.parse_select_list()?)
602 } else {
603 None
604 };
605
606 Ok(InsertStmt {
607 span: start_span.merge(self.current_span()),
608 table,
609 columns,
610 source,
611 on_conflict,
612 returning,
613 })
614 }
615
616 fn parse_on_conflict(&mut self) -> Result<OnConflict, ParseError> {
618 let target = if self.match_token(&TokenKind::LParen) {
620 let cols = self.parse_identifier_list()?;
621 self.expect(&TokenKind::RParen, "Expected ')' after conflict columns")?;
622 Some(ConflictTarget::Columns(cols))
623 } else if self.match_token(&TokenKind::On) {
624 None
628 } else {
629 None
630 };
631
632 self.expect(&TokenKind::Do, "Expected DO after ON CONFLICT")?;
634
635 let action = if self.match_token(&TokenKind::Nothing) {
636 ConflictAction::DoNothing
637 } else if self.match_token(&TokenKind::Update) {
638 self.expect(&TokenKind::Set, "Expected SET after UPDATE")?;
639 let assignments = self.parse_assignments()?;
640 ConflictAction::DoUpdate(assignments)
641 } else {
642 return Err(ParseError::new(
643 "Expected NOTHING or UPDATE after DO",
644 self.current_span(),
645 ));
646 };
647
648 Ok(OnConflict { target, action })
649 }
650
651 fn parse_values_list(&mut self) -> Result<Vec<Vec<Expr>>, ParseError> {
652 let mut rows = Vec::new();
653
654 loop {
655 self.expect(&TokenKind::LParen, "Expected '(' for VALUES row")?;
656 let row = self.parse_expr_list()?;
657 self.expect(&TokenKind::RParen, "Expected ')' after VALUES row")?;
658 rows.push(row);
659
660 if !self.match_token(&TokenKind::Comma) {
661 break;
662 }
663 }
664
665 Ok(rows)
666 }
667
668 fn parse_update(&mut self) -> Result<UpdateStmt, ParseError> {
671 let start_span = self.current_span();
672 self.expect(&TokenKind::Update, "Expected UPDATE")?;
673
674 let table = self.parse_object_name()?;
675
676 let alias = if self.match_token(&TokenKind::As) {
677 Some(self.expect_identifier("Expected alias after AS")?)
678 } else {
679 None
680 };
681
682 self.expect(&TokenKind::Set, "Expected SET")?;
683
684 let assignments = self.parse_assignments()?;
685
686 let from = if self.match_token(&TokenKind::From) {
687 Some(self.parse_from_clause()?)
688 } else {
689 None
690 };
691
692 let where_clause = if self.match_token(&TokenKind::Where) {
693 Some(self.parse_expr()?)
694 } else {
695 None
696 };
697
698 let returning = None; Ok(UpdateStmt {
701 span: start_span.merge(self.current_span()),
702 table,
703 alias,
704 assignments,
705 from,
706 where_clause,
707 returning,
708 })
709 }
710
711 fn parse_assignments(&mut self) -> Result<Vec<Assignment>, ParseError> {
712 let mut assignments = Vec::new();
713
714 loop {
715 let column = self.expect_identifier("Expected column name")?;
716 self.expect(&TokenKind::Eq, "Expected '=' after column name")?;
717 let value = self.parse_expr()?;
718
719 assignments.push(Assignment { column, value });
720
721 if !self.match_token(&TokenKind::Comma) {
722 break;
723 }
724 }
725
726 Ok(assignments)
727 }
728
729 fn parse_delete(&mut self) -> Result<DeleteStmt, ParseError> {
732 let start_span = self.current_span();
733 self.expect(&TokenKind::Delete, "Expected DELETE")?;
734 self.expect(&TokenKind::From, "Expected FROM")?;
735
736 let table = self.parse_object_name()?;
737
738 let alias = if self.match_token(&TokenKind::As) {
739 Some(self.expect_identifier("Expected alias after AS")?)
740 } else {
741 None
742 };
743
744 let using = None; let where_clause = if self.match_token(&TokenKind::Where) {
747 Some(self.parse_expr()?)
748 } else {
749 None
750 };
751
752 Ok(DeleteStmt {
753 span: start_span.merge(self.current_span()),
754 table,
755 alias,
756 using,
757 where_clause,
758 returning: None,
759 })
760 }
761
762 fn parse_create(&mut self) -> Result<Statement, ParseError> {
765 self.expect(&TokenKind::Create, "Expected CREATE")?;
766
767 let unique = self.match_token(&TokenKind::Unique);
769
770 if self.match_token(&TokenKind::Table) {
771 self.parse_create_table().map(Statement::CreateTable)
772 } else if self.match_token(&TokenKind::Index) {
773 self.parse_create_index(unique).map(Statement::CreateIndex)
774 } else if unique {
775 Err(ParseError::new(
777 "Expected INDEX after UNIQUE",
778 self.current_span(),
779 ))
780 } else {
781 Err(ParseError::new(
782 "Expected TABLE or INDEX after CREATE",
783 self.current_span(),
784 ))
785 }
786 }
787
788 fn parse_create_index(&mut self, unique: bool) -> Result<CreateIndexStmt, ParseError> {
789 let start_span = self.current_span();
790
791 let if_not_exists = if self.match_token(&TokenKind::If) {
793 self.expect(&TokenKind::Not, "Expected NOT after IF")?;
794 self.expect(&TokenKind::Exists, "Expected EXISTS after IF NOT")?;
795 true
796 } else {
797 false
798 };
799
800 let name = self.expect_identifier("Expected index name")?;
802
803 self.expect(&TokenKind::On, "Expected ON after index name")?;
804
805 let table = self.parse_object_name()?;
807
808 self.expect(&TokenKind::LParen, "Expected '(' after table name")?;
810 let mut columns = Vec::new();
811 loop {
812 let col_name = self.expect_identifier("Expected column name")?;
813
814 let asc = if self.match_token(&TokenKind::Desc) {
816 false
817 } else {
818 self.match_token(&TokenKind::Asc);
819 true
820 };
821
822 columns.push(IndexColumn {
823 name: col_name,
824 asc,
825 nulls_first: None,
826 });
827
828 if !self.match_token(&TokenKind::Comma) {
829 break;
830 }
831 }
832 self.expect(&TokenKind::RParen, "Expected ')' after column list")?;
833
834 let where_clause = if self.match_token(&TokenKind::Where) {
836 Some(self.parse_expr()?)
837 } else {
838 None
839 };
840
841 Ok(CreateIndexStmt {
842 span: start_span.merge(self.current_span()),
843 unique,
844 if_not_exists,
845 name,
846 table,
847 columns,
848 where_clause,
849 index_type: None,
850 })
851 }
852
853 fn parse_create_table(&mut self) -> Result<CreateTableStmt, ParseError> {
854 let start_span = self.current_span();
855
856 let if_not_exists = if self.match_token(&TokenKind::If) {
857 self.expect(&TokenKind::Not, "Expected NOT after IF")?;
858 self.expect(&TokenKind::Exists, "Expected EXISTS after IF NOT")?;
859 true
860 } else {
861 false
862 };
863
864 let name = self.parse_object_name()?;
865
866 self.expect(&TokenKind::LParen, "Expected '(' after table name")?;
867
868 let mut columns = Vec::new();
869 let constraints = Vec::new();
870
871 loop {
872 if self.check_keyword(&TokenKind::Primary)
874 || self.check_keyword(&TokenKind::Foreign)
875 || self.check_keyword(&TokenKind::Unique)
876 {
877 break;
879 }
880
881 if self.check(&TokenKind::RParen) {
883 break;
884 }
885
886 columns.push(self.parse_column_def()?);
888
889 if !self.match_token(&TokenKind::Comma) {
890 break;
891 }
892 }
893
894 self.expect(&TokenKind::RParen, "Expected ')' after column definitions")?;
895
896 Ok(CreateTableStmt {
897 span: start_span.merge(self.current_span()),
898 if_not_exists,
899 name,
900 columns,
901 constraints,
902 options: Vec::new(),
903 })
904 }
905
906 fn parse_column_def(&mut self) -> Result<ColumnDef, ParseError> {
907 let name = self.expect_identifier("Expected column name")?;
908 let data_type = self.parse_data_type()?;
909
910 let mut constraints = Vec::new();
911
912 loop {
914 if self.match_token(&TokenKind::Primary) {
915 self.expect(&TokenKind::Key, "Expected KEY after PRIMARY")?;
916 constraints.push(ColumnConstraint::PrimaryKey);
917 } else if self.match_token(&TokenKind::Not) {
918 self.expect(&TokenKind::Null, "Expected NULL after NOT")?;
919 constraints.push(ColumnConstraint::NotNull);
920 } else if self.match_token(&TokenKind::Null) {
921 constraints.push(ColumnConstraint::Null);
922 } else if self.match_token(&TokenKind::Unique) {
923 constraints.push(ColumnConstraint::Unique);
924 } else if self.match_token(&TokenKind::Default) {
925 constraints.push(ColumnConstraint::Default(self.parse_expr()?));
926 } else if self.match_token(&TokenKind::AutoIncrement) {
927 constraints.push(ColumnConstraint::AutoIncrement);
928 } else {
929 break;
930 }
931 }
932
933 Ok(ColumnDef {
934 name,
935 data_type,
936 constraints,
937 })
938 }
939
940 fn parse_data_type(&mut self) -> Result<DataType, ParseError> {
941 let type_name = match &self.peek().kind {
942 TokenKind::Int | TokenKind::IntegerKw => {
943 self.advance();
944 DataType::Int
945 }
946 TokenKind::Bigint => {
947 self.advance();
948 DataType::BigInt
949 }
950 TokenKind::Smallint => {
951 self.advance();
952 DataType::SmallInt
953 }
954 TokenKind::Tinyint => {
955 self.advance();
956 DataType::TinyInt
957 }
958 TokenKind::FloatKw | TokenKind::Real => {
959 self.advance();
960 DataType::Float
961 }
962 TokenKind::Double => {
963 self.advance();
964 DataType::Double
965 }
966 TokenKind::Varchar => {
967 self.advance();
968 let len = self.parse_type_length()?;
969 DataType::Varchar(len)
970 }
971 TokenKind::Char => {
972 self.advance();
973 let len = self.parse_type_length()?;
974 DataType::Char(len)
975 }
976 TokenKind::Text => {
977 self.advance();
978 DataType::Text
979 }
980 TokenKind::BlobKw => {
981 self.advance();
982 DataType::Blob
983 }
984 TokenKind::Boolean | TokenKind::Bool => {
985 self.advance();
986 DataType::Boolean
987 }
988 TokenKind::Date => {
989 self.advance();
990 DataType::Date
991 }
992 TokenKind::Time => {
993 self.advance();
994 DataType::Time
995 }
996 TokenKind::Timestamp | TokenKind::Datetime => {
997 self.advance();
998 DataType::Timestamp
999 }
1000 TokenKind::Vector => {
1001 self.advance();
1002 let dims = self.parse_type_length()?.unwrap_or(128);
1003 DataType::Vector(dims)
1004 }
1005 TokenKind::Embedding => {
1006 self.advance();
1007 let dims = self.parse_type_length()?.unwrap_or(1536);
1008 DataType::Embedding(dims)
1009 }
1010 TokenKind::Identifier(name) => {
1011 let name = name.to_string();
1012 self.advance();
1013 DataType::Custom(name)
1014 }
1015 _ => {
1016 return Err(ParseError::new(
1017 format!("Expected data type, got {:?}", self.peek().kind),
1018 self.current_span(),
1019 ));
1020 }
1021 };
1022
1023 Ok(type_name)
1024 }
1025
1026 fn parse_type_length(&mut self) -> Result<Option<u32>, ParseError> {
1027 if self.match_token(&TokenKind::LParen) {
1028 let len = match &self.peek().kind {
1029 TokenKind::Integer(n) => {
1030 let n = *n as u32;
1031 self.advance();
1032 n
1033 }
1034 _ => return Err(ParseError::new("Expected integer", self.current_span())),
1035 };
1036 self.expect(&TokenKind::RParen, "Expected ')'")?;
1037 Ok(Some(len))
1038 } else {
1039 Ok(None)
1040 }
1041 }
1042
1043 fn parse_drop(&mut self) -> Result<Statement, ParseError> {
1044 let start_span = self.current_span();
1045 self.expect(&TokenKind::Drop, "Expected DROP")?;
1046
1047 if self.match_token(&TokenKind::Table) {
1048 let if_exists = if self.match_token(&TokenKind::If) {
1049 self.expect(&TokenKind::Exists, "Expected EXISTS after IF")?;
1050 true
1051 } else {
1052 false
1053 };
1054
1055 let name = self.parse_object_name()?;
1056 let cascade = false; Ok(Statement::DropTable(DropTableStmt {
1059 span: start_span.merge(self.current_span()),
1060 if_exists,
1061 names: vec![name],
1062 cascade,
1063 }))
1064 } else if self.match_token(&TokenKind::Index) {
1065 let if_exists = if self.match_token(&TokenKind::If) {
1066 self.expect(&TokenKind::Exists, "Expected EXISTS after IF")?;
1067 true
1068 } else {
1069 false
1070 };
1071
1072 let name = self.expect_identifier("Expected index name")?;
1073
1074 let table = if self.match_token(&TokenKind::On) {
1076 Some(self.parse_object_name()?)
1077 } else {
1078 None
1079 };
1080
1081 Ok(Statement::DropIndex(DropIndexStmt {
1082 span: start_span.merge(self.current_span()),
1083 if_exists,
1084 name,
1085 table,
1086 cascade: false,
1087 }))
1088 } else {
1089 Err(ParseError::new(
1090 "Expected TABLE or INDEX after DROP",
1091 self.current_span(),
1092 ))
1093 }
1094 }
1095
1096 fn parse_alter(&mut self) -> Result<Statement, ParseError> {
1097 let start_span = self.current_span();
1098 self.expect(&TokenKind::Alter, "Expected ALTER")?;
1099 self.expect(&TokenKind::Table, "Expected TABLE after ALTER")?;
1100
1101 let name = self.parse_object_name()?;
1102 let mut operations = Vec::new();
1103
1104 loop {
1105 let op = self.parse_alter_table_op()?;
1106 operations.push(op);
1107
1108 if !self.match_token(&TokenKind::Comma) {
1109 break;
1110 }
1111 }
1112
1113 Ok(Statement::AlterTable(AlterTableStmt {
1114 span: start_span.merge(self.current_span()),
1115 name,
1116 operations,
1117 }))
1118 }
1119
1120 fn parse_alter_table_op(&mut self) -> Result<AlterTableOp, ParseError> {
1121 if self.match_token(&TokenKind::Add) {
1122 self.match_token(&TokenKind::Column); let col_def = self.parse_column_def()?;
1125 Ok(AlterTableOp::AddColumn(col_def))
1126 } else if self.match_token(&TokenKind::Drop) {
1127 self.match_token(&TokenKind::Column); let col_name = self.expect_identifier("Expected column name after DROP")?;
1130 let cascade = self.match_token(&TokenKind::Cascade);
1131 Ok(AlterTableOp::DropColumn {
1132 name: col_name,
1133 cascade,
1134 })
1135 } else if self.match_token(&TokenKind::Rename) {
1136 if self.match_token(&TokenKind::Column) {
1137 let old_name = self.expect_identifier("Expected old column name")?;
1139 self.expect(&TokenKind::To, "Expected TO after column name")?;
1140 let new_name = self.expect_identifier("Expected new column name")?;
1141 Ok(AlterTableOp::RenameColumn { old_name, new_name })
1142 } else if self.match_token(&TokenKind::To) {
1143 let new_name = self.parse_object_name()?;
1145 Ok(AlterTableOp::RenameTable(new_name))
1146 } else {
1147 let old_name = self.expect_identifier("Expected column name or TO")?;
1149 self.expect(&TokenKind::To, "Expected TO after column name")?;
1150 let new_name = self.expect_identifier("Expected new column name")?;
1151 Ok(AlterTableOp::RenameColumn { old_name, new_name })
1152 }
1153 } else if self.match_token(&TokenKind::Alter) {
1154 self.match_token(&TokenKind::Column); let col_name = self.expect_identifier("Expected column name after ALTER COLUMN")?;
1157
1158 let operation = if self.match_token(&TokenKind::Set) {
1159 if self.match_token(&TokenKind::Not) {
1160 self.expect(&TokenKind::Null, "Expected NULL after SET NOT")?;
1161 AlterColumnOp::SetNotNull
1162 } else if self.match_token(&TokenKind::Default) {
1163 let expr = self.parse_expr()?;
1164 AlterColumnOp::SetDefault(expr)
1165 } else {
1166 if self.check_keyword(&TokenKind::Identifier("TYPE")) {
1169 self.advance(); }
1171 let data_type = self.parse_data_type()?;
1172 AlterColumnOp::SetType(data_type)
1173 }
1174 } else if self.match_token(&TokenKind::Drop) {
1175 if self.match_token(&TokenKind::Not) {
1176 self.expect(&TokenKind::Null, "Expected NULL after DROP NOT")?;
1177 AlterColumnOp::DropNotNull
1178 } else if self.match_token(&TokenKind::Default) {
1179 AlterColumnOp::DropDefault
1180 } else {
1181 return Err(ParseError::new(
1182 "Expected NOT NULL or DEFAULT after DROP",
1183 self.current_span(),
1184 ));
1185 }
1186 } else {
1187 if self.check_keyword(&TokenKind::Identifier("TYPE")) {
1189 self.advance(); }
1191 let data_type = self.parse_data_type()?;
1192 AlterColumnOp::SetType(data_type)
1193 };
1194
1195 Ok(AlterTableOp::AlterColumn {
1196 name: col_name,
1197 operation,
1198 })
1199 } else {
1200 Err(ParseError::new(
1201 "Expected ADD, DROP, RENAME, or ALTER after ALTER TABLE <name>",
1202 self.current_span(),
1203 ))
1204 }
1205 }
1206
1207 fn parse_relate(&mut self) -> Result<RelateStmt, ParseError> {
1216 let start_span = self.current_span();
1217 self.expect(&TokenKind::Relate, "Expected RELATE")?;
1218
1219 let from = self.parse_additive_expr()?;
1222
1223 self.expect(&TokenKind::Arrow, "Expected '->' after source record")?;
1225 let edge = self.parse_object_name()?;
1226 self.expect(&TokenKind::Arrow, "Expected '->' after edge table")?;
1227
1228 let to = self.parse_additive_expr()?;
1229
1230 let mut set = Vec::new();
1232 let mut content = None;
1233 let mut returning = None;
1234
1235 if self.match_token(&TokenKind::Set) {
1236 set = self.parse_assignments()?;
1237 } else if self.match_token(&TokenKind::Content) {
1238 content = Some(self.parse_expr()?);
1239 }
1240
1241 if self.match_token(&TokenKind::Returning) {
1243 returning = Some(self.parse_select_list()?);
1244 }
1245
1246 Ok(RelateStmt {
1247 span: start_span.merge(self.current_span()),
1248 from,
1249 edge,
1250 to,
1251 set,
1252 content,
1253 returning,
1254 })
1255 }
1256
1257 fn parse_live_select(&mut self) -> Result<LiveSelectStmt, ParseError> {
1264 let start_span = self.current_span();
1265 self.expect(&TokenKind::Live, "Expected LIVE")?;
1266
1267 let diff = self.match_token(&TokenKind::Diff);
1269
1270 let select = self.parse_select()?;
1272
1273 Ok(LiveSelectStmt {
1274 span: start_span.merge(self.current_span()),
1275 select,
1276 diff,
1277 })
1278 }
1279
1280 fn parse_define(&mut self) -> Result<Statement, ParseError> {
1288 self.expect(&TokenKind::Define, "Expected DEFINE")?;
1289
1290 if self.match_token(&TokenKind::Scope) {
1291 self.parse_define_scope()
1292 } else if self.match_token(&TokenKind::Table) {
1293 self.parse_define_table_permissions()
1294 } else if self.match_token(&TokenKind::Event) {
1295 self.parse_define_event()
1296 } else {
1297 Err(ParseError::new(
1298 "Expected SCOPE, TABLE, or EVENT after DEFINE",
1299 self.current_span(),
1300 ))
1301 }
1302 }
1303
1304 fn parse_define_scope(&mut self) -> Result<Statement, ParseError> {
1306 let name = self.expect_identifier("Expected scope name after DEFINE SCOPE")?;
1307
1308 let mut session_duration_secs = None;
1309 let mut signin = None;
1310 let mut signup = None;
1311
1312 loop {
1314 if self.match_token(&TokenKind::Session) {
1315 match &self.peek().kind {
1318 TokenKind::Integer(n) => {
1319 session_duration_secs = Some(*n as u64);
1320 self.advance();
1321 }
1322 TokenKind::Identifier(s) => {
1323 session_duration_secs = Some(parse_duration_string(s));
1324 self.advance();
1325 }
1326 TokenKind::String(s) => {
1327 session_duration_secs = Some(parse_duration_string(s.as_ref()));
1328 self.advance();
1329 }
1330 _ => {
1331 return Err(ParseError::new(
1332 "Expected duration after SESSION",
1333 self.current_span(),
1334 ));
1335 }
1336 }
1337 } else if self.match_token(&TokenKind::Signin) {
1338 self.expect(&TokenKind::LParen, "Expected '(' after SIGNIN")?;
1339 let expr = self.parse_expr()?;
1340 self.expect(&TokenKind::RParen, "Expected ')' after SIGNIN expression")?;
1341 signin = Some(Box::new(expr));
1342 } else if self.match_token(&TokenKind::Signup) {
1343 self.expect(&TokenKind::LParen, "Expected '(' after SIGNUP")?;
1344 let expr = self.parse_expr()?;
1345 self.expect(&TokenKind::RParen, "Expected ')' after SIGNUP expression")?;
1346 signup = Some(Box::new(expr));
1347 } else {
1348 break;
1349 }
1350 }
1351
1352 Ok(Statement::DefineScope(DefineScopeStmt {
1353 name,
1354 session_duration_secs,
1355 signin,
1356 signup,
1357 }))
1358 }
1359
1360 fn parse_define_table_permissions(&mut self) -> Result<Statement, ParseError> {
1362 let table = self.parse_object_name()?;
1363 self.expect(
1364 &TokenKind::Permissions,
1365 "Expected PERMISSIONS after table name",
1366 )?;
1367
1368 let mut permissions = Vec::new();
1369 loop {
1370 if !self.match_token(&TokenKind::For) {
1371 break;
1372 }
1373
1374 let operation = self.parse_permission_op()?;
1375 self.expect(&TokenKind::Where, "Expected WHERE after FOR <operation>")?;
1376 let condition = self.parse_expr()?;
1377
1378 permissions.push(TablePermission {
1379 operation,
1380 condition,
1381 });
1382 }
1383
1384 Ok(Statement::DefineTablePermissions(
1385 DefineTablePermissionsStmt { table, permissions },
1386 ))
1387 }
1388
1389 fn parse_permission_op(&mut self) -> Result<PermissionOp, ParseError> {
1391 match &self.peek().kind {
1392 TokenKind::Select => {
1393 self.advance();
1394 Ok(PermissionOp::Select)
1395 }
1396 TokenKind::Insert => {
1397 self.advance();
1398 Ok(PermissionOp::Create)
1399 }
1400 TokenKind::Update => {
1401 self.advance();
1402 Ok(PermissionOp::Update)
1403 }
1404 TokenKind::Delete => {
1405 self.advance();
1406 Ok(PermissionOp::Delete)
1407 }
1408 TokenKind::Create => {
1409 self.advance();
1410 Ok(PermissionOp::Create)
1411 }
1412 TokenKind::Identifier(s) if s.eq_ignore_ascii_case("CREATE") => {
1413 self.advance();
1414 Ok(PermissionOp::Create)
1415 }
1416 _ => Err(ParseError::new(
1417 "Expected SELECT, CREATE, INSERT, UPDATE, or DELETE after FOR",
1418 self.current_span(),
1419 )),
1420 }
1421 }
1422
1423 fn parse_remove(&mut self) -> Result<Statement, ParseError> {
1425 self.expect(&TokenKind::Remove, "Expected REMOVE")?;
1426 self.expect(&TokenKind::Scope, "Expected SCOPE after REMOVE")?;
1427 let name = self.expect_identifier("Expected scope name after REMOVE SCOPE")?;
1428 Ok(Statement::RemoveScope(name))
1429 }
1430
1431 fn parse_define_event(&mut self) -> Result<Statement, ParseError> {
1433 let start_span = self.current_span();
1434 let name = self.expect_identifier("Expected event name after DEFINE EVENT")?;
1435
1436 self.expect(&TokenKind::On, "Expected ON after event name")?;
1438 self.match_token(&TokenKind::Table); let table = self.parse_object_name()?;
1440
1441 self.expect(&TokenKind::When, "Expected WHEN")?;
1443 let condition = self.parse_expr()?;
1444
1445 self.expect(&TokenKind::Then, "Expected THEN")?;
1447 let action = self.parse_expr()?;
1448
1449 Ok(Statement::DefineEvent(DefineEventStmt {
1450 span: start_span.merge(self.current_span()),
1451 name,
1452 table,
1453 condition,
1454 action,
1455 }))
1456 }
1457
1458 fn parse_begin(&mut self) -> Result<BeginStmt, ParseError> {
1461 self.expect(&TokenKind::Begin, "Expected BEGIN")?;
1462 self.match_token(&TokenKind::Transaction);
1463
1464 Ok(BeginStmt {
1466 read_only: false,
1467 isolation_level: None,
1468 })
1469 }
1470
1471 fn parse_rollback(&mut self) -> Result<Statement, ParseError> {
1472 self.expect(&TokenKind::Rollback, "Expected ROLLBACK")?;
1473 self.match_token(&TokenKind::Transaction);
1474
1475 Ok(Statement::Rollback(None))
1479 }
1480
1481 fn parse_savepoint(&mut self) -> Result<Statement, ParseError> {
1482 self.expect(&TokenKind::Savepoint, "Expected SAVEPOINT")?;
1483 let name = self.expect_identifier("Expected savepoint name")?;
1484 Ok(Statement::Savepoint(name))
1485 }
1486
1487 fn parse_release(&mut self) -> Result<Statement, ParseError> {
1488 self.expect(&TokenKind::Release, "Expected RELEASE")?;
1489 self.match_token(&TokenKind::Savepoint);
1490 let name = self.expect_identifier("Expected savepoint name")?;
1491 Ok(Statement::Release(name))
1492 }
1493
1494 #[inline]
1500 fn enter_recursion(&mut self) -> Result<(), ParseError> {
1501 self.depth += 1;
1502 if self.depth > MAX_EXPR_DEPTH {
1503 self.depth -= 1;
1504 return Err(ParseError::new(
1505 "expression nesting too deep",
1506 self.current_span(),
1507 ));
1508 }
1509 Ok(())
1510 }
1511
1512 #[inline]
1513 fn exit_recursion(&mut self) {
1514 self.depth = self.depth.saturating_sub(1);
1515 }
1516
1517 fn parse_expr(&mut self) -> Result<Expr, ParseError> {
1518 self.enter_recursion()?;
1519 let r = self.parse_or_expr();
1520 self.exit_recursion();
1521 r
1522 }
1523
1524 fn parse_or_expr(&mut self) -> Result<Expr, ParseError> {
1525 let mut left = self.parse_and_expr()?;
1526
1527 while self.match_token(&TokenKind::Or) {
1528 let right = self.parse_and_expr()?;
1529 left = Expr::BinaryOp {
1530 left: Box::new(left),
1531 op: BinaryOperator::Or,
1532 right: Box::new(right),
1533 };
1534 }
1535
1536 Ok(left)
1537 }
1538
1539 fn parse_and_expr(&mut self) -> Result<Expr, ParseError> {
1540 let mut left = self.parse_not_expr()?;
1541
1542 while self.match_token(&TokenKind::And) {
1543 let right = self.parse_not_expr()?;
1544 left = Expr::BinaryOp {
1545 left: Box::new(left),
1546 op: BinaryOperator::And,
1547 right: Box::new(right),
1548 };
1549 }
1550
1551 Ok(left)
1552 }
1553
1554 fn parse_not_expr(&mut self) -> Result<Expr, ParseError> {
1555 self.enter_recursion()?;
1556 let r = if self.match_token(&TokenKind::Not) {
1557 self.parse_not_expr().map(|expr| Expr::UnaryOp {
1558 op: UnaryOperator::Not,
1559 expr: Box::new(expr),
1560 })
1561 } else {
1562 self.parse_comparison_expr()
1563 };
1564 self.exit_recursion();
1565 r
1566 }
1567
1568 fn parse_comparison_expr(&mut self) -> Result<Expr, ParseError> {
1569 let mut left = self.parse_graph_expr()?;
1570
1571 if self.match_token(&TokenKind::Is) {
1573 let negated = self.match_token(&TokenKind::Not);
1574 self.expect(&TokenKind::Null, "Expected NULL after IS")?;
1575 return Ok(Expr::IsNull {
1576 expr: Box::new(left),
1577 negated,
1578 });
1579 }
1580
1581 let negated = self.match_token(&TokenKind::Not);
1583 if self.match_token(&TokenKind::In) {
1584 self.expect(&TokenKind::LParen, "Expected '(' after IN")?;
1585
1586 if self.check_keyword(&TokenKind::Select) {
1587 let subquery = self.parse_select()?;
1588 self.expect(&TokenKind::RParen, "Expected ')'")?;
1589 return Ok(Expr::InSubquery {
1590 expr: Box::new(left),
1591 subquery: Box::new(subquery),
1592 negated,
1593 });
1594 } else {
1595 let list = self.parse_expr_list()?;
1596 self.expect(&TokenKind::RParen, "Expected ')'")?;
1597 return Ok(Expr::InList {
1598 expr: Box::new(left),
1599 list,
1600 negated,
1601 });
1602 }
1603 }
1604
1605 if self.match_token(&TokenKind::Between) {
1607 let low = self.parse_graph_expr()?;
1608 self.expect(&TokenKind::And, "Expected AND in BETWEEN")?;
1609 let high = self.parse_graph_expr()?;
1610 return Ok(Expr::Between {
1611 expr: Box::new(left),
1612 low: Box::new(low),
1613 high: Box::new(high),
1614 negated,
1615 });
1616 }
1617
1618 if self.match_token(&TokenKind::Like) {
1620 let pattern = self.parse_graph_expr()?;
1621 let escape = if self.match_token(&TokenKind::Escape) {
1622 Some(Box::new(self.parse_graph_expr()?))
1623 } else {
1624 None
1625 };
1626 return Ok(Expr::Like {
1627 expr: Box::new(left),
1628 pattern: Box::new(pattern),
1629 escape,
1630 negated,
1631 });
1632 }
1633
1634 if negated {
1636 return Err(ParseError::new(
1637 "Expected IN, BETWEEN, or LIKE after NOT",
1638 self.current_span(),
1639 ));
1640 }
1641
1642 let op = match &self.peek().kind {
1644 TokenKind::Eq => Some(BinaryOperator::Eq),
1645 TokenKind::Ne => Some(BinaryOperator::Ne),
1646 TokenKind::Lt => Some(BinaryOperator::Lt),
1647 TokenKind::Le => Some(BinaryOperator::Le),
1648 TokenKind::Gt => Some(BinaryOperator::Gt),
1649 TokenKind::Ge => Some(BinaryOperator::Ge),
1650 _ => None,
1651 };
1652
1653 if let Some(op) = op {
1654 self.advance();
1655 let right = self.parse_graph_expr()?;
1656 left = Expr::BinaryOp {
1657 left: Box::new(left),
1658 op,
1659 right: Box::new(right),
1660 };
1661 }
1662
1663 Ok(left)
1664 }
1665
1666 fn parse_graph_expr(&mut self) -> Result<Expr, ParseError> {
1676 let mut left = self.parse_additive_expr()?;
1677
1678 loop {
1679 let op = match &self.peek().kind {
1680 TokenKind::Arrow => BinaryOperator::GraphRight,
1681 TokenKind::LeftArrow => BinaryOperator::GraphLeft,
1682 TokenKind::BiArrow => BinaryOperator::GraphBi,
1683 _ => break,
1684 };
1685 self.advance();
1686
1687 let right = self.parse_additive_expr()?;
1688 left = Expr::BinaryOp {
1689 left: Box::new(left),
1690 op,
1691 right: Box::new(right),
1692 };
1693 }
1694
1695 Ok(left)
1696 }
1697
1698 fn parse_additive_expr(&mut self) -> Result<Expr, ParseError> {
1699 let mut left = self.parse_multiplicative_expr()?;
1700
1701 loop {
1702 let op = match &self.peek().kind {
1703 TokenKind::Plus => BinaryOperator::Plus,
1704 TokenKind::Minus => BinaryOperator::Minus,
1705 TokenKind::Concat => BinaryOperator::Concat,
1706 _ => break,
1707 };
1708 self.advance();
1709
1710 let right = self.parse_multiplicative_expr()?;
1711 left = Expr::BinaryOp {
1712 left: Box::new(left),
1713 op,
1714 right: Box::new(right),
1715 };
1716 }
1717
1718 Ok(left)
1719 }
1720
1721 fn parse_multiplicative_expr(&mut self) -> Result<Expr, ParseError> {
1722 let mut left = self.parse_unary_expr()?;
1723
1724 loop {
1725 let op = match &self.peek().kind {
1726 TokenKind::Star => BinaryOperator::Multiply,
1727 TokenKind::Slash => BinaryOperator::Divide,
1728 TokenKind::Percent => BinaryOperator::Modulo,
1729 _ => break,
1730 };
1731 self.advance();
1732
1733 let right = self.parse_unary_expr()?;
1734 left = Expr::BinaryOp {
1735 left: Box::new(left),
1736 op,
1737 right: Box::new(right),
1738 };
1739 }
1740
1741 Ok(left)
1742 }
1743
1744 fn parse_unary_expr(&mut self) -> Result<Expr, ParseError> {
1745 let op = match &self.peek().kind {
1748 TokenKind::Minus => Some(UnaryOperator::Minus),
1749 TokenKind::Plus => Some(UnaryOperator::Plus),
1750 TokenKind::BitNot => Some(UnaryOperator::BitNot),
1751 _ => None,
1752 };
1753 match op {
1754 Some(op) => {
1755 self.advance();
1756 self.enter_recursion()?;
1757 let inner = self.parse_unary_expr();
1758 self.exit_recursion();
1759 inner.map(|expr| Expr::UnaryOp {
1760 op,
1761 expr: Box::new(expr),
1762 })
1763 }
1764 None => self.parse_primary_expr(),
1765 }
1766 }
1767
1768 fn parse_primary_expr(&mut self) -> Result<Expr, ParseError> {
1769 let expr = match self.peek().kind.clone() {
1770 TokenKind::Integer(n) => {
1772 self.advance();
1773 Expr::Literal(Literal::Integer(n))
1774 }
1775 TokenKind::Float(n) => {
1776 self.advance();
1777 Expr::Literal(Literal::Float(n))
1778 }
1779 TokenKind::String(s) => {
1780 self.advance();
1781 Expr::Literal(Literal::String(s.into_owned()))
1782 }
1783 TokenKind::Blob(b) => {
1784 self.advance();
1785 Expr::Literal(Literal::Blob(b))
1786 }
1787 TokenKind::True => {
1788 self.advance();
1789 Expr::Literal(Literal::Boolean(true))
1790 }
1791 TokenKind::False => {
1792 self.advance();
1793 Expr::Literal(Literal::Boolean(false))
1794 }
1795 TokenKind::Null => {
1796 self.advance();
1797 Expr::Literal(Literal::Null)
1798 }
1799
1800 TokenKind::Placeholder(n) => {
1802 self.advance();
1803 Expr::Placeholder(n)
1804 }
1805
1806 TokenKind::LParen => {
1808 self.advance();
1809 if self.check_keyword(&TokenKind::Select) {
1810 let query = self.parse_select()?;
1811 self.expect(&TokenKind::RParen, "Expected ')'")?;
1812 Expr::Subquery(Box::new(query))
1813 } else {
1814 let expr = self.parse_expr()?;
1815
1816 if self.match_token(&TokenKind::Comma) {
1818 let mut exprs = vec![expr];
1819 exprs.push(self.parse_expr()?);
1820 while self.match_token(&TokenKind::Comma) {
1821 exprs.push(self.parse_expr()?);
1822 }
1823 self.expect(&TokenKind::RParen, "Expected ')'")?;
1824 Expr::Tuple(exprs)
1825 } else {
1826 self.expect(&TokenKind::RParen, "Expected ')'")?;
1827 expr
1828 }
1829 }
1830 }
1831
1832 TokenKind::Case => {
1834 self.advance();
1835 self.parse_case_expr()?
1836 }
1837
1838 TokenKind::Exists => {
1840 self.advance();
1841 self.expect(&TokenKind::LParen, "Expected '(' after EXISTS")?;
1842 let query = self.parse_select()?;
1843 self.expect(&TokenKind::RParen, "Expected ')'")?;
1844 Expr::Exists(Box::new(query))
1845 }
1846
1847 TokenKind::Cast => {
1849 self.advance();
1850 self.expect(&TokenKind::LParen, "Expected '(' after CAST")?;
1851 let expr = self.parse_expr()?;
1852 self.expect(&TokenKind::As, "Expected AS in CAST")?;
1853 let data_type = self.parse_data_type()?;
1854 self.expect(&TokenKind::RParen, "Expected ')'")?;
1855 Expr::Cast {
1856 expr: Box::new(expr),
1857 data_type,
1858 }
1859 }
1860
1861 TokenKind::VectorSearch => {
1863 self.advance();
1864 self.parse_vector_search()?
1865 }
1866 TokenKind::ContextWindow => {
1867 self.advance();
1868 self.parse_context_window()?
1869 }
1870
1871 TokenKind::Count
1873 | TokenKind::Sum
1874 | TokenKind::Avg
1875 | TokenKind::Min
1876 | TokenKind::Max => self.parse_aggregate_function()?,
1877
1878 TokenKind::Identifier(_) | TokenKind::QuotedIdentifier(_) => {
1880 self.parse_identifier_or_function()?
1881 }
1882
1883 TokenKind::Vector | TokenKind::Embedding | TokenKind::Text | TokenKind::BlobKw => {
1885 let name = match &self.peek().kind {
1887 TokenKind::Vector => "vector".to_string(),
1888 TokenKind::Embedding => "embedding".to_string(),
1889 TokenKind::Text => "text".to_string(),
1890 TokenKind::BlobKw => "blob".to_string(),
1891 _ => unreachable!(),
1892 };
1893 self.advance();
1894 Expr::Column(ColumnRef::new(name))
1895 }
1896
1897 _ => {
1898 return Err(ParseError::new(
1899 format!("Unexpected token in expression: {:?}", self.peek().kind),
1900 self.current_span(),
1901 ));
1902 }
1903 };
1904
1905 self.parse_postfix_expr(expr)
1907 }
1908
1909 fn parse_postfix_expr(&mut self, mut expr: Expr) -> Result<Expr, ParseError> {
1910 loop {
1911 if self.match_token(&TokenKind::LBracket) {
1912 let index = self.parse_expr()?;
1914 self.expect(&TokenKind::RBracket, "Expected ']'")?;
1915 expr = Expr::Subscript {
1916 expr: Box::new(expr),
1917 index: Box::new(index),
1918 };
1919 } else if self.match_token(&TokenKind::DoubleArrow) {
1920 let path = self.parse_primary_expr()?;
1922 expr = Expr::JsonAccess {
1923 expr: Box::new(expr),
1924 path: Box::new(path),
1925 return_text: true,
1926 };
1927 } else if self.match_token(&TokenKind::DoubleColon) {
1928 let data_type = self.parse_data_type()?;
1930 expr = Expr::Cast {
1931 expr: Box::new(expr),
1932 data_type,
1933 };
1934 } else if self.match_token(&TokenKind::Colon) {
1935 if let Expr::Column(ref col) = expr {
1937 if col.table.is_none() {
1938 let table = col.column.clone();
1939 let id = self.parse_primary_expr()?;
1940 expr = Expr::RecordId {
1941 table,
1942 id: Box::new(id),
1943 };
1944 continue;
1945 }
1946 }
1947 return Err(ParseError::new(
1948 "Unexpected ':' — record ID requires unqualified identifier on left",
1949 self.current_span(),
1950 ));
1951 } else {
1952 break;
1953 }
1954 }
1955
1956 Ok(expr)
1957 }
1958
1959 fn parse_case_expr(&mut self) -> Result<Expr, ParseError> {
1960 let operand = if !self.check_keyword(&TokenKind::When) {
1964 Some(Box::new(self.parse_expr()?))
1965 } else {
1966 None
1967 };
1968
1969 let mut conditions = Vec::new();
1970
1971 while self.match_token(&TokenKind::When) {
1972 let when_expr = self.parse_expr()?;
1973 self.expect(&TokenKind::Then, "Expected THEN")?;
1974 let then_expr = self.parse_expr()?;
1975 conditions.push((when_expr, then_expr));
1976 }
1977
1978 let else_result = if self.match_token(&TokenKind::Else) {
1979 Some(Box::new(self.parse_expr()?))
1980 } else {
1981 None
1982 };
1983
1984 self.expect(&TokenKind::End, "Expected END")?;
1985
1986 Ok(Expr::Case {
1987 operand,
1988 conditions,
1989 else_result,
1990 })
1991 }
1992
1993 fn parse_identifier_or_function(&mut self) -> Result<Expr, ParseError> {
1994 let name = self.parse_object_name()?;
1995
1996 if self.match_token(&TokenKind::LParen) {
1998 let args = if self.check(&TokenKind::RParen) {
1999 Vec::new()
2000 } else {
2001 self.parse_expr_list()?
2002 };
2003 self.expect(&TokenKind::RParen, "Expected ')'")?;
2004
2005 Ok(Expr::Function(FunctionCall {
2006 name,
2007 args,
2008 distinct: false,
2009 filter: None,
2010 over: None,
2011 }))
2012 } else {
2013 let parts = name.parts;
2015 if parts.len() == 1 {
2016 Ok(Expr::Column(ColumnRef::new(
2017 parts.into_iter().next().unwrap(),
2018 )))
2019 } else if parts.len() == 2 {
2020 let mut iter = parts.into_iter();
2021 let table = iter.next().unwrap();
2022 let column = iter.next().unwrap();
2023 Ok(Expr::Column(ColumnRef::qualified(table, column)))
2024 } else {
2025 Err(ParseError::new(
2026 "Invalid column reference",
2027 self.current_span(),
2028 ))
2029 }
2030 }
2031 }
2032
2033 fn parse_aggregate_function(&mut self) -> Result<Expr, ParseError> {
2034 let name = match &self.peek().kind {
2035 TokenKind::Count => "COUNT",
2036 TokenKind::Sum => "SUM",
2037 TokenKind::Avg => "AVG",
2038 TokenKind::Min => "MIN",
2039 TokenKind::Max => "MAX",
2040 _ => {
2041 return Err(ParseError::new(
2042 "Expected aggregate function",
2043 self.current_span(),
2044 ));
2045 }
2046 };
2047 self.advance();
2048
2049 self.expect(&TokenKind::LParen, "Expected '(' after aggregate function")?;
2050
2051 let distinct = self.match_token(&TokenKind::Distinct);
2052
2053 let args = if self.match_token(&TokenKind::Star) {
2054 vec![Expr::Column(ColumnRef::new("*"))]
2055 } else {
2056 self.parse_expr_list()?
2057 };
2058
2059 self.expect(&TokenKind::RParen, "Expected ')'")?;
2060
2061 Ok(Expr::Function(FunctionCall {
2062 name: ObjectName::new(name),
2063 args,
2064 distinct,
2065 filter: None,
2066 over: None,
2067 }))
2068 }
2069
2070 fn parse_vector_search(&mut self) -> Result<Expr, ParseError> {
2071 self.expect(&TokenKind::LParen, "Expected '(' after VECTOR_SEARCH")?;
2072
2073 let column = self.parse_expr()?;
2074 self.expect(&TokenKind::Comma, "Expected ','")?;
2075
2076 let query = self.parse_expr()?;
2077 self.expect(&TokenKind::Comma, "Expected ','")?;
2078
2079 let k = match &self.peek().kind {
2080 TokenKind::Integer(n) => *n as u32,
2081 _ => return Err(ParseError::new("Expected integer k", self.current_span())),
2082 };
2083 self.advance();
2084
2085 let metric = if self.match_token(&TokenKind::Comma) {
2086 match &self.peek().kind {
2087 TokenKind::Cosine => {
2088 self.advance();
2089 VectorMetric::Cosine
2090 }
2091 TokenKind::Euclidean => {
2092 self.advance();
2093 VectorMetric::Euclidean
2094 }
2095 TokenKind::DotProduct => {
2096 self.advance();
2097 VectorMetric::DotProduct
2098 }
2099 _ => VectorMetric::Cosine,
2100 }
2101 } else {
2102 VectorMetric::Cosine
2103 };
2104
2105 self.expect(&TokenKind::RParen, "Expected ')'")?;
2106
2107 Ok(Expr::VectorSearch {
2108 column: Box::new(column),
2109 query: Box::new(query),
2110 k,
2111 metric,
2112 })
2113 }
2114
2115 fn parse_context_window(&mut self) -> Result<Expr, ParseError> {
2116 self.expect(&TokenKind::LParen, "Expected '(' after CONTEXT_WINDOW")?;
2117
2118 let source = self.parse_expr()?;
2119 self.expect(&TokenKind::Comma, "Expected ','")?;
2120
2121 let max_tokens = match &self.peek().kind {
2122 TokenKind::Integer(n) => *n as u32,
2123 _ => {
2124 return Err(ParseError::new(
2125 "Expected integer max_tokens",
2126 self.current_span(),
2127 ));
2128 }
2129 };
2130 self.advance();
2131
2132 let priority = if self.match_token(&TokenKind::Comma) {
2133 Some(Box::new(self.parse_expr()?))
2134 } else {
2135 None
2136 };
2137
2138 self.expect(&TokenKind::RParen, "Expected ')'")?;
2139
2140 Ok(Expr::ContextWindow {
2141 source: Box::new(source),
2142 max_tokens,
2143 priority,
2144 })
2145 }
2146
2147 fn parse_object_name(&mut self) -> Result<ObjectName, ParseError> {
2150 let mut parts = Vec::new();
2151 parts.push(self.expect_identifier("Expected identifier")?);
2152
2153 while self.match_token(&TokenKind::Dot) {
2154 if self.check(&TokenKind::Star) {
2156 break;
2158 }
2159 parts.push(self.expect_identifier("Expected identifier after '.'")?);
2160 }
2161
2162 Ok(ObjectName { parts })
2163 }
2164
2165 fn parse_identifier_list(&mut self) -> Result<Vec<String>, ParseError> {
2166 let mut list = vec![self.expect_identifier("Expected identifier")?];
2167
2168 while self.match_token(&TokenKind::Comma) {
2169 list.push(self.expect_identifier("Expected identifier")?);
2170 }
2171
2172 Ok(list)
2173 }
2174
2175 fn parse_expr_list(&mut self) -> Result<Vec<Expr>, ParseError> {
2176 let mut list = vec![self.parse_expr()?];
2177
2178 while self.match_token(&TokenKind::Comma) {
2179 list.push(self.parse_expr()?);
2180 }
2181
2182 Ok(list)
2183 }
2184
2185 fn parse_order_by_list(&mut self) -> Result<Vec<OrderByItem>, ParseError> {
2186 let mut list = Vec::new();
2187
2188 loop {
2189 let expr = self.parse_expr()?;
2190
2191 let asc = if self.match_token(&TokenKind::Desc) {
2192 false
2193 } else {
2194 self.match_token(&TokenKind::Asc);
2195 true
2196 };
2197
2198 let nulls_first = if self.match_token(&TokenKind::Nulls) {
2199 if self.match_token(&TokenKind::First) {
2200 Some(true)
2201 } else if self.match_token(&TokenKind::Last) {
2202 Some(false)
2203 } else {
2204 return Err(ParseError::new(
2205 "Expected FIRST or LAST after NULLS",
2206 self.current_span(),
2207 ));
2208 }
2209 } else {
2210 None
2211 };
2212
2213 list.push(OrderByItem {
2214 expr,
2215 asc,
2216 nulls_first,
2217 });
2218
2219 if !self.match_token(&TokenKind::Comma) {
2220 break;
2221 }
2222 }
2223
2224 Ok(list)
2225 }
2226}
2227
2228#[cfg(test)]
2229mod tests {
2230 use super::*;
2231
2232 #[test]
2233 fn test_simple_select() {
2234 let stmt = Parser::parse("SELECT * FROM users").unwrap();
2235 assert!(matches!(stmt, Statement::Select(_)));
2236 }
2237
2238 #[test]
2239 fn test_deeply_nested_expr_errors_not_panics() {
2240 let depth = MAX_EXPR_DEPTH + 50;
2245 for (open, close) in [("(", ")"), ("NOT ", ""), ("-", "")] {
2246 let expr = format!(
2247 "SELECT {}1{} FROM t",
2248 open.repeat(depth),
2249 close.repeat(depth)
2250 );
2251 let r = Parser::parse(&expr);
2252 assert!(
2253 r.is_err(),
2254 "depth {} of {:?} should error, not parse/panic",
2255 depth,
2256 open
2257 );
2258 }
2259 let ok = format!("SELECT {}1{} FROM t", "(".repeat(20), ")".repeat(20));
2261 assert!(Parser::parse(&ok).is_ok(), "20-deep nesting must still parse");
2262 }
2263
2264 #[test]
2265 fn test_select_with_where() {
2266 let stmt = Parser::parse("SELECT id, name FROM users WHERE id = 1").unwrap();
2267 if let Statement::Select(select) = stmt {
2268 assert_eq!(select.columns.len(), 2);
2269 assert!(select.where_clause.is_some());
2270 } else {
2271 panic!("Expected SELECT statement");
2272 }
2273 }
2274
2275 #[test]
2276 fn test_insert() {
2277 let stmt = Parser::parse("INSERT INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2278 assert!(matches!(stmt, Statement::Insert(_)));
2279 }
2280
2281 #[test]
2282 fn test_create_table() {
2283 let stmt = Parser::parse(
2284 "CREATE TABLE users (id INTEGER PRIMARY KEY, name VARCHAR(100) NOT NULL)",
2285 )
2286 .unwrap();
2287 if let Statement::CreateTable(create) = stmt {
2288 assert_eq!(create.columns.len(), 2);
2289 } else {
2290 panic!("Expected CREATE TABLE statement");
2291 }
2292 }
2293
2294 #[test]
2295 fn test_vector_search() {
2296 let stmt = Parser::parse(
2297 "SELECT * FROM docs WHERE VECTOR_SEARCH(embedding, $1, 10, COSINE) > 0.8",
2298 )
2299 .unwrap();
2300 assert!(matches!(stmt, Statement::Select(_)));
2301 }
2302
2303 #[test]
2304 fn test_join() {
2305 let stmt = Parser::parse(
2306 "SELECT u.name, o.total FROM users u INNER JOIN orders o ON u.id = o.user_id",
2307 )
2308 .unwrap();
2309 assert!(matches!(stmt, Statement::Select(_)));
2310 }
2311
2312 #[test]
2313 fn test_subquery() {
2314 let stmt =
2315 Parser::parse("SELECT * FROM users WHERE id IN (SELECT user_id FROM orders)").unwrap();
2316 assert!(matches!(stmt, Statement::Select(_)));
2317 }
2318
2319 #[test]
2320 fn test_update() {
2321 let stmt = Parser::parse("UPDATE users SET name = 'Bob', age = 30 WHERE id = 1").unwrap();
2322 assert!(matches!(stmt, Statement::Update(_)));
2323 }
2324
2325 #[test]
2326 fn test_delete() {
2327 let stmt = Parser::parse("DELETE FROM users WHERE id = 1").unwrap();
2328 assert!(matches!(stmt, Statement::Delete(_)));
2329 }
2330
2331 #[test]
2332 fn test_group_by() {
2333 let stmt = Parser::parse(
2334 "SELECT category, COUNT(*) FROM products GROUP BY category HAVING COUNT(*) > 5",
2335 )
2336 .unwrap();
2337 if let Statement::Select(select) = stmt {
2338 assert!(!select.group_by.is_empty());
2339 assert!(select.having.is_some());
2340 } else {
2341 panic!("Expected SELECT statement");
2342 }
2343 }
2344
2345 #[test]
2346 fn test_order_by() {
2347 let stmt =
2348 Parser::parse("SELECT * FROM users ORDER BY name ASC, age DESC NULLS LAST").unwrap();
2349 if let Statement::Select(select) = stmt {
2350 assert_eq!(select.order_by.len(), 2);
2351 } else {
2352 panic!("Expected SELECT statement");
2353 }
2354 }
2355
2356 #[test]
2357 fn test_between() {
2358 let stmt = Parser::parse("SELECT * FROM products WHERE price BETWEEN 10 AND 100").unwrap();
2359 assert!(matches!(stmt, Statement::Select(_)));
2360 }
2361
2362 #[test]
2363 fn test_like() {
2364 let stmt = Parser::parse("SELECT * FROM users WHERE name LIKE '%Alice%'").unwrap();
2365 assert!(matches!(stmt, Statement::Select(_)));
2366 }
2367
2368 #[test]
2369 fn test_case() {
2370 let stmt =
2371 Parser::parse("SELECT CASE WHEN x > 0 THEN 'positive' ELSE 'non-positive' END FROM t")
2372 .unwrap();
2373 assert!(matches!(stmt, Statement::Select(_)));
2374 }
2375
2376 #[test]
2377 fn test_transactions() {
2378 let stmts = Parser::parse_statements("BEGIN; COMMIT; ROLLBACK").unwrap();
2379 assert_eq!(stmts.len(), 3);
2380 assert!(matches!(stmts[0], Statement::Begin(_)));
2381 assert!(matches!(stmts[1], Statement::Commit));
2382 assert!(matches!(stmts[2], Statement::Rollback(_)));
2383 }
2384
2385 #[test]
2388 fn test_insert_on_conflict_do_nothing() {
2389 let stmt = Parser::parse(
2390 "INSERT INTO users (id, name) VALUES (1, 'Alice') ON CONFLICT DO NOTHING",
2391 )
2392 .unwrap();
2393 if let Statement::Insert(insert) = stmt {
2394 assert!(insert.on_conflict.is_some());
2395 let on_conflict = insert.on_conflict.unwrap();
2396 assert!(matches!(on_conflict.action, ConflictAction::DoNothing));
2397 } else {
2398 panic!("Expected INSERT statement");
2399 }
2400 }
2401
2402 #[test]
2403 fn test_insert_on_conflict_do_update() {
2404 let stmt = Parser::parse(
2405 "INSERT INTO users (id, name) VALUES (1, 'Alice') ON CONFLICT (id) DO UPDATE SET name = 'Bob'",
2406 )
2407 .unwrap();
2408 if let Statement::Insert(insert) = stmt {
2409 assert!(insert.on_conflict.is_some());
2410 let on_conflict = insert.on_conflict.unwrap();
2411 assert!(matches!(
2412 on_conflict.target,
2413 Some(ConflictTarget::Columns(_))
2414 ));
2415 assert!(matches!(on_conflict.action, ConflictAction::DoUpdate(_)));
2416 } else {
2417 panic!("Expected INSERT statement");
2418 }
2419 }
2420
2421 #[test]
2422 fn test_insert_ignore_mysql() {
2423 let stmt =
2424 Parser::parse("INSERT IGNORE INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2425 if let Statement::Insert(insert) = stmt {
2426 assert!(insert.on_conflict.is_some());
2427 let on_conflict = insert.on_conflict.unwrap();
2428 assert!(matches!(on_conflict.action, ConflictAction::DoNothing));
2429 } else {
2430 panic!("Expected INSERT statement");
2431 }
2432 }
2433
2434 #[test]
2435 fn test_insert_or_ignore_sqlite() {
2436 let stmt =
2437 Parser::parse("INSERT OR IGNORE INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2438 if let Statement::Insert(insert) = stmt {
2439 assert!(insert.on_conflict.is_some());
2440 let on_conflict = insert.on_conflict.unwrap();
2441 assert!(matches!(on_conflict.action, ConflictAction::DoNothing));
2442 } else {
2443 panic!("Expected INSERT statement");
2444 }
2445 }
2446
2447 #[test]
2448 fn test_insert_or_replace_sqlite() {
2449 let stmt =
2450 Parser::parse("INSERT OR REPLACE INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2451 if let Statement::Insert(insert) = stmt {
2452 assert!(insert.on_conflict.is_some());
2453 let on_conflict = insert.on_conflict.unwrap();
2454 assert!(matches!(on_conflict.action, ConflictAction::DoReplace));
2455 } else {
2456 panic!("Expected INSERT statement");
2457 }
2458 }
2459
2460 #[test]
2461 fn test_on_duplicate_key_update_mysql() {
2462 let stmt = Parser::parse(
2463 "INSERT INTO users (id, name) VALUES (1, 'Alice') ON DUPLICATE KEY UPDATE name = 'Bob'",
2464 )
2465 .unwrap();
2466 if let Statement::Insert(insert) = stmt {
2467 assert!(insert.on_conflict.is_some());
2468 let on_conflict = insert.on_conflict.unwrap();
2469 assert!(matches!(on_conflict.action, ConflictAction::DoUpdate(_)));
2470 } else {
2471 panic!("Expected INSERT statement");
2472 }
2473 }
2474
2475 #[test]
2478 fn test_create_table_if_not_exists() {
2479 let stmt = Parser::parse("CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY)").unwrap();
2480 if let Statement::CreateTable(create) = stmt {
2481 assert!(create.if_not_exists);
2482 } else {
2483 panic!("Expected CREATE TABLE statement");
2484 }
2485 }
2486
2487 #[test]
2488 fn test_drop_table_if_exists() {
2489 let stmt = Parser::parse("DROP TABLE IF EXISTS users").unwrap();
2490 if let Statement::DropTable(drop) = stmt {
2491 assert!(drop.if_exists);
2492 } else {
2493 panic!("Expected DROP TABLE statement");
2494 }
2495 }
2496
2497 #[test]
2498 fn test_create_index() {
2499 let stmt = Parser::parse("CREATE INDEX idx_users_name ON users (name)").unwrap();
2500 if let Statement::CreateIndex(create) = stmt {
2501 assert_eq!(create.name, "idx_users_name");
2502 assert_eq!(create.table.name(), "users");
2503 assert!(!create.unique);
2504 assert!(!create.if_not_exists);
2505 } else {
2506 panic!("Expected CREATE INDEX statement");
2507 }
2508 }
2509
2510 #[test]
2511 fn test_create_unique_index() {
2512 let stmt = Parser::parse("CREATE UNIQUE INDEX idx_users_email ON users (email)").unwrap();
2513 if let Statement::CreateIndex(create) = stmt {
2514 assert!(create.unique);
2515 } else {
2516 panic!("Expected CREATE INDEX statement");
2517 }
2518 }
2519
2520 #[test]
2521 fn test_create_index_if_not_exists() {
2522 let stmt =
2523 Parser::parse("CREATE INDEX IF NOT EXISTS idx_users_name ON users (name)").unwrap();
2524 if let Statement::CreateIndex(create) = stmt {
2525 assert!(create.if_not_exists);
2526 } else {
2527 panic!("Expected CREATE INDEX statement");
2528 }
2529 }
2530
2531 #[test]
2532 fn test_drop_index() {
2533 let stmt = Parser::parse("DROP INDEX idx_users_name").unwrap();
2534 if let Statement::DropIndex(drop) = stmt {
2535 assert_eq!(drop.name, "idx_users_name");
2536 assert!(!drop.if_exists);
2537 } else {
2538 panic!("Expected DROP INDEX statement");
2539 }
2540 }
2541
2542 #[test]
2543 fn test_drop_index_if_exists() {
2544 let stmt = Parser::parse("DROP INDEX IF EXISTS idx_users_name").unwrap();
2545 if let Statement::DropIndex(drop) = stmt {
2546 assert!(drop.if_exists);
2547 } else {
2548 panic!("Expected DROP INDEX statement");
2549 }
2550 }
2551
2552 #[test]
2555 fn test_insert_returning() {
2556 let stmt =
2557 Parser::parse("INSERT INTO users (id, name) VALUES (1, 'Alice') RETURNING id, name")
2558 .unwrap();
2559 if let Statement::Insert(insert) = stmt {
2560 assert!(insert.returning.is_some());
2561 let returning = insert.returning.unwrap();
2562 assert_eq!(returning.len(), 2);
2563 } else {
2564 panic!("Expected INSERT statement");
2565 }
2566 }
2567
2568 #[test]
2569 fn test_define_scope() {
2570 let stmt =
2571 Parser::parse("DEFINE SCOPE user_scope SESSION 86400 SIGNIN (1) SIGNUP (2)").unwrap();
2572 if let Statement::DefineScope(scope) = stmt {
2573 assert_eq!(scope.name, "user_scope");
2574 assert_eq!(scope.session_duration_secs, Some(86400));
2575 assert!(scope.signin.is_some());
2576 assert!(scope.signup.is_some());
2577 } else {
2578 panic!("Expected DEFINE SCOPE statement, got {:?}", stmt);
2579 }
2580 }
2581
2582 #[test]
2583 fn test_define_table_permissions() {
2584 let stmt =
2585 Parser::parse("DEFINE TABLE post PERMISSIONS FOR select WHERE 1 FOR delete WHERE 0")
2586 .unwrap();
2587 if let Statement::DefineTablePermissions(def) = stmt {
2588 assert_eq!(def.table.to_string(), "post");
2589 assert_eq!(def.permissions.len(), 2);
2590 assert_eq!(def.permissions[0].operation, PermissionOp::Select);
2591 assert_eq!(def.permissions[1].operation, PermissionOp::Delete);
2592 } else {
2593 panic!(
2594 "Expected DEFINE TABLE PERMISSIONS statement, got {:?}",
2595 stmt
2596 );
2597 }
2598 }
2599
2600 #[test]
2601 fn test_remove_scope() {
2602 let stmt = Parser::parse("REMOVE SCOPE user_scope").unwrap();
2603 if let Statement::RemoveScope(name) = stmt {
2604 assert_eq!(name, "user_scope");
2605 } else {
2606 panic!("Expected REMOVE SCOPE statement");
2607 }
2608 }
2609
2610 #[test]
2613 fn test_graph_arrow_operator() {
2614 let stmt = Parser::parse("SELECT person -> knows FROM graph").unwrap();
2616 if let Statement::Select(select) = stmt {
2617 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2618 if let Expr::BinaryOp { op, .. } = expr {
2619 assert_eq!(*op, BinaryOperator::GraphRight);
2620 } else {
2621 panic!("Expected BinaryOp with GraphRight, got {:?}", expr);
2622 }
2623 } else {
2624 panic!("Expected Expr select item");
2625 }
2626 } else {
2627 panic!("Expected SELECT statement");
2628 }
2629 }
2630
2631 #[test]
2632 fn test_graph_left_arrow_operator() {
2633 let stmt = Parser::parse("SELECT x <- y FROM graph").unwrap();
2634 if let Statement::Select(select) = stmt {
2635 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2636 if let Expr::BinaryOp { op, .. } = expr {
2637 assert_eq!(*op, BinaryOperator::GraphLeft);
2638 } else {
2639 panic!("Expected BinaryOp with GraphLeft, got {:?}", expr);
2640 }
2641 } else {
2642 panic!("Expected Expr select item");
2643 }
2644 } else {
2645 panic!("Expected SELECT statement");
2646 }
2647 }
2648
2649 #[test]
2650 fn test_graph_biarrow_operator() {
2651 let stmt = Parser::parse("SELECT x <-> y FROM graph").unwrap();
2652 if let Statement::Select(select) = stmt {
2653 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2654 if let Expr::BinaryOp { op, .. } = expr {
2655 assert_eq!(*op, BinaryOperator::GraphBi);
2656 } else {
2657 panic!("Expected BinaryOp with GraphBi, got {:?}", expr);
2658 }
2659 } else {
2660 panic!("Expected Expr select item");
2661 }
2662 } else {
2663 panic!("Expected SELECT statement");
2664 }
2665 }
2666
2667 #[test]
2668 fn test_graph_traversal_chain() {
2669 let stmt = Parser::parse("SELECT a -> b -> c FROM graph").unwrap();
2671 if let Statement::Select(select) = stmt {
2672 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2673 if let Expr::BinaryOp { left, op, .. } = expr {
2675 assert_eq!(*op, BinaryOperator::GraphRight);
2676 if let Expr::BinaryOp { op: inner_op, .. } = left.as_ref() {
2677 assert_eq!(*inner_op, BinaryOperator::GraphRight);
2678 } else {
2679 panic!("Expected chained -> operator");
2680 }
2681 } else {
2682 panic!("Expected BinaryOp");
2683 }
2684 }
2685 }
2686 }
2687
2688 #[test]
2689 fn test_record_id_literal() {
2690 let stmt = Parser::parse("SELECT person:1 FROM people").unwrap();
2691 if let Statement::Select(select) = stmt {
2692 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2693 if let Expr::RecordId { table, id } = expr {
2694 assert_eq!(table, "person");
2695 assert!(matches!(id.as_ref(), Expr::Literal(Literal::Integer(1))));
2696 } else {
2697 panic!("Expected RecordId, got {:?}", expr);
2698 }
2699 }
2700 }
2701 }
2702
2703 #[test]
2704 fn test_record_id_with_string() {
2705 let stmt = Parser::parse("SELECT user:'abc' FROM users").unwrap();
2706 if let Statement::Select(select) = stmt {
2707 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2708 if let Expr::RecordId { table, id } = expr {
2709 assert_eq!(table, "user");
2710 if let Expr::Literal(Literal::String(s)) = id.as_ref() {
2711 assert_eq!(s, "abc");
2712 } else {
2713 panic!("Expected string id");
2714 }
2715 } else {
2716 panic!("Expected RecordId, got {:?}", expr);
2717 }
2718 }
2719 }
2720 }
2721
2722 #[test]
2723 fn test_relate_statement() {
2724 let stmt =
2725 Parser::parse("RELATE person:1 -> knows -> person:2 SET since = '2024-01-01'").unwrap();
2726 if let Statement::Relate(relate) = stmt {
2727 assert_eq!(relate.edge.to_string(), "knows");
2728 if let Expr::RecordId { table, .. } = &relate.from {
2729 assert_eq!(table, "person");
2730 } else {
2731 panic!("Expected RecordId for from, got {:?}", relate.from);
2732 }
2733 if let Expr::RecordId { table, .. } = &relate.to {
2734 assert_eq!(table, "person");
2735 } else {
2736 panic!("Expected RecordId for to, got {:?}", relate.to);
2737 }
2738 assert_eq!(relate.set.len(), 1);
2739 assert_eq!(relate.set[0].column, "since");
2740 } else {
2741 panic!("Expected RELATE statement, got {:?}", stmt);
2742 }
2743 }
2744
2745 #[test]
2746 fn test_relate_with_content() {
2747 let stmt = Parser::parse("RELATE user:1 -> follows -> user:2 CONTENT 'data'").unwrap();
2748 if let Statement::Relate(relate) = stmt {
2749 assert_eq!(relate.edge.to_string(), "follows");
2750 assert!(relate.content.is_some());
2751 assert!(relate.set.is_empty());
2752 } else {
2753 panic!("Expected RELATE statement");
2754 }
2755 }
2756
2757 #[test]
2758 fn test_live_select() {
2759 let stmt = Parser::parse("LIVE SELECT * FROM person WHERE age > 18").unwrap();
2760 if let Statement::LiveSelect(live) = stmt {
2761 assert!(!live.diff);
2762 assert_eq!(live.select.columns.len(), 1);
2763 assert!(matches!(live.select.columns[0], SelectItem::Wildcard));
2764 assert!(live.select.where_clause.is_some());
2765 } else {
2766 panic!("Expected LIVE SELECT statement, got {:?}", stmt);
2767 }
2768 }
2769
2770 #[test]
2771 fn test_live_select_diff() {
2772 let stmt = Parser::parse("LIVE DIFF SELECT * FROM person").unwrap();
2773 if let Statement::LiveSelect(live) = stmt {
2774 assert!(live.diff);
2775 } else {
2776 panic!("Expected LIVE SELECT DIFF statement");
2777 }
2778 }
2779
2780 #[test]
2781 fn test_define_event() {
2782 let stmt = Parser::parse("DEFINE EVENT notify ON TABLE user WHEN 1 THEN 2").unwrap();
2783 if let Statement::DefineEvent(event) = stmt {
2784 assert_eq!(event.name, "notify");
2785 assert_eq!(event.table.to_string(), "user");
2786 } else {
2787 panic!("Expected DEFINE EVENT statement, got {:?}", stmt);
2788 }
2789 }
2790
2791 #[test]
2792 fn test_graph_precedence_vs_comparison() {
2793 let stmt = Parser::parse("SELECT a -> b = c FROM t").unwrap();
2795 if let Statement::Select(select) = stmt {
2796 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2797 if let Expr::BinaryOp { op, left, .. } = expr {
2798 assert_eq!(*op, BinaryOperator::Eq);
2799 if let Expr::BinaryOp { op: inner_op, .. } = left.as_ref() {
2801 assert_eq!(*inner_op, BinaryOperator::GraphRight);
2802 } else {
2803 panic!("Expected -> in left operand of =");
2804 }
2805 } else {
2806 panic!("Expected comparison at top level");
2807 }
2808 }
2809 }
2810 }
2811}
2812
2813fn parse_duration_string(s: &str) -> u64 {
2819 let s = s.trim();
2820 if s.is_empty() {
2821 return 0;
2822 }
2823
2824 if let Ok(n) = s.parse::<u64>() {
2826 return n;
2827 }
2828
2829 let (num_part, suffix) = s.split_at(s.len() - 1);
2831 let n: u64 = num_part.parse().unwrap_or(0);
2832 match suffix {
2833 "s" => n,
2834 "m" => n * 60,
2835 "h" => n * 3600,
2836 "d" => n * 86400,
2837 "w" => n * 604800,
2838 _ => 0,
2839 }
2840}