* Compute the final value of all aggregates for one group. * * This function handles only one grouping set at a time, which the caller must * have selected. It's also the caller's responsibility to adjust the supplied * pergroup parameter to point to the current set's transvalues. * * Results are stored in the output econtext aggvalues/aggnulls. */
| 1353 | * Results are stored in the output econtext aggvalues/aggnulls. |
| 1354 | */ |
| 1355 | static void |
| 1356 | finalize_aggregates(AggState *aggstate, |
| 1357 | AggStatePerAgg peraggs, |
| 1358 | AggStatePerGroup pergroup) |
| 1359 | { |
| 1360 | ExprContext *econtext = aggstate->ss.ps.ps_ExprContext; |
| 1361 | Datum *aggvalues = econtext->ecxt_aggvalues; |
| 1362 | bool *aggnulls = econtext->ecxt_aggnulls; |
| 1363 | int aggno; |
| 1364 | int transno; |
| 1365 | |
| 1366 | /* |
| 1367 | * If there were any DISTINCT and/or ORDER BY aggregates, sort their |
| 1368 | * inputs and run the transition functions. |
| 1369 | */ |
| 1370 | for (transno = 0; transno < aggstate->numtrans; transno++) |
| 1371 | { |
| 1372 | AggStatePerTrans pertrans = &aggstate->pertrans[transno]; |
| 1373 | AggStatePerGroup pergroupstate; |
| 1374 | if (!bms_is_member(transno, aggstate->aggs_used)) |
| 1375 | continue; |
| 1376 | pergroupstate = &pergroup[transno]; |
| 1377 | |
| 1378 | if (pertrans->numSortCols > 0) |
| 1379 | { |
| 1380 | Assert(aggstate->aggstrategy != AGG_HASHED && |
| 1381 | aggstate->aggstrategy != AGG_MIXED); |
| 1382 | |
| 1383 | if (pertrans->numInputs == 1) |
| 1384 | process_ordered_aggregate_single(aggstate, |
| 1385 | pertrans, |
| 1386 | pergroupstate); |
| 1387 | else |
| 1388 | process_ordered_aggregate_multi(aggstate, |
| 1389 | pertrans, |
| 1390 | pergroupstate); |
| 1391 | } |
| 1392 | } |
| 1393 | |
| 1394 | /* |
| 1395 | * Run the final functions. |
| 1396 | */ |
| 1397 | for (aggno = 0; aggno < aggstate->numaggs; aggno++) |
| 1398 | { |
| 1399 | AggStatePerAgg peragg = &peraggs[aggno]; |
| 1400 | int transno = peragg->transno; |
| 1401 | AggStatePerGroup pergroupstate; |
| 1402 | |
| 1403 | if (!bms_is_member(transno, aggstate->aggs_used) || !peragg->aggref) |
| 1404 | continue; |
| 1405 | |
| 1406 | pergroupstate = &pergroup[transno]; |
| 1407 | |
| 1408 | if (DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit)) |
| 1409 | finalize_partialaggregate(aggstate, peragg, pergroupstate, |
| 1410 | &aggvalues[aggno], &aggnulls[aggno]); |
| 1411 | else |
| 1412 | finalize_aggregate(aggstate, peragg, pergroupstate, |
no test coverage detected