1#[cfg(test)]
16mod tests;
17
18use std::collections::BTreeMap;
19use std::sync::Arc;
20
21use async_recursion::async_recursion;
22use chrono::{
23 Datelike, Duration, LocalResult, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Weekday,
24};
25use drasi_query_ast::ast;
26
27use crate::evaluation::temporal_constants::{
28 self, EPOCH_MIDNIGHT_NAIVE_DATETIME, MIDNIGHT_NAIVE_TIME, UTC_FIXED_OFFSET,
29};
30use crate::evaluation::variable_value::duration::Duration as DurationStruct;
31use crate::evaluation::variable_value::float::Float;
32use crate::evaluation::variable_value::integer::Integer;
33use crate::evaluation::variable_value::zoned_datetime::ZonedDateTime;
34use crate::evaluation::variable_value::zoned_time::ZonedTime;
35use crate::evaluation::variable_value::{ListRange, RangeBound};
36use crate::interface::{ResultKey, ResultOwner};
37use crate::{evaluation::variable_value::VariableValue, interface::ResultIndex};
38
39use super::{
40 context::{ExpressionEvaluationContext, SideEffects},
41 functions::{aggregation::Accumulator, Function, FunctionRegistry},
42 EvaluationError, FunctionEvaluationError,
43};
44
45pub struct ExpressionEvaluator {
46 functions: Arc<FunctionRegistry>,
47 result_index: Arc<dyn ResultIndex>,
48}
49
50impl ExpressionEvaluator {
51 pub fn new(
52 functions: Arc<FunctionRegistry>,
53 result_index: Arc<dyn ResultIndex>,
54 ) -> ExpressionEvaluator {
55 ExpressionEvaluator {
56 functions,
57 result_index,
58 }
59 }
60
61 #[async_recursion]
62 pub async fn evaluate_expression(
63 &self,
64 context: &ExpressionEvaluationContext<'_>,
65 expression: &ast::Expression,
66 ) -> Result<VariableValue, EvaluationError> {
67 match expression {
68 ast::Expression::UnaryExpression(expression) => {
69 self.evaluate_unary_expression(context, expression).await
70 }
71 ast::Expression::BinaryExpression(expression) => {
72 self.evaluate_binary_expression(context, expression).await
73 }
74 ast::Expression::FunctionExpression(expression) => {
75 self.evaluate_function_expression(context, expression).await
76 }
77 ast::Expression::CaseExpression(expression) => {
78 self.evaluate_case_expression(context, expression).await
79 }
80 ast::Expression::ListExpression(expression) => {
81 self.evaluate_list_expression(context, expression).await
82 }
83 ast::Expression::ObjectExpression(expression) => {
84 self.evaluate_object_expression(context, expression).await
85 }
86 ast::Expression::IteratorExpression(expression) => {
87 self.evaluate_iterator_expression(context, expression).await
88 }
89 }
90 }
91
92 pub async fn evaluate_predicate(
93 &self,
94 context: &ExpressionEvaluationContext<'_>,
95 expression: &ast::Expression,
96 ) -> Result<bool, EvaluationError> {
97 let value = self.evaluate_expression(context, expression).await?;
98 match value {
99 VariableValue::Bool(b) => Ok(b),
101 _ => Ok(false),
102 }
103 }
104
105 pub async fn evaluate_projection_field(
106 &self,
107 context: &ExpressionEvaluationContext<'_>,
108 expression: &ast::Expression,
109 ) -> Result<(String, VariableValue), EvaluationError> {
110 let value = self.evaluate_expression(context, expression).await?;
111 let alias = match expression {
112 ast::Expression::UnaryExpression(expression) => match expression {
113 ast::UnaryExpression::Property { name: _, key } => key,
114 ast::UnaryExpression::Parameter(p) => p,
115 ast::UnaryExpression::Alias { source: _, alias } => alias,
116 ast::UnaryExpression::Identifier(id) => id,
117 _ => "expression",
118 },
119 ast::Expression::BinaryExpression(_) => "expression",
120 ast::Expression::FunctionExpression(f) => &f.name,
121 ast::Expression::CaseExpression(_) => "case",
122 ast::Expression::ListExpression(_) => "list",
123 ast::Expression::ObjectExpression(_) => "object",
124 ast::Expression::IteratorExpression(_) => "iterator",
125 };
126
127 Ok((alias.to_string(), value))
128 }
129
130 #[async_recursion]
131 async fn evaluate_unary_expression(
132 &self,
133 context: &ExpressionEvaluationContext<'_>,
134 expression: &ast::UnaryExpression,
135 ) -> Result<VariableValue, EvaluationError> {
136 let result = match expression {
137 ast::UnaryExpression::Not(expression) => {
138 VariableValue::Bool(!self.evaluate_predicate(context, expression).await?)
139 }
140 ast::UnaryExpression::Exists(_) => todo!(),
141 ast::UnaryExpression::IsNull(e) => {
142 VariableValue::Bool(self.evaluate_expression(context, e).await?.is_null())
143 }
144 ast::UnaryExpression::IsNotNull(e) => {
145 VariableValue::Bool(!self.evaluate_expression(context, e).await?.is_null())
146 }
147 ast::UnaryExpression::Literal(l) => match l {
148 ast::Literal::Boolean(b) => VariableValue::Bool(*b),
149 ast::Literal::Text(t) => VariableValue::String(t.to_string()),
150 ast::Literal::Null => VariableValue::Null,
151 ast::Literal::Date(_) => VariableValue::Date(*temporal_constants::EPOCH_NAIVE_DATE),
152 ast::Literal::Integer(i) => VariableValue::Integer(Integer::from(
153 match serde_json::Number::from(*i).as_i64() {
154 Some(n) => n,
155 None => return Err(EvaluationError::ParseError),
156 },
157 )),
158 ast::Literal::Real(r) => match serde_json::Number::from_f64(*r) {
159 Some(n) => VariableValue::Float(Float::from(match n.as_f64() {
160 Some(n) => n,
161 None => return Err(EvaluationError::ParseError),
162 })),
163 None => VariableValue::Null,
164 },
165 ast::Literal::LocalTime(_t) => VariableValue::LocalTime(*MIDNIGHT_NAIVE_TIME),
166 ast::Literal::ZonedTime(_t) => VariableValue::ZonedTime(ZonedTime::new(
167 *MIDNIGHT_NAIVE_TIME,
168 *UTC_FIXED_OFFSET,
169 )),
170 ast::Literal::LocalDateTime(_dt) => {
171 VariableValue::LocalDateTime(*EPOCH_MIDNIGHT_NAIVE_DATETIME)
172 }
173 ast::Literal::ZonedDateTime(_dt) => {
174 let local_datetime = *EPOCH_MIDNIGHT_NAIVE_DATETIME;
175 VariableValue::ZonedDateTime(ZonedDateTime::new(
176 match local_datetime.and_local_timezone(*UTC_FIXED_OFFSET) {
177 LocalResult::Single(dt) => dt,
178 _ => {
179 return Err(EvaluationError::InvalidType {
180 expected: "DateTime".to_string(),
181 })
182 }
183 },
184 None,
185 ))
186 }
187 ast::Literal::Duration(_d) => {
188 VariableValue::Duration(DurationStruct::new(chrono::Duration::zero(), 0, 0))
189 }
190 ast::Literal::Object(o) => {
191 let mut map = BTreeMap::new();
192 for (key, value) in o {
193 let val = match value {
194 ast::Literal::Integer(i) => VariableValue::Integer(Integer::from(
195 match serde_json::Number::from(*i).as_i64() {
196 Some(n) => n,
197 None => return Err(EvaluationError::ParseError),
198 },
199 )),
200 ast::Literal::Text(s) => VariableValue::String(s.to_string()),
201 ast::Literal::Real(r) => match serde_json::Number::from_f64(*r) {
202 Some(n) => VariableValue::Float(Float::from(match n.as_f64() {
203 Some(n) => n,
204 None => return Err(EvaluationError::OverflowError),
205 })),
206 None => return Err(EvaluationError::ParseError),
207 },
208 _ => VariableValue::Null,
209 };
210 map.insert(key.to_string(), val);
211 }
212 VariableValue::Object(map)
213 }
214 ast::Literal::Expression(expr) => {
215 let expression = *expr.clone();
216 VariableValue::Expression(expression)
217 }
218 },
219 ast::UnaryExpression::Property { name, key } => {
220 match context.get_variable(name.clone()) {
221 Some(v) => match v {
222 VariableValue::Element(e) => e.get_property(key).into(),
223
224 VariableValue::Object(o) => match o.get(&key.to_string()) {
226 Some(v) => v.clone(),
227 None => VariableValue::Null,
228 },
229 VariableValue::Date(d) => {
230 match get_date_property(*d, (*key).to_string()).await {
231 Some(v) => VariableValue::Integer(v.into()),
232 None => {
233 return Err(EvaluationError::UnknownProperty {
234 property_name: (*key).to_string(),
235 })
236 }
237 }
238 }
239 VariableValue::LocalTime(t) => {
240 match get_local_time_property(*t, (*key).to_string()).await {
241 Some(v) => VariableValue::Integer(v.into()),
242 None => {
243 return Err(EvaluationError::UnknownProperty {
244 property_name: (*key).to_string(),
245 })
246 }
247 }
248 }
249 VariableValue::ZonedTime(t) => {
250 match get_time_property(*t, (*key).to_string()).await {
251 Some(v) => {
252 if (*key).to_string() == "timezone"
253 || (*key).to_string() == "offset"
254 {
255 VariableValue::String(v.to_string())
256 } else {
257 match v.parse::<i64>() {
258 Ok(parsed_num) => {
259 VariableValue::Integer(parsed_num.into())
260 }
261 Err(_) => {
262 return Err(EvaluationError::ParseError);
263 }
264 }
265 }
266 }
267 None => {
268 return Err(EvaluationError::UnknownProperty {
269 property_name: (*key).to_string(),
270 })
271 }
272 }
273 }
274 VariableValue::LocalDateTime(t) => {
275 match get_local_datetime_property(*t, (*key).to_string()).await {
276 Some(v) => VariableValue::Integer(v.into()),
277 None => {
278 return Err(EvaluationError::UnknownProperty {
279 property_name: (*key).to_string(),
280 })
281 }
282 }
283 }
284 VariableValue::ZonedDateTime(t) => {
285 match get_datetime_property(t.clone(), (*key).to_string()).await {
286 Some(v) => {
287 if (*key).to_string() == "timezone"
288 || (*key).to_string() == "offset"
289 {
290 VariableValue::String(v.to_string())
291 } else {
292 match v.parse::<i64>() {
293 Ok(parsed_num) => {
294 VariableValue::Integer(parsed_num.into())
295 }
296 Err(_) => {
297 return Err(EvaluationError::ParseError);
298 }
299 }
300 }
301 }
302 None => {
303 return Err(EvaluationError::UnknownProperty {
304 property_name: (*key).to_string(),
305 })
306 }
307 }
308 }
309 VariableValue::Duration(d) => {
310 match get_duration_property(d.clone(), (*key).to_string()).await {
311 Some(v) => VariableValue::Integer(v.into()),
312 None => {
313 return Err(EvaluationError::UnknownProperty {
314 property_name: (*key).to_string(),
315 })
316 }
317 }
318 }
319 _ => VariableValue::Null,
320 },
321 None => VariableValue::Null,
322 }
323 }
324 ast::UnaryExpression::ExpressionProperty { exp, key } => {
325 let v = self.evaluate_expression(context, exp).await?;
326 match v {
327 VariableValue::Object(o) => match o.get(&key.to_string()) {
329 Some(v) => v.clone(),
330 None => VariableValue::Null,
331 },
332 VariableValue::Date(d) => {
333 match get_date_property(d, (*key).to_string()).await {
334 Some(v) => VariableValue::Integer(v.into()),
335 None => {
336 return Err(EvaluationError::UnknownFunction((*key).to_string()))
337 }
338 }
339 }
340 VariableValue::LocalTime(t) => {
341 match get_local_time_property(t, (*key).to_string()).await {
342 Some(v) => VariableValue::Integer(v.into()),
343 None => {
344 return Err(EvaluationError::UnknownFunction((*key).to_string()))
345 }
346 }
347 }
348 VariableValue::ZonedTime(t) => match get_time_property(t, (*key).to_string())
349 .await
350 {
351 Some(v) => {
352 if (*key).to_string() == "timezone" || (*key).to_string() == "offset" {
353 VariableValue::String(v.to_string())
354 } else {
355 match v.parse::<i64>() {
356 Ok(parsed_num) => VariableValue::Integer(parsed_num.into()),
357 Err(_) => {
358 return Err(EvaluationError::ParseError);
359 }
360 }
361 }
362 }
363 None => return Err(EvaluationError::UnknownFunction((*key).to_string())),
364 },
365 VariableValue::LocalDateTime(t) => {
366 match get_local_datetime_property(t, (*key).to_string()).await {
367 Some(v) => VariableValue::Integer(v.into()),
368 None => {
369 return Err(EvaluationError::UnknownFunction((*key).to_string()))
370 }
371 }
372 }
373 VariableValue::ZonedDateTime(t) => {
374 match get_datetime_property(t.clone(), (*key).to_string()).await {
375 Some(v) => {
376 if (*key).to_string() == "timezone"
377 || (*key).to_string() == "offset"
378 {
379 VariableValue::String(v.to_string())
380 } else {
381 match v.parse::<i64>() {
382 Ok(parsed_num) => VariableValue::Integer(parsed_num.into()),
383 Err(_) => {
384 return Err(EvaluationError::ParseError);
385 }
386 }
387 }
388 }
389 None => {
390 return Err(EvaluationError::UnknownFunction((*key).to_string()))
391 }
392 }
393 }
394 VariableValue::Duration(d) => {
395 match get_duration_property(d.clone(), (*key).to_string()).await {
396 Some(v) => VariableValue::Integer(v.into()),
397 None => {
398 return Err(EvaluationError::UnknownFunction((*key).to_string()))
399 }
400 }
401 }
402 _ => VariableValue::Null,
403 }
404 }
405 ast::UnaryExpression::Parameter(p) => match context.get_variable(p.clone()) {
406 Some(v) => v.clone(),
407 None => VariableValue::Null,
408 },
409 ast::UnaryExpression::Variable { name, value } => {
410 let variable_value = self.evaluate_expression(context, value).await?;
413 let mut map = BTreeMap::new();
414 map.insert(name.to_string(), variable_value.clone());
415 VariableValue::Object(map)
416 }
417 ast::UnaryExpression::Alias { source, alias: _ } => {
418 self.evaluate_expression(context, source).await?
419 }
420 ast::UnaryExpression::Identifier(ident) => match context.get_variable(ident.clone()) {
421 Some(value) => value.clone(),
422 None => return Err(EvaluationError::UnknownIdentifier(ident.to_string())),
423 },
424 ast::UnaryExpression::ListRange {
425 start_bound,
426 end_bound,
427 } => match (start_bound, end_bound) {
428 (Some(start), Some(end)) => {
429 let start = self.evaluate_expression(context, start).await?;
430 if !start.is_i64() {
431 return Err(EvaluationError::OverflowError);
432 }
433 let end = self.evaluate_expression(context, end).await?;
434 if !end.is_i64() {
435 return Err(EvaluationError::OverflowError);
436 }
437 VariableValue::ListRange(ListRange {
438 start: RangeBound::Index(match start.as_i64() {
439 Some(n) => n,
440 None => return Err(EvaluationError::OverflowError),
441 }),
442 end: RangeBound::Index(match end.as_i64() {
443 Some(n) => n,
444 None => return Err(EvaluationError::OverflowError),
445 }),
446 })
447 }
448 (Some(start), None) => {
449 let start = self.evaluate_expression(context, start).await?;
450 VariableValue::ListRange(ListRange {
451 start: RangeBound::Index(match start.as_i64() {
452 Some(n) => n,
453 None => return Err(EvaluationError::OverflowError),
454 }),
455 end: RangeBound::Unbounded,
456 })
457 }
458 (None, Some(end)) => {
459 let end = self.evaluate_expression(context, end).await?;
460 VariableValue::ListRange(ListRange {
461 start: RangeBound::Unbounded,
462 end: RangeBound::Index(match end.as_i64() {
463 Some(n) => n,
464 None => return Err(EvaluationError::OverflowError),
465 }),
466 })
467 }
468 (None, None) => VariableValue::ListRange(ListRange {
469 start: RangeBound::Unbounded,
470 end: RangeBound::Unbounded,
471 }),
472 },
473 };
474 Ok(result)
475 }
476
477 #[async_recursion]
478 async fn evaluate_binary_expression(
479 &self,
480 context: &ExpressionEvaluationContext<'_>,
481 expression: &ast::BinaryExpression,
482 ) -> Result<VariableValue, EvaluationError> {
483 let result = match expression {
484 ast::BinaryExpression::And(c1, c2) => VariableValue::Bool(
485 self.evaluate_predicate(context, c1).await?
486 && self.evaluate_predicate(context, c2).await?,
487 ),
488 ast::BinaryExpression::Or(c1, c2) => VariableValue::Bool(
489 self.evaluate_predicate(context, c1).await?
490 || self.evaluate_predicate(context, c2).await?,
491 ),
492 ast::BinaryExpression::Eq(e1, e2) => match (
493 self.evaluate_expression(context, e1).await?,
494 self.evaluate_expression(context, e2).await?,
495 ) {
496 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
497 VariableValue::Bool(n1 == n2)
498 }
499 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
500 VariableValue::Bool(n1 == n2)
501 }
502 (VariableValue::String(s1), VariableValue::String(s2)) => {
503 VariableValue::Bool(s1 == s2)
504 }
505 (VariableValue::Bool(b1), VariableValue::Bool(b2)) => VariableValue::Bool(b1 == b2),
506 (VariableValue::Null, VariableValue::Null) => VariableValue::Bool(true),
507 (VariableValue::List(a1), VariableValue::List(a2)) => VariableValue::Bool(a1 == a2),
508 (VariableValue::ElementReference(e1), VariableValue::ElementReference(e2)) => {
509 VariableValue::Bool(e1 == e2)
510 }
511 (VariableValue::Date(date1), VariableValue::Date(date2)) => {
512 VariableValue::Bool(date1 == date2)
513 }
514 (VariableValue::LocalTime(time1), VariableValue::LocalTime(time2)) => {
515 VariableValue::Bool(time1 == time2)
516 }
517 (VariableValue::LocalDateTime(dt1), VariableValue::LocalDateTime(dt2)) => {
518 VariableValue::Bool(dt1 == dt2)
519 }
520 (VariableValue::ZonedTime(time1), VariableValue::ZonedTime(time2)) => {
521 VariableValue::Bool(time1 == time2)
522 }
523 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedDateTime(zdt2)) => {
524 VariableValue::Bool(zdt1 == zdt2)
525 }
526 (VariableValue::Duration(d1), VariableValue::Duration(d2)) => {
527 VariableValue::Bool(d1 == d2)
528 }
529 (VariableValue::Awaiting, VariableValue::Awaiting) => VariableValue::Bool(true),
530 _ => VariableValue::Bool(false),
531 },
532 ast::BinaryExpression::Ne(e1, e2) => match (
533 self.evaluate_expression(context, e1).await?,
534 self.evaluate_expression(context, e2).await?,
535 ) {
536 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
537 VariableValue::Bool(n1 != n2)
538 }
539 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
540 VariableValue::Bool(n1 != n2)
541 }
542 (VariableValue::Float(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
543 n1 != match n2.as_i64() {
544 Some(n) => n as f64,
545 None => {
546 return Err(EvaluationError::InvalidType {
547 expected: "Integer".to_string(),
548 })
549 }
550 },
551 ),
552 (VariableValue::Integer(n1), VariableValue::Float(n2)) => VariableValue::Bool(
553 n2 != match n1.as_i64() {
554 Some(n) => n as f64,
555 None => {
556 return Err(EvaluationError::InvalidType {
557 expected: "Integer".to_string(),
558 })
559 }
560 },
561 ),
562 (VariableValue::String(s1), VariableValue::String(s2)) => {
563 VariableValue::Bool(s1 != s2)
564 }
565 (VariableValue::Bool(b1), VariableValue::Bool(b2)) => VariableValue::Bool(b1 != b2),
566 (VariableValue::Null, VariableValue::Null) => VariableValue::Bool(false),
567 (VariableValue::List(a1), VariableValue::List(a2)) => VariableValue::Bool(a1 != a2),
568 (VariableValue::Date(date1), VariableValue::Date(date2)) => {
569 VariableValue::Bool(date1 != date2)
570 }
571 (VariableValue::LocalTime(time1), VariableValue::LocalTime(time2)) => {
572 VariableValue::Bool(time1 != time2)
573 }
574 (VariableValue::LocalDateTime(dt1), VariableValue::LocalDateTime(dt2)) => {
575 VariableValue::Bool(dt1 != dt2)
576 }
577 (VariableValue::ZonedTime(time1), VariableValue::ZonedTime(time2)) => {
578 VariableValue::Bool(time1 != time2)
579 }
580 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedDateTime(zdt2)) => {
581 VariableValue::Bool(zdt1 != zdt2)
582 }
583 (VariableValue::Duration(d1), VariableValue::Duration(d2)) => {
584 VariableValue::Bool(d1 != d2)
585 }
586 (VariableValue::ElementReference(e1), VariableValue::ElementReference(e2)) => {
587 VariableValue::Bool(e1 != e2)
588 }
589 _ => VariableValue::Bool(false),
590 },
591 ast::BinaryExpression::Lt(e1, e2) => match (
592 self.evaluate_expression(context, e1).await?,
593 self.evaluate_expression(context, e2).await?,
594 ) {
595 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
596 n1.as_i64().unwrap_or_default() < n2.as_i64().unwrap_or_default(),
597 ),
598 (VariableValue::Float(n1), VariableValue::Float(n2)) => VariableValue::Bool(
599 n1.as_f64().unwrap_or_default() < n2.as_f64().unwrap_or_default(),
600 ),
601 (VariableValue::Float(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
602 n1.as_f64().unwrap_or_default() < n2.as_i64().unwrap_or_default() as f64,
603 ),
604 (VariableValue::Integer(n1), VariableValue::Float(n2)) => VariableValue::Bool(
605 (n1.as_i64().unwrap_or_default() as f64) < n2.as_f64().unwrap_or_default(),
606 ),
607 (VariableValue::Date(date1), VariableValue::Date(date2)) => {
608 VariableValue::Bool(date1 < date2)
609 }
610 (VariableValue::LocalTime(time1), VariableValue::LocalTime(time2)) => {
611 VariableValue::Bool(time1 < time2)
612 }
613 (VariableValue::LocalDateTime(dt1), VariableValue::LocalDateTime(dt2)) => {
614 VariableValue::Bool(dt1 < dt2)
615 }
616 (VariableValue::LocalDateTime(dt1), VariableValue::Date(date2)) => {
617 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
618 VariableValue::Bool(dt1 < dt2)
619 }
620 (VariableValue::LocalDateTime(dt1), VariableValue::LocalTime(time2)) => {
621 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
622 VariableValue::Bool(dt1 < dt2)
623 }
624 (VariableValue::LocalTime(time1), VariableValue::LocalDateTime(dt2)) => {
625 let dt1 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time1);
626 VariableValue::Bool(dt1 < dt2)
627 }
628 (VariableValue::Date(date1), VariableValue::LocalDateTime(dt2)) => {
629 let dt1 = NaiveDateTime::new(date1, *MIDNIGHT_NAIVE_TIME);
630 VariableValue::Bool(dt1 < dt2)
631 }
632 (VariableValue::ZonedTime(time1), VariableValue::ZonedTime(time2)) => {
633 let dt1 = match NaiveDateTime::new(
634 *temporal_constants::EPOCH_NAIVE_DATE,
635 *time1.time(),
636 )
637 .and_local_timezone(*time1.offset())
638 {
639 LocalResult::Single(dt) => dt,
640 _ => {
641 return Err(EvaluationError::InvalidType {
642 expected: "Time".to_string(),
643 })
644 }
645 };
646 let dt2 = match NaiveDateTime::new(
647 *temporal_constants::EPOCH_NAIVE_DATE,
648 *time2.time(),
649 )
650 .and_local_timezone(*time2.offset())
651 {
652 LocalResult::Single(dt) => dt,
653 _ => {
654 return Err(EvaluationError::InvalidType {
655 expected: "Time".to_string(),
656 })
657 }
658 };
659 VariableValue::Bool(dt1 < dt2)
660 }
661 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedDateTime(zdt2)) => {
662 VariableValue::Bool(zdt1.datetime() < zdt2.datetime())
663 }
664 (VariableValue::ZonedDateTime(zdt1), VariableValue::Date(date2)) => {
665 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
666 VariableValue::Bool(zdt1.datetime() < &dt2.and_utc())
667 }
668 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalDateTime(dt2)) => {
669 VariableValue::Bool(zdt1.datetime().naive_utc() < dt2)
670 }
671 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalTime(time2)) => {
672 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
673 VariableValue::Bool(zdt1.datetime() < &dt2.and_utc())
674 }
675 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedTime(time2)) => {
676 let dt2 =
677 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time2.time());
678 let zdt2 = match dt2.and_local_timezone(*time2.offset()) {
679 LocalResult::Single(dt) => dt,
680 _ => {
681 return Err(EvaluationError::InvalidType {
682 expected: "Time".to_string(),
683 })
684 }
685 };
686 VariableValue::Bool(zdt1.datetime() < &zdt2)
687 }
688 (VariableValue::ZonedTime(time1), VariableValue::ZonedDateTime(zdt2)) => {
689 let dt1 =
690 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
691 let zdt1 = match dt1.and_local_timezone(*time1.offset()) {
692 LocalResult::Single(dt) => dt,
693 _ => {
694 return Err(EvaluationError::InvalidType {
695 expected: "DateTiie".to_string(),
696 })
697 }
698 };
699 VariableValue::Bool(zdt1 < *zdt2.datetime())
700 }
701 (VariableValue::ZonedTime(time1), VariableValue::Date(date2)) => {
702 let dt1 =
703 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
704 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
705 VariableValue::Bool(dt1 < dt2)
706 }
707 (VariableValue::ZonedTime(time1), VariableValue::LocalDateTime(dt2)) => {
708 let dt1 =
709 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
710 VariableValue::Bool(dt1 < dt2)
711 }
712 (VariableValue::ZonedTime(time1), VariableValue::LocalTime(time2)) => {
713 let dt1 =
714 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
715 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
716 VariableValue::Bool(dt1 < dt2)
717 }
718 (VariableValue::Duration(d1), VariableValue::Duration(d2)) => {
719 let year1 = d1.year();
720 let year2 = d2.year();
721 let month1 = d1.month() + year1 * 12;
722 let month2 = d2.month() + year2 * 12;
723 VariableValue::Bool(
725 *d1.duration() + Duration::days(30 * month1)
726 < *d2.duration() + Duration::days(30 * month2),
727 )
728 }
729 _ => VariableValue::Bool(false),
730 },
731 ast::BinaryExpression::Le(e1, e2) => match (
732 self.evaluate_expression(context, e1).await?,
733 self.evaluate_expression(context, e2).await?,
734 ) {
735 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
736 n1.as_i64().unwrap_or_default() <= n2.as_i64().unwrap_or_default(),
737 ),
738 (VariableValue::Float(n1), VariableValue::Float(n2)) => VariableValue::Bool(
739 n1.as_f64().unwrap_or_default() <= n2.as_f64().unwrap_or_default(),
740 ),
741 (VariableValue::Float(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
742 n1.as_f64().unwrap_or_default() <= n2.as_i64().unwrap_or_default() as f64,
743 ),
744 (VariableValue::Integer(n1), VariableValue::Float(n2)) => VariableValue::Bool(
745 n1.as_i64().unwrap_or_default() as f64 <= n2.as_f64().unwrap_or_default(),
746 ),
747 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedDateTime(zdt2)) => {
748 VariableValue::Bool(zdt1.datetime() <= zdt2.datetime())
749 }
750 (VariableValue::Date(date1), VariableValue::Date(date2)) => {
751 VariableValue::Bool(date1 <= date2)
752 }
753 (VariableValue::LocalTime(time1), VariableValue::LocalTime(time2)) => {
754 VariableValue::Bool(time1 <= time2)
755 }
756 (VariableValue::LocalDateTime(dt1), VariableValue::LocalDateTime(dt2)) => {
757 VariableValue::Bool(dt1 <= dt2)
758 }
759 (VariableValue::LocalDateTime(dt1), VariableValue::Date(date2)) => {
760 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
761 VariableValue::Bool(dt1 <= dt2)
762 }
763 (VariableValue::LocalDateTime(dt1), VariableValue::LocalTime(time2)) => {
764 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
765 VariableValue::Bool(dt1 <= dt2)
766 }
767 (VariableValue::LocalTime(time1), VariableValue::LocalDateTime(dt2)) => {
768 let dt1 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time1);
769 VariableValue::Bool(dt1 <= dt2)
770 }
771 (VariableValue::Date(date1), VariableValue::LocalDateTime(dt2)) => {
772 let dt1 = NaiveDateTime::new(date1, *MIDNIGHT_NAIVE_TIME);
773 VariableValue::Bool(dt1 <= dt2)
774 }
775 (VariableValue::ZonedTime(time1), VariableValue::ZonedTime(time2)) => {
776 let dt1 = match NaiveDateTime::new(
777 *temporal_constants::EPOCH_NAIVE_DATE,
778 *time1.time(),
779 )
780 .and_local_timezone(*time1.offset())
781 {
782 LocalResult::Single(dt) => dt,
783 _ => {
784 return Err(EvaluationError::InvalidType {
785 expected: "Time".to_string(),
786 })
787 }
788 };
789 let dt2 = match NaiveDateTime::new(
790 *temporal_constants::EPOCH_NAIVE_DATE,
791 *time2.time(),
792 )
793 .and_local_timezone(*time2.offset())
794 {
795 LocalResult::Single(dt) => dt,
796 _ => {
797 return Err(EvaluationError::InvalidType {
798 expected: "Time".to_string(),
799 })
800 }
801 };
802 VariableValue::Bool(dt1 <= dt2)
803 }
804 (VariableValue::ZonedDateTime(zdt1), VariableValue::Date(date2)) => {
805 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
806 VariableValue::Bool(zdt1.datetime() <= &dt2.and_utc())
807 }
808 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalDateTime(dt2)) => {
809 VariableValue::Bool(zdt1.datetime().naive_utc() <= dt2)
810 }
811 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalTime(time2)) => {
812 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
813 VariableValue::Bool(zdt1.datetime() <= &dt2.and_utc())
814 }
815 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedTime(time2)) => {
816 let dt2 =
817 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time2.time());
818 let zdt2 = match dt2.and_local_timezone(*time2.offset()) {
819 LocalResult::Single(dt) => dt,
820 _ => {
821 return Err(EvaluationError::InvalidType {
822 expected: "Time".to_string(),
823 })
824 }
825 };
826 VariableValue::Bool(zdt1.datetime() <= &zdt2)
827 }
828 (VariableValue::ZonedTime(time1), VariableValue::ZonedDateTime(zdt2)) => {
829 let dt1 =
830 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
831 let zdt1 = match dt1.and_local_timezone(*time1.offset()) {
832 LocalResult::Single(dt) => dt,
833 _ => {
834 return Err(EvaluationError::InvalidType {
835 expected: "DateTime".to_string(),
836 })
837 }
838 };
839 VariableValue::Bool(zdt1 <= *zdt2.datetime())
840 }
841 (VariableValue::ZonedTime(time1), VariableValue::Date(date2)) => {
842 let dt1 =
843 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
844 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
845 VariableValue::Bool(dt1 <= dt2)
846 }
847 (VariableValue::ZonedTime(time1), VariableValue::LocalDateTime(dt2)) => {
848 let dt1 =
849 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
850 VariableValue::Bool(dt1 <= dt2)
851 }
852 (VariableValue::ZonedTime(time1), VariableValue::LocalTime(time2)) => {
853 let dt1 =
854 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
855 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
856 VariableValue::Bool(dt1 <= dt2)
857 }
858 (VariableValue::Duration(d1), VariableValue::Duration(d2)) => {
859 let year1 = d1.year();
860 let year2 = d2.year();
861 let month1 = d1.month() + year1 * 12;
862 let month2 = d2.month() + year2 * 12;
863 VariableValue::Bool(
865 *d1.duration() + Duration::days(30 * month1)
866 <= *d2.duration() + Duration::days(30 * month2),
867 )
868 }
869 _ => VariableValue::Bool(false),
870 },
871 ast::BinaryExpression::Gt(e1, e2) => match (
872 self.evaluate_expression(context, e1).await?,
873 self.evaluate_expression(context, e2).await?,
874 ) {
875 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
876 n1.as_i64().unwrap_or_default() > n2.as_i64().unwrap_or_default(),
877 ),
878 (VariableValue::Float(n1), VariableValue::Float(n2)) => VariableValue::Bool(
879 n1.as_f64().unwrap_or_default() > n2.as_f64().unwrap_or_default(),
880 ),
881 (VariableValue::Float(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
882 n1.as_f64().unwrap_or_default() > n2.as_i64().unwrap_or_default() as f64,
883 ),
884 (VariableValue::Integer(n1), VariableValue::Float(n2)) => VariableValue::Bool(
885 n1.as_i64().unwrap_or_default() as f64 > n2.as_f64().unwrap_or_default(),
886 ),
887 (VariableValue::Date(date1), VariableValue::Date(date2)) => {
888 VariableValue::Bool(date1 > date2)
889 }
890 (VariableValue::LocalTime(time1), VariableValue::LocalTime(time2)) => {
891 VariableValue::Bool(time1 > time2)
892 }
893 (VariableValue::LocalDateTime(dt1), VariableValue::LocalDateTime(dt2)) => {
894 VariableValue::Bool(dt1 > dt2)
895 }
896 (VariableValue::LocalDateTime(dt1), VariableValue::Date(date2)) => {
897 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
898 VariableValue::Bool(dt1 > dt2)
899 }
900 (VariableValue::LocalDateTime(dt1), VariableValue::LocalTime(time2)) => {
901 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
902 VariableValue::Bool(dt1 > dt2)
903 }
904 (VariableValue::LocalTime(time1), VariableValue::LocalDateTime(dt2)) => {
905 let dt1 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time1);
906 VariableValue::Bool(dt1 > dt2)
907 }
908 (VariableValue::Date(date1), VariableValue::LocalDateTime(dt2)) => {
909 let dt1 = NaiveDateTime::new(date1, *MIDNIGHT_NAIVE_TIME);
910 VariableValue::Bool(dt1 > dt2)
911 }
912 (VariableValue::ZonedTime(time1), VariableValue::ZonedTime(time2)) => {
913 let dt1 = match NaiveDateTime::new(
914 *temporal_constants::EPOCH_NAIVE_DATE,
915 *time1.time(),
916 )
917 .and_local_timezone(*time1.offset())
918 {
919 LocalResult::Single(dt) => dt,
920 _ => {
921 return Err(EvaluationError::InvalidType {
922 expected: "Time".to_string(),
923 })
924 }
925 };
926 let dt2 = match NaiveDateTime::new(
927 *temporal_constants::EPOCH_NAIVE_DATE,
928 *time2.time(),
929 )
930 .and_local_timezone(*time2.offset())
931 {
932 LocalResult::Single(dt) => dt,
933 _ => {
934 return Err(EvaluationError::InvalidType {
935 expected: "Time".to_string(),
936 })
937 }
938 };
939
940 VariableValue::Bool(dt1 > dt2)
941 }
942 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedDateTime(zdt2)) => {
943 VariableValue::Bool(zdt1.datetime() > zdt2.datetime())
944 }
945 (VariableValue::ZonedDateTime(zdt1), VariableValue::Date(date2)) => {
946 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
947 VariableValue::Bool(zdt1.datetime() > &dt2.and_utc())
948 }
949 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalDateTime(dt2)) => {
950 VariableValue::Bool(zdt1.datetime().naive_utc() > dt2)
951 }
952 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalTime(time2)) => {
953 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
954 VariableValue::Bool(zdt1.datetime() > &dt2.and_utc())
955 }
956 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedTime(time2)) => {
957 let dt2 =
958 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time2.time());
959 let zdt2 = match dt2.and_local_timezone(*time2.offset()) {
960 LocalResult::Single(dt) => dt,
961 _ => {
962 return Err(EvaluationError::InvalidType {
963 expected: "Time".to_string(),
964 })
965 }
966 };
967 VariableValue::Bool(zdt1.datetime() > &zdt2)
968 }
969 (VariableValue::ZonedTime(time1), VariableValue::ZonedDateTime(zdt2)) => {
970 let dt1 =
971 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
972 let zdt1 = match dt1.and_local_timezone(*time1.offset()) {
973 LocalResult::Single(dt) => dt,
974 _ => {
975 return Err(EvaluationError::InvalidType {
976 expected: "Time".to_string(),
977 })
978 }
979 };
980 VariableValue::Bool(zdt1 > *zdt2.datetime())
981 }
982 (VariableValue::ZonedTime(time1), VariableValue::Date(date2)) => {
983 let dt1 =
984 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
985 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
986 VariableValue::Bool(dt1 > dt2)
987 }
988 (VariableValue::ZonedTime(time1), VariableValue::LocalDateTime(dt2)) => {
989 let dt1 =
990 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
991 VariableValue::Bool(dt1 > dt2)
992 }
993 (VariableValue::Date(date1), VariableValue::ZonedDateTime(zdt2)) => {
994 let dt1 = NaiveDateTime::new(date1, *MIDNIGHT_NAIVE_TIME);
995 VariableValue::Bool(&dt1.and_utc() > zdt2.datetime())
996 }
997 (VariableValue::Date(date1), VariableValue::LocalTime(time2)) => {
998 let dt1 = NaiveDateTime::new(date1, *MIDNIGHT_NAIVE_TIME);
999 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
1000 VariableValue::Bool(dt1 > dt2)
1001 }
1002 (VariableValue::Date(date1), VariableValue::ZonedTime(time2)) => {
1003 let dt1 = NaiveDateTime::new(date1, *MIDNIGHT_NAIVE_TIME);
1004 let dt2 =
1005 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time2.time());
1006 let zdt2 = match dt2.and_local_timezone(*time2.offset()) {
1007 LocalResult::Single(dt) => dt,
1008 _ => {
1009 return Err(EvaluationError::InvalidType {
1010 expected: "Time".to_string(),
1011 })
1012 }
1013 };
1014 VariableValue::Bool(dt1.and_utc() > zdt2)
1015 }
1016 (VariableValue::ZonedTime(time1), VariableValue::LocalTime(time2)) => {
1017 let dt1 =
1018 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
1019 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
1020 VariableValue::Bool(dt1 > dt2)
1021 }
1022 (VariableValue::Duration(d1), VariableValue::Duration(d2)) => {
1023 let year1 = d1.year();
1024 let year2 = d2.year();
1025 let month1 = d1.month() + year1 * 12;
1026 let month2 = d2.month() + year2 * 12;
1027 VariableValue::Bool(
1029 *d1.duration() + Duration::days(30 * month1)
1030 > *d2.duration() + Duration::days(30 * month2),
1031 )
1032 }
1033 _ => VariableValue::Bool(false),
1034 },
1035 ast::BinaryExpression::Ge(e1, e2) => match (
1036 self.evaluate_expression(context, e1).await?,
1037 self.evaluate_expression(context, e2).await?,
1038 ) {
1039 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
1040 n1.as_i64().unwrap_or_default() >= n2.as_i64().unwrap_or_default(),
1041 ),
1042 (VariableValue::Float(n1), VariableValue::Float(n2)) => VariableValue::Bool(
1043 n1.as_f64().unwrap_or_default() >= n2.as_f64().unwrap_or_default(),
1044 ),
1045 (VariableValue::Float(n1), VariableValue::Integer(n2)) => VariableValue::Bool(
1046 n1.as_f64().unwrap_or_default() >= n2.as_i64().unwrap_or_default() as f64,
1047 ),
1048 (VariableValue::Integer(n1), VariableValue::Float(n2)) => VariableValue::Bool(
1049 n1.as_i64().unwrap_or_default() as f64 >= n2.as_f64().unwrap_or_default(),
1050 ),
1051 (VariableValue::Date(date1), VariableValue::Date(date2)) => {
1052 VariableValue::Bool(date1 >= date2)
1053 }
1054 (VariableValue::LocalTime(time1), VariableValue::LocalTime(time2)) => {
1055 VariableValue::Bool(time1 >= time2)
1056 }
1057 (VariableValue::LocalDateTime(dt1), VariableValue::LocalDateTime(dt2)) => {
1058 VariableValue::Bool(dt1 >= dt2)
1059 }
1060 (VariableValue::LocalDateTime(dt1), VariableValue::Date(date2)) => {
1061 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
1062 VariableValue::Bool(dt1 >= dt2)
1063 }
1064 (VariableValue::LocalDateTime(dt1), VariableValue::LocalTime(time2)) => {
1065 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
1066 VariableValue::Bool(dt1 >= dt2)
1067 }
1068 (VariableValue::LocalTime(time1), VariableValue::LocalDateTime(dt2)) => {
1069 let dt1 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time1);
1070 VariableValue::Bool(dt1 >= dt2)
1071 }
1072 (VariableValue::Date(date1), VariableValue::LocalDateTime(dt2)) => {
1073 let dt1 = NaiveDateTime::new(date1, *MIDNIGHT_NAIVE_TIME);
1074 VariableValue::Bool(dt1 >= dt2)
1075 }
1076 (VariableValue::LocalDateTime(dt1), VariableValue::ZonedDateTime(zdt2)) => {
1077 VariableValue::Bool(dt1 >= zdt2.datetime().naive_utc())
1078 }
1079 (VariableValue::ZonedDateTime(zdt1), VariableValue::Date(date2)) => {
1080 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
1081 VariableValue::Bool(zdt1.datetime() >= &dt2.and_utc())
1082 }
1083 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalDateTime(dt2)) => {
1084 VariableValue::Bool(zdt1.datetime().naive_utc() >= dt2)
1085 }
1086 (VariableValue::ZonedDateTime(zdt1), VariableValue::LocalTime(time2)) => {
1087 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
1088 VariableValue::Bool(zdt1.datetime() >= &dt2.and_utc())
1089 }
1090 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedTime(time2)) => {
1091 let dt2 =
1092 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time2.time());
1093 let zdt2 = match dt2.and_local_timezone(*time2.offset()) {
1094 LocalResult::Single(dt) => dt,
1095 _ => {
1096 return Err(EvaluationError::InvalidType {
1097 expected: "Time".to_string(),
1098 })
1099 }
1100 };
1101 VariableValue::Bool(zdt1.datetime() >= &zdt2)
1102 }
1103 (VariableValue::ZonedTime(time1), VariableValue::ZonedDateTime(zdt2)) => {
1104 let dt1 =
1105 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
1106 let zdt1 = match dt1.and_local_timezone(zdt2.datetime().timezone()) {
1107 LocalResult::Single(dt) => dt,
1108 _ => {
1109 return Err(EvaluationError::InvalidType {
1110 expected: "Time".to_string(),
1111 })
1112 }
1113 };
1114 VariableValue::Bool(zdt1 >= *zdt2.datetime())
1115 }
1116 (VariableValue::ZonedTime(time1), VariableValue::Date(date2)) => {
1117 let dt1 =
1118 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
1119 let dt2 = NaiveDateTime::new(date2, *MIDNIGHT_NAIVE_TIME);
1120 VariableValue::Bool(dt1 >= dt2)
1121 }
1122 (VariableValue::ZonedTime(time1), VariableValue::LocalDateTime(dt2)) => {
1123 let dt1 =
1124 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
1125 VariableValue::Bool(dt1 >= dt2)
1126 }
1127 (VariableValue::ZonedTime(time1), VariableValue::LocalTime(time2)) => {
1128 let dt1 =
1129 NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, *time1.time());
1130 let dt2 = NaiveDateTime::new(*temporal_constants::EPOCH_NAIVE_DATE, time2);
1131 VariableValue::Bool(dt1 >= dt2)
1132 }
1133 (VariableValue::ZonedTime(time1), VariableValue::ZonedTime(time2)) => {
1134 let dt1 = match NaiveDateTime::new(
1135 *temporal_constants::EPOCH_NAIVE_DATE,
1136 *time1.time(),
1137 )
1138 .and_local_timezone(*time1.offset())
1139 {
1140 LocalResult::Single(dt) => dt,
1141 _ => {
1142 return Err(EvaluationError::InvalidType {
1143 expected: "Time".to_string(),
1144 })
1145 }
1146 };
1147 let dt2 = match NaiveDateTime::new(
1148 *temporal_constants::EPOCH_NAIVE_DATE,
1149 *time2.time(),
1150 )
1151 .and_local_timezone(*time2.offset())
1152 {
1153 LocalResult::Single(dt) => dt,
1154 _ => {
1155 return Err(EvaluationError::InvalidType {
1156 expected: "Time".to_string(),
1157 })
1158 }
1159 };
1160 VariableValue::Bool(dt1 >= dt2)
1161 }
1162 (VariableValue::Duration(d1), VariableValue::Duration(d2)) => {
1163 let year1 = d1.year();
1164 let year2 = d2.year();
1165 let month1 = d1.month() + year1 * 12;
1166 let month2 = d2.month() + year2 * 12;
1167 VariableValue::Bool(
1169 *d1.duration() + Duration::days(30 * month1)
1170 >= *d2.duration() + Duration::days(30 * month2),
1171 )
1172 }
1173 (VariableValue::ZonedDateTime(zdt1), VariableValue::ZonedDateTime(zdt2)) => {
1174 VariableValue::Bool(zdt1.datetime() >= zdt2.datetime())
1175 }
1176 _ => VariableValue::Bool(false),
1177 },
1178 ast::BinaryExpression::Add(e1, e2) => {
1179 let n1 = self.evaluate_expression(context, e1).await?;
1180 let n2 = self.evaluate_expression(context, e2).await?;
1181 match (n1, n2) {
1182 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
1183 VariableValue::Integer(Integer::from(
1184 n1.as_i64().unwrap_or_default() + n2.as_i64().unwrap_or_default(),
1185 ))
1186 }
1187 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
1188 VariableValue::Float(Float::from(
1189 n1.as_f64().unwrap_or_default() + n2.as_f64().unwrap_or_default(),
1190 ))
1191 }
1192 (VariableValue::Float(n1), VariableValue::Integer(n2)) => {
1193 VariableValue::Float(Float::from(
1194 n1.as_f64().unwrap_or_default()
1195 + n2.as_i64().unwrap_or_default() as f64,
1196 ))
1197 }
1198 (VariableValue::Integer(n1), VariableValue::Float(n2)) => {
1199 VariableValue::Float(Float::from(
1200 n1.as_i64().unwrap_or_default() as f64
1201 + n2.as_f64().unwrap_or_default(),
1202 ))
1203 }
1204 (VariableValue::Integer(n1), VariableValue::String(s2)) => {
1205 VariableValue::String(n1.to_string() + &s2)
1206 }
1207 (VariableValue::Float(n1), VariableValue::String(s2)) => {
1208 VariableValue::String(n1.to_string() + &s2)
1209 }
1210 (VariableValue::String(s1), VariableValue::Bool(b2)) => {
1211 VariableValue::String(s1 + &b2.to_string())
1212 }
1213 (VariableValue::String(s1), VariableValue::Integer(n2)) => {
1214 VariableValue::String(s1 + &n2.to_string())
1215 }
1216 (VariableValue::String(s1), VariableValue::Float(n2)) => {
1217 VariableValue::String(s1 + &n2.to_string())
1218 }
1219 (VariableValue::String(s1), VariableValue::String(s2)) => {
1220 VariableValue::String(s1 + &s2)
1221 }
1222 (VariableValue::Date(date), VariableValue::Duration(duration)) => date
1223 .checked_add_signed(*duration.duration())
1224 .map_or(VariableValue::Null, |new_date| {
1225 VariableValue::Date(new_date)
1226 }),
1227 (VariableValue::LocalTime(time), VariableValue::Duration(duration)) => {
1228 let new_time = time + *duration.duration();
1229 VariableValue::LocalTime(new_time)
1230 }
1231 (VariableValue::LocalDateTime(dt), VariableValue::Duration(duration)) => dt
1232 .checked_add_signed(*duration.duration())
1233 .map_or(VariableValue::Null, |new_dt| {
1234 VariableValue::LocalDateTime(new_dt)
1235 }),
1236 (VariableValue::ZonedTime(time), VariableValue::Duration(duration)) => {
1237 let new_time = *time.time() + *duration.duration();
1238 VariableValue::ZonedTime(ZonedTime::new(new_time, *time.offset()))
1239 }
1240 (VariableValue::ZonedDateTime(zdt), VariableValue::Duration(d)) => zdt
1241 .datetime()
1242 .checked_add_signed(*d.duration())
1243 .map_or(VariableValue::Null, |new_zdt| {
1244 VariableValue::ZonedDateTime(ZonedDateTime::new(
1245 new_zdt,
1246 zdt.timezone().clone(),
1247 ))
1248 }),
1249 (VariableValue::Duration(duration1), VariableValue::Duration(duration2)) => {
1250 VariableValue::Duration(duration1 + duration2)
1251 }
1252 _ => VariableValue::Null,
1253 }
1254 }
1255 ast::BinaryExpression::Subtract(e1, e2) => {
1256 let n1 = self.evaluate_expression(context, e1).await?;
1257 let n2 = self.evaluate_expression(context, e2).await?;
1258 match (n1, n2) {
1259 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
1260 VariableValue::Integer(Integer::from(
1261 n1.as_i64().unwrap_or_default() - n2.as_i64().unwrap_or_default(),
1262 ))
1263 }
1264 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
1265 VariableValue::Float(Float::from(
1266 n1.as_f64().unwrap_or_default() - n2.as_f64().unwrap_or_default(),
1267 ))
1268 }
1269 (VariableValue::Float(n1), VariableValue::Integer(n2)) => {
1270 VariableValue::Float(Float::from(
1271 n1.as_f64().unwrap_or_default()
1272 - n2.as_i64().unwrap_or_default() as f64,
1273 ))
1274 }
1275 (VariableValue::Integer(n1), VariableValue::Float(n2)) => {
1276 VariableValue::Float(Float::from(
1277 n1.as_i64().unwrap_or_default() as f64
1278 - n2.as_f64().unwrap_or_default(),
1279 ))
1280 }
1281 (VariableValue::Date(date), VariableValue::Duration(duration)) => date
1282 .checked_sub_signed(*duration.duration())
1283 .map_or(VariableValue::Null, |new_date| {
1284 VariableValue::Date(new_date)
1285 }),
1286 (VariableValue::LocalTime(time), VariableValue::Duration(duration)) => {
1287 let new_time = time - *duration.duration();
1288 VariableValue::LocalTime(new_time)
1289 }
1290 (VariableValue::LocalDateTime(dt), VariableValue::Duration(duration)) => dt
1291 .checked_sub_signed(*duration.duration())
1292 .map_or(VariableValue::Null, |new_dt| {
1293 VariableValue::LocalDateTime(new_dt)
1294 }),
1295 (VariableValue::ZonedTime(time), VariableValue::Duration(duration)) => {
1296 let new_time = *time.time() - *duration.duration();
1297 VariableValue::ZonedTime(ZonedTime::new(new_time, *time.offset()))
1298 }
1299 (VariableValue::ZonedDateTime(zdt), VariableValue::Duration(d)) => zdt
1300 .datetime()
1301 .checked_sub_signed(*d.duration())
1302 .map_or(VariableValue::Null, |new_zdt| {
1303 VariableValue::ZonedDateTime(ZonedDateTime::new(
1304 new_zdt,
1305 zdt.timezone().clone(),
1306 ))
1307 }),
1308 (VariableValue::Duration(duration1), VariableValue::Duration(duration2)) => {
1309 VariableValue::Duration(duration1 - duration2)
1310 }
1311 _ => VariableValue::Null,
1312 }
1313 }
1314 ast::BinaryExpression::Multiply(e1, e2) => {
1315 let n1 = self.evaluate_expression(context, e1).await?;
1316 let n2 = self.evaluate_expression(context, e2).await?;
1317 match (n1, n2) {
1318 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
1319 VariableValue::Integer(Integer::from(
1320 n1.as_i64().unwrap_or_default() * n2.as_i64().unwrap_or_default(),
1321 ))
1322 }
1323 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
1324 VariableValue::Float(Float::from(
1325 n1.as_f64().unwrap_or_default() * n2.as_f64().unwrap_or_default(),
1326 ))
1327 }
1328 (VariableValue::Float(n1), VariableValue::Integer(n2)) => {
1329 VariableValue::Float(Float::from(
1330 n1.as_f64().unwrap_or_default()
1331 * n2.as_i64().unwrap_or_default() as f64,
1332 ))
1333 }
1334 (VariableValue::Integer(n1), VariableValue::Float(n2)) => {
1335 VariableValue::Float(Float::from(
1336 n1.as_i64().unwrap_or_default() as f64
1337 * n2.as_f64().unwrap_or_default(),
1338 ))
1339 }
1340 _ => VariableValue::Null,
1341 }
1342 }
1343 ast::BinaryExpression::Divide(e1, e2) => {
1344 let n1 = self.evaluate_expression(context, e1).await?;
1345 let n2 = self.evaluate_expression(context, e2).await?;
1346 match (n1, n2) {
1347 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
1348 let m1 = n1.as_i64().ok_or(EvaluationError::OverflowError)?;
1349 let m2 = n2.as_i64().ok_or(EvaluationError::OverflowError)?;
1350 if m2 == 0 {
1351 return Err(EvaluationError::DivideByZero);
1352 } else {
1353 VariableValue::Float(Float::from(m1 as f64 / m2 as f64))
1354 }
1355 }
1356 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
1357 let m1 = n1.as_f64().ok_or(EvaluationError::OverflowError)?;
1358 let m2 = n2.as_f64().ok_or(EvaluationError::OverflowError)?;
1359 if m2 == 0.0 {
1360 return Err(EvaluationError::DivideByZero);
1361 } else {
1362 VariableValue::Float(Float::from(m1 / m2))
1363 }
1364 }
1365 (VariableValue::Float(n1), VariableValue::Integer(n2)) => {
1366 let m1 = n1.as_f64().ok_or(EvaluationError::OverflowError)?;
1367 let m2 = n2.as_i64().ok_or(EvaluationError::OverflowError)?;
1368 if m2 == 0 {
1369 return Err(EvaluationError::DivideByZero);
1370 } else {
1371 VariableValue::Float(Float::from(m1 / m2 as f64))
1372 }
1373 }
1374 (VariableValue::Integer(n1), VariableValue::Float(n2)) => {
1375 let m1 = n1.as_i64().ok_or(EvaluationError::OverflowError)?;
1376 let m2 = n2.as_f64().ok_or(EvaluationError::OverflowError)?;
1377 if m2 == 0.0 {
1378 return Err(EvaluationError::DivideByZero);
1379 } else {
1380 VariableValue::Float(Float::from(m1 as f64 / m2))
1381 }
1382 }
1383 _ => VariableValue::Null,
1384 }
1385 }
1386 ast::BinaryExpression::In(e1, e2) => {
1387 let e1 = self.evaluate_expression(context, e1).await?;
1388 match self.evaluate_expression(context, e2).await? {
1389 VariableValue::List(a) => VariableValue::Bool(a.contains(&e1)),
1390 _ => {
1391 return Err(EvaluationError::InvalidType {
1392 expected: "List".to_string(),
1393 })
1394 }
1395 }
1396 }
1397 ast::BinaryExpression::Modulo(e1, e2) => {
1398 let n1 = self.evaluate_expression(context, e1).await?;
1399 let n2 = self.evaluate_expression(context, e2).await?;
1400 match (n1, n2) {
1401 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
1402 VariableValue::Integer(Integer::from(
1403 n1.as_i64().unwrap_or_default() % n2.as_i64().unwrap_or_default(),
1404 ))
1405 }
1406 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
1407 VariableValue::Float(Float::from(
1408 n1.as_f64().unwrap_or_default() % n2.as_f64().unwrap_or_default(),
1409 ))
1410 }
1411 (VariableValue::Float(n1), VariableValue::Integer(n2)) => {
1412 VariableValue::Float(Float::from(
1413 n1.as_f64().unwrap_or_default()
1414 % n2.as_i64().unwrap_or_default() as f64,
1415 ))
1416 }
1417 (VariableValue::Integer(n1), VariableValue::Float(n2)) => {
1418 VariableValue::Float(Float::from(
1419 n1.as_i64().unwrap_or_default() as f64
1420 % n2.as_f64().unwrap_or_default(),
1421 ))
1422 }
1423 _ => VariableValue::Null,
1424 }
1425 }
1426 ast::BinaryExpression::Exponent(e1, e2) => {
1427 let n1 = self.evaluate_expression(context, e1).await?;
1428 let n2 = self.evaluate_expression(context, e2).await?;
1429 match (n1, n2) {
1430 (VariableValue::Integer(n1), VariableValue::Integer(n2)) => {
1431 VariableValue::Integer(Integer::from(
1432 n1.as_i64().unwrap_or_default().pow(
1433 n2.as_i64()
1434 .unwrap_or_default()
1435 .try_into()
1436 .map_err(|_| EvaluationError::OverflowError)?,
1437 ),
1438 ))
1439 }
1440 (VariableValue::Float(n1), VariableValue::Float(n2)) => {
1441 VariableValue::Float(Float::from(
1442 n1.as_f64()
1443 .unwrap_or_default()
1444 .powf(n2.as_f64().unwrap_or_default()),
1445 ))
1446 }
1447 (VariableValue::Float(n1), VariableValue::Integer(n2)) => {
1448 VariableValue::Float(Float::from(
1449 n1.as_f64()
1450 .unwrap_or_default()
1451 .powf(n2.as_i64().unwrap_or_default() as f64),
1452 ))
1453 }
1454 (VariableValue::Integer(n1), VariableValue::Float(n2)) => {
1455 VariableValue::Float(Float::from(
1456 (n1.as_i64().unwrap_or_default() as f64)
1457 .powf(n2.as_f64().unwrap_or_default()),
1458 ))
1459 }
1460 _ => VariableValue::Null,
1461 }
1462 }
1463 ast::BinaryExpression::HasLabel(e1, e2) => {
1464 let subject = self.evaluate_expression(context, e1).await?;
1465 let label = match self.evaluate_expression(context, e2).await? {
1466 VariableValue::String(s) => Arc::from(s),
1467 _ => {
1468 return Err(EvaluationError::InvalidType {
1469 expected: "String".to_string(),
1470 })
1471 }
1472 };
1473
1474 match subject {
1475 VariableValue::Element(n) => {
1476 VariableValue::Bool(n.get_metadata().labels.contains(&label))
1477 }
1478 _ => VariableValue::Bool(false),
1479 }
1480 }
1481 ast::BinaryExpression::Index(e1, e2) => {
1482 let index_exp = self.evaluate_expression(context, e2).await?;
1483 let variable_value_list = self.evaluate_expression(context, e1).await?;
1484 let list = match variable_value_list.as_array() {
1485 Some(list) => list,
1486 None => {
1487 return Err(EvaluationError::InvalidType {
1488 expected: "List".to_string(),
1489 })
1490 }
1491 };
1492 match index_exp {
1493 VariableValue::ListRange(list_range) => {
1494 let start_bound = match list_range.start {
1495 RangeBound::Index(index) => {
1496 if index < 0 {
1497 index.abs() + 1
1498 } else if index > list.len() as i64 {
1499 list.len() as i64
1500 } else {
1501 index
1502 }
1503 }
1504 RangeBound::Unbounded => 0,
1505 };
1506 let end_bound = match list_range.end {
1507 RangeBound::Index(index) => {
1508 if index > list.len() as i64 {
1509 list.len() as i64
1510 } else if index < 0 {
1511 list.len() as i64 + index
1512 } else {
1513 index
1514 }
1515 }
1516 RangeBound::Unbounded => list.len() as i64,
1517 };
1518 let result = list[start_bound as usize..end_bound as usize].to_vec();
1519 return Ok(VariableValue::List(result));
1520 }
1521 VariableValue::Integer(index) => {
1522 let index_i64 = match index.as_i64() {
1523 Some(index) => index,
1524 None => {
1525 return Err(EvaluationError::InvalidType {
1526 expected: "Integer".to_string(),
1527 })
1528 }
1529 };
1530 if index_i64 >= list.len() as i64 {
1531 return Ok(VariableValue::Null);
1532 }
1533 if index_i64 < 0 {
1534 let index_i64 = list.len() as i64 + index_i64;
1535 let element = list[index_i64 as usize].clone();
1536 return Ok(element);
1537 }
1538 let index = match index.as_i64() {
1539 Some(index) => index as usize,
1540 None => {
1541 return Err(EvaluationError::InvalidType {
1542 expected: "Integer".to_string(),
1543 })
1544 }
1545 };
1546 let element = list[index].clone();
1547
1548 return Ok(element);
1549 }
1550 _ => {
1551 return Err(EvaluationError::InvalidType {
1552 expected: "Integer or ListRange".to_string(),
1553 })
1554 }
1555 }
1556 }
1557 };
1558 Ok(result)
1559 }
1560
1561 async fn evaluate_function_expression(
1562 &self,
1563 context: &ExpressionEvaluationContext<'_>,
1564 expression: &ast::FunctionExpression,
1565 ) -> Result<VariableValue, EvaluationError> {
1566 let result = match self.functions.get_function(&expression.name) {
1567 Some(function) => match function.as_ref() {
1568 Function::Scalar(scalar) => {
1569 let mut values = Vec::new();
1570 for arg in &expression.args {
1571 values.push(self.evaluate_expression(context, arg).await?);
1572 }
1573 scalar
1574 .call(context, expression, values)
1575 .await
1576 .map_err(EvaluationError::FunctionError)?
1577 }
1578 Function::LazyScalar(scalar) => scalar
1579 .call(context, expression, &expression.args)
1580 .await
1581 .map_err(EvaluationError::FunctionError)?,
1582 Function::Aggregating(aggregate) => {
1583 let mut values = Vec::new();
1584 for arg in &expression.args {
1585 values.push(self.evaluate_expression(context, arg).await?);
1586 }
1587 let grouping_keys = Arc::new(match context.get_output_grouping_key() {
1588 Some(group_expressions) => {
1589 let mut grouping_keys = Vec::new();
1590 for group_expression in group_expressions {
1591 grouping_keys.push(
1592 self.evaluate_expression(context, group_expression).await?,
1593 );
1594 }
1595 grouping_keys
1596 }
1597 None => Vec::new(),
1598 });
1599
1600 let result_key = ResultKey::GroupBy(grouping_keys.clone());
1601 let result_owner = ResultOwner::Function(expression.position_in_query);
1602
1603 let mut accumulator = {
1604 if aggregate.accumulator_is_lazy() {
1605 aggregate.initialize_accumulator(
1606 context,
1607 expression,
1608 &grouping_keys,
1609 self.result_index.clone(),
1610 )
1611 } else {
1612 match self.result_index.get(&result_key, &result_owner).await? {
1613 Some(acc) => Accumulator::Value(acc),
1614 None => aggregate.initialize_accumulator(
1615 context,
1616 expression,
1617 &grouping_keys,
1618 self.result_index.clone(),
1619 ),
1620 }
1621 }
1622 };
1623
1624 let result = match context.get_side_effects() {
1625 SideEffects::Apply => aggregate
1626 .apply(context, values, &mut accumulator)
1627 .await
1628 .map_err(EvaluationError::FunctionError)?,
1629 SideEffects::RevertForUpdate | SideEffects::RevertForDelete => aggregate
1630 .revert(context, values, &mut accumulator)
1631 .await
1632 .map_err(EvaluationError::FunctionError)?,
1633 SideEffects::Snapshot => aggregate
1634 .snapshot(context, values, &accumulator)
1635 .await
1636 .map_err(EvaluationError::FunctionError)?,
1637 };
1638
1639 match accumulator {
1642 super::functions::aggregation::Accumulator::Value(va) => {
1643 self.result_index
1644 .set(result_key, result_owner, Some(va))
1645 .await?
1646 }
1647 super::functions::aggregation::Accumulator::LazySortedSet(
1648 mut accumulator,
1649 ) => accumulator.commit().await?,
1650 };
1651
1652 result
1653 }
1654 Function::ContextMutator(context_mutator) => {
1655 if expression.args.is_empty() {
1656 VariableValue::Null
1657 } else {
1658 let new_context = match context_mutator.call(context, expression).await {
1659 Ok(new_context) => new_context,
1660 Err(e) => {
1661 return Err(EvaluationError::FunctionError(e));
1662 }
1663 };
1664
1665 self.evaluate_expression(&new_context, &expression.args[0])
1666 .await?
1667 }
1668 }
1669 },
1670 None => {
1671 return Err(EvaluationError::UnknownFunction(
1672 expression.name.to_string(),
1673 ))
1674 }
1675 };
1676
1677 Ok(result)
1678 }
1679
1680 async fn evaluate_case_expression(
1681 &self,
1682 context: &ExpressionEvaluationContext<'_>,
1683 expression: &ast::CaseExpression,
1684 ) -> Result<VariableValue, EvaluationError> {
1685 let match_ = match expression.match_ {
1686 Some(ref match_) => Some(self.evaluate_expression(context, match_).await?),
1687 None => None,
1688 };
1689
1690 for when in &expression.when {
1691 match match_ {
1692 Some(ref match_) => {
1693 let condition = self.evaluate_expression(context, &when.0).await?;
1694 if condition == *match_ {
1695 return self.evaluate_expression(context, &when.1).await;
1696 }
1697 }
1698 None => {
1699 let condition = self.evaluate_predicate(context, &when.0).await?;
1700 if condition {
1701 return self.evaluate_expression(context, &when.1).await;
1702 }
1703 }
1704 }
1705 }
1706
1707 match expression.else_ {
1708 Some(ref else_) => Ok(self.evaluate_expression(context, else_).await?),
1709 None => Ok(VariableValue::Null),
1710 }
1711 }
1712
1713 async fn evaluate_list_expression(
1714 &self,
1715 context: &ExpressionEvaluationContext<'_>,
1716 expression: &ast::ListExpression,
1717 ) -> Result<VariableValue, EvaluationError> {
1718 let mut result = Vec::new();
1719 for e in &expression.elements {
1720 result.push(self.evaluate_expression(context, e).await?);
1721 }
1722
1723 Ok(VariableValue::List(result))
1724 }
1725
1726 async fn evaluate_object_expression(
1727 &self,
1728 context: &ExpressionEvaluationContext<'_>,
1729 expression: &ast::ObjectExpression,
1730 ) -> Result<VariableValue, EvaluationError> {
1731 let mut result = BTreeMap::new();
1732 for (key, value) in &expression.elements {
1733 result.insert(
1734 key.to_string(),
1735 self.evaluate_expression(context, value).await?,
1736 );
1737 }
1738
1739 Ok(VariableValue::Object(result))
1740 }
1741
1742 pub async fn evaluate_assignment(
1743 &self,
1744 context: &ExpressionEvaluationContext<'_>,
1745 expression: &ast::Expression,
1746 ) -> Result<(Arc<str>, VariableValue), FunctionEvaluationError> {
1747 match expression {
1748 ast::Expression::BinaryExpression(exp) => match exp {
1749 ast::BinaryExpression::Eq(var, val) => {
1750 let variable = match *var.clone() {
1751 ast::Expression::UnaryExpression(exp) => match exp {
1752 ast::UnaryExpression::Identifier(ident) => ident,
1753 _ => {
1754 return Err(FunctionEvaluationError::InvalidType {
1755 expected: "Identifier expression".to_string(),
1756 })
1757 }
1758 },
1759 _ => {
1760 return Err(FunctionEvaluationError::InvalidType {
1761 expected: "Unary expression".to_string(),
1762 })
1763 }
1764 };
1765 let value = match self.evaluate_expression(context, val).await {
1766 Ok(value) => value,
1767 Err(_) => {
1768 return Err(FunctionEvaluationError::InvalidType {
1769 expected: "valid identifier expresssion".to_string(),
1770 })
1771 }
1772 };
1773 Ok((variable, value))
1774 }
1775 _ => Err(FunctionEvaluationError::InvalidType {
1776 expected: "Eq expression".to_string(),
1777 }),
1778 },
1779 _ => Err(FunctionEvaluationError::InvalidType {
1780 expected: "Binary expression".to_string(),
1781 }),
1782 }
1783 }
1784
1785 async fn evaluate_iterator_expression(
1786 &self,
1787 context: &ExpressionEvaluationContext<'_>,
1788 expression: &ast::IteratorExpression,
1789 ) -> Result<VariableValue, EvaluationError> {
1790 let items = self
1791 .evaluate_expression(context, &expression.list_expression)
1792 .await?;
1793 match items {
1794 VariableValue::List(items) => {
1795 let mut result = Vec::new();
1796 let mut variables = context.clone_variables();
1797 for item in items {
1798 if let Some(filter) = &expression.filter {
1799 variables
1800 .insert(expression.item_identifier.to_string().into(), item.clone());
1801 let local_context =
1802 ExpressionEvaluationContext::new(&variables, context.get_clock());
1803 if !self.evaluate_predicate(&local_context, filter).await? {
1804 continue;
1805 }
1806 }
1807
1808 if let Some(map_expression) = &expression.map_expression {
1809 variables
1810 .insert(expression.item_identifier.to_string().into(), item.clone());
1811 let local_context =
1812 ExpressionEvaluationContext::new(&variables, context.get_clock());
1813 let item_result = self
1814 .evaluate_expression(&local_context, map_expression)
1815 .await?;
1816 result.push(item_result);
1817 } else {
1818 result.push(item);
1819 }
1820 }
1821 Ok(VariableValue::List(result))
1822 }
1823 _ => Err(EvaluationError::InvalidType {
1824 expected: "List".to_string(),
1825 }),
1826 }
1827 }
1828
1829 pub async fn reduce_iterator_expression(
1830 &self,
1831 context: &ExpressionEvaluationContext<'_>,
1832 expression: &ast::IteratorExpression,
1833 accumulator_variable: Arc<str>,
1834 ) -> Result<VariableValue, EvaluationError> {
1835 let items = self
1836 .evaluate_expression(context, &expression.list_expression)
1837 .await?;
1838 match items {
1839 VariableValue::List(items) => {
1840 let mut result = match context.get_variable(accumulator_variable.clone()) {
1841 Some(value) => value.clone(),
1842 None => VariableValue::Null,
1843 };
1844 let mut variables = context.clone_variables();
1845 for item in items {
1846 if let Some(filter) = &expression.filter {
1847 variables
1848 .insert(expression.item_identifier.to_string().into(), item.clone());
1849 let local_context =
1850 ExpressionEvaluationContext::new(&variables, context.get_clock());
1851
1852 if !self.evaluate_predicate(&local_context, filter).await? {
1853 continue;
1854 }
1855 }
1856
1857 if let Some(map_expression) = &expression.map_expression {
1858 variables
1859 .insert(expression.item_identifier.to_string().into(), item.clone());
1860 let local_context =
1861 ExpressionEvaluationContext::new(&variables, context.get_clock());
1862 result = self
1863 .evaluate_expression(&local_context, map_expression)
1864 .await?;
1865 variables.insert(accumulator_variable.to_string().into(), result.clone());
1866 }
1867 }
1868 Ok(result)
1869 }
1870 _ => Err(EvaluationError::InvalidType {
1871 expected: "List".to_string(),
1872 }),
1873 }
1874 }
1875}
1876
1877async fn get_date_property(date: NaiveDate, property: String) -> Option<u32> {
1878 match property.as_str() {
1879 "year" => Some(date.year() as u32),
1880 "month" => Some(date.month()),
1881 "day" => Some(date.day()),
1882 "quarter" => Some((date.month() - 1) / 3 + 1),
1883 "week" => Some(date.iso_week().week()),
1884 "dayOfWeek" => {
1885 let day_of_week = date.weekday();
1886 let day_of_week_num = match day_of_week {
1887 Weekday::Mon => 1,
1888 Weekday::Tue => 2,
1889 Weekday::Wed => 3,
1890 Weekday::Thu => 4,
1891 Weekday::Fri => 5,
1892 Weekday::Sat => 6,
1893 Weekday::Sun => 7,
1894 };
1895 Some(day_of_week_num)
1896 }
1897 "weekDay" => {
1898 let day_of_week = date.weekday();
1899 let day_of_week_num = match day_of_week {
1900 Weekday::Mon => 1,
1901 Weekday::Tue => 2,
1902 Weekday::Wed => 3,
1903 Weekday::Thu => 4,
1904 Weekday::Fri => 5,
1905 Weekday::Sat => 6,
1906 Weekday::Sun => 7,
1907 };
1908 Some(day_of_week_num)
1909 }
1910 "ordinalDay" => Some(date.ordinal()),
1911 "weekYear" => Some(date.iso_week().year() as u32),
1912 "dayOfQuarter" => {
1913 let quarter = (date.month() - 1) / 3 + 1;
1914 let start_date = match NaiveDate::from_ymd_opt(date.year(), (quarter - 1) * 3 + 1, 1) {
1915 Some(date) => date,
1916 None => return None,
1917 };
1918
1919 let duration = date - start_date;
1920 let num_days = duration.num_days();
1921 Some((num_days + 1) as u32)
1922 }
1923 "quarterDay" => {
1924 let quarter = (date.month() - 1) / 3 + 1;
1925 let start_date = match NaiveDate::from_ymd_opt(date.year(), (quarter - 1) * 3 + 1, 1) {
1926 Some(date) => date,
1927 None => return None,
1928 };
1929 let duration = date - start_date;
1930 let num_days = duration.num_days();
1931 Some((num_days + 1) as u32)
1932 }
1933 _ => None,
1934 }
1935}
1936
1937async fn get_local_time_property(time: NaiveTime, property: String) -> Option<u32> {
1938 match property.as_str() {
1939 "hour" => Some(time.hour()),
1940 "minute" => Some(time.minute()),
1941 "second" => Some(time.second()),
1942 "millisecond" => Some(time.nanosecond() / 1000000),
1943 "microsecond" => Some(time.nanosecond() / 1000),
1944 "nanosecond" => Some(time.nanosecond()),
1945 _ => None,
1946 }
1947}
1948
1949async fn get_time_property(zoned_time: ZonedTime, property: String) -> Option<String> {
1950 let time = zoned_time.time();
1951 let offset = zoned_time.offset();
1952 match property.as_str() {
1953 "hour" => Some(time.hour().to_string()),
1954 "minute" => Some(time.minute().to_string()),
1955 "second" => Some(time.second().to_string()),
1956 "millisecond" => Some((time.nanosecond() / 1000000).to_string()),
1957 "microsecond" => Some((time.nanosecond() / 1000).to_string()),
1958 "nanosecond" => Some(time.nanosecond().to_string()),
1959 "offset" => Some(offset.to_string()),
1960 "timezone" => Some(offset.to_string()),
1961 "offsetSeconds" => {
1962 let seconds = offset.local_minus_utc();
1963 Some(seconds.to_string())
1964 }
1965 "offsetMinutes" => {
1966 let minutes = offset.local_minus_utc() / 60;
1967 Some(minutes.to_string())
1968 }
1969 _ => None,
1970 }
1971}
1972
1973async fn get_local_datetime_property(datetime: NaiveDateTime, property: String) -> Option<u32> {
1974 let date = datetime.date();
1975 let time = datetime.time();
1976 match property.as_str() {
1977 "year" => Some(date.year() as u32),
1978 "month" => Some(date.month()),
1979 "day" => Some(date.day()),
1980 "quarter" => Some((date.month() - 1) / 3 + 1),
1981 "week" => Some(date.iso_week().week()),
1982 "dayOfWeek" => {
1983 let day_of_week = date.weekday();
1984 let day_of_week_num = match day_of_week {
1985 Weekday::Mon => 1,
1986 Weekday::Tue => 2,
1987 Weekday::Wed => 3,
1988 Weekday::Thu => 4,
1989 Weekday::Fri => 5,
1990 Weekday::Sat => 6,
1991 Weekday::Sun => 7,
1992 };
1993 Some(day_of_week_num)
1994 }
1995 "weekDay" => {
1996 let day_of_week = date.weekday();
1997 let day_of_week_num = match day_of_week {
1998 Weekday::Mon => 1,
1999 Weekday::Tue => 2,
2000 Weekday::Wed => 3,
2001 Weekday::Thu => 4,
2002 Weekday::Fri => 5,
2003 Weekday::Sat => 6,
2004 Weekday::Sun => 7,
2005 };
2006 Some(day_of_week_num)
2007 }
2008 "ordinalDay" => Some(date.ordinal()),
2009 "weekYear" => Some(date.iso_week().year() as u32),
2010 "dayOfQuarter" => {
2011 let quarter = (date.month() - 1) / 3 + 1;
2012 let start_date = match NaiveDate::from_ymd_opt(date.year(), (quarter - 1) * 3 + 1, 1) {
2013 Some(date) => date,
2014 None => return None,
2015 };
2016 let duration = date - start_date;
2017 let num_days = duration.num_days();
2018 Some((num_days + 1) as u32)
2019 }
2020 "quarterDay" => {
2021 let quarter = (date.month() - 1) / 3 + 1;
2022 let start_date = match NaiveDate::from_ymd_opt(date.year(), (quarter - 1) * 3 + 1, 1) {
2023 Some(date) => date,
2024 None => return None,
2025 };
2026 let duration = date - start_date;
2027 let num_days = duration.num_days();
2028 Some((num_days + 1) as u32)
2029 }
2030 "hour" => Some(time.hour()),
2031 "minute" => Some(time.minute()),
2032 "second" => Some(time.second()),
2033 "millisecond" => Some(time.nanosecond() / 1000000),
2034 "microsecond" => Some(time.nanosecond() / 1000),
2035 "nanosecond" => Some(time.nanosecond()),
2036 _ => None,
2037 }
2038}
2039
2040async fn get_datetime_property(zoned_datetime: ZonedDateTime, property: String) -> Option<String> {
2041 let datetime = zoned_datetime.datetime();
2042
2043 let date = datetime.date_naive();
2044 let time = datetime.time();
2045 let offset = datetime.offset();
2046 let timezone = zoned_datetime.timezone();
2047
2048 match property.as_str() {
2049 "year" => Some(date.year().to_string()),
2050 "month" => Some(date.month().to_string()),
2051 "day" => Some(date.day().to_string()),
2052 "quarter" => Some(((date.month() - 1) / 3 + 1).to_string()),
2053 "week" => Some(date.iso_week().week().to_string()),
2054 "dayOfWeek" => {
2055 let day_of_week = date.weekday();
2056 let day_of_week_num = match day_of_week {
2057 Weekday::Mon => "1",
2058 Weekday::Tue => "2",
2059 Weekday::Wed => "3",
2060 Weekday::Thu => "4",
2061 Weekday::Fri => "5",
2062 Weekday::Sat => "6",
2063 Weekday::Sun => "7",
2064 };
2065 Some(day_of_week_num.to_string())
2066 }
2067 "weekDay" => {
2068 let day_of_week = date.weekday();
2069 let day_of_week_num = match day_of_week {
2070 Weekday::Mon => "1",
2071 Weekday::Tue => "2",
2072 Weekday::Wed => "3",
2073 Weekday::Thu => "4",
2074 Weekday::Fri => "5",
2075 Weekday::Sat => "6",
2076 Weekday::Sun => "7",
2077 };
2078 Some(day_of_week_num.to_string())
2079 }
2080 "ordinalDay" => Some(date.ordinal().to_string()),
2081 "weekYear" => Some(date.iso_week().year().to_string()),
2082 "dayOfQuarter" => {
2083 let quarter = (date.month() - 1) / 3 + 1;
2084 let start_date = match NaiveDate::from_ymd_opt(date.year(), (quarter - 1) * 3 + 1, 1) {
2085 Some(date) => date,
2086 None => return None,
2087 };
2088 let duration = date - start_date;
2089 let num_days = duration.num_days();
2090 Some((num_days + 1).to_string())
2091 }
2092 "quarterDay" => {
2093 let quarter = (date.month() - 1) / 3 + 1;
2094 let start_date = match NaiveDate::from_ymd_opt(date.year(), (quarter - 1) * 3 + 1, 1) {
2095 Some(date) => date,
2096 None => return None,
2097 };
2098 let duration = date - start_date;
2099 let num_days = duration.num_days();
2100 Some((num_days + 1).to_string())
2101 }
2102 "hour" => Some(time.hour().to_string()),
2103 "minute" => Some(time.minute().to_string()),
2104 "second" => Some(time.second().to_string()),
2105 "millisecond" => Some((time.nanosecond() / 1000000).to_string()),
2106 "microsecond" => Some((time.nanosecond() / 1000).to_string()),
2107 "nanosecond" => Some(time.nanosecond().to_string()),
2108 "timezone" => match timezone {
2109 Some(tz) => Some(tz.to_string()),
2110 None => Some(offset.to_string()),
2111 },
2112 "offset" => Some(offset.to_string()),
2113 "offsetSeconds" => {
2114 let seconds = offset.local_minus_utc();
2115 Some(seconds.to_string())
2116 }
2117 "offsetMinutes" => {
2118 let minutes = offset.local_minus_utc() / 60;
2119 Some(minutes.to_string())
2120 }
2121 "epochMillis" => {
2122 let epoch = *EPOCH_MIDNIGHT_NAIVE_DATETIME;
2123 let duration = datetime.naive_utc() - epoch;
2124 let millis = duration.num_milliseconds();
2125 Some(millis.to_string())
2126 }
2127 "epochSeconds" => {
2128 let epoch = *EPOCH_MIDNIGHT_NAIVE_DATETIME;
2129 let duration = datetime.naive_utc() - epoch;
2130 let seconds = duration.num_seconds();
2131 Some(seconds.to_string())
2132 }
2133 _ => None,
2134 }
2135}
2136
2137async fn get_duration_property(duration_struct: DurationStruct, property: String) -> Option<i64> {
2138 let year = duration_struct.year();
2139 let month = duration_struct.month();
2140 let duration = duration_struct.duration();
2141
2142 match property.as_str() {
2143 "years" => Some(year + month / 12 + duration.num_days() / 365),
2144 "months" => Some(month + year * 12 + duration.num_days() / 30),
2145 "quarters" => Some(month / 3 + year * 4),
2146 "weeks" => Some(duration.num_weeks()),
2147 "days" => Some(duration.num_days()),
2148 "hours" => Some(duration.num_hours()),
2149 "minutes" => Some(duration.num_minutes()),
2150 "seconds" => Some(duration.num_seconds()),
2151 "milliseconds" => Some(duration.num_milliseconds()),
2152 "microseconds" => Some(duration.num_microseconds().unwrap_or_default()),
2153 "nanoseconds" => Some(duration.num_nanoseconds().unwrap_or_default()),
2154 "quartersOfYear" => {
2155 let quarters = month / 3 + 1;
2156 Some(quarters)
2157 }
2158 "monthsOfYear" => {
2159 if month % 12 == 0 {
2160 return Some(12);
2161 }
2162 let months = month % 12;
2163 Some(months)
2164 }
2165 "monthsOfQuarter" => {
2166 if month % 3 == 0 {
2167 return Some(3);
2168 }
2169 let months = month % 3;
2170 Some(months)
2171 }
2172 "daysOfWeek" => {
2173 if duration.num_days() % 7 == 0 {
2174 return Some(7);
2175 }
2176 let days = duration.num_days() % 7;
2177 Some(days)
2178 }
2179 "minutesOfHour" => {
2180 let mins = duration.num_minutes() % 60;
2181 Some(mins)
2182 }
2183 "secondsOfMinute" => {
2184 let secs = duration.num_seconds() % 60;
2185 Some(secs)
2186 }
2187 "millisecondsOfSecond" => {
2188 let millis = duration.num_milliseconds() % 1000;
2189 Some(millis)
2190 }
2191 "microsecondsOfSecond" => {
2192 let micros = duration.num_microseconds().unwrap_or_default() % 1000000;
2193 Some(micros)
2194 }
2195 "nanosecondsOfSecond" => {
2196 let nanos = duration.num_nanoseconds().unwrap_or_default() % 1000000000;
2197 Some(nanos)
2198 }
2199 _ => None,
2200 }
2201}