reifydb_core/value/column/view/
group_by.rs1use indexmap::IndexMap;
5use reifydb_type::{Value, diagnostic::engine, error};
6
7use crate::value::column::{ColumnData, Columns};
8
9pub type GroupKey = Vec<Value>;
10pub type GroupByView = IndexMap<GroupKey, Vec<usize>>;
11
12impl Columns {
13 pub fn group_by_view(&self, keys: &[&str]) -> crate::Result<GroupByView> {
14 let row_count = self.first().map_or(0, |c| c.data().len());
15
16 let mut key_columns: Vec<&ColumnData> = Vec::with_capacity(keys.len());
17
18 for &key in keys {
19 let column = self
20 .iter()
21 .find(|c| c.name() == key)
22 .ok_or_else(|| error!(engine::frame_error(format!("Column '{}' not found", key))))?;
23 key_columns.push(&column.data());
24 }
25
26 let mut result = GroupByView::new();
27
28 for row_numberx in 0..row_count {
29 let mut values = Vec::with_capacity(keys.len());
30
31 for col in &key_columns {
32 let value = col.get_value(row_numberx);
33 values.push(value);
34 }
35
36 result.entry(values).or_default().push(row_numberx);
37 }
38
39 Ok(result)
40 }
41}