alopex_sql/planner/
aggregate_expr.rs1use crate::planner::typed_expr::{SortExpr, TypedExpr};
2use crate::planner::types::ResolvedType;
3
4#[derive(Debug, Clone, PartialEq)]
6pub enum AggregateFunction {
7 Count,
8 Sum,
9 Total,
10 Avg,
11 Min,
12 Max,
13 GroupConcat {
14 separator: Option<String>,
15 },
16 StringAgg {
17 separator: Option<String>,
18 },
19 PercentileDisc {
24 fraction: f64,
25 },
26}
27
28#[derive(Debug, Clone)]
30pub struct AggregateExpr {
31 pub function: AggregateFunction,
32 pub arg: Option<TypedExpr>,
33 pub distinct: bool,
34 pub result_type: ResolvedType,
35 pub filter: Option<TypedExpr>,
38 pub order_by: Vec<SortExpr>,
43}
44
45impl AggregateExpr {
46 pub fn count_star() -> Self {
47 Self {
48 function: AggregateFunction::Count,
49 arg: None,
50 distinct: false,
51 result_type: ResolvedType::BigInt,
52 filter: None,
53 order_by: Vec::new(),
54 }
55 }
56
57 pub fn count(arg: TypedExpr, distinct: bool) -> Self {
58 Self {
59 function: AggregateFunction::Count,
60 arg: Some(arg),
61 distinct,
62 result_type: ResolvedType::BigInt,
63 filter: None,
64 order_by: Vec::new(),
65 }
66 }
67
68 pub fn sum(arg: TypedExpr) -> Self {
69 let result_type = sum_result_type(&arg.resolved_type);
70 Self {
71 function: AggregateFunction::Sum,
72 arg: Some(arg),
73 distinct: false,
74 result_type,
75 filter: None,
76 order_by: Vec::new(),
77 }
78 }
79
80 pub fn total(arg: TypedExpr) -> Self {
81 Self {
82 function: AggregateFunction::Total,
83 arg: Some(arg),
84 distinct: false,
85 result_type: ResolvedType::Double,
86 filter: None,
87 order_by: Vec::new(),
88 }
89 }
90
91 pub fn avg(arg: TypedExpr) -> Self {
92 Self {
93 function: AggregateFunction::Avg,
94 arg: Some(arg),
95 distinct: false,
96 result_type: ResolvedType::Double,
97 filter: None,
98 order_by: Vec::new(),
99 }
100 }
101
102 pub fn min(arg: TypedExpr) -> Self {
103 let result_type = arg.resolved_type.clone();
104 Self {
105 function: AggregateFunction::Min,
106 arg: Some(arg),
107 distinct: false,
108 result_type,
109 filter: None,
110 order_by: Vec::new(),
111 }
112 }
113
114 pub fn max(arg: TypedExpr) -> Self {
115 let result_type = arg.resolved_type.clone();
116 Self {
117 function: AggregateFunction::Max,
118 arg: Some(arg),
119 distinct: false,
120 result_type,
121 filter: None,
122 order_by: Vec::new(),
123 }
124 }
125}
126
127pub fn sum_result_type(input_type: &ResolvedType) -> ResolvedType {
137 match input_type {
138 ResolvedType::Integer | ResolvedType::BigInt => ResolvedType::BigInt,
139 _ => ResolvedType::Double,
140 }
141}