#12807: Empty results break when part of ORs
-------------------------------------+-------------------------------------
     Reporter:  sciyoshi             |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  1.1
  (models, ORM)                      |               Resolution:
     Severity:  Normal               |             Triage Stage:  Accepted
     Keywords:  query, sql, q,       |      Needs documentation:  0
  filter, or, empty                  |  Patch needs improvement:  1
    Has patch:  1                    |                    UI/UX:  0
  Needs tests:  0                    |
Easy pickings:  0                    |
-------------------------------------+-------------------------------------
Description changed by akaariai:

Old description:

> 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.

New description:

 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.

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/12807#comment:7>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.48e1e2653e9be9d2fd0605deae84e8c9%40djangoproject.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to