From 233b46f93171d4a7cc279bc3f35e5a99e9a167b8 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Sat, 15 Aug 2015 19:05:42 -0400 Subject: [PATCH] Fixed #19263 -- Fixed crash when filtering using __in and an empty QuerySet. Thanks Marcin Biernat for the initial patch and tests. --- django/db/models/sql/compiler.py | 5 ++++- tests/queries/tests.py | 9 +++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 8b841f6d5e..3f50e951a3 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -484,7 +484,10 @@ class SQLCompiler(object): if obj.low_mark == 0 and obj.high_mark is None and not self.query.distinct_fields: # If there is no slicing in use, then we can safely drop all ordering obj.clear_ordering(True) - return obj.get_compiler(connection=self.connection).as_sql(subquery=True) + nested_sql = obj.get_compiler(connection=self.connection).as_sql(subquery=True) + if nested_sql == ('', ()): + raise EmptyResultSet + return nested_sql def get_default_columns(self, start_alias=None, opts=None, from_parent=None): """ diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 831990f099..c9919dce44 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -2362,6 +2362,9 @@ class WeirdQuerysetSlicingTests(BaseQuerysetTest): Article.objects.create(name='three', created=datetime.datetime.now()) Article.objects.create(name='four', created=datetime.datetime.now()) + food = Food.objects.create(name='spam') + Eaten.objects.create(meal='spam with eggs', food=food) + def test_tickets_7698_10202(self): # People like to slice with '0' as the high-water mark. self.assertQuerysetEqual(Article.objects.all()[0:0], []) @@ -2377,6 +2380,12 @@ class WeirdQuerysetSlicingTests(BaseQuerysetTest): # ticket #12192 self.assertNumQueries(0, lambda: list(Number.objects.all()[1:1])) + def test_empty_sliced_subquery(self): + self.assertEqual(Eaten.objects.filter(food__in=Food.objects.all()[0:0]).count(), 0) + + def test_empty_sliced_subquery_exclude(self): + self.assertEqual(Eaten.objects.exclude(food__in=Food.objects.all()[0:0]).count(), 1) + class EscapingTests(TestCase): def test_ticket_7302(self):