clicktype_query/
aggregate.rs1use std::marker::PhantomData;
4use clicktype_core::traits::{ClickHouseType, Numeric};
5use crate::expr::Expression;
6
7pub trait AggregateFn {
9 type Input: ClickHouseType;
11 type Output: ClickHouseType;
13 fn name() -> &'static str;
15}
16
17pub struct AggregateExpr<F: AggregateFn, E: Expression> {
19 inner: E,
20 _fn: PhantomData<F>,
21}
22
23impl<F: AggregateFn, E: Expression> AggregateExpr<F, E> {
24 pub fn new(inner: E) -> Self {
25 Self {
26 inner,
27 _fn: PhantomData,
28 }
29 }
30}
31
32impl<F: AggregateFn, E: Expression> Expression for AggregateExpr<F, E> {
33 type Output = F::Output;
34
35 fn render(&self) -> String {
36 format!("{}({})", F::name(), self.inner.render())
37 }
38
39 fn is_aggregate(&self) -> bool {
40 true
41 }
42}
43
44pub struct Count;
48
49impl AggregateFn for Count {
50 type Input = u64;
51 type Output = u64;
52
53 fn name() -> &'static str {
54 "count"
55 }
56}
57
58pub struct Sum<T: Numeric>(PhantomData<T>);
60
61impl<T: Numeric> AggregateFn for Sum<T> {
62 type Input = T;
63 type Output = T;
64
65 fn name() -> &'static str {
66 "sum"
67 }
68}
69
70pub struct Avg<T: Numeric>(PhantomData<T>);
72
73impl<T: Numeric> AggregateFn for Avg<T> {
74 type Input = T;
75 type Output = f64;
76
77 fn name() -> &'static str {
78 "avg"
79 }
80}
81
82pub struct Min<T: ClickHouseType>(PhantomData<T>);
84
85impl<T: ClickHouseType> AggregateFn for Min<T> {
86 type Input = T;
87 type Output = T;
88
89 fn name() -> &'static str {
90 "min"
91 }
92}
93
94pub struct Max<T: ClickHouseType>(PhantomData<T>);
96
97impl<T: ClickHouseType> AggregateFn for Max<T> {
98 type Input = T;
99 type Output = T;
100
101 fn name() -> &'static str {
102 "max"
103 }
104}
105
106pub struct Any<T: ClickHouseType>(PhantomData<T>);
108
109impl<T: ClickHouseType> AggregateFn for Any<T> {
110 type Input = T;
111 type Output = T;
112
113 fn name() -> &'static str {
114 "any"
115 }
116}
117
118pub struct AnyLast<T: ClickHouseType>(PhantomData<T>);
120
121impl<T: ClickHouseType> AggregateFn for AnyLast<T> {
122 type Input = T;
123 type Output = T;
124
125 fn name() -> &'static str {
126 "anyLast"
127 }
128}
129
130pub struct Uniq<T: ClickHouseType>(PhantomData<T>);
134
135impl<T: ClickHouseType> AggregateFn for Uniq<T> {
136 type Input = T;
137 type Output = u64;
138
139 fn name() -> &'static str {
140 "uniq"
141 }
142}
143
144pub struct UniqExact<T: ClickHouseType>(PhantomData<T>);
146
147impl<T: ClickHouseType> AggregateFn for UniqExact<T> {
148 type Input = T;
149 type Output = u64;
150
151 fn name() -> &'static str {
152 "uniqExact"
153 }
154}
155
156pub struct GroupArray<T: ClickHouseType>(PhantomData<T>);
158
159impl<T: ClickHouseType> AggregateFn for GroupArray<T> {
160 type Input = T;
161 type Output = Vec<T>;
162
163 fn name() -> &'static str {
164 "groupArray"
165 }
166}
167
168pub struct Star;
172
173impl Expression for Star {
174 type Output = u64;
175
176 fn render(&self) -> String {
177 "*".to_string()
178 }
179}
180
181pub fn count_all() -> AggregateExpr<Count, Star> {
183 AggregateExpr::new(Star)
184}
185
186pub fn count<E: Expression>(expr: E) -> AggregateExpr<Count, E> {
188 AggregateExpr::new(expr)
189}
190
191pub fn sum<E: Expression>(expr: E) -> AggregateExpr<Sum<E::Output>, E>
193where
194 E::Output: Numeric,
195{
196 AggregateExpr::new(expr)
197}
198
199pub fn avg<E: Expression>(expr: E) -> AggregateExpr<Avg<E::Output>, E>
201where
202 E::Output: Numeric,
203{
204 AggregateExpr::new(expr)
205}
206
207pub fn min<E: Expression>(expr: E) -> AggregateExpr<Min<E::Output>, E> {
209 AggregateExpr::new(expr)
210}
211
212pub fn max<E: Expression>(expr: E) -> AggregateExpr<Max<E::Output>, E> {
214 AggregateExpr::new(expr)
215}
216
217pub fn any<E: Expression>(expr: E) -> AggregateExpr<Any<E::Output>, E> {
219 AggregateExpr::new(expr)
220}
221
222pub fn any_last<E: Expression>(expr: E) -> AggregateExpr<AnyLast<E::Output>, E> {
224 AggregateExpr::new(expr)
225}
226
227pub fn uniq<E: Expression>(expr: E) -> AggregateExpr<Uniq<E::Output>, E> {
229 AggregateExpr::new(expr)
230}
231
232pub fn uniq_exact<E: Expression>(expr: E) -> AggregateExpr<UniqExact<E::Output>, E> {
234 AggregateExpr::new(expr)
235}
236
237pub fn group_array<E: Expression>(expr: E) -> AggregateExpr<GroupArray<E::Output>, E> {
239 AggregateExpr::new(expr)
240}
241
242pub struct QuantileExpr<E: Expression> {
246 level: f64,
247 inner: E,
248}
249
250impl<E: Expression> Expression for QuantileExpr<E>
251where
252 E::Output: Numeric,
253{
254 type Output = f64;
255
256 fn render(&self) -> String {
257 format!("quantile({})({})", self.level, self.inner.render())
258 }
259
260 fn is_aggregate(&self) -> bool {
261 true
262 }
263}
264
265pub fn quantile<E: Expression>(level: f64, expr: E) -> QuantileExpr<E>
267where
268 E::Output: Numeric,
269{
270 QuantileExpr { level, inner: expr }
271}
272
273pub struct ArgMaxExpr<A: Expression, V: Expression> {
275 arg: A,
276 val: V,
277}
278
279impl<A: Expression, V: Expression> Expression for ArgMaxExpr<A, V> {
280 type Output = A::Output;
281
282 fn render(&self) -> String {
283 format!("argMax({}, {})", self.arg.render(), self.val.render())
284 }
285
286 fn is_aggregate(&self) -> bool {
287 true
288 }
289}
290
291pub fn arg_max<A: Expression, V: Expression>(arg: A, val: V) -> ArgMaxExpr<A, V> {
293 ArgMaxExpr { arg, val }
294}
295
296pub struct ArgMinExpr<A: Expression, V: Expression> {
298 arg: A,
299 val: V,
300}
301
302impl<A: Expression, V: Expression> Expression for ArgMinExpr<A, V> {
303 type Output = A::Output;
304
305 fn render(&self) -> String {
306 format!("argMin({}, {})", self.arg.render(), self.val.render())
307 }
308
309 fn is_aggregate(&self) -> bool {
310 true
311 }
312}
313
314pub fn arg_min<A: Expression, V: Expression>(arg: A, val: V) -> ArgMinExpr<A, V> {
316 ArgMinExpr { arg, val }
317}
318
319pub struct TopKExpr<const N: usize, E: Expression> {
321 inner: E,
322}
323
324impl<const N: usize, E: Expression> Expression for TopKExpr<N, E> {
325 type Output = Vec<E::Output>;
326
327 fn render(&self) -> String {
328 format!("topK({})({})", N, self.inner.render())
329 }
330
331 fn is_aggregate(&self) -> bool {
332 true
333 }
334}
335
336pub fn top_k<const N: usize, E: Expression>(expr: E) -> TopKExpr<N, E> {
338 TopKExpr { inner: expr }
339}
340
341pub struct GroupArrayIfExpr<E: Expression, C: Expression<Output = bool>> {
343 inner: E,
344 condition: C,
345}
346
347impl<E: Expression, C: Expression<Output = bool>> Expression for GroupArrayIfExpr<E, C> {
348 type Output = Vec<E::Output>;
349
350 fn render(&self) -> String {
351 format!(
352 "groupArrayIf({}, {})",
353 self.inner.render(),
354 self.condition.render()
355 )
356 }
357
358 fn is_aggregate(&self) -> bool {
359 true
360 }
361}
362
363pub fn group_array_if<E: Expression, C: Expression<Output = bool>>(
365 expr: E,
366 condition: C,
367) -> GroupArrayIfExpr<E, C> {
368 GroupArrayIfExpr {
369 inner: expr,
370 condition,
371 }
372}