reifydb_engine/expression/
context.rs1use std::sync::LazyLock;
5
6use reifydb_core::{
7 interface::{
8 catalog::property::{ColumnPropertyKind, ColumnSaturationStrategy, DEFAULT_COLUMN_SATURATION_STRATEGY},
9 evaluate::TargetColumn,
10 },
11 value::column::columns::Columns,
12};
13use reifydb_extension::transform::context::TransformContext;
14use reifydb_routine::function::registry::Functions;
15use reifydb_runtime::context::{RuntimeContext, clock::Clock};
16use reifydb_type::{params::Params, value::identity::IdentityId};
17
18use crate::{
19 arena::QueryArena,
20 vm::{stack::SymbolTable, volcano::query::QueryContext},
21};
22
23pub struct EvalContext<'a> {
24 pub target: Option<TargetColumn>,
25 pub columns: Columns,
26 pub row_count: usize,
27 pub take: Option<usize>,
28 pub params: &'a Params,
29 pub symbols: &'a SymbolTable,
30 pub is_aggregate_context: bool,
31 pub functions: &'a Functions,
32 pub runtime_context: &'a RuntimeContext,
33 pub arena: Option<&'a QueryArena>,
34 pub identity: IdentityId,
35}
36
37impl<'a> EvalContext<'a> {
38 pub fn testing() -> EvalContext<'static> {
39 static EMPTY_PARAMS: LazyLock<Params> = LazyLock::new(|| Params::None);
40 static EMPTY_SYMBOL_TABLE: LazyLock<SymbolTable> = LazyLock::new(SymbolTable::new);
41 static EMPTY_FUNCTIONS: LazyLock<Functions> = LazyLock::new(Functions::empty);
42 static DEFAULT_RUNTIME_CONTEXT: LazyLock<RuntimeContext> =
43 LazyLock::new(|| RuntimeContext::with_clock(Clock::Real));
44
45 EvalContext {
46 target: None,
47 columns: Columns::empty(),
48 row_count: 1,
49 take: None,
50 params: &EMPTY_PARAMS,
51 symbols: &EMPTY_SYMBOL_TABLE,
52 is_aggregate_context: false,
53 functions: &EMPTY_FUNCTIONS,
54 runtime_context: &DEFAULT_RUNTIME_CONTEXT,
55 arena: None,
56 identity: IdentityId::root(),
57 }
58 }
59
60 pub fn with_eval(&self, columns: Columns, row_count: usize) -> EvalContext<'a> {
62 EvalContext {
63 target: None,
64 columns,
65 row_count,
66 take: None,
67 params: self.params,
68 symbols: self.symbols,
69 is_aggregate_context: self.is_aggregate_context,
70 functions: self.functions,
71 runtime_context: self.runtime_context,
72 arena: self.arena,
73 identity: self.identity,
74 }
75 }
76
77 pub fn with_eval_empty(&self) -> EvalContext<'a> {
78 self.with_eval(Columns::empty(), 1)
79 }
80
81 pub fn with_eval_join(&self, columns: Columns) -> EvalContext<'a> {
82 let mut ctx = self.with_eval(columns, 1);
83 ctx.take = Some(1);
84 ctx
85 }
86
87 pub fn from_query(ctx: &'a QueryContext) -> Self {
88 EvalContext {
89 target: None,
90 columns: Columns::empty(),
91 row_count: 1,
92 take: None,
93 params: &ctx.params,
94 symbols: &ctx.symbols,
95 is_aggregate_context: false,
96 functions: &ctx.services.functions,
97 runtime_context: &ctx.services.runtime_context,
98 arena: None,
99 identity: ctx.identity,
100 }
101 }
102
103 pub fn from_transform(ctx: &'a TransformContext, stored: &'a QueryContext) -> Self {
104 EvalContext {
105 target: None,
106 columns: Columns::empty(),
107 row_count: 1,
108 take: None,
109 params: ctx.params,
110 symbols: &stored.symbols,
111 is_aggregate_context: false,
112 functions: ctx.functions,
113 runtime_context: ctx.runtime_context,
114 arena: None,
115 identity: stored.identity,
116 }
117 }
118
119 pub(crate) fn saturation_policy(&self) -> ColumnSaturationStrategy {
120 self.target
121 .as_ref()
122 .and_then(|t| {
123 t.properties()
124 .into_iter()
125 .map(|p| {
126 let ColumnPropertyKind::Saturation(policy) = p;
127 policy
128 })
129 .next()
130 })
131 .unwrap_or(DEFAULT_COLUMN_SATURATION_STRATEGY.clone())
132 }
133}
134
135pub struct CompileContext<'a> {
137 pub functions: &'a Functions,
138 pub symbols: &'a SymbolTable,
139}