Compute an aggregate function over raw MessagePack documents. Each entry in `docs` is a complete MessagePack map (the raw bytes from storage). Returns the result as `Value` — conversion to JSON happens at the response boundary only.
(
op: &str,
field: &str,
expr: Option<&crate::expr::SqlExpr>,
docs: &[&[u8]],
)
| 23 | /// Returns the result as `Value` — conversion to JSON happens at the |
| 24 | /// response boundary only. |
| 25 | pub fn compute_aggregate_binary( |
| 26 | op: &str, |
| 27 | field: &str, |
| 28 | expr: Option<&crate::expr::SqlExpr>, |
| 29 | docs: &[&[u8]], |
| 30 | ) -> Value { |
| 31 | match op { |
| 32 | "count" => { |
| 33 | if field == "*" && expr.is_none() { |
| 34 | Value::Integer(docs.len() as i64) |
| 35 | } else { |
| 36 | let count = docs |
| 37 | .iter() |
| 38 | .filter_map(|d| extract_as_value(d, field, expr)) |
| 39 | .filter(|v| !v.is_null()) |
| 40 | .count(); |
| 41 | Value::Integer(count as i64) |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | "sum" => { |
| 46 | let total: f64 = docs |
| 47 | .iter() |
| 48 | .filter_map(|d| extract_f64_val(d, field, expr)) |
| 49 | .sum(); |
| 50 | Value::Float(total) |
| 51 | } |
| 52 | |
| 53 | "avg" => { |
| 54 | let (sum, count) = docs |
| 55 | .iter() |
| 56 | .filter_map(|d| extract_f64_val(d, field, expr)) |
| 57 | .fold((0.0f64, 0u64), |(s, c), v| (s + v, c + 1)); |
| 58 | if count == 0 { |
| 59 | Value::Null |
| 60 | } else { |
| 61 | Value::Float(sum / count as f64) |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | "min" => find_minmax(docs, field, expr, false), |
| 66 | "max" => find_minmax(docs, field, expr, true), |
| 67 | |
| 68 | "count_distinct" => { |
| 69 | let mut seen = HashSet::new(); |
| 70 | for doc in docs { |
| 71 | if let Some(bytes) = extract_value_bytes(doc, field, expr) |
| 72 | && !value_bytes_are_null(&bytes) |
| 73 | { |
| 74 | seen.insert(bytes); |
| 75 | } |
| 76 | } |
| 77 | Value::Integer(seen.len() as i64) |
| 78 | } |
| 79 | |
| 80 | "stddev" | "stddev_pop" => { |
| 81 | stat_aggregate(docs, field, expr, |variance, _n| variance.sqrt(), true) |
| 82 | } |