sql_cli/sql/parser/expressions/
case.rs1use crate::sql::parser::ast::{SqlExpression, WhenBranch};
5use crate::sql::parser::lexer::Token;
6use tracing::debug;
7
8use super::{log_parse_decision, trace_parse_entry, trace_parse_exit};
9
10pub fn parse_case_expression<P>(parser: &mut P) -> Result<SqlExpression, String>
13where
14 P: ParseCase + ?Sized,
15{
16 trace_parse_entry("parse_case_expression", parser.current_token());
17
18 parser.consume(Token::Case)?;
20
21 debug!("Starting CASE expression parsing");
22
23 let mut when_branches = Vec::new();
28
29 while matches!(parser.current_token(), Token::When) {
31 log_parse_decision(
32 "parse_case_expression",
33 parser.current_token(),
34 "WHEN clause found, parsing condition and result",
35 );
36
37 parser.advance(); debug!("Parsing WHEN condition");
41 let condition = parser.parse_expression()?;
42
43 parser.consume(Token::Then)?;
45
46 debug!("Parsing THEN result");
48 let result = parser.parse_expression()?;
49
50 when_branches.push(WhenBranch {
51 condition: Box::new(condition),
52 result: Box::new(result),
53 });
54
55 debug!("Added WHEN branch #{}", when_branches.len());
56 }
57
58 if when_branches.is_empty() {
60 return Err("CASE expression must have at least one WHEN clause".to_string());
61 }
62
63 let else_branch = if matches!(parser.current_token(), Token::Else) {
65 log_parse_decision(
66 "parse_case_expression",
67 parser.current_token(),
68 "ELSE clause found, parsing default result",
69 );
70
71 parser.advance(); debug!("Parsing ELSE branch");
73 Some(Box::new(parser.parse_expression()?))
74 } else {
75 debug!("No ELSE branch");
76 None
77 };
78
79 parser.consume(Token::End)?;
81
82 debug!(
83 "Completed CASE expression with {} WHEN branches{}",
84 when_branches.len(),
85 if else_branch.is_some() {
86 " and ELSE"
87 } else {
88 ""
89 }
90 );
91
92 let result = Ok(SqlExpression::CaseExpression {
93 when_branches,
94 else_branch,
95 });
96
97 trace_parse_exit("parse_case_expression", &result);
98 result
99}
100
101pub trait ParseCase {
103 fn current_token(&self) -> &Token;
104 fn advance(&mut self);
105 fn consume(&mut self, expected: Token) -> Result<(), String>;
106
107 fn parse_expression(&mut self) -> Result<SqlExpression, String>;
109}