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!(
2262 Parser::parse(&ok).is_ok(),
2263 "20-deep nesting must still parse"
2264 );
2265 }
2266
2267 #[test]
2268 fn test_select_with_where() {
2269 let stmt = Parser::parse("SELECT id, name FROM users WHERE id = 1").unwrap();
2270 if let Statement::Select(select) = stmt {
2271 assert_eq!(select.columns.len(), 2);
2272 assert!(select.where_clause.is_some());
2273 } else {
2274 panic!("Expected SELECT statement");
2275 }
2276 }
2277
2278 #[test]
2279 fn test_insert() {
2280 let stmt = Parser::parse("INSERT INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2281 assert!(matches!(stmt, Statement::Insert(_)));
2282 }
2283
2284 #[test]
2285 fn test_create_table() {
2286 let stmt = Parser::parse(
2287 "CREATE TABLE users (id INTEGER PRIMARY KEY, name VARCHAR(100) NOT NULL)",
2288 )
2289 .unwrap();
2290 if let Statement::CreateTable(create) = stmt {
2291 assert_eq!(create.columns.len(), 2);
2292 } else {
2293 panic!("Expected CREATE TABLE statement");
2294 }
2295 }
2296
2297 #[test]
2298 fn test_vector_search() {
2299 let stmt = Parser::parse(
2300 "SELECT * FROM docs WHERE VECTOR_SEARCH(embedding, $1, 10, COSINE) > 0.8",
2301 )
2302 .unwrap();
2303 assert!(matches!(stmt, Statement::Select(_)));
2304 }
2305
2306 #[test]
2307 fn test_join() {
2308 let stmt = Parser::parse(
2309 "SELECT u.name, o.total FROM users u INNER JOIN orders o ON u.id = o.user_id",
2310 )
2311 .unwrap();
2312 assert!(matches!(stmt, Statement::Select(_)));
2313 }
2314
2315 #[test]
2316 fn test_subquery() {
2317 let stmt =
2318 Parser::parse("SELECT * FROM users WHERE id IN (SELECT user_id FROM orders)").unwrap();
2319 assert!(matches!(stmt, Statement::Select(_)));
2320 }
2321
2322 #[test]
2323 fn test_update() {
2324 let stmt = Parser::parse("UPDATE users SET name = 'Bob', age = 30 WHERE id = 1").unwrap();
2325 assert!(matches!(stmt, Statement::Update(_)));
2326 }
2327
2328 #[test]
2329 fn test_delete() {
2330 let stmt = Parser::parse("DELETE FROM users WHERE id = 1").unwrap();
2331 assert!(matches!(stmt, Statement::Delete(_)));
2332 }
2333
2334 #[test]
2335 fn test_group_by() {
2336 let stmt = Parser::parse(
2337 "SELECT category, COUNT(*) FROM products GROUP BY category HAVING COUNT(*) > 5",
2338 )
2339 .unwrap();
2340 if let Statement::Select(select) = stmt {
2341 assert!(!select.group_by.is_empty());
2342 assert!(select.having.is_some());
2343 } else {
2344 panic!("Expected SELECT statement");
2345 }
2346 }
2347
2348 #[test]
2349 fn test_order_by() {
2350 let stmt =
2351 Parser::parse("SELECT * FROM users ORDER BY name ASC, age DESC NULLS LAST").unwrap();
2352 if let Statement::Select(select) = stmt {
2353 assert_eq!(select.order_by.len(), 2);
2354 } else {
2355 panic!("Expected SELECT statement");
2356 }
2357 }
2358
2359 #[test]
2360 fn test_between() {
2361 let stmt = Parser::parse("SELECT * FROM products WHERE price BETWEEN 10 AND 100").unwrap();
2362 assert!(matches!(stmt, Statement::Select(_)));
2363 }
2364
2365 #[test]
2366 fn test_like() {
2367 let stmt = Parser::parse("SELECT * FROM users WHERE name LIKE '%Alice%'").unwrap();
2368 assert!(matches!(stmt, Statement::Select(_)));
2369 }
2370
2371 #[test]
2372 fn test_case() {
2373 let stmt =
2374 Parser::parse("SELECT CASE WHEN x > 0 THEN 'positive' ELSE 'non-positive' END FROM t")
2375 .unwrap();
2376 assert!(matches!(stmt, Statement::Select(_)));
2377 }
2378
2379 #[test]
2380 fn test_transactions() {
2381 let stmts = Parser::parse_statements("BEGIN; COMMIT; ROLLBACK").unwrap();
2382 assert_eq!(stmts.len(), 3);
2383 assert!(matches!(stmts[0], Statement::Begin(_)));
2384 assert!(matches!(stmts[1], Statement::Commit));
2385 assert!(matches!(stmts[2], Statement::Rollback(_)));
2386 }
2387
2388 #[test]
2391 fn test_insert_on_conflict_do_nothing() {
2392 let stmt = Parser::parse(
2393 "INSERT INTO users (id, name) VALUES (1, 'Alice') ON CONFLICT DO NOTHING",
2394 )
2395 .unwrap();
2396 if let Statement::Insert(insert) = stmt {
2397 assert!(insert.on_conflict.is_some());
2398 let on_conflict = insert.on_conflict.unwrap();
2399 assert!(matches!(on_conflict.action, ConflictAction::DoNothing));
2400 } else {
2401 panic!("Expected INSERT statement");
2402 }
2403 }
2404
2405 #[test]
2406 fn test_insert_on_conflict_do_update() {
2407 let stmt = Parser::parse(
2408 "INSERT INTO users (id, name) VALUES (1, 'Alice') ON CONFLICT (id) DO UPDATE SET name = 'Bob'",
2409 )
2410 .unwrap();
2411 if let Statement::Insert(insert) = stmt {
2412 assert!(insert.on_conflict.is_some());
2413 let on_conflict = insert.on_conflict.unwrap();
2414 assert!(matches!(
2415 on_conflict.target,
2416 Some(ConflictTarget::Columns(_))
2417 ));
2418 assert!(matches!(on_conflict.action, ConflictAction::DoUpdate(_)));
2419 } else {
2420 panic!("Expected INSERT statement");
2421 }
2422 }
2423
2424 #[test]
2425 fn test_insert_ignore_mysql() {
2426 let stmt =
2427 Parser::parse("INSERT IGNORE INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2428 if let Statement::Insert(insert) = stmt {
2429 assert!(insert.on_conflict.is_some());
2430 let on_conflict = insert.on_conflict.unwrap();
2431 assert!(matches!(on_conflict.action, ConflictAction::DoNothing));
2432 } else {
2433 panic!("Expected INSERT statement");
2434 }
2435 }
2436
2437 #[test]
2438 fn test_insert_or_ignore_sqlite() {
2439 let stmt =
2440 Parser::parse("INSERT OR IGNORE INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2441 if let Statement::Insert(insert) = stmt {
2442 assert!(insert.on_conflict.is_some());
2443 let on_conflict = insert.on_conflict.unwrap();
2444 assert!(matches!(on_conflict.action, ConflictAction::DoNothing));
2445 } else {
2446 panic!("Expected INSERT statement");
2447 }
2448 }
2449
2450 #[test]
2451 fn test_insert_or_replace_sqlite() {
2452 let stmt =
2453 Parser::parse("INSERT OR REPLACE INTO users (id, name) VALUES (1, 'Alice')").unwrap();
2454 if let Statement::Insert(insert) = stmt {
2455 assert!(insert.on_conflict.is_some());
2456 let on_conflict = insert.on_conflict.unwrap();
2457 assert!(matches!(on_conflict.action, ConflictAction::DoReplace));
2458 } else {
2459 panic!("Expected INSERT statement");
2460 }
2461 }
2462
2463 #[test]
2464 fn test_on_duplicate_key_update_mysql() {
2465 let stmt = Parser::parse(
2466 "INSERT INTO users (id, name) VALUES (1, 'Alice') ON DUPLICATE KEY UPDATE name = 'Bob'",
2467 )
2468 .unwrap();
2469 if let Statement::Insert(insert) = stmt {
2470 assert!(insert.on_conflict.is_some());
2471 let on_conflict = insert.on_conflict.unwrap();
2472 assert!(matches!(on_conflict.action, ConflictAction::DoUpdate(_)));
2473 } else {
2474 panic!("Expected INSERT statement");
2475 }
2476 }
2477
2478 #[test]
2481 fn test_create_table_if_not_exists() {
2482 let stmt = Parser::parse("CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY)").unwrap();
2483 if let Statement::CreateTable(create) = stmt {
2484 assert!(create.if_not_exists);
2485 } else {
2486 panic!("Expected CREATE TABLE statement");
2487 }
2488 }
2489
2490 #[test]
2491 fn test_drop_table_if_exists() {
2492 let stmt = Parser::parse("DROP TABLE IF EXISTS users").unwrap();
2493 if let Statement::DropTable(drop) = stmt {
2494 assert!(drop.if_exists);
2495 } else {
2496 panic!("Expected DROP TABLE statement");
2497 }
2498 }
2499
2500 #[test]
2501 fn test_create_index() {
2502 let stmt = Parser::parse("CREATE INDEX idx_users_name ON users (name)").unwrap();
2503 if let Statement::CreateIndex(create) = stmt {
2504 assert_eq!(create.name, "idx_users_name");
2505 assert_eq!(create.table.name(), "users");
2506 assert!(!create.unique);
2507 assert!(!create.if_not_exists);
2508 } else {
2509 panic!("Expected CREATE INDEX statement");
2510 }
2511 }
2512
2513 #[test]
2514 fn test_create_unique_index() {
2515 let stmt = Parser::parse("CREATE UNIQUE INDEX idx_users_email ON users (email)").unwrap();
2516 if let Statement::CreateIndex(create) = stmt {
2517 assert!(create.unique);
2518 } else {
2519 panic!("Expected CREATE INDEX statement");
2520 }
2521 }
2522
2523 #[test]
2524 fn test_create_index_if_not_exists() {
2525 let stmt =
2526 Parser::parse("CREATE INDEX IF NOT EXISTS idx_users_name ON users (name)").unwrap();
2527 if let Statement::CreateIndex(create) = stmt {
2528 assert!(create.if_not_exists);
2529 } else {
2530 panic!("Expected CREATE INDEX statement");
2531 }
2532 }
2533
2534 #[test]
2535 fn test_drop_index() {
2536 let stmt = Parser::parse("DROP INDEX idx_users_name").unwrap();
2537 if let Statement::DropIndex(drop) = stmt {
2538 assert_eq!(drop.name, "idx_users_name");
2539 assert!(!drop.if_exists);
2540 } else {
2541 panic!("Expected DROP INDEX statement");
2542 }
2543 }
2544
2545 #[test]
2546 fn test_drop_index_if_exists() {
2547 let stmt = Parser::parse("DROP INDEX IF EXISTS idx_users_name").unwrap();
2548 if let Statement::DropIndex(drop) = stmt {
2549 assert!(drop.if_exists);
2550 } else {
2551 panic!("Expected DROP INDEX statement");
2552 }
2553 }
2554
2555 #[test]
2558 fn test_insert_returning() {
2559 let stmt =
2560 Parser::parse("INSERT INTO users (id, name) VALUES (1, 'Alice') RETURNING id, name")
2561 .unwrap();
2562 if let Statement::Insert(insert) = stmt {
2563 assert!(insert.returning.is_some());
2564 let returning = insert.returning.unwrap();
2565 assert_eq!(returning.len(), 2);
2566 } else {
2567 panic!("Expected INSERT statement");
2568 }
2569 }
2570
2571 #[test]
2572 fn test_define_scope() {
2573 let stmt =
2574 Parser::parse("DEFINE SCOPE user_scope SESSION 86400 SIGNIN (1) SIGNUP (2)").unwrap();
2575 if let Statement::DefineScope(scope) = stmt {
2576 assert_eq!(scope.name, "user_scope");
2577 assert_eq!(scope.session_duration_secs, Some(86400));
2578 assert!(scope.signin.is_some());
2579 assert!(scope.signup.is_some());
2580 } else {
2581 panic!("Expected DEFINE SCOPE statement, got {:?}", stmt);
2582 }
2583 }
2584
2585 #[test]
2586 fn test_define_table_permissions() {
2587 let stmt =
2588 Parser::parse("DEFINE TABLE post PERMISSIONS FOR select WHERE 1 FOR delete WHERE 0")
2589 .unwrap();
2590 if let Statement::DefineTablePermissions(def) = stmt {
2591 assert_eq!(def.table.to_string(), "post");
2592 assert_eq!(def.permissions.len(), 2);
2593 assert_eq!(def.permissions[0].operation, PermissionOp::Select);
2594 assert_eq!(def.permissions[1].operation, PermissionOp::Delete);
2595 } else {
2596 panic!(
2597 "Expected DEFINE TABLE PERMISSIONS statement, got {:?}",
2598 stmt
2599 );
2600 }
2601 }
2602
2603 #[test]
2604 fn test_remove_scope() {
2605 let stmt = Parser::parse("REMOVE SCOPE user_scope").unwrap();
2606 if let Statement::RemoveScope(name) = stmt {
2607 assert_eq!(name, "user_scope");
2608 } else {
2609 panic!("Expected REMOVE SCOPE statement");
2610 }
2611 }
2612
2613 #[test]
2616 fn test_graph_arrow_operator() {
2617 let stmt = Parser::parse("SELECT person -> knows FROM graph").unwrap();
2619 if let Statement::Select(select) = stmt {
2620 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2621 if let Expr::BinaryOp { op, .. } = expr {
2622 assert_eq!(*op, BinaryOperator::GraphRight);
2623 } else {
2624 panic!("Expected BinaryOp with GraphRight, got {:?}", expr);
2625 }
2626 } else {
2627 panic!("Expected Expr select item");
2628 }
2629 } else {
2630 panic!("Expected SELECT statement");
2631 }
2632 }
2633
2634 #[test]
2635 fn test_graph_left_arrow_operator() {
2636 let stmt = Parser::parse("SELECT x <- y FROM graph").unwrap();
2637 if let Statement::Select(select) = stmt {
2638 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2639 if let Expr::BinaryOp { op, .. } = expr {
2640 assert_eq!(*op, BinaryOperator::GraphLeft);
2641 } else {
2642 panic!("Expected BinaryOp with GraphLeft, got {:?}", expr);
2643 }
2644 } else {
2645 panic!("Expected Expr select item");
2646 }
2647 } else {
2648 panic!("Expected SELECT statement");
2649 }
2650 }
2651
2652 #[test]
2653 fn test_graph_biarrow_operator() {
2654 let stmt = Parser::parse("SELECT x <-> y FROM graph").unwrap();
2655 if let Statement::Select(select) = stmt {
2656 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2657 if let Expr::BinaryOp { op, .. } = expr {
2658 assert_eq!(*op, BinaryOperator::GraphBi);
2659 } else {
2660 panic!("Expected BinaryOp with GraphBi, got {:?}", expr);
2661 }
2662 } else {
2663 panic!("Expected Expr select item");
2664 }
2665 } else {
2666 panic!("Expected SELECT statement");
2667 }
2668 }
2669
2670 #[test]
2671 fn test_graph_traversal_chain() {
2672 let stmt = Parser::parse("SELECT a -> b -> c FROM graph").unwrap();
2674 if let Statement::Select(select) = stmt {
2675 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2676 if let Expr::BinaryOp { left, op, .. } = expr {
2678 assert_eq!(*op, BinaryOperator::GraphRight);
2679 if let Expr::BinaryOp { op: inner_op, .. } = left.as_ref() {
2680 assert_eq!(*inner_op, BinaryOperator::GraphRight);
2681 } else {
2682 panic!("Expected chained -> operator");
2683 }
2684 } else {
2685 panic!("Expected BinaryOp");
2686 }
2687 }
2688 }
2689 }
2690
2691 #[test]
2692 fn test_record_id_literal() {
2693 let stmt = Parser::parse("SELECT person:1 FROM people").unwrap();
2694 if let Statement::Select(select) = stmt {
2695 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2696 if let Expr::RecordId { table, id } = expr {
2697 assert_eq!(table, "person");
2698 assert!(matches!(id.as_ref(), Expr::Literal(Literal::Integer(1))));
2699 } else {
2700 panic!("Expected RecordId, got {:?}", expr);
2701 }
2702 }
2703 }
2704 }
2705
2706 #[test]
2707 fn test_record_id_with_string() {
2708 let stmt = Parser::parse("SELECT user:'abc' FROM users").unwrap();
2709 if let Statement::Select(select) = stmt {
2710 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2711 if let Expr::RecordId { table, id } = expr {
2712 assert_eq!(table, "user");
2713 if let Expr::Literal(Literal::String(s)) = id.as_ref() {
2714 assert_eq!(s, "abc");
2715 } else {
2716 panic!("Expected string id");
2717 }
2718 } else {
2719 panic!("Expected RecordId, got {:?}", expr);
2720 }
2721 }
2722 }
2723 }
2724
2725 #[test]
2726 fn test_relate_statement() {
2727 let stmt =
2728 Parser::parse("RELATE person:1 -> knows -> person:2 SET since = '2024-01-01'").unwrap();
2729 if let Statement::Relate(relate) = stmt {
2730 assert_eq!(relate.edge.to_string(), "knows");
2731 if let Expr::RecordId { table, .. } = &relate.from {
2732 assert_eq!(table, "person");
2733 } else {
2734 panic!("Expected RecordId for from, got {:?}", relate.from);
2735 }
2736 if let Expr::RecordId { table, .. } = &relate.to {
2737 assert_eq!(table, "person");
2738 } else {
2739 panic!("Expected RecordId for to, got {:?}", relate.to);
2740 }
2741 assert_eq!(relate.set.len(), 1);
2742 assert_eq!(relate.set[0].column, "since");
2743 } else {
2744 panic!("Expected RELATE statement, got {:?}", stmt);
2745 }
2746 }
2747
2748 #[test]
2749 fn test_relate_with_content() {
2750 let stmt = Parser::parse("RELATE user:1 -> follows -> user:2 CONTENT 'data'").unwrap();
2751 if let Statement::Relate(relate) = stmt {
2752 assert_eq!(relate.edge.to_string(), "follows");
2753 assert!(relate.content.is_some());
2754 assert!(relate.set.is_empty());
2755 } else {
2756 panic!("Expected RELATE statement");
2757 }
2758 }
2759
2760 #[test]
2761 fn test_live_select() {
2762 let stmt = Parser::parse("LIVE SELECT * FROM person WHERE age > 18").unwrap();
2763 if let Statement::LiveSelect(live) = stmt {
2764 assert!(!live.diff);
2765 assert_eq!(live.select.columns.len(), 1);
2766 assert!(matches!(live.select.columns[0], SelectItem::Wildcard));
2767 assert!(live.select.where_clause.is_some());
2768 } else {
2769 panic!("Expected LIVE SELECT statement, got {:?}", stmt);
2770 }
2771 }
2772
2773 #[test]
2774 fn test_live_select_diff() {
2775 let stmt = Parser::parse("LIVE DIFF SELECT * FROM person").unwrap();
2776 if let Statement::LiveSelect(live) = stmt {
2777 assert!(live.diff);
2778 } else {
2779 panic!("Expected LIVE SELECT DIFF statement");
2780 }
2781 }
2782
2783 #[test]
2784 fn test_define_event() {
2785 let stmt = Parser::parse("DEFINE EVENT notify ON TABLE user WHEN 1 THEN 2").unwrap();
2786 if let Statement::DefineEvent(event) = stmt {
2787 assert_eq!(event.name, "notify");
2788 assert_eq!(event.table.to_string(), "user");
2789 } else {
2790 panic!("Expected DEFINE EVENT statement, got {:?}", stmt);
2791 }
2792 }
2793
2794 #[test]
2795 fn test_graph_precedence_vs_comparison() {
2796 let stmt = Parser::parse("SELECT a -> b = c FROM t").unwrap();
2798 if let Statement::Select(select) = stmt {
2799 if let SelectItem::Expr { expr, .. } = &select.columns[0] {
2800 if let Expr::BinaryOp { op, left, .. } = expr {
2801 assert_eq!(*op, BinaryOperator::Eq);
2802 if let Expr::BinaryOp { op: inner_op, .. } = left.as_ref() {
2804 assert_eq!(*inner_op, BinaryOperator::GraphRight);
2805 } else {
2806 panic!("Expected -> in left operand of =");
2807 }
2808 } else {
2809 panic!("Expected comparison at top level");
2810 }
2811 }
2812 }
2813 }
2814}
2815
2816fn parse_duration_string(s: &str) -> u64 {
2822 let s = s.trim();
2823 if s.is_empty() {
2824 return 0;
2825 }
2826
2827 if let Ok(n) = s.parse::<u64>() {
2829 return n;
2830 }
2831
2832 let (num_part, suffix) = s.split_at(s.len() - 1);
2834 let n: u64 = num_part.parse().unwrap_or(0);
2835 match suffix {
2836 "s" => n,
2837 "m" => n * 60,
2838 "h" => n * 3600,
2839 "d" => n * 86400,
2840 "w" => n * 604800,
2841 _ => 0,
2842 }
2843}