Skip to main content

reifydb_rql/expression/
mod.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4//! Planner-side expression representation. Mirrors the AST's expression shapes but in a form that has been
5//! type-checked, name-resolved, and stripped of source-only details. The engine consumes these expressions to
6//! evaluate filters, projections, and join conditions; routine call resolution and JSON-path navigation are part
7//! of this representation rather than the runtime.
8
9pub mod fragment;
10pub mod join;
11pub mod json;
12pub mod name;
13
14use crate::{
15	ast,
16	ast::{
17		ast::{Ast, AstFrom, AstInfix, AstLiteral, InfixOperator},
18		parse_str,
19	},
20	bump::{Bump, BumpBox},
21	convert_data_type,
22};
23
24pub fn parse_expression(rql: &str) -> Result<Vec<Expression>> {
25	let bump = Bump::new();
26	let statements = parse_str(&bump, rql)?;
27	if statements.is_empty() {
28		return Ok(vec![]);
29	}
30
31	let mut result = Vec::new();
32	for statement in statements {
33		for ast in statement.nodes {
34			result.push(ExpressionCompiler::compile(ast)?);
35		}
36	}
37
38	Ok(result)
39}
40
41use std::{
42	fmt,
43	fmt::{Display, Formatter},
44	str::FromStr,
45	sync::Arc,
46};
47
48use ast::ast::AstMatchArm;
49use reifydb_core::interface::identifier::{ColumnIdentifier, ColumnShape};
50use reifydb_type::{
51	err,
52	error::Diagnostic,
53	fragment::Fragment,
54	value::{row_number::ROW_NUMBER_COLUMN_NAME, r#type::Type},
55};
56use serde::{Deserialize, Serialize};
57
58use crate::{Result, ast::ast::AstBlock, diagnostic::AstError};
59
60#[derive(Debug, Clone, Serialize, Deserialize)]
61pub struct AliasExpression {
62	pub alias: IdentExpression,
63	pub expression: Box<Expression>,
64	pub fragment: Fragment,
65}
66
67impl Display for AliasExpression {
68	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
69		Display::fmt(&self.alias, f)
70	}
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub enum Expression {
75	AccessSource(AccessShapeExpression),
76
77	Alias(AliasExpression),
78
79	Cast(CastExpression),
80
81	Constant(ConstantExpression),
82
83	Column(ColumnExpression),
84
85	Add(AddExpression),
86
87	Div(DivExpression),
88
89	Call(CallExpression),
90
91	Rem(RemExpression),
92
93	Mul(MulExpression),
94
95	Sub(SubExpression),
96
97	Tuple(TupleExpression),
98
99	List(ListExpression),
100
101	Prefix(PrefixExpression),
102
103	GreaterThan(GreaterThanExpression),
104
105	GreaterThanEqual(GreaterThanEqExpression),
106
107	LessThan(LessThanExpression),
108
109	LessThanEqual(LessThanEqExpression),
110
111	Equal(EqExpression),
112
113	NotEqual(NotEqExpression),
114
115	Between(BetweenExpression),
116
117	And(AndExpression),
118
119	Or(OrExpression),
120
121	Xor(XorExpression),
122
123	In(InExpression),
124
125	Contains(ContainsExpression),
126
127	Type(TypeExpression),
128
129	Parameter(ParameterExpression),
130	Variable(VariableExpression),
131
132	If(IfExpression),
133	Map(MapExpression),
134	Extend(ExtendExpression),
135	SumTypeConstructor(SumTypeConstructorExpression),
136	IsVariant(IsVariantExpression),
137	FieldAccess(FieldAccessExpression),
138}
139
140#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
141pub struct AccessShapeExpression {
142	pub column: ColumnIdentifier,
143}
144
145impl AccessShapeExpression {
146	pub fn full_fragment_owned(&self) -> Fragment {
147		match &self.column.shape {
148			ColumnShape::Qualified {
149				name,
150				..
151			} => Fragment::merge_all([name.clone(), self.column.name.clone()]),
152			ColumnShape::Alias(alias) => Fragment::merge_all([alias.clone(), self.column.name.clone()]),
153		}
154	}
155}
156
157#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
158pub enum ConstantExpression {
159	None {
160		fragment: Fragment,
161	},
162	Bool {
163		fragment: Fragment,
164	},
165
166	Number {
167		fragment: Fragment,
168	},
169
170	Text {
171		fragment: Fragment,
172	},
173
174	Temporal {
175		fragment: Fragment,
176	},
177}
178
179impl Display for ConstantExpression {
180	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
181		match self {
182			ConstantExpression::None {
183				..
184			} => write!(f, "none"),
185			ConstantExpression::Bool {
186				fragment,
187			} => write!(f, "{}", fragment.text()),
188			ConstantExpression::Number {
189				fragment,
190			} => write!(f, "{}", fragment.text()),
191			ConstantExpression::Text {
192				fragment,
193			} => write!(f, "\"{}\"", fragment.text()),
194			ConstantExpression::Temporal {
195				fragment,
196			} => write!(f, "{}", fragment.text()),
197		}
198	}
199}
200
201impl ConstantExpression {
202	pub fn infer_type(&self) -> Type {
203		match self {
204			ConstantExpression::None {
205				..
206			} => Type::Any,
207			ConstantExpression::Bool {
208				..
209			} => Type::Boolean,
210			ConstantExpression::Number {
211				..
212			} => Type::Int4,
213			ConstantExpression::Text {
214				..
215			} => Type::Utf8,
216			ConstantExpression::Temporal {
217				..
218			} => Type::DateTime,
219		}
220	}
221}
222
223impl Expression {
224	pub fn infer_type(&self) -> Option<Type> {
225		match self {
226			Expression::Constant(c) => Some(c.infer_type()),
227			_ => None,
228		}
229	}
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct CastExpression {
234	pub fragment: Fragment,
235	pub expression: Box<Expression>,
236	pub to: TypeExpression,
237}
238
239impl CastExpression {
240	pub fn full_fragment_owned(&self) -> Fragment {
241		Fragment::merge_all([
242			self.fragment.clone(),
243			self.expression.full_fragment_owned(),
244			self.to.full_fragment_owned(),
245		])
246	}
247
248	pub fn lazy_fragment(&self) -> impl Fn() -> Fragment {
249		move || self.full_fragment_owned()
250	}
251}
252
253#[derive(Debug, Clone, Serialize, Deserialize)]
254pub struct TypeExpression {
255	pub fragment: Fragment,
256	pub ty: Type,
257}
258
259impl TypeExpression {
260	pub fn full_fragment_owned(&self) -> Fragment {
261		self.fragment.clone()
262	}
263
264	pub fn lazy_fragment(&self) -> impl Fn() -> Fragment {
265		move || self.full_fragment_owned()
266	}
267}
268
269#[derive(Debug, Clone, Serialize, Deserialize)]
270pub struct AddExpression {
271	pub left: Box<Expression>,
272	pub right: Box<Expression>,
273	pub fragment: Fragment,
274}
275
276#[derive(Debug, Clone, Serialize, Deserialize)]
277pub struct DivExpression {
278	pub left: Box<Expression>,
279	pub right: Box<Expression>,
280	pub fragment: Fragment,
281}
282
283#[derive(Debug, Clone, Serialize, Deserialize)]
284pub struct SubExpression {
285	pub left: Box<Expression>,
286	pub right: Box<Expression>,
287	pub fragment: Fragment,
288}
289
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct RemExpression {
292	pub left: Box<Expression>,
293	pub right: Box<Expression>,
294	pub fragment: Fragment,
295}
296
297#[derive(Debug, Clone, Serialize, Deserialize)]
298pub struct MulExpression {
299	pub left: Box<Expression>,
300	pub right: Box<Expression>,
301	pub fragment: Fragment,
302}
303
304#[derive(Debug, Clone, Serialize, Deserialize)]
305pub struct GreaterThanExpression {
306	pub left: Box<Expression>,
307	pub right: Box<Expression>,
308	pub fragment: Fragment,
309}
310
311impl GreaterThanExpression {
312	pub fn full_fragment_owned(&self) -> Fragment {
313		Fragment::merge_all([
314			self.left.full_fragment_owned(),
315			self.fragment.clone(),
316			self.right.full_fragment_owned(),
317		])
318	}
319}
320
321#[derive(Debug, Clone, Serialize, Deserialize)]
322pub struct GreaterThanEqExpression {
323	pub left: Box<Expression>,
324	pub right: Box<Expression>,
325	pub fragment: Fragment,
326}
327
328impl GreaterThanEqExpression {
329	pub fn full_fragment_owned(&self) -> Fragment {
330		Fragment::merge_all([
331			self.left.full_fragment_owned(),
332			self.fragment.clone(),
333			self.right.full_fragment_owned(),
334		])
335	}
336}
337
338#[derive(Debug, Clone, Serialize, Deserialize)]
339pub struct LessThanExpression {
340	pub left: Box<Expression>,
341	pub right: Box<Expression>,
342	pub fragment: Fragment,
343}
344
345impl LessThanExpression {
346	pub fn full_fragment_owned(&self) -> Fragment {
347		Fragment::merge_all([
348			self.left.full_fragment_owned(),
349			self.fragment.clone(),
350			self.right.full_fragment_owned(),
351		])
352	}
353}
354
355#[derive(Debug, Clone, Serialize, Deserialize)]
356pub struct LessThanEqExpression {
357	pub left: Box<Expression>,
358	pub right: Box<Expression>,
359	pub fragment: Fragment,
360}
361
362impl LessThanEqExpression {
363	pub fn full_fragment_owned(&self) -> Fragment {
364		Fragment::merge_all([
365			self.left.full_fragment_owned(),
366			self.fragment.clone(),
367			self.right.full_fragment_owned(),
368		])
369	}
370}
371
372#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct EqExpression {
374	pub left: Box<Expression>,
375	pub right: Box<Expression>,
376	pub fragment: Fragment,
377}
378
379impl EqExpression {
380	pub fn full_fragment_owned(&self) -> Fragment {
381		Fragment::merge_all([
382			self.left.full_fragment_owned(),
383			self.fragment.clone(),
384			self.right.full_fragment_owned(),
385		])
386	}
387}
388
389#[derive(Debug, Clone, Serialize, Deserialize)]
390pub struct NotEqExpression {
391	pub left: Box<Expression>,
392	pub right: Box<Expression>,
393	pub fragment: Fragment,
394}
395
396impl NotEqExpression {
397	pub fn full_fragment_owned(&self) -> Fragment {
398		Fragment::merge_all([
399			self.left.full_fragment_owned(),
400			self.fragment.clone(),
401			self.right.full_fragment_owned(),
402		])
403	}
404}
405
406#[derive(Debug, Clone, Serialize, Deserialize)]
407pub struct BetweenExpression {
408	pub value: Box<Expression>,
409	pub lower: Box<Expression>,
410	pub upper: Box<Expression>,
411	pub fragment: Fragment,
412}
413
414impl BetweenExpression {
415	pub fn full_fragment_owned(&self) -> Fragment {
416		Fragment::merge_all([
417			self.value.full_fragment_owned(),
418			self.fragment.clone(),
419			self.lower.full_fragment_owned(),
420			self.upper.full_fragment_owned(),
421		])
422	}
423}
424
425#[derive(Debug, Clone, Serialize, Deserialize)]
426pub struct AndExpression {
427	pub left: Box<Expression>,
428	pub right: Box<Expression>,
429	pub fragment: Fragment,
430}
431
432impl AndExpression {
433	pub fn full_fragment_owned(&self) -> Fragment {
434		Fragment::merge_all([
435			self.left.full_fragment_owned(),
436			self.fragment.clone(),
437			self.right.full_fragment_owned(),
438		])
439	}
440}
441
442#[derive(Debug, Clone, Serialize, Deserialize)]
443pub struct OrExpression {
444	pub left: Box<Expression>,
445	pub right: Box<Expression>,
446	pub fragment: Fragment,
447}
448
449impl OrExpression {
450	pub fn full_fragment_owned(&self) -> Fragment {
451		Fragment::merge_all([
452			self.left.full_fragment_owned(),
453			self.fragment.clone(),
454			self.right.full_fragment_owned(),
455		])
456	}
457}
458
459#[derive(Debug, Clone, Serialize, Deserialize)]
460pub struct XorExpression {
461	pub left: Box<Expression>,
462	pub right: Box<Expression>,
463	pub fragment: Fragment,
464}
465
466impl XorExpression {
467	pub fn full_fragment_owned(&self) -> Fragment {
468		Fragment::merge_all([
469			self.left.full_fragment_owned(),
470			self.fragment.clone(),
471			self.right.full_fragment_owned(),
472		])
473	}
474}
475
476#[derive(Debug, Clone, Serialize, Deserialize)]
477pub struct InExpression {
478	pub value: Box<Expression>,
479	pub list: Box<Expression>,
480	pub negated: bool,
481	pub fragment: Fragment,
482}
483
484impl InExpression {
485	pub fn full_fragment_owned(&self) -> Fragment {
486		Fragment::merge_all([
487			self.value.full_fragment_owned(),
488			self.fragment.clone(),
489			self.list.full_fragment_owned(),
490		])
491	}
492}
493
494#[derive(Debug, Clone, Serialize, Deserialize)]
495pub struct ContainsExpression {
496	pub value: Box<Expression>,
497	pub list: Box<Expression>,
498	pub fragment: Fragment,
499}
500
501impl ContainsExpression {
502	pub fn full_fragment_owned(&self) -> Fragment {
503		Fragment::merge_all([
504			self.value.full_fragment_owned(),
505			self.fragment.clone(),
506			self.list.full_fragment_owned(),
507		])
508	}
509}
510
511#[derive(Debug, Clone, Serialize, Deserialize)]
512pub struct ColumnExpression(pub ColumnIdentifier);
513
514impl ColumnExpression {
515	pub fn full_fragment_owned(&self) -> Fragment {
516		self.0.name.clone()
517	}
518
519	pub fn column(&self) -> &ColumnIdentifier {
520		&self.0
521	}
522}
523
524impl Display for Expression {
525	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
526		match self {
527			Expression::AccessSource(AccessShapeExpression {
528				column,
529			}) => match &column.shape {
530				ColumnShape::Qualified {
531					name,
532					..
533				} => {
534					write!(f, "{}.{}", name.text(), column.name.text())
535				}
536				ColumnShape::Alias(alias) => {
537					write!(f, "{}.{}", alias.text(), column.name.text())
538				}
539			},
540			Expression::Alias(AliasExpression {
541				alias,
542				expression,
543				..
544			}) => {
545				write!(f, "{} as {}", expression, alias)
546			}
547			Expression::Cast(CastExpression {
548				expression: expr,
549				..
550			}) => write!(f, "{}", expr),
551			Expression::Constant(fragment) => {
552				write!(f, "Constant({})", fragment)
553			}
554			Expression::Column(ColumnExpression(column)) => {
555				write!(f, "{}", column.name.text())
556			}
557			Expression::Add(AddExpression {
558				left,
559				right,
560				..
561			}) => {
562				write!(f, "({} + {})", left, right)
563			}
564			Expression::Div(DivExpression {
565				left,
566				right,
567				..
568			}) => {
569				write!(f, "({} / {})", left, right)
570			}
571			Expression::Call(call) => write!(f, "{}", call),
572			Expression::Rem(RemExpression {
573				left,
574				right,
575				..
576			}) => {
577				write!(f, "({} % {})", left, right)
578			}
579			Expression::Mul(MulExpression {
580				left,
581				right,
582				..
583			}) => {
584				write!(f, "({} * {})", left, right)
585			}
586			Expression::Sub(SubExpression {
587				left,
588				right,
589				..
590			}) => {
591				write!(f, "({} - {})", left, right)
592			}
593			Expression::Tuple(tuple) => write!(f, "({})", tuple),
594			Expression::List(list) => write!(f, "{}", list),
595			Expression::Prefix(prefix) => write!(f, "{}", prefix),
596			Expression::GreaterThan(GreaterThanExpression {
597				left,
598				right,
599				..
600			}) => {
601				write!(f, "({} > {})", left, right)
602			}
603			Expression::GreaterThanEqual(GreaterThanEqExpression {
604				left,
605				right,
606				..
607			}) => {
608				write!(f, "({} >= {})", left, right)
609			}
610			Expression::LessThan(LessThanExpression {
611				left,
612				right,
613				..
614			}) => {
615				write!(f, "({} < {})", left, right)
616			}
617			Expression::LessThanEqual(LessThanEqExpression {
618				left,
619				right,
620				..
621			}) => {
622				write!(f, "({} <= {})", left, right)
623			}
624			Expression::Equal(EqExpression {
625				left,
626				right,
627				..
628			}) => {
629				write!(f, "({} == {})", left, right)
630			}
631			Expression::NotEqual(NotEqExpression {
632				left,
633				right,
634				..
635			}) => {
636				write!(f, "({} != {})", left, right)
637			}
638			Expression::Between(BetweenExpression {
639				value,
640				lower,
641				upper,
642				..
643			}) => {
644				write!(f, "({} BETWEEN {} AND {})", value, lower, upper)
645			}
646			Expression::And(AndExpression {
647				left,
648				right,
649				..
650			}) => {
651				write!(f, "({} and {})", left, right)
652			}
653			Expression::Or(OrExpression {
654				left,
655				right,
656				..
657			}) => {
658				write!(f, "({} or {})", left, right)
659			}
660			Expression::Xor(XorExpression {
661				left,
662				right,
663				..
664			}) => {
665				write!(f, "({} xor {})", left, right)
666			}
667			Expression::In(InExpression {
668				value,
669				list,
670				negated,
671				..
672			}) => {
673				if *negated {
674					write!(f, "({} NOT IN {})", value, list)
675				} else {
676					write!(f, "({} IN {})", value, list)
677				}
678			}
679			Expression::Contains(ContainsExpression {
680				value,
681				list,
682				..
683			}) => {
684				write!(f, "({} CONTAINS {})", value, list)
685			}
686			Expression::Type(TypeExpression {
687				fragment,
688				..
689			}) => write!(f, "{}", fragment.text()),
690			Expression::Parameter(param) => match param {
691				ParameterExpression::Positional {
692					fragment,
693					..
694				} => write!(f, "{}", fragment.text()),
695				ParameterExpression::Named {
696					fragment,
697				} => write!(f, "{}", fragment.text()),
698			},
699			Expression::Variable(var) => write!(f, "{}", var.fragment.text()),
700			Expression::If(if_expr) => write!(f, "{}", if_expr),
701			Expression::Map(map_expr) => write!(
702				f,
703				"MAP{{ {} }}",
704				map_expr.expressions
705					.iter()
706					.map(|expr| format!("{}", expr))
707					.collect::<Vec<_>>()
708					.join(", ")
709			),
710			Expression::Extend(extend_expr) => write!(
711				f,
712				"EXTEND{{ {} }}",
713				extend_expr
714					.expressions
715					.iter()
716					.map(|expr| format!("{}", expr))
717					.collect::<Vec<_>>()
718					.join(", ")
719			),
720			Expression::SumTypeConstructor(ctor) => write!(
721				f,
722				"{}::{}{{ {} }}",
723				ctor.sumtype_name.text(),
724				ctor.variant_name.text(),
725				ctor.columns
726					.iter()
727					.map(|(name, expr)| format!("{}: {}", name.text(), expr))
728					.collect::<Vec<_>>()
729					.join(", ")
730			),
731			Expression::IsVariant(e) => write!(f, "({} IS {})", e.expression, e.variant_name.text()),
732			Expression::FieldAccess(field_access) => write!(f, "{}", field_access),
733		}
734	}
735}
736
737#[derive(Debug, Clone, Serialize, Deserialize)]
738pub struct CallExpression {
739	pub func: IdentExpression,
740	pub args: Vec<Expression>,
741	pub fragment: Fragment,
742}
743
744impl CallExpression {
745	pub fn full_fragment_owned(&self) -> Fragment {
746		Fragment::Statement {
747			column: self.func.0.column(),
748			line: self.func.0.line(),
749			text: Arc::from(format!(
750				"{}({})",
751				self.func.0.text(),
752				self.args
753					.iter()
754					.map(|arg| arg.full_fragment_owned().text().to_string())
755					.collect::<Vec<_>>()
756					.join(",")
757			)),
758		}
759	}
760}
761
762impl Display for CallExpression {
763	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
764		let args = self.args.iter().map(|arg| format!("{}", arg)).collect::<Vec<_>>().join(", ");
765		write!(f, "{}({})", self.func, args)
766	}
767}
768
769#[derive(Debug, Clone, Serialize, Deserialize)]
770pub struct IdentExpression(pub Fragment);
771
772#[derive(Debug, Clone, Serialize, Deserialize)]
773pub enum ParameterExpression {
774	Positional {
775		fragment: Fragment,
776	},
777	Named {
778		fragment: Fragment,
779	},
780}
781
782impl ParameterExpression {
783	pub fn position(&self) -> Option<u32> {
784		match self {
785			ParameterExpression::Positional {
786				fragment,
787			} => fragment.text()[1..].parse().ok(),
788			ParameterExpression::Named {
789				..
790			} => None,
791		}
792	}
793
794	pub fn name(&self) -> Option<&str> {
795		match self {
796			ParameterExpression::Named {
797				fragment,
798			} => Some(&fragment.text()[1..]),
799			ParameterExpression::Positional {
800				..
801			} => None,
802		}
803	}
804}
805
806#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
807pub struct VariableExpression {
808	pub fragment: Fragment,
809}
810
811impl VariableExpression {
812	pub fn name(&self) -> &str {
813		let text = self.fragment.text();
814		text.strip_prefix('$').unwrap_or(text)
815	}
816}
817
818#[derive(Debug, Clone, Serialize, Deserialize)]
819pub struct IfExpression {
820	pub condition: Box<Expression>,
821	pub then_expr: Box<Expression>,
822	pub else_ifs: Vec<ElseIfExpression>,
823	pub else_expr: Option<Box<Expression>>,
824	pub fragment: Fragment,
825}
826
827#[derive(Debug, Clone, Serialize, Deserialize)]
828pub struct ElseIfExpression {
829	pub condition: Box<Expression>,
830	pub then_expr: Box<Expression>,
831	pub fragment: Fragment,
832}
833
834impl IfExpression {
835	pub fn full_fragment_owned(&self) -> Fragment {
836		self.fragment.clone()
837	}
838
839	pub fn lazy_fragment(&self) -> impl Fn() -> Fragment {
840		move || self.full_fragment_owned()
841	}
842}
843
844impl Display for IfExpression {
845	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
846		write!(f, "if {} {{ {} }}", self.condition, self.then_expr)?;
847
848		for else_if in &self.else_ifs {
849			write!(f, " else if {} {{ {} }}", else_if.condition, else_if.then_expr)?;
850		}
851
852		if let Some(else_expr) = &self.else_expr {
853			write!(f, " else {{ {} }}", else_expr)?;
854		}
855
856		Ok(())
857	}
858}
859
860impl IdentExpression {
861	pub fn name(&self) -> &str {
862		self.0.text()
863	}
864}
865
866impl Display for IdentExpression {
867	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
868		write!(f, "{}", self.0.text())
869	}
870}
871
872#[derive(Debug, Clone, Serialize, Deserialize)]
873pub enum PrefixOperator {
874	Minus(Fragment),
875	Plus(Fragment),
876	Not(Fragment),
877}
878
879impl PrefixOperator {
880	pub fn full_fragment_owned(&self) -> Fragment {
881		match self {
882			PrefixOperator::Minus(fragment) => fragment.clone(),
883			PrefixOperator::Plus(fragment) => fragment.clone(),
884			PrefixOperator::Not(fragment) => fragment.clone(),
885		}
886	}
887}
888
889impl Display for PrefixOperator {
890	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
891		match self {
892			PrefixOperator::Minus(_) => write!(f, "-"),
893			PrefixOperator::Plus(_) => write!(f, "+"),
894			PrefixOperator::Not(_) => write!(f, "not"),
895		}
896	}
897}
898
899#[derive(Debug, Clone, Serialize, Deserialize)]
900pub struct PrefixExpression {
901	pub operator: PrefixOperator,
902	pub expression: Box<Expression>,
903	pub fragment: Fragment,
904}
905
906impl PrefixExpression {
907	pub fn full_fragment_owned(&self) -> Fragment {
908		Fragment::merge_all([self.operator.full_fragment_owned(), self.expression.full_fragment_owned()])
909	}
910}
911
912impl Display for PrefixExpression {
913	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
914		write!(f, "({}{})", self.operator, self.expression)
915	}
916}
917
918#[derive(Debug, Clone, Serialize, Deserialize)]
919pub struct TupleExpression {
920	pub expressions: Vec<Expression>,
921	pub fragment: Fragment,
922}
923
924impl Display for TupleExpression {
925	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
926		let items = self.expressions.iter().map(|e| format!("{}", e)).collect::<Vec<_>>().join(", ");
927		write!(f, "({})", items)
928	}
929}
930
931#[derive(Debug, Clone, Serialize, Deserialize)]
932pub struct ListExpression {
933	pub expressions: Vec<Expression>,
934	pub fragment: Fragment,
935}
936
937impl Display for ListExpression {
938	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
939		let items = self.expressions.iter().map(|e| format!("{}", e)).collect::<Vec<_>>().join(", ");
940		write!(f, "[{}]", items)
941	}
942}
943
944pub struct ExpressionCompiler {}
945
946impl ExpressionCompiler {
947	pub fn compile(ast: Ast<'_>) -> Result<Expression> {
948		match ast {
949			Ast::Literal(literal) => match literal {
950				AstLiteral::Boolean(_) => Ok(Expression::Constant(ConstantExpression::Bool {
951					fragment: literal.fragment().to_owned(),
952				})),
953				AstLiteral::Number(_) => Ok(Expression::Constant(ConstantExpression::Number {
954					fragment: literal.fragment().to_owned(),
955				})),
956				AstLiteral::Temporal(_) => Ok(Expression::Constant(ConstantExpression::Temporal {
957					fragment: literal.fragment().to_owned(),
958				})),
959				AstLiteral::Text(_) => Ok(Expression::Constant(ConstantExpression::Text {
960					fragment: literal.fragment().to_owned(),
961				})),
962				AstLiteral::None(_) => Ok(Expression::Constant(ConstantExpression::None {
963					fragment: literal.fragment().to_owned(),
964				})),
965			},
966			Ast::Identifier(identifier) => {
967				let column = ColumnIdentifier {
968					shape: ColumnShape::Qualified {
969						namespace: Fragment::Internal {
970							text: Arc::from("_context"),
971						},
972						name: Fragment::Internal {
973							text: Arc::from("_context"),
974						},
975					},
976					name: identifier.token.fragment.to_owned(),
977				};
978				Ok(Expression::Column(ColumnExpression(column)))
979			}
980			Ast::CallFunction(call) => {
981				let full_name = if call.function.namespaces.is_empty() {
982					call.function.name.text().to_string()
983				} else {
984					let namespace_path = call
985						.function
986						.namespaces
987						.iter()
988						.map(|ns| ns.text())
989						.collect::<Vec<_>>()
990						.join("::");
991					format!("{}::{}", namespace_path, call.function.name.text())
992				};
993
994				let mut arg_expressions = Vec::new();
995				for arg_ast in call.arguments.nodes {
996					let compiled = Self::compile(arg_ast)?;
997					let compiled = match &compiled {
998						Expression::Column(col_expr) => {
999							if let Ok(ty) = Type::from_str(col_expr.0.name.text()) {
1000								Expression::Type(TypeExpression {
1001									fragment: col_expr.0.name.clone(),
1002									ty,
1003								})
1004							} else {
1005								compiled
1006							}
1007						}
1008						_ => compiled,
1009					};
1010					arg_expressions.push(compiled);
1011				}
1012
1013				Ok(Expression::Call(CallExpression {
1014					func: IdentExpression(Fragment::testing(&full_name)),
1015					args: arg_expressions,
1016					fragment: call.token.fragment.to_owned(),
1017				}))
1018			}
1019			Ast::Infix(ast) => Self::infix(ast),
1020			Ast::Between(between) => {
1021				let value = Self::compile(BumpBox::into_inner(between.value))?;
1022				let lower = Self::compile(BumpBox::into_inner(between.lower))?;
1023				let upper = Self::compile(BumpBox::into_inner(between.upper))?;
1024
1025				Ok(Expression::Between(BetweenExpression {
1026					value: Box::new(value),
1027					lower: Box::new(lower),
1028					upper: Box::new(upper),
1029					fragment: between.token.fragment.to_owned(),
1030				}))
1031			}
1032			Ast::Tuple(tuple) => {
1033				let mut expressions = Vec::with_capacity(tuple.len());
1034
1035				for ast in tuple.nodes {
1036					expressions.push(Self::compile(ast)?);
1037				}
1038
1039				Ok(Expression::Tuple(TupleExpression {
1040					expressions,
1041					fragment: tuple.token.fragment.to_owned(),
1042				}))
1043			}
1044			Ast::Prefix(prefix) => {
1045				let (fragment, operator) = match prefix.operator {
1046					ast::ast::AstPrefixOperator::Plus(token) => (
1047						token.fragment.to_owned(),
1048						PrefixOperator::Plus(token.fragment.to_owned()),
1049					),
1050					ast::ast::AstPrefixOperator::Negate(token) => (
1051						token.fragment.to_owned(),
1052						PrefixOperator::Minus(token.fragment.to_owned()),
1053					),
1054					ast::ast::AstPrefixOperator::Not(token) => (
1055						token.fragment.to_owned(),
1056						PrefixOperator::Not(token.fragment.to_owned()),
1057					),
1058				};
1059
1060				Ok(Expression::Prefix(PrefixExpression {
1061					operator,
1062					expression: Box::new(Self::compile(BumpBox::into_inner(prefix.node))?),
1063					fragment,
1064				}))
1065			}
1066			Ast::Cast(node) => {
1067				let mut tuple = node.tuple;
1068				let node = tuple.nodes.pop().unwrap();
1069				let bump_fragment = node.as_identifier().token.fragment;
1070				let ty = convert_data_type(&bump_fragment)?;
1071				let fragment = bump_fragment.to_owned();
1072
1073				let expr = tuple.nodes.pop().unwrap();
1074
1075				Ok(Expression::Cast(CastExpression {
1076					fragment: tuple.token.fragment.to_owned(),
1077					expression: Box::new(Self::compile(expr)?),
1078					to: TypeExpression {
1079						fragment,
1080						ty,
1081					},
1082				}))
1083			}
1084			Ast::Variable(var) => Ok(Expression::Variable(VariableExpression {
1085				fragment: var.token.fragment.to_owned(),
1086			})),
1087			Ast::Rownum(_rownum) => {
1088				let column = ColumnIdentifier {
1089					shape: ColumnShape::Qualified {
1090						namespace: Fragment::Internal {
1091							text: Arc::from("_context"),
1092						},
1093						name: Fragment::Internal {
1094							text: Arc::from("_context"),
1095						},
1096					},
1097					name: Fragment::Internal {
1098						text: Arc::from(ROW_NUMBER_COLUMN_NAME),
1099					},
1100				};
1101				Ok(Expression::Column(ColumnExpression(column)))
1102			}
1103			Ast::SystemColumn(node) => {
1104				let name = node
1105					.token
1106					.fragment
1107					.text()
1108					.strip_prefix('#')
1109					.unwrap_or(node.token.fragment.text());
1110				let column = ColumnIdentifier {
1111					shape: ColumnShape::Qualified {
1112						namespace: Fragment::Internal {
1113							text: Arc::from("_context"),
1114						},
1115						name: Fragment::Internal {
1116							text: Arc::from("_context"),
1117						},
1118					},
1119					name: Fragment::Internal {
1120						text: Arc::from(name),
1121					},
1122				};
1123				Ok(Expression::Column(ColumnExpression(column)))
1124			}
1125			Ast::If(if_ast) => {
1126				let condition = Box::new(Self::compile(BumpBox::into_inner(if_ast.condition))?);
1127
1128				let then_expr = Box::new(Self::compile_block_as_expr(if_ast.then_block)?);
1129
1130				let mut else_ifs = Vec::new();
1131				for else_if in if_ast.else_ifs {
1132					let else_if_condition =
1133						Box::new(Self::compile(BumpBox::into_inner(else_if.condition))?);
1134					let else_if_then = Box::new(Self::compile_block_as_expr(else_if.then_block)?);
1135					else_ifs.push(ElseIfExpression {
1136						condition: else_if_condition,
1137						then_expr: else_if_then,
1138						fragment: else_if.token.fragment.to_owned(),
1139					});
1140				}
1141
1142				let else_expr = if let Some(else_block) = if_ast.else_block {
1143					Some(Box::new(Self::compile_block_as_expr(else_block)?))
1144				} else {
1145					None
1146				};
1147
1148				Ok(Expression::If(IfExpression {
1149					condition,
1150					then_expr,
1151					else_ifs,
1152					else_expr,
1153					fragment: if_ast.token.fragment.to_owned(),
1154				}))
1155			}
1156			Ast::Map(map) => {
1157				let mut expressions = Vec::with_capacity(map.nodes.len());
1158				for node in map.nodes {
1159					expressions.push(Self::compile(node)?);
1160				}
1161
1162				Ok(Expression::Map(MapExpression {
1163					expressions,
1164					fragment: map.token.fragment.to_owned(),
1165				}))
1166			}
1167			Ast::Extend(extend) => {
1168				let mut expressions = Vec::with_capacity(extend.nodes.len());
1169				for node in extend.nodes {
1170					expressions.push(Self::compile(node)?);
1171				}
1172
1173				Ok(Expression::Extend(ExtendExpression {
1174					expressions,
1175					fragment: extend.token.fragment.to_owned(),
1176				}))
1177			}
1178			Ast::List(list) => {
1179				let mut expressions = Vec::with_capacity(list.nodes.len());
1180				for ast in list.nodes {
1181					expressions.push(Self::compile(ast)?);
1182				}
1183				Ok(Expression::List(ListExpression {
1184					expressions,
1185					fragment: list.token.fragment.to_owned(),
1186				}))
1187			}
1188			Ast::SumTypeConstructor(ctor) => {
1189				let mut columns = Vec::with_capacity(ctor.columns.keyed_values.len());
1190				for kv in ctor.columns.keyed_values {
1191					let name = kv.key.token.fragment.to_owned();
1192					let expr = Self::compile(BumpBox::into_inner(kv.value))?;
1193					columns.push((name, expr));
1194				}
1195				Ok(Expression::SumTypeConstructor(SumTypeConstructorExpression {
1196					namespace: ctor.namespace.to_owned(),
1197					sumtype_name: ctor.sumtype_name.to_owned(),
1198					variant_name: ctor.variant_name.to_owned(),
1199					columns,
1200					fragment: ctor.token.fragment.to_owned(),
1201				}))
1202			}
1203			Ast::IsVariant(is) => {
1204				let expression = Self::compile(BumpBox::into_inner(is.expression))?;
1205				Ok(Expression::IsVariant(IsVariantExpression {
1206					expression: Box::new(expression),
1207					namespace: is.namespace.map(|n| n.to_owned()),
1208					sumtype_name: is.sumtype_name.to_owned(),
1209					variant_name: is.variant_name.to_owned(),
1210					tag: None,
1211					fragment: is.token.fragment.to_owned(),
1212				}))
1213			}
1214			Ast::Match(match_ast) => Self::compile_match(match_ast),
1215			Ast::Identity(ident) => Ok(Expression::Variable(VariableExpression {
1216				fragment: ident.token.fragment.to_owned(),
1217			})),
1218			Ast::From(AstFrom::Variable {
1219				variable,
1220				..
1221			}) => Ok(Expression::Variable(VariableExpression {
1222				fragment: variable.token.fragment.to_owned(),
1223			})),
1224			ast => unimplemented!("{:?}", ast),
1225		}
1226	}
1227
1228	fn compile_block_as_expr(block: AstBlock<'_>) -> Result<Expression> {
1229		let fragment = block.token.fragment.to_owned();
1230		if let Some(first_stmt) = block.statements.into_iter().next()
1231			&& let Some(first_node) = first_stmt.nodes.into_iter().next()
1232		{
1233			return Self::compile(first_node);
1234		}
1235
1236		Ok(Expression::Constant(ConstantExpression::None {
1237			fragment,
1238		}))
1239	}
1240
1241	fn compile_match(match_ast: ast::ast::AstMatch<'_>) -> Result<Expression> {
1242		let fragment = match_ast.token.fragment.to_owned();
1243
1244		let subject = match match_ast.subject {
1245			Some(s) => Some(Self::compile(BumpBox::into_inner(s))?),
1246			None => None,
1247		};
1248
1249		let subject_col_name = subject.as_ref().and_then(|s| match s {
1250			Expression::Column(ColumnExpression(col)) => Some(col.name.text().to_string()),
1251			_ => None,
1252		});
1253
1254		let mut branches: Vec<(Expression, Expression)> = Vec::new();
1255		let mut else_result: Option<Expression> = None;
1256
1257		for arm in match_ast.arms {
1258			match arm {
1259				AstMatchArm::Else {
1260					result,
1261				} => {
1262					else_result = Some(Self::compile(BumpBox::into_inner(result))?);
1263				}
1264				AstMatchArm::Value {
1265					pattern,
1266					guard,
1267					result,
1268				} => {
1269					let subject_expr = subject.clone().expect("Value arm requires a MATCH subject");
1270					let pattern_expr = Self::compile(BumpBox::into_inner(pattern))?;
1271
1272					let mut condition = Expression::Equal(EqExpression {
1273						left: Box::new(subject_expr),
1274						right: Box::new(pattern_expr),
1275						fragment: fragment.clone(),
1276					});
1277
1278					if let Some(guard) = guard {
1279						let guard_expr = Self::compile(BumpBox::into_inner(guard))?;
1280						condition = Expression::And(AndExpression {
1281							left: Box::new(condition),
1282							right: Box::new(guard_expr),
1283							fragment: fragment.clone(),
1284						});
1285					}
1286
1287					let result_expr = Self::compile(BumpBox::into_inner(result))?;
1288					branches.push((condition, result_expr));
1289				}
1290				AstMatchArm::IsVariant {
1291					namespace,
1292					sumtype_name,
1293					variant_name,
1294					destructure,
1295					guard,
1296					result,
1297				} => {
1298					let subject_expr = subject.clone().expect("IS arm requires a MATCH subject");
1299
1300					let bindings: Vec<(String, String)> = match (&destructure, &subject_col_name) {
1301						(Some(destr), Some(col_name)) => {
1302							let variant_lower = variant_name.text().to_lowercase();
1303							destr.fields
1304								.iter()
1305								.map(|f| {
1306									let field_name = f.text().to_string();
1307									let physical = format!(
1308										"{}_{}_{}",
1309										col_name,
1310										variant_lower,
1311										field_name.to_lowercase()
1312									);
1313									(field_name, physical)
1314								})
1315								.collect()
1316						}
1317						_ => vec![],
1318					};
1319
1320					let mut condition = Expression::IsVariant(IsVariantExpression {
1321						expression: Box::new(subject_expr),
1322						namespace: namespace.map(|n| n.to_owned()),
1323						sumtype_name: sumtype_name.to_owned(),
1324						variant_name: variant_name.to_owned(),
1325						tag: None,
1326						fragment: fragment.clone(),
1327					});
1328
1329					if let Some(guard) = guard {
1330						let mut guard_expr = Self::compile(BumpBox::into_inner(guard))?;
1331						Self::rewrite_field_refs(&mut guard_expr, &bindings);
1332						condition = Expression::And(AndExpression {
1333							left: Box::new(condition),
1334							right: Box::new(guard_expr),
1335							fragment: fragment.clone(),
1336						});
1337					}
1338
1339					let mut result_expr = Self::compile(BumpBox::into_inner(result))?;
1340					Self::rewrite_field_refs(&mut result_expr, &bindings);
1341					branches.push((condition, result_expr));
1342				}
1343				AstMatchArm::Variant {
1344					variant_name,
1345					destructure,
1346					guard,
1347					result,
1348				} => {
1349					let subject_expr =
1350						subject.clone().expect("Variant arm requires a MATCH subject");
1351
1352					let bindings: Vec<(String, String)> = match (&destructure, &subject_col_name) {
1353						(Some(destr), Some(col_name)) => {
1354							let variant_lower = variant_name.text().to_lowercase();
1355							destr.fields
1356								.iter()
1357								.map(|f| {
1358									let field_name = f.text().to_string();
1359									let physical = format!(
1360										"{}_{}_{}",
1361										col_name,
1362										variant_lower,
1363										field_name.to_lowercase()
1364									);
1365									(field_name, physical)
1366								})
1367								.collect()
1368						}
1369						_ => vec![],
1370					};
1371
1372					let mut condition = Expression::IsVariant(IsVariantExpression {
1373						expression: Box::new(subject_expr),
1374						namespace: None,
1375						sumtype_name: variant_name.to_owned(),
1376						variant_name: variant_name.to_owned(),
1377						tag: None,
1378						fragment: fragment.clone(),
1379					});
1380
1381					if let Some(guard) = guard {
1382						let mut guard_expr = Self::compile(BumpBox::into_inner(guard))?;
1383						Self::rewrite_field_refs(&mut guard_expr, &bindings);
1384						condition = Expression::And(AndExpression {
1385							left: Box::new(condition),
1386							right: Box::new(guard_expr),
1387							fragment: fragment.clone(),
1388						});
1389					}
1390
1391					let mut result_expr = Self::compile(BumpBox::into_inner(result))?;
1392					Self::rewrite_field_refs(&mut result_expr, &bindings);
1393					branches.push((condition, result_expr));
1394				}
1395				AstMatchArm::Condition {
1396					condition,
1397					guard,
1398					result,
1399				} => {
1400					let mut cond = Self::compile(BumpBox::into_inner(condition))?;
1401
1402					if let Some(guard) = guard {
1403						let guard_expr = Self::compile(BumpBox::into_inner(guard))?;
1404						cond = Expression::And(AndExpression {
1405							left: Box::new(cond),
1406							right: Box::new(guard_expr),
1407							fragment: fragment.clone(),
1408						});
1409					}
1410
1411					let result_expr = Self::compile(BumpBox::into_inner(result))?;
1412					branches.push((cond, result_expr));
1413				}
1414			}
1415		}
1416
1417		if branches.is_empty() {
1418			return Ok(else_result.unwrap_or(Expression::Constant(ConstantExpression::None {
1419				fragment,
1420			})));
1421		}
1422
1423		let (first_cond, first_then) = branches.remove(0);
1424
1425		let else_ifs: Vec<ElseIfExpression> = branches
1426			.into_iter()
1427			.map(|(cond, then_expr)| ElseIfExpression {
1428				condition: Box::new(cond),
1429				then_expr: Box::new(then_expr),
1430				fragment: fragment.clone(),
1431			})
1432			.collect();
1433
1434		Ok(Expression::If(IfExpression {
1435			condition: Box::new(first_cond),
1436			then_expr: Box::new(first_then),
1437			else_ifs,
1438			else_expr: else_result.map(Box::new),
1439			fragment,
1440		}))
1441	}
1442
1443	pub(crate) fn rewrite_field_refs(expr: &mut Expression, bindings: &[(String, String)]) {
1444		if bindings.is_empty() {
1445			return;
1446		}
1447		match expr {
1448			Expression::Column(ColumnExpression(col)) => {
1449				let name = col.name.text().to_string();
1450				for (field_name, physical_name) in bindings {
1451					if name == *field_name {
1452						col.name = Fragment::internal(physical_name);
1453						break;
1454					}
1455				}
1456			}
1457			Expression::Add(e) => {
1458				Self::rewrite_field_refs(&mut e.left, bindings);
1459				Self::rewrite_field_refs(&mut e.right, bindings);
1460			}
1461			Expression::Sub(e) => {
1462				Self::rewrite_field_refs(&mut e.left, bindings);
1463				Self::rewrite_field_refs(&mut e.right, bindings);
1464			}
1465			Expression::Mul(e) => {
1466				Self::rewrite_field_refs(&mut e.left, bindings);
1467				Self::rewrite_field_refs(&mut e.right, bindings);
1468			}
1469			Expression::Div(e) => {
1470				Self::rewrite_field_refs(&mut e.left, bindings);
1471				Self::rewrite_field_refs(&mut e.right, bindings);
1472			}
1473			Expression::Rem(e) => {
1474				Self::rewrite_field_refs(&mut e.left, bindings);
1475				Self::rewrite_field_refs(&mut e.right, bindings);
1476			}
1477			Expression::Equal(e) => {
1478				Self::rewrite_field_refs(&mut e.left, bindings);
1479				Self::rewrite_field_refs(&mut e.right, bindings);
1480			}
1481			Expression::NotEqual(e) => {
1482				Self::rewrite_field_refs(&mut e.left, bindings);
1483				Self::rewrite_field_refs(&mut e.right, bindings);
1484			}
1485			Expression::GreaterThan(e) => {
1486				Self::rewrite_field_refs(&mut e.left, bindings);
1487				Self::rewrite_field_refs(&mut e.right, bindings);
1488			}
1489			Expression::GreaterThanEqual(e) => {
1490				Self::rewrite_field_refs(&mut e.left, bindings);
1491				Self::rewrite_field_refs(&mut e.right, bindings);
1492			}
1493			Expression::LessThan(e) => {
1494				Self::rewrite_field_refs(&mut e.left, bindings);
1495				Self::rewrite_field_refs(&mut e.right, bindings);
1496			}
1497			Expression::LessThanEqual(e) => {
1498				Self::rewrite_field_refs(&mut e.left, bindings);
1499				Self::rewrite_field_refs(&mut e.right, bindings);
1500			}
1501			Expression::And(e) => {
1502				Self::rewrite_field_refs(&mut e.left, bindings);
1503				Self::rewrite_field_refs(&mut e.right, bindings);
1504			}
1505			Expression::Or(e) => {
1506				Self::rewrite_field_refs(&mut e.left, bindings);
1507				Self::rewrite_field_refs(&mut e.right, bindings);
1508			}
1509			Expression::Xor(e) => {
1510				Self::rewrite_field_refs(&mut e.left, bindings);
1511				Self::rewrite_field_refs(&mut e.right, bindings);
1512			}
1513			Expression::Prefix(e) => {
1514				Self::rewrite_field_refs(&mut e.expression, bindings);
1515			}
1516			Expression::Cast(e) => {
1517				Self::rewrite_field_refs(&mut e.expression, bindings);
1518			}
1519			Expression::Call(e) => {
1520				for arg in &mut e.args {
1521					Self::rewrite_field_refs(arg, bindings);
1522				}
1523			}
1524			Expression::If(e) => {
1525				Self::rewrite_field_refs(&mut e.condition, bindings);
1526				Self::rewrite_field_refs(&mut e.then_expr, bindings);
1527				for else_if in &mut e.else_ifs {
1528					Self::rewrite_field_refs(&mut else_if.condition, bindings);
1529					Self::rewrite_field_refs(&mut else_if.then_expr, bindings);
1530				}
1531				if let Some(else_expr) = &mut e.else_expr {
1532					Self::rewrite_field_refs(else_expr, bindings);
1533				}
1534			}
1535			Expression::Alias(e) => {
1536				Self::rewrite_field_refs(&mut e.expression, bindings);
1537			}
1538			Expression::Tuple(e) => {
1539				for expr in &mut e.expressions {
1540					Self::rewrite_field_refs(expr, bindings);
1541				}
1542			}
1543			Expression::List(e) => {
1544				for expr in &mut e.expressions {
1545					Self::rewrite_field_refs(expr, bindings);
1546				}
1547			}
1548			Expression::Between(e) => {
1549				Self::rewrite_field_refs(&mut e.value, bindings);
1550				Self::rewrite_field_refs(&mut e.lower, bindings);
1551				Self::rewrite_field_refs(&mut e.upper, bindings);
1552			}
1553			Expression::In(e) => {
1554				Self::rewrite_field_refs(&mut e.value, bindings);
1555				Self::rewrite_field_refs(&mut e.list, bindings);
1556			}
1557			Expression::Contains(e) => {
1558				Self::rewrite_field_refs(&mut e.value, bindings);
1559				Self::rewrite_field_refs(&mut e.list, bindings);
1560			}
1561
1562			Expression::Constant(_)
1563			| Expression::AccessSource(_)
1564			| Expression::Type(_)
1565			| Expression::Parameter(_)
1566			| Expression::Variable(_)
1567			| Expression::Map(_)
1568			| Expression::Extend(_)
1569			| Expression::SumTypeConstructor(_)
1570			| Expression::IsVariant(_)
1571			| Expression::FieldAccess(_) => {}
1572		}
1573	}
1574
1575	fn infix(ast: AstInfix<'_>) -> Result<Expression> {
1576		match ast.operator {
1577			InfixOperator::Add(token) => {
1578				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1579				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1580				Ok(Expression::Add(AddExpression {
1581					left: Box::new(left),
1582					right: Box::new(right),
1583					fragment: token.fragment.to_owned(),
1584				}))
1585			}
1586			InfixOperator::Divide(token) => {
1587				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1588				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1589				Ok(Expression::Div(DivExpression {
1590					left: Box::new(left),
1591					right: Box::new(right),
1592					fragment: token.fragment.to_owned(),
1593				}))
1594			}
1595			InfixOperator::Subtract(token) => {
1596				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1597				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1598				Ok(Expression::Sub(SubExpression {
1599					left: Box::new(left),
1600					right: Box::new(right),
1601					fragment: token.fragment.to_owned(),
1602				}))
1603			}
1604			InfixOperator::Rem(token) => {
1605				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1606				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1607				Ok(Expression::Rem(RemExpression {
1608					left: Box::new(left),
1609					right: Box::new(right),
1610					fragment: token.fragment.to_owned(),
1611				}))
1612			}
1613			InfixOperator::Multiply(token) => {
1614				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1615				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1616				Ok(Expression::Mul(MulExpression {
1617					left: Box::new(left),
1618					right: Box::new(right),
1619					fragment: token.fragment.to_owned(),
1620				}))
1621			}
1622			InfixOperator::Call(token) => {
1623				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1624				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1625
1626				let func_name = match left {
1627					Expression::Column(ColumnExpression(column)) => column.name,
1628					Expression::Variable(var) => var.fragment,
1629					_ => panic!("unexpected left-hand side in call expression"),
1630				};
1631				let Expression::Tuple(tuple) = right else {
1632					panic!()
1633				};
1634
1635				Ok(Expression::Call(CallExpression {
1636					func: IdentExpression(func_name),
1637					args: tuple.expressions,
1638					fragment: token.fragment.to_owned(),
1639				}))
1640			}
1641			InfixOperator::GreaterThan(token) => {
1642				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1643				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1644
1645				Ok(Expression::GreaterThan(GreaterThanExpression {
1646					left: Box::new(left),
1647					right: Box::new(right),
1648					fragment: token.fragment.to_owned(),
1649				}))
1650			}
1651			InfixOperator::GreaterThanEqual(token) => {
1652				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1653				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1654
1655				Ok(Expression::GreaterThanEqual(GreaterThanEqExpression {
1656					left: Box::new(left),
1657					right: Box::new(right),
1658					fragment: token.fragment.to_owned(),
1659				}))
1660			}
1661			InfixOperator::LessThan(token) => {
1662				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1663				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1664
1665				Ok(Expression::LessThan(LessThanExpression {
1666					left: Box::new(left),
1667					right: Box::new(right),
1668					fragment: token.fragment.to_owned(),
1669				}))
1670			}
1671			InfixOperator::LessThanEqual(token) => {
1672				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1673				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1674
1675				Ok(Expression::LessThanEqual(LessThanEqExpression {
1676					left: Box::new(left),
1677					right: Box::new(right),
1678					fragment: token.fragment.to_owned(),
1679				}))
1680			}
1681			InfixOperator::Equal(token) => {
1682				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1683				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1684
1685				Ok(Expression::Equal(EqExpression {
1686					left: Box::new(left),
1687					right: Box::new(right),
1688					fragment: token.fragment.to_owned(),
1689				}))
1690			}
1691			InfixOperator::NotEqual(token) => {
1692				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1693				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1694
1695				Ok(Expression::NotEqual(NotEqExpression {
1696					left: Box::new(left),
1697					right: Box::new(right),
1698					fragment: token.fragment.to_owned(),
1699				}))
1700			}
1701			InfixOperator::As(token) => {
1702				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1703				let alias_fragment = match BumpBox::into_inner(ast.right) {
1704					Ast::Identifier(ident) => ident.token.fragment.to_owned(),
1705					Ast::Literal(AstLiteral::Text(text)) => {
1706						let raw = text.0.fragment.text();
1707						let unquoted = raw.trim_matches('"');
1708						Fragment::internal(unquoted)
1709					}
1710					_ => unimplemented!(),
1711				};
1712
1713				Ok(Expression::Alias(AliasExpression {
1714					alias: IdentExpression(alias_fragment),
1715					expression: Box::new(left),
1716					fragment: token.fragment.to_owned(),
1717				}))
1718			}
1719
1720			InfixOperator::And(token) => {
1721				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1722				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1723
1724				Ok(Expression::And(AndExpression {
1725					left: Box::new(left),
1726					right: Box::new(right),
1727					fragment: token.fragment.to_owned(),
1728				}))
1729			}
1730
1731			InfixOperator::Or(token) => {
1732				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1733				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1734
1735				Ok(Expression::Or(OrExpression {
1736					left: Box::new(left),
1737					right: Box::new(right),
1738					fragment: token.fragment.to_owned(),
1739				}))
1740			}
1741
1742			InfixOperator::Xor(token) => {
1743				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1744				let right = Self::compile(BumpBox::into_inner(ast.right))?;
1745
1746				Ok(Expression::Xor(XorExpression {
1747					left: Box::new(left),
1748					right: Box::new(right),
1749					fragment: token.fragment.to_owned(),
1750				}))
1751			}
1752
1753			InfixOperator::In(token) => {
1754				let value = Self::compile(BumpBox::into_inner(ast.left))?;
1755				let list = Self::compile(BumpBox::into_inner(ast.right))?;
1756
1757				Ok(Expression::In(InExpression {
1758					value: Box::new(value),
1759					list: Box::new(list),
1760					negated: false,
1761					fragment: token.fragment.to_owned(),
1762				}))
1763			}
1764
1765			InfixOperator::NotIn(token) => {
1766				let value = Self::compile(BumpBox::into_inner(ast.left))?;
1767				let list = Self::compile(BumpBox::into_inner(ast.right))?;
1768
1769				Ok(Expression::In(InExpression {
1770					value: Box::new(value),
1771					list: Box::new(list),
1772					negated: true,
1773					fragment: token.fragment.to_owned(),
1774				}))
1775			}
1776
1777			InfixOperator::Contains(token) => {
1778				let value = Self::compile(BumpBox::into_inner(ast.left))?;
1779				let list = Self::compile(BumpBox::into_inner(ast.right))?;
1780
1781				Ok(Expression::Contains(ContainsExpression {
1782					value: Box::new(value),
1783					list: Box::new(list),
1784					fragment: token.fragment.to_owned(),
1785				}))
1786			}
1787
1788			InfixOperator::Assign(token) => {
1789				// Assignment operator (=) is not valid in expression context
1790				// Use == for equality comparison
1791				Err(AstError::UnsupportedToken {
1792					fragment: token.fragment.to_owned(),
1793				}
1794				.into())
1795			}
1796
1797			InfixOperator::TypeAscription(token) => {
1798				match BumpBox::into_inner(ast.left) {
1799					Ast::Identifier(alias) => {
1800						let right = Self::compile(BumpBox::into_inner(ast.right))?;
1801
1802						Ok(Expression::Alias(AliasExpression {
1803							alias: IdentExpression(alias.token.fragment.to_owned()),
1804							expression: Box::new(right),
1805							fragment: token.fragment.to_owned(),
1806						}))
1807					}
1808					Ast::Literal(AstLiteral::Text(text)) => {
1809						// Handle string literals as alias names (common in MAP syntax)
1810						let right = Self::compile(BumpBox::into_inner(ast.right))?;
1811
1812						Ok(Expression::Alias(AliasExpression {
1813							alias: IdentExpression(text.0.fragment.to_owned()),
1814							expression: Box::new(right),
1815							fragment: token.fragment.to_owned(),
1816						}))
1817					}
1818					_ => {
1819						err!(Diagnostic {
1820							code: "EXPR_001".to_string(),
1821							rql: None,
1822							message: "Invalid alias expression".to_string(),
1823							column: None,
1824							fragment: Fragment::None,
1825							label: Some("Only identifiers and string literals can be used as alias names".to_string()),
1826							help: Some("Use an identifier or string literal for the alias name".to_string()),
1827							notes: vec![],
1828							cause: None,
1829							operator_chain: None,
1830						})
1831					}
1832				}
1833			}
1834			InfixOperator::AccessNamespace(_token) => {
1835				// Handle namespace access: `ns::func(args)` → CallExpression with namespaced name
1836				// Extract namespace name from left side (always an identifier)
1837				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1838				let namespace = match &left {
1839					Expression::Column(ColumnExpression(col)) => col.name.text().to_string(),
1840					other => unimplemented!("unsupported namespace expression: {other:?}"),
1841				};
1842
1843				// The right side may contain keywords (e.g. `undefined`) that should be
1844				// treated as identifiers in a namespace context. Extract the name from the
1845				// raw AST token before compiling, so keywords are treated as identifier_or_keyword.
1846				let right_ast = BumpBox::into_inner(ast.right);
1847				Self::compile_namespace_right(&namespace, right_ast)
1848			}
1849
1850			InfixOperator::AccessTable(token) => {
1851				let left = Self::compile(BumpBox::into_inner(ast.left))?;
1852				let right_ast = BumpBox::into_inner(ast.right);
1853				let field_name = right_ast.token().fragment.to_owned();
1854				let fragment = token.fragment.to_owned();
1855				Ok(Expression::FieldAccess(FieldAccessExpression {
1856					object: Box::new(left),
1857					field: field_name,
1858					fragment,
1859				}))
1860			}
1861		}
1862	}
1863
1864	/// Compile the right-hand side of a namespace access (`ns::...`).
1865	///
1866	/// Keywords like `undefined` or `true` are treated as identifiers in this
1867	/// context so that `is::none(x)` resolves to a function call rather
1868	/// than parsing `undefined` as the literal keyword.
1869	fn compile_namespace_right(namespace: &str, right_ast: Ast<'_>) -> Result<Expression> {
1870		// Helper: extract a token's text from any AST node that should be treated
1871		// as an identifier_or_keyword in namespace position.
1872		fn identifier_or_keyword_name(ast: &Ast<'_>) -> Option<String> {
1873			Some(ast.token().fragment.text().to_string())
1874		}
1875
1876		match right_ast {
1877			// ns::func(args)  where func is parsed as Infix(left, Call, right)
1878			Ast::Infix(infix) if matches!(infix.operator, InfixOperator::Call(_)) => {
1879				let func_name = identifier_or_keyword_name(&infix.left)
1880					.expect("namespace function name must be extractable");
1881				let full_name = format!("{}::{}", namespace, func_name);
1882
1883				let right = Self::compile(BumpBox::into_inner(infix.right))?;
1884				let Expression::Tuple(tuple) = right else {
1885					panic!("expected tuple arguments for namespaced call");
1886				};
1887
1888				Ok(Expression::Call(CallExpression {
1889					func: IdentExpression(Fragment::testing(&full_name)),
1890					args: tuple.expressions,
1891					fragment: infix.token.fragment.to_owned(),
1892				}))
1893			}
1894			// ns::func(args) where func is parsed as CallFunction
1895			// (happens when the namespace token is a keyword like `is`,
1896			// so the parser treats the right side as a standalone call)
1897			Ast::CallFunction(call) => {
1898				let func_name = call.function.name.text().to_string();
1899				let full_name = if call.function.namespaces.is_empty() {
1900					format!("{}::{}", namespace, func_name)
1901				} else {
1902					let sub_ns = call
1903						.function
1904						.namespaces
1905						.iter()
1906						.map(|ns| ns.text())
1907						.collect::<Vec<_>>()
1908						.join("::");
1909					format!("{}::{}::{}", namespace, sub_ns, func_name)
1910				};
1911
1912				let mut arg_expressions = Vec::new();
1913				for arg_ast in call.arguments.nodes {
1914					let compiled = Self::compile(arg_ast)?;
1915					let compiled = match &compiled {
1916						Expression::Column(col_expr) => {
1917							if let Ok(ty) = Type::from_str(col_expr.0.name.text()) {
1918								Expression::Type(TypeExpression {
1919									fragment: col_expr.0.name.clone(),
1920									ty,
1921								})
1922							} else {
1923								compiled
1924							}
1925						}
1926						_ => compiled,
1927					};
1928					arg_expressions.push(compiled);
1929				}
1930
1931				Ok(Expression::Call(CallExpression {
1932					func: IdentExpression(Fragment::testing(&full_name)),
1933					args: arg_expressions,
1934					fragment: call.token.fragment.to_owned(),
1935				}))
1936			}
1937			// ns::name  (bare namespaced reference, no call)
1938			other => {
1939				if let Some(name) = identifier_or_keyword_name(&other) {
1940					let full_name = format!("{}::{}", namespace, name);
1941					Ok(Expression::Column(ColumnExpression(ColumnIdentifier {
1942						shape: ColumnShape::Qualified {
1943							namespace: Fragment::Internal {
1944								text: Arc::from("_context"),
1945							},
1946							name: Fragment::Internal {
1947								text: Arc::from("_context"),
1948							},
1949						},
1950						name: Fragment::testing(&full_name),
1951					})))
1952				} else {
1953					let compiled = Self::compile(other)?;
1954					match compiled {
1955						Expression::Column(ColumnExpression(col)) => {
1956							let full_name = format!("{}::{}", namespace, col.name.text());
1957							Ok(Expression::Column(ColumnExpression(ColumnIdentifier {
1958								shape: col.shape,
1959								name: Fragment::testing(&full_name),
1960							})))
1961						}
1962						other => unimplemented!(
1963							"unsupported namespace right-hand side: {other:?}"
1964						),
1965					}
1966				}
1967			}
1968		}
1969	}
1970}
1971
1972#[derive(Debug, Clone, Serialize, Deserialize)]
1973pub struct MapExpression {
1974	pub expressions: Vec<Expression>,
1975	pub fragment: Fragment,
1976}
1977
1978#[derive(Debug, Clone, Serialize, Deserialize)]
1979pub struct ExtendExpression {
1980	pub expressions: Vec<Expression>,
1981	pub fragment: Fragment,
1982}
1983
1984#[derive(Debug, Clone, Serialize, Deserialize)]
1985pub struct SumTypeConstructorExpression {
1986	pub namespace: Fragment,
1987	pub sumtype_name: Fragment,
1988	pub variant_name: Fragment,
1989	pub columns: Vec<(Fragment, Expression)>,
1990	pub fragment: Fragment,
1991}
1992
1993#[derive(Debug, Clone, Serialize, Deserialize)]
1994pub struct IsVariantExpression {
1995	pub expression: Box<Expression>,
1996	pub namespace: Option<Fragment>,
1997	pub sumtype_name: Fragment,
1998	pub variant_name: Fragment,
1999	pub tag: Option<u8>,
2000	pub fragment: Fragment,
2001}
2002
2003#[derive(Debug, Clone, Serialize, Deserialize)]
2004pub struct FieldAccessExpression {
2005	pub object: Box<Expression>,
2006	pub field: Fragment,
2007	pub fragment: Fragment,
2008}
2009
2010impl FieldAccessExpression {
2011	pub fn full_fragment_owned(&self) -> Fragment {
2012		Fragment::merge_all([self.object.full_fragment_owned(), self.fragment.clone(), self.field.clone()])
2013	}
2014}
2015
2016impl Display for FieldAccessExpression {
2017	fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2018		write!(f, "{}.{}", self.object, self.field.text())
2019	}
2020}
2021
2022/// Recursively extract all variable names referenced in an expression tree.
2023pub fn extract_variable_names(expr: &Expression) -> Vec<String> {
2024	let mut names = Vec::new();
2025	collect_variable_names(expr, &mut names);
2026	names
2027}
2028
2029fn collect_variable_names(expr: &Expression, names: &mut Vec<String>) {
2030	match expr {
2031		Expression::Variable(v) => {
2032			let name = v.name().to_string();
2033			if !names.contains(&name) {
2034				names.push(name);
2035			}
2036		}
2037		Expression::Add(e) => {
2038			collect_variable_names(&e.left, names);
2039			collect_variable_names(&e.right, names);
2040		}
2041		Expression::Sub(e) => {
2042			collect_variable_names(&e.left, names);
2043			collect_variable_names(&e.right, names);
2044		}
2045		Expression::Mul(e) => {
2046			collect_variable_names(&e.left, names);
2047			collect_variable_names(&e.right, names);
2048		}
2049		Expression::Div(e) => {
2050			collect_variable_names(&e.left, names);
2051			collect_variable_names(&e.right, names);
2052		}
2053		Expression::Rem(e) => {
2054			collect_variable_names(&e.left, names);
2055			collect_variable_names(&e.right, names);
2056		}
2057		Expression::GreaterThan(e) => {
2058			collect_variable_names(&e.left, names);
2059			collect_variable_names(&e.right, names);
2060		}
2061		Expression::GreaterThanEqual(e) => {
2062			collect_variable_names(&e.left, names);
2063			collect_variable_names(&e.right, names);
2064		}
2065		Expression::LessThan(e) => {
2066			collect_variable_names(&e.left, names);
2067			collect_variable_names(&e.right, names);
2068		}
2069		Expression::LessThanEqual(e) => {
2070			collect_variable_names(&e.left, names);
2071			collect_variable_names(&e.right, names);
2072		}
2073		Expression::Equal(e) => {
2074			collect_variable_names(&e.left, names);
2075			collect_variable_names(&e.right, names);
2076		}
2077		Expression::NotEqual(e) => {
2078			collect_variable_names(&e.left, names);
2079			collect_variable_names(&e.right, names);
2080		}
2081		Expression::And(e) => {
2082			collect_variable_names(&e.left, names);
2083			collect_variable_names(&e.right, names);
2084		}
2085		Expression::Or(e) => {
2086			collect_variable_names(&e.left, names);
2087			collect_variable_names(&e.right, names);
2088		}
2089		Expression::Xor(e) => {
2090			collect_variable_names(&e.left, names);
2091			collect_variable_names(&e.right, names);
2092		}
2093		Expression::Between(e) => {
2094			collect_variable_names(&e.value, names);
2095			collect_variable_names(&e.lower, names);
2096			collect_variable_names(&e.upper, names);
2097		}
2098		Expression::In(e) => {
2099			collect_variable_names(&e.value, names);
2100			collect_variable_names(&e.list, names);
2101		}
2102		Expression::Contains(e) => {
2103			collect_variable_names(&e.value, names);
2104			collect_variable_names(&e.list, names);
2105		}
2106		Expression::Prefix(e) => collect_variable_names(&e.expression, names),
2107		Expression::Cast(e) => collect_variable_names(&e.expression, names),
2108		Expression::Alias(e) => collect_variable_names(&e.expression, names),
2109		Expression::Call(e) => {
2110			for arg in &e.args {
2111				collect_variable_names(arg, names);
2112			}
2113		}
2114		Expression::Tuple(e) => {
2115			for expr in &e.expressions {
2116				collect_variable_names(expr, names);
2117			}
2118		}
2119		Expression::List(e) => {
2120			for expr in &e.expressions {
2121				collect_variable_names(expr, names);
2122			}
2123		}
2124		Expression::If(e) => {
2125			collect_variable_names(&e.condition, names);
2126			collect_variable_names(&e.then_expr, names);
2127			for else_if in &e.else_ifs {
2128				collect_variable_names(&else_if.condition, names);
2129				collect_variable_names(&else_if.then_expr, names);
2130			}
2131			if let Some(else_expr) = &e.else_expr {
2132				collect_variable_names(else_expr, names);
2133			}
2134		}
2135		Expression::Map(e) => {
2136			for expr in &e.expressions {
2137				collect_variable_names(expr, names);
2138			}
2139		}
2140		Expression::Extend(e) => {
2141			for expr in &e.expressions {
2142				collect_variable_names(expr, names);
2143			}
2144		}
2145		Expression::SumTypeConstructor(e) => {
2146			for (_, expr) in &e.columns {
2147				collect_variable_names(expr, names);
2148			}
2149		}
2150		Expression::IsVariant(e) => collect_variable_names(&e.expression, names),
2151		Expression::FieldAccess(e) => collect_variable_names(&e.object, names),
2152		// Leaf nodes with no sub-expressions
2153		Expression::Constant(_)
2154		| Expression::Column(_)
2155		| Expression::AccessSource(_)
2156		| Expression::Parameter(_)
2157		| Expression::Type(_) => {}
2158	}
2159}