Skip to main content

reifydb_core/expression/
tree_node.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use datafusion_common::{
5	Result,
6	tree_node::{Transformed, TreeNode, TreeNodeIterator, TreeNodeRecursion},
7};
8
9use crate::expression::{
10	AddExpression, AliasExpression, AndExpression, BetweenExpression, CallExpression, CastExpression,
11	ContainsExpression, DivExpression, ElseIfExpression, EqExpression, Expression, ExtendExpression,
12	FieldAccessExpression, GreaterThanEqExpression, GreaterThanExpression, IfExpression, InExpression,
13	IsVariantExpression, LessThanEqExpression, LessThanExpression, ListExpression, MapExpression, MulExpression,
14	NotEqExpression, OrExpression, PrefixExpression, RecordExpression, RemExpression, SubExpression,
15	SumTypeConstructorExpression, TupleExpression, XorExpression,
16};
17
18impl TreeNode for Expression {
19	fn apply_children<'n, F: FnMut(&'n Self) -> Result<TreeNodeRecursion>>(
20		&'n self,
21		f: F,
22	) -> Result<TreeNodeRecursion> {
23		children(self).into_iter().apply_until_stop(f)
24	}
25
26	fn map_children<F: FnMut(Self) -> Result<Transformed<Self>>>(self, f: F) -> Result<Transformed<Self>> {
27		let mut m = Children {
28			f,
29			transformed: false,
30			tnr: TreeNodeRecursion::Continue,
31		};
32		let expr = match self {
33			Expression::AccessSource(_)
34			| Expression::Constant(_)
35			| Expression::Column(_)
36			| Expression::Type(_)
37			| Expression::Parameter(_)
38			| Expression::Variable(_) => return Ok(Transformed::no(self)),
39			Expression::Alias(AliasExpression {
40				alias,
41				expression,
42				fragment,
43			}) => Expression::Alias(AliasExpression {
44				alias,
45				expression: m.boxed(expression)?,
46				fragment,
47			}),
48			Expression::Cast(CastExpression {
49				fragment,
50				expression,
51				to,
52			}) => Expression::Cast(CastExpression {
53				fragment,
54				expression: m.boxed(expression)?,
55				to,
56			}),
57			Expression::Prefix(PrefixExpression {
58				operator,
59				expression,
60				fragment,
61			}) => Expression::Prefix(PrefixExpression {
62				operator,
63				expression: m.boxed(expression)?,
64				fragment,
65			}),
66			Expression::IsVariant(IsVariantExpression {
67				expression,
68				namespace,
69				sumtype_name,
70				variant_name,
71				tag,
72				fragment,
73			}) => Expression::IsVariant(IsVariantExpression {
74				expression: m.boxed(expression)?,
75				namespace,
76				sumtype_name,
77				variant_name,
78				tag,
79				fragment,
80			}),
81			Expression::FieldAccess(FieldAccessExpression {
82				object,
83				field,
84				fragment,
85			}) => Expression::FieldAccess(FieldAccessExpression {
86				object: m.boxed(object)?,
87				field,
88				fragment,
89			}),
90			Expression::Add(e) => Expression::Add(AddExpression {
91				left: m.boxed(e.left)?,
92				right: m.boxed(e.right)?,
93				fragment: e.fragment,
94			}),
95			Expression::Div(e) => Expression::Div(DivExpression {
96				left: m.boxed(e.left)?,
97				right: m.boxed(e.right)?,
98				fragment: e.fragment,
99			}),
100			Expression::Rem(e) => Expression::Rem(RemExpression {
101				left: m.boxed(e.left)?,
102				right: m.boxed(e.right)?,
103				fragment: e.fragment,
104			}),
105			Expression::Mul(e) => Expression::Mul(MulExpression {
106				left: m.boxed(e.left)?,
107				right: m.boxed(e.right)?,
108				fragment: e.fragment,
109			}),
110			Expression::Sub(e) => Expression::Sub(SubExpression {
111				left: m.boxed(e.left)?,
112				right: m.boxed(e.right)?,
113				fragment: e.fragment,
114			}),
115			Expression::GreaterThan(e) => Expression::GreaterThan(GreaterThanExpression {
116				left: m.boxed(e.left)?,
117				right: m.boxed(e.right)?,
118				fragment: e.fragment,
119			}),
120			Expression::GreaterThanEqual(e) => Expression::GreaterThanEqual(GreaterThanEqExpression {
121				left: m.boxed(e.left)?,
122				right: m.boxed(e.right)?,
123				fragment: e.fragment,
124			}),
125			Expression::LessThan(e) => Expression::LessThan(LessThanExpression {
126				left: m.boxed(e.left)?,
127				right: m.boxed(e.right)?,
128				fragment: e.fragment,
129			}),
130			Expression::LessThanEqual(e) => Expression::LessThanEqual(LessThanEqExpression {
131				left: m.boxed(e.left)?,
132				right: m.boxed(e.right)?,
133				fragment: e.fragment,
134			}),
135			Expression::Equal(e) => Expression::Equal(EqExpression {
136				left: m.boxed(e.left)?,
137				right: m.boxed(e.right)?,
138				fragment: e.fragment,
139			}),
140			Expression::NotEqual(e) => Expression::NotEqual(NotEqExpression {
141				left: m.boxed(e.left)?,
142				right: m.boxed(e.right)?,
143				fragment: e.fragment,
144			}),
145			Expression::And(e) => Expression::And(AndExpression {
146				left: m.boxed(e.left)?,
147				right: m.boxed(e.right)?,
148				fragment: e.fragment,
149			}),
150			Expression::Or(e) => Expression::Or(OrExpression {
151				left: m.boxed(e.left)?,
152				right: m.boxed(e.right)?,
153				fragment: e.fragment,
154			}),
155			Expression::Xor(e) => Expression::Xor(XorExpression {
156				left: m.boxed(e.left)?,
157				right: m.boxed(e.right)?,
158				fragment: e.fragment,
159			}),
160			Expression::Between(e) => Expression::Between(BetweenExpression {
161				value: m.boxed(e.value)?,
162				lower: m.boxed(e.lower)?,
163				upper: m.boxed(e.upper)?,
164				fragment: e.fragment,
165			}),
166			Expression::In(e) => Expression::In(InExpression {
167				value: m.boxed(e.value)?,
168				list: m.boxed(e.list)?,
169				negated: e.negated,
170				fragment: e.fragment,
171			}),
172			Expression::Contains(e) => Expression::Contains(ContainsExpression {
173				value: m.boxed(e.value)?,
174				list: m.boxed(e.list)?,
175				fragment: e.fragment,
176			}),
177			Expression::Call(CallExpression {
178				func,
179				args,
180				fragment,
181			}) => Expression::Call(CallExpression {
182				func,
183				args: m.all(args)?,
184				fragment,
185			}),
186			Expression::Tuple(e) => Expression::Tuple(TupleExpression {
187				expressions: m.all(e.expressions)?,
188				fragment: e.fragment,
189			}),
190			Expression::List(e) => Expression::List(ListExpression {
191				expressions: m.all(e.expressions)?,
192				fragment: e.fragment,
193			}),
194			Expression::Map(e) => Expression::Map(MapExpression {
195				expressions: m.all(e.expressions)?,
196				fragment: e.fragment,
197			}),
198			Expression::Extend(e) => Expression::Extend(ExtendExpression {
199				expressions: m.all(e.expressions)?,
200				fragment: e.fragment,
201			}),
202			Expression::Record(RecordExpression {
203				fields,
204				fragment,
205			}) => Expression::Record(RecordExpression {
206				fields: fields
207					.into_iter()
208					.map(|(name, expr)| Ok((name, m.map(expr)?)))
209					.collect::<Result<_>>()?,
210				fragment,
211			}),
212			Expression::SumTypeConstructor(SumTypeConstructorExpression {
213				namespace,
214				sumtype_name,
215				variant_name,
216				columns,
217				fragment,
218			}) => Expression::SumTypeConstructor(SumTypeConstructorExpression {
219				namespace,
220				sumtype_name,
221				variant_name,
222				columns: columns
223					.into_iter()
224					.map(|(name, expr)| Ok((name, m.map(expr)?)))
225					.collect::<Result<_>>()?,
226				fragment,
227			}),
228			Expression::If(IfExpression {
229				condition,
230				then_expr,
231				else_ifs,
232				else_expr,
233				fragment,
234			}) => Expression::If(IfExpression {
235				condition: m.boxed(condition)?,
236				then_expr: m.boxed(then_expr)?,
237				else_ifs: else_ifs
238					.into_iter()
239					.map(|e| {
240						Ok(ElseIfExpression {
241							condition: m.boxed(e.condition)?,
242							then_expr: m.boxed(e.then_expr)?,
243							fragment: e.fragment,
244						})
245					})
246					.collect::<Result<_>>()?,
247				else_expr: else_expr.map(|e| m.boxed(e)).transpose()?,
248				fragment,
249			}),
250		};
251		Ok(Transformed::new(expr, m.transformed, m.tnr))
252	}
253}
254
255struct Children<F> {
256	f: F,
257	transformed: bool,
258	tnr: TreeNodeRecursion,
259}
260
261impl<F: FnMut(Expression) -> Result<Transformed<Expression>>> Children<F> {
262	fn map(&mut self, expr: Expression) -> Result<Expression> {
263		if self.tnr == TreeNodeRecursion::Stop {
264			return Ok(expr);
265		}
266		let result = (self.f)(expr)?;
267		self.tnr = result.tnr;
268		self.transformed |= result.transformed;
269		Ok(result.data)
270	}
271
272	fn boxed(&mut self, expr: Box<Expression>) -> Result<Box<Expression>> {
273		Ok(Box::new(self.map(*expr)?))
274	}
275
276	fn all(&mut self, exprs: Vec<Expression>) -> Result<Vec<Expression>> {
277		exprs.into_iter().map(|e| self.map(e)).collect()
278	}
279}
280
281fn children(expr: &Expression) -> Vec<&Expression> {
282	match expr {
283		Expression::AccessSource(_)
284		| Expression::Constant(_)
285		| Expression::Column(_)
286		| Expression::Type(_)
287		| Expression::Parameter(_)
288		| Expression::Variable(_) => vec![],
289		Expression::Alias(e) => vec![&e.expression],
290		Expression::Cast(e) => vec![&e.expression],
291		Expression::Prefix(e) => vec![&e.expression],
292		Expression::IsVariant(e) => vec![&e.expression],
293		Expression::FieldAccess(e) => vec![&e.object],
294		Expression::Add(e) => vec![&e.left, &e.right],
295		Expression::Div(e) => vec![&e.left, &e.right],
296		Expression::Rem(e) => vec![&e.left, &e.right],
297		Expression::Mul(e) => vec![&e.left, &e.right],
298		Expression::Sub(e) => vec![&e.left, &e.right],
299		Expression::GreaterThan(e) => vec![&e.left, &e.right],
300		Expression::GreaterThanEqual(e) => vec![&e.left, &e.right],
301		Expression::LessThan(e) => vec![&e.left, &e.right],
302		Expression::LessThanEqual(e) => vec![&e.left, &e.right],
303		Expression::Equal(e) => vec![&e.left, &e.right],
304		Expression::NotEqual(e) => vec![&e.left, &e.right],
305		Expression::And(e) => vec![&e.left, &e.right],
306		Expression::Or(e) => vec![&e.left, &e.right],
307		Expression::Xor(e) => vec![&e.left, &e.right],
308		Expression::Between(e) => vec![&e.value, &e.lower, &e.upper],
309		Expression::In(e) => vec![&e.value, &e.list],
310		Expression::Contains(e) => vec![&e.value, &e.list],
311		Expression::Call(e) => e.args.iter().collect(),
312		Expression::Tuple(e) => e.expressions.iter().collect(),
313		Expression::List(e) => e.expressions.iter().collect(),
314		Expression::Map(e) => e.expressions.iter().collect(),
315		Expression::Extend(e) => e.expressions.iter().collect(),
316		Expression::Record(e) => e.fields.iter().map(|(_, expr)| expr).collect(),
317		Expression::SumTypeConstructor(e) => e.columns.iter().map(|(_, expr)| expr).collect(),
318		Expression::If(e) => {
319			let mut out: Vec<&Expression> = vec![&e.condition, &e.then_expr];
320			for else_if in &e.else_ifs {
321				out.push(&else_if.condition);
322				out.push(&else_if.then_expr);
323			}
324			if let Some(else_expr) = &e.else_expr {
325				out.push(else_expr);
326			}
327			out
328		}
329	}
330}