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