1use 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}