From a3f91891d2c7f4bdc33f48ae70820ef6f36da26e Mon Sep 17 00:00:00 2001 From: Caio Ariede Date: Sat, 25 May 2019 10:19:32 -0300 Subject: Fixed #30315 -- Fixed crash of ArrayAgg and StringAgg with ordering when used in Subquery. --- tests/postgres_tests/test_aggregates.py | 35 +++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'tests/postgres_tests') diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py index 23f3c59ded..9bd5b70a9e 100644 --- a/tests/postgres_tests/test_aggregates.py +++ b/tests/postgres_tests/test_aggregates.py @@ -1,7 +1,8 @@ import json -from django.db.models.expressions import F, Value -from django.db.models.functions import Concat, Substr +from django.db.models import CharField +from django.db.models.expressions import F, OuterRef, Subquery, Value +from django.db.models.functions import Cast, Concat, Substr from django.test.utils import Approximate from . import PostgreSQLTestCase @@ -202,6 +203,36 @@ class TestGeneralAggregate(PostgreSQLTestCase): values = AggregateTestModel.objects.none().aggregate(jsonagg=JSONBAgg('integer_field')) self.assertEqual(values, json.loads('{"jsonagg": []}')) + def test_string_agg_array_agg_ordering_in_subquery(self): + stats = [] + for i, agg in enumerate(AggregateTestModel.objects.order_by('char_field')): + stats.append(StatTestModel(related_field=agg, int1=i, int2=i + 1)) + stats.append(StatTestModel(related_field=agg, int1=i + 1, int2=i)) + StatTestModel.objects.bulk_create(stats) + + for aggregate, expected_result in ( + ( + ArrayAgg('stattestmodel__int1', ordering='-stattestmodel__int2'), + [('Foo1', [0, 1]), ('Foo2', [1, 2]), ('Foo3', [2, 3]), ('Foo4', [3, 4])], + ), + ( + StringAgg( + Cast('stattestmodel__int1', CharField()), + delimiter=';', + ordering='-stattestmodel__int2', + ), + [('Foo1', '0;1'), ('Foo2', '1;2'), ('Foo3', '2;3'), ('Foo4', '3;4')], + ), + ): + with self.subTest(aggregate=aggregate.__class__.__name__): + subquery = AggregateTestModel.objects.filter( + pk=OuterRef('pk'), + ).annotate(agg=aggregate).values('agg') + values = AggregateTestModel.objects.annotate( + agg=Subquery(subquery), + ).order_by('char_field').values_list('char_field', 'agg') + self.assertEqual(list(values), expected_result) + class TestAggregateDistinct(PostgreSQLTestCase): @classmethod -- cgit v1.3