reifydb_engine/expression/
prefix.rs1use reifydb_core::{
5 error::diagnostic::engine::frame_error,
6 value::column::{Column, data::ColumnData},
7};
8use reifydb_function::registry::Functions;
9use reifydb_rql::expression::{PrefixExpression, PrefixOperator};
10use reifydb_runtime::clock::Clock;
11use reifydb_type::{
12 err,
13 error::diagnostic::{
14 operator,
15 operator::{
16 not_can_not_applied_to_number, not_can_not_applied_to_temporal, not_can_not_applied_to_uuid,
17 },
18 },
19 value::{decimal::Decimal, int::Int, uint::Uint},
20};
21
22use crate::expression::context::EvalContext;
23
24pub(crate) fn prefix_eval(
25 ctx: &EvalContext,
26 prefix: &PrefixExpression,
27 functions: &Functions,
28 clock: &Clock,
29) -> crate::Result<Column> {
30 let inner_ctx = EvalContext {
31 target: None,
32 columns: ctx.columns.clone(),
33 row_count: ctx.row_count,
34 take: ctx.take,
35 params: ctx.params,
36 symbol_table: ctx.symbol_table,
37 is_aggregate_context: ctx.is_aggregate_context,
38 functions: ctx.functions,
39 clock: ctx.clock,
40 arena: None,
41 };
42 let column = super::eval::evaluate(&inner_ctx, &prefix.expression, functions, clock)?;
43
44 crate::expression::option::unary_op_unwrap_option(&column, |column| match column.data() {
45 ColumnData::Bool(container) => match prefix.operator {
46 PrefixOperator::Not(_) => {
47 let mut result = Vec::with_capacity(container.data().len());
48 for (idx, val) in container.data().iter().enumerate() {
49 if container.is_defined(idx) {
50 result.push(!val);
51 } else {
52 result.push(false);
53 }
54 }
55
56 let new_data = ColumnData::bool(result);
57 Ok(column.with_new_data(new_data))
58 }
59 _ => err!(frame_error("Cannot apply arithmetic prefix operator to bool".to_string())),
60 },
61
62 ColumnData::Float4(container) => {
63 let mut result = Vec::with_capacity(container.data().len());
64 for (idx, val) in container.data().iter().enumerate() {
65 if container.is_defined(idx) {
66 result.push(match prefix.operator {
67 PrefixOperator::Minus(_) => -*val,
68 PrefixOperator::Plus(_) => *val,
69 PrefixOperator::Not(_) => {
70 return err!(not_can_not_applied_to_number(
71 prefix.full_fragment_owned()
72 ));
73 }
74 });
75 } else {
76 result.push(0.0f32);
77 }
78 }
79 let new_data = ColumnData::float4(result);
80 Ok(column.with_new_data(new_data))
81 }
82
83 ColumnData::Float8(container) => {
84 let mut result = Vec::with_capacity(container.data().len());
85 for (idx, val) in container.data().iter().enumerate() {
86 if container.is_defined(idx) {
87 result.push(match prefix.operator {
88 PrefixOperator::Minus(_) => -*val,
89 PrefixOperator::Plus(_) => *val,
90 PrefixOperator::Not(_) => {
91 return err!(not_can_not_applied_to_number(
92 prefix.full_fragment_owned()
93 ));
94 }
95 });
96 } else {
97 result.push(0.0f64);
98 }
99 }
100 let new_data = ColumnData::float8(result);
101 Ok(column.with_new_data(new_data))
102 }
103
104 ColumnData::Int1(container) => {
105 let mut result = Vec::with_capacity(container.data().len());
106 for (idx, val) in container.data().iter().enumerate() {
107 if container.is_defined(idx) {
108 result.push(match prefix.operator {
109 PrefixOperator::Minus(_) => -*val,
110 PrefixOperator::Plus(_) => *val,
111 PrefixOperator::Not(_) => {
112 return err!(not_can_not_applied_to_number(
113 prefix.full_fragment_owned()
114 ));
115 }
116 });
117 } else {
118 result.push(0);
119 }
120 }
121 let new_data = ColumnData::int1(result);
122 Ok(column.with_new_data(new_data))
123 }
124
125 ColumnData::Int2(container) => {
126 let mut result = Vec::with_capacity(container.data().len());
127 for (idx, val) in container.data().iter().enumerate() {
128 if container.is_defined(idx) {
129 result.push(match prefix.operator {
130 PrefixOperator::Minus(_) => -*val,
131 PrefixOperator::Plus(_) => *val,
132 PrefixOperator::Not(_) => {
133 return err!(not_can_not_applied_to_number(
134 prefix.full_fragment_owned()
135 ));
136 }
137 });
138 } else {
139 result.push(0);
140 }
141 }
142 let new_data = ColumnData::int2(result);
143 Ok(column.with_new_data(new_data))
144 }
145
146 ColumnData::Int4(container) => {
147 let mut result = Vec::with_capacity(container.data().len());
148 for (idx, val) in container.data().iter().enumerate() {
149 if container.is_defined(idx) {
150 result.push(match prefix.operator {
151 PrefixOperator::Minus(_) => -*val,
152 PrefixOperator::Plus(_) => *val,
153 PrefixOperator::Not(_) => {
154 return err!(not_can_not_applied_to_number(
155 prefix.full_fragment_owned()
156 ));
157 }
158 });
159 } else {
160 result.push(0);
161 }
162 }
163 let new_data = ColumnData::int4(result);
164 Ok(column.with_new_data(new_data))
165 }
166
167 ColumnData::Int8(container) => {
168 let mut result = Vec::with_capacity(container.data().len());
169 for (idx, val) in container.data().iter().enumerate() {
170 if container.is_defined(idx) {
171 result.push(match prefix.operator {
172 PrefixOperator::Minus(_) => -*val,
173 PrefixOperator::Plus(_) => *val,
174 PrefixOperator::Not(_) => {
175 return err!(not_can_not_applied_to_number(
176 prefix.full_fragment_owned()
177 ));
178 }
179 });
180 } else {
181 result.push(0);
182 }
183 }
184 let new_data = ColumnData::int8(result);
185 Ok(column.with_new_data(new_data))
186 }
187
188 ColumnData::Int16(container) => {
189 let mut result = Vec::with_capacity(container.data().len());
190 for (idx, val) in container.data().iter().enumerate() {
191 if container.is_defined(idx) {
192 result.push(match prefix.operator {
193 PrefixOperator::Minus(_) => -*val,
194 PrefixOperator::Plus(_) => *val,
195 PrefixOperator::Not(_) => {
196 return err!(not_can_not_applied_to_number(
197 prefix.full_fragment_owned()
198 ));
199 }
200 });
201 } else {
202 result.push(0);
203 }
204 }
205 let new_data = ColumnData::int16(result);
206 Ok(column.with_new_data(new_data))
207 }
208
209 ColumnData::Utf8 {
210 container: _,
211 ..
212 } => match prefix.operator {
213 PrefixOperator::Not(_) => {
214 err!(operator::not_can_not_applied_to_text(prefix.full_fragment_owned()))
215 }
216 _ => err!(frame_error("Cannot apply arithmetic prefix operator to text".to_string())),
217 },
218
219 ColumnData::Uint1(container) => {
220 let mut result = Vec::with_capacity(container.data().len());
221 for val in container.data().iter() {
222 let signed = *val as i8;
223 result.push(match prefix.operator {
224 PrefixOperator::Minus(_) => -signed,
225 PrefixOperator::Plus(_) => signed,
226 PrefixOperator::Not(_) => {
227 return err!(not_can_not_applied_to_number(
228 prefix.full_fragment_owned()
229 ));
230 }
231 });
232 }
233 let new_data = ColumnData::int1(result);
234 Ok(column.with_new_data(new_data))
235 }
236
237 ColumnData::Uint2(container) => {
238 let mut result = Vec::with_capacity(container.data().len());
239 for val in container.data().iter() {
240 let signed = *val as i16;
241 result.push(match prefix.operator {
242 PrefixOperator::Minus(_) => -signed,
243 PrefixOperator::Plus(_) => signed,
244 PrefixOperator::Not(_) => {
245 return err!(not_can_not_applied_to_number(
246 prefix.full_fragment_owned()
247 ));
248 }
249 });
250 }
251 let new_data = ColumnData::int2(result);
252 Ok(column.with_new_data(new_data))
253 }
254
255 ColumnData::Uint4(container) => {
256 let mut result = Vec::with_capacity(container.data().len());
257 for val in container.data().iter() {
258 let signed = *val as i32;
259 result.push(match prefix.operator {
260 PrefixOperator::Minus(_) => -signed,
261 PrefixOperator::Plus(_) => signed,
262 PrefixOperator::Not(_) => {
263 return err!(not_can_not_applied_to_number(
264 prefix.full_fragment_owned()
265 ));
266 }
267 });
268 }
269 let new_data = ColumnData::int4(result);
270 Ok(column.with_new_data(new_data))
271 }
272
273 ColumnData::Uint8(container) => {
274 let mut result = Vec::with_capacity(container.data().len());
275 for val in container.data().iter() {
276 let signed = *val as i64;
277 result.push(match prefix.operator {
278 PrefixOperator::Minus(_) => -signed,
279 PrefixOperator::Plus(_) => signed,
280 PrefixOperator::Not(_) => {
281 return err!(not_can_not_applied_to_number(
282 prefix.full_fragment_owned()
283 ));
284 }
285 });
286 }
287 let new_data = ColumnData::int8(result);
288 Ok(column.with_new_data(new_data))
289 }
290 ColumnData::Uint16(container) => {
291 let mut result = Vec::with_capacity(container.data().len());
292 for val in container.data().iter() {
293 let signed = *val as i128;
294 result.push(match prefix.operator {
295 PrefixOperator::Minus(_) => -signed,
296 PrefixOperator::Plus(_) => signed,
297 PrefixOperator::Not(_) => {
298 return err!(not_can_not_applied_to_number(
299 prefix.full_fragment_owned()
300 ));
301 }
302 });
303 }
304 let new_data = ColumnData::int16(result);
305 Ok(column.with_new_data(new_data))
306 }
307 ColumnData::Date(_) => match prefix.operator {
308 PrefixOperator::Not(_) => {
309 err!(not_can_not_applied_to_temporal(prefix.full_fragment_owned()))
310 }
311 _ => unimplemented!(),
312 },
313 ColumnData::DateTime(_) => match prefix.operator {
314 PrefixOperator::Not(_) => {
315 err!(not_can_not_applied_to_temporal(prefix.full_fragment_owned()))
316 }
317 _ => unimplemented!(),
318 },
319 ColumnData::Time(_) => match prefix.operator {
320 PrefixOperator::Not(_) => {
321 err!(not_can_not_applied_to_temporal(prefix.full_fragment_owned()))
322 }
323 _ => unimplemented!(),
324 },
325 ColumnData::Duration(_) => match prefix.operator {
326 PrefixOperator::Not(_) => {
327 err!(not_can_not_applied_to_temporal(prefix.full_fragment_owned()))
328 }
329 _ => unimplemented!(),
330 },
331 ColumnData::IdentityId(_) => match prefix.operator {
332 PrefixOperator::Not(_) => {
333 err!(not_can_not_applied_to_uuid(prefix.full_fragment_owned()))
334 }
335 _ => unimplemented!(),
336 },
337 ColumnData::Uuid4(_) => match prefix.operator {
338 PrefixOperator::Not(_) => {
339 err!(not_can_not_applied_to_uuid(prefix.full_fragment_owned()))
340 }
341 _ => unimplemented!(),
342 },
343 ColumnData::Uuid7(_) => match prefix.operator {
344 PrefixOperator::Not(_) => {
345 err!(not_can_not_applied_to_uuid(prefix.full_fragment_owned()))
346 }
347 _ => unimplemented!(),
348 },
349 ColumnData::Blob {
350 container: _,
351 ..
352 } => match prefix.operator {
353 PrefixOperator::Not(_) => {
354 err!(frame_error("Cannot apply NOT operator to BLOB".to_string()))
355 }
356 _ => err!(frame_error("Cannot apply arithmetic prefix operator to BLOB".to_string())),
357 },
358 ColumnData::Int {
359 container,
360 ..
361 } => {
362 let mut result = Vec::with_capacity(container.data().len());
363 for (idx, val) in container.data().iter().enumerate() {
364 if container.is_defined(idx) {
365 result.push(match prefix.operator {
366 PrefixOperator::Minus(_) => Int(-val.0.clone()),
367 PrefixOperator::Plus(_) => val.clone(),
368 PrefixOperator::Not(_) => {
369 return err!(not_can_not_applied_to_number(
370 prefix.full_fragment_owned()
371 ));
372 }
373 });
374 } else {
375 result.push(Int::zero());
376 }
377 }
378 let new_data = ColumnData::int(result);
379 Ok(column.with_new_data(new_data))
380 }
381 ColumnData::Uint {
382 container,
383 ..
384 } => match prefix.operator {
385 PrefixOperator::Minus(_) => {
386 let mut result = Vec::with_capacity(container.data().len());
387 for (idx, val) in container.data().iter().enumerate() {
388 if container.is_defined(idx) {
389 let negated = -val.0.clone();
390 result.push(Int::from(negated));
391 } else {
392 result.push(Int::zero());
393 }
394 }
395 let new_data = ColumnData::int(result);
396 Ok(column.with_new_data(new_data))
397 }
398 PrefixOperator::Plus(_) => {
399 let mut result = Vec::with_capacity(container.data().len());
400 for (idx, val) in container.data().iter().enumerate() {
401 if container.is_defined(idx) {
402 result.push(val.clone());
403 } else {
404 result.push(Uint::zero());
405 }
406 }
407 let new_data = ColumnData::uint(result);
408 Ok(column.with_new_data(new_data))
409 }
410 PrefixOperator::Not(_) => {
411 err!(not_can_not_applied_to_number(prefix.full_fragment_owned()))
412 }
413 },
414 ColumnData::Decimal {
415 container,
416 ..
417 } => {
418 let mut result = Vec::with_capacity(container.data().len());
419 for (idx, val) in container.data().iter().enumerate() {
420 if container.is_defined(idx) {
421 result.push(match prefix.operator {
422 PrefixOperator::Minus(_) => val.clone().negate(),
423 PrefixOperator::Plus(_) => val.clone(),
424 PrefixOperator::Not(_) => {
425 return err!(not_can_not_applied_to_number(
426 prefix.full_fragment_owned()
427 ));
428 }
429 });
430 } else {
431 result.push(Decimal::from(0));
432 }
433 }
434 let new_data = ColumnData::decimal(result);
435 Ok(column.with_new_data(new_data))
436 }
437 ColumnData::DictionaryId(_) => match prefix.operator {
438 PrefixOperator::Not(_) => {
439 err!(frame_error("Cannot apply NOT operator to DictionaryId type".to_string()))
440 }
441 _ => err!(frame_error(
442 "Cannot apply arithmetic prefix operator to DictionaryId type".to_string()
443 )),
444 },
445 ColumnData::Any(_) => match prefix.operator {
446 PrefixOperator::Not(_) => {
447 err!(frame_error("Cannot apply NOT operator to Any type".to_string()))
448 }
449 _ => err!(frame_error("Cannot apply arithmetic prefix operator to Any type".to_string())),
450 },
451 ColumnData::Option {
452 ..
453 } => unreachable!("nested Option after unwrap"),
454 })
455}