#33482 closed Bug (fixed)
filter on exists-subquery with empty queryset removes whole WHERE block
Reported by: | Tobias Bengfort | Owned by: | Simon Charette |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.0 |
Severity: | Normal | Keywords: | orm, EmptyResultSet, Exists |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
>>> qs = MyModel.objects.filter(~models.Exists(MyModel.objects.none()), name='test') >>> qs <QuerySet []> >>> print(qs.query) EmptyResultSet
With django-debug-toolbar I can still see the query, but there WHERE block is missing completely.
This seems to be very similar to #33018.
Change History (14)
comment:1 by , 3 years ago
Description: | modified (diff) |
---|
comment:2 by , 3 years ago
Description: | modified (diff) |
---|
comment:3 by , 3 years ago
Summary: | filter on exists-subquery with emoty queryset removes whole WHERE block → filter on exists-subquery with empty queryset removes whole WHERE block |
---|
comment:4 by , 3 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
Type: | Uncategorized → Bug |
comment:5 by , 3 years ago
Has patch: | set |
---|
comment:6 by , 3 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:9 by , 15 months ago
Resolution: | fixed |
---|---|
Status: | closed → new |
I still get this error in 4.2 if I include the empty exists expression in the filter:
def test_filter_by_empty_exists(self): manager = Manager.objects.create() qs = Manager.objects.annotate( exists=Exists(Manager.objects.none()) ).filter(pk=manager.pk, exists=False) self.assertSequenceEqual(qs, [manager]) self.assertIs(qs.get().exists, False)
comment:10 by , 15 months ago
The fact the problem manifests itself when the queryset is not negated was missed during the initial patch.
Tobias, can you confirm the following PR addresses the issue.
It seemed worth continuing the discussion here instead of creating a separate ticket.
comment:11 by , 15 months ago
Thanks for the quick response! It looks good. It fixed the bug in my application.
comment:13 by , 15 months ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
I think that this is an issue with
Exists.as_sql
whenself.invert is True
.Since
Exists
encapsulate its negation logic (see__invert__
) it should catchEmptyResultSet
when raised by itssuper()
call inas_sql
and return an always true predicate (e.g.1=1
).Does the following patch address your issue?
django/db/models/expressions.py
tests/expressions/tests.py