-
Type:
New Feature
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Query
-
None
-
5
-
None
-
None
-
None
-
None
-
None
-
None
-
None
This ticket adds accumulator support so that aggregate functions can be used in the SELECT list and in the HAVING clause of a grouped query.
SELECT p.country, COUNT(*), SUM(p.amount) FROM Payment p GROUP BY p.country HAVING COUNT(*) > 1
MongoDB mapping
Each aggregate function becomes an accumulator field in the $group stage.
An aggregate in SELECT is projected normally:
[
{"$group": {"_id": {"country": "$country"}, "#count_0": {"$sum": 1}, "#sum_0": {"$sum": "$amount"}}},
{"$project": {"_id#country": "$_id.country", "#count_0": "$#count_0", "#sum_0": "$#sum_0"}}
]
An aggregate that appears only in HAVING is computed per group for filtering and must not appear in the result, so it is added as a hidden accumulator and excluded from $project:
[
{"$group": {"_id": {"country": "$country"}, "_having_0": {"$sum": 1}}},
{"$match": {"_having_0": {"$gt": 1}}},
{"$project": {"_id#country": "$_id.country", "_having_0": 0}}
]
Aggregate functions in ORDER BY resolve to their accumulator field already registered in $group.
Implementation approach
- Each aggregate function encountered registers a named accumulator (for example #count_0) in GroupByContext and yields a field reference to it.
- The $group stage emits both group keys and registered accumulators.
- $sort and $project reference registered named accumulators in GroupByContext; a hidden HAVING-only accumulator is not addressable from either.
- HAVING with aggregates needs a two-phase approach: $group must be emitted before $match, but HAVING has to be scanned first to know which accumulators to add.
Acceptance criteria
- All standard aggregate functions (COUNT, SUM, AVG, MIN, MAX) are supported in the SELECT list of a grouped query.
- Aggregate functions in ORDER BY resolve to their accumulator field without re-computation.
- Aggregate functions in HAVING that do not appear in SELECT are computed as hidden accumulators and are absent from the result.
- An aggregate function shared between HAVING and SELECT reuses the same accumulator, with no duplication in $group.
- Expressions wrapping aggregates (for example AVG
+ 1) are supported: the accumulator is registered for the inner aggregate and the outer arithmetic is resolved in $project. - Non-aggregate, non-grouped columns in SELECT still throw FeatureNotSupportedException.
- Integration tests cover each aggregate function individually and in combination, plus HAVING aggregate only, HAVING and SELECT with the same and with different functions, HAVING with an expression wrapping an aggregate, and HAVING with ORDER BY.
- is duplicated by
-
HIBERNATE-240 Support aggregate functions in HAVING clause
-
- Closed
-