reifydb_engine/evaluate/column/
mod.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use reifydb_core::value::column::Column;
5use reifydb_rql::expression::Expression;
6
7pub(crate) use crate::evaluate::ColumnEvaluationContext;
8use crate::function::{Functions, blob, math, text};
9
10mod access;
11mod alias;
12mod arith;
13mod call;
14pub(crate) mod cast;
15mod column;
16mod compare;
17pub(crate) mod constant;
18mod extend_expr;
19mod if_expr;
20mod logic;
21mod map_expr;
22mod parameter;
23mod prefix;
24mod tuple;
25mod variable;
26
27pub struct StandardColumnEvaluator {
28	functions: Functions,
29}
30
31impl Default for StandardColumnEvaluator {
32	fn default() -> Self {
33		Self {
34			functions: Functions::builder()
35				.register_scalar("math::abs", math::scalar::Abs::new)
36				.register_scalar("math::avg", math::scalar::Avg::new)
37				.register_scalar("math::max", math::scalar::Max::new)
38				.register_scalar("math::min", math::scalar::Min::new)
39				.register_scalar("math::power", math::scalar::Power::new)
40				.register_scalar("math::round", math::scalar::Round::new)
41				.register_scalar("blob::hex", blob::BlobHex::new)
42				.register_scalar("blob::b64", blob::BlobB64::new)
43				.register_scalar("blob::b64url", blob::BlobB64url::new)
44				.register_scalar("blob::utf8", blob::BlobUtf8::new)
45				.register_scalar("text::trim", text::TextTrim::new)
46				.register_scalar("text::upper", text::TextUpper::new)
47				.register_scalar("text::substring", text::TextSubstring::new)
48				.register_scalar("text::length", text::TextLength::new)
49				.build(),
50		}
51	}
52}
53
54impl StandardColumnEvaluator {
55	pub fn evaluate<'a>(
56		&self,
57		ctx: &ColumnEvaluationContext<'a>,
58		expr: &Expression<'a>,
59	) -> crate::Result<Column<'a>> {
60		match expr {
61			Expression::AccessSource(expr) => self.access(ctx, expr),
62			Expression::Alias(expr) => self.alias(ctx, expr),
63			Expression::Add(expr) => self.add(ctx, expr),
64			Expression::Div(expr) => self.div(ctx, expr),
65			Expression::Call(expr) => self.call(ctx, expr),
66			Expression::Cast(expr) => self.cast(ctx, expr),
67			Expression::Column(expr) => self.column(ctx, expr),
68			Expression::Constant(expr) => self.constant(ctx, expr),
69			Expression::GreaterThan(expr) => self.greater_than(ctx, expr),
70			Expression::GreaterThanEqual(expr) => self.greater_than_equal(ctx, expr),
71			Expression::LessThan(expr) => self.less_than(ctx, expr),
72			Expression::LessThanEqual(expr) => self.less_than_equal(ctx, expr),
73			Expression::Equal(expr) => self.equal(ctx, expr),
74			Expression::NotEqual(expr) => self.not_equal(ctx, expr),
75			Expression::Between(expr) => self.between(ctx, expr),
76			Expression::And(expr) => self.and(ctx, expr),
77			Expression::Or(expr) => self.or(ctx, expr),
78			Expression::Xor(expr) => self.xor(ctx, expr),
79			Expression::Rem(expr) => self.rem(ctx, expr),
80			Expression::Mul(expr) => self.mul(ctx, expr),
81			Expression::Prefix(expr) => self.prefix(ctx, expr),
82			Expression::Sub(expr) => self.sub(ctx, expr),
83			Expression::Tuple(expr) => self.tuple(ctx, expr),
84			Expression::Parameter(expr) => self.parameter(ctx, expr),
85			Expression::Variable(expr) => self.variable(ctx, expr),
86			Expression::If(expr) => self.if_expr(ctx, expr),
87			Expression::Map(expr) => self.map_expr(ctx, expr),
88			Expression::Extend(expr) => self.extend_expr(ctx, expr),
89			expr => unimplemented!("{expr:?}"),
90		}
91	}
92}
93
94pub fn evaluate<'a>(ctx: &ColumnEvaluationContext<'a>, expr: &Expression<'a>) -> crate::Result<Column<'a>> {
95	let evaluator = StandardColumnEvaluator {
96		functions: Functions::builder()
97			.register_scalar("math::abs", math::scalar::Abs::new)
98			.register_scalar("math::avg", math::scalar::Avg::new)
99			.register_scalar("math::max", math::scalar::Max::new)
100			.register_scalar("math::min", math::scalar::Min::new)
101			.register_scalar("math::power", math::scalar::Power::new)
102			.register_scalar("math::round", math::scalar::Round::new)
103			.register_scalar("blob::hex", blob::BlobHex::new)
104			.register_scalar("blob::b64", blob::BlobB64::new)
105			.register_scalar("blob::b64url", blob::BlobB64url::new)
106			.register_scalar("blob::utf8", blob::BlobUtf8::new)
107			.register_scalar("text::trim", text::TextTrim::new)
108			.register_scalar("text::upper", text::TextUpper::new)
109			.register_scalar("text::substring", text::TextSubstring::new)
110			.register_scalar("text::length", text::TextLength::new)
111			.build(),
112	};
113
114	// Ensures that result column data type matches the expected target
115	// column type
116	if let Some(ty) = ctx.target.as_ref().map(|c| c.column_type()) {
117		let mut column = evaluator.evaluate(ctx, expr)?;
118		let data = cast::cast_column_data(ctx, &column.data(), ty, &expr.lazy_fragment())?;
119		column = Column {
120			name: column.name,
121			data,
122		};
123		Ok(column)
124	} else {
125		evaluator.evaluate(ctx, expr)
126	}
127}