Fixed #34975 -- Fixed crash of conditional aggregate() over aggregations.

Adjustments made to solve_lookup_type to defer the resolving of
references for summarized aggregates failed to account for similar
requirements for lookup values which can also reference annotations
through Aggregate.filter.

Regression in b181cae2e3.

Refs #25307.

Thanks Sergey Nesterenko for the report.
This commit is contained in:
Simon Charette 2023-11-17 19:42:44 -05:00 committed by Mariusz Felisiak
parent 594873befb
commit 7530cf3900
3 changed files with 13 additions and 2 deletions

View File

@ -1256,12 +1256,13 @@ class Query(BaseExpression):
sql = "(%s)" % sql sql = "(%s)" % sql
return sql, params return sql, params
def resolve_lookup_value(self, value, can_reuse, allow_joins): def resolve_lookup_value(self, value, can_reuse, allow_joins, summarize=False):
if hasattr(value, "resolve_expression"): if hasattr(value, "resolve_expression"):
value = value.resolve_expression( value = value.resolve_expression(
self, self,
reuse=can_reuse, reuse=can_reuse,
allow_joins=allow_joins, allow_joins=allow_joins,
summarize=summarize,
) )
elif isinstance(value, (list, tuple)): elif isinstance(value, (list, tuple)):
# The items of the iterable may be expressions and therefore need # The items of the iterable may be expressions and therefore need
@ -1487,7 +1488,7 @@ class Query(BaseExpression):
raise FieldError("Joined field references are not permitted in this query") raise FieldError("Joined field references are not permitted in this query")
pre_joins = self.alias_refcount.copy() pre_joins = self.alias_refcount.copy()
value = self.resolve_lookup_value(value, can_reuse, allow_joins) value = self.resolve_lookup_value(value, can_reuse, allow_joins, summarize)
used_joins = { used_joins = {
k for k, v in self.alias_refcount.items() if v > pre_joins.get(k, 0) k for k, v in self.alias_refcount.items() if v > pre_joins.get(k, 0)
} }

View File

@ -11,3 +11,7 @@ Bugfixes
* Fixed a regression in Django 4.2 that caused :option:`makemigrations --check` * Fixed a regression in Django 4.2 that caused :option:`makemigrations --check`
to stop displaying pending migrations (:ticket:`34457`). to stop displaying pending migrations (:ticket:`34457`).
* Fixed a regression in Django 4.2 that caused a crash of
``QuerySet.aggregate()`` with aggregates referencing other aggregates or
window functions through conditional expressions (:ticket:`34975`).

View File

@ -2309,3 +2309,9 @@ class AggregateAnnotationPruningTests(TestCase):
aggregate, aggregate,
{"sum_avg_publisher_pages": 1100.0, "books_count": 2}, {"sum_avg_publisher_pages": 1100.0, "books_count": 2},
) )
def test_aggregate_reference_lookup_rhs(self):
aggregates = Author.objects.annotate(
max_book_author=Max("book__authors"),
).aggregate(count=Count("id", filter=Q(id=F("max_book_author"))))
self.assertEqual(aggregates, {"count": 1})