diff options
| author | David Wobrock <david.wobrock@gmail.com> | 2022-08-07 17:25:43 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-08-09 07:55:31 +0200 |
| commit | 036bb2b74afb50a71e7a945e8dd83499b603ac3a (patch) | |
| tree | a77a599596972b8002f3ca21b400be8002c6162d | |
| parent | 63884829acd207404f2a5c3cc1d6b4cd0a822b70 (diff) | |
Fixed #33895 -- Fixed Case() crash with filters that match everything in When().
Thanks shukryzablah for the report.
| -rw-r--r-- | django/db/models/expressions.py | 5 | ||||
| -rw-r--r-- | tests/expressions_case/tests.py | 10 |
2 files changed, 15 insertions, 0 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 822968ef56..ba836024e5 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -1299,6 +1299,11 @@ class When(Expression): template_params = extra_context sql_params = [] condition_sql, condition_params = compiler.compile(self.condition) + # Filters that match everything are handled as empty strings in the + # WHERE clause, but in a CASE WHEN expression they must use a predicate + # that's always True. + if condition_sql == "": + condition_sql, condition_params = compiler.compile(Value(True)) template_params["condition"] = condition_sql sql_params.extend(condition_params) result_sql, result_params = compiler.compile(self.result) diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py index 9bad0b8747..221806c933 100644 --- a/tests/expressions_case/tests.py +++ b/tests/expressions_case/tests.py @@ -415,6 +415,16 @@ class CaseExpressionTests(TestCase): self.assertEqual(len(objects), CaseTestModel.objects.count()) self.assertTrue(all(obj.selected == "not selected" for obj in objects)) + def test_annotate_with_full_when(self): + objects = CaseTestModel.objects.annotate( + selected=Case( + When(~Q(pk__in=[]), then=Value("selected")), + default=Value("not selected"), + ) + ) + self.assertEqual(len(objects), CaseTestModel.objects.count()) + self.assertTrue(all(obj.selected == "selected" for obj in objects)) + def test_combined_expression(self): self.assertQuerysetEqual( CaseTestModel.objects.annotate( |
