mirror of
https://github.com/django/django.git
synced 2025-11-29 15:01:18 +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:
parent
789c47e6de
commit
c2d4926702
5 changed files with 26 additions and 17 deletions
|
|
@ -17,9 +17,7 @@ from collections.abc import Iterator, Mapping
|
|||
from itertools import chain, count, product
|
||||
from string import ascii_uppercase
|
||||
|
||||
from django.core.exceptions import (
|
||||
EmptyResultSet, FieldDoesNotExist, FieldError,
|
||||
)
|
||||
from django.core.exceptions import FieldDoesNotExist, FieldError
|
||||
from django.db import DEFAULT_DB_ALIAS, NotSupportedError, connections
|
||||
from django.db.models.aggregates import Count
|
||||
from django.db.models.constants import LOOKUP_SEP
|
||||
|
|
@ -449,8 +447,9 @@ class Query(BaseExpression):
|
|||
if (isinstance(self.group_by, tuple) or self.is_sliced or existing_annotations or
|
||||
self.distinct or self.combinator):
|
||||
from django.db.models.sql.subqueries import AggregateQuery
|
||||
outer_query = AggregateQuery(self.model)
|
||||
inner_query = self.clone()
|
||||
inner_query.subquery = True
|
||||
outer_query = AggregateQuery(self.model, inner_query)
|
||||
inner_query.select_for_update = False
|
||||
inner_query.select_related = False
|
||||
inner_query.set_annotation_mask(self.annotation_select)
|
||||
|
|
@ -492,13 +491,6 @@ class Query(BaseExpression):
|
|||
# field selected in the inner query, yet we must use a subquery.
|
||||
# So, make sure at least one field is selected.
|
||||
inner_query.select = (self.model._meta.pk.get_col(inner_query.get_initial_alias()),)
|
||||
try:
|
||||
outer_query.add_subquery(inner_query, using)
|
||||
except EmptyResultSet:
|
||||
return {
|
||||
alias: None
|
||||
for alias in outer_query.annotation_select
|
||||
}
|
||||
else:
|
||||
outer_query = self
|
||||
self.select = ()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue