aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execQual.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2015-08-04 17:53:10 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2015-08-04 17:53:10 +0300
commit804163bc25e979fcd91b02e58fa2d1c6b587cc65 (patch)
tree841c63e6356df2bc42b3729cb05ba2f9834bdd78 /src/backend/executor/execQual.c
parentdee0200f0276c0f9da930a2c926f90f5615f2d64 (diff)
downloadpostgresql-804163bc25e979fcd91b02e58fa2d1c6b587cc65.tar.gz
postgresql-804163bc25e979fcd91b02e58fa2d1c6b587cc65.zip
Share transition state between different aggregates when possible.
If there are two different aggregates in the query with same inputs, and the aggregates have the same initial condition and transition function, only calculate the state value once, and only call the final functions separately. For example, AVG(x) and SUM(x) aggregates have the same transition function, which accumulates the sum and number of input tuples. For a query like "SELECT AVG(x), SUM(x) FROM x", we can therefore accumulate the state function only once, which gives a nice speedup. David Rowley, reviewed and edited by me.
Diffstat (limited to 'src/backend/executor/execQual.c')
-rw-r--r--src/backend/executor/execQual.c22
1 files changed, 1 insertions, 21 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 16bc8fa5f6c..29f058ce5cb 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -4487,35 +4487,15 @@ ExecInitExpr(Expr *node, PlanState *parent)
break;
case T_Aggref:
{
- Aggref *aggref = (Aggref *) node;
AggrefExprState *astate = makeNode(AggrefExprState);
astate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalAggref;
if (parent && IsA(parent, AggState))
{
AggState *aggstate = (AggState *) parent;
- int naggs;
aggstate->aggs = lcons(astate, aggstate->aggs);
- naggs = ++aggstate->numaggs;
-
- astate->aggdirectargs = (List *) ExecInitExpr((Expr *) aggref->aggdirectargs,
- parent);
- astate->args = (List *) ExecInitExpr((Expr *) aggref->args,
- parent);
- astate->aggfilter = ExecInitExpr(aggref->aggfilter,
- parent);
-
- /*
- * Complain if the aggregate's arguments contain any
- * aggregates; nested agg functions are semantically
- * nonsensical. (This should have been caught earlier,
- * but we defend against it here anyway.)
- */
- if (naggs != aggstate->numaggs)
- ereport(ERROR,
- (errcode(ERRCODE_GROUPING_ERROR),
- errmsg("aggregate function calls cannot be nested")));
+ aggstate->numaggs++;
}
else
{