sql_cli/sql/
recursive_parser.rs

1// Keep chrono imports for the parser implementation
2
3// Re-exports for backward compatibility - these serve as both imports and re-exports
4pub 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
14// Re-export formatting functions for backward compatibility
15pub use super::parser::formatter::{format_ast_tree, format_sql_pretty, format_sql_pretty_compact};
16
17// New AST-based formatter
18pub use super::parser::ast_formatter::{format_sql_ast, format_sql_ast_with_config, FormatConfig};
19
20// Import the new expression modules
21use 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
38// Import function registry to check for function existence
39use crate::sql::functions::{FunctionCategory, FunctionRegistry};
40use crate::sql::generators::GeneratorRegistry;
41use std::sync::Arc;
42
43// Import Web CTE parser
44use super::parser::web_cte_parser::WebCteParser;
45pub struct Parser {
46    lexer: Lexer,
47    pub current_token: Token,    // Made public for web_cte_parser access
48    in_method_args: bool,        // Track if we're parsing method arguments
49    columns: Vec<String>,        // Known column names for context-aware parsing
50    paren_depth: i32,            // Track parentheses nesting depth
51    paren_depth_stack: Vec<i32>, // Stack to save/restore paren depth for nested contexts
52    _config: ParserConfig,       // Parser configuration including case sensitivity
53    debug_trace: bool,           // Enable detailed token-by-token trace
54    trace_depth: usize,          // Track recursion depth for indented trace
55    function_registry: Arc<FunctionRegistry>, // Function registry for validation
56    generator_registry: Arc<GeneratorRegistry>, // Generator registry for table functions
57}
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        // Alternative peek that returns owned token
151        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    /// Check if current token is one of the reserved keywords that should stop parsing
161    /// Check if an identifier string is a reserved keyword (for backward compatibility)
162    /// This is used when the lexer hasn't properly tokenized keywords and they come through
163    /// as Token::Identifier instead of their proper token types
164    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    /// Get comparison operator string representation (for autocomplete context)
173    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            // Track parentheses depth
179            self.update_paren_depth(&expected)?;
180
181            self.current_token = self.lexer.next_token();
182            Ok(())
183        } else {
184            // Provide better error messages for common cases
185            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        // Track parentheses depth when advancing
209        match &self.current_token {
210            Token::LeftParen => self.paren_depth += 1,
211            Token::RightParen => {
212                self.paren_depth -= 1;
213                // Note: We don't check for < 0 here because advance() is used
214                // in contexts where we're not necessarily expecting a right paren
215            }
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    /// Collect all leading comments before a SQL construct
230    /// This consumes comment tokens and returns them as a Vec<Comment>
231    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    /// Collect a trailing inline comment (on the same line)
250    /// This consumes a single comment token if present
251    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            // Ignore the internal depth - just restore the saved value
275            self.paren_depth = depth;
276        }
277    }
278
279    pub fn parse(&mut self) -> Result<SelectStatement, String> {
280        self.trace_enter("parse");
281
282        // Check for WITH clause at the beginning
283        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        // Parse the main SELECT statement - use inner version since we're already tracking parens
298        let mut main_query = self.parse_select_statement_inner()?;
299        main_query.ctes = ctes;
300
301        // Check for balanced parentheses at the end of parsing
302        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        // Parse the main SELECT statement (without parenthesis checking for subqueries)
312        let mut main_query = self.parse_select_statement_inner()?;
313        main_query.ctes = ctes;
314
315        Ok(main_query)
316    }
317
318    // Helper function to parse CTE list - eliminates duplication
319    fn parse_cte_list(&mut self) -> Result<Vec<CTE>, String> {
320        let mut ctes = Vec::new();
321
322        // Parse CTEs
323        loop {
324            // Check for WEB keyword for each CTE (can be different for each one)
325            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            // Parse CTE name
334            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            // Optional column list: WITH t(col1, col2) AS ...
346            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            // Expect AS
356            self.consume(Token::As)?;
357
358            let cte_type = if is_web {
359                // Expect opening parenthesis for WEB CTE
360                self.consume(Token::LeftParen)?;
361                // Parse WEB CTE specification using dedicated parser
362                let web_spec = WebCteParser::parse(self)?;
363                // Consume closing parenthesis for WEB CTE
364                self.consume(Token::RightParen)?;
365                CTEType::Web(web_spec)
366            } else {
367                // For standard CTEs, push depth BEFORE consuming opening paren
368                // This ensures the paren is counted in the inner context
369                self.push_paren_depth();
370                // Now consume opening parenthesis
371                self.consume(Token::LeftParen)?;
372                let query = self.parse_select_statement_inner()?;
373                // Expect closing parenthesis while still in CTE context
374                self.consume(Token::RightParen)?;
375                // Now pop to restore outer depth after consuming both parens
376                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            // Check for more CTEs
387            if !matches!(self.current_token, Token::Comma) {
388                break;
389            }
390            self.advance();
391        }
392
393        Ok(ctes)
394    }
395
396    /// Helper function to parse an optional table alias (with or without AS keyword)
397    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            // AS is optional for table aliases
410            let alias = name.clone();
411            self.advance();
412            Ok(Some(alias))
413        } else {
414            Ok(None)
415        }
416    }
417
418    /// Helper function to check if an identifier is valid (quoted or regular)
419    fn is_valid_identifier(name: &str) -> bool {
420        if name.starts_with('"') && name.ends_with('"') {
421            // Quoted identifier - always valid
422            true
423        } else {
424            // Regular identifier - check if it's alphanumeric or underscore
425            name.chars().all(|c| c.is_alphanumeric() || c == '_')
426        }
427    }
428
429    /// Helper function to update parentheses depth tracking
430    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                // Check for extra closing parenthesis
436                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    /// Helper function to parse comma-separated argument list
449    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    /// Helper function to check for balanced parentheses at the end of parsing
468    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        // Check for balanced parentheses at the end of parsing
487        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        // Check for DISTINCT keyword
496        let distinct = if matches!(self.current_token, Token::Distinct) {
497            self.advance();
498            true
499        } else {
500            false
501        };
502
503        // Parse SELECT items (supports computed expressions)
504        let select_items = self.parse_select_items()?;
505
506        // Create legacy columns vector for backward compatibility
507        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        // Parse INTO clause (for temporary tables) - comes immediately after SELECT items
519        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        // Parse FROM clause - can be a table name, subquery, or table function
527        let (from_table, from_subquery, from_function, from_alias) =
528            if matches!(self.current_token, Token::From) {
529                self.advance();
530
531                // Check for table function like RANGE()
532                if let Token::Identifier(name) = &self.current_token.clone() {
533                    // Check if this is a table function by consulting the registry
534                    // We need to lookahead to see if there's a parenthesis to distinguish
535                    // between a function call and a table with the same name
536                    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                    // Check if it's a known table function or generator
545                    // In FROM clause context, prioritize generators over scalar functions
546                    let is_table_function = if has_paren {
547                        // First check generator registry (for FROM clause context)
548                        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                            // Then check if it's a table function in the function registry
559                            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                        // Parse table function
595                        let function_name = name.clone();
596                        self.advance(); // Skip function name
597
598                        // Parse arguments
599                        self.consume(Token::LeftParen)?;
600                        let args = self.parse_argument_list()?;
601                        self.consume(Token::RightParen)?;
602
603                        // Optional alias
604                        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                        // Not a RANGE, SPLIT, or generator function, so it's a regular table name
633                        let table_name = name.clone();
634                        self.advance();
635
636                        // Check for optional alias
637                        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                    // Check for subquery: FROM (SELECT ...) or FROM (WITH ... SELECT ...)
643                    self.advance();
644
645                    // Parse the subquery - it might start with WITH
646                    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                    // Subqueries must have an alias
655                    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                        // AS is optional, but alias is required
667                        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                    // Regular table name
684                    match &self.current_token {
685                        Token::Identifier(table) => {
686                            let table_name = table.clone();
687                            self.advance();
688
689                            // Check for optional alias
690                            let alias = self.parse_optional_alias()?;
691
692                            (Some(table_name), None, None, alias)
693                        }
694                        Token::QuotedIdentifier(table) => {
695                            // Handle quoted table names
696                            let table_name = table.clone();
697                            self.advance();
698
699                            // Check for optional alias
700                            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        // Parse JOIN clauses
712        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            // Parse expressions instead of just identifiers for GROUP BY
727            // This allows GROUP BY TIME_BUCKET(...), CASE ..., etc.
728            Some(self.parse_expression_list()?)
729        } else {
730            None
731        };
732
733        // Parse HAVING clause (must come after GROUP BY)
734        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        // Parse ORDER BY clause (comes after GROUP BY and HAVING)
745        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            // This shouldn't happen if the lexer properly tokenizes ORDER BY
751            // But keeping as fallback for compatibility
752            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(); // consume ORDER
755                if matches!(&self.current_token, Token::By) {
756                    self.advance(); // consume BY
757                    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        // Parse LIMIT clause
769        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        // Parse OFFSET clause
786        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        // Parse INTO clause (alternative position - SQL Server also supports INTO after all clauses)
803        // This handles: SELECT * FROM table WHERE x > 5 INTO #temp
804        // If INTO was already parsed after SELECT, this will be None (can't have two INTOs)
805        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 // Keep the one from after SELECT if it exists
810        };
811
812        // Parse UNION/INTERSECT/EXCEPT operations
813        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(), // Will be populated by WITH clause parser
831            into_table,
832            set_operations,
833            leading_comments: vec![],
834            trailing_comment: None,
835        })
836    }
837
838    /// Parse UNION/INTERSECT/EXCEPT operations
839    /// Returns a vector of (operation, select_statement) pairs
840    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            // Determine the operation type
850            let operation = match &self.current_token {
851                Token::Union => {
852                    self.advance();
853                    // Check for ALL keyword
854                    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            // Parse the next SELECT statement
877            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    /// Parse SELECT items that support computed expressions with aliases
886    fn parse_select_items(&mut self) -> Result<Vec<SelectItem>, String> {
887        let mut items = Vec::new();
888
889        loop {
890            // Check for * only at the beginning of a select item
891            // After a comma, * could be either SELECT * or part of multiplication
892            if matches!(self.current_token, Token::Star) {
893                // Determine if this is SELECT * or multiplication
894                // SELECT * is only valid:
895                // 1. As the first item in SELECT
896                // 2. Right after a comma (but not if followed by something that makes it multiplication)
897
898                // For now, treat Star as SELECT * only if we're at the start or just after a comma
899                // and the star is not immediately followed by something that would make it multiplication
900                items.push(SelectItem::Star {
901                    leading_comments: vec![],
902                    trailing_comment: None,
903                });
904                self.advance();
905            } else {
906                // Parse expression or column
907                let expr = self.parse_comparison()?; // Use comparison to support IS NULL and other comparisons
908
909                // Check for AS alias
910                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                    // Generate default alias based on expression
927                    match &expr {
928                        SqlExpression::Column(col_ref) => col_ref.name.clone(),
929                        _ => format!("expr_{}", items.len() + 1), // Default alias for computed expressions
930                    }
931                };
932
933                // Create SelectItem based on expression type
934                let item = match expr {
935                    SqlExpression::Column(col_ref) if alias == col_ref.name => {
936                        // Simple column reference without alias
937                        SelectItem::Column {
938                            column: col_ref,
939                            leading_comments: vec![],
940                            trailing_comment: None,
941                        }
942                    }
943                    _ => {
944                        // Computed expression or column with different alias
945                        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            // Check for comma to continue
958            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                    // Check if this is a reserved keyword that should stop identifier parsing
975                    if Self::is_identifier_reserved(id) {
976                        // Stop parsing identifiers if we hit a reserved keyword
977                        break;
978                    }
979                    identifiers.push(id.clone());
980                    self.advance();
981                }
982                Token::QuotedIdentifier(id) => {
983                    // Handle quoted identifiers like "Customer Id"
984                    identifiers.push(id.clone());
985                    self.advance();
986                }
987                _ => {
988                    // Stop parsing if we hit any other token type
989                    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        // Check for PARTITION BY
1012        if matches!(self.current_token, Token::Partition) {
1013            self.advance(); // consume PARTITION
1014            if !matches!(self.current_token, Token::By) {
1015                return Err("Expected BY after PARTITION".to_string());
1016            }
1017            self.advance(); // consume BY
1018
1019            // Parse partition columns
1020            partition_by = self.parse_identifier_list()?;
1021        }
1022
1023        // Check for ORDER BY
1024        if matches!(self.current_token, Token::OrderBy) {
1025            self.advance(); // consume ORDER BY (as single token)
1026            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                // Handle ORDER BY as two tokens
1030                self.advance(); // consume ORDER
1031                if !matches!(self.current_token, Token::By) {
1032                    return Err("Expected BY after ORDER".to_string());
1033                }
1034                self.advance(); // consume BY
1035                order_by = self.parse_order_by_list()?;
1036            }
1037        }
1038
1039        // Parse optional window frame (ROWS/RANGE BETWEEN ... AND ...)
1040        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                    // Check for qualified column name (table.column)
1059                    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                    // Support numeric column names like "202204"
1082                    let col = num.clone();
1083                    self.advance();
1084                    col
1085                }
1086                // Handle window keywords that can be column names
1087                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            // Check for ASC/DESC
1103            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, // Default to ASC if not specified
1113            };
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    /// Parse INTO clause for temporary tables
1128    /// Syntax: INTO #table_name
1129    fn parse_into_clause(&mut self) -> Result<IntoTable, String> {
1130        // Expect an identifier starting with #
1131        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        // Check for ROWS or RANGE keyword
1155        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                // RANGE as window frame unit
1162                self.advance();
1163                FrameUnit::Range
1164            }
1165            _ => return Ok(None), // No window frame specified
1166        };
1167
1168        // Check for BETWEEN or just a single bound
1169        let (start, end) = if let Token::Between = &self.current_token {
1170            self.advance(); // consume BETWEEN
1171                            // Parse start bound
1172            let start = self.parse_frame_bound()?;
1173
1174            // Expect AND
1175            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            // Parse end bound
1181            let end = self.parse_frame_bound()?;
1182            (start, Some(end))
1183        } else {
1184            // Single bound (e.g., "ROWS 5 PRECEDING")
1185            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        // Parse the entire WHERE clause as a single expression tree
1239        // The logical operators (AND/OR) are now handled within parse_expression
1240        let expr = self.parse_expression()?;
1241
1242        // Check for unexpected closing parenthesis
1243        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        // Create a single condition with the entire expression
1250        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        // Start with logical OR as the lowest precedence operator
1261        // The hierarchy is: OR -> AND -> comparison -> additive -> multiplicative -> primary
1262        let mut left = self.parse_logical_or()?;
1263
1264        // Handle IN operator (not preceded by NOT)
1265        // This uses the modular comparison module
1266        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        // Use the new modular comparison expression parser
1275        parse_comparison_expr(self)
1276    }
1277
1278    fn parse_additive(&mut self) -> Result<SqlExpression, String> {
1279        // Use the new modular arithmetic expression parser
1280        parse_additive_expr(self)
1281    }
1282
1283    fn parse_multiplicative(&mut self) -> Result<SqlExpression, String> {
1284        // Use the new modular arithmetic expression parser
1285        parse_multiplicative_expr(self)
1286    }
1287
1288    fn parse_logical_or(&mut self) -> Result<SqlExpression, String> {
1289        // Use the new modular logical expression parser
1290        parse_logical_or_expr(self)
1291    }
1292
1293    fn parse_logical_and(&mut self) -> Result<SqlExpression, String> {
1294        // Use the new modular logical expression parser
1295        parse_logical_and_expr(self)
1296    }
1297
1298    fn parse_case_expression(&mut self) -> Result<SqlExpression, String> {
1299        // Use the new modular CASE expression parser
1300        parse_case_expr(self)
1301    }
1302
1303    fn parse_primary(&mut self) -> Result<SqlExpression, String> {
1304        // Use the new modular primary expression parser
1305        // Clone the necessary data to avoid borrowing issues
1306        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    // Keep the old implementation temporarily for reference (will be removed)
1316    fn parse_method_args(&mut self) -> Result<Vec<SqlExpression>, String> {
1317        // Set flag to indicate we're parsing method arguments
1318        self.in_method_args = true;
1319
1320        let args = self.parse_argument_list()?;
1321
1322        // Clear the flag
1323        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            // Check if first argument starts with DISTINCT
1334            if matches!(self.current_token, Token::Distinct) {
1335                self.advance(); // consume DISTINCT
1336                has_distinct = true;
1337            }
1338
1339            // Parse the expression (either after DISTINCT or directly)
1340            args.push(self.parse_additive()?);
1341
1342            // Parse any remaining arguments (DISTINCT only applies to first arg for aggregates)
1343            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    // Check if current token is a JOIN-related token
1374    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    // Parse a JOIN clause
1382    fn parse_join_clause(&mut self) -> Result<JoinClause, String> {
1383        // Determine join type
1384        let join_type = match &self.current_token {
1385            Token::Join => {
1386                self.advance();
1387                JoinType::Inner // Default JOIN is INNER JOIN
1388            }
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                // Handle optional OUTER keyword
1400                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                // Handle optional OUTER keyword
1412                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                // Handle optional OUTER keyword
1424                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        // Parse the table being joined
1445        let (table, alias) = self.parse_join_table_source()?;
1446
1447        // Parse ON condition (required for all joins except CROSS JOIN)
1448        let condition = if join_type == JoinType::Cross {
1449            // CROSS JOIN doesn't have ON condition - create empty condition
1450            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                // Subquery as table source
1476                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                // Subqueries must have an alias
1484                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        // Check for optional alias
1516        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        // Parse first condition
1543        conditions.push(self.parse_single_join_condition()?);
1544
1545        // Parse additional conditions connected by AND
1546        while matches!(self.current_token, Token::And) {
1547            self.advance(); // consume AND
1548            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        // Parse left column (can include table prefix)
1556        let left_column = self.parse_column_reference()?;
1557
1558        // Parse operator
1559        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        // Parse right column (can include table prefix)
1571        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                // Check for table.column notation
1587                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// Context detection for cursor position
1607#[derive(Debug, Clone)]
1608pub enum CursorContext {
1609    SelectClause,
1610    FromClause,
1611    WhereClause,
1612    OrderByClause,
1613    AfterColumn(String),
1614    AfterLogicalOp(LogicalOp),
1615    AfterComparisonOp(String, String), // column_name, operator
1616    InMethodCall(String, String),      // object, method
1617    InExpression,
1618    Unknown,
1619}
1620
1621/// Safe UTF-8 string slicing that ensures we don't slice in the middle of a character
1622fn safe_slice_to(s: &str, pos: usize) -> &str {
1623    if pos >= s.len() {
1624        return s;
1625    }
1626
1627    // Find the nearest valid character boundary at or before pos
1628    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
1636/// Safe UTF-8 string slicing from a position to the end
1637fn safe_slice_from(s: &str, pos: usize) -> &str {
1638    if pos >= s.len() {
1639        return "";
1640    }
1641
1642    // Find the nearest valid character boundary at or after pos
1643    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    // Try to parse as much as possible
1657    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        // Partial parse - analyze what we have
1664        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]
1679/// Helper function to find the start of a quoted string searching backwards
1680fn find_quote_start(bytes: &[u8], mut pos: usize) -> Option<usize> {
1681    // Skip the closing quote and search backwards
1682    if pos > 0 {
1683        pos -= 1;
1684        while pos > 0 {
1685            if bytes[pos] == b'"' {
1686                // Check if it's not an escaped quote
1687                if pos == 0 || bytes[pos - 1] != b'\\' {
1688                    return Some(pos);
1689                }
1690            }
1691            pos -= 1;
1692        }
1693        // Check position 0 separately
1694        if bytes[0] == b'"' {
1695            return Some(0);
1696        }
1697    }
1698    None
1699}
1700
1701/// Helper function to handle method call context after validation
1702fn handle_method_call_context(col_name: &str, after_dot: &str) -> (CursorContext, Option<String>) {
1703    // Check if there's a partial method name after the dot
1704    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    // For AfterColumn context, strip quotes if present for consistency
1713    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
1726/// Helper function to check if we're after a comparison operator
1727fn 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            // Check if we have a column name before the operator
1739            if let Some(col_name) = before_op.split_whitespace().last() {
1740                if col_name.chars().all(|c| c.is_alphanumeric() || c == '_') {
1741                    // Check if we're at or near the end of the query
1742                    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    // First check for method call context (e.g., "columnName." or "columnName.Con")
1775    let trimmed = query.trim();
1776
1777    // Check if we're after a comparison operator (e.g., "createdDate > ")
1778    if let Some(result) = check_after_comparison_operator(query) {
1779        return result;
1780    }
1781
1782    // First check if we're after AND/OR - this takes precedence
1783    // Helper function to check if string ends with a logical operator
1784    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        // Don't check for method context if we're clearly after a logical operator
1791    } else {
1792        // Look for the last dot in the query
1793        if let Some(dot_pos) = trimmed.rfind('.') {
1794            // Check if we're after a column name and dot
1795            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            // Check if the part after dot looks like an incomplete method call
1804            // (not a complete method call like "Contains(...)")
1805            if !after_dot.contains('(') {
1806                // Try to extract the column name - could be quoted or regular
1807                let col_name = if before_dot.ends_with('"') {
1808                    // Handle quoted identifier - search backwards for matching opening quote
1809                    let bytes = before_dot.as_bytes();
1810                    let pos = before_dot.len() - 1; // Position of closing quote
1811
1812                    find_quote_start(bytes, pos).map(|start| safe_slice_from(before_dot, start))
1813                } else {
1814                    // Regular identifier - get the last word, handling parentheses
1815                    // Strip all leading parentheses
1816                    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                    // For quoted identifiers, keep the quotes, for regular identifiers check validity
1824                    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    // Check if we're in WHERE clause
1835    if let Some(where_clause) = &stmt.where_clause {
1836        // Check if query ends with AND/OR (with or without trailing space/partial)
1837        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        // Check if we have AND/OR followed by a partial word
1848        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                // We're after AND/OR
1868                return (
1869                    CursorContext::AfterLogicalOp(connector.clone()),
1870                    extract_partial_at_end(query),
1871                );
1872            }
1873        }
1874        // We're in WHERE clause but not after AND/OR
1875        return (CursorContext::WhereClause, extract_partial_at_end(query));
1876    }
1877
1878    // Check if we're after ORDER BY
1879    let query_upper = query.to_uppercase();
1880    if query_upper.ends_with(" ORDER BY") {
1881        return (CursorContext::OrderByClause, None);
1882    }
1883
1884    // Check other contexts based on what's in the statement
1885    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
1900/// Helper function to find the last occurrence of a token type in the token stream
1901fn 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
1908/// Helper function to find the last occurrence of any matching token
1909fn 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
1922/// Helper function to check if we're in a specific clause based on tokens
1923fn is_in_clause(
1924    tokens: &[(usize, usize, Token)],
1925    clause_token: Token,
1926    exclude_tokens: &[Token],
1927) -> bool {
1928    // Find the last occurrence of the clause token
1929    if let Some(clause_pos) = find_last_token(tokens, &clause_token) {
1930        // Check if any exclude tokens appear after it
1931        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    // Tokenize the query up to cursor position
1943    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    // Check if we're after a comparison operator (e.g., "createdDate > ")
1956    if let Some(result) = check_after_comparison_operator(query) {
1957        return result;
1958    }
1959
1960    // Look for the last dot in the query (method call context) - check this FIRST
1961    // before AND/OR detection to properly handle cases like "AND (Country."
1962    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        // Check if we're after a column name and dot
1970        let before_dot = &trimmed[..dot_pos];
1971        let after_dot = &trimmed[dot_pos + 1..];
1972
1973        // Check if the part after dot looks like an incomplete method call
1974        // (not a complete method call like "Contains(...)")
1975        if !after_dot.contains('(') {
1976            // Try to extract the column name before the dot
1977            // It could be a quoted identifier like "Last Name" or a regular identifier
1978            let col_name = if before_dot.ends_with('"') {
1979                // Handle quoted identifier - search backwards for matching opening quote
1980                let bytes = before_dot.as_bytes();
1981                let pos = before_dot.len() - 1; // Position of closing quote
1982
1983                #[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                    // Extract the full quoted identifier including quotes
1994                    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                // Regular identifier - get the last word, handling parentheses
2013                // Strip all leading parentheses
2014                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                // For quoted identifiers, keep the quotes, for regular identifiers check validity
2029                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    // Check if we're after AND/OR using tokens - but only after checking for method calls
2046    if let Some((pos, token)) =
2047        find_last_matching_token(&tokens, |t| matches!(t, Token::And | Token::Or))
2048    {
2049        // Check if cursor is after the logical operator
2050        let token_end_pos = if matches!(token, Token::And) {
2051            pos + 3 // "AND" is 3 characters
2052        } else {
2053            pos + 2 // "OR" is 2 characters
2054        };
2055
2056        if cursor_pos > token_end_pos {
2057            // Extract any partial word after the operator
2058            let after_op = safe_slice_from(query, token_end_pos + 1); // +1 for the space
2059            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    // Check if the last token is AND or OR (handles case where it's at the very end)
2070    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    // Check if we're in ORDER BY clause using tokens
2082    if let Some(order_pos) = find_last_token(&tokens, &Token::OrderBy) {
2083        // Check if there's a BY token after ORDER
2084        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    // Check if we're in WHERE clause using tokens
2097    if is_in_clause(&tokens, Token::Where, &[Token::OrderBy, Token::GroupBy]) {
2098        return (CursorContext::WhereClause, extract_partial_at_end(query));
2099    }
2100
2101    // Check if we're in FROM clause using tokens
2102    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    // Check if we're in SELECT clause using tokens
2111    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    // First check if the last word itself starts with a quote (unclosed quoted identifier being typed)
2124    if let Some(last_word) = trimmed.split_whitespace().last() {
2125        if last_word.starts_with('"') && !last_word.ends_with('"') {
2126            // This is an unclosed quoted identifier like "Cust
2127            return Some(last_word.to_string());
2128        }
2129    }
2130
2131    // Regular identifier extraction
2132    let last_word = trimmed.split_whitespace().last()?;
2133
2134    // Check if it's a partial identifier (not a keyword or operator)
2135    // First check if it's alphanumeric (potential identifier)
2136    if last_word.chars().all(|c| c.is_alphanumeric() || c == '_') {
2137        // Use lexer to determine if it's a keyword or identifier
2138        if !is_sql_keyword(last_word) {
2139            Some(last_word.to_string())
2140        } else {
2141            None
2142        }
2143    } else {
2144        None
2145    }
2146}
2147
2148// Implement the ParsePrimary trait for Parser to use the modular expression parsing
2149impl 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        // Parse subquery without parenthesis balance validation
2188        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
2196// Implement the ExpressionParser trait for Parser to use the modular expression parsing
2197impl ExpressionParser for Parser {
2198    fn current_token(&self) -> &Token {
2199        &self.current_token
2200    }
2201
2202    fn advance(&mut self) {
2203        // Call the main advance method directly to avoid recursion
2204        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        // We can't return a reference to a token from a temporary lexer,
2216        // so we need a different approach. For now, let's use a workaround
2217        // that checks the next token type without consuming it.
2218        // This is a limitation of the current design.
2219        // A proper fix would be to store the peeked token in the Parser struct.
2220        None // TODO: Implement proper lookahead
2221    }
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        // Call the main consume method to avoid recursion
2229        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
2255// Implement the ParseArithmetic trait for Parser to use the modular arithmetic parsing
2256impl 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
2282// Implement the ParseComparison trait for Parser to use the modular comparison parsing
2283impl 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        // Parse subquery without parenthesis balance validation
2310        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
2318// Implement the ParseLogical trait for Parser to use the modular logical parsing
2319impl 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        // This is the base for logical AND - it should parse comparison expressions
2338        // to avoid infinite recursion with parse_expression
2339        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
2351// Implement the ParseCase trait for Parser to use the modular CASE parsing
2352impl 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    // Use the lexer to check if this word produces a keyword token
2372    let mut lexer = Lexer::new(word);
2373    let token = lexer.next_token();
2374
2375    // Check if it's a keyword token (not an identifier)
2376    !matches!(token, Token::Identifier(_) | Token::Eof)
2377}