1pub use super::parser::ast::{
5 CTEType, Comment, Condition, DataFormat, FrameBound, FrameUnit, HttpMethod, IntoTable,
6 JoinClause, JoinCondition, JoinOperator, JoinType, LogicalOp, OrderByColumn, SelectItem,
7 SelectStatement, SetOperation, SingleJoinCondition, SortDirection, SqlExpression,
8 TableFunction, TableSource, WebCTESpec, WhenBranch, WhereClause, WindowFrame, WindowSpec, CTE,
9};
10pub use super::parser::legacy::{ParseContext, ParseState, Schema, SqlParser, SqlToken, TableInfo};
11pub use super::parser::lexer::{Lexer, LexerMode, Token};
12pub use super::parser::ParserConfig;
13
14pub use super::parser::formatter::{format_ast_tree, format_sql_pretty, format_sql_pretty_compact};
16
17pub use super::parser::ast_formatter::{format_sql_ast, format_sql_ast_with_config, FormatConfig};
19
20use super::parser::expressions::arithmetic::{
22 parse_additive as parse_additive_expr, parse_multiplicative as parse_multiplicative_expr,
23 ParseArithmetic,
24};
25use super::parser::expressions::case::{parse_case_expression as parse_case_expr, ParseCase};
26use super::parser::expressions::comparison::{
27 parse_comparison as parse_comparison_expr, parse_in_operator, ParseComparison,
28};
29use super::parser::expressions::logical::{
30 parse_logical_and as parse_logical_and_expr, parse_logical_or as parse_logical_or_expr,
31 ParseLogical,
32};
33use super::parser::expressions::primary::{
34 parse_primary as parse_primary_expr, ParsePrimary, PrimaryExpressionContext,
35};
36use super::parser::expressions::ExpressionParser;
37
38use crate::sql::functions::{FunctionCategory, FunctionRegistry};
40use crate::sql::generators::GeneratorRegistry;
41use std::sync::Arc;
42
43use super::parser::web_cte_parser::WebCteParser;
45pub struct Parser {
46 lexer: Lexer,
47 pub current_token: Token, in_method_args: bool, columns: Vec<String>, paren_depth: i32, paren_depth_stack: Vec<i32>, _config: ParserConfig, debug_trace: bool, trace_depth: usize, function_registry: Arc<FunctionRegistry>, generator_registry: Arc<GeneratorRegistry>, }
58
59impl Parser {
60 #[must_use]
61 pub fn new(input: &str) -> 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 paren_depth_stack: Vec::new(),
71 _config: ParserConfig::default(),
72 debug_trace: false,
73 trace_depth: 0,
74 function_registry: Arc::new(FunctionRegistry::new()),
75 generator_registry: Arc::new(GeneratorRegistry::new()),
76 }
77 }
78
79 #[must_use]
80 pub fn with_config(input: &str, config: ParserConfig) -> Self {
81 let mut lexer = Lexer::new(input);
82 let current_token = lexer.next_token();
83 Self {
84 lexer,
85 current_token,
86 in_method_args: false,
87 columns: Vec::new(),
88 paren_depth: 0,
89 paren_depth_stack: Vec::new(),
90 _config: config,
91 debug_trace: false,
92 trace_depth: 0,
93 function_registry: Arc::new(FunctionRegistry::new()),
94 generator_registry: Arc::new(GeneratorRegistry::new()),
95 }
96 }
97
98 #[must_use]
99 pub fn with_columns(mut self, columns: Vec<String>) -> Self {
100 self.columns = columns;
101 self
102 }
103
104 #[must_use]
105 pub fn with_debug_trace(mut self, enabled: bool) -> Self {
106 self.debug_trace = enabled;
107 self
108 }
109
110 #[must_use]
111 pub fn with_function_registry(mut self, registry: Arc<FunctionRegistry>) -> Self {
112 self.function_registry = registry;
113 self
114 }
115
116 #[must_use]
117 pub fn with_generator_registry(mut self, registry: Arc<GeneratorRegistry>) -> Self {
118 self.generator_registry = registry;
119 self
120 }
121
122 fn trace_enter(&mut self, context: &str) {
123 if self.debug_trace {
124 let indent = " ".repeat(self.trace_depth);
125 eprintln!("{}→ {} | Token: {:?}", indent, context, self.current_token);
126 self.trace_depth += 1;
127 }
128 }
129
130 fn trace_exit(&mut self, context: &str, result: &Result<impl std::fmt::Debug, String>) {
131 if self.debug_trace {
132 self.trace_depth = self.trace_depth.saturating_sub(1);
133 let indent = " ".repeat(self.trace_depth);
134 match result {
135 Ok(val) => eprintln!("{}← {} ✓ | Result: {:?}", indent, context, val),
136 Err(e) => eprintln!("{}← {} ✗ | Error: {}", indent, context, e),
137 }
138 }
139 }
140
141 fn trace_token(&self, action: &str) {
142 if self.debug_trace {
143 let indent = " ".repeat(self.trace_depth);
144 eprintln!("{} {} | Token: {:?}", indent, action, self.current_token);
145 }
146 }
147
148 #[allow(dead_code)]
149 fn peek_token(&self) -> Option<Token> {
150 let mut temp_lexer = self.lexer.clone();
152 let next_token = temp_lexer.next_token();
153 if matches!(next_token, Token::Eof) {
154 None
155 } else {
156 Some(next_token)
157 }
158 }
159
160 fn is_identifier_reserved(id: &str) -> bool {
165 let id_upper = id.to_uppercase();
166 matches!(
167 id_upper.as_str(),
168 "ORDER" | "HAVING" | "LIMIT" | "OFFSET" | "UNION" | "INTERSECT" | "EXCEPT"
169 )
170 }
171
172 const COMPARISON_OPERATORS: [&'static str; 6] = [" > ", " < ", " >= ", " <= ", " = ", " != "];
174
175 pub fn consume(&mut self, expected: Token) -> Result<(), String> {
176 self.trace_token(&format!("Consuming expected {:?}", expected));
177 if std::mem::discriminant(&self.current_token) == std::mem::discriminant(&expected) {
178 self.update_paren_depth(&expected)?;
180
181 self.current_token = self.lexer.next_token();
182 Ok(())
183 } else {
184 let error_msg = match (&expected, &self.current_token) {
186 (Token::RightParen, Token::Eof) if self.paren_depth > 0 => {
187 format!(
188 "Unclosed parenthesis - missing {} closing parenthes{}",
189 self.paren_depth,
190 if self.paren_depth == 1 { "is" } else { "es" }
191 )
192 }
193 (Token::RightParen, _) if self.paren_depth > 0 => {
194 format!(
195 "Expected closing parenthesis but found {:?} (currently {} unclosed parenthes{})",
196 self.current_token,
197 self.paren_depth,
198 if self.paren_depth == 1 { "is" } else { "es" }
199 )
200 }
201 _ => format!("Expected {:?}, found {:?}", expected, self.current_token),
202 };
203 Err(error_msg)
204 }
205 }
206
207 pub fn advance(&mut self) {
208 match &self.current_token {
210 Token::LeftParen => self.paren_depth += 1,
211 Token::RightParen => {
212 self.paren_depth -= 1;
213 }
216 _ => {}
217 }
218 let old_token = self.current_token.clone();
219 self.current_token = self.lexer.next_token();
220 if self.debug_trace {
221 let indent = " ".repeat(self.trace_depth);
222 eprintln!(
223 "{} Advanced: {:?} → {:?}",
224 indent, old_token, self.current_token
225 );
226 }
227 }
228
229 fn collect_leading_comments(&mut self) -> Vec<Comment> {
232 let mut comments = Vec::new();
233 loop {
234 match &self.current_token {
235 Token::LineComment(text) => {
236 comments.push(Comment::line(text.clone()));
237 self.advance();
238 }
239 Token::BlockComment(text) => {
240 comments.push(Comment::block(text.clone()));
241 self.advance();
242 }
243 _ => break,
244 }
245 }
246 comments
247 }
248
249 fn collect_trailing_comment(&mut self) -> Option<Comment> {
252 match &self.current_token {
253 Token::LineComment(text) => {
254 let comment = Some(Comment::line(text.clone()));
255 self.advance();
256 comment
257 }
258 Token::BlockComment(text) => {
259 let comment = Some(Comment::block(text.clone()));
260 self.advance();
261 comment
262 }
263 _ => None,
264 }
265 }
266
267 fn push_paren_depth(&mut self) {
268 self.paren_depth_stack.push(self.paren_depth);
269 self.paren_depth = 0;
270 }
271
272 fn pop_paren_depth(&mut self) {
273 if let Some(depth) = self.paren_depth_stack.pop() {
274 self.paren_depth = depth;
276 }
277 }
278
279 pub fn parse(&mut self) -> Result<SelectStatement, String> {
280 self.trace_enter("parse");
281
282 let result = if matches!(self.current_token, Token::With) {
284 self.parse_with_clause()
285 } else {
286 self.parse_select_statement()
287 };
288
289 self.trace_exit("parse", &result);
290 result
291 }
292
293 fn parse_with_clause(&mut self) -> Result<SelectStatement, String> {
294 self.consume(Token::With)?;
295 let ctes = self.parse_cte_list()?;
296
297 let mut main_query = self.parse_select_statement_inner()?;
299 main_query.ctes = ctes;
300
301 self.check_balanced_parentheses()?;
303
304 Ok(main_query)
305 }
306
307 fn parse_with_clause_inner(&mut self) -> Result<SelectStatement, String> {
308 self.consume(Token::With)?;
309 let ctes = self.parse_cte_list()?;
310
311 let mut main_query = self.parse_select_statement_inner()?;
313 main_query.ctes = ctes;
314
315 Ok(main_query)
316 }
317
318 fn parse_cte_list(&mut self) -> Result<Vec<CTE>, String> {
320 let mut ctes = Vec::new();
321
322 loop {
324 let is_web = if matches!(&self.current_token, Token::Web) {
326 self.trace_token("Found WEB keyword for CTE");
327 self.advance();
328 true
329 } else {
330 false
331 };
332
333 let name = match &self.current_token {
335 Token::Identifier(name) => name.clone(),
336 _ => {
337 return Err(format!(
338 "Expected CTE name after {}",
339 if is_web { "WEB" } else { "WITH or comma" }
340 ))
341 }
342 };
343 self.advance();
344
345 let column_list = if matches!(self.current_token, Token::LeftParen) {
347 self.advance();
348 let cols = self.parse_identifier_list()?;
349 self.consume(Token::RightParen)?;
350 Some(cols)
351 } else {
352 None
353 };
354
355 self.consume(Token::As)?;
357
358 let cte_type = if is_web {
359 self.consume(Token::LeftParen)?;
361 let web_spec = WebCteParser::parse(self)?;
363 self.consume(Token::RightParen)?;
365 CTEType::Web(web_spec)
366 } else {
367 self.push_paren_depth();
370 self.consume(Token::LeftParen)?;
372 let query = self.parse_select_statement_inner()?;
373 self.consume(Token::RightParen)?;
375 self.pop_paren_depth();
377 CTEType::Standard(query)
378 };
379
380 ctes.push(CTE {
381 name,
382 column_list,
383 cte_type,
384 });
385
386 if !matches!(self.current_token, Token::Comma) {
388 break;
389 }
390 self.advance();
391 }
392
393 Ok(ctes)
394 }
395
396 fn parse_optional_alias(&mut self) -> Result<Option<String>, String> {
398 if matches!(self.current_token, Token::As) {
399 self.advance();
400 match &self.current_token {
401 Token::Identifier(name) => {
402 let alias = name.clone();
403 self.advance();
404 Ok(Some(alias))
405 }
406 _ => Err("Expected alias name after AS".to_string()),
407 }
408 } else if let Token::Identifier(name) = &self.current_token {
409 let alias = name.clone();
411 self.advance();
412 Ok(Some(alias))
413 } else {
414 Ok(None)
415 }
416 }
417
418 fn is_valid_identifier(name: &str) -> bool {
420 if name.starts_with('"') && name.ends_with('"') {
421 true
423 } else {
424 name.chars().all(|c| c.is_alphanumeric() || c == '_')
426 }
427 }
428
429 fn update_paren_depth(&mut self, token: &Token) -> Result<(), String> {
431 match token {
432 Token::LeftParen => self.paren_depth += 1,
433 Token::RightParen => {
434 self.paren_depth -= 1;
435 if self.paren_depth < 0 {
437 return Err(
438 "Unexpected closing parenthesis - no matching opening parenthesis"
439 .to_string(),
440 );
441 }
442 }
443 _ => {}
444 }
445 Ok(())
446 }
447
448 fn parse_argument_list(&mut self) -> Result<Vec<SqlExpression>, String> {
450 let mut args = Vec::new();
451
452 if !matches!(self.current_token, Token::RightParen) {
453 loop {
454 args.push(self.parse_expression()?);
455
456 if matches!(self.current_token, Token::Comma) {
457 self.advance();
458 } else {
459 break;
460 }
461 }
462 }
463
464 Ok(args)
465 }
466
467 fn check_balanced_parentheses(&self) -> Result<(), String> {
469 if self.paren_depth > 0 {
470 Err(format!(
471 "Unclosed parenthesis - missing {} closing parenthes{}",
472 self.paren_depth,
473 if self.paren_depth == 1 { "is" } else { "es" }
474 ))
475 } else if self.paren_depth < 0 {
476 Err("Extra closing parenthesis found - no matching opening parenthesis".to_string())
477 } else {
478 Ok(())
479 }
480 }
481
482 fn parse_select_statement(&mut self) -> Result<SelectStatement, String> {
483 self.trace_enter("parse_select_statement");
484 let result = self.parse_select_statement_inner()?;
485
486 self.check_balanced_parentheses()?;
488
489 Ok(result)
490 }
491
492 fn parse_select_statement_inner(&mut self) -> Result<SelectStatement, String> {
493 self.consume(Token::Select)?;
494
495 let distinct = if matches!(self.current_token, Token::Distinct) {
497 self.advance();
498 true
499 } else {
500 false
501 };
502
503 let select_items = self.parse_select_items()?;
505
506 let columns = select_items
508 .iter()
509 .map(|item| match item {
510 SelectItem::Star { .. } => "*".to_string(),
511 SelectItem::Column {
512 column: col_ref, ..
513 } => col_ref.name.clone(),
514 SelectItem::Expression { alias, .. } => alias.clone(),
515 })
516 .collect();
517
518 let into_table = if matches!(self.current_token, Token::Into) {
520 self.advance();
521 Some(self.parse_into_clause()?)
522 } else {
523 None
524 };
525
526 let (from_table, from_subquery, from_function, from_alias) =
528 if matches!(self.current_token, Token::From) {
529 self.advance();
530
531 if let Token::Identifier(name) = &self.current_token.clone() {
533 let has_paren = self.peek_token() == Some(Token::LeftParen);
537 if self.debug_trace {
538 eprintln!(
539 " Checking {} for table function, has_paren={}",
540 name, has_paren
541 );
542 }
543
544 let is_table_function = if has_paren {
547 if self.debug_trace {
549 eprintln!(" Checking generator registry for {}", name.to_uppercase());
550 }
551 if let Some(_gen) = self.generator_registry.get(&name.to_uppercase()) {
552 if self.debug_trace {
553 eprintln!(" Found {} in generator registry", name);
554 }
555 self.trace_token(&format!("Found generator: {}", name));
556 true
557 } else {
558 if let Some(func) = self.function_registry.get(&name.to_uppercase()) {
560 let sig = func.signature();
561 let is_table_fn = sig.category == FunctionCategory::TableFunction;
562 if self.debug_trace {
563 eprintln!(
564 " Found {} in function registry, is_table_function={}",
565 name, is_table_fn
566 );
567 }
568 if is_table_fn {
569 self.trace_token(&format!(
570 "Found table function in function registry: {}",
571 name
572 ));
573 }
574 is_table_fn
575 } else {
576 if self.debug_trace {
577 eprintln!(" {} not found in either registry", name);
578 self.trace_token(&format!(
579 "Not found as generator or table function: {}",
580 name
581 ));
582 }
583 false
584 }
585 }
586 } else {
587 if self.debug_trace {
588 eprintln!(" No parenthesis after {}, treating as table", name);
589 }
590 false
591 };
592
593 if is_table_function {
594 let function_name = name.clone();
596 self.advance(); self.consume(Token::LeftParen)?;
600 let args = self.parse_argument_list()?;
601 self.consume(Token::RightParen)?;
602
603 let alias = if matches!(self.current_token, Token::As) {
605 self.advance();
606 match &self.current_token {
607 Token::Identifier(name) => {
608 let alias = name.clone();
609 self.advance();
610 Some(alias)
611 }
612 _ => return Err("Expected alias name after AS".to_string()),
613 }
614 } else if let Token::Identifier(name) = &self.current_token {
615 let alias = name.clone();
616 self.advance();
617 Some(alias)
618 } else {
619 None
620 };
621
622 (
623 None,
624 None,
625 Some(TableFunction::Generator {
626 name: function_name,
627 args,
628 }),
629 alias,
630 )
631 } else {
632 let table_name = name.clone();
634 self.advance();
635
636 let alias = self.parse_optional_alias()?;
638
639 (Some(table_name), None, None, alias)
640 }
641 } else if matches!(self.current_token, Token::LeftParen) {
642 self.advance();
644
645 let subquery = if matches!(self.current_token, Token::With) {
647 self.parse_with_clause_inner()?
648 } else {
649 self.parse_select_statement_inner()?
650 };
651
652 self.consume(Token::RightParen)?;
653
654 let alias = if matches!(self.current_token, Token::As) {
656 self.advance();
657 match &self.current_token {
658 Token::Identifier(name) => {
659 let alias = name.clone();
660 self.advance();
661 alias
662 }
663 _ => return Err("Expected alias name after AS".to_string()),
664 }
665 } else {
666 match &self.current_token {
668 Token::Identifier(name) => {
669 let alias = name.clone();
670 self.advance();
671 alias
672 }
673 _ => {
674 return Err(
675 "Subquery in FROM must have an alias (e.g., AS t)".to_string()
676 )
677 }
678 }
679 };
680
681 (None, Some(Box::new(subquery)), None, Some(alias))
682 } else {
683 match &self.current_token {
685 Token::Identifier(table) => {
686 let table_name = table.clone();
687 self.advance();
688
689 let alias = self.parse_optional_alias()?;
691
692 (Some(table_name), None, None, alias)
693 }
694 Token::QuotedIdentifier(table) => {
695 let table_name = table.clone();
697 self.advance();
698
699 let alias = self.parse_optional_alias()?;
701
702 (Some(table_name), None, None, alias)
703 }
704 _ => return Err("Expected table name or subquery after FROM".to_string()),
705 }
706 }
707 } else {
708 (None, None, None, None)
709 };
710
711 let mut joins = Vec::new();
713 while self.is_join_token() {
714 joins.push(self.parse_join_clause()?);
715 }
716
717 let where_clause = if matches!(self.current_token, Token::Where) {
718 self.advance();
719 Some(self.parse_where_clause()?)
720 } else {
721 None
722 };
723
724 let group_by = if matches!(self.current_token, Token::GroupBy) {
725 self.advance();
726 Some(self.parse_expression_list()?)
729 } else {
730 None
731 };
732
733 let having = if matches!(self.current_token, Token::Having) {
735 if group_by.is_none() {
736 return Err("HAVING clause requires GROUP BY".to_string());
737 }
738 self.advance();
739 Some(self.parse_expression()?)
740 } else {
741 None
742 };
743
744 let order_by = if matches!(self.current_token, Token::OrderBy) {
746 self.trace_token("Found OrderBy token");
747 self.advance();
748 Some(self.parse_order_by_list()?)
749 } else if let Token::Identifier(s) = &self.current_token {
750 if Self::is_identifier_reserved(s) && s.to_uppercase() == "ORDER" {
753 self.trace_token("Warning: ORDER as identifier instead of OrderBy token");
754 self.advance(); if matches!(&self.current_token, Token::By) {
756 self.advance(); Some(self.parse_order_by_list()?)
758 } else {
759 return Err("Expected BY after ORDER".to_string());
760 }
761 } else {
762 None
763 }
764 } else {
765 None
766 };
767
768 let limit = if matches!(self.current_token, Token::Limit) {
770 self.advance();
771 match &self.current_token {
772 Token::NumberLiteral(num) => {
773 let limit_val = num
774 .parse::<usize>()
775 .map_err(|_| format!("Invalid LIMIT value: {num}"))?;
776 self.advance();
777 Some(limit_val)
778 }
779 _ => return Err("Expected number after LIMIT".to_string()),
780 }
781 } else {
782 None
783 };
784
785 let offset = if matches!(self.current_token, Token::Offset) {
787 self.advance();
788 match &self.current_token {
789 Token::NumberLiteral(num) => {
790 let offset_val = num
791 .parse::<usize>()
792 .map_err(|_| format!("Invalid OFFSET value: {num}"))?;
793 self.advance();
794 Some(offset_val)
795 }
796 _ => return Err("Expected number after OFFSET".to_string()),
797 }
798 } else {
799 None
800 };
801
802 let into_table = if into_table.is_none() && matches!(self.current_token, Token::Into) {
806 self.advance();
807 Some(self.parse_into_clause()?)
808 } else {
809 into_table };
811
812 let set_operations = self.parse_set_operations()?;
814
815 Ok(SelectStatement {
816 distinct,
817 columns,
818 select_items,
819 from_table,
820 from_subquery,
821 from_function,
822 from_alias,
823 joins,
824 where_clause,
825 order_by,
826 group_by,
827 having,
828 limit,
829 offset,
830 ctes: Vec::new(), into_table,
832 set_operations,
833 leading_comments: vec![],
834 trailing_comment: None,
835 })
836 }
837
838 fn parse_set_operations(
841 &mut self,
842 ) -> Result<Vec<(SetOperation, Box<SelectStatement>)>, String> {
843 let mut operations = Vec::new();
844
845 while matches!(
846 self.current_token,
847 Token::Union | Token::Intersect | Token::Except
848 ) {
849 let operation = match &self.current_token {
851 Token::Union => {
852 self.advance();
853 if let Token::Identifier(id) = &self.current_token {
855 if id.to_uppercase() == "ALL" {
856 self.advance();
857 SetOperation::UnionAll
858 } else {
859 SetOperation::Union
860 }
861 } else {
862 SetOperation::Union
863 }
864 }
865 Token::Intersect => {
866 self.advance();
867 SetOperation::Intersect
868 }
869 Token::Except => {
870 self.advance();
871 SetOperation::Except
872 }
873 _ => unreachable!(),
874 };
875
876 let next_select = self.parse_select_statement_inner()?;
878
879 operations.push((operation, Box::new(next_select)));
880 }
881
882 Ok(operations)
883 }
884
885 fn parse_select_items(&mut self) -> Result<Vec<SelectItem>, String> {
887 let mut items = Vec::new();
888
889 loop {
890 if matches!(self.current_token, Token::Star) {
893 items.push(SelectItem::Star {
901 leading_comments: vec![],
902 trailing_comment: None,
903 });
904 self.advance();
905 } else {
906 let expr = self.parse_comparison()?; let alias = if matches!(self.current_token, Token::As) {
911 self.advance();
912 match &self.current_token {
913 Token::Identifier(alias_name) => {
914 let alias = alias_name.clone();
915 self.advance();
916 alias
917 }
918 Token::QuotedIdentifier(alias_name) => {
919 let alias = alias_name.clone();
920 self.advance();
921 alias
922 }
923 _ => return Err("Expected alias name after AS".to_string()),
924 }
925 } else {
926 match &expr {
928 SqlExpression::Column(col_ref) => col_ref.name.clone(),
929 _ => format!("expr_{}", items.len() + 1), }
931 };
932
933 let item = match expr {
935 SqlExpression::Column(col_ref) if alias == col_ref.name => {
936 SelectItem::Column {
938 column: col_ref,
939 leading_comments: vec![],
940 trailing_comment: None,
941 }
942 }
943 _ => {
944 SelectItem::Expression {
946 expr,
947 alias,
948 leading_comments: vec![],
949 trailing_comment: None,
950 }
951 }
952 };
953
954 items.push(item);
955 }
956
957 if matches!(self.current_token, Token::Comma) {
959 self.advance();
960 } else {
961 break;
962 }
963 }
964
965 Ok(items)
966 }
967
968 fn parse_identifier_list(&mut self) -> Result<Vec<String>, String> {
969 let mut identifiers = Vec::new();
970
971 loop {
972 match &self.current_token {
973 Token::Identifier(id) => {
974 if Self::is_identifier_reserved(id) {
976 break;
978 }
979 identifiers.push(id.clone());
980 self.advance();
981 }
982 Token::QuotedIdentifier(id) => {
983 identifiers.push(id.clone());
985 self.advance();
986 }
987 _ => {
988 break;
990 }
991 }
992
993 if matches!(self.current_token, Token::Comma) {
994 self.advance();
995 } else {
996 break;
997 }
998 }
999
1000 if identifiers.is_empty() {
1001 return Err("Expected at least one identifier".to_string());
1002 }
1003
1004 Ok(identifiers)
1005 }
1006
1007 fn parse_window_spec(&mut self) -> Result<WindowSpec, String> {
1008 let mut partition_by = Vec::new();
1009 let mut order_by = Vec::new();
1010
1011 if matches!(self.current_token, Token::Partition) {
1013 self.advance(); if !matches!(self.current_token, Token::By) {
1015 return Err("Expected BY after PARTITION".to_string());
1016 }
1017 self.advance(); partition_by = self.parse_identifier_list()?;
1021 }
1022
1023 if matches!(self.current_token, Token::OrderBy) {
1025 self.advance(); order_by = self.parse_order_by_list()?;
1027 } else if let Token::Identifier(s) = &self.current_token {
1028 if Self::is_identifier_reserved(s) && s.to_uppercase() == "ORDER" {
1029 self.advance(); if !matches!(self.current_token, Token::By) {
1032 return Err("Expected BY after ORDER".to_string());
1033 }
1034 self.advance(); order_by = self.parse_order_by_list()?;
1036 }
1037 }
1038
1039 let frame = self.parse_window_frame()?;
1041
1042 Ok(WindowSpec {
1043 partition_by,
1044 order_by,
1045 frame,
1046 })
1047 }
1048
1049 fn parse_order_by_list(&mut self) -> Result<Vec<OrderByColumn>, String> {
1050 let mut order_columns = Vec::new();
1051
1052 loop {
1053 let column = match &self.current_token {
1054 Token::Identifier(id) => {
1055 let col = id.clone();
1056 self.advance();
1057
1058 if matches!(self.current_token, Token::Dot) {
1060 self.advance();
1061 match &self.current_token {
1062 Token::Identifier(col_name) => {
1063 let mut qualified = col;
1064 qualified.push('.');
1065 qualified.push_str(col_name);
1066 self.advance();
1067 qualified
1068 }
1069 _ => return Err("Expected column name after '.'".to_string()),
1070 }
1071 } else {
1072 col
1073 }
1074 }
1075 Token::QuotedIdentifier(id) => {
1076 let col = id.clone();
1077 self.advance();
1078 col
1079 }
1080 Token::NumberLiteral(num) if self.columns.iter().any(|col| col == num) => {
1081 let col = num.clone();
1083 self.advance();
1084 col
1085 }
1086 Token::Row => {
1088 self.advance();
1089 "row".to_string()
1090 }
1091 Token::Rows => {
1092 self.advance();
1093 "rows".to_string()
1094 }
1095 Token::Range => {
1096 self.advance();
1097 "range".to_string()
1098 }
1099 _ => return Err("Expected column name in ORDER BY".to_string()),
1100 };
1101
1102 let direction = match &self.current_token {
1104 Token::Asc => {
1105 self.advance();
1106 SortDirection::Asc
1107 }
1108 Token::Desc => {
1109 self.advance();
1110 SortDirection::Desc
1111 }
1112 _ => SortDirection::Asc, };
1114
1115 order_columns.push(OrderByColumn { column, direction });
1116
1117 if matches!(self.current_token, Token::Comma) {
1118 self.advance();
1119 } else {
1120 break;
1121 }
1122 }
1123
1124 Ok(order_columns)
1125 }
1126
1127 fn parse_into_clause(&mut self) -> Result<IntoTable, String> {
1130 let name = match &self.current_token {
1132 Token::Identifier(id) if id.starts_with('#') => {
1133 let table_name = id.clone();
1134 self.advance();
1135 table_name
1136 }
1137 Token::Identifier(id) => {
1138 return Err(format!(
1139 "Temporary table name must start with #, got: {}",
1140 id
1141 ));
1142 }
1143 _ => {
1144 return Err(
1145 "Expected temporary table name (starting with #) after INTO".to_string()
1146 );
1147 }
1148 };
1149
1150 Ok(IntoTable { name })
1151 }
1152
1153 fn parse_window_frame(&mut self) -> Result<Option<WindowFrame>, String> {
1154 let unit = match &self.current_token {
1156 Token::Rows => {
1157 self.advance();
1158 FrameUnit::Rows
1159 }
1160 Token::Identifier(id) if id.to_uppercase() == "RANGE" => {
1161 self.advance();
1163 FrameUnit::Range
1164 }
1165 _ => return Ok(None), };
1167
1168 let (start, end) = if let Token::Between = &self.current_token {
1170 self.advance(); let start = self.parse_frame_bound()?;
1173
1174 if !matches!(&self.current_token, Token::And) {
1176 return Err("Expected AND after window frame start bound".to_string());
1177 }
1178 self.advance();
1179
1180 let end = self.parse_frame_bound()?;
1182 (start, Some(end))
1183 } else {
1184 let bound = self.parse_frame_bound()?;
1186 (bound, None)
1187 };
1188
1189 Ok(Some(WindowFrame { unit, start, end }))
1190 }
1191
1192 fn parse_frame_bound(&mut self) -> Result<FrameBound, String> {
1193 match &self.current_token {
1194 Token::Unbounded => {
1195 self.advance();
1196 match &self.current_token {
1197 Token::Preceding => {
1198 self.advance();
1199 Ok(FrameBound::UnboundedPreceding)
1200 }
1201 Token::Following => {
1202 self.advance();
1203 Ok(FrameBound::UnboundedFollowing)
1204 }
1205 _ => Err("Expected PRECEDING or FOLLOWING after UNBOUNDED".to_string()),
1206 }
1207 }
1208 Token::Current => {
1209 self.advance();
1210 if matches!(&self.current_token, Token::Row) {
1211 self.advance();
1212 return Ok(FrameBound::CurrentRow);
1213 }
1214 Err("Expected ROW after CURRENT".to_string())
1215 }
1216 Token::NumberLiteral(num) => {
1217 let n: i64 = num
1218 .parse()
1219 .map_err(|_| "Invalid number in window frame".to_string())?;
1220 self.advance();
1221 match &self.current_token {
1222 Token::Preceding => {
1223 self.advance();
1224 Ok(FrameBound::Preceding(n))
1225 }
1226 Token::Following => {
1227 self.advance();
1228 Ok(FrameBound::Following(n))
1229 }
1230 _ => Err("Expected PRECEDING or FOLLOWING after number".to_string()),
1231 }
1232 }
1233 _ => Err("Invalid window frame bound".to_string()),
1234 }
1235 }
1236
1237 fn parse_where_clause(&mut self) -> Result<WhereClause, String> {
1238 let expr = self.parse_expression()?;
1241
1242 if matches!(self.current_token, Token::RightParen) && self.paren_depth <= 0 {
1244 return Err(
1245 "Unexpected closing parenthesis - no matching opening parenthesis".to_string(),
1246 );
1247 }
1248
1249 let conditions = vec![Condition {
1251 expr,
1252 connector: None,
1253 }];
1254
1255 Ok(WhereClause { conditions })
1256 }
1257
1258 fn parse_expression(&mut self) -> Result<SqlExpression, String> {
1259 self.trace_enter("parse_expression");
1260 let mut left = self.parse_logical_or()?;
1263
1264 left = parse_in_operator(self, left)?;
1267
1268 let result = Ok(left);
1269 self.trace_exit("parse_expression", &result);
1270 result
1271 }
1272
1273 fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
1274 parse_comparison_expr(self)
1276 }
1277
1278 fn parse_additive(&mut self) -> Result<SqlExpression, String> {
1279 parse_additive_expr(self)
1281 }
1282
1283 fn parse_multiplicative(&mut self) -> Result<SqlExpression, String> {
1284 parse_multiplicative_expr(self)
1286 }
1287
1288 fn parse_logical_or(&mut self) -> Result<SqlExpression, String> {
1289 parse_logical_or_expr(self)
1291 }
1292
1293 fn parse_logical_and(&mut self) -> Result<SqlExpression, String> {
1294 parse_logical_and_expr(self)
1296 }
1297
1298 fn parse_case_expression(&mut self) -> Result<SqlExpression, String> {
1299 parse_case_expr(self)
1301 }
1302
1303 fn parse_primary(&mut self) -> Result<SqlExpression, String> {
1304 let columns = self.columns.clone();
1307 let in_method_args = self.in_method_args;
1308 let ctx = PrimaryExpressionContext {
1309 columns: &columns,
1310 in_method_args,
1311 };
1312 parse_primary_expr(self, &ctx)
1313 }
1314
1315 fn parse_method_args(&mut self) -> Result<Vec<SqlExpression>, String> {
1317 self.in_method_args = true;
1319
1320 let args = self.parse_argument_list()?;
1321
1322 self.in_method_args = false;
1324
1325 Ok(args)
1326 }
1327
1328 fn parse_function_args(&mut self) -> Result<(Vec<SqlExpression>, bool), String> {
1329 let mut args = Vec::new();
1330 let mut has_distinct = false;
1331
1332 if !matches!(self.current_token, Token::RightParen) {
1333 if matches!(self.current_token, Token::Distinct) {
1335 self.advance(); has_distinct = true;
1337 }
1338
1339 args.push(self.parse_additive()?);
1341
1342 while matches!(self.current_token, Token::Comma) {
1344 self.advance();
1345 args.push(self.parse_additive()?);
1346 }
1347 }
1348
1349 Ok((args, has_distinct))
1350 }
1351
1352 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
1353 let mut expressions = Vec::new();
1354
1355 loop {
1356 expressions.push(self.parse_expression()?);
1357
1358 if matches!(self.current_token, Token::Comma) {
1359 self.advance();
1360 } else {
1361 break;
1362 }
1363 }
1364
1365 Ok(expressions)
1366 }
1367
1368 #[must_use]
1369 pub fn get_position(&self) -> usize {
1370 self.lexer.get_position()
1371 }
1372
1373 fn is_join_token(&self) -> bool {
1375 matches!(
1376 self.current_token,
1377 Token::Join | Token::Inner | Token::Left | Token::Right | Token::Full | Token::Cross
1378 )
1379 }
1380
1381 fn parse_join_clause(&mut self) -> Result<JoinClause, String> {
1383 let join_type = match &self.current_token {
1385 Token::Join => {
1386 self.advance();
1387 JoinType::Inner }
1389 Token::Inner => {
1390 self.advance();
1391 if !matches!(self.current_token, Token::Join) {
1392 return Err("Expected JOIN after INNER".to_string());
1393 }
1394 self.advance();
1395 JoinType::Inner
1396 }
1397 Token::Left => {
1398 self.advance();
1399 if matches!(self.current_token, Token::Outer) {
1401 self.advance();
1402 }
1403 if !matches!(self.current_token, Token::Join) {
1404 return Err("Expected JOIN after LEFT".to_string());
1405 }
1406 self.advance();
1407 JoinType::Left
1408 }
1409 Token::Right => {
1410 self.advance();
1411 if matches!(self.current_token, Token::Outer) {
1413 self.advance();
1414 }
1415 if !matches!(self.current_token, Token::Join) {
1416 return Err("Expected JOIN after RIGHT".to_string());
1417 }
1418 self.advance();
1419 JoinType::Right
1420 }
1421 Token::Full => {
1422 self.advance();
1423 if matches!(self.current_token, Token::Outer) {
1425 self.advance();
1426 }
1427 if !matches!(self.current_token, Token::Join) {
1428 return Err("Expected JOIN after FULL".to_string());
1429 }
1430 self.advance();
1431 JoinType::Full
1432 }
1433 Token::Cross => {
1434 self.advance();
1435 if !matches!(self.current_token, Token::Join) {
1436 return Err("Expected JOIN after CROSS".to_string());
1437 }
1438 self.advance();
1439 JoinType::Cross
1440 }
1441 _ => return Err("Expected JOIN keyword".to_string()),
1442 };
1443
1444 let (table, alias) = self.parse_join_table_source()?;
1446
1447 let condition = if join_type == JoinType::Cross {
1449 JoinCondition { conditions: vec![] }
1451 } else {
1452 if !matches!(self.current_token, Token::On) {
1453 return Err("Expected ON keyword after JOIN table".to_string());
1454 }
1455 self.advance();
1456 self.parse_join_condition()?
1457 };
1458
1459 Ok(JoinClause {
1460 join_type,
1461 table,
1462 alias,
1463 condition,
1464 })
1465 }
1466
1467 fn parse_join_table_source(&mut self) -> Result<(TableSource, Option<String>), String> {
1468 let table = match &self.current_token {
1469 Token::Identifier(name) => {
1470 let table_name = name.clone();
1471 self.advance();
1472 TableSource::Table(table_name)
1473 }
1474 Token::LeftParen => {
1475 self.advance();
1477 let subquery = self.parse_select_statement_inner()?;
1478 if !matches!(self.current_token, Token::RightParen) {
1479 return Err("Expected ')' after subquery".to_string());
1480 }
1481 self.advance();
1482
1483 let alias = match &self.current_token {
1485 Token::Identifier(alias_name) => {
1486 let alias = alias_name.clone();
1487 self.advance();
1488 alias
1489 }
1490 Token::As => {
1491 self.advance();
1492 match &self.current_token {
1493 Token::Identifier(alias_name) => {
1494 let alias = alias_name.clone();
1495 self.advance();
1496 alias
1497 }
1498 _ => return Err("Expected alias after AS keyword".to_string()),
1499 }
1500 }
1501 _ => return Err("Subqueries must have an alias".to_string()),
1502 };
1503
1504 return Ok((
1505 TableSource::DerivedTable {
1506 query: Box::new(subquery),
1507 alias: alias.clone(),
1508 },
1509 Some(alias),
1510 ));
1511 }
1512 _ => return Err("Expected table name or subquery in JOIN clause".to_string()),
1513 };
1514
1515 let alias = match &self.current_token {
1517 Token::Identifier(alias_name) => {
1518 let alias = alias_name.clone();
1519 self.advance();
1520 Some(alias)
1521 }
1522 Token::As => {
1523 self.advance();
1524 match &self.current_token {
1525 Token::Identifier(alias_name) => {
1526 let alias = alias_name.clone();
1527 self.advance();
1528 Some(alias)
1529 }
1530 _ => return Err("Expected alias after AS keyword".to_string()),
1531 }
1532 }
1533 _ => None,
1534 };
1535
1536 Ok((table, alias))
1537 }
1538
1539 fn parse_join_condition(&mut self) -> Result<JoinCondition, String> {
1540 let mut conditions = Vec::new();
1541
1542 conditions.push(self.parse_single_join_condition()?);
1544
1545 while matches!(self.current_token, Token::And) {
1547 self.advance(); conditions.push(self.parse_single_join_condition()?);
1549 }
1550
1551 Ok(JoinCondition { conditions })
1552 }
1553
1554 fn parse_single_join_condition(&mut self) -> Result<SingleJoinCondition, String> {
1555 let left_column = self.parse_column_reference()?;
1557
1558 let operator = match &self.current_token {
1560 Token::Equal => JoinOperator::Equal,
1561 Token::NotEqual => JoinOperator::NotEqual,
1562 Token::LessThan => JoinOperator::LessThan,
1563 Token::LessThanOrEqual => JoinOperator::LessThanOrEqual,
1564 Token::GreaterThan => JoinOperator::GreaterThan,
1565 Token::GreaterThanOrEqual => JoinOperator::GreaterThanOrEqual,
1566 _ => return Err("Expected comparison operator in JOIN condition".to_string()),
1567 };
1568 self.advance();
1569
1570 let right_column = self.parse_column_reference()?;
1572
1573 Ok(SingleJoinCondition {
1574 left_column,
1575 operator,
1576 right_column,
1577 })
1578 }
1579
1580 fn parse_column_reference(&mut self) -> Result<String, String> {
1581 match &self.current_token {
1582 Token::Identifier(name) => {
1583 let mut column_ref = name.clone();
1584 self.advance();
1585
1586 if matches!(self.current_token, Token::Dot) {
1588 self.advance();
1589 match &self.current_token {
1590 Token::Identifier(col_name) => {
1591 column_ref.push('.');
1592 column_ref.push_str(col_name);
1593 self.advance();
1594 }
1595 _ => return Err("Expected column name after '.'".to_string()),
1596 }
1597 }
1598
1599 Ok(column_ref)
1600 }
1601 _ => Err("Expected column reference".to_string()),
1602 }
1603 }
1604}
1605
1606#[derive(Debug, Clone)]
1608pub enum CursorContext {
1609 SelectClause,
1610 FromClause,
1611 WhereClause,
1612 OrderByClause,
1613 AfterColumn(String),
1614 AfterLogicalOp(LogicalOp),
1615 AfterComparisonOp(String, String), InMethodCall(String, String), InExpression,
1618 Unknown,
1619}
1620
1621fn safe_slice_to(s: &str, pos: usize) -> &str {
1623 if pos >= s.len() {
1624 return s;
1625 }
1626
1627 let mut safe_pos = pos;
1629 while safe_pos > 0 && !s.is_char_boundary(safe_pos) {
1630 safe_pos -= 1;
1631 }
1632
1633 &s[..safe_pos]
1634}
1635
1636fn safe_slice_from(s: &str, pos: usize) -> &str {
1638 if pos >= s.len() {
1639 return "";
1640 }
1641
1642 let mut safe_pos = pos;
1644 while safe_pos < s.len() && !s.is_char_boundary(safe_pos) {
1645 safe_pos += 1;
1646 }
1647
1648 &s[safe_pos..]
1649}
1650
1651#[must_use]
1652pub fn detect_cursor_context(query: &str, cursor_pos: usize) -> (CursorContext, Option<String>) {
1653 let truncated = safe_slice_to(query, cursor_pos);
1654 let mut parser = Parser::new(truncated);
1655
1656 if let Ok(stmt) = parser.parse() {
1658 let (ctx, partial) = analyze_statement(&stmt, truncated, cursor_pos);
1659 #[cfg(test)]
1660 println!("analyze_statement returned: {ctx:?}, {partial:?} for query: '{truncated}'");
1661 (ctx, partial)
1662 } else {
1663 let (ctx, partial) = analyze_partial(truncated, cursor_pos);
1665 #[cfg(test)]
1666 println!("analyze_partial returned: {ctx:?}, {partial:?} for query: '{truncated}'");
1667 (ctx, partial)
1668 }
1669}
1670
1671#[must_use]
1672pub fn tokenize_query(query: &str) -> Vec<String> {
1673 let mut lexer = Lexer::new(query);
1674 let tokens = lexer.tokenize_all();
1675 tokens.iter().map(|t| format!("{t:?}")).collect()
1676}
1677
1678#[must_use]
1679fn find_quote_start(bytes: &[u8], mut pos: usize) -> Option<usize> {
1681 if pos > 0 {
1683 pos -= 1;
1684 while pos > 0 {
1685 if bytes[pos] == b'"' {
1686 if pos == 0 || bytes[pos - 1] != b'\\' {
1688 return Some(pos);
1689 }
1690 }
1691 pos -= 1;
1692 }
1693 if bytes[0] == b'"' {
1695 return Some(0);
1696 }
1697 }
1698 None
1699}
1700
1701fn handle_method_call_context(col_name: &str, after_dot: &str) -> (CursorContext, Option<String>) {
1703 let partial_method = if after_dot.is_empty() {
1705 None
1706 } else if after_dot.chars().all(|c| c.is_alphanumeric() || c == '_') {
1707 Some(after_dot.to_string())
1708 } else {
1709 None
1710 };
1711
1712 let col_name_for_context =
1714 if col_name.starts_with('"') && col_name.ends_with('"') && col_name.len() > 2 {
1715 col_name[1..col_name.len() - 1].to_string()
1716 } else {
1717 col_name.to_string()
1718 };
1719
1720 (
1721 CursorContext::AfterColumn(col_name_for_context),
1722 partial_method,
1723 )
1724}
1725
1726fn check_after_comparison_operator(query: &str) -> Option<(CursorContext, Option<String>)> {
1728 for op in &Parser::COMPARISON_OPERATORS {
1729 if let Some(op_pos) = query.rfind(op) {
1730 let before_op = safe_slice_to(query, op_pos);
1731 let after_op_start = op_pos + op.len();
1732 let after_op = if after_op_start < query.len() {
1733 &query[after_op_start..]
1734 } else {
1735 ""
1736 };
1737
1738 if let Some(col_name) = before_op.split_whitespace().last() {
1740 if col_name.chars().all(|c| c.is_alphanumeric() || c == '_') {
1741 let after_op_trimmed = after_op.trim();
1743 if after_op_trimmed.is_empty()
1744 || (after_op_trimmed
1745 .chars()
1746 .all(|c| c.is_alphanumeric() || c == '_')
1747 && !after_op_trimmed.contains('('))
1748 {
1749 let partial = if after_op_trimmed.is_empty() {
1750 None
1751 } else {
1752 Some(after_op_trimmed.to_string())
1753 };
1754 return Some((
1755 CursorContext::AfterComparisonOp(
1756 col_name.to_string(),
1757 op.trim().to_string(),
1758 ),
1759 partial,
1760 ));
1761 }
1762 }
1763 }
1764 }
1765 }
1766 None
1767}
1768
1769fn analyze_statement(
1770 stmt: &SelectStatement,
1771 query: &str,
1772 _cursor_pos: usize,
1773) -> (CursorContext, Option<String>) {
1774 let trimmed = query.trim();
1776
1777 if let Some(result) = check_after_comparison_operator(query) {
1779 return result;
1780 }
1781
1782 let ends_with_logical_op = |s: &str| -> bool {
1785 let s_upper = s.to_uppercase();
1786 s_upper.ends_with(" AND") || s_upper.ends_with(" OR")
1787 };
1788
1789 if ends_with_logical_op(trimmed) {
1790 } else {
1792 if let Some(dot_pos) = trimmed.rfind('.') {
1794 let before_dot = safe_slice_to(trimmed, dot_pos);
1796 let after_dot_start = dot_pos + 1;
1797 let after_dot = if after_dot_start < trimmed.len() {
1798 &trimmed[after_dot_start..]
1799 } else {
1800 ""
1801 };
1802
1803 if !after_dot.contains('(') {
1806 let col_name = if before_dot.ends_with('"') {
1808 let bytes = before_dot.as_bytes();
1810 let pos = before_dot.len() - 1; find_quote_start(bytes, pos).map(|start| safe_slice_from(before_dot, start))
1813 } else {
1814 before_dot
1817 .split_whitespace()
1818 .last()
1819 .map(|word| word.trim_start_matches('('))
1820 };
1821
1822 if let Some(col_name) = col_name {
1823 let is_valid = Parser::is_valid_identifier(col_name);
1825
1826 if is_valid {
1827 return handle_method_call_context(col_name, after_dot);
1828 }
1829 }
1830 }
1831 }
1832 }
1833
1834 if let Some(where_clause) = &stmt.where_clause {
1836 let trimmed_upper = trimmed.to_uppercase();
1838 if trimmed_upper.ends_with(" AND") || trimmed_upper.ends_with(" OR") {
1839 let op = if trimmed_upper.ends_with(" AND") {
1840 LogicalOp::And
1841 } else {
1842 LogicalOp::Or
1843 };
1844 return (CursorContext::AfterLogicalOp(op), None);
1845 }
1846
1847 let query_upper = query.to_uppercase();
1849 if let Some(and_pos) = query_upper.rfind(" AND ") {
1850 let after_and = safe_slice_from(query, and_pos + 5);
1851 let partial = extract_partial_at_end(after_and);
1852 if partial.is_some() {
1853 return (CursorContext::AfterLogicalOp(LogicalOp::And), partial);
1854 }
1855 }
1856
1857 if let Some(or_pos) = query_upper.rfind(" OR ") {
1858 let after_or = safe_slice_from(query, or_pos + 4);
1859 let partial = extract_partial_at_end(after_or);
1860 if partial.is_some() {
1861 return (CursorContext::AfterLogicalOp(LogicalOp::Or), partial);
1862 }
1863 }
1864
1865 if let Some(last_condition) = where_clause.conditions.last() {
1866 if let Some(connector) = &last_condition.connector {
1867 return (
1869 CursorContext::AfterLogicalOp(connector.clone()),
1870 extract_partial_at_end(query),
1871 );
1872 }
1873 }
1874 return (CursorContext::WhereClause, extract_partial_at_end(query));
1876 }
1877
1878 let query_upper = query.to_uppercase();
1880 if query_upper.ends_with(" ORDER BY") {
1881 return (CursorContext::OrderByClause, None);
1882 }
1883
1884 if stmt.order_by.is_some() {
1886 return (CursorContext::OrderByClause, extract_partial_at_end(query));
1887 }
1888
1889 if stmt.from_table.is_some() && stmt.where_clause.is_none() && stmt.order_by.is_none() {
1890 return (CursorContext::FromClause, extract_partial_at_end(query));
1891 }
1892
1893 if !stmt.columns.is_empty() && stmt.from_table.is_none() {
1894 return (CursorContext::SelectClause, extract_partial_at_end(query));
1895 }
1896
1897 (CursorContext::Unknown, None)
1898}
1899
1900fn find_last_token(tokens: &[(usize, usize, Token)], target: &Token) -> Option<usize> {
1902 tokens
1903 .iter()
1904 .rposition(|(_, _, t)| t == target)
1905 .map(|idx| tokens[idx].0)
1906}
1907
1908fn find_last_matching_token<F>(
1910 tokens: &[(usize, usize, Token)],
1911 predicate: F,
1912) -> Option<(usize, &Token)>
1913where
1914 F: Fn(&Token) -> bool,
1915{
1916 tokens
1917 .iter()
1918 .rposition(|(_, _, t)| predicate(t))
1919 .map(|idx| (tokens[idx].0, &tokens[idx].2))
1920}
1921
1922fn is_in_clause(
1924 tokens: &[(usize, usize, Token)],
1925 clause_token: Token,
1926 exclude_tokens: &[Token],
1927) -> bool {
1928 if let Some(clause_pos) = find_last_token(tokens, &clause_token) {
1930 for (pos, _, token) in tokens.iter() {
1932 if *pos > clause_pos && exclude_tokens.contains(token) {
1933 return false;
1934 }
1935 }
1936 return true;
1937 }
1938 false
1939}
1940
1941fn analyze_partial(query: &str, cursor_pos: usize) -> (CursorContext, Option<String>) {
1942 let mut lexer = Lexer::new(query);
1944 let tokens = lexer.tokenize_all_with_positions();
1945
1946 let trimmed = query.trim();
1947
1948 #[cfg(test)]
1949 {
1950 if trimmed.contains("\"Last Name\"") {
1951 eprintln!("DEBUG analyze_partial: query='{query}', trimmed='{trimmed}'");
1952 }
1953 }
1954
1955 if let Some(result) = check_after_comparison_operator(query) {
1957 return result;
1958 }
1959
1960 if let Some(dot_pos) = trimmed.rfind('.') {
1963 #[cfg(test)]
1964 {
1965 if trimmed.contains("\"Last Name\"") {
1966 eprintln!("DEBUG: Found dot at position {dot_pos}");
1967 }
1968 }
1969 let before_dot = &trimmed[..dot_pos];
1971 let after_dot = &trimmed[dot_pos + 1..];
1972
1973 if !after_dot.contains('(') {
1976 let col_name = if before_dot.ends_with('"') {
1979 let bytes = before_dot.as_bytes();
1981 let pos = before_dot.len() - 1; #[cfg(test)]
1984 {
1985 if trimmed.contains("\"Last Name\"") {
1986 eprintln!("DEBUG: before_dot='{before_dot}', looking for opening quote");
1987 }
1988 }
1989
1990 let found_start = find_quote_start(bytes, pos);
1991
1992 if let Some(start) = found_start {
1993 let result = safe_slice_from(before_dot, start);
1995 #[cfg(test)]
1996 {
1997 if trimmed.contains("\"Last Name\"") {
1998 eprintln!("DEBUG: Extracted quoted identifier: '{result}'");
1999 }
2000 }
2001 Some(result)
2002 } else {
2003 #[cfg(test)]
2004 {
2005 if trimmed.contains("\"Last Name\"") {
2006 eprintln!("DEBUG: No opening quote found!");
2007 }
2008 }
2009 None
2010 }
2011 } else {
2012 before_dot
2015 .split_whitespace()
2016 .last()
2017 .map(|word| word.trim_start_matches('('))
2018 };
2019
2020 if let Some(col_name) = col_name {
2021 #[cfg(test)]
2022 {
2023 if trimmed.contains("\"Last Name\"") {
2024 eprintln!("DEBUG: col_name = '{col_name}'");
2025 }
2026 }
2027
2028 let is_valid = Parser::is_valid_identifier(col_name);
2030
2031 #[cfg(test)]
2032 {
2033 if trimmed.contains("\"Last Name\"") {
2034 eprintln!("DEBUG: is_valid = {is_valid}");
2035 }
2036 }
2037
2038 if is_valid {
2039 return handle_method_call_context(col_name, after_dot);
2040 }
2041 }
2042 }
2043 }
2044
2045 if let Some((pos, token)) =
2047 find_last_matching_token(&tokens, |t| matches!(t, Token::And | Token::Or))
2048 {
2049 let token_end_pos = if matches!(token, Token::And) {
2051 pos + 3 } else {
2053 pos + 2 };
2055
2056 if cursor_pos > token_end_pos {
2057 let after_op = safe_slice_from(query, token_end_pos + 1); let partial = extract_partial_at_end(after_op);
2060 let op = if matches!(token, Token::And) {
2061 LogicalOp::And
2062 } else {
2063 LogicalOp::Or
2064 };
2065 return (CursorContext::AfterLogicalOp(op), partial);
2066 }
2067 }
2068
2069 if let Some((_, _, last_token)) = tokens.last() {
2071 if matches!(last_token, Token::And | Token::Or) {
2072 let op = if matches!(last_token, Token::And) {
2073 LogicalOp::And
2074 } else {
2075 LogicalOp::Or
2076 };
2077 return (CursorContext::AfterLogicalOp(op), None);
2078 }
2079 }
2080
2081 if let Some(order_pos) = find_last_token(&tokens, &Token::OrderBy) {
2083 let has_by = tokens
2085 .iter()
2086 .any(|(pos, _, t)| *pos > order_pos && matches!(t, Token::By));
2087 if has_by
2088 || tokens
2089 .last()
2090 .map_or(false, |(_, _, t)| matches!(t, Token::OrderBy))
2091 {
2092 return (CursorContext::OrderByClause, extract_partial_at_end(query));
2093 }
2094 }
2095
2096 if is_in_clause(&tokens, Token::Where, &[Token::OrderBy, Token::GroupBy]) {
2098 return (CursorContext::WhereClause, extract_partial_at_end(query));
2099 }
2100
2101 if is_in_clause(
2103 &tokens,
2104 Token::From,
2105 &[Token::Where, Token::OrderBy, Token::GroupBy],
2106 ) {
2107 return (CursorContext::FromClause, extract_partial_at_end(query));
2108 }
2109
2110 if find_last_token(&tokens, &Token::Select).is_some()
2112 && find_last_token(&tokens, &Token::From).is_none()
2113 {
2114 return (CursorContext::SelectClause, extract_partial_at_end(query));
2115 }
2116
2117 (CursorContext::Unknown, None)
2118}
2119
2120fn extract_partial_at_end(query: &str) -> Option<String> {
2121 let trimmed = query.trim();
2122
2123 if let Some(last_word) = trimmed.split_whitespace().last() {
2125 if last_word.starts_with('"') && !last_word.ends_with('"') {
2126 return Some(last_word.to_string());
2128 }
2129 }
2130
2131 let last_word = trimmed.split_whitespace().last()?;
2133
2134 if last_word.chars().all(|c| c.is_alphanumeric() || c == '_') {
2137 if !is_sql_keyword(last_word) {
2139 Some(last_word.to_string())
2140 } else {
2141 None
2142 }
2143 } else {
2144 None
2145 }
2146}
2147
2148impl ParsePrimary for Parser {
2150 fn current_token(&self) -> &Token {
2151 &self.current_token
2152 }
2153
2154 fn advance(&mut self) {
2155 self.advance();
2156 }
2157
2158 fn consume(&mut self, expected: Token) -> Result<(), String> {
2159 self.consume(expected)
2160 }
2161
2162 fn parse_case_expression(&mut self) -> Result<SqlExpression, String> {
2163 self.parse_case_expression()
2164 }
2165
2166 fn parse_function_args(&mut self) -> Result<(Vec<SqlExpression>, bool), String> {
2167 self.parse_function_args()
2168 }
2169
2170 fn parse_window_spec(&mut self) -> Result<WindowSpec, String> {
2171 self.parse_window_spec()
2172 }
2173
2174 fn parse_logical_or(&mut self) -> Result<SqlExpression, String> {
2175 self.parse_logical_or()
2176 }
2177
2178 fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
2179 self.parse_comparison()
2180 }
2181
2182 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
2183 self.parse_expression_list()
2184 }
2185
2186 fn parse_subquery(&mut self) -> Result<SelectStatement, String> {
2187 if matches!(self.current_token, Token::With) {
2189 self.parse_with_clause_inner()
2190 } else {
2191 self.parse_select_statement_inner()
2192 }
2193 }
2194}
2195
2196impl ExpressionParser for Parser {
2198 fn current_token(&self) -> &Token {
2199 &self.current_token
2200 }
2201
2202 fn advance(&mut self) {
2203 match &self.current_token {
2205 Token::LeftParen => self.paren_depth += 1,
2206 Token::RightParen => {
2207 self.paren_depth -= 1;
2208 }
2209 _ => {}
2210 }
2211 self.current_token = self.lexer.next_token();
2212 }
2213
2214 fn peek(&self) -> Option<&Token> {
2215 None }
2222
2223 fn is_at_end(&self) -> bool {
2224 matches!(self.current_token, Token::Eof)
2225 }
2226
2227 fn consume(&mut self, expected: Token) -> Result<(), String> {
2228 if std::mem::discriminant(&self.current_token) == std::mem::discriminant(&expected) {
2230 self.update_paren_depth(&expected)?;
2231 self.current_token = self.lexer.next_token();
2232 Ok(())
2233 } else {
2234 Err(format!(
2235 "Expected {:?}, found {:?}",
2236 expected, self.current_token
2237 ))
2238 }
2239 }
2240
2241 fn parse_identifier(&mut self) -> Result<String, String> {
2242 if let Token::Identifier(id) = &self.current_token {
2243 let id = id.clone();
2244 self.advance();
2245 Ok(id)
2246 } else {
2247 Err(format!(
2248 "Expected identifier, found {:?}",
2249 self.current_token
2250 ))
2251 }
2252 }
2253}
2254
2255impl ParseArithmetic for Parser {
2257 fn current_token(&self) -> &Token {
2258 &self.current_token
2259 }
2260
2261 fn advance(&mut self) {
2262 self.advance();
2263 }
2264
2265 fn consume(&mut self, expected: Token) -> Result<(), String> {
2266 self.consume(expected)
2267 }
2268
2269 fn parse_primary(&mut self) -> Result<SqlExpression, String> {
2270 self.parse_primary()
2271 }
2272
2273 fn parse_multiplicative(&mut self) -> Result<SqlExpression, String> {
2274 self.parse_multiplicative()
2275 }
2276
2277 fn parse_method_args(&mut self) -> Result<Vec<SqlExpression>, String> {
2278 self.parse_method_args()
2279 }
2280}
2281
2282impl ParseComparison for Parser {
2284 fn current_token(&self) -> &Token {
2285 &self.current_token
2286 }
2287
2288 fn advance(&mut self) {
2289 self.advance();
2290 }
2291
2292 fn consume(&mut self, expected: Token) -> Result<(), String> {
2293 self.consume(expected)
2294 }
2295
2296 fn parse_primary(&mut self) -> Result<SqlExpression, String> {
2297 self.parse_primary()
2298 }
2299
2300 fn parse_additive(&mut self) -> Result<SqlExpression, String> {
2301 self.parse_additive()
2302 }
2303
2304 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
2305 self.parse_expression_list()
2306 }
2307
2308 fn parse_subquery(&mut self) -> Result<SelectStatement, String> {
2309 if matches!(self.current_token, Token::With) {
2311 self.parse_with_clause_inner()
2312 } else {
2313 self.parse_select_statement_inner()
2314 }
2315 }
2316}
2317
2318impl ParseLogical for Parser {
2320 fn current_token(&self) -> &Token {
2321 &self.current_token
2322 }
2323
2324 fn advance(&mut self) {
2325 self.advance();
2326 }
2327
2328 fn consume(&mut self, expected: Token) -> Result<(), String> {
2329 self.consume(expected)
2330 }
2331
2332 fn parse_logical_and(&mut self) -> Result<SqlExpression, String> {
2333 self.parse_logical_and()
2334 }
2335
2336 fn parse_base_logical_expression(&mut self) -> Result<SqlExpression, String> {
2337 self.parse_comparison()
2340 }
2341
2342 fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
2343 self.parse_comparison()
2344 }
2345
2346 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
2347 self.parse_expression_list()
2348 }
2349}
2350
2351impl ParseCase for Parser {
2353 fn current_token(&self) -> &Token {
2354 &self.current_token
2355 }
2356
2357 fn advance(&mut self) {
2358 self.advance();
2359 }
2360
2361 fn consume(&mut self, expected: Token) -> Result<(), String> {
2362 self.consume(expected)
2363 }
2364
2365 fn parse_expression(&mut self) -> Result<SqlExpression, String> {
2366 self.parse_expression()
2367 }
2368}
2369
2370fn is_sql_keyword(word: &str) -> bool {
2371 let mut lexer = Lexer::new(word);
2373 let token = lexer.next_token();
2374
2375 !matches!(token, Token::Identifier(_) | Token::Eof)
2377}