Skip to main content

reifydb_core/expression/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4pub mod fragment;
5pub mod name;
6mod tree_node;
7
8use std::{
9	fmt,
10	fmt::{Display, Formatter},
11	sync::Arc,
12};
13
14use reifydb_value::{
15	fragment::Fragment,
16	value::{constraint::Constraint, value_type::ValueType},
17};
18use serde::{Deserialize, Serialize};
19
20use crate::interface::identifier::{ColumnIdentifier, ColumnObject};
21
22#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
23pub struct AliasExpression {
24	pub alias: IdentExpression,
25	pub expression: Box<Expression>,
26	pub fragment: Fragment,
27}
28
29impl Display for AliasExpression {
30	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
31		Display::fmt(&self.alias, f)
32	}
33}
34
35#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
36pub enum Expression {
37	AccessSource(AccessObjectExpression),
38
39	Alias(AliasExpression),
40
41	Cast(CastExpression),
42
43	Constant(ConstantExpression),
44
45	Column(ColumnExpression),
46
47	Add(AddExpression),
48
49	Div(DivExpression),
50
51	Call(CallExpression),
52
53	Rem(RemExpression),
54
55	Mul(MulExpression),
56
57	Sub(SubExpression),
58
59	Tuple(TupleExpression),
60
61	List(ListExpression),
62
63	Record(RecordExpression),
64
65	Prefix(PrefixExpression),
66
67	GreaterThan(GreaterThanExpression),
68
69	GreaterThanEqual(GreaterThanEqExpression),
70
71	LessThan(LessThanExpression),
72
73	LessThanEqual(LessThanEqExpression),
74
75	Equal(EqExpression),
76
77	NotEqual(NotEqExpression),
78
79	Between(BetweenExpression),
80
81	And(AndExpression),
82
83	Or(OrExpression),
84
85	Xor(XorExpression),
86
87	In(InExpression),
88
89	Contains(ContainsExpression),
90
91	Type(TypeExpression),
92
93	Parameter(ParameterExpression),
94	Variable(VariableExpression),
95
96	If(IfExpression),
97	Map(MapExpression),
98	Extend(ExtendExpression),
99	SumTypeConstructor(SumTypeConstructorExpression),
100	IsVariant(IsVariantExpression),
101	FieldAccess(FieldAccessExpression),
102}
103
104#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
105pub struct AccessObjectExpression {
106	pub column: ColumnIdentifier,
107}
108
109impl AccessObjectExpression {
110	pub fn full_fragment_owned(&self) -> Fragment {
111		match &self.column.object {
112			ColumnObject::Qualified {
113				name,
114				..
115			} => Fragment::merge_all([name.clone(), self.column.name.clone()]),
116			ColumnObject::Alias(alias) => Fragment::merge_all([alias.clone(), self.column.name.clone()]),
117		}
118	}
119}
120
121#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
122pub enum ConstantExpression {
123	None {
124		fragment: Fragment,
125	},
126	Bool {
127		fragment: Fragment,
128	},
129
130	Number {
131		fragment: Fragment,
132	},
133
134	Text {
135		fragment: Fragment,
136	},
137
138	Temporal {
139		fragment: Fragment,
140	},
141
142	Duration {
143		fragment: Fragment,
144	},
145}
146
147impl Display for ConstantExpression {
148	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
149		match self {
150			ConstantExpression::None {
151				..
152			} => write!(f, "none"),
153			ConstantExpression::Bool {
154				fragment,
155			} => write!(f, "{}", fragment.text()),
156			ConstantExpression::Number {
157				fragment,
158			} => write!(f, "{}", fragment.text()),
159			ConstantExpression::Text {
160				fragment,
161			} => write!(f, "\"{}\"", fragment.text()),
162			ConstantExpression::Temporal {
163				fragment,
164			} => write!(f, "{}", fragment.text()),
165			ConstantExpression::Duration {
166				fragment,
167			} => write!(f, "{}", fragment.text()),
168		}
169	}
170}
171
172impl ConstantExpression {
173	pub fn infer_type(&self) -> ValueType {
174		match self {
175			ConstantExpression::None {
176				..
177			} => ValueType::Any,
178			ConstantExpression::Bool {
179				..
180			} => ValueType::Boolean,
181			ConstantExpression::Number {
182				..
183			} => ValueType::Int4,
184			ConstantExpression::Text {
185				..
186			} => ValueType::Utf8,
187			ConstantExpression::Temporal {
188				..
189			} => ValueType::DateTime,
190			ConstantExpression::Duration {
191				..
192			} => ValueType::Duration,
193		}
194	}
195}
196
197impl Expression {
198	pub fn infer_type(&self) -> Option<ValueType> {
199		match self {
200			Expression::Constant(c) => Some(c.infer_type()),
201			_ => None,
202		}
203	}
204}
205
206#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
207pub struct CastExpression {
208	pub fragment: Fragment,
209	pub expression: Box<Expression>,
210	pub to: TypeExpression,
211}
212
213impl CastExpression {
214	pub fn full_fragment_owned(&self) -> Fragment {
215		Fragment::merge_all([
216			self.fragment.clone(),
217			self.expression.full_fragment_owned(),
218			self.to.full_fragment_owned(),
219		])
220	}
221
222	pub fn lazy_fragment(&self) -> impl Fn() -> Fragment {
223		move || self.full_fragment_owned()
224	}
225}
226
227#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
228pub struct TypeExpression {
229	pub fragment: Fragment,
230	pub ty: ValueType,
231	pub constraint: Option<Constraint>,
232}
233
234impl TypeExpression {
235	pub fn full_fragment_owned(&self) -> Fragment {
236		self.fragment.clone()
237	}
238
239	pub fn lazy_fragment(&self) -> impl Fn() -> Fragment {
240		move || self.full_fragment_owned()
241	}
242}
243
244#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
245pub struct AddExpression {
246	pub left: Box<Expression>,
247	pub right: Box<Expression>,
248	pub fragment: Fragment,
249}
250
251#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
252pub struct DivExpression {
253	pub left: Box<Expression>,
254	pub right: Box<Expression>,
255	pub fragment: Fragment,
256}
257
258#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
259pub struct SubExpression {
260	pub left: Box<Expression>,
261	pub right: Box<Expression>,
262	pub fragment: Fragment,
263}
264
265#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
266pub struct RemExpression {
267	pub left: Box<Expression>,
268	pub right: Box<Expression>,
269	pub fragment: Fragment,
270}
271
272#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
273pub struct MulExpression {
274	pub left: Box<Expression>,
275	pub right: Box<Expression>,
276	pub fragment: Fragment,
277}
278
279#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
280pub struct GreaterThanExpression {
281	pub left: Box<Expression>,
282	pub right: Box<Expression>,
283	pub fragment: Fragment,
284}
285
286impl GreaterThanExpression {
287	pub fn full_fragment_owned(&self) -> Fragment {
288		Fragment::merge_all([
289			self.left.full_fragment_owned(),
290			self.fragment.clone(),
291			self.right.full_fragment_owned(),
292		])
293	}
294}
295
296#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
297pub struct GreaterThanEqExpression {
298	pub left: Box<Expression>,
299	pub right: Box<Expression>,
300	pub fragment: Fragment,
301}
302
303impl GreaterThanEqExpression {
304	pub fn full_fragment_owned(&self) -> Fragment {
305		Fragment::merge_all([
306			self.left.full_fragment_owned(),
307			self.fragment.clone(),
308			self.right.full_fragment_owned(),
309		])
310	}
311}
312
313#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
314pub struct LessThanExpression {
315	pub left: Box<Expression>,
316	pub right: Box<Expression>,
317	pub fragment: Fragment,
318}
319
320impl LessThanExpression {
321	pub fn full_fragment_owned(&self) -> Fragment {
322		Fragment::merge_all([
323			self.left.full_fragment_owned(),
324			self.fragment.clone(),
325			self.right.full_fragment_owned(),
326		])
327	}
328}
329
330#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
331pub struct LessThanEqExpression {
332	pub left: Box<Expression>,
333	pub right: Box<Expression>,
334	pub fragment: Fragment,
335}
336
337impl LessThanEqExpression {
338	pub fn full_fragment_owned(&self) -> Fragment {
339		Fragment::merge_all([
340			self.left.full_fragment_owned(),
341			self.fragment.clone(),
342			self.right.full_fragment_owned(),
343		])
344	}
345}
346
347#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
348pub struct EqExpression {
349	pub left: Box<Expression>,
350	pub right: Box<Expression>,
351	pub fragment: Fragment,
352}
353
354impl EqExpression {
355	pub fn full_fragment_owned(&self) -> Fragment {
356		Fragment::merge_all([
357			self.left.full_fragment_owned(),
358			self.fragment.clone(),
359			self.right.full_fragment_owned(),
360		])
361	}
362}
363
364#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
365pub struct NotEqExpression {
366	pub left: Box<Expression>,
367	pub right: Box<Expression>,
368	pub fragment: Fragment,
369}
370
371impl NotEqExpression {
372	pub fn full_fragment_owned(&self) -> Fragment {
373		Fragment::merge_all([
374			self.left.full_fragment_owned(),
375			self.fragment.clone(),
376			self.right.full_fragment_owned(),
377		])
378	}
379}
380
381#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
382pub struct BetweenExpression {
383	pub value: Box<Expression>,
384	pub lower: Box<Expression>,
385	pub upper: Box<Expression>,
386	pub fragment: Fragment,
387}
388
389impl BetweenExpression {
390	pub fn full_fragment_owned(&self) -> Fragment {
391		Fragment::merge_all([
392			self.value.full_fragment_owned(),
393			self.fragment.clone(),
394			self.lower.full_fragment_owned(),
395			self.upper.full_fragment_owned(),
396		])
397	}
398}
399
400#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
401pub struct AndExpression {
402	pub left: Box<Expression>,
403	pub right: Box<Expression>,
404	pub fragment: Fragment,
405}
406
407impl AndExpression {
408	pub fn full_fragment_owned(&self) -> Fragment {
409		Fragment::merge_all([
410			self.left.full_fragment_owned(),
411			self.fragment.clone(),
412			self.right.full_fragment_owned(),
413		])
414	}
415}
416
417#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
418pub struct OrExpression {
419	pub left: Box<Expression>,
420	pub right: Box<Expression>,
421	pub fragment: Fragment,
422}
423
424impl OrExpression {
425	pub fn full_fragment_owned(&self) -> Fragment {
426		Fragment::merge_all([
427			self.left.full_fragment_owned(),
428			self.fragment.clone(),
429			self.right.full_fragment_owned(),
430		])
431	}
432}
433
434#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
435pub struct XorExpression {
436	pub left: Box<Expression>,
437	pub right: Box<Expression>,
438	pub fragment: Fragment,
439}
440
441impl XorExpression {
442	pub fn full_fragment_owned(&self) -> Fragment {
443		Fragment::merge_all([
444			self.left.full_fragment_owned(),
445			self.fragment.clone(),
446			self.right.full_fragment_owned(),
447		])
448	}
449}
450
451#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
452pub struct InExpression {
453	pub value: Box<Expression>,
454	pub list: Box<Expression>,
455	pub negated: bool,
456	pub fragment: Fragment,
457}
458
459impl InExpression {
460	pub fn full_fragment_owned(&self) -> Fragment {
461		Fragment::merge_all([
462			self.value.full_fragment_owned(),
463			self.fragment.clone(),
464			self.list.full_fragment_owned(),
465		])
466	}
467}
468
469#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
470pub struct ContainsExpression {
471	pub value: Box<Expression>,
472	pub list: Box<Expression>,
473	pub fragment: Fragment,
474}
475
476impl ContainsExpression {
477	pub fn full_fragment_owned(&self) -> Fragment {
478		Fragment::merge_all([
479			self.value.full_fragment_owned(),
480			self.fragment.clone(),
481			self.list.full_fragment_owned(),
482		])
483	}
484}
485
486#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
487pub struct ColumnExpression(pub ColumnIdentifier);
488
489impl ColumnExpression {
490	pub fn full_fragment_owned(&self) -> Fragment {
491		self.0.name.clone()
492	}
493
494	pub fn column(&self) -> &ColumnIdentifier {
495		&self.0
496	}
497}
498
499impl Display for Expression {
500	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
501		match self {
502			Expression::AccessSource(AccessObjectExpression {
503				column,
504			}) => match &column.object {
505				ColumnObject::Qualified {
506					name,
507					..
508				} => {
509					write!(f, "{}.{}", name.text(), column.name.text())
510				}
511				ColumnObject::Alias(alias) => {
512					write!(f, "{}.{}", alias.text(), column.name.text())
513				}
514			},
515			Expression::Alias(AliasExpression {
516				alias,
517				expression,
518				..
519			}) => {
520				write!(f, "{} as {}", expression, alias)
521			}
522			Expression::Cast(CastExpression {
523				expression: expr,
524				..
525			}) => write!(f, "{}", expr),
526			Expression::Constant(fragment) => {
527				write!(f, "Constant({})", fragment)
528			}
529			Expression::Column(ColumnExpression(column)) => {
530				write!(f, "{}", column.name.text())
531			}
532			Expression::Add(AddExpression {
533				left,
534				right,
535				..
536			}) => {
537				write!(f, "({} + {})", left, right)
538			}
539			Expression::Div(DivExpression {
540				left,
541				right,
542				..
543			}) => {
544				write!(f, "({} / {})", left, right)
545			}
546			Expression::Call(call) => write!(f, "{}", call),
547			Expression::Rem(RemExpression {
548				left,
549				right,
550				..
551			}) => {
552				write!(f, "({} % {})", left, right)
553			}
554			Expression::Mul(MulExpression {
555				left,
556				right,
557				..
558			}) => {
559				write!(f, "({} * {})", left, right)
560			}
561			Expression::Sub(SubExpression {
562				left,
563				right,
564				..
565			}) => {
566				write!(f, "({} - {})", left, right)
567			}
568			Expression::Tuple(tuple) => write!(f, "({})", tuple),
569			Expression::List(list) => write!(f, "{}", list),
570			Expression::Record(record) => write!(f, "{}", record),
571			Expression::Prefix(prefix) => write!(f, "{}", prefix),
572			Expression::GreaterThan(GreaterThanExpression {
573				left,
574				right,
575				..
576			}) => {
577				write!(f, "({} > {})", left, right)
578			}
579			Expression::GreaterThanEqual(GreaterThanEqExpression {
580				left,
581				right,
582				..
583			}) => {
584				write!(f, "({} >= {})", left, right)
585			}
586			Expression::LessThan(LessThanExpression {
587				left,
588				right,
589				..
590			}) => {
591				write!(f, "({} < {})", left, right)
592			}
593			Expression::LessThanEqual(LessThanEqExpression {
594				left,
595				right,
596				..
597			}) => {
598				write!(f, "({} <= {})", left, right)
599			}
600			Expression::Equal(EqExpression {
601				left,
602				right,
603				..
604			}) => {
605				write!(f, "({} == {})", left, right)
606			}
607			Expression::NotEqual(NotEqExpression {
608				left,
609				right,
610				..
611			}) => {
612				write!(f, "({} != {})", left, right)
613			}
614			Expression::Between(BetweenExpression {
615				value,
616				lower,
617				upper,
618				..
619			}) => {
620				write!(f, "({} BETWEEN {} AND {})", value, lower, upper)
621			}
622			Expression::And(AndExpression {
623				left,
624				right,
625				..
626			}) => {
627				write!(f, "({} and {})", left, right)
628			}
629			Expression::Or(OrExpression {
630				left,
631				right,
632				..
633			}) => {
634				write!(f, "({} or {})", left, right)
635			}
636			Expression::Xor(XorExpression {
637				left,
638				right,
639				..
640			}) => {
641				write!(f, "({} xor {})", left, right)
642			}
643			Expression::In(InExpression {
644				value,
645				list,
646				negated,
647				..
648			}) => {
649				if *negated {
650					write!(f, "({} NOT IN {})", value, list)
651				} else {
652					write!(f, "({} IN {})", value, list)
653				}
654			}
655			Expression::Contains(ContainsExpression {
656				value,
657				list,
658				..
659			}) => {
660				write!(f, "({} CONTAINS {})", value, list)
661			}
662			Expression::Type(TypeExpression {
663				fragment,
664				..
665			}) => write!(f, "{}", fragment.text()),
666			Expression::Parameter(param) => match param {
667				ParameterExpression::Positional {
668					fragment,
669					..
670				} => write!(f, "{}", fragment.text()),
671				ParameterExpression::Named {
672					fragment,
673				} => write!(f, "{}", fragment.text()),
674			},
675			Expression::Variable(var) => write!(f, "{}", var.fragment.text()),
676			Expression::If(if_expr) => write!(f, "{}", if_expr),
677			Expression::Map(map_expr) => write!(
678				f,
679				"MAP{{ {} }}",
680				map_expr.expressions
681					.iter()
682					.map(|expr| format!("{}", expr))
683					.collect::<Vec<_>>()
684					.join(", ")
685			),
686			Expression::Extend(extend_expr) => write!(
687				f,
688				"EXTEND{{ {} }}",
689				extend_expr
690					.expressions
691					.iter()
692					.map(|expr| format!("{}", expr))
693					.collect::<Vec<_>>()
694					.join(", ")
695			),
696			Expression::SumTypeConstructor(ctor) => write!(
697				f,
698				"{}::{}{{ {} }}",
699				ctor.sumtype_name.text(),
700				ctor.variant_name.text(),
701				ctor.columns
702					.iter()
703					.map(|(name, expr)| format!("{}: {}", name.text(), expr))
704					.collect::<Vec<_>>()
705					.join(", ")
706			),
707			Expression::IsVariant(e) => write!(f, "({} IS {})", e.expression, e.variant_name.text()),
708			Expression::FieldAccess(field_access) => write!(f, "{}", field_access),
709		}
710	}
711}
712
713#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
714pub struct CallExpression {
715	pub func: IdentExpression,
716	pub args: Vec<Expression>,
717	pub fragment: Fragment,
718}
719
720impl CallExpression {
721	pub fn full_fragment_owned(&self) -> Fragment {
722		Fragment::Statement {
723			column: self.func.0.column(),
724			line: self.func.0.line(),
725			text: Arc::from(format!(
726				"{}({})",
727				self.func.0.text(),
728				self.args
729					.iter()
730					.map(|arg| arg.full_fragment_owned().text().to_string())
731					.collect::<Vec<_>>()
732					.join(",")
733			)),
734		}
735	}
736}
737
738impl Display for CallExpression {
739	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
740		let args = self.args.iter().map(|arg| format!("{}", arg)).collect::<Vec<_>>().join(", ");
741		write!(f, "{}({})", self.func, args)
742	}
743}
744
745#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
746pub struct IdentExpression(pub Fragment);
747
748#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
749pub enum ParameterExpression {
750	Positional {
751		fragment: Fragment,
752	},
753	Named {
754		fragment: Fragment,
755	},
756}
757
758impl ParameterExpression {
759	pub fn position(&self) -> Option<u32> {
760		match self {
761			ParameterExpression::Positional {
762				fragment,
763			} => fragment.text()[1..].parse().ok(),
764			ParameterExpression::Named {
765				..
766			} => None,
767		}
768	}
769
770	pub fn name(&self) -> Option<&str> {
771		match self {
772			ParameterExpression::Named {
773				fragment,
774			} => Some(&fragment.text()[1..]),
775			ParameterExpression::Positional {
776				..
777			} => None,
778		}
779	}
780}
781
782#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
783pub struct VariableExpression {
784	pub fragment: Fragment,
785}
786
787impl VariableExpression {
788	pub fn name(&self) -> &str {
789		let text = self.fragment.text();
790		text.strip_prefix('$').unwrap_or(text)
791	}
792}
793
794#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
795pub struct IfExpression {
796	pub condition: Box<Expression>,
797	pub then_expr: Box<Expression>,
798	pub else_ifs: Vec<ElseIfExpression>,
799	pub else_expr: Option<Box<Expression>>,
800	pub fragment: Fragment,
801}
802
803#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
804pub struct ElseIfExpression {
805	pub condition: Box<Expression>,
806	pub then_expr: Box<Expression>,
807	pub fragment: Fragment,
808}
809
810impl IfExpression {
811	pub fn full_fragment_owned(&self) -> Fragment {
812		self.fragment.clone()
813	}
814
815	pub fn lazy_fragment(&self) -> impl Fn() -> Fragment {
816		move || self.full_fragment_owned()
817	}
818}
819
820impl Display for IfExpression {
821	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
822		write!(f, "if {} {{ {} }}", self.condition, self.then_expr)?;
823
824		for else_if in &self.else_ifs {
825			write!(f, " else if {} {{ {} }}", else_if.condition, else_if.then_expr)?;
826		}
827
828		if let Some(else_expr) = &self.else_expr {
829			write!(f, " else {{ {} }}", else_expr)?;
830		}
831
832		Ok(())
833	}
834}
835
836impl IdentExpression {
837	pub fn name(&self) -> &str {
838		self.0.text()
839	}
840}
841
842impl Display for IdentExpression {
843	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
844		write!(f, "{}", self.0.text())
845	}
846}
847
848#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
849pub enum PrefixOperator {
850	Minus(Fragment),
851	Plus(Fragment),
852	Not(Fragment),
853}
854
855impl PrefixOperator {
856	pub fn full_fragment_owned(&self) -> Fragment {
857		match self {
858			PrefixOperator::Minus(fragment) => fragment.clone(),
859			PrefixOperator::Plus(fragment) => fragment.clone(),
860			PrefixOperator::Not(fragment) => fragment.clone(),
861		}
862	}
863}
864
865impl Display for PrefixOperator {
866	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
867		match self {
868			PrefixOperator::Minus(_) => write!(f, "-"),
869			PrefixOperator::Plus(_) => write!(f, "+"),
870			PrefixOperator::Not(_) => write!(f, "not"),
871		}
872	}
873}
874
875#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
876pub struct PrefixExpression {
877	pub operator: PrefixOperator,
878	pub expression: Box<Expression>,
879	pub fragment: Fragment,
880}
881
882impl PrefixExpression {
883	pub fn full_fragment_owned(&self) -> Fragment {
884		Fragment::merge_all([self.operator.full_fragment_owned(), self.expression.full_fragment_owned()])
885	}
886}
887
888impl Display for PrefixExpression {
889	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
890		write!(f, "({}{})", self.operator, self.expression)
891	}
892}
893
894#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
895pub struct TupleExpression {
896	pub expressions: Vec<Expression>,
897	pub fragment: Fragment,
898}
899
900impl Display for TupleExpression {
901	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
902		let items = self.expressions.iter().map(|e| format!("{}", e)).collect::<Vec<_>>().join(", ");
903		write!(f, "({})", items)
904	}
905}
906
907#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
908pub struct ListExpression {
909	pub expressions: Vec<Expression>,
910	pub fragment: Fragment,
911}
912
913impl Display for ListExpression {
914	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
915		let items = self.expressions.iter().map(|e| format!("{}", e)).collect::<Vec<_>>().join(", ");
916		write!(f, "[{}]", items)
917	}
918}
919
920#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
921pub struct RecordExpression {
922	pub fields: Vec<(Fragment, Expression)>,
923	pub fragment: Fragment,
924}
925
926impl Display for RecordExpression {
927	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
928		let items = self
929			.fields
930			.iter()
931			.map(|(name, e)| format!("{}: {}", name.text(), e))
932			.collect::<Vec<_>>()
933			.join(", ");
934		write!(f, "{{{}}}", items)
935	}
936}
937
938#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
939pub struct MapExpression {
940	pub expressions: Vec<Expression>,
941	pub fragment: Fragment,
942}
943
944#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
945pub struct ExtendExpression {
946	pub expressions: Vec<Expression>,
947	pub fragment: Fragment,
948}
949
950#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
951pub struct SumTypeConstructorExpression {
952	pub namespace: Fragment,
953	pub sumtype_name: Fragment,
954	pub variant_name: Fragment,
955	pub columns: Vec<(Fragment, Expression)>,
956	pub fragment: Fragment,
957}
958
959#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
960pub struct IsVariantExpression {
961	pub expression: Box<Expression>,
962	pub namespace: Option<Fragment>,
963	pub sumtype_name: Fragment,
964	pub variant_name: Fragment,
965	pub tag: Option<u8>,
966	pub fragment: Fragment,
967}
968
969#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
970pub struct FieldAccessExpression {
971	pub object: Box<Expression>,
972	pub field: Fragment,
973	pub fragment: Fragment,
974}
975
976impl FieldAccessExpression {
977	pub fn full_fragment_owned(&self) -> Fragment {
978		Fragment::merge_all([self.object.full_fragment_owned(), self.fragment.clone(), self.field.clone()])
979	}
980}
981
982impl Display for FieldAccessExpression {
983	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
984		write!(f, "{}.{}", self.object, self.field.text())
985	}
986}
987
988pub fn extract_variable_names(expr: &Expression) -> Vec<String> {
989	let mut names = Vec::new();
990	collect_variable_names(expr, &mut names);
991	names
992}
993
994fn collect_variable_names(expr: &Expression, names: &mut Vec<String>) {
995	match expr {
996		Expression::Variable(v) => {
997			let name = v.name().to_string();
998			if !names.contains(&name) {
999				names.push(name);
1000			}
1001		}
1002		Expression::Add(e) => {
1003			collect_variable_names(&e.left, names);
1004			collect_variable_names(&e.right, names);
1005		}
1006		Expression::Sub(e) => {
1007			collect_variable_names(&e.left, names);
1008			collect_variable_names(&e.right, names);
1009		}
1010		Expression::Mul(e) => {
1011			collect_variable_names(&e.left, names);
1012			collect_variable_names(&e.right, names);
1013		}
1014		Expression::Div(e) => {
1015			collect_variable_names(&e.left, names);
1016			collect_variable_names(&e.right, names);
1017		}
1018		Expression::Rem(e) => {
1019			collect_variable_names(&e.left, names);
1020			collect_variable_names(&e.right, names);
1021		}
1022		Expression::GreaterThan(e) => {
1023			collect_variable_names(&e.left, names);
1024			collect_variable_names(&e.right, names);
1025		}
1026		Expression::GreaterThanEqual(e) => {
1027			collect_variable_names(&e.left, names);
1028			collect_variable_names(&e.right, names);
1029		}
1030		Expression::LessThan(e) => {
1031			collect_variable_names(&e.left, names);
1032			collect_variable_names(&e.right, names);
1033		}
1034		Expression::LessThanEqual(e) => {
1035			collect_variable_names(&e.left, names);
1036			collect_variable_names(&e.right, names);
1037		}
1038		Expression::Equal(e) => {
1039			collect_variable_names(&e.left, names);
1040			collect_variable_names(&e.right, names);
1041		}
1042		Expression::NotEqual(e) => {
1043			collect_variable_names(&e.left, names);
1044			collect_variable_names(&e.right, names);
1045		}
1046		Expression::And(e) => {
1047			collect_variable_names(&e.left, names);
1048			collect_variable_names(&e.right, names);
1049		}
1050		Expression::Or(e) => {
1051			collect_variable_names(&e.left, names);
1052			collect_variable_names(&e.right, names);
1053		}
1054		Expression::Xor(e) => {
1055			collect_variable_names(&e.left, names);
1056			collect_variable_names(&e.right, names);
1057		}
1058		Expression::Between(e) => {
1059			collect_variable_names(&e.value, names);
1060			collect_variable_names(&e.lower, names);
1061			collect_variable_names(&e.upper, names);
1062		}
1063		Expression::In(e) => {
1064			collect_variable_names(&e.value, names);
1065			collect_variable_names(&e.list, names);
1066		}
1067		Expression::Contains(e) => {
1068			collect_variable_names(&e.value, names);
1069			collect_variable_names(&e.list, names);
1070		}
1071		Expression::Prefix(e) => collect_variable_names(&e.expression, names),
1072		Expression::Cast(e) => collect_variable_names(&e.expression, names),
1073		Expression::Alias(e) => collect_variable_names(&e.expression, names),
1074		Expression::Call(e) => {
1075			for arg in &e.args {
1076				collect_variable_names(arg, names);
1077			}
1078		}
1079		Expression::Tuple(e) => {
1080			for expr in &e.expressions {
1081				collect_variable_names(expr, names);
1082			}
1083		}
1084		Expression::List(e) => {
1085			for expr in &e.expressions {
1086				collect_variable_names(expr, names);
1087			}
1088		}
1089		Expression::If(e) => {
1090			collect_variable_names(&e.condition, names);
1091			collect_variable_names(&e.then_expr, names);
1092			for else_if in &e.else_ifs {
1093				collect_variable_names(&else_if.condition, names);
1094				collect_variable_names(&else_if.then_expr, names);
1095			}
1096			if let Some(else_expr) = &e.else_expr {
1097				collect_variable_names(else_expr, names);
1098			}
1099		}
1100		Expression::Map(e) => {
1101			for expr in &e.expressions {
1102				collect_variable_names(expr, names);
1103			}
1104		}
1105		Expression::Extend(e) => {
1106			for expr in &e.expressions {
1107				collect_variable_names(expr, names);
1108			}
1109		}
1110		Expression::Record(e) => {
1111			for (_, expr) in &e.fields {
1112				collect_variable_names(expr, names);
1113			}
1114		}
1115		Expression::SumTypeConstructor(e) => {
1116			for (_, expr) in &e.columns {
1117				collect_variable_names(expr, names);
1118			}
1119		}
1120		Expression::IsVariant(e) => collect_variable_names(&e.expression, names),
1121		Expression::FieldAccess(e) => collect_variable_names(&e.object, names),
1122		Expression::Constant(_)
1123		| Expression::Column(_)
1124		| Expression::AccessSource(_)
1125		| Expression::Parameter(_)
1126		| Expression::Type(_) => {}
1127	}
1128}