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