reifydb_engine/expression/
context.rs1use std::sync::LazyLock;
5
6use reifydb_core::{
7 interface::{
8 catalog::property::{ColumnPropertyKind, ColumnSaturationPolicy, DEFAULT_COLUMN_SATURATION_POLICY},
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;
16use reifydb_type::{params::Params, value::identity::IdentityId};
17
18use crate::{
19 arena::QueryArena,
20 vm::{stack::SymbolTable, volcano::query::QueryContext},
21};
22
23#[derive(Clone, Copy)]
27pub struct EvalSession<'a> {
28 pub params: &'a Params,
29 pub symbols: &'a SymbolTable,
30 pub functions: &'a Functions,
31 pub runtime_context: &'a RuntimeContext,
32 pub arena: Option<&'a QueryArena>,
33 pub identity: IdentityId,
34 pub is_aggregate_context: bool,
35}
36
37impl<'a> EvalSession<'a> {
38 pub fn eval(&self, columns: Columns, row_count: usize) -> EvalContext<'a> {
40 EvalContext {
41 target: None,
42 columns,
43 row_count,
44 take: None,
45 params: self.params,
46 symbols: self.symbols,
47 is_aggregate_context: self.is_aggregate_context,
48 functions: self.functions,
49 runtime_context: self.runtime_context,
50 arena: self.arena,
51 identity: self.identity,
52 }
53 }
54
55 pub fn eval_empty(&self) -> EvalContext<'a> {
57 self.eval(Columns::empty(), 1)
58 }
59
60 pub fn eval_join(&self, columns: Columns) -> EvalContext<'a> {
62 let mut ctx = self.eval(columns, 1);
63 ctx.take = Some(1);
64 ctx
65 }
66
67 pub fn from_transform(ctx: &'a TransformContext, stored: &'a QueryContext) -> Self {
69 Self {
70 params: ctx.params,
71 symbols: &stored.symbols,
72 functions: ctx.functions,
73 runtime_context: ctx.runtime_context,
74 arena: None,
75 identity: stored.identity,
76 is_aggregate_context: false,
77 }
78 }
79
80 pub fn from_query(ctx: &'a QueryContext) -> Self {
82 Self {
83 params: &ctx.params,
84 symbols: &ctx.symbols,
85 functions: &ctx.services.functions,
86 runtime_context: &ctx.services.runtime_context,
87 arena: None,
88 identity: ctx.identity,
89 is_aggregate_context: false,
90 }
91 }
92
93 pub fn testing() -> EvalSession<'static> {
95 static EMPTY_PARAMS: LazyLock<Params> = LazyLock::new(|| Params::None);
96 static EMPTY_SYMBOL_TABLE: LazyLock<SymbolTable> = LazyLock::new(|| SymbolTable::new());
97 static EMPTY_FUNCTIONS: LazyLock<Functions> = LazyLock::new(|| Functions::empty());
98 static DEFAULT_RUNTIME_CONTEXT: LazyLock<RuntimeContext> = LazyLock::new(|| RuntimeContext::default());
99 EvalSession {
100 params: &EMPTY_PARAMS,
101 symbols: &EMPTY_SYMBOL_TABLE,
102 functions: &EMPTY_FUNCTIONS,
103 runtime_context: &DEFAULT_RUNTIME_CONTEXT,
104 arena: None,
105 identity: IdentityId::root(),
106 is_aggregate_context: false,
107 }
108 }
109}
110
111pub struct EvalContext<'a> {
112 pub target: Option<TargetColumn>,
113 pub columns: Columns,
114 pub row_count: usize,
115 pub take: Option<usize>,
116 pub params: &'a Params,
117 pub symbols: &'a SymbolTable,
118 pub is_aggregate_context: bool,
121 pub functions: &'a Functions,
122 pub runtime_context: &'a RuntimeContext,
123 pub arena: Option<&'a QueryArena>,
124 pub identity: IdentityId,
125}
126
127impl<'a> EvalContext<'a> {
128 pub fn testing() -> Self {
129 EvalSession::testing().eval_empty()
130 }
131
132 pub(crate) fn saturation_policy(&self) -> ColumnSaturationPolicy {
133 self.target
134 .as_ref()
135 .and_then(|t| {
136 t.properties().into_iter().find_map(|p| match p {
137 ColumnPropertyKind::Saturation(policy) => Some(policy),
138 })
139 })
140 .unwrap_or(DEFAULT_COLUMN_SATURATION_POLICY.clone())
141 }
142}
143
144pub struct CompileContext<'a> {
146 pub functions: &'a Functions,
147 pub symbols: &'a SymbolTable,
148}