Browse Source

Fixed #34372 -- Fixed queryset crash on order by aggregation using OrderBy.

Regression in 278881e37619278789942513916acafaa88d26f3 caused by a lack
of expression copying when an OrderBy expression is explicitly provided.

Thanks Jannis Vajen for the report and regression test.
Simon Charette 2 years ago
parent
commit
b15f162f25
2 changed files with 8 additions and 0 deletions
  1. 2 0
      django/db/models/sql/compiler.py
  2. 6 0
      tests/ordering/tests.py

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

@@ -358,11 +358,13 @@ class SQLCompiler:
                     if (
                         field.nulls_first is None and field.nulls_last is None
                     ) or self.connection.features.supports_order_by_nulls_modifier:
+                        field = field.copy()
                         field.expression = select_ref
                     # Alias collisions are not possible when dealing with
                     # combined queries so fallback to it if emulation of NULLS
                     # handling is required.
                     elif self.query.combinator:
+                        field = field.copy()
                         field.expression = Ref(select_ref.refs, select_ref.source)
                 yield field, select_ref is not None
                 continue

+ 6 - 0
tests/ordering/tests.py

@@ -638,3 +638,9 @@ class OrderingTests(TestCase):
             .first(),
             self.a1,
         )
+
+    def test_order_by_expr_query_reuse(self):
+        qs = Author.objects.annotate(num=Count("article")).order_by(
+            F("num").desc(), "pk"
+        )
+        self.assertCountEqual(qs, qs.iterator())