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, Condition, DataFormat, FrameBound, FrameUnit, JoinClause, JoinCondition, JoinOperator,
6    JoinType, LogicalOp, OrderByColumn, SelectItem, SelectStatement, SortDirection, SqlExpression,
7    TableFunction, TableSource, WebCTESpec, WhenBranch, WhereClause, WindowFrame, WindowSpec, CTE,
8};
9pub use super::parser::legacy::{ParseContext, ParseState, Schema, SqlParser, SqlToken, TableInfo};
10pub use super::parser::lexer::{Lexer, Token};
11pub use super::parser::ParserConfig;
12
13// Re-export formatting functions for backward compatibility
14pub use super::parser::formatter::{format_ast_tree, format_sql_pretty, format_sql_pretty_compact};
15
16// New AST-based formatter
17pub use super::parser::ast_formatter::{format_sql_ast, format_sql_ast_with_config, FormatConfig};
18
19// Import the new expression modules
20use super::parser::expressions::arithmetic::{
21    parse_additive as parse_additive_expr, parse_multiplicative as parse_multiplicative_expr,
22    ParseArithmetic,
23};
24use super::parser::expressions::case::{parse_case_expression as parse_case_expr, ParseCase};
25use super::parser::expressions::comparison::{
26    parse_comparison as parse_comparison_expr, parse_in_operator, ParseComparison,
27};
28use super::parser::expressions::logical::{
29    parse_logical_and as parse_logical_and_expr, parse_logical_or as parse_logical_or_expr,
30    ParseLogical,
31};
32use super::parser::expressions::primary::{
33    parse_primary as parse_primary_expr, ParsePrimary, PrimaryExpressionContext,
34};
35use super::parser::expressions::ExpressionParser;
36pub struct Parser {
37    lexer: Lexer,
38    current_token: Token,
39    in_method_args: bool, // Track if we're parsing method arguments
40    columns: Vec<String>, // Known column names for context-aware parsing
41    paren_depth: i32,     // Track parentheses nesting depth
42    #[allow(dead_code)]
43    config: ParserConfig, // Parser configuration including case sensitivity
44}
45
46impl Parser {
47    #[must_use]
48    pub fn new(input: &str) -> Self {
49        let mut lexer = Lexer::new(input);
50        let current_token = lexer.next_token();
51        Self {
52            lexer,
53            current_token,
54            in_method_args: false,
55            columns: Vec::new(),
56            paren_depth: 0,
57            config: ParserConfig::default(),
58        }
59    }
60
61    #[must_use]
62    pub fn with_config(input: &str, config: ParserConfig) -> Self {
63        let mut lexer = Lexer::new(input);
64        let current_token = lexer.next_token();
65        Self {
66            lexer,
67            current_token,
68            in_method_args: false,
69            columns: Vec::new(),
70            paren_depth: 0,
71            config,
72        }
73    }
74
75    #[must_use]
76    pub fn with_columns(mut self, columns: Vec<String>) -> Self {
77        self.columns = columns;
78        self
79    }
80
81    #[allow(dead_code)]
82    fn peek_token(&self) -> Option<Token> {
83        // Alternative peek that returns owned token
84        let mut temp_lexer = self.lexer.clone();
85        let next_token = temp_lexer.next_token();
86        if matches!(next_token, Token::Eof) {
87            None
88        } else {
89            Some(next_token)
90        }
91    }
92
93    fn consume(&mut self, expected: Token) -> Result<(), String> {
94        if std::mem::discriminant(&self.current_token) == std::mem::discriminant(&expected) {
95            // Track parentheses depth
96            match &expected {
97                Token::LeftParen => self.paren_depth += 1,
98                Token::RightParen => {
99                    self.paren_depth -= 1;
100                    // Check for extra closing parenthesis
101                    if self.paren_depth < 0 {
102                        return Err(
103                            "Unexpected closing parenthesis - no matching opening parenthesis"
104                                .to_string(),
105                        );
106                    }
107                }
108                _ => {}
109            }
110
111            self.current_token = self.lexer.next_token();
112            Ok(())
113        } else {
114            // Provide better error messages for common cases
115            let error_msg = match (&expected, &self.current_token) {
116                (Token::RightParen, Token::Eof) if self.paren_depth > 0 => {
117                    format!(
118                        "Unclosed parenthesis - missing {} closing parenthes{}",
119                        self.paren_depth,
120                        if self.paren_depth == 1 { "is" } else { "es" }
121                    )
122                }
123                (Token::RightParen, _) if self.paren_depth > 0 => {
124                    format!(
125                        "Expected closing parenthesis but found {:?} (currently {} unclosed parenthes{})",
126                        self.current_token,
127                        self.paren_depth,
128                        if self.paren_depth == 1 { "is" } else { "es" }
129                    )
130                }
131                _ => format!("Expected {:?}, found {:?}", expected, self.current_token),
132            };
133            Err(error_msg)
134        }
135    }
136
137    fn advance(&mut self) {
138        // Track parentheses depth when advancing
139        match &self.current_token {
140            Token::LeftParen => self.paren_depth += 1,
141            Token::RightParen => {
142                self.paren_depth -= 1;
143                // Note: We don't check for < 0 here because advance() is used
144                // in contexts where we're not necessarily expecting a right paren
145            }
146            _ => {}
147        }
148        self.current_token = self.lexer.next_token();
149    }
150
151    pub fn parse(&mut self) -> Result<SelectStatement, String> {
152        // Check for WITH clause at the beginning
153        if matches!(self.current_token, Token::With) {
154            self.parse_with_clause()
155        } else {
156            self.parse_select_statement()
157        }
158    }
159
160    fn parse_with_clause(&mut self) -> Result<SelectStatement, String> {
161        self.consume(Token::With)?;
162
163        let mut ctes = Vec::new();
164
165        // Parse CTEs
166        loop {
167            // Check for WEB keyword for each CTE (can be different for each one)
168            let is_web = if let Token::Identifier(id) = &self.current_token {
169                if id.to_uppercase() == "WEB" {
170                    self.advance();
171                    true
172                } else {
173                    false
174                }
175            } else {
176                false
177            };
178
179            // Parse CTE name
180            let name = match &self.current_token {
181                Token::Identifier(name) => name.clone(),
182                _ => {
183                    return Err(format!(
184                        "Expected CTE name after {}",
185                        if is_web { "WEB" } else { "WITH or comma" }
186                    ))
187                }
188            };
189            self.advance();
190
191            // Optional column list: WITH t(col1, col2) AS ...
192            let column_list = if matches!(self.current_token, Token::LeftParen) {
193                self.advance();
194                let cols = self.parse_identifier_list()?;
195                self.consume(Token::RightParen)?;
196                Some(cols)
197            } else {
198                None
199            };
200
201            // Expect AS
202            self.consume(Token::As)?;
203
204            // Expect opening parenthesis
205            self.consume(Token::LeftParen)?;
206
207            let cte_type = if is_web {
208                // Parse WEB CTE specification
209                let web_spec = self.parse_web_cte_spec()?;
210                CTEType::Web(web_spec)
211            } else {
212                // Parse the CTE query (inner version that doesn't check parentheses)
213                let query = self.parse_select_statement_inner()?;
214                CTEType::Standard(query)
215            };
216
217            // Expect closing parenthesis
218            self.consume(Token::RightParen)?;
219
220            ctes.push(CTE {
221                name,
222                column_list,
223                cte_type,
224            });
225
226            // Check for more CTEs
227            if !matches!(self.current_token, Token::Comma) {
228                break;
229            }
230            self.advance();
231        }
232
233        // Parse the main SELECT statement (with parenthesis checking)
234        let mut main_query = self.parse_select_statement()?;
235        main_query.ctes = ctes;
236
237        Ok(main_query)
238    }
239
240    fn parse_web_cte_spec(&mut self) -> Result<WebCTESpec, String> {
241        // Expect URL keyword
242        if let Token::Identifier(id) = &self.current_token {
243            if id.to_uppercase() != "URL" {
244                return Err("Expected URL keyword in WEB CTE".to_string());
245            }
246        } else {
247            return Err("Expected URL keyword in WEB CTE".to_string());
248        }
249        self.advance();
250
251        // Parse URL string
252        let url = match &self.current_token {
253            Token::StringLiteral(url) => url.clone(),
254            _ => return Err("Expected URL string after URL keyword".to_string()),
255        };
256        self.advance();
257
258        // Parse optional clauses
259        let mut format = None;
260        let mut headers = Vec::new();
261        let mut cache_seconds = None;
262
263        // Parse optional clauses until we hit the closing parenthesis
264        while !matches!(self.current_token, Token::RightParen)
265            && !matches!(self.current_token, Token::Eof)
266        {
267            if let Token::Identifier(id) = &self.current_token {
268                match id.to_uppercase().as_str() {
269                    "FORMAT" => {
270                        self.advance();
271                        format = Some(self.parse_data_format()?);
272                    }
273                    "CACHE" => {
274                        self.advance();
275                        cache_seconds = Some(self.parse_cache_duration()?);
276                    }
277                    "HEADERS" => {
278                        self.advance();
279                        headers = self.parse_headers()?;
280                    }
281                    _ => {
282                        return Err(format!(
283                            "Unexpected keyword '{}' in WEB CTE specification",
284                            id
285                        ));
286                    }
287                }
288            } else {
289                break;
290            }
291        }
292
293        Ok(WebCTESpec {
294            url,
295            format,
296            headers,
297            cache_seconds,
298        })
299    }
300
301    fn parse_data_format(&mut self) -> Result<DataFormat, String> {
302        if let Token::Identifier(id) = &self.current_token {
303            let format = match id.to_uppercase().as_str() {
304                "CSV" => DataFormat::CSV,
305                "JSON" => DataFormat::JSON,
306                "AUTO" => DataFormat::Auto,
307                _ => return Err(format!("Unknown data format: {}", id)),
308            };
309            self.advance();
310            Ok(format)
311        } else {
312            Err("Expected data format (CSV, JSON, or AUTO)".to_string())
313        }
314    }
315
316    fn parse_cache_duration(&mut self) -> Result<u64, String> {
317        match &self.current_token {
318            Token::NumberLiteral(n) => {
319                let duration = n
320                    .parse::<u64>()
321                    .map_err(|_| format!("Invalid cache duration: {}", n))?;
322                self.advance();
323                Ok(duration)
324            }
325            _ => Err("Expected number for cache duration".to_string()),
326        }
327    }
328
329    fn parse_headers(&mut self) -> Result<Vec<(String, String)>, String> {
330        self.consume(Token::LeftParen)?;
331
332        let mut headers = Vec::new();
333
334        loop {
335            // Parse header name
336            let key = match &self.current_token {
337                Token::Identifier(id) => id.clone(),
338                Token::StringLiteral(s) => s.clone(),
339                _ => return Err("Expected header name".to_string()),
340            };
341            self.advance();
342
343            // Expect : (colon) for header key-value separator
344            if !matches!(self.current_token, Token::Colon) {
345                // For backwards compatibility, also accept =
346                if matches!(self.current_token, Token::Equal) {
347                    self.advance();
348                } else {
349                    return Err("Expected ':' or '=' after header name".to_string());
350                }
351            } else {
352                self.advance(); // consume the colon
353            }
354
355            // Parse header value
356            let value = match &self.current_token {
357                Token::StringLiteral(s) => s.clone(),
358                _ => return Err("Expected header value as string".to_string()),
359            };
360            self.advance();
361
362            headers.push((key, value));
363
364            // Check for more headers
365            if !matches!(self.current_token, Token::Comma) {
366                break;
367            }
368            self.advance();
369        }
370
371        self.consume(Token::RightParen)?;
372        Ok(headers)
373    }
374
375    fn parse_with_clause_inner(&mut self) -> Result<SelectStatement, String> {
376        self.consume(Token::With)?;
377
378        let mut ctes = Vec::new();
379
380        // Parse CTEs
381        loop {
382            // Check for WEB keyword for each CTE (can be different for each one)
383            let is_web = if let Token::Identifier(id) = &self.current_token {
384                if id.to_uppercase() == "WEB" {
385                    self.advance();
386                    true
387                } else {
388                    false
389                }
390            } else {
391                false
392            };
393
394            // Parse CTE name
395            let name = match &self.current_token {
396                Token::Identifier(name) => name.clone(),
397                _ => return Err("Expected CTE name after WITH or comma".to_string()),
398            };
399            self.advance();
400
401            // Optional column list: WITH t(col1, col2) AS ...
402            let column_list = if matches!(self.current_token, Token::LeftParen) {
403                self.advance();
404                let cols = self.parse_identifier_list()?;
405                self.consume(Token::RightParen)?;
406                Some(cols)
407            } else {
408                None
409            };
410
411            // Expect AS
412            self.consume(Token::As)?;
413
414            // Expect opening parenthesis
415            self.consume(Token::LeftParen)?;
416
417            let cte_type = if is_web {
418                // Parse WEB CTE specification
419                let web_spec = self.parse_web_cte_spec()?;
420                CTEType::Web(web_spec)
421            } else {
422                // Parse the CTE query (inner version that doesn't check parentheses)
423                let query = self.parse_select_statement_inner()?;
424                CTEType::Standard(query)
425            };
426
427            // Expect closing parenthesis
428            self.consume(Token::RightParen)?;
429
430            ctes.push(CTE {
431                name,
432                column_list,
433                cte_type,
434            });
435
436            // Check for more CTEs
437            if !matches!(self.current_token, Token::Comma) {
438                break;
439            }
440            self.advance();
441        }
442
443        // Parse the main SELECT statement (without parenthesis checking for subqueries)
444        let mut main_query = self.parse_select_statement_inner()?;
445        main_query.ctes = ctes;
446
447        Ok(main_query)
448    }
449
450    fn parse_select_statement(&mut self) -> Result<SelectStatement, String> {
451        let result = self.parse_select_statement_inner()?;
452
453        // Check for balanced parentheses at the end of parsing
454        if self.paren_depth > 0 {
455            return Err(format!(
456                "Unclosed parenthesis - missing {} closing parenthes{}",
457                self.paren_depth,
458                if self.paren_depth == 1 { "is" } else { "es" }
459            ));
460        } else if self.paren_depth < 0 {
461            return Err(
462                "Extra closing parenthesis found - no matching opening parenthesis".to_string(),
463            );
464        }
465
466        Ok(result)
467    }
468
469    fn parse_select_statement_inner(&mut self) -> Result<SelectStatement, String> {
470        self.consume(Token::Select)?;
471
472        // Check for DISTINCT keyword
473        let distinct = if matches!(self.current_token, Token::Distinct) {
474            self.advance();
475            true
476        } else {
477            false
478        };
479
480        // Parse SELECT items (supports computed expressions)
481        let select_items = self.parse_select_items()?;
482
483        // Create legacy columns vector for backward compatibility
484        let columns = select_items
485            .iter()
486            .map(|item| match item {
487                SelectItem::Star => "*".to_string(),
488                SelectItem::Column(col_ref) => col_ref.name.clone(),
489                SelectItem::Expression { alias, .. } => alias.clone(),
490            })
491            .collect();
492
493        // Parse FROM clause - can be a table name, subquery, or table function
494        let (from_table, from_subquery, from_function, from_alias) =
495            if matches!(self.current_token, Token::From) {
496                self.advance();
497
498                // Check for table function like RANGE()
499                if let Token::Identifier(name) = &self.current_token.clone() {
500                    if name.to_uppercase() == "RANGE" {
501                        self.advance();
502                        // Parse RANGE function
503                        self.consume(Token::LeftParen)?;
504
505                        // Parse start expression
506                        let start = self.parse_expression()?;
507                        self.consume(Token::Comma)?;
508
509                        // Parse end expression
510                        let end = self.parse_expression()?;
511
512                        // Parse optional step
513                        let step = if matches!(self.current_token, Token::Comma) {
514                            self.advance();
515                            Some(self.parse_expression()?)
516                        } else {
517                            None
518                        };
519
520                        self.consume(Token::RightParen)?;
521
522                        // Optional alias
523                        let alias = if matches!(self.current_token, Token::As) {
524                            self.advance();
525                            match &self.current_token {
526                                Token::Identifier(name) => {
527                                    let alias = name.clone();
528                                    self.advance();
529                                    Some(alias)
530                                }
531                                _ => return Err("Expected alias name after AS".to_string()),
532                            }
533                        } else if let Token::Identifier(name) = &self.current_token {
534                            let alias = name.clone();
535                            self.advance();
536                            Some(alias)
537                        } else {
538                            None
539                        };
540
541                        (
542                            None,
543                            None,
544                            Some(TableFunction::Range { start, end, step }),
545                            alias,
546                        )
547                    } else if name.to_uppercase() == "SPLIT" {
548                        // Parse SPLIT(text[, delimiter])
549                        self.advance(); // Skip "SPLIT"
550                        self.consume(Token::LeftParen)?;
551
552                        let text = self.parse_expression()?;
553
554                        let delimiter = if matches!(self.current_token, Token::Comma) {
555                            self.advance();
556                            Some(self.parse_expression()?)
557                        } else {
558                            None
559                        };
560
561                        self.consume(Token::RightParen)?;
562
563                        // Optional alias
564                        let alias = if matches!(self.current_token, Token::As) {
565                            self.advance();
566                            match &self.current_token {
567                                Token::Identifier(name) => {
568                                    let alias = name.clone();
569                                    self.advance();
570                                    Some(alias)
571                                }
572                                _ => return Err("Expected alias name after AS".to_string()),
573                            }
574                        } else if let Token::Identifier(name) = &self.current_token {
575                            let alias = name.clone();
576                            self.advance();
577                            Some(alias)
578                        } else {
579                            None
580                        };
581
582                        (
583                            None,
584                            None,
585                            Some(TableFunction::Split { text, delimiter }),
586                            alias,
587                        )
588                    } else if name.to_uppercase().starts_with("GENERATE_")
589                        || name.to_uppercase().starts_with("RANDOM_")
590                        || name.to_uppercase() == "FIBONACCI"
591                        || name.to_uppercase() == "PRIME_FACTORS"
592                        || name.to_uppercase() == "COLLATZ"
593                        || name.to_uppercase() == "PASCAL_TRIANGLE"
594                        || name.to_uppercase() == "TRIANGULAR"
595                        || name.to_uppercase() == "SQUARES"
596                        || name.to_uppercase() == "FACTORIALS"
597                    {
598                        // Parse generator function
599                        let generator_name = name.clone();
600                        self.advance(); // Skip generator name
601
602                        // Parse arguments
603                        self.consume(Token::LeftParen)?;
604                        let mut args = Vec::new();
605
606                        if !matches!(self.current_token, Token::RightParen) {
607                            loop {
608                                args.push(self.parse_expression()?);
609
610                                if matches!(self.current_token, Token::Comma) {
611                                    self.advance();
612                                } else {
613                                    break;
614                                }
615                            }
616                        }
617
618                        self.consume(Token::RightParen)?;
619
620                        // Optional alias
621                        let alias = if matches!(self.current_token, Token::As) {
622                            self.advance();
623                            match &self.current_token {
624                                Token::Identifier(name) => {
625                                    let alias = name.clone();
626                                    self.advance();
627                                    Some(alias)
628                                }
629                                _ => return Err("Expected alias name after AS".to_string()),
630                            }
631                        } else if let Token::Identifier(name) = &self.current_token {
632                            let alias = name.clone();
633                            self.advance();
634                            Some(alias)
635                        } else {
636                            None
637                        };
638
639                        (
640                            None,
641                            None,
642                            Some(TableFunction::Generator {
643                                name: generator_name,
644                                args,
645                            }),
646                            alias,
647                        )
648                    } else {
649                        // Not a RANGE, SPLIT, or generator function, so it's a regular table name
650                        let table_name = name.clone();
651                        self.advance();
652
653                        // Check for optional alias
654                        let alias = if matches!(self.current_token, Token::As) {
655                            self.advance();
656                            match &self.current_token {
657                                Token::Identifier(name) => {
658                                    let alias = name.clone();
659                                    self.advance();
660                                    Some(alias)
661                                }
662                                _ => return Err("Expected alias name after AS".to_string()),
663                            }
664                        } else if let Token::Identifier(name) = &self.current_token {
665                            // AS is optional for table aliases
666                            let alias = name.clone();
667                            self.advance();
668                            Some(alias)
669                        } else {
670                            None
671                        };
672
673                        (Some(table_name), None, None, alias)
674                    }
675                } else if matches!(self.current_token, Token::LeftParen) {
676                    // Check for subquery: FROM (SELECT ...) or FROM (WITH ... SELECT ...)
677                    self.advance();
678
679                    // Parse the subquery - it might start with WITH
680                    let subquery = if matches!(self.current_token, Token::With) {
681                        self.parse_with_clause_inner()?
682                    } else {
683                        self.parse_select_statement_inner()?
684                    };
685
686                    self.consume(Token::RightParen)?;
687
688                    // Subqueries must have an alias
689                    let alias = if matches!(self.current_token, Token::As) {
690                        self.advance();
691                        match &self.current_token {
692                            Token::Identifier(name) => {
693                                let alias = name.clone();
694                                self.advance();
695                                alias
696                            }
697                            _ => return Err("Expected alias name after AS".to_string()),
698                        }
699                    } else {
700                        // AS is optional, but alias is required
701                        match &self.current_token {
702                            Token::Identifier(name) => {
703                                let alias = name.clone();
704                                self.advance();
705                                alias
706                            }
707                            _ => {
708                                return Err(
709                                    "Subquery in FROM must have an alias (e.g., AS t)".to_string()
710                                )
711                            }
712                        }
713                    };
714
715                    (None, Some(Box::new(subquery)), None, Some(alias))
716                } else {
717                    // Regular table name
718                    match &self.current_token {
719                        Token::Identifier(table) => {
720                            let table_name = table.clone();
721                            self.advance();
722
723                            // Check for optional alias
724                            let alias = if matches!(self.current_token, Token::As) {
725                                self.advance();
726                                match &self.current_token {
727                                    Token::Identifier(name) => {
728                                        let alias = name.clone();
729                                        self.advance();
730                                        Some(alias)
731                                    }
732                                    _ => return Err("Expected alias name after AS".to_string()),
733                                }
734                            } else if let Token::Identifier(name) = &self.current_token {
735                                // AS is optional for table aliases
736                                let alias = name.clone();
737                                self.advance();
738                                Some(alias)
739                            } else {
740                                None
741                            };
742
743                            (Some(table_name), None, None, alias)
744                        }
745                        Token::QuotedIdentifier(table) => {
746                            // Handle quoted table names
747                            let table_name = table.clone();
748                            self.advance();
749
750                            // Check for optional alias
751                            let alias = if matches!(self.current_token, Token::As) {
752                                self.advance();
753                                match &self.current_token {
754                                    Token::Identifier(name) => {
755                                        let alias = name.clone();
756                                        self.advance();
757                                        Some(alias)
758                                    }
759                                    _ => return Err("Expected alias name after AS".to_string()),
760                                }
761                            } else if let Token::Identifier(name) = &self.current_token {
762                                // AS is optional for table aliases
763                                let alias = name.clone();
764                                self.advance();
765                                Some(alias)
766                            } else {
767                                None
768                            };
769
770                            (Some(table_name), None, None, alias)
771                        }
772                        _ => return Err("Expected table name or subquery after FROM".to_string()),
773                    }
774                }
775            } else {
776                (None, None, None, None)
777            };
778
779        // Parse JOIN clauses
780        let mut joins = Vec::new();
781        while self.is_join_token() {
782            joins.push(self.parse_join_clause()?);
783        }
784
785        let where_clause = if matches!(self.current_token, Token::Where) {
786            self.advance();
787            Some(self.parse_where_clause()?)
788        } else {
789            None
790        };
791
792        let group_by = if matches!(self.current_token, Token::GroupBy) {
793            self.advance();
794            // Parse expressions instead of just identifiers for GROUP BY
795            // This allows GROUP BY TIME_BUCKET(...), CASE ..., etc.
796            Some(self.parse_expression_list()?)
797        } else {
798            None
799        };
800
801        // Parse HAVING clause (must come after GROUP BY)
802        let having = if matches!(self.current_token, Token::Having) {
803            if group_by.is_none() {
804                return Err("HAVING clause requires GROUP BY".to_string());
805            }
806            self.advance();
807            Some(self.parse_expression()?)
808        } else {
809            None
810        };
811
812        // Parse ORDER BY clause (comes after GROUP BY and HAVING)
813        let order_by = if matches!(self.current_token, Token::OrderBy) {
814            self.advance();
815            Some(self.parse_order_by_list()?)
816        } else if let Token::Identifier(s) = &self.current_token {
817            if s.to_uppercase() == "ORDER" {
818                // Handle ORDER BY as two separate tokens
819                self.advance(); // consume ORDER
820                if matches!(&self.current_token, Token::Identifier(by_token) if by_token.to_uppercase() == "BY")
821                {
822                    self.advance(); // consume BY
823                    Some(self.parse_order_by_list()?)
824                } else {
825                    return Err("Expected BY after ORDER".to_string());
826                }
827            } else {
828                None
829            }
830        } else {
831            None
832        };
833
834        // Parse LIMIT clause
835        let limit = if matches!(self.current_token, Token::Limit) {
836            self.advance();
837            match &self.current_token {
838                Token::NumberLiteral(num) => {
839                    let limit_val = num
840                        .parse::<usize>()
841                        .map_err(|_| format!("Invalid LIMIT value: {num}"))?;
842                    self.advance();
843                    Some(limit_val)
844                }
845                _ => return Err("Expected number after LIMIT".to_string()),
846            }
847        } else {
848            None
849        };
850
851        // Parse OFFSET clause
852        let offset = if matches!(self.current_token, Token::Offset) {
853            self.advance();
854            match &self.current_token {
855                Token::NumberLiteral(num) => {
856                    let offset_val = num
857                        .parse::<usize>()
858                        .map_err(|_| format!("Invalid OFFSET value: {num}"))?;
859                    self.advance();
860                    Some(offset_val)
861                }
862                _ => return Err("Expected number after OFFSET".to_string()),
863            }
864        } else {
865            None
866        };
867
868        Ok(SelectStatement {
869            distinct,
870            columns,
871            select_items,
872            from_table,
873            from_subquery,
874            from_function,
875            from_alias,
876            joins,
877            where_clause,
878            order_by,
879            group_by,
880            having,
881            limit,
882            offset,
883            ctes: Vec::new(), // Will be populated by WITH clause parser
884        })
885    }
886
887    fn parse_select_list(&mut self) -> Result<Vec<String>, String> {
888        let mut columns = Vec::new();
889
890        if matches!(self.current_token, Token::Star) {
891            columns.push("*".to_string());
892            self.advance();
893        } else {
894            loop {
895                match &self.current_token {
896                    Token::Identifier(col) => {
897                        columns.push(col.clone());
898                        self.advance();
899                    }
900                    Token::QuotedIdentifier(col) => {
901                        // Handle quoted column names like "Customer Id"
902                        columns.push(col.clone());
903                        self.advance();
904                    }
905                    _ => return Err("Expected column name".to_string()),
906                }
907
908                if matches!(self.current_token, Token::Comma) {
909                    self.advance();
910                } else {
911                    break;
912                }
913            }
914        }
915
916        Ok(columns)
917    }
918
919    /// Parse SELECT items that support computed expressions with aliases
920    fn parse_select_items(&mut self) -> Result<Vec<SelectItem>, String> {
921        let mut items = Vec::new();
922
923        loop {
924            // Check for * only at the beginning of a select item
925            // After a comma, * could be either SELECT * or part of multiplication
926            if matches!(self.current_token, Token::Star) {
927                // Determine if this is SELECT * or multiplication
928                // SELECT * is only valid:
929                // 1. As the first item in SELECT
930                // 2. Right after a comma (but not if followed by something that makes it multiplication)
931
932                // For now, treat Star as SELECT * only if we're at the start or just after a comma
933                // and the star is not immediately followed by something that would make it multiplication
934                items.push(SelectItem::Star);
935                self.advance();
936            } else {
937                // Parse expression or column
938                let expr = self.parse_comparison()?; // Use comparison to support IS NULL and other comparisons
939
940                // Check for AS alias
941                let alias = if matches!(self.current_token, Token::As) {
942                    self.advance();
943                    match &self.current_token {
944                        Token::Identifier(alias_name) => {
945                            let alias = alias_name.clone();
946                            self.advance();
947                            alias
948                        }
949                        Token::QuotedIdentifier(alias_name) => {
950                            let alias = alias_name.clone();
951                            self.advance();
952                            alias
953                        }
954                        _ => return Err("Expected alias name after AS".to_string()),
955                    }
956                } else {
957                    // Generate default alias based on expression
958                    match &expr {
959                        SqlExpression::Column(col_ref) => col_ref.name.clone(),
960                        _ => format!("expr_{}", items.len() + 1), // Default alias for computed expressions
961                    }
962                };
963
964                // Create SelectItem based on expression type
965                let item = match expr {
966                    SqlExpression::Column(col_ref) if alias == col_ref.name => {
967                        // Simple column reference without alias
968                        SelectItem::Column(col_ref)
969                    }
970                    _ => {
971                        // Computed expression or column with different alias
972                        SelectItem::Expression { expr, alias }
973                    }
974                };
975
976                items.push(item);
977            }
978
979            // Check for comma to continue
980            if matches!(self.current_token, Token::Comma) {
981                self.advance();
982            } else {
983                break;
984            }
985        }
986
987        Ok(items)
988    }
989
990    fn parse_identifier_list(&mut self) -> Result<Vec<String>, String> {
991        let mut identifiers = Vec::new();
992
993        loop {
994            match &self.current_token {
995                Token::Identifier(id) => {
996                    // Check if this is a reserved keyword that should stop identifier parsing
997                    let id_upper = id.to_uppercase();
998                    if matches!(
999                        id_upper.as_str(),
1000                        "ORDER" | "HAVING" | "LIMIT" | "OFFSET" | "UNION" | "INTERSECT" | "EXCEPT"
1001                    ) {
1002                        // Stop parsing identifiers if we hit a reserved keyword
1003                        break;
1004                    }
1005                    identifiers.push(id.clone());
1006                    self.advance();
1007                }
1008                Token::QuotedIdentifier(id) => {
1009                    // Handle quoted identifiers like "Customer Id"
1010                    identifiers.push(id.clone());
1011                    self.advance();
1012                }
1013                _ => {
1014                    // Stop parsing if we hit any other token type
1015                    break;
1016                }
1017            }
1018
1019            if matches!(self.current_token, Token::Comma) {
1020                self.advance();
1021            } else {
1022                break;
1023            }
1024        }
1025
1026        if identifiers.is_empty() {
1027            return Err("Expected at least one identifier".to_string());
1028        }
1029
1030        Ok(identifiers)
1031    }
1032
1033    fn parse_window_spec(&mut self) -> Result<WindowSpec, String> {
1034        let mut partition_by = Vec::new();
1035        let mut order_by = Vec::new();
1036
1037        // Check for PARTITION BY
1038        if matches!(self.current_token, Token::Partition) {
1039            self.advance(); // consume PARTITION
1040            if !matches!(self.current_token, Token::By) {
1041                return Err("Expected BY after PARTITION".to_string());
1042            }
1043            self.advance(); // consume BY
1044
1045            // Parse partition columns
1046            partition_by = self.parse_identifier_list()?;
1047        }
1048
1049        // Check for ORDER BY
1050        if matches!(self.current_token, Token::OrderBy) {
1051            self.advance(); // consume ORDER BY (as single token)
1052            order_by = self.parse_order_by_list()?;
1053        } else if let Token::Identifier(s) = &self.current_token {
1054            if s.to_uppercase() == "ORDER" {
1055                // Handle ORDER BY as two tokens
1056                self.advance(); // consume ORDER
1057                if !matches!(self.current_token, Token::By) {
1058                    return Err("Expected BY after ORDER".to_string());
1059                }
1060                self.advance(); // consume BY
1061                order_by = self.parse_order_by_list()?;
1062            }
1063        }
1064
1065        // Parse optional window frame (ROWS/RANGE BETWEEN ... AND ...)
1066        let frame = self.parse_window_frame()?;
1067
1068        Ok(WindowSpec {
1069            partition_by,
1070            order_by,
1071            frame,
1072        })
1073    }
1074
1075    fn parse_order_by_list(&mut self) -> Result<Vec<OrderByColumn>, String> {
1076        let mut order_columns = Vec::new();
1077
1078        loop {
1079            let column = match &self.current_token {
1080                Token::Identifier(id) => {
1081                    let col = id.clone();
1082                    self.advance();
1083                    col
1084                }
1085                Token::QuotedIdentifier(id) => {
1086                    let col = id.clone();
1087                    self.advance();
1088                    col
1089                }
1090                Token::NumberLiteral(num) if self.columns.iter().any(|col| col == num) => {
1091                    // Support numeric column names like "202204"
1092                    let col = num.clone();
1093                    self.advance();
1094                    col
1095                }
1096                _ => return Err("Expected column name in ORDER BY".to_string()),
1097            };
1098
1099            // Check for ASC/DESC
1100            let direction = match &self.current_token {
1101                Token::Asc => {
1102                    self.advance();
1103                    SortDirection::Asc
1104                }
1105                Token::Desc => {
1106                    self.advance();
1107                    SortDirection::Desc
1108                }
1109                _ => SortDirection::Asc, // Default to ASC if not specified
1110            };
1111
1112            order_columns.push(OrderByColumn { column, direction });
1113
1114            if matches!(self.current_token, Token::Comma) {
1115                self.advance();
1116            } else {
1117                break;
1118            }
1119        }
1120
1121        Ok(order_columns)
1122    }
1123
1124    fn parse_window_frame(&mut self) -> Result<Option<WindowFrame>, String> {
1125        // Check for ROWS or RANGE keyword
1126        let unit = match &self.current_token {
1127            Token::Identifier(id) if id.to_uppercase() == "ROWS" => {
1128                self.advance();
1129                FrameUnit::Rows
1130            }
1131            Token::Identifier(id) if id.to_uppercase() == "RANGE" => {
1132                self.advance();
1133                FrameUnit::Range
1134            }
1135            _ => return Ok(None), // No window frame specified
1136        };
1137
1138        // Check for BETWEEN or just a single bound
1139        let (start, end) = if let Token::Between = &self.current_token {
1140            self.advance(); // consume BETWEEN
1141                            // Parse start bound
1142            let start = self.parse_frame_bound()?;
1143
1144            // Expect AND
1145            if !matches!(&self.current_token, Token::And) {
1146                return Err("Expected AND after window frame start bound".to_string());
1147            }
1148            self.advance();
1149
1150            // Parse end bound
1151            let end = self.parse_frame_bound()?;
1152            (start, Some(end))
1153        } else {
1154            // Single bound (e.g., "ROWS 5 PRECEDING")
1155            let bound = self.parse_frame_bound()?;
1156            (bound, None)
1157        };
1158
1159        Ok(Some(WindowFrame { unit, start, end }))
1160    }
1161
1162    fn parse_frame_bound(&mut self) -> Result<FrameBound, String> {
1163        match &self.current_token {
1164            Token::Identifier(id) if id.to_uppercase() == "UNBOUNDED" => {
1165                self.advance();
1166                match &self.current_token {
1167                    Token::Identifier(id) if id.to_uppercase() == "PRECEDING" => {
1168                        self.advance();
1169                        Ok(FrameBound::UnboundedPreceding)
1170                    }
1171                    Token::Identifier(id) if id.to_uppercase() == "FOLLOWING" => {
1172                        self.advance();
1173                        Ok(FrameBound::UnboundedFollowing)
1174                    }
1175                    _ => Err("Expected PRECEDING or FOLLOWING after UNBOUNDED".to_string()),
1176                }
1177            }
1178            Token::Identifier(id) if id.to_uppercase() == "CURRENT" => {
1179                self.advance();
1180                if let Token::Identifier(id) = &self.current_token {
1181                    if id.to_uppercase() == "ROW" {
1182                        self.advance();
1183                        return Ok(FrameBound::CurrentRow);
1184                    }
1185                }
1186                Err("Expected ROW after CURRENT".to_string())
1187            }
1188            Token::NumberLiteral(num) => {
1189                let n: i64 = num
1190                    .parse()
1191                    .map_err(|_| "Invalid number in window frame".to_string())?;
1192                self.advance();
1193                match &self.current_token {
1194                    Token::Identifier(id) if id.to_uppercase() == "PRECEDING" => {
1195                        self.advance();
1196                        Ok(FrameBound::Preceding(n))
1197                    }
1198                    Token::Identifier(id) if id.to_uppercase() == "FOLLOWING" => {
1199                        self.advance();
1200                        Ok(FrameBound::Following(n))
1201                    }
1202                    _ => Err("Expected PRECEDING or FOLLOWING after number".to_string()),
1203                }
1204            }
1205            _ => Err("Invalid window frame bound".to_string()),
1206        }
1207    }
1208
1209    fn parse_where_clause(&mut self) -> Result<WhereClause, String> {
1210        // Parse the entire WHERE clause as a single expression tree
1211        // The logical operators (AND/OR) are now handled within parse_expression
1212        let expr = self.parse_expression()?;
1213
1214        // Check for unexpected closing parenthesis
1215        if matches!(self.current_token, Token::RightParen) && self.paren_depth <= 0 {
1216            return Err(
1217                "Unexpected closing parenthesis - no matching opening parenthesis".to_string(),
1218            );
1219        }
1220
1221        // Create a single condition with the entire expression
1222        let conditions = vec![Condition {
1223            expr,
1224            connector: None,
1225        }];
1226
1227        Ok(WhereClause { conditions })
1228    }
1229
1230    fn parse_expression(&mut self) -> Result<SqlExpression, String> {
1231        // Start with logical OR as the lowest precedence operator
1232        // The hierarchy is: OR -> AND -> comparison -> additive -> multiplicative -> primary
1233        let mut left = self.parse_logical_or()?;
1234
1235        // Handle IN operator (not preceded by NOT)
1236        // This uses the modular comparison module
1237        left = parse_in_operator(self, left)?;
1238
1239        Ok(left)
1240    }
1241
1242    fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
1243        // Use the new modular comparison expression parser
1244        parse_comparison_expr(self)
1245    }
1246
1247    fn parse_additive(&mut self) -> Result<SqlExpression, String> {
1248        // Use the new modular arithmetic expression parser
1249        parse_additive_expr(self)
1250    }
1251
1252    fn parse_multiplicative(&mut self) -> Result<SqlExpression, String> {
1253        // Use the new modular arithmetic expression parser
1254        parse_multiplicative_expr(self)
1255    }
1256
1257    fn parse_logical_or(&mut self) -> Result<SqlExpression, String> {
1258        // Use the new modular logical expression parser
1259        parse_logical_or_expr(self)
1260    }
1261
1262    fn parse_logical_and(&mut self) -> Result<SqlExpression, String> {
1263        // Use the new modular logical expression parser
1264        parse_logical_and_expr(self)
1265    }
1266
1267    fn parse_case_expression(&mut self) -> Result<SqlExpression, String> {
1268        // Use the new modular CASE expression parser
1269        parse_case_expr(self)
1270    }
1271
1272    fn parse_primary(&mut self) -> Result<SqlExpression, String> {
1273        // Use the new modular primary expression parser
1274        // Clone the necessary data to avoid borrowing issues
1275        let columns = self.columns.clone();
1276        let in_method_args = self.in_method_args;
1277        let ctx = PrimaryExpressionContext {
1278            columns: &columns,
1279            in_method_args,
1280        };
1281        parse_primary_expr(self, &ctx)
1282    }
1283
1284    // Keep the old implementation temporarily for reference (will be removed)
1285    fn parse_method_args(&mut self) -> Result<Vec<SqlExpression>, String> {
1286        let mut args = Vec::new();
1287
1288        // Set flag to indicate we're parsing method arguments
1289        self.in_method_args = true;
1290
1291        if !matches!(self.current_token, Token::RightParen) {
1292            loop {
1293                args.push(self.parse_expression()?);
1294
1295                if matches!(self.current_token, Token::Comma) {
1296                    self.advance();
1297                } else {
1298                    break;
1299                }
1300            }
1301        }
1302
1303        // Clear the flag
1304        self.in_method_args = false;
1305
1306        Ok(args)
1307    }
1308
1309    fn parse_function_args(&mut self) -> Result<(Vec<SqlExpression>, bool), String> {
1310        let mut args = Vec::new();
1311        let mut has_distinct = false;
1312
1313        if !matches!(self.current_token, Token::RightParen) {
1314            // Check if first argument starts with DISTINCT
1315            if matches!(self.current_token, Token::Distinct) {
1316                self.advance(); // consume DISTINCT
1317                has_distinct = true;
1318            }
1319
1320            // Parse the expression (either after DISTINCT or directly)
1321            args.push(self.parse_additive()?);
1322
1323            // Parse any remaining arguments (DISTINCT only applies to first arg for aggregates)
1324            while matches!(self.current_token, Token::Comma) {
1325                self.advance();
1326                args.push(self.parse_additive()?);
1327            }
1328        }
1329
1330        Ok((args, has_distinct))
1331    }
1332
1333    fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
1334        let mut expressions = Vec::new();
1335
1336        loop {
1337            expressions.push(self.parse_expression()?);
1338
1339            if matches!(self.current_token, Token::Comma) {
1340                self.advance();
1341            } else {
1342                break;
1343            }
1344        }
1345
1346        Ok(expressions)
1347    }
1348
1349    fn get_binary_op(&self) -> Option<String> {
1350        match &self.current_token {
1351            Token::Equal => Some("=".to_string()),
1352            Token::NotEqual => Some("!=".to_string()),
1353            Token::LessThan => Some("<".to_string()),
1354            Token::GreaterThan => Some(">".to_string()),
1355            Token::LessThanOrEqual => Some("<=".to_string()),
1356            Token::GreaterThanOrEqual => Some(">=".to_string()),
1357            Token::Like => Some("LIKE".to_string()),
1358            _ => None,
1359        }
1360    }
1361
1362    fn get_arithmetic_op(&self) -> Option<String> {
1363        match &self.current_token {
1364            Token::Plus => Some("+".to_string()),
1365            Token::Minus => Some("-".to_string()),
1366            Token::Star => Some("*".to_string()), // Multiplication (context-sensitive)
1367            Token::Divide => Some("/".to_string()),
1368            Token::Modulo => Some("%".to_string()),
1369            _ => None,
1370        }
1371    }
1372
1373    #[must_use]
1374    pub fn get_position(&self) -> usize {
1375        self.lexer.get_position()
1376    }
1377
1378    // Check if current token is a JOIN-related token
1379    fn is_join_token(&self) -> bool {
1380        matches!(
1381            self.current_token,
1382            Token::Join | Token::Inner | Token::Left | Token::Right | Token::Full | Token::Cross
1383        )
1384    }
1385
1386    // Parse a JOIN clause
1387    fn parse_join_clause(&mut self) -> Result<JoinClause, String> {
1388        // Determine join type
1389        let join_type = match &self.current_token {
1390            Token::Join => {
1391                self.advance();
1392                JoinType::Inner // Default JOIN is INNER JOIN
1393            }
1394            Token::Inner => {
1395                self.advance();
1396                if !matches!(self.current_token, Token::Join) {
1397                    return Err("Expected JOIN after INNER".to_string());
1398                }
1399                self.advance();
1400                JoinType::Inner
1401            }
1402            Token::Left => {
1403                self.advance();
1404                // Handle optional OUTER keyword
1405                if matches!(self.current_token, Token::Outer) {
1406                    self.advance();
1407                }
1408                if !matches!(self.current_token, Token::Join) {
1409                    return Err("Expected JOIN after LEFT".to_string());
1410                }
1411                self.advance();
1412                JoinType::Left
1413            }
1414            Token::Right => {
1415                self.advance();
1416                // Handle optional OUTER keyword
1417                if matches!(self.current_token, Token::Outer) {
1418                    self.advance();
1419                }
1420                if !matches!(self.current_token, Token::Join) {
1421                    return Err("Expected JOIN after RIGHT".to_string());
1422                }
1423                self.advance();
1424                JoinType::Right
1425            }
1426            Token::Full => {
1427                self.advance();
1428                // Handle optional OUTER keyword
1429                if matches!(self.current_token, Token::Outer) {
1430                    self.advance();
1431                }
1432                if !matches!(self.current_token, Token::Join) {
1433                    return Err("Expected JOIN after FULL".to_string());
1434                }
1435                self.advance();
1436                JoinType::Full
1437            }
1438            Token::Cross => {
1439                self.advance();
1440                if !matches!(self.current_token, Token::Join) {
1441                    return Err("Expected JOIN after CROSS".to_string());
1442                }
1443                self.advance();
1444                JoinType::Cross
1445            }
1446            _ => return Err("Expected JOIN keyword".to_string()),
1447        };
1448
1449        // Parse the table being joined
1450        let (table, alias) = self.parse_join_table_source()?;
1451
1452        // Parse ON condition (required for all joins except CROSS JOIN)
1453        let condition = if join_type == JoinType::Cross {
1454            // CROSS JOIN doesn't have ON condition
1455            JoinCondition {
1456                left_column: String::new(),
1457                operator: JoinOperator::Equal,
1458                right_column: String::new(),
1459            }
1460        } else {
1461            if !matches!(self.current_token, Token::On) {
1462                return Err("Expected ON keyword after JOIN table".to_string());
1463            }
1464            self.advance();
1465            self.parse_join_condition()?
1466        };
1467
1468        Ok(JoinClause {
1469            join_type,
1470            table,
1471            alias,
1472            condition,
1473        })
1474    }
1475
1476    fn parse_join_table_source(&mut self) -> Result<(TableSource, Option<String>), String> {
1477        let table = match &self.current_token {
1478            Token::Identifier(name) => {
1479                let table_name = name.clone();
1480                self.advance();
1481                TableSource::Table(table_name)
1482            }
1483            Token::LeftParen => {
1484                // Subquery as table source
1485                self.advance();
1486                let subquery = self.parse_select_statement_inner()?;
1487                if !matches!(self.current_token, Token::RightParen) {
1488                    return Err("Expected ')' after subquery".to_string());
1489                }
1490                self.advance();
1491
1492                // Subqueries must have an alias
1493                let alias = match &self.current_token {
1494                    Token::Identifier(alias_name) => {
1495                        let alias = alias_name.clone();
1496                        self.advance();
1497                        alias
1498                    }
1499                    Token::As => {
1500                        self.advance();
1501                        match &self.current_token {
1502                            Token::Identifier(alias_name) => {
1503                                let alias = alias_name.clone();
1504                                self.advance();
1505                                alias
1506                            }
1507                            _ => return Err("Expected alias after AS keyword".to_string()),
1508                        }
1509                    }
1510                    _ => return Err("Subqueries must have an alias".to_string()),
1511                };
1512
1513                return Ok((
1514                    TableSource::DerivedTable {
1515                        query: Box::new(subquery),
1516                        alias: alias.clone(),
1517                    },
1518                    Some(alias),
1519                ));
1520            }
1521            _ => return Err("Expected table name or subquery in JOIN clause".to_string()),
1522        };
1523
1524        // Check for optional alias
1525        let alias = match &self.current_token {
1526            Token::Identifier(alias_name) => {
1527                let alias = alias_name.clone();
1528                self.advance();
1529                Some(alias)
1530            }
1531            Token::As => {
1532                self.advance();
1533                match &self.current_token {
1534                    Token::Identifier(alias_name) => {
1535                        let alias = alias_name.clone();
1536                        self.advance();
1537                        Some(alias)
1538                    }
1539                    _ => return Err("Expected alias after AS keyword".to_string()),
1540                }
1541            }
1542            _ => None,
1543        };
1544
1545        Ok((table, alias))
1546    }
1547
1548    fn parse_join_condition(&mut self) -> Result<JoinCondition, String> {
1549        // Parse left column (can include table prefix)
1550        let left_column = self.parse_column_reference()?;
1551
1552        // Parse operator
1553        let operator = match &self.current_token {
1554            Token::Equal => JoinOperator::Equal,
1555            Token::NotEqual => JoinOperator::NotEqual,
1556            Token::LessThan => JoinOperator::LessThan,
1557            Token::LessThanOrEqual => JoinOperator::LessThanOrEqual,
1558            Token::GreaterThan => JoinOperator::GreaterThan,
1559            Token::GreaterThanOrEqual => JoinOperator::GreaterThanOrEqual,
1560            _ => return Err("Expected comparison operator in JOIN condition".to_string()),
1561        };
1562        self.advance();
1563
1564        // Parse right column (can include table prefix)
1565        let right_column = self.parse_column_reference()?;
1566
1567        Ok(JoinCondition {
1568            left_column,
1569            operator,
1570            right_column,
1571        })
1572    }
1573
1574    fn parse_column_reference(&mut self) -> Result<String, String> {
1575        match &self.current_token {
1576            Token::Identifier(name) => {
1577                let mut column_ref = name.clone();
1578                self.advance();
1579
1580                // Check for table.column notation
1581                if matches!(self.current_token, Token::Dot) {
1582                    self.advance();
1583                    match &self.current_token {
1584                        Token::Identifier(col_name) => {
1585                            column_ref.push('.');
1586                            column_ref.push_str(col_name);
1587                            self.advance();
1588                        }
1589                        _ => return Err("Expected column name after '.'".to_string()),
1590                    }
1591                }
1592
1593                Ok(column_ref)
1594            }
1595            _ => Err("Expected column reference".to_string()),
1596        }
1597    }
1598}
1599
1600// Context detection for cursor position
1601#[derive(Debug, Clone)]
1602pub enum CursorContext {
1603    SelectClause,
1604    FromClause,
1605    WhereClause,
1606    OrderByClause,
1607    AfterColumn(String),
1608    AfterLogicalOp(LogicalOp),
1609    AfterComparisonOp(String, String), // column_name, operator
1610    InMethodCall(String, String),      // object, method
1611    InExpression,
1612    Unknown,
1613}
1614
1615/// Safe UTF-8 string slicing that ensures we don't slice in the middle of a character
1616fn safe_slice_to(s: &str, pos: usize) -> &str {
1617    if pos >= s.len() {
1618        return s;
1619    }
1620
1621    // Find the nearest valid character boundary at or before pos
1622    let mut safe_pos = pos;
1623    while safe_pos > 0 && !s.is_char_boundary(safe_pos) {
1624        safe_pos -= 1;
1625    }
1626
1627    &s[..safe_pos]
1628}
1629
1630/// Safe UTF-8 string slicing from a position to the end
1631fn safe_slice_from(s: &str, pos: usize) -> &str {
1632    if pos >= s.len() {
1633        return "";
1634    }
1635
1636    // Find the nearest valid character boundary at or after pos
1637    let mut safe_pos = pos;
1638    while safe_pos < s.len() && !s.is_char_boundary(safe_pos) {
1639        safe_pos += 1;
1640    }
1641
1642    &s[safe_pos..]
1643}
1644
1645#[must_use]
1646pub fn detect_cursor_context(query: &str, cursor_pos: usize) -> (CursorContext, Option<String>) {
1647    let truncated = safe_slice_to(query, cursor_pos);
1648    let mut parser = Parser::new(truncated);
1649
1650    // Try to parse as much as possible
1651    if let Ok(stmt) = parser.parse() {
1652        let (ctx, partial) = analyze_statement(&stmt, truncated, cursor_pos);
1653        #[cfg(test)]
1654        println!("analyze_statement returned: {ctx:?}, {partial:?} for query: '{truncated}'");
1655        (ctx, partial)
1656    } else {
1657        // Partial parse - analyze what we have
1658        let (ctx, partial) = analyze_partial(truncated, cursor_pos);
1659        #[cfg(test)]
1660        println!("analyze_partial returned: {ctx:?}, {partial:?} for query: '{truncated}'");
1661        (ctx, partial)
1662    }
1663}
1664
1665#[must_use]
1666pub fn tokenize_query(query: &str) -> Vec<String> {
1667    let mut lexer = Lexer::new(query);
1668    let tokens = lexer.tokenize_all();
1669    tokens.iter().map(|t| format!("{t:?}")).collect()
1670}
1671
1672#[must_use]
1673fn analyze_statement(
1674    stmt: &SelectStatement,
1675    query: &str,
1676    _cursor_pos: usize,
1677) -> (CursorContext, Option<String>) {
1678    // First check for method call context (e.g., "columnName." or "columnName.Con")
1679    let trimmed = query.trim();
1680
1681    // Check if we're after a comparison operator (e.g., "createdDate > ")
1682    let comparison_ops = [" > ", " < ", " >= ", " <= ", " = ", " != "];
1683    for op in &comparison_ops {
1684        if let Some(op_pos) = query.rfind(op) {
1685            let before_op = safe_slice_to(query, op_pos);
1686            let after_op_start = op_pos + op.len();
1687            let after_op = if after_op_start < query.len() {
1688                &query[after_op_start..]
1689            } else {
1690                ""
1691            };
1692
1693            // Check if we have a column name before the operator
1694            if let Some(col_name) = before_op.split_whitespace().last() {
1695                if col_name.chars().all(|c| c.is_alphanumeric() || c == '_') {
1696                    // Check if we're at or near the end of the query
1697                    let after_op_trimmed = after_op.trim();
1698                    if after_op_trimmed.is_empty()
1699                        || (after_op_trimmed
1700                            .chars()
1701                            .all(|c| c.is_alphanumeric() || c == '_')
1702                            && !after_op_trimmed.contains('('))
1703                    {
1704                        let partial = if after_op_trimmed.is_empty() {
1705                            None
1706                        } else {
1707                            Some(after_op_trimmed.to_string())
1708                        };
1709                        return (
1710                            CursorContext::AfterComparisonOp(
1711                                col_name.to_string(),
1712                                op.trim().to_string(),
1713                            ),
1714                            partial,
1715                        );
1716                    }
1717                }
1718            }
1719        }
1720    }
1721
1722    // First check if we're after AND/OR - this takes precedence
1723    if trimmed.to_uppercase().ends_with(" AND")
1724        || trimmed.to_uppercase().ends_with(" OR")
1725        || trimmed.to_uppercase().ends_with(" AND ")
1726        || trimmed.to_uppercase().ends_with(" OR ")
1727    {
1728        // Don't check for method context if we're clearly after a logical operator
1729    } else {
1730        // Look for the last dot in the query
1731        if let Some(dot_pos) = trimmed.rfind('.') {
1732            // Check if we're after a column name and dot
1733            let before_dot = safe_slice_to(trimmed, dot_pos);
1734            let after_dot_start = dot_pos + 1;
1735            let after_dot = if after_dot_start < trimmed.len() {
1736                &trimmed[after_dot_start..]
1737            } else {
1738                ""
1739            };
1740
1741            // Check if the part after dot looks like an incomplete method call
1742            // (not a complete method call like "Contains(...)")
1743            if !after_dot.contains('(') {
1744                // Try to extract the column name - could be quoted or regular
1745                let col_name = if before_dot.ends_with('"') {
1746                    // Handle quoted identifier - search backwards for matching opening quote
1747                    let bytes = before_dot.as_bytes();
1748                    let mut pos = before_dot.len() - 1; // Position of closing quote
1749                    let mut found_start = None;
1750
1751                    // Skip the closing quote and search backwards
1752                    if pos > 0 {
1753                        pos -= 1;
1754                        while pos > 0 {
1755                            if bytes[pos] == b'"' {
1756                                // Check if it's not an escaped quote
1757                                if pos == 0 || bytes[pos - 1] != b'\\' {
1758                                    found_start = Some(pos);
1759                                    break;
1760                                }
1761                            }
1762                            pos -= 1;
1763                        }
1764                        // Check position 0 separately
1765                        if found_start.is_none() && bytes[0] == b'"' {
1766                            found_start = Some(0);
1767                        }
1768                    }
1769
1770                    found_start.map(|start| safe_slice_from(before_dot, start))
1771                } else {
1772                    // Regular identifier - get the last word, handling parentheses
1773                    // Strip all leading parentheses
1774                    before_dot
1775                        .split_whitespace()
1776                        .last()
1777                        .map(|word| word.trim_start_matches('('))
1778                };
1779
1780                if let Some(col_name) = col_name {
1781                    // For quoted identifiers, keep the quotes, for regular identifiers check validity
1782                    let is_valid = if col_name.starts_with('"') && col_name.ends_with('"') {
1783                        // Quoted identifier - always valid
1784                        true
1785                    } else {
1786                        // Regular identifier - check if it's alphanumeric or underscore
1787                        col_name.chars().all(|c| c.is_alphanumeric() || c == '_')
1788                    };
1789
1790                    if is_valid {
1791                        // We're in a method call context
1792                        // Check if there's a partial method name after the dot
1793                        let partial_method = if after_dot.is_empty() {
1794                            None
1795                        } else if after_dot.chars().all(|c| c.is_alphanumeric() || c == '_') {
1796                            Some(after_dot.to_string())
1797                        } else {
1798                            None
1799                        };
1800
1801                        // For AfterColumn context, strip quotes if present for consistency
1802                        let col_name_for_context = if col_name.starts_with('"')
1803                            && col_name.ends_with('"')
1804                            && col_name.len() > 2
1805                        {
1806                            col_name[1..col_name.len() - 1].to_string()
1807                        } else {
1808                            col_name.to_string()
1809                        };
1810
1811                        return (
1812                            CursorContext::AfterColumn(col_name_for_context),
1813                            partial_method,
1814                        );
1815                    }
1816                }
1817            }
1818        }
1819    }
1820
1821    // Check if we're in WHERE clause
1822    if let Some(where_clause) = &stmt.where_clause {
1823        // Check if query ends with AND/OR (with or without trailing space/partial)
1824        if trimmed.to_uppercase().ends_with(" AND") || trimmed.to_uppercase().ends_with(" OR") {
1825            let op = if trimmed.to_uppercase().ends_with(" AND") {
1826                LogicalOp::And
1827            } else {
1828                LogicalOp::Or
1829            };
1830            return (CursorContext::AfterLogicalOp(op), None);
1831        }
1832
1833        // Check if we have AND/OR followed by a partial word
1834        if let Some(and_pos) = query.to_uppercase().rfind(" AND ") {
1835            let after_and = safe_slice_from(query, and_pos + 5);
1836            let partial = extract_partial_at_end(after_and);
1837            if partial.is_some() {
1838                return (CursorContext::AfterLogicalOp(LogicalOp::And), partial);
1839            }
1840        }
1841
1842        if let Some(or_pos) = query.to_uppercase().rfind(" OR ") {
1843            let after_or = safe_slice_from(query, or_pos + 4);
1844            let partial = extract_partial_at_end(after_or);
1845            if partial.is_some() {
1846                return (CursorContext::AfterLogicalOp(LogicalOp::Or), partial);
1847            }
1848        }
1849
1850        if let Some(last_condition) = where_clause.conditions.last() {
1851            if let Some(connector) = &last_condition.connector {
1852                // We're after AND/OR
1853                return (
1854                    CursorContext::AfterLogicalOp(connector.clone()),
1855                    extract_partial_at_end(query),
1856                );
1857            }
1858        }
1859        // We're in WHERE clause but not after AND/OR
1860        return (CursorContext::WhereClause, extract_partial_at_end(query));
1861    }
1862
1863    // Check if we're after ORDER BY
1864    if query.to_uppercase().ends_with(" ORDER BY ") || query.to_uppercase().ends_with(" ORDER BY") {
1865        return (CursorContext::OrderByClause, None);
1866    }
1867
1868    // Check other contexts based on what's in the statement
1869    if stmt.order_by.is_some() {
1870        return (CursorContext::OrderByClause, extract_partial_at_end(query));
1871    }
1872
1873    if stmt.from_table.is_some() && stmt.where_clause.is_none() && stmt.order_by.is_none() {
1874        return (CursorContext::FromClause, extract_partial_at_end(query));
1875    }
1876
1877    if !stmt.columns.is_empty() && stmt.from_table.is_none() {
1878        return (CursorContext::SelectClause, extract_partial_at_end(query));
1879    }
1880
1881    (CursorContext::Unknown, None)
1882}
1883
1884fn analyze_partial(query: &str, cursor_pos: usize) -> (CursorContext, Option<String>) {
1885    let upper = query.to_uppercase();
1886
1887    // Check for method call context first (e.g., "columnName." or "columnName.Con")
1888    let trimmed = query.trim();
1889
1890    #[cfg(test)]
1891    {
1892        if trimmed.contains("\"Last Name\"") {
1893            eprintln!("DEBUG analyze_partial: query='{query}', trimmed='{trimmed}'");
1894        }
1895    }
1896
1897    // Check if we're after a comparison operator (e.g., "createdDate > ")
1898    let comparison_ops = [" > ", " < ", " >= ", " <= ", " = ", " != "];
1899    for op in &comparison_ops {
1900        if let Some(op_pos) = query.rfind(op) {
1901            let before_op = safe_slice_to(query, op_pos);
1902            let after_op_start = op_pos + op.len();
1903            let after_op = if after_op_start < query.len() {
1904                &query[after_op_start..]
1905            } else {
1906                ""
1907            };
1908
1909            // Check if we have a column name before the operator
1910            if let Some(col_name) = before_op.split_whitespace().last() {
1911                if col_name.chars().all(|c| c.is_alphanumeric() || c == '_') {
1912                    // Check if we're at or near the end of the query (allowing for some whitespace)
1913                    let after_op_trimmed = after_op.trim();
1914                    if after_op_trimmed.is_empty()
1915                        || (after_op_trimmed
1916                            .chars()
1917                            .all(|c| c.is_alphanumeric() || c == '_')
1918                            && !after_op_trimmed.contains('('))
1919                    {
1920                        let partial = if after_op_trimmed.is_empty() {
1921                            None
1922                        } else {
1923                            Some(after_op_trimmed.to_string())
1924                        };
1925                        return (
1926                            CursorContext::AfterComparisonOp(
1927                                col_name.to_string(),
1928                                op.trim().to_string(),
1929                            ),
1930                            partial,
1931                        );
1932                    }
1933                }
1934            }
1935        }
1936    }
1937
1938    // Look for the last dot in the query (method call context) - check this FIRST
1939    // before AND/OR detection to properly handle cases like "AND (Country."
1940    if let Some(dot_pos) = trimmed.rfind('.') {
1941        #[cfg(test)]
1942        {
1943            if trimmed.contains("\"Last Name\"") {
1944                eprintln!("DEBUG: Found dot at position {dot_pos}");
1945            }
1946        }
1947        // Check if we're after a column name and dot
1948        let before_dot = &trimmed[..dot_pos];
1949        let after_dot = &trimmed[dot_pos + 1..];
1950
1951        // Check if the part after dot looks like an incomplete method call
1952        // (not a complete method call like "Contains(...)")
1953        if !after_dot.contains('(') {
1954            // Try to extract the column name before the dot
1955            // It could be a quoted identifier like "Last Name" or a regular identifier
1956            let col_name = if before_dot.ends_with('"') {
1957                // Handle quoted identifier - search backwards for matching opening quote
1958                let bytes = before_dot.as_bytes();
1959                let mut pos = before_dot.len() - 1; // Position of closing quote
1960                let mut found_start = None;
1961
1962                #[cfg(test)]
1963                {
1964                    if trimmed.contains("\"Last Name\"") {
1965                        eprintln!("DEBUG: before_dot='{before_dot}', looking for opening quote");
1966                    }
1967                }
1968
1969                // Skip the closing quote and search backwards
1970                if pos > 0 {
1971                    pos -= 1;
1972                    while pos > 0 {
1973                        if bytes[pos] == b'"' {
1974                            // Check if it's not an escaped quote
1975                            if pos == 0 || bytes[pos - 1] != b'\\' {
1976                                found_start = Some(pos);
1977                                break;
1978                            }
1979                        }
1980                        pos -= 1;
1981                    }
1982                    // Check position 0 separately
1983                    if found_start.is_none() && bytes[0] == b'"' {
1984                        found_start = Some(0);
1985                    }
1986                }
1987
1988                if let Some(start) = found_start {
1989                    // Extract the full quoted identifier including quotes
1990                    let result = safe_slice_from(before_dot, start);
1991                    #[cfg(test)]
1992                    {
1993                        if trimmed.contains("\"Last Name\"") {
1994                            eprintln!("DEBUG: Extracted quoted identifier: '{result}'");
1995                        }
1996                    }
1997                    Some(result)
1998                } else {
1999                    #[cfg(test)]
2000                    {
2001                        if trimmed.contains("\"Last Name\"") {
2002                            eprintln!("DEBUG: No opening quote found!");
2003                        }
2004                    }
2005                    None
2006                }
2007            } else {
2008                // Regular identifier - get the last word, handling parentheses
2009                // Strip all leading parentheses
2010                before_dot
2011                    .split_whitespace()
2012                    .last()
2013                    .map(|word| word.trim_start_matches('('))
2014            };
2015
2016            if let Some(col_name) = col_name {
2017                #[cfg(test)]
2018                {
2019                    if trimmed.contains("\"Last Name\"") {
2020                        eprintln!("DEBUG: col_name = '{col_name}'");
2021                    }
2022                }
2023
2024                // For quoted identifiers, keep the quotes, for regular identifiers check validity
2025                let is_valid = if col_name.starts_with('"') && col_name.ends_with('"') {
2026                    // Quoted identifier - always valid
2027                    true
2028                } else {
2029                    // Regular identifier - check if it's alphanumeric or underscore
2030                    col_name.chars().all(|c| c.is_alphanumeric() || c == '_')
2031                };
2032
2033                #[cfg(test)]
2034                {
2035                    if trimmed.contains("\"Last Name\"") {
2036                        eprintln!("DEBUG: is_valid = {is_valid}");
2037                    }
2038                }
2039
2040                if is_valid {
2041                    // We're in a method call context
2042                    // Check if there's a partial method name after the dot
2043                    let partial_method = if after_dot.is_empty() {
2044                        None
2045                    } else if after_dot.chars().all(|c| c.is_alphanumeric() || c == '_') {
2046                        Some(after_dot.to_string())
2047                    } else {
2048                        None
2049                    };
2050
2051                    // For AfterColumn context, strip quotes if present for consistency
2052                    let col_name_for_context = if col_name.starts_with('"')
2053                        && col_name.ends_with('"')
2054                        && col_name.len() > 2
2055                    {
2056                        col_name[1..col_name.len() - 1].to_string()
2057                    } else {
2058                        col_name.to_string()
2059                    };
2060
2061                    return (
2062                        CursorContext::AfterColumn(col_name_for_context),
2063                        partial_method,
2064                    );
2065                }
2066            }
2067        }
2068    }
2069
2070    // Check if we're after AND/OR - but only after checking for method calls
2071    if let Some(and_pos) = upper.rfind(" AND ") {
2072        // Check if cursor is after AND
2073        if cursor_pos >= and_pos + 5 {
2074            // Extract any partial word after AND
2075            let after_and = safe_slice_from(query, and_pos + 5);
2076            let partial = extract_partial_at_end(after_and);
2077            return (CursorContext::AfterLogicalOp(LogicalOp::And), partial);
2078        }
2079    }
2080
2081    if let Some(or_pos) = upper.rfind(" OR ") {
2082        // Check if cursor is after OR
2083        if cursor_pos >= or_pos + 4 {
2084            // Extract any partial word after OR
2085            let after_or = safe_slice_from(query, or_pos + 4);
2086            let partial = extract_partial_at_end(after_or);
2087            return (CursorContext::AfterLogicalOp(LogicalOp::Or), partial);
2088        }
2089    }
2090
2091    // Handle case where AND/OR is at the very end
2092    if trimmed.to_uppercase().ends_with(" AND") || trimmed.to_uppercase().ends_with(" OR") {
2093        let op = if trimmed.to_uppercase().ends_with(" AND") {
2094            LogicalOp::And
2095        } else {
2096            LogicalOp::Or
2097        };
2098        return (CursorContext::AfterLogicalOp(op), None);
2099    }
2100
2101    // Check if we're after ORDER BY
2102    if upper.ends_with(" ORDER BY ") || upper.ends_with(" ORDER BY") || upper.contains("ORDER BY ")
2103    {
2104        return (CursorContext::OrderByClause, extract_partial_at_end(query));
2105    }
2106
2107    if upper.contains("WHERE") && !upper.contains("ORDER") && !upper.contains("GROUP") {
2108        return (CursorContext::WhereClause, extract_partial_at_end(query));
2109    }
2110
2111    if upper.contains("FROM") && !upper.contains("WHERE") && !upper.contains("ORDER") {
2112        return (CursorContext::FromClause, extract_partial_at_end(query));
2113    }
2114
2115    if upper.contains("SELECT") && !upper.contains("FROM") {
2116        return (CursorContext::SelectClause, extract_partial_at_end(query));
2117    }
2118
2119    (CursorContext::Unknown, None)
2120}
2121
2122fn extract_partial_at_end(query: &str) -> Option<String> {
2123    let trimmed = query.trim();
2124
2125    // First check if the last word itself starts with a quote (unclosed quoted identifier being typed)
2126    if let Some(last_word) = trimmed.split_whitespace().last() {
2127        if last_word.starts_with('"') && !last_word.ends_with('"') {
2128            // This is an unclosed quoted identifier like "Cust
2129            return Some(last_word.to_string());
2130        }
2131    }
2132
2133    // Regular identifier extraction
2134    let last_word = trimmed.split_whitespace().last()?;
2135
2136    // Check if it's a partial identifier (not a keyword or operator)
2137    if last_word.chars().all(|c| c.is_alphanumeric() || c == '_') && !is_sql_keyword(last_word) {
2138        Some(last_word.to_string())
2139    } else {
2140        None
2141    }
2142}
2143
2144// Implement the ParsePrimary trait for Parser to use the modular expression parsing
2145impl ParsePrimary for Parser {
2146    fn current_token(&self) -> &Token {
2147        &self.current_token
2148    }
2149
2150    fn advance(&mut self) {
2151        self.advance();
2152    }
2153
2154    fn consume(&mut self, expected: Token) -> Result<(), String> {
2155        self.consume(expected)
2156    }
2157
2158    fn parse_case_expression(&mut self) -> Result<SqlExpression, String> {
2159        self.parse_case_expression()
2160    }
2161
2162    fn parse_function_args(&mut self) -> Result<(Vec<SqlExpression>, bool), String> {
2163        self.parse_function_args()
2164    }
2165
2166    fn parse_window_spec(&mut self) -> Result<WindowSpec, String> {
2167        self.parse_window_spec()
2168    }
2169
2170    fn parse_logical_or(&mut self) -> Result<SqlExpression, String> {
2171        self.parse_logical_or()
2172    }
2173
2174    fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
2175        self.parse_comparison()
2176    }
2177
2178    fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
2179        self.parse_expression_list()
2180    }
2181
2182    fn parse_subquery(&mut self) -> Result<SelectStatement, String> {
2183        // Parse subquery without parenthesis balance validation
2184        if matches!(self.current_token, Token::With) {
2185            self.parse_with_clause_inner()
2186        } else {
2187            self.parse_select_statement_inner()
2188        }
2189    }
2190}
2191
2192// Implement the ExpressionParser trait for Parser to use the modular expression parsing
2193impl ExpressionParser for Parser {
2194    fn current_token(&self) -> &Token {
2195        &self.current_token
2196    }
2197
2198    fn advance(&mut self) {
2199        // Call the main advance method directly to avoid recursion
2200        match &self.current_token {
2201            Token::LeftParen => self.paren_depth += 1,
2202            Token::RightParen => {
2203                self.paren_depth -= 1;
2204            }
2205            _ => {}
2206        }
2207        self.current_token = self.lexer.next_token();
2208    }
2209
2210    fn peek(&self) -> Option<&Token> {
2211        // We can't return a reference to a token from a temporary lexer,
2212        // so we need a different approach. For now, let's use a workaround
2213        // that checks the next token type without consuming it.
2214        // This is a limitation of the current design.
2215        // A proper fix would be to store the peeked token in the Parser struct.
2216        None // TODO: Implement proper lookahead
2217    }
2218
2219    fn is_at_end(&self) -> bool {
2220        matches!(self.current_token, Token::Eof)
2221    }
2222
2223    fn consume(&mut self, expected: Token) -> Result<(), String> {
2224        // Call the main consume method to avoid recursion
2225        if std::mem::discriminant(&self.current_token) == std::mem::discriminant(&expected) {
2226            match &expected {
2227                Token::LeftParen => self.paren_depth += 1,
2228                Token::RightParen => {
2229                    self.paren_depth -= 1;
2230                    if self.paren_depth < 0 {
2231                        return Err(
2232                            "Unexpected closing parenthesis - no matching opening parenthesis"
2233                                .to_string(),
2234                        );
2235                    }
2236                }
2237                _ => {}
2238            }
2239            self.current_token = self.lexer.next_token();
2240            Ok(())
2241        } else {
2242            Err(format!(
2243                "Expected {:?}, found {:?}",
2244                expected, self.current_token
2245            ))
2246        }
2247    }
2248
2249    fn parse_identifier(&mut self) -> Result<String, String> {
2250        if let Token::Identifier(id) = &self.current_token {
2251            let id = id.clone();
2252            self.advance();
2253            Ok(id)
2254        } else {
2255            Err(format!(
2256                "Expected identifier, found {:?}",
2257                self.current_token
2258            ))
2259        }
2260    }
2261}
2262
2263// Implement the ParseArithmetic trait for Parser to use the modular arithmetic parsing
2264impl ParseArithmetic for Parser {
2265    fn current_token(&self) -> &Token {
2266        &self.current_token
2267    }
2268
2269    fn advance(&mut self) {
2270        self.advance();
2271    }
2272
2273    fn consume(&mut self, expected: Token) -> Result<(), String> {
2274        self.consume(expected)
2275    }
2276
2277    fn parse_primary(&mut self) -> Result<SqlExpression, String> {
2278        self.parse_primary()
2279    }
2280
2281    fn parse_multiplicative(&mut self) -> Result<SqlExpression, String> {
2282        self.parse_multiplicative()
2283    }
2284
2285    fn parse_method_args(&mut self) -> Result<Vec<SqlExpression>, String> {
2286        self.parse_method_args()
2287    }
2288}
2289
2290// Implement the ParseComparison trait for Parser to use the modular comparison parsing
2291impl ParseComparison for Parser {
2292    fn current_token(&self) -> &Token {
2293        &self.current_token
2294    }
2295
2296    fn advance(&mut self) {
2297        self.advance();
2298    }
2299
2300    fn consume(&mut self, expected: Token) -> Result<(), String> {
2301        self.consume(expected)
2302    }
2303
2304    fn parse_primary(&mut self) -> Result<SqlExpression, String> {
2305        self.parse_primary()
2306    }
2307
2308    fn parse_additive(&mut self) -> Result<SqlExpression, String> {
2309        self.parse_additive()
2310    }
2311
2312    fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
2313        self.parse_expression_list()
2314    }
2315
2316    fn parse_subquery(&mut self) -> Result<SelectStatement, String> {
2317        // Parse subquery without parenthesis balance validation
2318        if matches!(self.current_token, Token::With) {
2319            self.parse_with_clause_inner()
2320        } else {
2321            self.parse_select_statement_inner()
2322        }
2323    }
2324}
2325
2326// Implement the ParseLogical trait for Parser to use the modular logical parsing
2327impl ParseLogical for Parser {
2328    fn current_token(&self) -> &Token {
2329        &self.current_token
2330    }
2331
2332    fn advance(&mut self) {
2333        self.advance();
2334    }
2335
2336    fn consume(&mut self, expected: Token) -> Result<(), String> {
2337        self.consume(expected)
2338    }
2339
2340    fn parse_logical_and(&mut self) -> Result<SqlExpression, String> {
2341        self.parse_logical_and()
2342    }
2343
2344    fn parse_base_logical_expression(&mut self) -> Result<SqlExpression, String> {
2345        // This is the base for logical AND - it should parse comparison expressions
2346        // to avoid infinite recursion with parse_expression
2347        self.parse_comparison()
2348    }
2349
2350    fn parse_comparison(&mut self) -> Result<SqlExpression, String> {
2351        self.parse_comparison()
2352    }
2353
2354    fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String> {
2355        self.parse_expression_list()
2356    }
2357}
2358
2359// Implement the ParseCase trait for Parser to use the modular CASE parsing
2360impl ParseCase for Parser {
2361    fn current_token(&self) -> &Token {
2362        &self.current_token
2363    }
2364
2365    fn advance(&mut self) {
2366        self.advance();
2367    }
2368
2369    fn consume(&mut self, expected: Token) -> Result<(), String> {
2370        self.consume(expected)
2371    }
2372
2373    fn parse_expression(&mut self) -> Result<SqlExpression, String> {
2374        self.parse_expression()
2375    }
2376}
2377
2378fn is_sql_keyword(word: &str) -> bool {
2379    matches!(
2380        word.to_uppercase().as_str(),
2381        "SELECT"
2382            | "FROM"
2383            | "WHERE"
2384            | "AND"
2385            | "OR"
2386            | "IN"
2387            | "ORDER"
2388            | "BY"
2389            | "GROUP"
2390            | "HAVING"
2391            | "ASC"
2392            | "DESC"
2393            | "DISTINCT"
2394    )
2395}