mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
Implement the FILTER clause for aggregate function calls.
This is SQL-standard with a few extensions, namely support for subqueries and outer references in clause expressions. catversion bump due to change in Aggref and WindowFunc. David Fetter, reviewed by Dean Rasheed.
This commit is contained in:
@ -1590,6 +1590,14 @@ cost_windowagg(Path *path, PlannerInfo *root,
|
||||
startup_cost += argcosts.startup;
|
||||
wfunccost += argcosts.per_tuple;
|
||||
|
||||
/*
|
||||
* Add the filter's cost to per-input-row costs. XXX We should reduce
|
||||
* input expression costs according to filter selectivity.
|
||||
*/
|
||||
cost_qual_eval_node(&argcosts, (Node *) wfunc->aggfilter, root);
|
||||
startup_cost += argcosts.startup;
|
||||
wfunccost += argcosts.per_tuple;
|
||||
|
||||
total_cost += wfunccost * input_tuples;
|
||||
}
|
||||
|
||||
|
@ -329,6 +329,12 @@ find_minmax_aggs_walker(Node *node, List **context)
|
||||
*/
|
||||
if (aggref->aggorder != NIL)
|
||||
return true;
|
||||
/*
|
||||
* We might implement the optimization when a FILTER clause is present
|
||||
* by adding the filter to the quals of the generated subquery.
|
||||
*/
|
||||
if (aggref->aggfilter != NULL)
|
||||
return true;
|
||||
/* note: we do not care if DISTINCT is mentioned ... */
|
||||
|
||||
aggsortop = fetch_agg_sort_op(aggref->aggfnoid);
|
||||
|
@ -495,6 +495,15 @@ count_agg_clauses_walker(Node *node, count_agg_clauses_context *context)
|
||||
costs->transCost.startup += argcosts.startup;
|
||||
costs->transCost.per_tuple += argcosts.per_tuple;
|
||||
|
||||
/*
|
||||
* Add the filter's cost to per-input-row costs. XXX We should reduce
|
||||
* input expression costs according to filter selectivity.
|
||||
*/
|
||||
cost_qual_eval_node(&argcosts, (Node *) aggref->aggfilter,
|
||||
context->root);
|
||||
costs->transCost.startup += argcosts.startup;
|
||||
costs->transCost.per_tuple += argcosts.per_tuple;
|
||||
|
||||
/* extract argument types (ignoring any ORDER BY expressions) */
|
||||
inputTypes = (Oid *) palloc(sizeof(Oid) * list_length(aggref->args));
|
||||
numArguments = 0;
|
||||
@ -565,7 +574,8 @@ count_agg_clauses_walker(Node *node, count_agg_clauses_context *context)
|
||||
|
||||
/*
|
||||
* Complain if the aggregate's arguments contain any aggregates;
|
||||
* nested agg functions are semantically nonsensical.
|
||||
* nested agg functions are semantically nonsensical. Aggregates in
|
||||
* the FILTER clause are detected in transformAggregateCall().
|
||||
*/
|
||||
if (contain_agg_clause((Node *) aggref->args))
|
||||
ereport(ERROR,
|
||||
@ -639,7 +649,8 @@ find_window_functions_walker(Node *node, WindowFuncLists *lists)
|
||||
|
||||
/*
|
||||
* Complain if the window function's arguments contain window
|
||||
* functions
|
||||
* functions. Window functions in the FILTER clause are detected in
|
||||
* transformAggregateCall().
|
||||
*/
|
||||
if (contain_window_function((Node *) wfunc->args))
|
||||
ereport(ERROR,
|
||||
|
Reference in New Issue
Block a user