reifydb_engine/vm/volcano/
variable.rs1use std::sync::Arc;
5
6use reifydb_core::value::column::{columns::Columns, headers::ColumnHeaders};
7use reifydb_rql::expression::VariableExpression;
8use reifydb_transaction::transaction::Transaction;
9
10use crate::{
11 Result,
12 error::EngineError,
13 vm::{
14 stack::Variable,
15 volcano::query::{QueryContext, QueryNode},
16 },
17};
18
19pub(crate) struct VariableNode {
20 variable_expr: VariableExpression,
21 context: Option<Arc<QueryContext>>,
22 executed: bool,
23}
24
25impl VariableNode {
26 pub fn new(variable_expr: VariableExpression) -> Self {
27 Self {
28 variable_expr,
29 context: None,
30 executed: false,
31 }
32 }
33}
34
35impl QueryNode for VariableNode {
36 fn initialize<'a>(&mut self, _rx: &mut Transaction<'a>, ctx: &QueryContext) -> Result<()> {
37 self.context = Some(Arc::new(ctx.clone()));
38 Ok(())
39 }
40
41 fn next<'a>(&mut self, _rx: &mut Transaction<'a>, ctx: &mut QueryContext) -> Result<Option<Columns>> {
42 debug_assert!(self.context.is_some(), "VariableNode::next() called before initialize()");
43
44 if self.executed {
46 return Ok(None);
47 }
48
49 let variable_name = self.variable_expr.name();
50
51 match ctx.symbols.get(variable_name) {
53 Some(Variable::Columns {
54 columns,
55 }) => {
56 self.executed = true;
57 Ok(Some(columns.clone()))
58 }
59 Some(Variable::ForIterator {
60 columns,
61 ..
62 }) => {
63 self.executed = true;
65
66 Ok(Some(columns.clone()))
67 }
68 Some(Variable::Closure(_)) => {
69 Err(EngineError::VariableNotFound {
71 name: variable_name.to_string(),
72 }
73 .into())
74 }
75 None => {
76 Err(EngineError::VariableNotFound {
78 name: variable_name.to_string(),
79 }
80 .into())
81 }
82 }
83 }
84
85 fn headers(&self) -> Option<ColumnHeaders> {
86 None
88 }
89}