summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2015-05-05 14:11:58 +0300
committerTim Graham <timograham@gmail.com>2015-05-05 11:38:48 -0400
commit5b5858575c96719d928b0df03e6aff272f849e44 (patch)
tree2a2835d4d153c9acf70afd2d61657f83aa23dc9a
parenteb00b427fc9d12c8ba53ce3875d7e481cd825e38 (diff)
[1.8.x] Fixed #24752 -- query crash when reusing Case expressions
Case expressions weren't copied deep enough (self.cases list was reused resulting in an error). Backport of 7b05d2fdaed582662d8f79130932f600f4f966a0 from master
-rw-r--r--django/db/models/expressions.py5
-rw-r--r--docs/releases/1.8.2.txt3
-rw-r--r--tests/expressions_case/tests.py12
3 files changed, 20 insertions, 0 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index c6959f87b8..43061933e6 100644
--- a/django/db/models/expressions.py
+++ b/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:
diff --git a/docs/releases/1.8.2.txt b/docs/releases/1.8.2.txt
index c66539c9b7..a0c18e78bb 100644
--- a/docs/releases/1.8.2.txt
+++ b/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`).
diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py
index 1ebaf6d220..5eacd1cf9f 100644
--- a/tests/expressions_case/tests.py
+++ b/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(