summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/sql/compiler.py6
-rw-r--r--tests/queries/test_qs_combinators.py26
2 files changed, 31 insertions, 1 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 8d6b667828..318e6b8707 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -531,7 +531,6 @@ class SQLCompiler:
compilers = [
query.get_compiler(self.using, self.connection, self.elide_empty)
for query in self.query.combined_queries
- if not query.is_empty()
]
if not features.supports_slicing_ordering_in_compound:
for compiler in compilers:
@@ -546,6 +545,11 @@ class SQLCompiler:
elif self.query.is_sliced and combinator == "union":
limit = (self.query.low_mark, self.query.high_mark)
for compiler in compilers:
+ # A sliced union cannot have its parts elided as some of them
+ # might be sliced as well and in the event where only a single
+ # part produces a non-empty resultset it might be impossible to
+ # generate valid SQL.
+ compiler.elide_empty = False
if not compiler.query.is_sliced:
compiler.query.set_limits(*limit)
parts = ()
diff --git a/tests/queries/test_qs_combinators.py b/tests/queries/test_qs_combinators.py
index 97b3f97b68..865e172816 100644
--- a/tests/queries/test_qs_combinators.py
+++ b/tests/queries/test_qs_combinators.py
@@ -61,6 +61,32 @@ class QuerySetSetOperationTests(TestCase):
self.assertSequenceEqual(qs3.none(), [])
self.assertNumbersEqual(qs3, [0, 1, 8, 9], ordered=False)
+ def test_union_none_slice(self):
+ qs1 = Number.objects.filter(num__lte=0)
+ qs2 = Number.objects.none()
+ qs3 = qs1.union(qs2)
+ self.assertNumbersEqual(qs3[:1], [0])
+
+ def test_union_empty_filter_slice(self):
+ qs1 = Number.objects.filter(num__lte=0)
+ qs2 = Number.objects.filter(pk__in=[])
+ qs3 = qs1.union(qs2)
+ self.assertNumbersEqual(qs3[:1], [0])
+
+ @skipUnlessDBFeature("supports_slicing_ordering_in_compound")
+ def test_union_slice_compound_empty(self):
+ qs1 = Number.objects.filter(num__lte=0)[:1]
+ qs2 = Number.objects.none()
+ qs3 = qs1.union(qs2)
+ self.assertNumbersEqual(qs3[:1], [0])
+
+ @skipUnlessDBFeature("supports_slicing_ordering_in_compound")
+ def test_union_combined_slice_compound_empty(self):
+ qs1 = Number.objects.filter(num__lte=2)[:3]
+ qs2 = Number.objects.none()
+ qs3 = qs1.union(qs2)
+ self.assertNumbersEqual(qs3.order_by("num")[2:3], [2])
+
def test_union_order_with_null_first_last(self):
Number.objects.filter(other_num=5).update(other_num=None)
qs1 = Number.objects.filter(num__lte=1)