[3.0.x] Fixed #31109 -- Disabled grouping by aliases on QuerySet.exists().

Clearing the SELECT clause in Query.has_results was orphaning GROUP BY
references to it.

Thanks Thierry Bastian for the report and Baptiste Mispelon for the
bisect.

Regression in fb3f034f1c.

Backport of 720de4d044 from master
This commit is contained in:
Simon Charette 2019-12-21 23:22:49 -05:00 committed by Mariusz Felisiak
parent b1a309f6f0
commit 7b065c41e4
3 changed files with 19 additions and 2 deletions

View File

@ -527,7 +527,9 @@ class Query(BaseExpression):
if not q.distinct:
if q.group_by is True:
q.add_fields((f.attname for f in self.model._meta.concrete_fields), False)
q.set_group_by()
# Disable GROUP BY aliases to avoid orphaning references to the
# SELECT clause which is about to be cleared.
q.set_group_by(allow_aliases=False)
q.clear_select_clause()
q.clear_ordering(True)
q.set_limits(high=1)
@ -1920,7 +1922,7 @@ class Query(BaseExpression):
if force_empty:
self.default_ordering = False
def set_group_by(self):
def set_group_by(self, allow_aliases=True):
"""
Expand the GROUP BY clause required by the query.
@ -1943,6 +1945,8 @@ class Query(BaseExpression):
warnings.warn(msg, category=RemovedInDjango40Warning)
group_by_cols = annotation.get_group_by_cols()
else:
if not allow_aliases:
alias = None
group_by_cols = annotation.get_group_by_cols(alias=alias)
group_by.extend(group_by_cols)
self.group_by = tuple(group_by)

View File

@ -11,3 +11,6 @@ Bugfixes
* Fixed a regression in Django 3.0 that didn't include columns referenced by a
``Subquery()`` in the ``GROUP BY`` clause (:ticket:`31094`).
* Fixed a regression in Django 3.0 where ``QuerySet.exists()`` crashed if a
queryset contained an aggregation over a ``Subquery()`` (:ticket:`31109`).

View File

@ -1139,6 +1139,16 @@ class AggregateTestCase(TestCase):
list(publisher_qs)
self.assertEqual(ctx[0]['sql'].count('SELECT'), 2)
def test_aggregation_subquery_annotation_exists(self):
latest_book_pubdate_qs = Book.objects.filter(
publisher=OuterRef('pk')
).order_by('-pubdate').values('pubdate')[:1]
publisher_qs = Publisher.objects.annotate(
latest_book_pubdate=Subquery(latest_book_pubdate_qs),
count=Count('book'),
)
self.assertTrue(publisher_qs.exists())
@skipUnlessDBFeature('supports_subqueries_in_group_by')
def test_group_by_subquery_annotation(self):
"""