summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-10-12 13:02:12 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-10-14 21:02:29 +0200
commitd94e777b6658701b6d9beea2c7be864bee4f6d59 (patch)
tree773eb1932b3a5ea22d5de1991f4e94ded90fcff2
parent735c88fdd75ca1f798bd39b00be77af4acc6cf15 (diff)
[3.1.x] Refs #32096 -- Fixed crash of ArrayAgg/StringAgg/JSONBAgg with ordering over JSONField key transforms.
Regression in 6789ded0a6ab797f0dcdfa6ad5d1cfa46e23abcd. Thanks Igor Jerosimić for the report. Backport of 1f31027bb3ad460864fbcbbb89eeb328c0a2f184 from master
-rw-r--r--django/contrib/postgres/aggregates/mixins.py2
-rw-r--r--docs/releases/3.1.3.txt5
-rw-r--r--tests/postgres_tests/test_aggregates.py23
3 files changed, 28 insertions, 2 deletions
diff --git a/django/contrib/postgres/aggregates/mixins.py b/django/contrib/postgres/aggregates/mixins.py
index 2ab9052467..f2ba5c4439 100644
--- a/django/contrib/postgres/aggregates/mixins.py
+++ b/django/contrib/postgres/aggregates/mixins.py
@@ -24,7 +24,7 @@ class OrderableAggMixin:
ordering_params = []
ordering_expr_sql = []
for expr in self.ordering:
- expr_sql, expr_params = expr.as_sql(compiler, connection)
+ expr_sql, expr_params = compiler.compile(expr)
ordering_expr_sql.append(expr_sql)
ordering_params.extend(expr_params)
sql, sql_params = super().as_sql(compiler, connection, ordering=(
diff --git a/docs/releases/3.1.3.txt b/docs/releases/3.1.3.txt
index 38062d4eed..8bc4877a0c 100644
--- a/docs/releases/3.1.3.txt
+++ b/docs/releases/3.1.3.txt
@@ -20,3 +20,8 @@ Bugfixes
:class:`forms.JSONField <django.forms.JSONField>` and read-only
:class:`models.JSONField <django.db.models.JSONField>` values in the admin
(:ticket:`32080`).
+
+* Fixed a regression in Django 3.1 that caused a crash of
+ :class:`~django.contrib.postgres.aggregates.ArrayAgg` and
+ :class:`~django.contrib.postgres.aggregates.StringAgg` with ``ordering``
+ on key transforms for :class:`~django.db.models.JSONField` (:ticket:`32096`).
diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py
index 8963ddbcf1..12f2a38e71 100644
--- a/tests/postgres_tests/test_aggregates.py
+++ b/tests/postgres_tests/test_aggregates.py
@@ -1,7 +1,7 @@
import json
from django.db.models import CharField, F, OuterRef, Q, Subquery, Value
-from django.db.models.fields.json import KeyTransform
+from django.db.models.fields.json import KeyTextTransform, KeyTransform
from django.db.models.functions import Cast, Concat, Substr
from django.test.utils import Approximate
@@ -106,6 +106,16 @@ class TestGeneralAggregate(PostgreSQLTestCase):
)
self.assertEqual(values, {'arrayagg': ['pl', 'en']})
+ def test_array_agg_jsonfield_ordering(self):
+ values = AggregateTestModel.objects.aggregate(
+ arrayagg=ArrayAgg(
+ KeyTransform('lang', 'json_field'),
+ filter=Q(json_field__lang__isnull=False),
+ ordering=KeyTransform('lang', 'json_field'),
+ ),
+ )
+ self.assertEqual(values, {'arrayagg': ['en', 'pl']})
+
def test_array_agg_filter(self):
values = AggregateTestModel.objects.aggregate(
arrayagg=ArrayAgg('integer_field', filter=Q(integer_field__gt=0)),
@@ -220,6 +230,17 @@ class TestGeneralAggregate(PostgreSQLTestCase):
)
self.assertEqual(values, {'stringagg': expected_output})
+ def test_string_agg_jsonfield_ordering(self):
+ values = AggregateTestModel.objects.aggregate(
+ stringagg=StringAgg(
+ KeyTextTransform('lang', 'json_field'),
+ delimiter=';',
+ ordering=KeyTextTransform('lang', 'json_field'),
+ output_field=CharField(),
+ ),
+ )
+ self.assertEqual(values, {'stringagg': 'en;pl'})
+
def test_string_agg_filter(self):
values = AggregateTestModel.objects.aggregate(
stringagg=StringAgg(