diff options
| author | Simon Charette <charette.s@gmail.com> | 2024-08-09 08:43:20 -0400 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2024-08-13 11:28:03 +0200 |
| commit | df236b0bcbbf1f54dfe6acc7761cd81b76ebf2cc (patch) | |
| tree | cef9184d9269ffcbe22d4f9c1afe81b186b91b41 /tests | |
| parent | dbca05698a14d6c771346d3fe6b72159cb32ce14 (diff) | |
[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 e16d0c176e9b89628cdec5e58c418378c4a2436a 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 602fe961e6834d665f2359087a1272e9f9806b71 from main.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/expressions/tests.py | 5 | ||||
| -rw-r--r-- | tests/expressions_window/tests.py | 14 | ||||
| -rw-r--r-- | tests/prefetch_related/tests.py | 15 |
3 files changed, 29 insertions, 5 deletions
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index 64103f14db..5bc98eed4d 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -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) diff --git a/tests/expressions_window/tests.py b/tests/expressions_window/tests.py index fd674e319b..fd9858ccf9 100644 --- a/tests/expressions_window/tests.py +++ b/tests/expressions_window/tests.py @@ -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( diff --git a/tests/prefetch_related/tests.py b/tests/prefetch_related/tests.py index a418beb5a5..9b1dfdd0d1 100644 --- a/tests/prefetch_related/tests.py +++ b/tests/prefetch_related/tests.py @@ -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): |
