Skip to main content

linkrs_query/executor/expression/evaluation_context/
row_context.rs

1//! Implementation in the context of row expressions
2//!
3//! Provide dedicated context implementations for the Join operation and the evaluation of row-level expressions.
4//! Support accessing row data by column name and column index.
5
6use linkrs_core::Value;
7use std::collections::HashMap;
8
9/// Context of the expression line
10///
11/// A context implementation specifically designed for evaluating expressions on row data
12/// Two access modes are supported:
13/// Access by column name: via the col_name_index mapping
14/// 2. Access by variable name: via the variables mapping
15#[derive(Debug, Clone)]
16pub struct RowExpressionContext {
17    /// Data from the current row
18    row: Vec<Value>,
19    /// Column name index mapping (for quick searching)
20    col_name_index: HashMap<String, usize>,
21    /// Extra variables (used to store intermediate results of calculations)
22    variables: HashMap<String, Value>,
23}
24
25impl RowExpressionContext {
26    /// Create a new line context.
27    pub fn new(row: Vec<Value>, col_names: Vec<String>) -> Self {
28        let col_name_index: HashMap<String, usize> = col_names
29            .into_iter()
30            .enumerate()
31            .map(|(i, name)| (name, i))
32            .collect();
33
34        Self {
35            row,
36            col_name_index,
37            variables: HashMap::new(),
38        }
39    }
40
41    /// Create a context based on the existing data.
42    pub fn from_dataset(row: &[Value], col_names: &[String]) -> Self {
43        Self::new(row.to_vec(), col_names.to_vec())
44    }
45
46    /// Retrieve values based on column names.
47    pub fn get_value_by_name(&self, name: &str) -> Option<&Value> {
48        let result = self
49            .col_name_index
50            .get(name)
51            .and_then(|&idx| self.row.get(idx));
52        result
53    }
54}
55
56impl crate::executor::expression::evaluator::traits::ExpressionContext for RowExpressionContext {
57    fn get_variable(&self, name: &str) -> Option<Value> {
58        // First, check the variable mapping.
59        if let Some(value) = self.variables.get(name) {
60            return Some(value.clone());
61        }
62
63        // Then check the column names (it is possible to access the column names as variables).
64        if let Some(value) = self.get_value_by_name(name) {
65            return Some(value.clone());
66        }
67
68        None
69    }
70
71    fn set_variable(&mut self, name: String, value: Value) {
72        self.variables.insert(name, value);
73    }
74
75    fn get_function(
76        &self,
77        name: &str,
78    ) -> Option<crate::executor::expression::functions::OwnedFunctionRef> {
79        let _ = name;
80        None
81    }
82}