diff options
| author | Johannes Dollinger <emulbreh@googlemail.com> | 2016-08-05 09:09:01 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-08-08 10:43:33 -0400 |
| commit | c002a0d39f18694f5e8a07d86684fc793b063056 (patch) | |
| tree | 8a6395bed9010d501783cdf1d65cf7b59f7079fc | |
| parent | 1410616e0e2637e4b0821620202bf62edc903b88 (diff) | |
Fixed #26517 -- Fixed ExpressionWrapper with empty queryset.
| -rw-r--r-- | django/db/models/sql/compiler.py | 7 | ||||
| -rw-r--r-- | tests/annotations/tests.py | 15 |
2 files changed, 20 insertions, 2 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 9447f06f85..0b7f9e20cb 100644 --- a/django/db/models/sql/compiler.py +++ b/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): diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py index d57f9ed0d7..28627e84ae 100644 --- a/tests/annotations/tests.py +++ b/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()), |
