summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2022-08-06 17:59:31 +0200
committerGitHub <noreply@github.com>2022-08-06 17:59:31 +0200
commitfd93db97c7228b16a4f92f97ef05b0d72418d952 (patch)
treed23a5c27270ea655faea558bee53cec2c8117d33
parent00370342ca3a478660372975b3309ffc4d535be1 (diff)
downloaddjango-fd93db97c7228b16a4f92f97ef05b0d72418d952.tar.gz
Fixed #33898 -- Fixed Window() expression crash with ArrayAgg().
Thanks Kia for the report. Regression in e06dc4571ea9fd5723c8029959b95808be9f8812.
-rw-r--r--django/db/models/expressions.py11
-rw-r--r--docs/releases/4.1.1.txt4
-rw-r--r--tests/postgres_tests/test_aggregates.py17
3 files changed, 26 insertions, 6 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 0eb70b057d..5d23c1572f 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1669,7 +1669,7 @@ class Window(SQLiteNumericMixin, Expression):
if not connection.features.supports_over_clause:
raise NotSupportedError("This backend does not support window expressions.")
expr_sql, params = compiler.compile(self.source_expression)
- window_sql, window_params = [], []
+ window_sql, window_params = [], ()
if self.partition_by is not None:
sql_expr, sql_params = self.partition_by.as_sql(
@@ -1678,24 +1678,23 @@ class Window(SQLiteNumericMixin, Expression):
template="PARTITION BY %(expressions)s",
)
window_sql.append(sql_expr)
- window_params.extend(sql_params)
+ window_params += tuple(sql_params)
if self.order_by is not None:
order_sql, order_params = compiler.compile(self.order_by)
window_sql.append(order_sql)
- window_params.extend(order_params)
+ window_params += tuple(order_params)
if self.frame:
frame_sql, frame_params = compiler.compile(self.frame)
window_sql.append(frame_sql)
- window_params.extend(frame_params)
+ window_params += tuple(frame_params)
- params.extend(window_params)
template = template or self.template
return (
template % {"expression": expr_sql, "window": " ".join(window_sql).strip()},
- params,
+ (*params, *window_params),
)
def as_sqlite(self, compiler, connection):
diff --git a/docs/releases/4.1.1.txt b/docs/releases/4.1.1.txt
index 3e11782eb2..7339390ffa 100644
--- a/docs/releases/4.1.1.txt
+++ b/docs/releases/4.1.1.txt
@@ -22,3 +22,7 @@ Bugfixes
* 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
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`).
diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py
index c3df490fcf..c2f38e42b6 100644
--- a/tests/postgres_tests/test_aggregates.py
+++ b/tests/postgres_tests/test_aggregates.py
@@ -8,6 +8,7 @@ from django.db.models import (
Q,
Subquery,
Value,
+ Window,
)
from django.db.models.fields.json import KeyTextTransform, KeyTransform
from django.db.models.functions import Cast, Concat, Substr
@@ -669,6 +670,22 @@ class TestGeneralAggregate(PostgreSQLTestCase):
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):
@classmethod