summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2019-03-08 11:26:53 -0500
committerTim Graham <timograham@gmail.com>2019-03-23 09:48:31 -0400
commitbdc07f176eb7c099ac3fdc42ebaadd48b7f67409 (patch)
treeb7377eb48c1f0fbdbfbf3992b2016ab26db74d73
parentf19a4945e1191e1696f1ad8e6cdc6f939c702728 (diff)
Fixed #30188 -- Fixed a crash when aggregating over a subquery annotation.
-rw-r--r--django/db/models/sql/query.py4
-rw-r--r--tests/expressions/tests.py13
2 files changed, 15 insertions, 2 deletions
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 4f2fe5acb5..74aed551a3 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -22,7 +22,7 @@ from django.db import DEFAULT_DB_ALIAS, NotSupportedError, connections
from django.db.models.aggregates import Count
from django.db.models.constants import LOOKUP_SEP
from django.db.models.expressions import (
- BaseExpression, Col, F, OuterRef, Ref, SimpleCol,
+ BaseExpression, Col, F, OuterRef, Ref, SimpleCol, Subquery,
)
from django.db.models.fields import Field
from django.db.models.fields.related_lookups import MultiColSource
@@ -382,7 +382,7 @@ class Query(BaseExpression):
# before the contains_aggregate/is_summary condition below.
new_expr, col_cnt = self.rewrite_cols(expr, col_cnt)
new_exprs.append(new_expr)
- elif isinstance(expr, Col) or (expr.contains_aggregate and not expr.is_summary):
+ elif isinstance(expr, (Col, Subquery)) or (expr.contains_aggregate and not expr.is_summary):
# Reference to column. Make sure the referenced column
# is selected.
col_cnt += 1
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index cc03e83ff4..bb448745c8 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -551,6 +551,19 @@ class BasicExpressionsTests(TestCase):
)
self.assertEqual(qs.get().float, 1.2)
+ @skipUnlessDBFeature('supports_subqueries_in_group_by')
+ def test_aggregate_subquery_annotation(self):
+ aggregate = Company.objects.annotate(
+ ceo_salary=Subquery(
+ Employee.objects.filter(
+ id=OuterRef('ceo_id'),
+ ).values('salary')
+ ),
+ ).aggregate(
+ ceo_salary_gt_20=Count('pk', filter=Q(ceo_salary__gt=20)),
+ )
+ self.assertEqual(aggregate, {'ceo_salary_gt_20': 1})
+
def test_explicit_output_field(self):
class FuncA(Func):
output_field = models.CharField()