diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index ffc9d3b13fd..9819be09a1f 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -240,10 +240,12 @@ class Query(object): obj.aggregate_select_mask = None else: obj.aggregate_select_mask = self.aggregate_select_mask.copy() - if self._aggregate_select_cache is None: - obj._aggregate_select_cache = None - else: - obj._aggregate_select_cache = self._aggregate_select_cache.copy() + # _aggregate_select_cache cannot be copied, as doing so breaks the + # (necessary) state in which both aggregates and + # _aggregate_select_cache point to the same underlying objects. + # It will get re-populated in the cloned queryset the next time it's + # used. + obj._aggregate_select_cache = None obj.max_depth = self.max_depth obj.extra = self.extra.copy() if self.extra_select_mask is None: diff --git a/tests/regressiontests/aggregation_regress/tests.py b/tests/regressiontests/aggregation_regress/tests.py new file mode 100644 index 00000000000..cf0f58a9a86 --- /dev/null +++ b/tests/regressiontests/aggregation_regress/tests.py @@ -0,0 +1,48 @@ +from django.test import TestCase +from django.db.models import Max + +from regressiontests.aggregation_regress.models import * + + +class AggregationTests(TestCase): + + def test_aggregates_in_where_clause(self): + """ + Regression test for #12822: DatabaseError: aggregates not allowed in + WHERE clause + + Tests that the subselect works and returns results equivalent to a + query with the IDs listed. + + Before the corresponding fix for this bug, this test passed in 1.1 and + failed in 1.2-beta (trunk). + """ + qs = Book.objects.values('contact').annotate(Max('id')) + qs = qs.order_by('contact').values_list('id__max', flat=True) + # don't do anything with the queryset (qs) before including it as a + # subquery + books = Book.objects.order_by('id') + qs1 = books.filter(id__in=qs) + qs2 = books.filter(id__in=list(qs)) + self.assertEqual(list(qs1), list(qs2)) + + def test_aggregates_in_where_clause_pre_eval(self): + """ + Regression test for #12822: DatabaseError: aggregates not allowed in + WHERE clause + + Same as the above test, but evaluates the queryset for the subquery + before it's used as a subquery. + + Before the corresponding fix for this bug, this test failed in both + 1.1 and 1.2-beta (trunk). + """ + qs = Book.objects.values('contact').annotate(Max('id')) + qs = qs.order_by('contact').values_list('id__max', flat=True) + # force the queryset (qs) for the subquery to be evaluated in its + # current state + list(qs) + books = Book.objects.order_by('id') + qs1 = books.filter(id__in=qs) + qs2 = books.filter(id__in=list(qs)) + self.assertEqual(list(qs1), list(qs2))