Common part of the planning of windowed and non-windowed aggregation functions.
(
ecx: &ExprContext,
Function::<Aug> {
name,
args,
filter,
over: _,
distinct,
}: &Function<Aug>,
)
| 5204 | |
| 5205 | /// Common part of the planning of windowed and non-windowed aggregation functions. |
| 5206 | fn plan_aggregate_common( |
| 5207 | ecx: &ExprContext, |
| 5208 | Function::<Aug> { |
| 5209 | name, |
| 5210 | args, |
| 5211 | filter, |
| 5212 | over: _, |
| 5213 | distinct, |
| 5214 | }: &Function<Aug>, |
| 5215 | ) -> Result<AggregateExpr, PlanError> { |
| 5216 | // Normal aggregate functions, like `sum`, expect as input a single expression |
| 5217 | // which yields the datum to aggregate. Order sensitive aggregate functions, |
| 5218 | // like `jsonb_agg`, are special, and instead expect a Record whose first |
| 5219 | // element yields the datum to aggregate and whose successive elements yield |
| 5220 | // keys to order by. This expectation is hard coded within the implementation |
| 5221 | // of each of the order-sensitive aggregates. The specification of how many |
| 5222 | // order by keys to consider, and in what order, is passed via the `order_by` |
| 5223 | // field on the `AggregateFunc` variant. |
| 5224 | |
| 5225 | // While all aggregate functions support the ORDER BY syntax, it's a no-op for |
| 5226 | // most, so explicitly drop it if the function doesn't care about order. This |
| 5227 | // prevents the projection into Record below from triggering on unsupported |
| 5228 | // functions. |
| 5229 | |
| 5230 | let impls = match resolve_func(ecx, name, args)? { |
| 5231 | Func::Aggregate(impls) => impls, |
| 5232 | _ => bail_internal!("plan_aggregate_common called on non-aggregate function"), |
| 5233 | }; |
| 5234 | |
| 5235 | // We follow PostgreSQL's rule here for mapping `count(*)` into the |
| 5236 | // generalized function selection framework. The rule is simple: the user |
| 5237 | // must type `count(*)`, but the function selection framework sees an empty |
| 5238 | // parameter list, as if the user had typed `count()`. But if the user types |
| 5239 | // `count()` directly, that is an error. Like PostgreSQL, we apply these |
| 5240 | // rules to all aggregates, not just `count`, since we may one day support |
| 5241 | // user-defined aggregates, including user-defined aggregates that take no |
| 5242 | // parameters. |
| 5243 | let (args, order_by) = match &args { |
| 5244 | FunctionArgs::Star => (vec![], vec![]), |
| 5245 | FunctionArgs::Args { args, order_by } => { |
| 5246 | if args.is_empty() { |
| 5247 | sql_bail!( |
| 5248 | "{}(*) must be used to call a parameterless aggregate function", |
| 5249 | humanize_or_debug(ecx.qcx.scx, name) |
| 5250 | ); |
| 5251 | } |
| 5252 | let args = plan_exprs(ecx, args)?; |
| 5253 | (args, order_by.clone()) |
| 5254 | } |
| 5255 | }; |
| 5256 | |
| 5257 | let (order_by_exprs, col_orders) = plan_function_order_by(ecx, &order_by)?; |
| 5258 | |
| 5259 | let (mut expr, func) = func::select_impl(ecx, FuncSpec::Func(name), impls, args, col_orders)?; |
| 5260 | if let Some(filter) = &filter { |
| 5261 | // If a filter is present, as in |
| 5262 | // |
| 5263 | // <agg>(<expr>) FILTER (WHERE <cond>) |
no test coverage detected