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