1pub use super::parser::ast::{
5 Condition, JoinClause, JoinCondition, JoinOperator, JoinType, LogicalOp, OrderByColumn,
6 SelectItem, SelectStatement, SortDirection, SqlExpression, TableFunction, TableSource,
7 WhenBranch, WhereClause, WindowSpec, CTE,
8};
9pub use super::parser::legacy::{ParseContext, ParseState, Schema, SqlParser, SqlToken, TableInfo};
10pub use super::parser::lexer::{Lexer, Token};
11pub use super::parser::ParserConfig;
12
13pub use super::parser::formatter::{format_ast_tree, format_sql_pretty, format_sql_pretty_compact};
15
16pub use super::parser::ast_formatter::{format_sql_ast, format_sql_ast_with_config, FormatConfig};
18
19use super::parser::expressions::arithmetic::{
21 parse_additive as parse_additive_expr, parse_multiplicative as parse_multiplicative_expr,
22 ParseArithmetic,
23};
24use super::parser::expressions::case::{parse_case_expression as parse_case_expr, ParseCase};
25use super::parser::expressions::comparison::{
26 parse_comparison as parse_comparison_expr, parse_in_operator, ParseComparison,
27};
28use super::parser::expressions::logical::{
29 parse_logical_and as parse_logical_and_expr, parse_logical_or as parse_logical_or_expr,
30 ParseLogical,
31};
32use super::parser::expressions::primary::{
33 parse_primary as parse_primary_expr, ParsePrimary, PrimaryExpressionContext,
34};
35pub struct Parser {
36 lexer: Lexer,
37 current_token: Token,
38 in_method_args: bool, columns: Vec<String>, paren_depth: i32, #[allow(dead_code)]
42 config: ParserConfig, }
44
45impl Parser {
46 #[must_use]
47 pub fn new(input: &str) -> Self {
48 let mut lexer = Lexer::new(input);
49 let current_token = lexer.next_token();
50 Self {
51 lexer,
52 current_token,
53 in_method_args: false,
54 columns: Vec::new(),
55 paren_depth: 0,
56 config: ParserConfig::default(),
57 }
58 }
59
60 #[must_use]
61 pub fn with_config(input: &str, config: ParserConfig) -> Self {
62 let mut lexer = Lexer::new(input);
63 let current_token = lexer.next_token();
64 Self {
65 lexer,
66 current_token,
67 in_method_args: false,
68 columns: Vec::new(),
69 paren_depth: 0,
70 config,
71 }
72 }
73
74 #[must_use]
75 pub fn with_columns(mut self, columns: Vec<String>) -> Self {
76 self.columns = columns;
77 self
78 }
79
80 fn consume(&mut self, expected: Token) -> Result<(), String> {
81 if std::mem::discriminant(&self.current_token) == std::mem::discriminant(&expected) {
82 match &expected {
84 Token::LeftParen => self.paren_depth += 1,
85 Token::RightParen => {
86 self.paren_depth -= 1;
87 if self.paren_depth < 0 {
89 return Err(
90 "Unexpected closing parenthesis - no matching opening parenthesis"
91 .to_string(),
92 );
93 }
94 }
95 _ => {}
96 }
97
98 self.current_token = self.lexer.next_token();
99 Ok(())
100 } else {
101 let error_msg = match (&expected, &self.current_token) {
103 (Token::RightParen, Token::Eof) if self.paren_depth > 0 => {
104 format!(
105 "Unclosed parenthesis - missing {} closing parenthes{}",
106 self.paren_depth,
107 if self.paren_depth == 1 { "is" } else { "es" }
108 )
109 }
110 (Token::RightParen, _) if self.paren_depth > 0 => {
111 format!(
112 "Expected closing parenthesis but found {:?} (currently {} unclosed parenthes{})",
113 self.current_token,
114 self.paren_depth,
115 if self.paren_depth == 1 { "is" } else { "es" }
116 )
117 }
118 _ => format!("Expected {:?}, found {:?}", expected, self.current_token),
119 };
120 Err(error_msg)
121 }
122 }
123
124 fn advance(&mut self) {
125 match &self.current_token {
127 Token::LeftParen => self.paren_depth += 1,
128 Token::RightParen => {
129 self.paren_depth -= 1;
130 }
133 _ => {}
134 }
135 self.current_token = self.lexer.next_token();
136 }
137
138 pub fn parse(&mut self) -> Result<SelectStatement, String> {
139 if matches!(self.current_token, Token::With) {
141 self.parse_with_clause()
142 } else {
143 self.parse_select_statement()
144 }
145 }
146
147 fn parse_with_clause(&mut self) -> Result<SelectStatement, String> {
148 self.consume(Token::With)?;
149
150 let mut ctes = Vec::new();
151
152 loop {
154 let name = match &self.current_token {
156 Token::Identifier(name) => name.clone(),
157 _ => return Err("Expected CTE name after WITH".to_string()),
158 };
159 self.advance();
160
161 let column_list = if matches!(self.current_token, Token::LeftParen) {
163 self.advance();
164 let cols = self.parse_identifier_list()?;
165 self.consume(Token::RightParen)?;
166 Some(cols)
167 } else {
168 None
169 };
170
171 self.consume(Token::As)?;
173
174 self.consume(Token::LeftParen)?;
176
177 let query = self.parse_select_statement_inner()?;
179
180 self.consume(Token::RightParen)?;
182
183 ctes.push(CTE {
184 name,
185 column_list,
186 query,
187 });
188
189 if !matches!(self.current_token, Token::Comma) {
191 break;
192 }
193 self.advance();
194 }
195
196 let mut main_query = self.parse_select_statement()?;
198 main_query.ctes = ctes;
199
200 Ok(main_query)
201 }
202
203 fn parse_with_clause_inner(&mut self) -> Result<SelectStatement, String> {
204 self.consume(Token::With)?;
205
206 let mut ctes = Vec::new();
207
208 loop {
210 let name = match &self.current_token {
212 Token::Identifier(name) => name.clone(),
213 _ => return Err("Expected CTE name after WITH".to_string()),
214 };
215 self.advance();
216
217 let column_list = if matches!(self.current_token, Token::LeftParen) {
219 self.advance();
220 let cols = self.parse_identifier_list()?;
221 self.consume(Token::RightParen)?;
222 Some(cols)
223 } else {
224 None
225 };
226
227 self.consume(Token::As)?;
229
230 self.consume(Token::LeftParen)?;
232
233 let query = self.parse_select_statement_inner()?;
235
236 self.consume(Token::RightParen)?;
238
239 ctes.push(CTE {
240 name,
241 column_list,
242 query,
243 });
244
245 if !matches!(self.current_token, Token::Comma) {
247 break;
248 }
249 self.advance();
250 }
251
252 let mut main_query = self.parse_select_statement_inner()?;
254 main_query.ctes = ctes;
255
256 Ok(main_query)
257 }
258
259 fn parse_select_statement(&mut self) -> Result<SelectStatement, String> {
260 let result = self.parse_select_statement_inner()?;
261
262 if self.paren_depth > 0 {
264 return Err(format!(
265 "Unclosed parenthesis - missing {} closing parenthes{}",
266 self.paren_depth,
267 if self.paren_depth == 1 { "is" } else { "es" }
268 ));
269 } else if self.paren_depth < 0 {
270 return Err(
271 "Extra closing parenthesis found - no matching opening parenthesis".to_string(),
272 );
273 }
274
275 Ok(result)
276 }
277
278 fn parse_select_statement_inner(&mut self) -> Result<SelectStatement, String> {
279 self.consume(Token::Select)?;
280
281 let distinct = if matches!(self.current_token, Token::Distinct) {
283 self.advance();
284 true
285 } else {
286 false
287 };
288
289 let select_items = self.parse_select_items()?;
291
292 let columns = select_items
294 .iter()
295 .map(|item| match item {
296 SelectItem::Star => "*".to_string(),
297 SelectItem::Column(name) => name.clone(),
298 SelectItem::Expression { alias, .. } => alias.clone(),
299 })
300 .collect();
301
302 let (from_table, from_subquery, from_function, from_alias) =
304 if matches!(self.current_token, Token::From) {
305 self.advance();
306
307 if let Token::Identifier(name) = &self.current_token.clone() {
309 if name.to_uppercase() == "RANGE" {
310 self.advance();
311 self.consume(Token::LeftParen)?;
313
314 let start = self.parse_expression()?;
316 self.consume(Token::Comma)?;
317
318 let end = self.parse_expression()?;
320
321 let step = if matches!(self.current_token, Token::Comma) {
323 self.advance();
324 Some(self.parse_expression()?)
325 } else {
326 None
327 };
328
329 self.consume(Token::RightParen)?;
330
331 let alias = if matches!(self.current_token, Token::As) {
333 self.advance();
334 match &self.current_token {
335 Token::Identifier(name) => {
336 let alias = name.clone();
337 self.advance();
338 Some(alias)
339 }
340 _ => return Err("Expected alias name after AS".to_string()),
341 }
342 } else if let Token::Identifier(name) = &self.current_token {
343 let alias = name.clone();
344 self.advance();
345 Some(alias)
346 } else {
347 None
348 };
349
350 (
351 None,
352 None,
353 Some(TableFunction::Range { start, end, step }),
354 alias,
355 )
356 } else {
357 let table_name = name.clone();
359 self.advance();
360
361 let alias = if matches!(self.current_token, Token::As) {
363 self.advance();
364 match &self.current_token {
365 Token::Identifier(name) => {
366 let alias = name.clone();
367 self.advance();
368 Some(alias)
369 }
370 _ => return Err("Expected alias name after AS".to_string()),
371 }
372 } else if let Token::Identifier(name) = &self.current_token {
373 let alias = name.clone();
375 self.advance();
376 Some(alias)
377 } else {
378 None
379 };
380
381 (Some(table_name), None, None, alias)
382 }
383 } else if matches!(self.current_token, Token::LeftParen) {
384 self.advance();
386
387 let subquery = self.parse_select_statement_inner()?;
389
390 self.consume(Token::RightParen)?;
391
392 let alias = if matches!(self.current_token, Token::As) {
394 self.advance();
395 match &self.current_token {
396 Token::Identifier(name) => {
397 let alias = name.clone();
398 self.advance();
399 alias
400 }
401 _ => return Err("Expected alias name after AS".to_string()),
402 }
403 } else {
404 match &self.current_token {
406 Token::Identifier(name) => {
407 let alias = name.clone();
408 self.advance();
409 alias
410 }
411 _ => {
412 return Err(
413 "Subquery in FROM must have an alias (e.g., AS t)".to_string()
414 )
415 }
416 }
417 };
418
419 (None, Some(Box::new(subquery)), None, Some(alias))
420 } else {
421 match &self.current_token {
423 Token::Identifier(table) => {
424 let table_name = table.clone();
425 self.advance();
426
427 let alias = if matches!(self.current_token, Token::As) {
429 self.advance();
430 match &self.current_token {
431 Token::Identifier(name) => {
432 let alias = name.clone();
433 self.advance();
434 Some(alias)
435 }
436 _ => return Err("Expected alias name after AS".to_string()),
437 }
438 } else if let Token::Identifier(name) = &self.current_token {
439 let alias = name.clone();
441 self.advance();
442 Some(alias)
443 } else {
444 None
445 };
446
447 (Some(table_name), None, None, alias)
448 }
449 Token::QuotedIdentifier(table) => {
450 let table_name = table.clone();
452 self.advance();
453
454 let alias = if matches!(self.current_token, Token::As) {
456 self.advance();
457 match &self.current_token {
458 Token::Identifier(name) => {
459 let alias = name.clone();
460 self.advance();
461 Some(alias)
462 }
463 _ => return Err("Expected alias name after AS".to_string()),
464 }
465 } else if let Token::Identifier(name) = &self.current_token {
466 let alias = name.clone();
468 self.advance();
469 Some(alias)
470 } else {
471 None
472 };
473
474 (Some(table_name), None, None, alias)
475 }
476 _ => return Err("Expected table name or subquery after FROM".to_string()),
477 }
478 }
479 } else {
480 (None, None, None, None)
481 };
482
483 let mut joins = Vec::new();
485 while self.is_join_token() {
486 joins.push(self.parse_join_clause()?);
487 }
488
489 let where_clause = if matches!(self.current_token, Token::Where) {
490 self.advance();
491 Some(self.parse_where_clause()?)
492 } else {
493 None
494 };
495
496 let group_by = if matches!(self.current_token, Token::GroupBy) {
497 self.advance();
498 Some(self.parse_expression_list()?)
501 } else {
502 None
503 };
504
505 let having = if matches!(self.current_token, Token::Having) {
507 if group_by.is_none() {
508 return Err("HAVING clause requires GROUP BY".to_string());
509 }
510 self.advance();
511 Some(self.parse_expression()?)
512 } else {
513 None
514 };
515
516 let order_by = if matches!(self.current_token, Token::OrderBy) {
518 self.advance();
519 Some(self.parse_order_by_list()?)
520 } else if let Token::Identifier(s) = &self.current_token {
521 if s.to_uppercase() == "ORDER" {
522 self.advance(); if matches!(&self.current_token, Token::Identifier(by_token) if by_token.to_uppercase() == "BY")
525 {
526 self.advance(); Some(self.parse_order_by_list()?)
528 } else {
529 return Err("Expected BY after ORDER".to_string());
530 }
531 } else {
532 None
533 }
534 } else {
535 None
536 };
537
538 let limit = if matches!(self.current_token, Token::Limit) {
540 self.advance();
541 match &self.current_token {
542 Token::NumberLiteral(num) => {
543 let limit_val = num
544 .parse::<usize>()
545 .map_err(|_| format!("Invalid LIMIT value: {num}"))?;
546 self.advance();
547 Some(limit_val)
548 }
549 _ => return Err("Expected number after LIMIT".to_string()),
550 }
551 } else {
552 None
553 };
554
555 let offset = if matches!(self.current_token, Token::Offset) {
557 self.advance();
558 match &self.current_token {
559 Token::NumberLiteral(num) => {
560 let offset_val = num
561 .parse::<usize>()
562 .map_err(|_| format!("Invalid OFFSET value: {num}"))?;
563 self.advance();
564 Some(offset_val)
565 }
566 _ => return Err("Expected number after OFFSET".to_string()),
567 }
568 } else {
569 None
570 };
571
572 Ok(SelectStatement {
573 distinct,
574 columns,
575 select_items,
576 from_table,
577 from_subquery,
578 from_function,
579 from_alias,
580 joins,
581 where_clause,
582 order_by,
583 group_by,
584 having,
585 limit,
586 offset,
587 ctes: Vec::new(), })
589 }
590
591 fn parse_select_list(&mut self) -> Result<Vec<String>, String> {
592 let mut columns = Vec::new();
593
594 if matches!(self.current_token, Token::Star) {
595 columns.push("*".to_string());
596 self.advance();
597 } else {
598 loop {
599 match &self.current_token {
600 Token::Identifier(col) => {
601 columns.push(col.clone());
602 self.advance();
603 }
604 Token::QuotedIdentifier(col) => {
605 columns.push(col.clone());
607 self.advance();
608 }
609 _ => return Err("Expected column name".to_string()),
610 }
611
612 if matches!(self.current_token, Token::Comma) {
613 self.advance();
614 } else {
615 break;
616 }
617 }
618 }
619
620 Ok(columns)
621 }
622
623 fn parse_select_items(&mut self) -> Result<Vec<SelectItem>, String> {
625 let mut items = Vec::new();
626
627 loop {
628 if matches!(self.current_token, Token::Star) {
631 items.push(SelectItem::Star);
639 self.advance();
640 } else {
641 let expr = self.parse_comparison()?; let alias = if matches!(self.current_token, Token::As) {
646 self.advance();
647 match &self.current_token {
648 Token::Identifier(alias_name) => {
649 let alias = alias_name.clone();
650 self.advance();
651 alias
652 }
653 Token::QuotedIdentifier(alias_name) => {
654 let alias = alias_name.clone();
655 self.advance();
656 alias
657 }
658 _ => return Err("Expected alias name after AS".to_string()),
659 }
660 } else {
661 match &expr {
663 SqlExpression::Column(col_name) => col_name.clone(),
664 _ => format!("expr_{}", items.len() + 1), }
666 };
667
668 let item = match expr {
670 SqlExpression::Column(col_name) if alias == col_name => {
671 SelectItem::Column(col_name)
673 }
674 _ => {
675 SelectItem::Expression { expr, alias }
677 }
678 };
679
680 items.push(item);
681 }
682
683 if matches!(self.current_token, Token::Comma) {
685 self.advance();
686 } else {
687 break;
688 }
689 }
690
691 Ok(items)
692 }
693
694 fn parse_identifier_list(&mut self) -> Result<Vec<String>, String> {
695 let mut identifiers = Vec::new();
696
697 loop {
698 match &self.current_token {
699 Token::Identifier(id) => {
700 let id_upper = id.to_uppercase();
702 if matches!(
703 id_upper.as_str(),
704 "ORDER" | "HAVING" | "LIMIT" | "OFFSET" | "UNION" | "INTERSECT" | "EXCEPT"
705 ) {
706 break;
708 }
709 identifiers.push(id.clone());
710 self.advance();
711 }
712 Token::QuotedIdentifier(id) => {
713 identifiers.push(id.clone());
715 self.advance();
716 }
717 _ => {
718 break;
720 }
721 }
722
723 if matches!(self.current_token, Token::Comma) {
724 self.advance();
725 } else {
726 break;
727 }
728 }
729
730 if identifiers.is_empty() {
731 return Err("Expected at least one identifier".to_string());
732 }
733
734 Ok(identifiers)
735 }
736
737 fn parse_window_spec(&mut self) -> Result<WindowSpec, String> {
738 let mut partition_by = Vec::new();
739 let mut order_by = Vec::new();
740
741 if matches!(self.current_token, Token::Partition) {
743 self.advance(); if !matches!(self.current_token, Token::By) {
745 return Err("Expected BY after PARTITION".to_string());
746 }
747 self.advance(); partition_by = self.parse_identifier_list()?;
751 }
752
753 if matches!(self.current_token, Token::OrderBy) {
755 self.advance(); order_by = self.parse_order_by_list()?;
757 } else if let Token::Identifier(s) = &self.current_token {
758 if s.to_uppercase() == "ORDER" {
759 self.advance(); if !matches!(self.current_token, Token::By) {
762 return Err("Expected BY after ORDER".to_string());
763 }
764 self.advance(); order_by = self.parse_order_by_list()?;
766 }
767 }
768
769 Ok(WindowSpec {
770 partition_by,
771 order_by,
772 })
773 }
774
775 fn parse_order_by_list(&mut self) -> Result<Vec<OrderByColumn>, String> {
776 let mut order_columns = Vec::new();
777
778 loop {
779 let column = match &self.current_token {
780 Token::Identifier(id) => {
781 let col = id.clone();
782 self.advance();
783 col
784 }
785 Token::QuotedIdentifier(id) => {
786 let col = id.clone();
787 self.advance();
788 col
789 }
790 Token::NumberLiteral(num) if self.columns.iter().any(|col| col == num) => {
791 let col = num.clone();
793 self.advance();
794 col
795 }
796 _ => return Err("Expected column name in ORDER BY".to_string()),
797 };
798
799 let direction = match &self.current_token {
801 Token::Asc => {
802 self.advance();
803 SortDirection::Asc
804 }
805 Token::Desc => {
806 self.advance();
807 SortDirection::Desc
808 }
809 _ => SortDirection::Asc, };
811
812 order_columns.push(OrderByColumn { column, direction });
813
814 if matches!(self.current_token, Token::Comma) {
815 self.advance();
816 } else {
817 break;
818 }
819 }
820
821 Ok(order_columns)
822 }
823
824 fn parse_where_clause(&mut self) -> Result<WhereClause, String> {
825 let expr = self.parse_expression()?;
828
829 if matches!(self.current_token, Token::RightParen) && self.paren_depth <= 0 {
831 return Err(
832 "Unexpected closing parenthesis - no matching opening parenthesis".to_string(),
833 );
834 }
835
836 let conditions = vec![Condition {
838 expr,
839 connector: None,
840 }];
841
842 Ok(WhereClause { conditions })
843 }
844
845 fn parse_expression(&mut self) -> Result<SqlExpression, String> {
846 let mut left = self.parse_logical_or()?;
849
850 left = parse_in_operator(self, left)?;
853
854 Ok(left)
855 }
856
857 fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
858 parse_comparison_expr(self)
860 }
861
862 fn parse_additive(&mut self) -> Result<SqlExpression, String> {
863 parse_additive_expr(self)
865 }
866
867 fn parse_multiplicative(&mut self) -> Result<SqlExpression, String> {
868 parse_multiplicative_expr(self)
870 }
871
872 fn parse_logical_or(&mut self) -> Result<SqlExpression, String> {
873 parse_logical_or_expr(self)
875 }
876
877 fn parse_logical_and(&mut self) -> Result<SqlExpression, String> {
878 parse_logical_and_expr(self)
880 }
881
882 fn parse_case_expression(&mut self) -> Result<SqlExpression, String> {
883 parse_case_expr(self)
885 }
886
887 fn parse_primary(&mut self) -> Result<SqlExpression, String> {
888 let columns = self.columns.clone();
891 let in_method_args = self.in_method_args;
892 let ctx = PrimaryExpressionContext {
893 columns: &columns,
894 in_method_args,
895 };
896 parse_primary_expr(self, &ctx)
897 }
898
899 fn parse_method_args(&mut self) -> Result<Vec<SqlExpression>, String> {
901 let mut args = Vec::new();
902
903 self.in_method_args = true;
905
906 if !matches!(self.current_token, Token::RightParen) {
907 loop {
908 args.push(self.parse_expression()?);
909
910 if matches!(self.current_token, Token::Comma) {
911 self.advance();
912 } else {
913 break;
914 }
915 }
916 }
917
918 self.in_method_args = false;
920
921 Ok(args)
922 }
923
924 fn parse_function_args(&mut self) -> Result<(Vec<SqlExpression>, bool), String> {
925 let mut args = Vec::new();
926 let mut has_distinct = false;
927
928 if !matches!(self.current_token, Token::RightParen) {
929 if matches!(self.current_token, Token::Distinct) {
931 self.advance(); has_distinct = true;
933 }
934
935 args.push(self.parse_additive()?);
937
938 while matches!(self.current_token, Token::Comma) {
940 self.advance();
941 args.push(self.parse_additive()?);
942 }
943 }
944
945 Ok((args, has_distinct))
946 }
947
948 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
949 let mut expressions = Vec::new();
950
951 loop {
952 expressions.push(self.parse_expression()?);
953
954 if matches!(self.current_token, Token::Comma) {
955 self.advance();
956 } else {
957 break;
958 }
959 }
960
961 Ok(expressions)
962 }
963
964 fn get_binary_op(&self) -> Option<String> {
965 match &self.current_token {
966 Token::Equal => Some("=".to_string()),
967 Token::NotEqual => Some("!=".to_string()),
968 Token::LessThan => Some("<".to_string()),
969 Token::GreaterThan => Some(">".to_string()),
970 Token::LessThanOrEqual => Some("<=".to_string()),
971 Token::GreaterThanOrEqual => Some(">=".to_string()),
972 Token::Like => Some("LIKE".to_string()),
973 _ => None,
974 }
975 }
976
977 fn get_arithmetic_op(&self) -> Option<String> {
978 match &self.current_token {
979 Token::Plus => Some("+".to_string()),
980 Token::Minus => Some("-".to_string()),
981 Token::Star => Some("*".to_string()), Token::Divide => Some("/".to_string()),
983 Token::Modulo => Some("%".to_string()),
984 _ => None,
985 }
986 }
987
988 #[must_use]
989 pub fn get_position(&self) -> usize {
990 self.lexer.get_position()
991 }
992
993 fn is_join_token(&self) -> bool {
995 matches!(
996 self.current_token,
997 Token::Join | Token::Inner | Token::Left | Token::Right | Token::Full | Token::Cross
998 )
999 }
1000
1001 fn parse_join_clause(&mut self) -> Result<JoinClause, String> {
1003 let join_type = match &self.current_token {
1005 Token::Join => {
1006 self.advance();
1007 JoinType::Inner }
1009 Token::Inner => {
1010 self.advance();
1011 if !matches!(self.current_token, Token::Join) {
1012 return Err("Expected JOIN after INNER".to_string());
1013 }
1014 self.advance();
1015 JoinType::Inner
1016 }
1017 Token::Left => {
1018 self.advance();
1019 if matches!(self.current_token, Token::Outer) {
1021 self.advance();
1022 }
1023 if !matches!(self.current_token, Token::Join) {
1024 return Err("Expected JOIN after LEFT".to_string());
1025 }
1026 self.advance();
1027 JoinType::Left
1028 }
1029 Token::Right => {
1030 self.advance();
1031 if matches!(self.current_token, Token::Outer) {
1033 self.advance();
1034 }
1035 if !matches!(self.current_token, Token::Join) {
1036 return Err("Expected JOIN after RIGHT".to_string());
1037 }
1038 self.advance();
1039 JoinType::Right
1040 }
1041 Token::Full => {
1042 self.advance();
1043 if matches!(self.current_token, Token::Outer) {
1045 self.advance();
1046 }
1047 if !matches!(self.current_token, Token::Join) {
1048 return Err("Expected JOIN after FULL".to_string());
1049 }
1050 self.advance();
1051 JoinType::Full
1052 }
1053 Token::Cross => {
1054 self.advance();
1055 if !matches!(self.current_token, Token::Join) {
1056 return Err("Expected JOIN after CROSS".to_string());
1057 }
1058 self.advance();
1059 JoinType::Cross
1060 }
1061 _ => return Err("Expected JOIN keyword".to_string()),
1062 };
1063
1064 let (table, alias) = self.parse_join_table_source()?;
1066
1067 let condition = if join_type == JoinType::Cross {
1069 JoinCondition {
1071 left_column: String::new(),
1072 operator: JoinOperator::Equal,
1073 right_column: String::new(),
1074 }
1075 } else {
1076 if !matches!(self.current_token, Token::On) {
1077 return Err("Expected ON keyword after JOIN table".to_string());
1078 }
1079 self.advance();
1080 self.parse_join_condition()?
1081 };
1082
1083 Ok(JoinClause {
1084 join_type,
1085 table,
1086 alias,
1087 condition,
1088 })
1089 }
1090
1091 fn parse_join_table_source(&mut self) -> Result<(TableSource, Option<String>), String> {
1092 let table = match &self.current_token {
1093 Token::Identifier(name) => {
1094 let table_name = name.clone();
1095 self.advance();
1096 TableSource::Table(table_name)
1097 }
1098 Token::LeftParen => {
1099 self.advance();
1101 let subquery = self.parse_select_statement_inner()?;
1102 if !matches!(self.current_token, Token::RightParen) {
1103 return Err("Expected ')' after subquery".to_string());
1104 }
1105 self.advance();
1106
1107 let alias = match &self.current_token {
1109 Token::Identifier(alias_name) => {
1110 let alias = alias_name.clone();
1111 self.advance();
1112 alias
1113 }
1114 Token::As => {
1115 self.advance();
1116 match &self.current_token {
1117 Token::Identifier(alias_name) => {
1118 let alias = alias_name.clone();
1119 self.advance();
1120 alias
1121 }
1122 _ => return Err("Expected alias after AS keyword".to_string()),
1123 }
1124 }
1125 _ => return Err("Subqueries must have an alias".to_string()),
1126 };
1127
1128 return Ok((
1129 TableSource::DerivedTable {
1130 query: Box::new(subquery),
1131 alias: alias.clone(),
1132 },
1133 Some(alias),
1134 ));
1135 }
1136 _ => return Err("Expected table name or subquery in JOIN clause".to_string()),
1137 };
1138
1139 let alias = match &self.current_token {
1141 Token::Identifier(alias_name) => {
1142 let alias = alias_name.clone();
1143 self.advance();
1144 Some(alias)
1145 }
1146 Token::As => {
1147 self.advance();
1148 match &self.current_token {
1149 Token::Identifier(alias_name) => {
1150 let alias = alias_name.clone();
1151 self.advance();
1152 Some(alias)
1153 }
1154 _ => return Err("Expected alias after AS keyword".to_string()),
1155 }
1156 }
1157 _ => None,
1158 };
1159
1160 Ok((table, alias))
1161 }
1162
1163 fn parse_join_condition(&mut self) -> Result<JoinCondition, String> {
1164 let left_column = self.parse_column_reference()?;
1166
1167 let operator = match &self.current_token {
1169 Token::Equal => JoinOperator::Equal,
1170 Token::NotEqual => JoinOperator::NotEqual,
1171 Token::LessThan => JoinOperator::LessThan,
1172 Token::LessThanOrEqual => JoinOperator::LessThanOrEqual,
1173 Token::GreaterThan => JoinOperator::GreaterThan,
1174 Token::GreaterThanOrEqual => JoinOperator::GreaterThanOrEqual,
1175 _ => return Err("Expected comparison operator in JOIN condition".to_string()),
1176 };
1177 self.advance();
1178
1179 let right_column = self.parse_column_reference()?;
1181
1182 Ok(JoinCondition {
1183 left_column,
1184 operator,
1185 right_column,
1186 })
1187 }
1188
1189 fn parse_column_reference(&mut self) -> Result<String, String> {
1190 match &self.current_token {
1191 Token::Identifier(name) => {
1192 let mut column_ref = name.clone();
1193 self.advance();
1194
1195 if matches!(self.current_token, Token::Dot) {
1197 self.advance();
1198 match &self.current_token {
1199 Token::Identifier(col_name) => {
1200 column_ref.push('.');
1201 column_ref.push_str(col_name);
1202 self.advance();
1203 }
1204 _ => return Err("Expected column name after '.'".to_string()),
1205 }
1206 }
1207
1208 Ok(column_ref)
1209 }
1210 _ => Err("Expected column reference".to_string()),
1211 }
1212 }
1213}
1214
1215#[derive(Debug, Clone)]
1217pub enum CursorContext {
1218 SelectClause,
1219 FromClause,
1220 WhereClause,
1221 OrderByClause,
1222 AfterColumn(String),
1223 AfterLogicalOp(LogicalOp),
1224 AfterComparisonOp(String, String), InMethodCall(String, String), InExpression,
1227 Unknown,
1228}
1229
1230fn safe_slice_to(s: &str, pos: usize) -> &str {
1232 if pos >= s.len() {
1233 return s;
1234 }
1235
1236 let mut safe_pos = pos;
1238 while safe_pos > 0 && !s.is_char_boundary(safe_pos) {
1239 safe_pos -= 1;
1240 }
1241
1242 &s[..safe_pos]
1243}
1244
1245fn safe_slice_from(s: &str, pos: usize) -> &str {
1247 if pos >= s.len() {
1248 return "";
1249 }
1250
1251 let mut safe_pos = pos;
1253 while safe_pos < s.len() && !s.is_char_boundary(safe_pos) {
1254 safe_pos += 1;
1255 }
1256
1257 &s[safe_pos..]
1258}
1259
1260#[must_use]
1261pub fn detect_cursor_context(query: &str, cursor_pos: usize) -> (CursorContext, Option<String>) {
1262 let truncated = safe_slice_to(query, cursor_pos);
1263 let mut parser = Parser::new(truncated);
1264
1265 if let Ok(stmt) = parser.parse() {
1267 let (ctx, partial) = analyze_statement(&stmt, truncated, cursor_pos);
1268 #[cfg(test)]
1269 println!("analyze_statement returned: {ctx:?}, {partial:?} for query: '{truncated}'");
1270 (ctx, partial)
1271 } else {
1272 let (ctx, partial) = analyze_partial(truncated, cursor_pos);
1274 #[cfg(test)]
1275 println!("analyze_partial returned: {ctx:?}, {partial:?} for query: '{truncated}'");
1276 (ctx, partial)
1277 }
1278}
1279
1280#[must_use]
1281pub fn tokenize_query(query: &str) -> Vec<String> {
1282 let mut lexer = Lexer::new(query);
1283 let tokens = lexer.tokenize_all();
1284 tokens.iter().map(|t| format!("{t:?}")).collect()
1285}
1286
1287#[must_use]
1288fn analyze_statement(
1289 stmt: &SelectStatement,
1290 query: &str,
1291 _cursor_pos: usize,
1292) -> (CursorContext, Option<String>) {
1293 let trimmed = query.trim();
1295
1296 let comparison_ops = [" > ", " < ", " >= ", " <= ", " = ", " != "];
1298 for op in &comparison_ops {
1299 if let Some(op_pos) = query.rfind(op) {
1300 let before_op = safe_slice_to(query, op_pos);
1301 let after_op_start = op_pos + op.len();
1302 let after_op = if after_op_start < query.len() {
1303 &query[after_op_start..]
1304 } else {
1305 ""
1306 };
1307
1308 if let Some(col_name) = before_op.split_whitespace().last() {
1310 if col_name.chars().all(|c| c.is_alphanumeric() || c == '_') {
1311 let after_op_trimmed = after_op.trim();
1313 if after_op_trimmed.is_empty()
1314 || (after_op_trimmed
1315 .chars()
1316 .all(|c| c.is_alphanumeric() || c == '_')
1317 && !after_op_trimmed.contains('('))
1318 {
1319 let partial = if after_op_trimmed.is_empty() {
1320 None
1321 } else {
1322 Some(after_op_trimmed.to_string())
1323 };
1324 return (
1325 CursorContext::AfterComparisonOp(
1326 col_name.to_string(),
1327 op.trim().to_string(),
1328 ),
1329 partial,
1330 );
1331 }
1332 }
1333 }
1334 }
1335 }
1336
1337 if trimmed.to_uppercase().ends_with(" AND")
1339 || trimmed.to_uppercase().ends_with(" OR")
1340 || trimmed.to_uppercase().ends_with(" AND ")
1341 || trimmed.to_uppercase().ends_with(" OR ")
1342 {
1343 } else {
1345 if let Some(dot_pos) = trimmed.rfind('.') {
1347 let before_dot = safe_slice_to(trimmed, dot_pos);
1349 let after_dot_start = dot_pos + 1;
1350 let after_dot = if after_dot_start < trimmed.len() {
1351 &trimmed[after_dot_start..]
1352 } else {
1353 ""
1354 };
1355
1356 if !after_dot.contains('(') {
1359 let col_name = if before_dot.ends_with('"') {
1361 let bytes = before_dot.as_bytes();
1363 let mut pos = before_dot.len() - 1; let mut found_start = None;
1365
1366 if pos > 0 {
1368 pos -= 1;
1369 while pos > 0 {
1370 if bytes[pos] == b'"' {
1371 if pos == 0 || bytes[pos - 1] != b'\\' {
1373 found_start = Some(pos);
1374 break;
1375 }
1376 }
1377 pos -= 1;
1378 }
1379 if found_start.is_none() && bytes[0] == b'"' {
1381 found_start = Some(0);
1382 }
1383 }
1384
1385 found_start.map(|start| safe_slice_from(before_dot, start))
1386 } else {
1387 before_dot
1390 .split_whitespace()
1391 .last()
1392 .map(|word| word.trim_start_matches('('))
1393 };
1394
1395 if let Some(col_name) = col_name {
1396 let is_valid = if col_name.starts_with('"') && col_name.ends_with('"') {
1398 true
1400 } else {
1401 col_name.chars().all(|c| c.is_alphanumeric() || c == '_')
1403 };
1404
1405 if is_valid {
1406 let partial_method = if after_dot.is_empty() {
1409 None
1410 } else if after_dot.chars().all(|c| c.is_alphanumeric() || c == '_') {
1411 Some(after_dot.to_string())
1412 } else {
1413 None
1414 };
1415
1416 let col_name_for_context = if col_name.starts_with('"')
1418 && col_name.ends_with('"')
1419 && col_name.len() > 2
1420 {
1421 col_name[1..col_name.len() - 1].to_string()
1422 } else {
1423 col_name.to_string()
1424 };
1425
1426 return (
1427 CursorContext::AfterColumn(col_name_for_context),
1428 partial_method,
1429 );
1430 }
1431 }
1432 }
1433 }
1434 }
1435
1436 if let Some(where_clause) = &stmt.where_clause {
1438 if trimmed.to_uppercase().ends_with(" AND") || trimmed.to_uppercase().ends_with(" OR") {
1440 let op = if trimmed.to_uppercase().ends_with(" AND") {
1441 LogicalOp::And
1442 } else {
1443 LogicalOp::Or
1444 };
1445 return (CursorContext::AfterLogicalOp(op), None);
1446 }
1447
1448 if let Some(and_pos) = query.to_uppercase().rfind(" AND ") {
1450 let after_and = safe_slice_from(query, and_pos + 5);
1451 let partial = extract_partial_at_end(after_and);
1452 if partial.is_some() {
1453 return (CursorContext::AfterLogicalOp(LogicalOp::And), partial);
1454 }
1455 }
1456
1457 if let Some(or_pos) = query.to_uppercase().rfind(" OR ") {
1458 let after_or = safe_slice_from(query, or_pos + 4);
1459 let partial = extract_partial_at_end(after_or);
1460 if partial.is_some() {
1461 return (CursorContext::AfterLogicalOp(LogicalOp::Or), partial);
1462 }
1463 }
1464
1465 if let Some(last_condition) = where_clause.conditions.last() {
1466 if let Some(connector) = &last_condition.connector {
1467 return (
1469 CursorContext::AfterLogicalOp(connector.clone()),
1470 extract_partial_at_end(query),
1471 );
1472 }
1473 }
1474 return (CursorContext::WhereClause, extract_partial_at_end(query));
1476 }
1477
1478 if query.to_uppercase().ends_with(" ORDER BY ") || query.to_uppercase().ends_with(" ORDER BY") {
1480 return (CursorContext::OrderByClause, None);
1481 }
1482
1483 if stmt.order_by.is_some() {
1485 return (CursorContext::OrderByClause, extract_partial_at_end(query));
1486 }
1487
1488 if stmt.from_table.is_some() && stmt.where_clause.is_none() && stmt.order_by.is_none() {
1489 return (CursorContext::FromClause, extract_partial_at_end(query));
1490 }
1491
1492 if !stmt.columns.is_empty() && stmt.from_table.is_none() {
1493 return (CursorContext::SelectClause, extract_partial_at_end(query));
1494 }
1495
1496 (CursorContext::Unknown, None)
1497}
1498
1499fn analyze_partial(query: &str, cursor_pos: usize) -> (CursorContext, Option<String>) {
1500 let upper = query.to_uppercase();
1501
1502 let trimmed = query.trim();
1504
1505 #[cfg(test)]
1506 {
1507 if trimmed.contains("\"Last Name\"") {
1508 eprintln!("DEBUG analyze_partial: query='{query}', trimmed='{trimmed}'");
1509 }
1510 }
1511
1512 let comparison_ops = [" > ", " < ", " >= ", " <= ", " = ", " != "];
1514 for op in &comparison_ops {
1515 if let Some(op_pos) = query.rfind(op) {
1516 let before_op = safe_slice_to(query, op_pos);
1517 let after_op_start = op_pos + op.len();
1518 let after_op = if after_op_start < query.len() {
1519 &query[after_op_start..]
1520 } else {
1521 ""
1522 };
1523
1524 if let Some(col_name) = before_op.split_whitespace().last() {
1526 if col_name.chars().all(|c| c.is_alphanumeric() || c == '_') {
1527 let after_op_trimmed = after_op.trim();
1529 if after_op_trimmed.is_empty()
1530 || (after_op_trimmed
1531 .chars()
1532 .all(|c| c.is_alphanumeric() || c == '_')
1533 && !after_op_trimmed.contains('('))
1534 {
1535 let partial = if after_op_trimmed.is_empty() {
1536 None
1537 } else {
1538 Some(after_op_trimmed.to_string())
1539 };
1540 return (
1541 CursorContext::AfterComparisonOp(
1542 col_name.to_string(),
1543 op.trim().to_string(),
1544 ),
1545 partial,
1546 );
1547 }
1548 }
1549 }
1550 }
1551 }
1552
1553 if let Some(dot_pos) = trimmed.rfind('.') {
1556 #[cfg(test)]
1557 {
1558 if trimmed.contains("\"Last Name\"") {
1559 eprintln!("DEBUG: Found dot at position {dot_pos}");
1560 }
1561 }
1562 let before_dot = &trimmed[..dot_pos];
1564 let after_dot = &trimmed[dot_pos + 1..];
1565
1566 if !after_dot.contains('(') {
1569 let col_name = if before_dot.ends_with('"') {
1572 let bytes = before_dot.as_bytes();
1574 let mut pos = before_dot.len() - 1; let mut found_start = None;
1576
1577 #[cfg(test)]
1578 {
1579 if trimmed.contains("\"Last Name\"") {
1580 eprintln!("DEBUG: before_dot='{before_dot}', looking for opening quote");
1581 }
1582 }
1583
1584 if pos > 0 {
1586 pos -= 1;
1587 while pos > 0 {
1588 if bytes[pos] == b'"' {
1589 if pos == 0 || bytes[pos - 1] != b'\\' {
1591 found_start = Some(pos);
1592 break;
1593 }
1594 }
1595 pos -= 1;
1596 }
1597 if found_start.is_none() && bytes[0] == b'"' {
1599 found_start = Some(0);
1600 }
1601 }
1602
1603 if let Some(start) = found_start {
1604 let result = safe_slice_from(before_dot, start);
1606 #[cfg(test)]
1607 {
1608 if trimmed.contains("\"Last Name\"") {
1609 eprintln!("DEBUG: Extracted quoted identifier: '{result}'");
1610 }
1611 }
1612 Some(result)
1613 } else {
1614 #[cfg(test)]
1615 {
1616 if trimmed.contains("\"Last Name\"") {
1617 eprintln!("DEBUG: No opening quote found!");
1618 }
1619 }
1620 None
1621 }
1622 } else {
1623 before_dot
1626 .split_whitespace()
1627 .last()
1628 .map(|word| word.trim_start_matches('('))
1629 };
1630
1631 if let Some(col_name) = col_name {
1632 #[cfg(test)]
1633 {
1634 if trimmed.contains("\"Last Name\"") {
1635 eprintln!("DEBUG: col_name = '{col_name}'");
1636 }
1637 }
1638
1639 let is_valid = if col_name.starts_with('"') && col_name.ends_with('"') {
1641 true
1643 } else {
1644 col_name.chars().all(|c| c.is_alphanumeric() || c == '_')
1646 };
1647
1648 #[cfg(test)]
1649 {
1650 if trimmed.contains("\"Last Name\"") {
1651 eprintln!("DEBUG: is_valid = {is_valid}");
1652 }
1653 }
1654
1655 if is_valid {
1656 let partial_method = if after_dot.is_empty() {
1659 None
1660 } else if after_dot.chars().all(|c| c.is_alphanumeric() || c == '_') {
1661 Some(after_dot.to_string())
1662 } else {
1663 None
1664 };
1665
1666 let col_name_for_context = if col_name.starts_with('"')
1668 && col_name.ends_with('"')
1669 && col_name.len() > 2
1670 {
1671 col_name[1..col_name.len() - 1].to_string()
1672 } else {
1673 col_name.to_string()
1674 };
1675
1676 return (
1677 CursorContext::AfterColumn(col_name_for_context),
1678 partial_method,
1679 );
1680 }
1681 }
1682 }
1683 }
1684
1685 if let Some(and_pos) = upper.rfind(" AND ") {
1687 if cursor_pos >= and_pos + 5 {
1689 let after_and = safe_slice_from(query, and_pos + 5);
1691 let partial = extract_partial_at_end(after_and);
1692 return (CursorContext::AfterLogicalOp(LogicalOp::And), partial);
1693 }
1694 }
1695
1696 if let Some(or_pos) = upper.rfind(" OR ") {
1697 if cursor_pos >= or_pos + 4 {
1699 let after_or = safe_slice_from(query, or_pos + 4);
1701 let partial = extract_partial_at_end(after_or);
1702 return (CursorContext::AfterLogicalOp(LogicalOp::Or), partial);
1703 }
1704 }
1705
1706 if trimmed.to_uppercase().ends_with(" AND") || trimmed.to_uppercase().ends_with(" OR") {
1708 let op = if trimmed.to_uppercase().ends_with(" AND") {
1709 LogicalOp::And
1710 } else {
1711 LogicalOp::Or
1712 };
1713 return (CursorContext::AfterLogicalOp(op), None);
1714 }
1715
1716 if upper.ends_with(" ORDER BY ") || upper.ends_with(" ORDER BY") || upper.contains("ORDER BY ")
1718 {
1719 return (CursorContext::OrderByClause, extract_partial_at_end(query));
1720 }
1721
1722 if upper.contains("WHERE") && !upper.contains("ORDER") && !upper.contains("GROUP") {
1723 return (CursorContext::WhereClause, extract_partial_at_end(query));
1724 }
1725
1726 if upper.contains("FROM") && !upper.contains("WHERE") && !upper.contains("ORDER") {
1727 return (CursorContext::FromClause, extract_partial_at_end(query));
1728 }
1729
1730 if upper.contains("SELECT") && !upper.contains("FROM") {
1731 return (CursorContext::SelectClause, extract_partial_at_end(query));
1732 }
1733
1734 (CursorContext::Unknown, None)
1735}
1736
1737fn extract_partial_at_end(query: &str) -> Option<String> {
1738 let trimmed = query.trim();
1739
1740 if let Some(last_word) = trimmed.split_whitespace().last() {
1742 if last_word.starts_with('"') && !last_word.ends_with('"') {
1743 return Some(last_word.to_string());
1745 }
1746 }
1747
1748 let last_word = trimmed.split_whitespace().last()?;
1750
1751 if last_word.chars().all(|c| c.is_alphanumeric() || c == '_') && !is_sql_keyword(last_word) {
1753 Some(last_word.to_string())
1754 } else {
1755 None
1756 }
1757}
1758
1759impl ParsePrimary for Parser {
1761 fn current_token(&self) -> &Token {
1762 &self.current_token
1763 }
1764
1765 fn advance(&mut self) {
1766 self.advance();
1767 }
1768
1769 fn consume(&mut self, expected: Token) -> Result<(), String> {
1770 self.consume(expected)
1771 }
1772
1773 fn parse_case_expression(&mut self) -> Result<SqlExpression, String> {
1774 self.parse_case_expression()
1775 }
1776
1777 fn parse_function_args(&mut self) -> Result<(Vec<SqlExpression>, bool), String> {
1778 self.parse_function_args()
1779 }
1780
1781 fn parse_window_spec(&mut self) -> Result<WindowSpec, String> {
1782 self.parse_window_spec()
1783 }
1784
1785 fn parse_logical_or(&mut self) -> Result<SqlExpression, String> {
1786 self.parse_logical_or()
1787 }
1788
1789 fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
1790 self.parse_comparison()
1791 }
1792
1793 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
1794 self.parse_expression_list()
1795 }
1796
1797 fn parse_subquery(&mut self) -> Result<SelectStatement, String> {
1798 if matches!(self.current_token, Token::With) {
1800 self.parse_with_clause_inner()
1801 } else {
1802 self.parse_select_statement_inner()
1803 }
1804 }
1805}
1806
1807impl ParseArithmetic for Parser {
1809 fn current_token(&self) -> &Token {
1810 &self.current_token
1811 }
1812
1813 fn advance(&mut self) {
1814 self.advance();
1815 }
1816
1817 fn consume(&mut self, expected: Token) -> Result<(), String> {
1818 self.consume(expected)
1819 }
1820
1821 fn parse_primary(&mut self) -> Result<SqlExpression, String> {
1822 self.parse_primary()
1823 }
1824
1825 fn parse_multiplicative(&mut self) -> Result<SqlExpression, String> {
1826 self.parse_multiplicative()
1827 }
1828
1829 fn parse_method_args(&mut self) -> Result<Vec<SqlExpression>, String> {
1830 self.parse_method_args()
1831 }
1832}
1833
1834impl ParseComparison for Parser {
1836 fn current_token(&self) -> &Token {
1837 &self.current_token
1838 }
1839
1840 fn advance(&mut self) {
1841 self.advance();
1842 }
1843
1844 fn consume(&mut self, expected: Token) -> Result<(), String> {
1845 self.consume(expected)
1846 }
1847
1848 fn parse_primary(&mut self) -> Result<SqlExpression, String> {
1849 self.parse_primary()
1850 }
1851
1852 fn parse_additive(&mut self) -> Result<SqlExpression, String> {
1853 self.parse_additive()
1854 }
1855
1856 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
1857 self.parse_expression_list()
1858 }
1859
1860 fn parse_subquery(&mut self) -> Result<SelectStatement, String> {
1861 if matches!(self.current_token, Token::With) {
1863 self.parse_with_clause_inner()
1864 } else {
1865 self.parse_select_statement_inner()
1866 }
1867 }
1868}
1869
1870impl ParseLogical for Parser {
1872 fn current_token(&self) -> &Token {
1873 &self.current_token
1874 }
1875
1876 fn advance(&mut self) {
1877 self.advance();
1878 }
1879
1880 fn consume(&mut self, expected: Token) -> Result<(), String> {
1881 self.consume(expected)
1882 }
1883
1884 fn parse_logical_and(&mut self) -> Result<SqlExpression, String> {
1885 self.parse_logical_and()
1886 }
1887
1888 fn parse_base_logical_expression(&mut self) -> Result<SqlExpression, String> {
1889 self.parse_comparison()
1892 }
1893
1894 fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
1895 self.parse_comparison()
1896 }
1897
1898 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
1899 self.parse_expression_list()
1900 }
1901}
1902
1903impl ParseCase for Parser {
1905 fn current_token(&self) -> &Token {
1906 &self.current_token
1907 }
1908
1909 fn advance(&mut self) {
1910 self.advance();
1911 }
1912
1913 fn consume(&mut self, expected: Token) -> Result<(), String> {
1914 self.consume(expected)
1915 }
1916
1917 fn parse_expression(&mut self) -> Result<SqlExpression, String> {
1918 self.parse_expression()
1919 }
1920}
1921
1922fn is_sql_keyword(word: &str) -> bool {
1923 matches!(
1924 word.to_uppercase().as_str(),
1925 "SELECT"
1926 | "FROM"
1927 | "WHERE"
1928 | "AND"
1929 | "OR"
1930 | "IN"
1931 | "ORDER"
1932 | "BY"
1933 | "GROUP"
1934 | "HAVING"
1935 | "ASC"
1936 | "DESC"
1937 | "DISTINCT"
1938 )
1939}