use crate::types::{AggregateExpr, SqlExpr};
pub fn aggregate_function_name(a: &AggregateExpr) -> String {
if !a.distinct {
return a.function.clone();
}
match a.function.as_str() {
"count" => "count_distinct".into(),
"array_agg" => "array_agg_distinct".into(),
"sum" => "sum_distinct".into(),
"avg" => "avg_distinct".into(),
_ => a.function.clone(),
}
}
pub fn aggregate_field_name(a: &AggregateExpr) -> String {
a.args
.first()
.map(|arg| match arg {
SqlExpr::Column { name, .. } => name.clone(),
_ => "*".to_string(),
})
.unwrap_or_else(|| "*".to_string())
}
pub fn aggregate_output_key(a: &AggregateExpr) -> String {
let arg = a
.arg_text
.clone()
.unwrap_or_else(|| aggregate_field_name(a));
let base = nodedb_query::agg_key::canonical_agg_key(&aggregate_function_name(a), &arg);
match &a.filter_text {
None => base,
Some(text) => format!("{base} filter (where {text})"),
}
}
pub fn computed_group_key_name(index: usize) -> String {
format!("group_{index}")
}
pub fn group_key_row_name(key: &SqlExpr, index: usize) -> String {
match key {
SqlExpr::Column { name, .. } => name.clone(),
SqlExpr::Function { .. }
| SqlExpr::BinaryOp { .. }
| SqlExpr::UnaryOp { .. }
| SqlExpr::Cast { .. }
| SqlExpr::IsNull { .. }
| SqlExpr::Case { .. }
| SqlExpr::InList { .. }
| SqlExpr::Between { .. }
| SqlExpr::Like { .. }
| SqlExpr::ArrayLiteral(_)
| SqlExpr::Literal(_)
| SqlExpr::Subquery(_)
| SqlExpr::Wildcard => computed_group_key_name(index),
}
}