Browse Source

Fixed #24752 -- query crash when reusing Case expressions

Case expressions weren't copied deep enough (self.cases list was
reused resulting in an error).
Anssi Kääriäinen 10 years ago
parent
commit
7b05d2fdae
3 changed files with 20 additions and 0 deletions
  1. 5 0
      django/db/models/expressions.py
  2. 3 0
      docs/releases/1.8.2.txt
  3. 12 0
      tests/expressions_case/tests.py

+ 5 - 0
django/db/models/expressions.py

@@ -780,6 +780,11 @@ class Case(Expression):
         c.default = c.default.resolve_expression(query, allow_joins, reuse, summarize, for_save)
         return c
 
+    def copy(self):
+        c = super(Case, self).copy()
+        c.cases = c.cases[:]
+        return c
+
     def as_sql(self, compiler, connection, template=None, extra=None):
         connection.ops.check_expression_support(self)
         if not self.cases:

+ 3 - 0
docs/releases/1.8.2.txt

@@ -10,3 +10,6 @@ Bugfixes
 ========
 
 * Fixed check for template engine alias uniqueness (:ticket:`24685`).
+
+* Fixed crash when reusing the same ``Case`` instance in a query
+  (:ticket:`24752`).

+ 12 - 0
tests/expressions_case/tests.py

@@ -274,6 +274,18 @@ class CaseExpressionTests(TestCase):
             transform=attrgetter('integer', 'integer2')
         )
 
+    def test_case_reuse(self):
+        SOME_CASE = Case(
+            When(pk=0, then=Value('0')),
+            default=Value('1'),
+            output_field=models.CharField(),
+        )
+        self.assertQuerysetEqual(
+            CaseTestModel.objects.annotate(somecase=SOME_CASE).order_by('pk'),
+            CaseTestModel.objects.annotate(somecase=SOME_CASE).order_by('pk').values_list('pk', 'somecase'),
+            lambda x: (x.pk, x.somecase)
+        )
+
     def test_aggregate(self):
         self.assertEqual(
             CaseTestModel.objects.aggregate(