Skip to main content

reifydb_core/expression/
fragment.rs

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