Skip to main content

reifydb_rql/expression/
fragment.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3use reifydb_value::{
4	fragment::Fragment,
5	value::{
6		Value,
7		boolean::parse::parse_bool,
8		decimal::parse::parse_decimal,
9		number::parse::{parse_primitive_int, parse_primitive_uint},
10	},
11};
12
13use crate::expression::{
14	AddExpression, CastExpression, ConstantExpression, DivExpression, Expression, MulExpression,
15	ParameterExpression, RemExpression, SubExpression,
16};
17
18impl Expression {
19	pub fn lazy_fragment(&self) -> impl Fn() -> Fragment {
20		move || match self {
21			Expression::AccessSource(expr) => expr.full_fragment_owned(),
22			Expression::Alias(expr) => expr.expression.full_fragment_owned(),
23			Expression::Cast(CastExpression {
24				expression: expr,
25				..
26			}) => expr.full_fragment_owned(),
27			Expression::Constant(expr) => match expr {
28				ConstantExpression::None {
29					fragment,
30				}
31				| ConstantExpression::Bool {
32					fragment,
33				}
34				| ConstantExpression::Number {
35					fragment,
36				}
37				| ConstantExpression::Temporal {
38					fragment,
39				}
40				| ConstantExpression::Text {
41					fragment,
42				} => fragment.clone(),
43			},
44			Expression::Column(expr) => expr.full_fragment_owned(),
45
46			Expression::Add(expr) => expr.full_fragment_owned(),
47			Expression::Sub(expr) => expr.full_fragment_owned(),
48			Expression::GreaterThan(expr) => expr.full_fragment_owned(),
49			Expression::GreaterThanEqual(expr) => expr.full_fragment_owned(),
50			Expression::LessThan(expr) => expr.full_fragment_owned(),
51			Expression::LessThanEqual(expr) => expr.full_fragment_owned(),
52			Expression::Equal(expr) => expr.full_fragment_owned(),
53			Expression::NotEqual(expr) => expr.full_fragment_owned(),
54			Expression::Between(expr) => expr.full_fragment_owned(),
55			Expression::And(expr) => expr.full_fragment_owned(),
56			Expression::Or(expr) => expr.full_fragment_owned(),
57			Expression::Xor(expr) => expr.full_fragment_owned(),
58
59			Expression::Mul(expr) => expr.full_fragment_owned(),
60			Expression::Div(expr) => expr.full_fragment_owned(),
61			Expression::Rem(expr) => expr.full_fragment_owned(),
62
63			Expression::Tuple(expr) => {
64				let fragments =
65					expr.expressions.iter().map(|e| e.full_fragment_owned()).collect::<Vec<_>>();
66				Fragment::merge_all(fragments)
67			}
68			Expression::List(expr) => {
69				let fragments =
70					expr.expressions.iter().map(|e| e.full_fragment_owned()).collect::<Vec<_>>();
71				Fragment::merge_all(fragments)
72			}
73			Expression::Type(expr) => expr.fragment.clone(),
74
75			Expression::Prefix(expr) => expr.full_fragment_owned(),
76
77			Expression::Call(expr) => expr.full_fragment_owned(),
78			Expression::Parameter(param) => match param {
79				ParameterExpression::Positional {
80					fragment,
81					..
82				} => fragment.clone(),
83				ParameterExpression::Named {
84					fragment,
85				} => fragment.clone(),
86			},
87			Expression::Variable(var) => var.fragment.clone(),
88			Expression::If(if_expr) => if_expr.full_fragment_owned(),
89			Expression::Map(map_expr) => map_expr.fragment.clone(),
90			Expression::Extend(extend_expr) => extend_expr.fragment.clone(),
91			Expression::In(in_expr) => in_expr.fragment.clone(),
92			Expression::Contains(contains_expr) => contains_expr.fragment.clone(),
93			Expression::SumTypeConstructor(ctor) => ctor.fragment.clone(),
94			Expression::IsVariant(e) => e.fragment.clone(),
95			Expression::FieldAccess(expr) => expr.full_fragment_owned(),
96		}
97	}
98}
99
100impl AddExpression {
101	pub fn full_fragment_owned(&self) -> Fragment {
102		Fragment::merge_all([
103			self.left.full_fragment_owned(),
104			self.fragment.clone(),
105			self.right.full_fragment_owned(),
106		])
107	}
108}
109
110impl ConstantExpression {
111	pub fn full_fragment_owned(&self) -> Fragment {
112		match self {
113			ConstantExpression::None {
114				fragment,
115			} => fragment.clone(),
116			ConstantExpression::Bool {
117				fragment,
118			} => fragment.clone(),
119			ConstantExpression::Number {
120				fragment,
121			} => fragment.clone(),
122			ConstantExpression::Temporal {
123				fragment,
124			} => fragment.clone(),
125			ConstantExpression::Text {
126				fragment,
127			} => fragment.clone(),
128		}
129	}
130
131	pub fn to_value(&self) -> Value {
132		match self {
133			Self::None {
134				..
135			} => Value::none(),
136			Self::Bool {
137				fragment,
138			} => parse_bool(fragment.clone()).map(Value::Boolean).unwrap_or(Value::none()),
139			Self::Number {
140				fragment,
141			} => Self::parse_number(fragment),
142			Self::Text {
143				fragment,
144			} => Value::Utf8(fragment.text().to_string()),
145			Self::Temporal {
146				fragment,
147			} => Value::Utf8(fragment.text().to_string()),
148		}
149	}
150
151	fn parse_number(fragment: &Fragment) -> Value {
152		let text = fragment.text();
153		if text.contains('.') || text.contains('e') || text.contains('E') {
154			return parse_decimal(fragment.clone()).map(Value::Decimal).unwrap_or(Value::none());
155		}
156		parse_primitive_int::<i8>(fragment.clone())
157			.map(Value::Int1)
158			.or_else(|_| parse_primitive_int::<i16>(fragment.clone()).map(Value::Int2))
159			.or_else(|_| parse_primitive_int::<i32>(fragment.clone()).map(Value::Int4))
160			.or_else(|_| parse_primitive_int::<i64>(fragment.clone()).map(Value::Int8))
161			.or_else(|_| parse_primitive_int::<i128>(fragment.clone()).map(Value::Int16))
162			.or_else(|_| parse_primitive_uint::<u128>(fragment.clone()).map(Value::Uint16))
163			.unwrap_or(Value::none())
164	}
165}
166
167impl SubExpression {
168	pub fn full_fragment_owned(&self) -> Fragment {
169		Fragment::merge_all([
170			self.left.full_fragment_owned(),
171			self.fragment.clone(),
172			self.right.full_fragment_owned(),
173		])
174	}
175}
176
177impl MulExpression {
178	pub fn full_fragment_owned(&self) -> Fragment {
179		Fragment::merge_all([
180			self.left.full_fragment_owned(),
181			self.fragment.clone(),
182			self.right.full_fragment_owned(),
183		])
184	}
185}
186
187impl DivExpression {
188	pub fn full_fragment_owned(&self) -> Fragment {
189		Fragment::merge_all([
190			self.left.full_fragment_owned(),
191			self.fragment.clone(),
192			self.right.full_fragment_owned(),
193		])
194	}
195}
196
197impl RemExpression {
198	pub fn full_fragment_owned(&self) -> Fragment {
199		Fragment::merge_all([
200			self.left.full_fragment_owned(),
201			self.fragment.clone(),
202			self.right.full_fragment_owned(),
203		])
204	}
205}
206
207impl Expression {
208	pub fn full_fragment_owned(&self) -> Fragment {
209		self.lazy_fragment()()
210	}
211}