summaryrefslogtreecommitdiff
path: root/tests/aggregation
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2021-12-01 00:43:39 -0500
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-12-02 07:23:33 +0100
commite5a92d400acb4ca6a8e1375d1ab8121f2c7220be (patch)
tree288bbfaafb587ea31f752c0ea955d695e9edcd47 /tests/aggregation
parente3bde71676a704e27d62e5f96dd967f7305db7f2 (diff)
downloaddjango-e5a92d400acb4ca6a8e1375d1ab8121f2c7220be.tar.gz
Fixed #33282 -- Fixed a crash when OR'ing subquery and aggregation lookups.
As a QuerySet resolves to Query the outer column references grouping logic should be defined on the latter and proxied from Subquery for the cases where get_group_by_cols is called on unresolved expressions. Thanks Antonio Terceiro for the report and initial patch.
Diffstat (limited to 'tests/aggregation')
-rw-r--r--tests/aggregation/tests.py34
1 files changed, 30 insertions, 4 deletions
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index 72575a526c..87ae945a7e 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -1280,10 +1280,17 @@ class AggregateTestCase(TestCase):
).values(
'publisher'
).annotate(count=Count('pk')).values('count')
- long_books_count_breakdown = Publisher.objects.values_list(
- Subquery(long_books_count_qs, IntegerField()),
- ).annotate(total=Count('*'))
- self.assertEqual(dict(long_books_count_breakdown), {None: 1, 1: 4})
+ groups = [
+ Subquery(long_books_count_qs),
+ long_books_count_qs,
+ long_books_count_qs.query,
+ ]
+ for group in groups:
+ with self.subTest(group=group.__class__.__name__):
+ long_books_count_breakdown = Publisher.objects.values_list(
+ group,
+ ).annotate(total=Count('*'))
+ self.assertEqual(dict(long_books_count_breakdown), {None: 1, 1: 4})
@skipUnlessDBFeature('supports_subqueries_in_group_by')
def test_group_by_exists_annotation(self):
@@ -1341,6 +1348,25 @@ class AggregateTestCase(TestCase):
).values_list('publisher_count', flat=True)
self.assertSequenceEqual(books_breakdown, [1] * 6)
+ def test_filter_in_subquery_or_aggregation(self):
+ """
+ Filtering against an aggregate requires the usage of the HAVING clause.
+
+ If such a filter is unionized to a non-aggregate one the latter will
+ also need to be moved to the HAVING clause and have its grouping
+ columns used in the GROUP BY.
+
+ When this is done with a subquery the specialized logic in charge of
+ using outer reference columns to group should be used instead of the
+ subquery itself as the latter might return multiple rows.
+ """
+ authors = Author.objects.annotate(
+ Count('book'),
+ ).filter(
+ Q(book__count__gt=0) | Q(pk__in=Book.objects.values('authors'))
+ )
+ self.assertQuerysetEqual(authors, Author.objects.all(), ordered=False)
+
def test_aggregation_random_ordering(self):
"""Random() is not included in the GROUP BY when used for ordering."""
authors = Author.objects.annotate(contact_count=Count('book')).order_by('?')