1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

[5.1.x] Fixed #35665 -- Fixed a crash when passing an empty order_by to Window.

This also caused un-ordered sliced prefetches to crash as they rely on Window.

Regression in e16d0c176e that made OrderByList
piggy-back ExpressionList without porting the empty handling that the latter
provided.

Supporting explicit empty ordering on Window functions and slicing is arguably
a foot-gun design due to how backends will return undeterministic results but
this is a problem that requires a larger discussion.

Refs #35064.

Thanks Andrew Backer for the report and Mariusz for the review.

Backport of 602fe961e6 from main.
This commit is contained in:
Simon Charette
2024-08-09 08:43:20 -04:00
committed by Sarah Boyce
parent dbca05698a
commit df236b0bcb
6 changed files with 38 additions and 13 deletions

View File

@@ -2311,11 +2311,6 @@ class ValueTests(TestCase):
self.assertNotEqual(value, other_value)
self.assertNotEqual(value, no_output_field)
def test_raise_empty_expressionlist(self):
msg = "ExpressionList requires at least one expression"
with self.assertRaisesMessage(ValueError, msg):
ExpressionList()
def test_compile_unresolved(self):
# This test might need to be revisited later on if #25425 is enforced.
compiler = Time.objects.all().query.get_compiler(connection=connection)

View File

@@ -928,6 +928,20 @@ class WindowFunctionTests(TestCase):
),
)
def test_empty_ordering(self):
"""
Explicit empty ordering makes little sense but it is something that
was historically allowed.
"""
qs = Employee.objects.annotate(
sum=Window(
expression=Sum("salary"),
partition_by="department",
order_by=[],
)
).order_by("department", "sum")
self.assertEqual(len(qs), 12)
def test_related_ordering_with_count(self):
qs = Employee.objects.annotate(
department_sum=Window(

View File

@@ -1999,6 +1999,21 @@ class PrefetchLimitTests(TestDataMixin, TestCase):
with self.assertRaisesMessage(NotSupportedError, msg):
list(Book.objects.prefetch_related(Prefetch("authors", authors[1:])))
@skipUnlessDBFeature("supports_over_clause")
def test_empty_order(self):
authors = Author.objects.order_by()
with self.assertNumQueries(3):
books = list(
Book.objects.prefetch_related(
Prefetch("authors", authors),
Prefetch("authors", authors[:1], to_attr="authors_sliced"),
)
)
for book in books:
with self.subTest(book=book):
self.assertEqual(len(book.authors_sliced), 1)
self.assertIn(book.authors_sliced[0], list(book.authors.all()))
class DeprecationTests(TestCase):
def test_get_current_queryset_warning(self):