Fixed #33898 -- Fixed Window() expression crash with ArrayAgg().

Thanks Kia for the report.

Regression in e06dc4571e.
This commit is contained in:
Mariusz Felisiak 2022-08-06 17:59:31 +02:00 committed by GitHub
parent 00370342ca
commit fd93db97c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 6 deletions

View File

@ -1669,7 +1669,7 @@ class Window(SQLiteNumericMixin, Expression):
if not connection.features.supports_over_clause: if not connection.features.supports_over_clause:
raise NotSupportedError("This backend does not support window expressions.") raise NotSupportedError("This backend does not support window expressions.")
expr_sql, params = compiler.compile(self.source_expression) expr_sql, params = compiler.compile(self.source_expression)
window_sql, window_params = [], [] window_sql, window_params = [], ()
if self.partition_by is not None: if self.partition_by is not None:
sql_expr, sql_params = self.partition_by.as_sql( sql_expr, sql_params = self.partition_by.as_sql(
@ -1678,24 +1678,23 @@ class Window(SQLiteNumericMixin, Expression):
template="PARTITION BY %(expressions)s", template="PARTITION BY %(expressions)s",
) )
window_sql.append(sql_expr) window_sql.append(sql_expr)
window_params.extend(sql_params) window_params += tuple(sql_params)
if self.order_by is not None: if self.order_by is not None:
order_sql, order_params = compiler.compile(self.order_by) order_sql, order_params = compiler.compile(self.order_by)
window_sql.append(order_sql) window_sql.append(order_sql)
window_params.extend(order_params) window_params += tuple(order_params)
if self.frame: if self.frame:
frame_sql, frame_params = compiler.compile(self.frame) frame_sql, frame_params = compiler.compile(self.frame)
window_sql.append(frame_sql) window_sql.append(frame_sql)
window_params.extend(frame_params) window_params += tuple(frame_params)
params.extend(window_params)
template = template or self.template template = template or self.template
return ( return (
template % {"expression": expr_sql, "window": " ".join(window_sql).strip()}, template % {"expression": expr_sql, "window": " ".join(window_sql).strip()},
params, (*params, *window_params),
) )
def as_sqlite(self, compiler, connection): def as_sqlite(self, compiler, connection):

View File

@ -22,3 +22,7 @@ Bugfixes
* Fixed a regression in Django 4.1 that caused an incorrect redirection to the * Fixed a regression in Django 4.1 that caused an incorrect redirection to the
admin changelist view when using *"Save and continue editing"* and *"Save and admin changelist view when using *"Save and continue editing"* and *"Save and
add another"* options (:ticket:`33893`). add another"* options (:ticket:`33893`).
* Fixed a regression in Django 4.1 that caused a crash of
:class:`~django.db.models.expressions.Window` expressions with
:class:`~django.contrib.postgres.aggregates.ArrayAgg` (:ticket:`33898`).

View File

@ -8,6 +8,7 @@ from django.db.models import (
Q, Q,
Subquery, Subquery,
Value, Value,
Window,
) )
from django.db.models.fields.json import KeyTextTransform, KeyTransform from django.db.models.fields.json import KeyTextTransform, KeyTransform
from django.db.models.functions import Cast, Concat, Substr from django.db.models.functions import Cast, Concat, Substr
@ -669,6 +670,22 @@ class TestGeneralAggregate(PostgreSQLTestCase):
inner_qs.values_list("integer_field", flat=True), inner_qs.values_list("integer_field", flat=True),
) )
def test_window(self):
self.assertCountEqual(
AggregateTestModel.objects.annotate(
integers=Window(
expression=ArrayAgg("char_field"),
partition_by=F("integer_field"),
)
).values("integers", "char_field"),
[
{"integers": ["Foo1", "Foo3"], "char_field": "Foo1"},
{"integers": ["Foo1", "Foo3"], "char_field": "Foo3"},
{"integers": ["Foo2"], "char_field": "Foo2"},
{"integers": ["Foo4"], "char_field": "Foo4"},
],
)
class TestAggregateDistinct(PostgreSQLTestCase): class TestAggregateDistinct(PostgreSQLTestCase):
@classmethod @classmethod