mirror of
https://github.com/django/django.git
synced 2025-01-13 03:47:26 +00:00
[4.2.x] Fixed #34717 -- Fixed QuerySet.aggregate() crash when referencing window functions.
Regression in59bea9efd2
. Refs #28477. Thanks younes-chaoui for the report. Backport of68912e4f6f
from main
This commit is contained in:
parent
c646412a75
commit
7a67b065d7
@ -390,6 +390,7 @@ class Query(BaseExpression):
|
|||||||
# Store annotation mask prior to temporarily adding aggregations for
|
# Store annotation mask prior to temporarily adding aggregations for
|
||||||
# resolving purpose to facilitate their subsequent removal.
|
# resolving purpose to facilitate their subsequent removal.
|
||||||
refs_subquery = False
|
refs_subquery = False
|
||||||
|
refs_window = False
|
||||||
replacements = {}
|
replacements = {}
|
||||||
annotation_select_mask = self.annotation_select_mask
|
annotation_select_mask = self.annotation_select_mask
|
||||||
for alias, aggregate_expr in aggregate_exprs.items():
|
for alias, aggregate_expr in aggregate_exprs.items():
|
||||||
@ -406,6 +407,10 @@ class Query(BaseExpression):
|
|||||||
getattr(self.annotations[ref], "subquery", False)
|
getattr(self.annotations[ref], "subquery", False)
|
||||||
for ref in aggregate.get_refs()
|
for ref in aggregate.get_refs()
|
||||||
)
|
)
|
||||||
|
refs_window |= any(
|
||||||
|
getattr(self.annotations[ref], "contains_over_clause", True)
|
||||||
|
for ref in aggregate.get_refs()
|
||||||
|
)
|
||||||
aggregate = aggregate.replace_expressions(replacements)
|
aggregate = aggregate.replace_expressions(replacements)
|
||||||
self.annotations[alias] = aggregate
|
self.annotations[alias] = aggregate
|
||||||
replacements[Ref(alias, aggregate)] = aggregate
|
replacements[Ref(alias, aggregate)] = aggregate
|
||||||
@ -438,6 +443,7 @@ class Query(BaseExpression):
|
|||||||
or self.is_sliced
|
or self.is_sliced
|
||||||
or has_existing_aggregation
|
or has_existing_aggregation
|
||||||
or refs_subquery
|
or refs_subquery
|
||||||
|
or refs_window
|
||||||
or qualify
|
or qualify
|
||||||
or self.distinct
|
or self.distinct
|
||||||
or self.combinator
|
or self.combinator
|
||||||
|
@ -9,4 +9,6 @@ Django 4.2.4 fixes several bugs in 4.2.3.
|
|||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed a regression in Django 4.2 that caused a crash of
|
||||||
|
``QuerySet.aggregate()`` with aggregates referencing window functions
|
||||||
|
(:ticket:`34717`).
|
||||||
|
@ -28,6 +28,7 @@ from django.db.models import (
|
|||||||
Value,
|
Value,
|
||||||
Variance,
|
Variance,
|
||||||
When,
|
When,
|
||||||
|
Window,
|
||||||
)
|
)
|
||||||
from django.db.models.expressions import Func, RawSQL
|
from django.db.models.expressions import Func, RawSQL
|
||||||
from django.db.models.functions import (
|
from django.db.models.functions import (
|
||||||
@ -2207,3 +2208,23 @@ class AggregateAnnotationPruningTests(TestCase):
|
|||||||
sql = ctx.captured_queries[0]["sql"].lower()
|
sql = ctx.captured_queries[0]["sql"].lower()
|
||||||
self.assertEqual(sql.count("select"), 3, "Subquery wrapping required")
|
self.assertEqual(sql.count("select"), 3, "Subquery wrapping required")
|
||||||
self.assertEqual(aggregate, {"sum_total_books": 3})
|
self.assertEqual(aggregate, {"sum_total_books": 3})
|
||||||
|
|
||||||
|
@skipUnlessDBFeature("supports_over_clause")
|
||||||
|
def test_referenced_window_requires_wrapping(self):
|
||||||
|
total_books_qs = Book.objects.annotate(
|
||||||
|
avg_publisher_pages=Coalesce(
|
||||||
|
Window(Avg("pages"), partition_by=F("publisher")),
|
||||||
|
0.0,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
with self.assertNumQueries(1) as ctx:
|
||||||
|
aggregate = total_books_qs.aggregate(
|
||||||
|
sum_avg_publisher_pages=Sum("avg_publisher_pages"),
|
||||||
|
books_count=Count("id"),
|
||||||
|
)
|
||||||
|
sql = ctx.captured_queries[0]["sql"].lower()
|
||||||
|
self.assertEqual(sql.count("select"), 2, "Subquery wrapping required")
|
||||||
|
self.assertEqual(
|
||||||
|
aggregate,
|
||||||
|
{"sum_avg_publisher_pages": 1100.0, "books_count": 2},
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user