summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wobrock <david.wobrock@gmail.com>2022-08-07 17:25:43 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-08-09 07:55:31 +0200
commit036bb2b74afb50a71e7a945e8dd83499b603ac3a (patch)
treea77a599596972b8002f3ca21b400be8002c6162d
parent63884829acd207404f2a5c3cc1d6b4cd0a822b70 (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.py5
-rw-r--r--tests/expressions_case/tests.py10
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(