diff options
author | David Wobrock <david.wobrock@gmail.com> | 2019-12-28 22:42:46 +0100 |
---|---|---|
committer | Carlton Gibson <carlton.gibson@noumenal.es> | 2020-01-14 09:49:56 +0100 |
commit | 0e6cf4393c84597273d119cf64feec2ef66e35c7 (patch) | |
tree | 807f92475056f47242246e31151039f7514d7d3c /tests | |
parent | d7adaa399ebb69d4fc22f585be5343b3576b19be (diff) | |
download | django-0e6cf4393c84597273d119cf64feec2ef66e35c7.tar.gz |
[3.0.x] Fixed #31097 -- Fixed crash of ArrayAgg and StringAgg with filter when used in Subquery.
Backport of 2f565f84aca136d9cc4e4d061f3196ddf9358ab8 from master
Diffstat (limited to 'tests')
-rw-r--r-- | tests/postgres_tests/test_aggregates.py | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py index 9bd5b70a9e..fc3bb57d28 100644 --- a/tests/postgres_tests/test_aggregates.py +++ b/tests/postgres_tests/test_aggregates.py @@ -21,7 +21,7 @@ except ImportError: class TestGeneralAggregate(PostgreSQLTestCase): @classmethod def setUpTestData(cls): - AggregateTestModel.objects.create(boolean_field=True, char_field='Foo1', integer_field=0) + cls.agg1 = AggregateTestModel.objects.create(boolean_field=True, char_field='Foo1', integer_field=0) AggregateTestModel.objects.create(boolean_field=False, char_field='Foo2', integer_field=1) AggregateTestModel.objects.create(boolean_field=False, char_field='Foo4', integer_field=2) AggregateTestModel.objects.create(boolean_field=True, char_field='Foo3', integer_field=0) @@ -233,6 +233,50 @@ class TestGeneralAggregate(PostgreSQLTestCase): ).order_by('char_field').values_list('char_field', 'agg') self.assertEqual(list(values), expected_result) + def test_string_agg_array_agg_filter_in_subquery(self): + StatTestModel.objects.bulk_create([ + StatTestModel(related_field=self.agg1, int1=0, int2=5), + StatTestModel(related_field=self.agg1, int1=1, int2=4), + StatTestModel(related_field=self.agg1, int1=2, int2=3), + ]) + for aggregate, expected_result in ( + ( + ArrayAgg('stattestmodel__int1', filter=Q(stattestmodel__int2__gt=3)), + [('Foo1', [0, 1]), ('Foo2', None)], + ), + ( + StringAgg( + Cast('stattestmodel__int2', CharField()), + delimiter=';', + filter=Q(stattestmodel__int1__lt=2), + ), + [('Foo1', '5;4'), ('Foo2', None)], + ), + ): + 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), + ).filter( + char_field__in=['Foo1', 'Foo2'], + ).order_by('char_field').values_list('char_field', 'agg') + self.assertEqual(list(values), expected_result) + + def test_string_agg_filter_in_subquery_with_exclude(self): + subquery = AggregateTestModel.objects.annotate( + stringagg=StringAgg( + 'char_field', + delimiter=';', + filter=Q(char_field__endswith='1'), + ) + ).exclude(stringagg='').values('id') + self.assertSequenceEqual( + AggregateTestModel.objects.filter(id__in=Subquery(subquery)), + [self.agg1], + ) + class TestAggregateDistinct(PostgreSQLTestCase): @classmethod |