diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-08-04 17:53:10 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2015-08-04 17:53:10 +0300 |
commit | 804163bc25e979fcd91b02e58fa2d1c6b587cc65 (patch) | |
tree | 841c63e6356df2bc42b3729cb05ba2f9834bdd78 /src/backend/executor/nodeWindowAgg.c | |
parent | dee0200f0276c0f9da930a2c926f90f5615f2d64 (diff) | |
download | postgresql-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/nodeWindowAgg.c')
-rw-r--r-- | src/backend/executor/nodeWindowAgg.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index ecf96f8c193..c371d4db141 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -2218,20 +2218,16 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc, numArguments); /* build expression trees using actual argument & result types */ - build_aggregate_fnexprs(inputTypes, - numArguments, - 0, /* no ordered-set window functions yet */ - peraggstate->numFinalArgs, - false, /* no variadic window functions yet */ - aggtranstype, - wfunc->wintype, - wfunc->inputcollid, - transfn_oid, - invtransfn_oid, - finalfn_oid, - &transfnexpr, - &invtransfnexpr, - &finalfnexpr); + build_aggregate_transfn_expr(inputTypes, + numArguments, + 0, /* no ordered-set window functions yet */ + false, /* no variadic window functions yet */ + wfunc->wintype, + wfunc->inputcollid, + transfn_oid, + invtransfn_oid, + &transfnexpr, + &invtransfnexpr); /* set up infrastructure for calling the transfn(s) and finalfn */ fmgr_info(transfn_oid, &peraggstate->transfn); @@ -2245,6 +2241,13 @@ initialize_peragg(WindowAggState *winstate, WindowFunc *wfunc, if (OidIsValid(finalfn_oid)) { + build_aggregate_finalfn_expr(inputTypes, + peraggstate->numFinalArgs, + aggtranstype, + wfunc->wintype, + wfunc->inputcollid, + finalfn_oid, + &finalfnexpr); fmgr_info(finalfn_oid, &peraggstate->finalfn); fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn); } |