mirror of https://github.com/django/django.git
Refs #32096 -- Fixed crash of ArrayAgg/StringAgg/JSONBAgg with ordering over JSONField key transforms.
Regression in 6789ded0a6
.
Thanks Igor Jerosimić for the report.
This commit is contained in:
parent
1d650ad019
commit
1f31027bb3
|
@ -24,7 +24,7 @@ class OrderableAggMixin:
|
||||||
ordering_params = []
|
ordering_params = []
|
||||||
ordering_expr_sql = []
|
ordering_expr_sql = []
|
||||||
for expr in self.ordering:
|
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_expr_sql.append(expr_sql)
|
||||||
ordering_params.extend(expr_params)
|
ordering_params.extend(expr_params)
|
||||||
sql, sql_params = super().as_sql(compiler, connection, ordering=(
|
sql, sql_params = super().as_sql(compiler, connection, ordering=(
|
||||||
|
|
|
@ -20,3 +20,9 @@ Bugfixes
|
||||||
:class:`forms.JSONField <django.forms.JSONField>` and read-only
|
:class:`forms.JSONField <django.forms.JSONField>` and read-only
|
||||||
:class:`models.JSONField <django.db.models.JSONField>` values in the admin
|
:class:`models.JSONField <django.db.models.JSONField>` values in the admin
|
||||||
(:ticket:`32080`).
|
(:ticket:`32080`).
|
||||||
|
|
||||||
|
* Fixed a regression in Django 3.1 that caused a crash of
|
||||||
|
:class:`~django.contrib.postgres.aggregates.ArrayAgg`,
|
||||||
|
:class:`~django.contrib.postgres.aggregates.JSONBAgg`, and
|
||||||
|
:class:`~django.contrib.postgres.aggregates.StringAgg` with ``ordering``
|
||||||
|
on key transforms for :class:`~django.db.models.JSONField` (:ticket:`32096`).
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.db.models import CharField, F, OuterRef, Q, Subquery, Value
|
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.db.models.functions import Cast, Concat, Substr
|
||||||
from django.test.utils import Approximate
|
from django.test.utils import Approximate
|
||||||
|
|
||||||
|
@ -106,6 +106,16 @@ class TestGeneralAggregate(PostgreSQLTestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(values, {'arrayagg': ['pl', 'en']})
|
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):
|
def test_array_agg_filter(self):
|
||||||
values = AggregateTestModel.objects.aggregate(
|
values = AggregateTestModel.objects.aggregate(
|
||||||
arrayagg=ArrayAgg('integer_field', filter=Q(integer_field__gt=0)),
|
arrayagg=ArrayAgg('integer_field', filter=Q(integer_field__gt=0)),
|
||||||
|
@ -232,6 +242,17 @@ class TestGeneralAggregate(PostgreSQLTestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(values, {'stringagg': expected_output})
|
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):
|
def test_string_agg_filter(self):
|
||||||
values = AggregateTestModel.objects.aggregate(
|
values = AggregateTestModel.objects.aggregate(
|
||||||
stringagg=StringAgg(
|
stringagg=StringAgg(
|
||||||
|
@ -297,6 +318,16 @@ class TestGeneralAggregate(PostgreSQLTestCase):
|
||||||
)
|
)
|
||||||
self.assertEqual(values, {'jsonagg': expected_output})
|
self.assertEqual(values, {'jsonagg': expected_output})
|
||||||
|
|
||||||
|
def test_json_agg_jsonfield_ordering(self):
|
||||||
|
values = AggregateTestModel.objects.aggregate(
|
||||||
|
jsonagg=JSONBAgg(
|
||||||
|
KeyTransform('lang', 'json_field'),
|
||||||
|
filter=Q(json_field__lang__isnull=False),
|
||||||
|
ordering=KeyTransform('lang', 'json_field'),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.assertEqual(values, {'jsonagg': ['en', 'pl']})
|
||||||
|
|
||||||
def test_string_agg_array_agg_ordering_in_subquery(self):
|
def test_string_agg_array_agg_ordering_in_subquery(self):
|
||||||
stats = []
|
stats = []
|
||||||
for i, agg in enumerate(AggregateTestModel.objects.order_by('char_field')):
|
for i, agg in enumerate(AggregateTestModel.objects.order_by('char_field')):
|
||||||
|
|
Loading…
Reference in New Issue