use std::sync::LazyLock;
use arrow_array::RecordBatch;
use reifydb_core::{
interface::evaluate::TargetColumn,
value::{
batch::empty_batch,
column::arith::context::{ArithContext, Overflow},
},
};
use reifydb_routine_abi::registry::Routines;
use reifydb_runtime::context::{RuntimeContext, clock::Clock};
use reifydb_value::{params::Params, value::identity::IdentityId};
use crate::stack::SymbolTable;
pub struct EvalContext<'a> {
pub target: Option<TargetColumn>,
pub batch: RecordBatch,
pub row_count: usize,
pub take: Option<usize>,
pub params: &'a Params,
pub symbols: &'a SymbolTable,
pub routines: &'a Routines,
pub runtime_context: &'a RuntimeContext,
pub identity: IdentityId,
}
impl<'a> EvalContext<'a> {
pub fn testing() -> EvalContext<'static> {
static EMPTY_PARAMS: LazyLock<Params> = LazyLock::new(|| Params::None);
static EMPTY_SYMBOL_TABLE: LazyLock<SymbolTable> = LazyLock::new(SymbolTable::new);
static EMPTY_ROUTINES: LazyLock<Routines> = LazyLock::new(Routines::empty);
static DEFAULT_RUNTIME_CONTEXT: LazyLock<RuntimeContext> =
LazyLock::new(|| RuntimeContext::with_clock(Clock::Real));
EvalContext {
target: None,
batch: empty_batch(),
row_count: 1,
take: None,
params: &EMPTY_PARAMS,
symbols: &EMPTY_SYMBOL_TABLE,
routines: &EMPTY_ROUTINES,
runtime_context: &DEFAULT_RUNTIME_CONTEXT,
identity: IdentityId::system(),
}
}
pub fn with_eval(&self, batch: RecordBatch, row_count: usize) -> EvalContext<'a> {
EvalContext {
target: None,
batch,
row_count,
take: None,
params: self.params,
symbols: self.symbols,
routines: self.routines,
runtime_context: self.runtime_context,
identity: self.identity,
}
}
pub fn with_eval_empty(&self) -> EvalContext<'a> {
self.with_eval(empty_batch(), 1)
}
pub fn with_eval_join(&self, batch: RecordBatch) -> EvalContext<'a> {
let mut ctx = self.with_eval(batch, 1);
ctx.take = Some(1);
ctx
}
pub fn arith(&self) -> ArithContext {
ArithContext {
target: self.target.clone(),
overflow: Overflow::Target,
}
}
}