Author: Alex
Date: 2010-11-16 20:57:14 -0600 (Tue, 16 Nov 2010)
New Revision: 14586
Modified:
django/trunk/django/db/models/sql/aggregates.py
django/trunk/django/db/models/sql/query.py
django/trunk/django/db/models/sql/subqueries.py
django/trunk/tests/regressiontests/aggregation_regress/tests.py
Log:
Fixed #12687 -- fixed an issue with aggregates and counts in conjunction with
annotations where the QuerySet was provably empty.
Modified: django/trunk/django/db/models/sql/aggregates.py
===================================================================
--- django/trunk/django/db/models/sql/aggregates.py 2010-11-17 02:25:20 UTC
(rev 14585)
+++ django/trunk/django/db/models/sql/aggregates.py 2010-11-17 02:57:14 UTC
(rev 14586)
@@ -8,6 +8,7 @@
"""
def __init__(self, internal_type):
self.internal_type = internal_type
+
def get_internal_type(self):
return self.internal_type
Modified: django/trunk/django/db/models/sql/query.py
===================================================================
--- django/trunk/django/db/models/sql/query.py 2010-11-17 02:25:20 UTC (rev
14585)
+++ django/trunk/django/db/models/sql/query.py 2010-11-17 02:57:14 UTC (rev
14586)
@@ -337,7 +337,7 @@
# information but retrieves only the first row. Aggregate
# over the subquery instead.
if self.group_by is not None:
- from subqueries import AggregateQuery
+ from django.db.models.sql.subqueries import AggregateQuery
query = AggregateQuery(self.model)
obj = self.clone()
@@ -349,7 +349,13 @@
query.aggregate_select[alias] = aggregate
del obj.aggregate_select[alias]
- query.add_subquery(obj, using)
+ try:
+ query.add_subquery(obj, using)
+ except EmptyResultSet:
+ return dict(
+ (alias, None)
+ for alias in query.aggregate_select
+ )
else:
query = self
self.select = []
@@ -382,13 +388,19 @@
# If a select clause exists, then the query has already started to
# specify the columns that are to be returned.
# In this case, we need to use a subquery to evaluate the count.
- from subqueries import AggregateQuery
+ from django.db.models.sql.subqueries import AggregateQuery
subquery = obj
subquery.clear_ordering(True)
subquery.clear_limits()
obj = AggregateQuery(obj.model)
- obj.add_subquery(subquery, using=using)
+ try:
+ obj.add_subquery(subquery, using=using)
+ except EmptyResultSet:
+ # add_subquery evaluates the query, if it's an EmptyResultSet
+ # then there are can be no results, and therefore there the
+ # count is obviously 0
+ return 0
obj.add_count_column()
number = obj.get_aggregation(using=using)[None]
Modified: django/trunk/django/db/models/sql/subqueries.py
===================================================================
--- django/trunk/django/db/models/sql/subqueries.py 2010-11-17 02:25:20 UTC
(rev 14585)
+++ django/trunk/django/db/models/sql/subqueries.py 2010-11-17 02:57:14 UTC
(rev 14586)
@@ -11,6 +11,7 @@
from django.db.models.sql.query import Query
from django.db.models.sql.where import AND, Constraint
+
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
'AggregateQuery']
Modified: django/trunk/tests/regressiontests/aggregation_regress/tests.py
===================================================================
--- django/trunk/tests/regressiontests/aggregation_regress/tests.py
2010-11-17 02:25:20 UTC (rev 14585)
+++ django/trunk/tests/regressiontests/aggregation_regress/tests.py
2010-11-17 02:57:14 UTC (rev 14586)
@@ -622,6 +622,24 @@
lambda:
Book.objects.annotate(mean_age=Avg('authors__age')).annotate(Avg('mean_age'))
)
+ def test_empty_filter_count(self):
+ self.assertEqual(
+
Author.objects.filter(id__in=[]).annotate(Count("friends")).count(),
+ 0
+ )
+
+ def test_empty_filter_aggregate(self):
+ self.assertEqual(
+
Author.objects.filter(id__in=[]).annotate(Count("friends")).aggregate(Count("pk")),
+ {"pk__count": None}
+ )
+
+ def test_annotate_and_join(self):
+ self.assertEqual(
+
Author.objects.annotate(c=Count("friends__name")).exclude(friends__name="Joe").count(),
+ Author.objects.count()
+ )
+
@skipUnlessDBFeature('supports_stddev')
def test_stddev(self):
self.assertEqual(
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.