diff options
| author | Simon Charette <charette.s@gmail.com> | 2020-11-03 16:50:10 -0500 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-11-04 09:54:58 +0100 |
| commit | c2d4926702045e342a668057f0a758eec9db9436 (patch) | |
| tree | 54640bce1e4fb40704ee488819848d7a16434f57 /tests | |
| parent | 789c47e6de70ca8249aceac83d629c5d38070e45 (diff) | |
Fixed #31910 -- Fixed crash of GIS aggregations over subqueries.
Regression was introduced by fff5186 but was due a long standing issue.
AggregateQuery was abusing Query.subquery: bool by stashing its
compiled inner query's SQL for later use in its compiler which made
select_format checks for Query.subquery wrongly assume the provide
query was a subquery.
This patch prevents that from happening by using a dedicated
inner_query attribute which is compiled at a later time by
SQLAggregateCompiler.
Moving the inner query's compilation to SQLAggregateCompiler.compile
had the side effect of addressing a long standing issue with
aggregation subquery pushdown which prevented converters from being
run. This is now fixed as the aggregation_regress adjustments
demonstrate.
Refs #25367.
Thanks Eran Keydar for the report.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/aggregation_regress/tests.py | 2 | ||||
| -rw-r--r-- | tests/gis_tests/geoapp/tests.py | 14 |
2 files changed, 15 insertions, 1 deletions
diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index 7604335257..48187ee00b 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -974,7 +974,7 @@ class AggregationTests(TestCase): def test_empty_filter_aggregate(self): self.assertEqual( Author.objects.filter(id__in=[]).annotate(Count("friends")).aggregate(Count("pk")), - {"pk__count": None} + {"pk__count": 0} ) def test_none_call_before_aggregate(self): diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py index 98523c2add..8dfe3d02a1 100644 --- a/tests/gis_tests/geoapp/tests.py +++ b/tests/gis_tests/geoapp/tests.py @@ -12,6 +12,7 @@ from django.core.management import call_command from django.db import DatabaseError, NotSupportedError, connection from django.db.models import F, OuterRef, Subquery from django.test import TestCase, skipUnlessDBFeature +from django.test.utils import CaptureQueriesContext from ..utils import ( mariadb, mysql, oracle, postgis, skipUnlessGISLookup, spatialite, @@ -593,6 +594,19 @@ class GeoQuerySetTest(TestCase): qs = City.objects.filter(name='NotACity') self.assertIsNone(qs.aggregate(Union('point'))['point__union']) + @skipUnlessDBFeature('supports_union_aggr') + def test_geoagg_subquery(self): + ks = State.objects.get(name='Kansas') + union = GEOSGeometry('MULTIPOINT(-95.235060 38.971823)') + # Use distinct() to force the usage of a subquery for aggregation. + with CaptureQueriesContext(connection) as ctx: + self.assertIs(union.equals( + City.objects.filter(point__within=ks.poly).distinct().aggregate( + Union('point'), + )['point__union'], + ), True) + self.assertIn('subquery', ctx.captured_queries[0]['sql']) + @unittest.skipUnless( connection.vendor == 'oracle', 'Oracle supports tolerance parameter.', |
