mirror of
https://github.com/django/django.git
synced 2025-06-04 02:59:13 +00:00
Fixed #35064 -- Fixed Window(order_by) crash with DecimalFields on SQLite.
This avoids cast of Window(order_by) for DecimalFields on SQLite. This was achieved by piggy-backing ExpressionList which already implements a specialized as_sqlite() method to override the inherited behaviour of Func through SQLiteNumericMixin. Refs #31723. Thanks Quoates for the report.
This commit is contained in:
parent
90d365d869
commit
e16d0c176e
@ -1267,12 +1267,12 @@ class ExpressionList(Func):
|
|||||||
|
|
||||||
def get_group_by_cols(self):
|
def get_group_by_cols(self):
|
||||||
group_by_cols = []
|
group_by_cols = []
|
||||||
for partition in self.get_source_expressions():
|
for expr in self.get_source_expressions():
|
||||||
group_by_cols.extend(partition.get_group_by_cols())
|
group_by_cols.extend(expr.get_group_by_cols())
|
||||||
return group_by_cols
|
return group_by_cols
|
||||||
|
|
||||||
|
|
||||||
class OrderByList(Func):
|
class OrderByList(ExpressionList):
|
||||||
allowed_default = False
|
allowed_default = False
|
||||||
template = "ORDER BY %(expressions)s"
|
template = "ORDER BY %(expressions)s"
|
||||||
|
|
||||||
@ -1287,17 +1287,6 @@ class OrderByList(Func):
|
|||||||
)
|
)
|
||||||
super().__init__(*expressions, **extra)
|
super().__init__(*expressions, **extra)
|
||||||
|
|
||||||
def as_sql(self, *args, **kwargs):
|
|
||||||
if not self.source_expressions:
|
|
||||||
return "", ()
|
|
||||||
return super().as_sql(*args, **kwargs)
|
|
||||||
|
|
||||||
def get_group_by_cols(self):
|
|
||||||
group_by_cols = []
|
|
||||||
for order_by in self.get_source_expressions():
|
|
||||||
group_by_cols.extend(order_by.get_group_by_cols())
|
|
||||||
return group_by_cols
|
|
||||||
|
|
||||||
|
|
||||||
@deconstructible(path="django.db.models.ExpressionWrapper")
|
@deconstructible(path="django.db.models.ExpressionWrapper")
|
||||||
class ExpressionWrapper(SQLiteNumericMixin, Expression):
|
class ExpressionWrapper(SQLiteNumericMixin, Expression):
|
||||||
|
@ -354,6 +354,29 @@ class WindowFunctionTests(TestCase):
|
|||||||
transform=lambda row: (row.name, row.bonus, row.department, row.lag),
|
transform=lambda row: (row.name, row.bonus, row.department, row.lag),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_order_by_decimalfield(self):
|
||||||
|
qs = Employee.objects.annotate(
|
||||||
|
rank=Window(expression=Rank(), order_by="bonus")
|
||||||
|
).order_by("-bonus", "id")
|
||||||
|
self.assertQuerySetEqual(
|
||||||
|
qs,
|
||||||
|
[
|
||||||
|
("Miller", 250.0, 12),
|
||||||
|
("Johnson", 200.0, 11),
|
||||||
|
("Wilkinson", 150.0, 10),
|
||||||
|
("Smith", 137.5, 9),
|
||||||
|
("Brown", 132.5, 8),
|
||||||
|
("Adams", 125.0, 7),
|
||||||
|
("Jones", 112.5, 5),
|
||||||
|
("Jenson", 112.5, 5),
|
||||||
|
("Johnson", 100.0, 4),
|
||||||
|
("Smith", 95.0, 3),
|
||||||
|
("Williams", 92.5, 2),
|
||||||
|
("Moore", 85.0, 1),
|
||||||
|
],
|
||||||
|
transform=lambda row: (row.name, float(row.bonus), row.rank),
|
||||||
|
)
|
||||||
|
|
||||||
def test_first_value(self):
|
def test_first_value(self):
|
||||||
qs = Employee.objects.annotate(
|
qs = Employee.objects.annotate(
|
||||||
first_value=Window(
|
first_value=Window(
|
||||||
@ -1934,8 +1957,7 @@ class NonQueryWindowTests(SimpleTestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
repr(Window(expression=Avg("salary"), order_by=F("department").asc())),
|
repr(Window(expression=Avg("salary"), order_by=F("department").asc())),
|
||||||
"<Window: Avg(F(salary)) OVER (OrderByList(OrderBy(F(department), "
|
"<Window: Avg(F(salary)) OVER (OrderBy(F(department), descending=False))>",
|
||||||
"descending=False)))>",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_window_frame_repr(self):
|
def test_window_frame_repr(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user