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