Forráskód Böngészése

Fixed #26517 -- Fixed ExpressionWrapper with empty queryset.

Johannes Dollinger 8 éve
szülő
commit
c002a0d39f
2 módosított fájl, 20 hozzáadás és 2 törlés
  1. 6 1
      django/db/models/sql/compiler.py
  2. 14 1
      tests/annotations/tests.py

+ 6 - 1
django/db/models/sql/compiler.py

@@ -223,7 +223,12 @@ class SQLCompiler(object):
 
         ret = []
         for col, alias in select:
-            ret.append((col, self.compile(col, select_format=True), alias))
+            try:
+                sql, params = self.compile(col, select_format=True)
+            except EmptyResultSet:
+                # Select a predicate that's always False.
+                sql, params = '0', ()
+            ret.append((col, (sql, params), alias))
         return ret, klass_info, annotations
 
     def get_order_by(self):

+ 14 - 1
tests/annotations/tests.py

@@ -6,7 +6,7 @@ from decimal import Decimal
 from django.core.exceptions import FieldDoesNotExist, FieldError
 from django.db.models import (
     BooleanField, CharField, Count, DateTimeField, ExpressionWrapper, F, Func,
-    IntegerField, Sum, Value,
+    IntegerField, Q, Sum, Value,
 )
 from django.db.models.functions import Lower
 from django.test import TestCase, skipUnlessDBFeature
@@ -148,6 +148,19 @@ class NonAggregateAnnotationTestCase(TestCase):
         combined = int(test.pages + test.rating)
         self.assertEqual(b.combined, combined)
 
+    def test_empty_expression_annotation(self):
+        books = Book.objects.annotate(
+            selected=ExpressionWrapper(Q(pk__in=[]), output_field=BooleanField())
+        )
+        self.assertEqual(len(books), Book.objects.count())
+        self.assertTrue(all(not book.selected for book in books))
+
+        books = Book.objects.annotate(
+            selected=ExpressionWrapper(Q(pk__in=Book.objects.none()), output_field=BooleanField())
+        )
+        self.assertEqual(len(books), Book.objects.count())
+        self.assertTrue(all(not book.selected for book in books))
+
     def test_annotate_with_aggregation(self):
         books = Book.objects.annotate(
             is_book=Value(1, output_field=IntegerField()),