From 720de4d0441fcfdb543051389c70efbe66ed962a Mon Sep 17 00:00:00 2001
From: Simon Charette <charette.s@gmail.com>
Date: Sat, 21 Dec 2019 23:22:49 -0500
Subject: [PATCH] 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 fb3f034f1c63160c0ff13c609acd01c18be12f80.
---
 django/db/models/sql/query.py |  8 ++++++--
 docs/releases/3.0.2.txt       |  3 +++
 tests/aggregation/tests.py    | 10 ++++++++++
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index ac4822e18a..fc423b6acf 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -526,7 +526,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)
@@ -1916,7 +1918,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.
 
@@ -1938,6 +1940,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)
diff --git a/docs/releases/3.0.2.txt b/docs/releases/3.0.2.txt
index 53b066838a..ccc82b18ae 100644
--- a/docs/releases/3.0.2.txt
+++ b/docs/releases/3.0.2.txt
@@ -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`).
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index ecbe81c151..dd30f57bed 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -1141,6 +1141,16 @@ class AggregateTestCase(TestCase):
         # The GROUP BY should not be by alias either.
         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')
     def test_group_by_subquery_annotation(self):
         """