POSSIBLE BUG: using Coalesce() with __in=[]

58 views
Skip to first unread message

Ryan Prater

unread,
Mar 30, 2016, 12:27:49 PM3/30/16
to Django users
It seems that using an empty list when using the `__in=` filter prevents an Aggregate Coalesce from working properly. See below:

# Test with matched Queryset. Sum will return 50
OrderItem.objects.filter(pk__in=[1]).aggregate(test=Coalesce(Sum('quantity'), Value(0)))
>>> {'test': 50}
 
# Test with unmatched Queryset. Sum will return 0
OrderItem.objects.filter(pk__in=[-1]).aggregate(test=Coalesce(Sum('quantity'), Value(0)))
>>> {'test':0}
 
# Test with unmatched Queryset (using empty list). Sum will return NONE
OrderItem.objects.filter(pk__in=[]).aggregate(test=Coalesce(Sum('quantity'), Value(0)))
>>> {'test': None}

Can someone confirm? I will post as a bug if so.

Simon Charette

unread,
Mar 30, 2016, 1:03:10 PM3/30/16
to Django users
Hi Ryan,

I think this should be considered a bug.

From what I understand the ORM simply doesn't perform any query in this case
as the `pk__in` lookup cannot match any `OrderItem` and result in an
`EmptyResultSet` exception[1].

This exception is caught in the `Query.get_aggregation()` method where all
aggregates are converted to `None`[2].

I suppose we should alter the `except EmptyResultSet` clause to account for
`outer_query.annotation_select` items that are `Coalesce()` instances used with
`Value()` but I'm unsure about how it should be done.

I think this will be hard to fix correctly as `Coalesce` can be nested.

e.g.

# This should return `0`
Coalesce(Coalesce(Sum('quantity'), Value(0)), F('other_field'))

Cheers,
Simon

[1] https://github.com/django/django/blob/2e0cd26ffb29189add1e0435913fd1490f52b20d/django/db/models/lookups.py#L221-L223
[2] https://github.com/django/django/blob/2e0cd26ffb29189add1e0435913fd1490f52b20d/django/db/models/sql/query.py#L439-L445

Ryan Prater

unread,
Mar 30, 2016, 6:11:14 PM3/30/16
to Django users
Thank you Simon!

I'll file a bug and include a link here, including your points. Your source documentation was incredibly helpful.
Reply all
Reply to author
Forward
0 new messages