1mod error;
2mod evaluated;
3mod expr;
4mod function;
5
6use {
7 self::function::BreakCase,
8 super::{context::RowContext, select::select},
9 crate::{
10 ast::{Aggregate, Expr, Function},
11 data::{CustomFunction, Interval, Literal, Row, Value},
12 mock::MockStorage,
13 result::{Error, Result},
14 store::GStore,
15 },
16 async_recursion::async_recursion,
17 chrono::prelude::Utc,
18 futures::{
19 future::{ready, try_join_all},
20 stream::{self, StreamExt, TryStreamExt},
21 },
22 im_rc::HashMap,
23 std::{borrow::Cow, ops::ControlFlow, rc::Rc},
24};
25
26pub use {error::EvaluateError, evaluated::Evaluated};
27
28#[async_recursion(?Send)]
29pub async fn evaluate<'a, 'b: 'a, 'c: 'a, T>(
30 storage: &'a T,
31 context: Option<Rc<RowContext<'b>>>,
32 aggregated: Option<Rc<HashMap<&'c Aggregate, Value>>>,
33 expr: &'a Expr,
34) -> Result<Evaluated<'a>>
35where
36 T: GStore,
37{
38 evaluate_inner(Some(storage), context, aggregated, expr).await
39}
40
41pub async fn evaluate_stateless<'a, 'b: 'a>(
42 context: Option<RowContext<'b>>,
43 expr: &'a Expr,
44) -> Result<Evaluated<'a>> {
45 let context = context.map(Rc::new);
46 let storage: Option<&MockStorage> = None;
47
48 evaluate_inner(storage, context, None, expr).await
49}
50
51#[async_recursion(?Send)]
52async fn evaluate_inner<'a, 'b: 'a, 'c: 'a, T>(
53 storage: Option<&'a T>,
54 context: Option<Rc<RowContext<'b>>>,
55 aggregated: Option<Rc<HashMap<&'c Aggregate, Value>>>,
56 expr: &'a Expr,
57) -> Result<Evaluated<'a>>
58where
59 T: GStore,
60{
61 let eval = |expr| {
62 let context = context.as_ref().map(Rc::clone);
63 let aggregated = aggregated.as_ref().map(Rc::clone);
64
65 evaluate_inner(storage, context, aggregated, expr)
66 };
67
68 match expr {
69 Expr::Literal(ast_literal) => expr::literal(ast_literal),
70 Expr::TypedString { data_type, value } => {
71 expr::typed_string(data_type, Cow::Borrowed(value))
72 }
73 Expr::Identifier(ident) => {
74 let context = context
75 .ok_or_else(|| EvaluateError::ContextRequiredForIdentEvaluation(expr.clone()))?;
76
77 match context.get_value(ident) {
78 Some(value) => Ok(value.clone()),
79 None => Err(EvaluateError::IdentifierNotFound(ident.to_owned()).into()),
80 }
81 .map(Evaluated::Value)
82 }
83 Expr::Nested(expr) => eval(expr).await,
84 Expr::CompoundIdentifier { alias, ident } => {
85 let context = context
86 .ok_or_else(|| EvaluateError::ContextRequiredForIdentEvaluation(expr.clone()))?;
87
88 match context.get_alias_value(alias, ident) {
89 Some(value) => Ok(value.clone()),
90 None => Err(EvaluateError::CompoundIdentifierNotFound {
91 table_alias: alias.to_owned(),
92 column_name: ident.to_owned(),
93 }
94 .into()),
95 }
96 .map(Evaluated::Value)
97 }
98 Expr::Subquery(query) => {
99 let storage =
100 storage.ok_or_else(|| EvaluateError::UnsupportedStatelessExpr(expr.clone()))?;
101
102 let evaluations = select(storage, query, context.as_ref().map(Rc::clone))
103 .await?
104 .map(|row| {
105 let value = match row? {
106 Row::Vec { columns, values } => {
107 if columns.len() > 1 {
108 return Err(EvaluateError::MoreThanOneColumnReturned.into());
109 }
110 values
111 }
112 Row::Map(_) => {
113 return Err(EvaluateError::SchemalessProjectionForSubQuery.into());
114 }
115 }
116 .into_iter()
117 .next();
118
119 Ok::<_, Error>(value)
120 })
121 .take(2)
122 .try_collect::<Vec<_>>()
123 .await?;
124
125 if evaluations.len() > 1 {
126 return Err(EvaluateError::MoreThanOneRowReturned.into());
127 }
128
129 let value = evaluations
130 .into_iter()
131 .next()
132 .flatten()
133 .unwrap_or(Value::Null);
134
135 Ok(Evaluated::Value(value))
136 }
137 Expr::BinaryOp { op, left, right } => {
138 let left = eval(left).await?;
139 let right = eval(right).await?;
140
141 expr::binary_op(op, left, right)
142 }
143 Expr::UnaryOp { op, expr } => {
144 let v = eval(expr).await?;
145
146 expr::unary_op(op, v)
147 }
148 Expr::Aggregate(aggr) => match aggregated
149 .as_ref()
150 .and_then(|aggregated| aggregated.get(aggr.as_ref()))
151 {
152 Some(value) => Ok(Evaluated::Value(value.clone())),
153 None => Err(EvaluateError::UnreachableEmptyAggregateValue(*aggr.clone()).into()),
154 },
155 Expr::Function(func) => {
156 let context = context.as_ref().map(Rc::clone);
157 let aggregated = aggregated.as_ref().map(Rc::clone);
158
159 evaluate_function(storage, context, aggregated, func).await
160 }
161 Expr::InList {
162 expr,
163 list,
164 negated,
165 } => {
166 let negated = *negated;
167 let target = eval(expr).await?;
168
169 stream::iter(list)
170 .then(eval)
171 .try_filter(|evaluated| ready(evaluated.evaluate_eq(&target)))
172 .try_next()
173 .await
174 .map(|v| v.is_some() ^ negated)
175 .map(Value::Bool)
176 .map(Evaluated::Value)
177 }
178 Expr::InSubquery {
179 expr: target_expr,
180 subquery,
181 negated,
182 } => {
183 let storage =
184 storage.ok_or_else(|| EvaluateError::UnsupportedStatelessExpr(expr.clone()))?;
185 let target = eval(target_expr).await?;
186
187 select(storage, subquery, context)
188 .await?
189 .map(|row| {
190 let value = match row? {
191 Row::Vec { values, .. } => values,
192 Row::Map(_) => {
193 return Err(EvaluateError::SchemalessProjectionForInSubQuery.into());
194 }
195 }
196 .into_iter()
197 .next()
198 .unwrap_or(Value::Null);
199
200 Ok(Evaluated::Value(value))
201 })
202 .try_filter(|evaluated| ready(evaluated.evaluate_eq(&target)))
203 .try_next()
204 .await
205 .map(|v| v.is_some() ^ negated)
206 .map(Value::Bool)
207 .map(Evaluated::Value)
208 }
209 Expr::Between {
210 expr,
211 negated,
212 low,
213 high,
214 } => {
215 let target = eval(expr).await?;
216 let low = eval(low).await?;
217 let high = eval(high).await?;
218
219 expr::between(target, *negated, low, high)
220 }
221 Expr::Like {
222 expr,
223 negated,
224 pattern,
225 } => {
226 let target = eval(expr).await?;
227 let pattern = eval(pattern).await?;
228 let evaluated = target.like(pattern, true)?;
229
230 Ok(match negated {
231 true => Evaluated::Value(Value::Bool(
232 evaluated.evaluate_eq(&Evaluated::Literal(Literal::Boolean(false))),
233 )),
234 false => evaluated,
235 })
236 }
237 Expr::ILike {
238 expr,
239 negated,
240 pattern,
241 } => {
242 let target = eval(expr).await?;
243 let pattern = eval(pattern).await?;
244 let evaluated = target.like(pattern, false)?;
245
246 Ok(match negated {
247 true => Evaluated::Value(Value::Bool(
248 evaluated.evaluate_eq(&Evaluated::Literal(Literal::Boolean(false))),
249 )),
250 false => evaluated,
251 })
252 }
253 Expr::Exists { subquery, negated } => {
254 let storage =
255 storage.ok_or_else(|| EvaluateError::UnsupportedStatelessExpr(expr.clone()))?;
256
257 select(storage, subquery, context)
258 .await?
259 .try_next()
260 .await
261 .map(|v| v.is_some() ^ negated)
262 .map(Value::Bool)
263 .map(Evaluated::Value)
264 }
265 Expr::IsNull(expr) => {
266 let v = eval(expr).await?.is_null();
267
268 Ok(Evaluated::Value(Value::Bool(v)))
269 }
270 Expr::IsNotNull(expr) => {
271 let v = eval(expr).await?.is_null();
272
273 Ok(Evaluated::Value(Value::Bool(!v)))
274 }
275 Expr::Case {
276 operand,
277 when_then,
278 else_result,
279 } => {
280 let operand = match operand {
281 Some(op) => eval(op).await?,
282 None => Evaluated::Value(Value::Bool(true)),
283 };
284
285 for (when, then) in when_then.iter() {
286 let when = eval(when).await?;
287
288 if when.evaluate_eq(&operand) {
289 return eval(then).await;
290 }
291 }
292
293 match else_result {
294 Some(er) => eval(er).await,
295 None => Ok(Evaluated::Value(Value::Null)),
296 }
297 }
298 Expr::ArrayIndex { obj, indexes } => {
299 let obj = eval(obj).await?;
300 let indexes = try_join_all(indexes.iter().map(eval)).await?;
301 expr::array_index(obj, indexes)
302 }
303 Expr::Array { elem } => try_join_all(elem.iter().map(eval))
304 .await?
305 .into_iter()
306 .map(Value::try_from)
307 .collect::<Result<Vec<_>>>()
308 .map(Value::List)
309 .map(Evaluated::Value),
310 Expr::Interval {
311 expr,
312 leading_field,
313 last_field,
314 } => {
315 let value = eval(expr)
316 .await
317 .and_then(Value::try_from)
318 .map(String::from)?;
319
320 Interval::try_from_str(&value, *leading_field, *last_field)
321 .map(Value::Interval)
322 .map(Evaluated::Value)
323 }
324 }
325}
326
327async fn evaluate_function<'a, 'b: 'a, 'c: 'a, T: GStore>(
328 storage: Option<&'a T>,
329 context: Option<Rc<RowContext<'b>>>,
330 aggregated: Option<Rc<HashMap<&'c Aggregate, Value>>>,
331 func: &'b Function,
332) -> Result<Evaluated<'a>> {
333 use function as f;
334
335 let eval = |expr| {
336 let context = context.as_ref().map(Rc::clone);
337 let aggregated = aggregated.as_ref().map(Rc::clone);
338
339 evaluate_inner(storage, context, aggregated, expr)
340 };
341
342 let name = func.to_string();
343
344 let result = match func {
345 Function::Concat(exprs) => {
347 let exprs = stream::iter(exprs).then(eval).try_collect().await?;
348 f::concat(exprs)
349 }
350 Function::Custom { name, exprs } => {
351 let CustomFunction {
352 func_name,
353 args,
354 body,
355 } = storage
356 .ok_or(EvaluateError::UnsupportedCustomFunction)?
357 .fetch_function(name)
358 .await?
359 .ok_or_else(|| EvaluateError::UnsupportedFunction(name.to_string()))?;
360
361 let min = args.iter().filter(|arg| arg.default.is_none()).count();
362 let max = args.len();
363
364 if !(min..=max).contains(&exprs.len()) {
365 return Err((EvaluateError::FunctionArgsLengthNotWithinRange {
366 name: func_name.to_owned(),
367 expected_minimum: min,
368 expected_maximum: max,
369 found: exprs.len(),
370 })
371 .into());
372 }
373
374 let exprs = exprs.iter().chain(
375 args.iter()
376 .skip(exprs.len())
377 .filter_map(|arg| arg.default.as_ref()),
378 );
379
380 let context = stream::iter(args.iter().zip(exprs))
381 .then(|(arg, expr)| async {
382 eval(expr)
383 .await?
384 .try_into_value(&arg.data_type, true)
385 .map(|value| (arg.name.to_owned(), value))
386 })
387 .try_collect()
388 .await
389 .map(|values| {
390 let row = Cow::Owned(Row::Map(values));
391 let context = RowContext::new(name, row, None);
392 Some(Rc::new(context))
393 })?;
394
395 return evaluate_inner(storage, context, None, body).await;
396 }
397 Function::ConcatWs { separator, exprs } => {
398 let separator = eval(separator).await?;
399 let exprs = stream::iter(exprs).then(eval).try_collect().await?;
400 f::concat_ws(name, separator, exprs)
401 }
402 Function::IfNull { expr, then } => f::ifnull(eval(expr).await?, eval(then).await?),
403 Function::Lower(expr) => f::lower(name, eval(expr).await?),
404 Function::Initcap(expr) => f::initcap(name, eval(expr).await?),
405 Function::Upper(expr) => f::upper(name, eval(expr).await?),
406 Function::Left { expr, size } | Function::Right { expr, size } => {
407 let expr = eval(expr).await?;
408 let size = eval(size).await?;
409
410 f::left_or_right(name, expr, size)
411 }
412 Function::Replace { expr, old, new } => {
413 let expr = eval(expr).await?;
414 let old = eval(old).await?;
415 let new = eval(new).await?;
416
417 f::replace(name, expr, old, new)
418 }
419 Function::Lpad { expr, size, fill } | Function::Rpad { expr, size, fill } => {
420 let expr = eval(expr).await?;
421 let size = eval(size).await?;
422 let fill = match fill {
423 Some(v) => Some(eval(v).await?),
424 None => None,
425 };
426
427 f::lpad_or_rpad(name, expr, size, fill)
428 }
429 Function::LastDay(expr) => {
430 let expr = eval(expr).await?;
431 f::last_day(name, expr)
432 }
433 Function::Trim {
434 expr,
435 filter_chars,
436 trim_where_field,
437 } => {
438 let expr = eval(expr).await?;
439 let filter_chars = match filter_chars {
440 Some(v) => Some(eval(v).await?),
441 None => None,
442 };
443
444 return expr.trim(name, filter_chars, trim_where_field);
445 }
446 Function::Ltrim { expr, chars } => {
447 let expr = eval(expr).await?;
448 let chars = match chars {
449 Some(v) => Some(eval(v).await?),
450 None => None,
451 };
452
453 return expr.ltrim(name, chars);
454 }
455 Function::Rtrim { expr, chars } => {
456 let expr = eval(expr).await?;
457 let chars = match chars {
458 Some(v) => Some(eval(v).await?),
459 None => None,
460 };
461
462 return expr.rtrim(name, chars);
463 }
464 Function::Reverse(expr) => {
465 let expr = eval(expr).await?;
466
467 f::reverse(name, expr)
468 }
469 Function::Repeat { expr, num } => {
470 let expr = eval(expr).await?;
471 let num = eval(num).await?;
472
473 f::repeat(name, expr, num)
474 }
475 Function::Substr { expr, start, count } => {
476 let expr = eval(expr).await?;
477 let start = eval(start).await?;
478 let count = match count {
479 Some(v) => Some(eval(v).await?),
480 None => None,
481 };
482
483 return expr.substr(name, start, count);
484 }
485 Function::Ascii(expr) => f::ascii(name, eval(expr).await?),
486 Function::Chr(expr) => f::chr(name, eval(expr).await?),
487 Function::Md5(expr) => f::md5(name, eval(expr).await?),
488
489 Function::Abs(expr) => f::abs(name, eval(expr).await?),
491 Function::Sign(expr) => f::sign(name, eval(expr).await?),
492 Function::Sqrt(expr) => f::sqrt(eval(expr).await?),
493 Function::Power { expr, power } => {
494 let expr = eval(expr).await?;
495 let power = eval(power).await?;
496
497 f::power(name, expr, power)
498 }
499 Function::Ceil(expr) => f::ceil(name, eval(expr).await?),
500 Function::Rand(expr) => {
501 let expr = match expr {
502 Some(v) => Some(eval(v).await?),
503 None => None,
504 };
505
506 f::rand(name, expr)
507 }
508 Function::Round(expr) => f::round(name, eval(expr).await?),
509 Function::Floor(expr) => f::floor(name, eval(expr).await?),
510 Function::Radians(expr) => f::radians(name, eval(expr).await?),
511 Function::Degrees(expr) => f::degrees(name, eval(expr).await?),
512 Function::Pi() => return Ok(Evaluated::Value(Value::F64(std::f64::consts::PI))),
513 Function::Exp(expr) => f::exp(name, eval(expr).await?),
514 Function::Log { antilog, base } => {
515 let antilog = eval(antilog).await?;
516 let base = eval(base).await?;
517
518 f::log(name, antilog, base)
519 }
520 Function::Ln(expr) => f::ln(name, eval(expr).await?),
521 Function::Log2(expr) => f::log2(name, eval(expr).await?),
522 Function::Log10(expr) => f::log10(name, eval(expr).await?),
523 Function::Sin(expr) => f::sin(name, eval(expr).await?),
524 Function::Cos(expr) => f::cos(name, eval(expr).await?),
525 Function::Tan(expr) => f::tan(name, eval(expr).await?),
526 Function::Asin(expr) => f::asin(name, eval(expr).await?),
527 Function::Acos(expr) => f::acos(name, eval(expr).await?),
528 Function::Atan(expr) => f::atan(name, eval(expr).await?),
529
530 Function::Div { dividend, divisor } => {
532 let dividend = eval(dividend).await?;
533 let divisor = eval(divisor).await?;
534
535 f::div(name, dividend, divisor)
536 }
537 Function::Mod { dividend, divisor } => {
538 let dividend = eval(dividend).await?;
539 let divisor = eval(divisor).await?;
540
541 return dividend.modulo(&divisor);
542 }
543 Function::Gcd { left, right } => {
544 let left = eval(left).await?;
545 let right = eval(right).await?;
546
547 f::gcd(name, left, right)
548 }
549 Function::Lcm { left, right } => {
550 let left = eval(left).await?;
551 let right = eval(right).await?;
552
553 f::lcm(name, left, right)
554 }
555
556 Function::Point { x, y } => {
558 let x = eval(x).await?;
559 let y = eval(y).await?;
560
561 f::point(name, x, y)
562 }
563 Function::GetX(expr) => f::get_x(name, eval(expr).await?),
564 Function::GetY(expr) => f::get_y(name, eval(expr).await?),
565 Function::CalcDistance {
566 geometry1,
567 geometry2,
568 } => {
569 let geometry1 = eval(geometry1).await?;
570 let geometry2 = eval(geometry2).await?;
571
572 f::calc_distance(name, geometry1, geometry2)
573 }
574
575 Function::Unwrap { expr, selector } => {
577 let expr = eval(expr).await?;
578 let selector = eval(selector).await?;
579
580 f::unwrap(name, expr, selector)
581 }
582 Function::GenerateUuid() => return Ok(f::generate_uuid()),
583 Function::Greatest(exprs) => {
584 let exprs = stream::iter(exprs).then(eval).try_collect().await?;
585 return f::greatest(name, exprs);
586 }
587 Function::Now() => return Ok(Evaluated::Value(Value::Timestamp(Utc::now().naive_utc()))),
588 Function::Format { expr, format } => {
589 let expr = eval(expr).await?;
590 let format = eval(format).await?;
591
592 f::format(name, expr, format)
593 }
594 Function::ToDate { expr, format } => {
595 let expr = eval(expr).await?;
596 let format = eval(format).await?;
597 f::to_date(name, expr, format)
598 }
599 Function::ToTimestamp { expr, format } => {
600 let expr = eval(expr).await?;
601 let format = eval(format).await?;
602 f::to_timestamp(name, expr, format)
603 }
604 Function::ToTime { expr, format } => {
605 let expr = eval(expr).await?;
606 let format = eval(format).await?;
607 f::to_time(name, expr, format)
608 }
609 Function::Position {
610 from_expr,
611 sub_expr,
612 } => {
613 let from_expr = eval(from_expr).await?;
614 let sub_expr = eval(sub_expr).await?;
615 f::position(from_expr, sub_expr)
616 }
617 Function::FindIdx {
618 from_expr,
619 sub_expr,
620 start,
621 } => {
622 let from_expr = eval(from_expr).await?;
623 let sub_expr = eval(sub_expr).await?;
624 let start = match start {
625 Some(idx) => Some(eval(idx).await?),
626 None => None,
627 };
628 f::find_idx(name, from_expr, sub_expr, start)
629 }
630 Function::Cast { expr, data_type } => return eval(expr).await?.cast(data_type),
631 Function::Extract { field, expr } => {
632 let expr = eval(expr).await?;
633 f::extract(field, expr)
634 }
635 Function::Coalesce(exprs) => {
636 let exprs = stream::iter(exprs).then(eval).try_collect().await?;
637 return f::coalesce(exprs);
638 }
639
640 Function::Append { expr, value } => {
642 let expr = eval(expr).await?;
643 let value = eval(value).await?;
644 f::append(expr, value)
645 }
646 Function::Prepend { expr, value } => {
647 let expr = eval(expr).await?;
648 let value = eval(value).await?;
649 f::prepend(expr, value)
650 }
651 Function::Skip { expr, size } => {
652 let expr = eval(expr).await?;
653 let size = eval(size).await?;
654 f::skip(name, expr, size)
655 }
656 Function::Sort { expr, order } => {
657 let expr = eval(expr).await?;
658 let order = match order {
659 Some(o) => eval(o).await?,
660 None => Evaluated::Value(Value::Str("ASC".to_owned())),
661 };
662 f::sort(expr, order)
663 }
664 Function::Take { expr, size } => {
665 let expr = eval(expr).await?;
666 let size = eval(size).await?;
667 f::take(name, expr, size)
668 }
669 Function::Slice {
670 expr,
671 start,
672 length,
673 } => {
674 let expr = eval(expr).await?;
675 let start = eval(start).await?;
676 let length = eval(length).await?;
677 f::slice(name, expr, start, length)
678 }
679 Function::IsEmpty(expr) => {
680 let expr = eval(expr).await?;
681 f::is_empty(expr)
682 }
683 Function::AddMonth { expr, size } => {
684 let expr = eval(expr).await?;
685 let size = eval(size).await?;
686 f::add_month(name, expr, size)
687 }
688 Function::Length(expr) => f::length(name, eval(expr).await?),
689 Function::Entries(expr) => f::entries(name, eval(expr).await?),
690 Function::Keys(expr) => f::keys(eval(expr).await?),
691 Function::Values(expr) => {
692 let expr = eval(expr).await?;
693 f::values(expr)
694 }
695 Function::Splice {
696 list_data,
697 begin_index,
698 end_index,
699 values,
700 } => {
701 let list_data = eval(list_data).await?;
702 let begin_index = eval(begin_index).await?;
703 let end_index = eval(end_index).await?;
704 let values = match values {
705 Some(v) => Some(eval(v).await?),
706 None => None,
707 };
708 f::splice(name, list_data, begin_index, end_index, values)
709 }
710 Function::Dedup(list) => f::dedup(eval(list).await?),
711 };
712
713 match result {
714 ControlFlow::Continue(v) => Ok(v),
715 ControlFlow::Break(BreakCase::Null) => Ok(Evaluated::Value(Value::Null)),
716 ControlFlow::Break(BreakCase::Err(err)) => Err(err),
717 }
718}