reifydb_engine/function/math/aggregate/
count.rs1use std::collections::HashMap;
5
6use reifydb_core::value::column::ColumnData;
7use reifydb_type::Value;
8
9use crate::function::{AggregateFunction, AggregateFunctionContext};
10
11pub struct Count {
12 pub counts: HashMap<Vec<Value>, i64>,
13}
14
15impl Count {
16 pub fn new() -> Self {
17 Self {
18 counts: HashMap::new(),
19 }
20 }
21}
22
23impl AggregateFunction for Count {
24 fn aggregate(&mut self, ctx: AggregateFunctionContext) -> crate::Result<()> {
25 let column = ctx.column;
26 let groups = &ctx.groups;
27
28 let is_count_star = column.name.text() == "dummy" && matches!(column.data(), ColumnData::Int4(_));
30
31 if is_count_star {
32 for (group, indices) in groups.iter() {
34 let count = indices.len() as i64;
35 self.counts.insert(group.clone(), count);
36 }
37 } else {
38 match &column.data() {
40 ColumnData::Bool(container) => {
41 for (group, indices) in groups.iter() {
42 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
43 as i64;
44 self.counts.insert(group.clone(), count);
45 }
46 }
47 ColumnData::Float8(container) => {
48 for (group, indices) in groups.iter() {
49 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
50 as i64;
51 self.counts.insert(group.clone(), count);
52 }
53 }
54 ColumnData::Float4(container) => {
55 for (group, indices) in groups.iter() {
56 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
57 as i64;
58 self.counts.insert(group.clone(), count);
59 }
60 }
61 ColumnData::Int4(container) => {
62 for (group, indices) in groups.iter() {
63 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
64 as i64;
65 self.counts.insert(group.clone(), count);
66 }
67 }
68 ColumnData::Int8(container) => {
69 for (group, indices) in groups.iter() {
70 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
71 as i64;
72 self.counts.insert(group.clone(), count);
73 }
74 }
75 ColumnData::Int2(container) => {
76 for (group, indices) in groups.iter() {
77 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
78 as i64;
79 self.counts.insert(group.clone(), count);
80 }
81 }
82 ColumnData::Int1(container) => {
83 for (group, indices) in groups.iter() {
84 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
85 as i64;
86 self.counts.insert(group.clone(), count);
87 }
88 }
89 ColumnData::Int16(container) => {
90 for (group, indices) in groups.iter() {
91 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
92 as i64;
93 self.counts.insert(group.clone(), count);
94 }
95 }
96 ColumnData::Utf8 {
97 container,
98 ..
99 } => {
100 for (group, indices) in groups.iter() {
101 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
102 as i64;
103 self.counts.insert(group.clone(), count);
104 }
105 }
106 ColumnData::Date(container) => {
107 for (group, indices) in groups.iter() {
108 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
109 as i64;
110 self.counts.insert(group.clone(), count);
111 }
112 }
113 ColumnData::DateTime(container) => {
114 for (group, indices) in groups.iter() {
115 let count = indices.iter().filter(|&i| container.is_defined(*i)).count()
116 as i64;
117 self.counts.insert(group.clone(), count);
118 }
119 }
120 ColumnData::Undefined(_) => {
121 for (group, _indices) in groups.iter() {
123 self.counts.insert(group.clone(), 0);
124 }
125 }
126 _ => {
127 for (group, indices) in groups.iter() {
129 let count = indices
130 .iter()
131 .filter(|&i| column.data().is_defined(*i))
132 .count() as i64;
133 self.counts.insert(group.clone(), count);
134 }
135 }
136 }
137 }
138 Ok(())
139 }
140
141 fn finalize(&mut self) -> crate::Result<(Vec<Vec<Value>>, ColumnData)> {
142 let mut keys = Vec::with_capacity(self.counts.len());
143 let mut data = ColumnData::int8_with_capacity(self.counts.len());
144
145 for (key, count) in std::mem::take(&mut self.counts) {
146 keys.push(key);
147 data.push_value(Value::Int8(count));
148 }
149
150 Ok((keys, data))
151 }
152}