Browse Source

Fixed #29108 -- Fixed crash in aggregation of distinct+ordered+sliced querysets.

Regression in 4acae21846f6212aa992763e587c7e201828d7b0.
Thanks Stephen Brooks for the report.
Simon Charette 7 years ago
parent
commit
d61fe24601
3 changed files with 9 additions and 3 deletions
  1. 4 2
      django/db/models/sql/compiler.py
  2. 2 1
      docs/releases/2.0.3.txt
  3. 3 0
      tests/queries/tests.py

+ 4 - 2
django/db/models/sql/compiler.py

@@ -547,7 +547,9 @@ class SQLCompiler:
                 # to exclude extraneous selects.
                 sub_selects = []
                 sub_params = []
-                for select, _, alias in self.select:
+                for index, (select, _, alias) in enumerate(self.select, start=1):
+                    if not alias and with_col_aliases:
+                        alias = 'col%d' % index
                     if alias:
                         sub_selects.append("%s.%s" % (
                             self.connection.ops.quote_name('subquery'),
@@ -561,7 +563,7 @@ class SQLCompiler:
                 return 'SELECT %s FROM (%s) subquery' % (
                     ', '.join(sub_selects),
                     ' '.join(result),
-                ), sub_params + params
+                ), tuple(sub_params + params)
 
             return ' '.join(result), tuple(params)
         finally:

+ 2 - 1
docs/releases/2.0.3.txt

@@ -9,4 +9,5 @@ Django 2.0.3 fixes several bugs in 2.0.2.
 Bugfixes
 ========
 
-* ...
+* Fixed a regression that caused sliced ``QuerySet.distinct().order_by()``
+  followed by ``count()`` to crash (:ticket:`29108`).

+ 3 - 0
tests/queries/tests.py

@@ -1918,6 +1918,9 @@ class Queries6Tests(TestCase):
         qs = Tag.objects.exclude(category=None).exclude(category__name='foo')
         self.assertEqual(str(qs.query).count(' INNER JOIN '), 1)
 
+    def test_distinct_ordered_sliced_subquery_aggregation(self):
+        self.assertEqual(Tag.objects.distinct().order_by('category__name')[:3].count(), 3)
+
 
 class RawQueriesTests(TestCase):
     def setUp(self):