mirror of
https://github.com/django/django.git
synced 2024-12-27 19:46:22 +00:00
[4.2.x] Fixed #34267 -- Fixed sliced QuerySet.union() crash.
Regression in3d734c09ff
. Thanks Raphaël Stefanini for the report. Backport ofcc8aa6bf9c
from main
This commit is contained in:
parent
3b6f307344
commit
84927e110e
@ -532,15 +532,12 @@ class SQLCompiler:
|
|||||||
"ORDER BY not allowed in subqueries of compound statements."
|
"ORDER BY not allowed in subqueries of compound statements."
|
||||||
)
|
)
|
||||||
elif self.query.is_sliced and combinator == "union":
|
elif self.query.is_sliced and combinator == "union":
|
||||||
limit = (self.query.low_mark, self.query.high_mark)
|
|
||||||
for compiler in compilers:
|
for compiler in compilers:
|
||||||
# A sliced union cannot have its parts elided as some of them
|
# 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
|
# might be sliced as well and in the event where only a single
|
||||||
# part produces a non-empty resultset it might be impossible to
|
# part produces a non-empty resultset it might be impossible to
|
||||||
# generate valid SQL.
|
# generate valid SQL.
|
||||||
compiler.elide_empty = False
|
compiler.elide_empty = False
|
||||||
if not compiler.query.is_sliced:
|
|
||||||
compiler.query.set_limits(*limit)
|
|
||||||
parts = ()
|
parts = ()
|
||||||
for compiler in compilers:
|
for compiler in compilers:
|
||||||
try:
|
try:
|
||||||
|
@ -87,6 +87,15 @@ class QuerySetSetOperationTests(TestCase):
|
|||||||
qs3 = qs1.union(qs2)
|
qs3 = qs1.union(qs2)
|
||||||
self.assertNumbersEqual(qs3.order_by("num")[2:3], [2])
|
self.assertNumbersEqual(qs3.order_by("num")[2:3], [2])
|
||||||
|
|
||||||
|
def test_union_slice_index(self):
|
||||||
|
Celebrity.objects.create(name="Famous")
|
||||||
|
c1 = Celebrity.objects.create(name="Very famous")
|
||||||
|
|
||||||
|
qs1 = Celebrity.objects.filter(name="nonexistent")
|
||||||
|
qs2 = Celebrity.objects.all()
|
||||||
|
combined_qs = qs1.union(qs2).order_by("name")
|
||||||
|
self.assertEqual(combined_qs[1], c1)
|
||||||
|
|
||||||
def test_union_order_with_null_first_last(self):
|
def test_union_order_with_null_first_last(self):
|
||||||
Number.objects.filter(other_num=5).update(other_num=None)
|
Number.objects.filter(other_num=5).update(other_num=None)
|
||||||
qs1 = Number.objects.filter(num__lte=1)
|
qs1 = Number.objects.filter(num__lte=1)
|
||||||
@ -319,10 +328,10 @@ class QuerySetSetOperationTests(TestCase):
|
|||||||
e1 = ExtraInfo.objects.create(value=7, info="e1")
|
e1 = ExtraInfo.objects.create(value=7, info="e1")
|
||||||
a1 = Author.objects.create(name="a1", num=1, extra=e1)
|
a1 = Author.objects.create(name="a1", num=1, extra=e1)
|
||||||
Author.objects.create(name="a2", num=3, extra=e1)
|
Author.objects.create(name="a2", num=3, extra=e1)
|
||||||
base_qs = Author.objects.select_related("extra")
|
base_qs = Author.objects.select_related("extra").order_by()
|
||||||
qs1 = base_qs.filter(name="a1")
|
qs1 = base_qs.filter(name="a1")
|
||||||
qs2 = base_qs.filter(name="a2")
|
qs2 = base_qs.filter(name="a2")
|
||||||
self.assertEqual(qs1.union(qs2).first(), a1)
|
self.assertEqual(qs1.union(qs2).order_by("name").first(), a1)
|
||||||
|
|
||||||
def test_union_with_first(self):
|
def test_union_with_first(self):
|
||||||
e1 = ExtraInfo.objects.create(value=7, info="e1")
|
e1 = ExtraInfo.objects.create(value=7, info="e1")
|
||||||
@ -455,8 +464,7 @@ class QuerySetSetOperationTests(TestCase):
|
|||||||
captured_sql,
|
captured_sql,
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
captured_sql.count(connection.ops.limit_offset_sql(None, 1)),
|
captured_sql.count(connection.ops.limit_offset_sql(None, 1)), 1
|
||||||
3 if connection.features.supports_slicing_ordering_in_compound else 1,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_exists_union_empty_result(self):
|
def test_exists_union_empty_result(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user