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
.
This commit is contained in:
parent
cebd41e416
commit
720de4d044
|
@ -526,7 +526,9 @@ class Query(BaseExpression):
|
||||||
if not q.distinct:
|
if not q.distinct:
|
||||||
if q.group_by is True:
|
if q.group_by is True:
|
||||||
q.add_fields((f.attname for f in self.model._meta.concrete_fields), False)
|
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_select_clause()
|
||||||
q.clear_ordering(True)
|
q.clear_ordering(True)
|
||||||
q.set_limits(high=1)
|
q.set_limits(high=1)
|
||||||
|
@ -1916,7 +1918,7 @@ class Query(BaseExpression):
|
||||||
if force_empty:
|
if force_empty:
|
||||||
self.default_ordering = False
|
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.
|
Expand the GROUP BY clause required by the query.
|
||||||
|
|
||||||
|
@ -1938,6 +1940,8 @@ class Query(BaseExpression):
|
||||||
warnings.warn(msg, category=RemovedInDjango40Warning)
|
warnings.warn(msg, category=RemovedInDjango40Warning)
|
||||||
group_by_cols = annotation.get_group_by_cols()
|
group_by_cols = annotation.get_group_by_cols()
|
||||||
else:
|
else:
|
||||||
|
if not allow_aliases:
|
||||||
|
alias = None
|
||||||
group_by_cols = annotation.get_group_by_cols(alias=alias)
|
group_by_cols = annotation.get_group_by_cols(alias=alias)
|
||||||
group_by.extend(group_by_cols)
|
group_by.extend(group_by_cols)
|
||||||
self.group_by = tuple(group_by)
|
self.group_by = tuple(group_by)
|
||||||
|
|
|
@ -11,3 +11,6 @@ Bugfixes
|
||||||
|
|
||||||
* Fixed a regression in Django 3.0 that didn't include columns referenced by a
|
* Fixed a regression in Django 3.0 that didn't include columns referenced by a
|
||||||
``Subquery()`` in the ``GROUP BY`` clause (:ticket:`31094`).
|
``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`).
|
||||||
|
|
|
@ -1141,6 +1141,16 @@ class AggregateTestCase(TestCase):
|
||||||
# The GROUP BY should not be by alias either.
|
# The GROUP BY should not be by alias either.
|
||||||
self.assertEqual(ctx[0]['sql'].lower().count('latest_book_pubdate'), 1)
|
self.assertEqual(ctx[0]['sql'].lower().count('latest_book_pubdate'), 1)
|
||||||
|
|
||||||
|
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')
|
@skipUnlessDBFeature('supports_subqueries_in_group_by')
|
||||||
def test_group_by_subquery_annotation(self):
|
def test_group_by_subquery_annotation(self):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue