sql_cli/sql/parser/expressions/
logical.rs1use crate::sql::parser::ast::SqlExpression;
6use crate::sql::parser::lexer::Token;
7use tracing::debug;
8
9use super::{log_parse_decision, trace_parse_entry, trace_parse_exit};
10
11pub fn parse_logical_or<P>(parser: &mut P) -> Result<SqlExpression, String>
14where
15 P: ParseLogical + ?Sized,
16{
17 trace_parse_entry("parse_logical_or", parser.current_token());
18
19 let mut left = parser.parse_logical_and()?;
20
21 while matches!(parser.current_token(), Token::Or) {
22 log_parse_decision(
23 "parse_logical_or",
24 parser.current_token(),
25 "OR operator found, parsing right operand",
26 );
27
28 debug!("Processing logical OR operator");
29 parser.advance();
30 let right = parser.parse_logical_and()?;
31
32 left = SqlExpression::BinaryOp {
34 left: Box::new(left),
35 op: "OR".to_string(),
36 right: Box::new(right),
37 };
38
39 debug!("Created OR expression");
40 }
41
42 let result = Ok(left);
43 trace_parse_exit("parse_logical_or", &result);
44 result
45}
46
47pub fn parse_logical_and<P>(parser: &mut P) -> Result<SqlExpression, String>
50where
51 P: ParseLogical + ?Sized,
52{
53 trace_parse_entry("parse_logical_and", parser.current_token());
54
55 let mut left = parser.parse_base_logical_expression()?;
57
58 while matches!(parser.current_token(), Token::And) {
59 log_parse_decision(
60 "parse_logical_and",
61 parser.current_token(),
62 "AND operator found, parsing right operand",
63 );
64
65 debug!("Processing logical AND operator");
66 parser.advance();
67 let right = parser.parse_base_logical_expression()?;
68
69 left = SqlExpression::BinaryOp {
71 left: Box::new(left),
72 op: "AND".to_string(),
73 right: Box::new(right),
74 };
75
76 debug!("Created AND expression");
77 }
78
79 let result = Ok(left);
80 trace_parse_exit("parse_logical_and", &result);
81 result
82}
83
84pub fn parse_not_expression<P>(parser: &mut P) -> Result<SqlExpression, String>
87where
88 P: ParseLogical + ?Sized,
89{
90 trace_parse_entry("parse_not_expression", parser.current_token());
91
92 if !matches!(parser.current_token(), Token::Not) {
93 return Err("Expected NOT token".to_string());
94 }
95
96 log_parse_decision(
97 "parse_not_expression",
98 parser.current_token(),
99 "NOT operator found, parsing operand",
100 );
101
102 debug!("Processing NOT operator");
103 parser.advance(); let inner_expr = parser.parse_comparison()?;
107
108 if matches!(parser.current_token(), Token::In) {
110 debug!("NOT IN expression detected");
111 parser.advance(); parser.consume(Token::LeftParen)?;
113 let values = parser.parse_expression_list()?;
114 parser.consume(Token::RightParen)?;
115
116 let result = Ok(SqlExpression::NotInList {
117 expr: Box::new(inner_expr),
118 values,
119 });
120 trace_parse_exit("parse_not_expression", &result);
121 result
122 } else {
123 debug!("Creating NOT expression");
125 let result = Ok(SqlExpression::Not {
126 expr: Box::new(inner_expr),
127 });
128 trace_parse_exit("parse_not_expression", &result);
129 result
130 }
131}
132
133pub trait ParseLogical {
135 fn current_token(&self) -> &Token;
136 fn advance(&mut self);
137 fn consume(&mut self, expected: Token) -> Result<(), String>;
138
139 fn parse_logical_and(&mut self) -> Result<SqlExpression, String>;
141 fn parse_base_logical_expression(&mut self) -> Result<SqlExpression, String>;
142 fn parse_comparison(&mut self) -> Result<SqlExpression, String>;
143 fn parse_expression_list(&mut self) -> Result<Vec<SqlExpression>, String>;
144}