diff options
| author | Simon Charette <charette.s@gmail.com> | 2021-05-21 22:32:16 -0400 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2021-07-02 07:25:42 +0200 |
| commit | 9f3cce172f6913c5ac74272fa5fc07f847b4e112 (patch) | |
| tree | 027dec2a7a1bef8c02c2e58ffded8718401b28d1 /django/db/models/sql/query.py | |
| parent | f3112fde981052801e0c2121027424496c03efdf (diff) | |
Refs #26430 -- Re-introduced empty aggregation optimization.
The introduction of the Expression.empty_aggregate_value interface
allows the compilation stage to enable the EmptyResultSet optimization
if all the aggregates expressions implement it.
This also removes unnecessary RegrCount/Count.convert_value() methods.
Disabling the empty result set aggregation optimization when it wasn't
appropriate prevented None returned for a Count aggregation value.
Thanks Nick Pope for the review.
Diffstat (limited to 'django/db/models/sql/query.py')
| -rw-r--r-- | django/db/models/sql/query.py | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index fabb346418..87be8ea9f0 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -490,12 +490,19 @@ class Query(BaseExpression): self.default_cols = False self.extra = {} + empty_aggregate_result = [ + expression.empty_aggregate_value + for expression in outer_query.annotation_select.values() + ] + elide_empty = not any(result is NotImplemented for result in empty_aggregate_result) outer_query.clear_ordering(force=True) outer_query.clear_limits() outer_query.select_for_update = False outer_query.select_related = False - compiler = outer_query.get_compiler(using, elide_empty=False) + compiler = outer_query.get_compiler(using, elide_empty=elide_empty) result = compiler.execute_sql(SINGLE) + if result is None: + result = empty_aggregate_result converters = compiler.get_converters(outer_query.annotation_select.values()) result = next(compiler.apply_converters((result,), converters)) |
