mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
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.
This commit is contained in:
committed by
Mariusz Felisiak
parent
789c47e6de
commit
c2d4926702
@@ -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.',
|
||||
|
||||
Reference in New Issue
Block a user