reifydb-evaluate 0.9.1

Runtime expression evaluator and variable environment for ReifyDB
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2026 ReifyDB

use std::sync::LazyLock;

use reifydb_core::{
	interface::{catalog::property::ColumnSaturationStrategy, evaluate::TargetColumn},
	value::column::{cast::convert::TargetConvert, columns::Columns},
};
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 columns: Columns,
	pub row_count: usize,
	pub take: Option<usize>,
	pub params: &'a Params,
	pub symbols: &'a SymbolTable,
	pub is_aggregate_context: bool,
	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,
			columns: Columns::empty(),
			row_count: 1,
			take: None,
			params: &EMPTY_PARAMS,
			symbols: &EMPTY_SYMBOL_TABLE,
			is_aggregate_context: false,
			routines: &EMPTY_ROUTINES,
			runtime_context: &DEFAULT_RUNTIME_CONTEXT,
			identity: IdentityId::system(),
		}
	}

	pub fn with_eval(&self, columns: Columns, row_count: usize) -> EvalContext<'a> {
		EvalContext {
			target: None,
			columns,
			row_count,
			take: None,
			params: self.params,
			symbols: self.symbols,
			is_aggregate_context: self.is_aggregate_context,
			routines: self.routines,
			runtime_context: self.runtime_context,
			identity: self.identity,
		}
	}

	pub fn with_eval_empty(&self) -> EvalContext<'a> {
		self.with_eval(Columns::empty(), 1)
	}

	pub fn with_eval_join(&self, columns: Columns) -> EvalContext<'a> {
		let mut ctx = self.with_eval(columns, 1);
		ctx.take = Some(1);
		ctx
	}

	pub(crate) fn saturation_policy(&self) -> ColumnSaturationStrategy {
		TargetConvert {
			target: self.target.as_ref(),
		}
		.saturation_policy()
	}
}

pub struct CompileContext<'a> {
	pub symbols: &'a SymbolTable,
}