Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #10089 -- Corrected handling of aggregates when the query set c…

…ontains no items (and the cursor returns None). Thanks to Kyle Fox for the report, and david for the initial patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9786 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 0e15932be392ab56fa0087f9c13b234af7749e2e 1 parent ed3d273
Russell Keith-Magee freakboy3742 authored
8 django/db/models/sql/query.py
View
@@ -217,6 +217,8 @@ def resolve_aggregate(self, value, aggregate):
to return Decimal and long types when they are not needed.
"""
if value is None:
+ if aggregate.is_ordinal:
+ return 0
# Return None as-is
return value
elif aggregate.is_ordinal:
@@ -295,10 +297,14 @@ def get_aggregation(self):
query.related_select_cols = []
query.related_select_fields = []
+ result = query.execute_sql(SINGLE)
+ if result is None:
+ result = [None for q in query.aggregate_select.items()]
+
return dict([
(alias, self.resolve_aggregate(val, aggregate))
for (alias, aggregate), val
- in zip(query.aggregate_select.items(), query.execute_sql(SINGLE))
+ in zip(query.aggregate_select.items(), result)
])
def get_count(self):
8 tests/modeltests/aggregation/fixtures/initial_data.json
View
@@ -32,6 +32,14 @@
}
},
{
+ "pk": 5,
+ "model": "aggregation.publisher",
+ "fields": {
+ "name": "Jonno's House of Books",
+ "num_awards": 0
+ }
+ },
+ {
"pk": 1,
"model": "aggregation.book",
"fields": {
4 tests/modeltests/aggregation/models.py
View
@@ -194,7 +194,7 @@ class Clues(models.Model):
# Annotate each publisher with the sum of the price of all books sold
>>> publishers = Publisher.objects.all().annotate(Sum('book__price'))
>>> sorted([(p.name, p.book__price__sum) for p in publishers])
-[(u'Apress', Decimal("59.69")), (u'Morgan Kaufmann', Decimal("75.00")), (u'Prentice Hall', Decimal("112.49")), (u'Sams', Decimal("23.09"))]
+[(u'Apress', Decimal("59.69")), (u"Jonno's House of Books", None), (u'Morgan Kaufmann', Decimal("75.00")), (u'Prentice Hall', Decimal("112.49")), (u'Sams', Decimal("23.09"))]
# Calls to values() are not commutative over annotate().
@@ -356,7 +356,7 @@ class Clues(models.Model):
[]
# Aggregates also work on dates, times and datetimes
->>> Publisher.objects.annotate(earliest_book=Min('book__pubdate')).order_by('earliest_book').values()
+>>> Publisher.objects.annotate(earliest_book=Min('book__pubdate')).exclude(earliest_book=None).order_by('earliest_book').values()
[{'earliest_book': datetime.date(1991, 10, 15), 'num_awards': 9, 'id': 4, 'name': u'Morgan Kaufmann'}, {'earliest_book': datetime.date(1995, 1, 15), 'num_awards': 7, 'id': 3, 'name': u'Prentice Hall'}, {'earliest_book': datetime.date(2007, 12, 6), 'num_awards': 3, 'id': 1, 'name': u'Apress'}, {'earliest_book': datetime.date(2008, 3, 3), 'num_awards': 1, 'id': 2, 'name': u'Sams'}]
>>> Store.objects.aggregate(Max('friday_night_closing'), Min("original_opening"))
8 tests/regressiontests/aggregation_regress/fixtures/initial_data.json
View
@@ -32,6 +32,14 @@
}
},
{
+ "pk": 5,
+ "model": "aggregation_regress.publisher",
+ "fields": {
+ "name": "Jonno's House of Books",
+ "num_awards": 0
+ }
+ },
+ {
"pk": 1,
"model": "aggregation_regress.book",
"fields": {
10 tests/regressiontests/aggregation_regress/models.py
View
@@ -164,6 +164,16 @@ def __unicode__(self):
>>> len(Book.objects.annotate(num_authors=Count('authors')).exclude(num_authors__lt=2).filter(num_authors__lt=3))
2
+# Regression for #10089: Check handling of empty result sets with aggregates
+>>> Book.objects.filter(id__in=[]).count()
+0
+
+>>> Book.objects.filter(id__in=[]).aggregate(num_authors=Count('authors'), avg_authors=Avg('authors'), max_authors=Max('authors'), max_price=Max('price'), max_rating=Max('rating'))
+{'max_authors': None, 'max_rating': None, 'num_authors': 0, 'avg_authors': None, 'max_price': None}
+
+>>> Publisher.objects.filter(pk=5).annotate(num_authors=Count('book__authors'), avg_authors=Avg('book__authors'), max_authors=Max('book__authors'), max_price=Max('book__price'), max_rating=Max('book__rating')).values()
+[{'max_authors': None, 'name': u"Jonno's House of Books", 'num_awards': 0, 'max_price': None, 'num_authors': 0, 'max_rating': None, 'id': 5, 'avg_authors': None}]
+
"""
}
Please sign in to comment.
Something went wrong with that request. Please try again.