Opened 7 years ago

Closed 3 years ago

#12807 closed Bug (fixed)

Empty results break when part of ORs

Reported by: Samuel Cormier-Iijima Owned by: nobody
Component: Database layer (models, ORM) Version: 1.1
Severity: Normal Keywords: query, sql, q, filter, or, empty
Cc: sciyoshi@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description (last modified by Anssi Kääriäinen)

The following query:

User.objects.filter((Q(pk=3) | ~Q(pk__in=[]) & Q(pk=1))

currently breaks, since ~Q(pk__in=[]) isn't noticed as being full, thus leading to the following query:

User.objects.filter((Q(pk=3) | ~Q(pk__in=[])) & Q(pk=1)).values('id').query.as_sql()

('SELECT "auth_user"."id" FROM "auth_user" WHERE (("auth_user"."id" = %s ) AND "auth_user"."id" = %s )', (3, 1))

and giving an empty result set, instead of the correct

User.objects.filter((Q(pk=3) | ~Q(pk__in=[])) & Q(pk=1)).values('id').query.as_sql()

('SELECT "auth_user"."id" FROM "auth_user" WHERE ("auth_user"."id" = %s )', (1,))

which returns the single user with PK 1.

Attaching a patch which fixes it by making as_sql() raise FullResultSet and adds a test case. The issue could also be fixed by checking if the child's as_sql() is empty, but this seemed cleaner.

Attachments (1)

12807.patch (3.9 KB) - added by Samuel Cormier-Iijima 7 years ago.

Download all attachments as: .zip

Change History (9)

Changed 7 years ago by Samuel Cormier-Iijima

Attachment: 12807.patch added

comment:1 Changed 7 years ago by Samuel Cormier-Iijima

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

Sorry about the formatting (should probably use preview next time). That should have read:

The following query:

User.objects.filter((Q(pk=3) | ~Q(pkin=[]) & Q(pk=1))

currently breaks, since ~Q(pkin=[]) isn't noticed as being full, thus leading to the following query:

>>> User.objects.filter((Q(pk=3) | ~Q(pkin=[])) & Q(pk=1)).values('id').query.as_sql()
('SELECT "auth_user"."id" FROM "auth_user" WHERE (("auth_user"."id" = %s ) AND "auth_user"."id" = %s )', (3, 1))

and giving an empty result set, instead of the correct

>>> User.objects.filter((Q(pk=3) | ~Q(pkin=[])) & Q(pk=1)).values('id').query.as_sql()
('SELECT "auth_user"."id" FROM "auth_user" WHERE ("auth_user"."id" = %s )', (1,))

which returns the single user with PK 1.

comment:2 Changed 7 years ago by Alex Gaynor

Triage Stage: UnreviewedAccepted

comment:3 Changed 5 years ago by Luke Plant

Type: Bug

comment:4 Changed 5 years ago by Luke Plant

Severity: Normal

comment:5 Changed 5 years ago by patchhammer

Easy pickings: unset
Patch needs improvement: set

12807.patch fails to apply cleanly on to trunk

comment:6 Changed 5 years ago by Aymeric Augustin

UI/UX: unset

Change UI/UX from NULL to False.

comment:7 Changed 3 years ago by Anssi Kääriäinen

Description: modified (diff)

comment:8 Changed 3 years ago by Anssi Kääriäinen <akaariai@…>

Resolution: fixed
Status: newclosed

In 58c6d0209d71872f0682d478921db1e00496e16c:

Fixed #12807 -- EmptyResultSet ORed condition

The EmptyResultSet wasn't treated correctly so the end results was
incorrect, too. The bug had been already fixed in master so only tests
added.

Note: See TracTickets for help on using tickets.
Back to Top