Skip to main content

reifydb_core/value/column/view/
group_by.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4use indexmap::IndexMap;
5use reifydb_type::{Result, error::Error, value::Value};
6
7use crate::{
8	error::CoreError,
9	value::column::{ColumnData, columns::Columns},
10};
11
12pub type GroupKey = Vec<Value>;
13pub type GroupByView = IndexMap<GroupKey, Vec<usize>>;
14
15impl Columns {
16	pub fn group_by_view(&self, keys: &[&str]) -> Result<GroupByView> {
17		let row_count = self.first().map_or(0, |c| c.data().len());
18
19		let mut key_columns: Vec<&ColumnData> = Vec::with_capacity(keys.len());
20
21		for &key in keys {
22			let column = self.iter().find(|c| c.name() == key).ok_or_else(|| {
23				let err: Error = CoreError::FrameError {
24					message: format!("Column '{}' not found", key),
25				}
26				.into();
27				err
28			})?;
29			key_columns.push(&column.data());
30		}
31
32		let mut result = GroupByView::new();
33
34		for row_numberx in 0..row_count {
35			let mut values = Vec::with_capacity(keys.len());
36
37			for col in &key_columns {
38				let value = col.get_value(row_numberx);
39				values.push(value);
40			}
41
42			result.entry(values).or_default().push(row_numberx);
43		}
44
45		Ok(result)
46	}
47}