From df236b0bcbbf1f54dfe6acc7761cd81b76ebf2cc Mon Sep 17 00:00:00 2001 From: Simon Charette Date: Fri, 9 Aug 2024 08:43:20 -0400 Subject: [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. --- django/db/backends/oracle/features.py | 1 + django/db/models/expressions.py | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'django') diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py index a83560b892..72c6180f50 100644 --- a/django/db/backends/oracle/features.py +++ b/django/db/backends/oracle/features.py @@ -116,6 +116,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): "Oracle requires ORDER BY in row_number, ANSI:SQL doesn't.": { "expressions_window.tests.WindowFunctionTests." "test_row_number_no_ordering", + "prefetch_related.tests.PrefetchLimitTests.test_empty_order", }, "Oracle doesn't support changing collations on indexed columns (#33671).": { "migrations.test_operations.OperationTests." diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 0f5e68b0d4..c24c585658 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -1377,16 +1377,14 @@ class ExpressionList(Func): template = "%(expressions)s" - def __init__(self, *expressions, **extra): - if not expressions: - raise ValueError( - "%s requires at least one expression." % self.__class__.__name__ - ) - super().__init__(*expressions, **extra) - def __str__(self): return self.arg_joiner.join(str(arg) for arg in self.source_expressions) + def as_sql(self, *args, **kwargs): + if not self.source_expressions: + return "", () + return super().as_sql(*args, **kwargs) + def as_sqlite(self, compiler, connection, **extra_context): # Casting to numeric is unnecessary. return self.as_sql(compiler, connection, **extra_context) -- cgit v1.3