vibesql_executor/evaluator/
single.rs1use crate::errors::ExecutorError;
7use lru::LruCache;
8use std::{cell::RefCell, rc::Rc};
9
10pub struct ExpressionEvaluator<'a> {
12 pub(super) schema: &'a vibesql_catalog::TableSchema,
13 pub(super) outer_row: Option<&'a vibesql_storage::Row>,
14 pub(super) outer_schema: Option<&'a vibesql_catalog::TableSchema>,
15 pub(super) database: Option<&'a vibesql_storage::Database>,
16 pub(super) trigger_context: Option<&'a crate::trigger_execution::TriggerContext<'a>>,
18 pub(super) procedural_context: Option<&'a crate::procedural::ExecutionContext>,
20 pub(super) depth: usize,
22 pub(super) cse_cache: Rc<RefCell<LruCache<u64, vibesql_types::SqlValue>>>,
24 pub(super) enable_cse: bool,
26 pub(super) subquery_cache: Rc<RefCell<LruCache<u64, Vec<vibesql_storage::Row>>>>,
29}
30
31impl<'a> ExpressionEvaluator<'a> {
32 pub fn new(schema: &'a vibesql_catalog::TableSchema) -> Self {
34 ExpressionEvaluator {
35 schema,
36 outer_row: None,
37 outer_schema: None,
38 database: None,
39 trigger_context: None,
40 procedural_context: None,
41 depth: 0,
42 cse_cache: Rc::new(RefCell::new(super::caching::create_cse_cache())),
43 enable_cse: super::caching::is_cse_enabled(),
44 subquery_cache: Rc::new(RefCell::new(super::caching::create_subquery_cache())),
45 }
46 }
47
48 pub fn with_outer_context(
50 schema: &'a vibesql_catalog::TableSchema,
51 outer_row: &'a vibesql_storage::Row,
52 outer_schema: &'a vibesql_catalog::TableSchema,
53 ) -> Self {
54 ExpressionEvaluator {
55 schema,
56 outer_row: Some(outer_row),
57 outer_schema: Some(outer_schema),
58 database: None,
59 trigger_context: None,
60 procedural_context: None,
61 depth: 0,
62 cse_cache: Rc::new(RefCell::new(super::caching::create_cse_cache())),
63 enable_cse: super::caching::is_cse_enabled(),
64 subquery_cache: Rc::new(RefCell::new(super::caching::create_subquery_cache())),
65 }
66 }
67
68 pub fn with_database(
70 schema: &'a vibesql_catalog::TableSchema,
71 database: &'a vibesql_storage::Database,
72 ) -> Self {
73 ExpressionEvaluator {
74 schema,
75 outer_row: None,
76 outer_schema: None,
77 database: Some(database),
78 trigger_context: None,
79 procedural_context: None,
80 depth: 0,
81 cse_cache: Rc::new(RefCell::new(super::caching::create_cse_cache())),
82 enable_cse: super::caching::is_cse_enabled(),
83 subquery_cache: Rc::new(RefCell::new(super::caching::create_subquery_cache())),
84 }
85 }
86
87 pub fn with_trigger_context(
89 schema: &'a vibesql_catalog::TableSchema,
90 database: &'a vibesql_storage::Database,
91 trigger_context: &'a crate::trigger_execution::TriggerContext<'a>,
92 ) -> Self {
93 ExpressionEvaluator {
94 schema,
95 outer_row: None,
96 outer_schema: None,
97 database: Some(database),
98 trigger_context: Some(trigger_context),
99 procedural_context: None,
100 depth: 0,
101 cse_cache: Rc::new(RefCell::new(super::caching::create_cse_cache())),
102 enable_cse: super::caching::is_cse_enabled(),
103 subquery_cache: Rc::new(RefCell::new(super::caching::create_subquery_cache())),
104 }
105 }
106
107 pub fn with_database_and_outer_context(
110 schema: &'a vibesql_catalog::TableSchema,
111 database: &'a vibesql_storage::Database,
112 outer_row: &'a vibesql_storage::Row,
113 outer_schema: &'a vibesql_catalog::TableSchema,
114 ) -> Self {
115 ExpressionEvaluator {
116 schema,
117 outer_row: Some(outer_row),
118 outer_schema: Some(outer_schema),
119 database: Some(database),
120 trigger_context: None,
121 procedural_context: None,
122 depth: 0,
123 cse_cache: Rc::new(RefCell::new(super::caching::create_cse_cache())),
124 enable_cse: super::caching::is_cse_enabled(),
125 subquery_cache: Rc::new(RefCell::new(super::caching::create_subquery_cache())),
126 }
127 }
128
129 pub fn with_procedural_context(
131 schema: &'a vibesql_catalog::TableSchema,
132 database: &'a vibesql_storage::Database,
133 procedural_context: &'a crate::procedural::ExecutionContext,
134 ) -> Self {
135 ExpressionEvaluator {
136 schema,
137 outer_row: None,
138 outer_schema: None,
139 database: Some(database),
140 trigger_context: None,
141 procedural_context: Some(procedural_context),
142 depth: 0,
143 cse_cache: Rc::new(RefCell::new(super::caching::create_cse_cache())),
144 enable_cse: super::caching::is_cse_enabled(),
145 subquery_cache: Rc::new(RefCell::new(super::caching::create_subquery_cache())),
146 }
147 }
148
149 pub(crate) fn eval_binary_op(
151 &self,
152 left: &vibesql_types::SqlValue,
153 op: &vibesql_ast::BinaryOperator,
154 right: &vibesql_types::SqlValue,
155 ) -> Result<vibesql_types::SqlValue, ExecutorError> {
156 let sql_mode = self.database.map(|db| db.sql_mode()).unwrap_or_default();
158
159 super::core::eval_binary_op_static(left, op, right, sql_mode)
160 }
161
162 pub fn clear_cse_cache(&self) {
165 self.cse_cache.borrow_mut().clear();
166 }
167
168 pub(crate) fn eval_binary_op_static(
172 left: &vibesql_types::SqlValue,
173 op: &vibesql_ast::BinaryOperator,
174 right: &vibesql_types::SqlValue,
175 sql_mode: vibesql_types::SqlMode,
176 ) -> Result<vibesql_types::SqlValue, ExecutorError> {
177 super::core::eval_binary_op_static(left, op, right, sql_mode)
178 }
179
180 pub(crate) fn eval_between_static(
184 expr_val: &vibesql_types::SqlValue,
185 low_val: &vibesql_types::SqlValue,
186 high_val: &vibesql_types::SqlValue,
187 negated: bool,
188 symmetric: bool,
189 sql_mode: vibesql_types::SqlMode,
190 ) -> Result<vibesql_types::SqlValue, ExecutorError> {
191 super::core::eval_between_static(expr_val, low_val, high_val, negated, symmetric, sql_mode)
192 }
193
194 pub(crate) fn values_are_equal(
198 left: &vibesql_types::SqlValue,
199 right: &vibesql_types::SqlValue,
200 ) -> bool {
201 super::core::values_are_equal(left, right)
202 }
203
204 pub(super) fn with_incremented_depth<F, T>(&self, f: F) -> Result<T, ExecutorError>
206 where
207 F: FnOnce(&Self) -> Result<T, ExecutorError>,
208 {
209 let evaluator = ExpressionEvaluator {
212 schema: self.schema,
213 outer_row: self.outer_row,
214 outer_schema: self.outer_schema,
215 database: self.database,
216 trigger_context: self.trigger_context,
217 procedural_context: self.procedural_context,
218 depth: self.depth + 1,
219 cse_cache: self.cse_cache.clone(),
220 enable_cse: self.enable_cse,
221 subquery_cache: self.subquery_cache.clone(),
222 };
223 f(&evaluator)
224 }
225}