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::routine::registry::Routines;
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 routines: &'a Routines,
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_ROUTINES: LazyLock<Routines> = LazyLock::new(Routines::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 routines: &EMPTY_ROUTINES,
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> {
61 EvalContext {
62 target: None,
63 columns,
64 row_count,
65 take: None,
66 params: self.params,
67 symbols: self.symbols,
68 is_aggregate_context: self.is_aggregate_context,
69 routines: self.routines,
70 runtime_context: self.runtime_context,
71 arena: self.arena,
72 identity: self.identity,
73 }
74 }
75
76 pub fn with_eval_empty(&self) -> EvalContext<'a> {
77 self.with_eval(Columns::empty(), 1)
78 }
79
80 pub fn with_eval_join(&self, columns: Columns) -> EvalContext<'a> {
81 let mut ctx = self.with_eval(columns, 1);
82 ctx.take = Some(1);
83 ctx
84 }
85
86 pub fn from_query(ctx: &'a QueryContext) -> Self {
87 EvalContext {
88 target: None,
89 columns: Columns::empty(),
90 row_count: 1,
91 take: None,
92 params: &ctx.params,
93 symbols: &ctx.symbols,
94 is_aggregate_context: false,
95 routines: &ctx.services.routines,
96 runtime_context: &ctx.services.runtime_context,
97 arena: None,
98 identity: ctx.identity,
99 }
100 }
101
102 pub fn from_transform(ctx: &'a TransformContext, stored: &'a QueryContext) -> Self {
103 EvalContext {
104 target: None,
105 columns: Columns::empty(),
106 row_count: 1,
107 take: None,
108 params: ctx.params,
109 symbols: &stored.symbols,
110 is_aggregate_context: false,
111 routines: &stored.services.routines,
112 runtime_context: ctx.runtime_context,
113 arena: None,
114 identity: stored.identity,
115 }
116 }
117
118 pub(crate) fn saturation_policy(&self) -> ColumnSaturationStrategy {
119 self.target
120 .as_ref()
121 .and_then(|t| {
122 t.properties()
123 .into_iter()
124 .map(|p| {
125 let ColumnPropertyKind::Saturation(policy) = p;
126 policy
127 })
128 .next()
129 })
130 .unwrap_or(DEFAULT_COLUMN_SATURATION_STRATEGY.clone())
131 }
132}
133
134pub struct CompileContext<'a> {
135 pub symbols: &'a SymbolTable,
136}