Opened 5 years ago

Closed 23 months ago

#12807 closed Bug (fixed)

Empty results break when part of ORs

Reported by: sciyoshi 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 akaariai)

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 sciyoshi 5 years ago.

Download all attachments as: .zip

Change History (9)

Changed 5 years ago by sciyoshi

comment:1 Changed 5 years ago by sciyoshi

  • 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 5 years ago by Alex

  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 4 years ago by lukeplant

  • Type set to Bug

comment:4 Changed 4 years ago by lukeplant

  • Severity set to Normal

comment:5 Changed 4 years ago by patchhammer

  • Easy pickings unset
  • Patch needs improvement set

12807.patch fails to apply cleanly on to trunk

comment:6 Changed 3 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:7 Changed 23 months ago by akaariai

  • Description modified (diff)

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

  • Resolution set to fixed
  • Status changed from new to closed

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