alopex_sql/executor/evaluator/
context.rs

1use crate::executor::{EvaluationError, ExecutorError};
2use crate::storage::SqlValue;
3
4/// Evaluation context holds a borrowed row for zero-copy access.
5pub struct EvalContext<'a> {
6    row: &'a [SqlValue],
7}
8
9impl<'a> EvalContext<'a> {
10    /// Create a new evaluation context for the given row slice.
11    pub fn new(row: &'a [SqlValue]) -> Self {
12        Self { row }
13    }
14
15    /// Get a column value by index.
16    pub fn get(&self, index: usize) -> Result<&'a SqlValue, ExecutorError> {
17        self.row.get(index).ok_or(ExecutorError::Evaluation(
18            EvaluationError::InvalidColumnRef { index },
19        ))
20    }
21}
22
23#[cfg(test)]
24mod tests {
25    use super::*;
26
27    #[test]
28    fn get_existing_column_returns_value() {
29        let row = vec![SqlValue::Integer(1), SqlValue::Text("a".into())];
30        let ctx = EvalContext::new(&row);
31        assert!(matches!(ctx.get(0), Ok(SqlValue::Integer(1))));
32    }
33
34    #[test]
35    fn get_out_of_range_errors() {
36        let row = vec![SqlValue::Integer(1)];
37        let ctx = EvalContext::new(&row);
38        let err = ctx.get(2).unwrap_err();
39        match err {
40            ExecutorError::Evaluation(EvaluationError::InvalidColumnRef { index }) => {
41                assert_eq!(index, 2)
42            }
43            other => panic!("unexpected error {other:?}"),
44        }
45    }
46}