siderite_orm/expr/
aggregate.rs1use super::Expr;
8
9#[derive(Debug, Clone, PartialEq)]
11pub enum AggFunc {
12 Count,
14 Sum,
16 Avg,
18 Min,
20 Max,
22 StdDev {
24 sample: bool,
26 },
27 Variance {
29 sample: bool,
31 },
32 ArrayAgg,
34 StringAgg {
36 separator: String,
38 },
39}
40
41#[derive(Debug, Clone, PartialEq)]
43pub struct Aggregate {
44 pub func: AggFunc,
46 pub arg: Option<Box<Expr>>,
48 pub distinct: bool,
50 pub filter: Option<Box<Expr>>,
52}
53
54impl Aggregate {
55 fn new(func: AggFunc, arg: Option<Expr>) -> Self {
56 Self {
57 func,
58 arg: arg.map(Box::new),
59 distinct: false,
60 filter: None,
61 }
62 }
63
64 #[must_use]
66 pub fn distinct(mut self) -> Self {
67 self.distinct = true;
68 self
69 }
70
71 #[must_use]
73 pub fn filter(mut self, predicate: Expr) -> Self {
74 self.filter = Some(Box::new(match self.filter.take() {
75 Some(existing) => existing.and(predicate),
76 None => predicate,
77 }));
78 self
79 }
80
81 pub(super) fn children(&self) -> Vec<&Expr> {
83 self.arg
84 .as_deref()
85 .into_iter()
86 .chain(self.filter.as_deref())
87 .collect()
88 }
89
90 pub(super) fn children_mut(&mut self) -> Vec<&mut Expr> {
92 self.arg
93 .as_deref_mut()
94 .into_iter()
95 .chain(self.filter.as_deref_mut())
96 .collect()
97 }
98}
99
100impl From<Aggregate> for Expr {
101 fn from(agg: Aggregate) -> Self {
102 Expr::Aggregate(agg)
103 }
104}
105
106macro_rules! aggregate_of {
107 ($($(#[$doc:meta])* $name:ident => $func:expr;)*) => {$(
108 $(#[$doc])*
109 #[derive(Debug, Clone, Copy)]
110 pub struct $name;
111
112 impl $name {
113 pub fn of(expr: impl Into<Expr>) -> Aggregate {
115 Aggregate::new($func, Some(expr.into()))
116 }
117 }
118 )*};
119}
120
121aggregate_of! {
122 Sum => AggFunc::Sum;
124 Avg => AggFunc::Avg;
126 Min => AggFunc::Min;
128 Max => AggFunc::Max;
130 ArrayAgg => AggFunc::ArrayAgg;
132}
133
134#[derive(Debug, Clone, Copy)]
136pub struct Count;
137
138impl Count {
139 pub fn all() -> Aggregate {
141 Aggregate::new(AggFunc::Count, None)
142 }
143
144 pub fn of(expr: impl Into<Expr>) -> Aggregate {
146 Aggregate::new(AggFunc::Count, Some(expr.into()))
147 }
148}
149
150#[derive(Debug, Clone, Copy)]
152pub struct StdDev;
153
154impl StdDev {
155 pub fn population(expr: impl Into<Expr>) -> Aggregate {
157 Aggregate::new(AggFunc::StdDev { sample: false }, Some(expr.into()))
158 }
159
160 pub fn sample(expr: impl Into<Expr>) -> Aggregate {
162 Aggregate::new(AggFunc::StdDev { sample: true }, Some(expr.into()))
163 }
164}
165
166#[derive(Debug, Clone, Copy)]
168pub struct Variance;
169
170impl Variance {
171 pub fn population(expr: impl Into<Expr>) -> Aggregate {
173 Aggregate::new(AggFunc::Variance { sample: false }, Some(expr.into()))
174 }
175
176 pub fn sample(expr: impl Into<Expr>) -> Aggregate {
178 Aggregate::new(AggFunc::Variance { sample: true }, Some(expr.into()))
179 }
180}
181
182#[derive(Debug, Clone, Copy)]
184pub struct StringAgg;
185
186impl StringAgg {
187 pub fn of(expr: impl Into<Expr>, separator: impl Into<String>) -> Aggregate {
189 Aggregate::new(
190 AggFunc::StringAgg {
191 separator: separator.into(),
192 },
193 Some(expr.into()),
194 )
195 }
196}