[4.1.x] Fixed #33796 -- Fixed ordered combined queryset crash when used in subquery on PostgreSQL and MySQL.
Thanks Shai Berger for the report. Regression in30a0144134
. Backport of44ffd8d06f
from main
This commit is contained in:
parent
2026314b20
commit
d38cd2677e
|
@ -171,6 +171,25 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
},
|
||||
}
|
||||
)
|
||||
if (
|
||||
self.connection.mysql_is_mariadb and self.connection.mysql_version < (10, 4)
|
||||
) or (
|
||||
not self.connection.mysql_is_mariadb
|
||||
and self.connection.mysql_version < (8,)
|
||||
):
|
||||
skips.update(
|
||||
{
|
||||
"Parenthesized combined queries are not supported on MySQL < 8 and "
|
||||
"MariaDB < 10.4": {
|
||||
"queries.test_qs_combinators.QuerySetSetOperationTests."
|
||||
"test_union_in_subquery",
|
||||
"queries.test_qs_combinators.QuerySetSetOperationTests."
|
||||
"test_union_in_subquery_related_outerref",
|
||||
"queries.test_qs_combinators.QuerySetSetOperationTests."
|
||||
"test_union_in_with_ordering",
|
||||
}
|
||||
}
|
||||
)
|
||||
if not self.supports_explain_analyze:
|
||||
skips.update(
|
||||
{
|
||||
|
|
|
@ -109,6 +109,11 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
"migrations.test_operations.OperationTests."
|
||||
"test_alter_field_pk_fk_db_collation",
|
||||
},
|
||||
"Oracle raises an error when a subquery contains unnecessary ORDER BY "
|
||||
"clause (#32786).": {
|
||||
"queries.test_qs_combinators.QuerySetSetOperationTests."
|
||||
"test_union_in_with_ordering",
|
||||
},
|
||||
}
|
||||
django_test_expected_failures = {
|
||||
# A bug in Django/cx_Oracle with respect to string handling (#23843).
|
||||
|
|
|
@ -548,6 +548,11 @@ class SQLCompiler:
|
|||
or not features.supports_slicing_ordering_in_compound
|
||||
):
|
||||
part_sql = "({})".format(part_sql)
|
||||
elif (
|
||||
self.query.subquery
|
||||
and features.supports_slicing_ordering_in_compound
|
||||
):
|
||||
part_sql = "({})".format(part_sql)
|
||||
parts += ((part_sql, part_args),)
|
||||
except EmptyResultSet:
|
||||
# Omit the empty queryset with UNION and with DIFFERENCE if the
|
||||
|
|
|
@ -321,6 +321,28 @@ class QuerySetSetOperationTests(TestCase):
|
|||
# Combined queries don't mutate.
|
||||
self.assertCountEqual(qs, ["a1", "a2"])
|
||||
|
||||
@skipUnlessDBFeature("supports_slicing_ordering_in_compound")
|
||||
def test_union_in_with_ordering(self):
|
||||
qs1 = Number.objects.filter(num__gt=7).order_by("num")
|
||||
qs2 = Number.objects.filter(num__lt=2).order_by("num")
|
||||
self.assertNumbersEqual(
|
||||
Number.objects.exclude(id__in=qs1.union(qs2).values("id")),
|
||||
[2, 3, 4, 5, 6, 7],
|
||||
ordered=False,
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature(
|
||||
"supports_slicing_ordering_in_compound", "allow_sliced_subqueries_with_in"
|
||||
)
|
||||
def test_union_in_with_ordering_and_slice(self):
|
||||
qs1 = Number.objects.filter(num__gt=7).order_by("num")[:1]
|
||||
qs2 = Number.objects.filter(num__lt=2).order_by("-num")[:1]
|
||||
self.assertNumbersEqual(
|
||||
Number.objects.exclude(id__in=qs1.union(qs2).values("id")),
|
||||
[0, 2, 3, 4, 5, 6, 7, 9],
|
||||
ordered=False,
|
||||
)
|
||||
|
||||
def test_count_union(self):
|
||||
qs1 = Number.objects.filter(num__lte=1).values("num")
|
||||
qs2 = Number.objects.filter(num__gte=2, num__lte=3).values("num")
|
||||
|
|
Loading…
Reference in New Issue