Kaydet (Commit) 5b585857 authored tarafından Anssi Kääriäinen's avatar Anssi Kääriäinen Kaydeden (comit) Tim Graham

[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 7b05d2fd from master
üst eb00b427
...@@ -780,6 +780,11 @@ class Case(Expression): ...@@ -780,6 +780,11 @@ class Case(Expression):
c.default = c.default.resolve_expression(query, allow_joins, reuse, summarize, for_save) c.default = c.default.resolve_expression(query, allow_joins, reuse, summarize, for_save)
return c 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): def as_sql(self, compiler, connection, template=None, extra=None):
connection.ops.check_expression_support(self) connection.ops.check_expression_support(self)
if not self.cases: if not self.cases:
......
...@@ -10,3 +10,6 @@ Bugfixes ...@@ -10,3 +10,6 @@ Bugfixes
======== ========
* Fixed check for template engine alias uniqueness (:ticket:`24685`). * Fixed check for template engine alias uniqueness (:ticket:`24685`).
* Fixed crash when reusing the same ``Case`` instance in a query
(:ticket:`24752`).
...@@ -274,6 +274,18 @@ class CaseExpressionTests(TestCase): ...@@ -274,6 +274,18 @@ class CaseExpressionTests(TestCase):
transform=attrgetter('integer', 'integer2') 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): def test_aggregate(self):
self.assertEqual( self.assertEqual(
CaseTestModel.objects.aggregate( CaseTestModel.objects.aggregate(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment