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