summaryrefslogtreecommitdiff
path: root/tests/aggregation
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2022-11-13 23:45:33 -0500
committerGitHub <noreply@github.com>2022-11-14 05:45:33 +0100
commit10037130c123cd747d32a14a9ba47e0c5c9a37d1 (patch)
treed675e31eccbc93ab389b11f504f81bbe89144451 /tests/aggregation
parentb088cc2feaac638aea91e4d3ab22d276f81630ff (diff)
downloaddjango-10037130c123cd747d32a14a9ba47e0c5c9a37d1.tar.gz
Refs #28477 -- Fixed handling aliased annotations on aggregation.
Just like when using .annotate(), the .alias() method will generate the necessary JOINs to resolve the alias even if not selected. Since these JOINs could be multi-valued non-selected aggregates must be considered to require subquery wrapping as a GROUP BY is required to combine duplicated tuples from the base table. Regression in 59bea9efd2768102fc9d3aedda469502c218e9b7.
Diffstat (limited to 'tests/aggregation')
-rw-r--r--tests/aggregation/tests.py35
1 files changed, 32 insertions, 3 deletions
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index a20c4d10a1..c098716cca 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -2088,13 +2088,41 @@ class AggregateTestCase(TestCase):
class AggregateAnnotationPruningTests(TestCase):
+ @classmethod
+ def setUpTestData(cls):
+ cls.a1 = Author.objects.create(age=1)
+ cls.a2 = Author.objects.create(age=2)
+ cls.p1 = Publisher.objects.create(num_awards=1)
+ cls.p2 = Publisher.objects.create(num_awards=0)
+ cls.b1 = Book.objects.create(
+ name="b1",
+ publisher=cls.p1,
+ pages=100,
+ rating=4.5,
+ price=10,
+ contact=cls.a1,
+ pubdate=datetime.date.today(),
+ )
+ cls.b1.authors.add(cls.a1)
+ cls.b2 = Book.objects.create(
+ name="b2",
+ publisher=cls.p2,
+ pages=1000,
+ rating=3.2,
+ price=50,
+ contact=cls.a2,
+ pubdate=datetime.date.today(),
+ )
+ cls.b2.authors.add(cls.a1, cls.a2)
+
def test_unused_aliased_aggregate_pruned(self):
with CaptureQueriesContext(connection) as ctx:
- Book.objects.alias(
+ cnt = Book.objects.alias(
authors_count=Count("authors"),
).count()
+ self.assertEqual(cnt, 2)
sql = ctx.captured_queries[0]["sql"].lower()
- self.assertEqual(sql.count("select"), 1, "No subquery wrapping required")
+ self.assertEqual(sql.count("select"), 2, "Subquery wrapping required")
self.assertNotIn("authors_count", sql)
def test_non_aggregate_annotation_pruned(self):
@@ -2108,9 +2136,10 @@ class AggregateAnnotationPruningTests(TestCase):
def test_unreferenced_aggregate_annotation_pruned(self):
with CaptureQueriesContext(connection) as ctx:
- Book.objects.annotate(
+ cnt = Book.objects.annotate(
authors_count=Count("authors"),
).count()
+ self.assertEqual(cnt, 2)
sql = ctx.captured_queries[0]["sql"].lower()
self.assertEqual(sql.count("select"), 2, "Subquery wrapping required")
self.assertNotIn("authors_count", sql)