#31922: QuerySet.filter() against Q() with Subquery() and __in produces wrong
results.
-------------------------------------+-------------------------------------
     Reporter:  Chris Bell           |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  orm, subquery, q,    |             Triage Stage:  Accepted
  order                              |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Jacob Walls):

 Dropping a failing test for tests/queries/tests.py:
 {{{
     def test_ticket_31922(self):
         from django.db.models import Subquery
         a1 = Order.objects.create(id=1, name='a1')
         a2 = Order.objects.create(id=2, name='a2')
         OrderItem.objects.create(order=a1, status=1)
         OrderItem.objects.create(order=a1, status=2)
         OrderItem.objects.create(order=a2, status=1)

         q1 =
 Q(items__id__in=Subquery(OrderItem.objects.only('id').filter(status=1)))
         q2 =
 ~Q(items__id__in=Subquery(OrderItem.objects.only('id').filter(status=2)))

         qs = Order.objects.filter(q1 & q2)
         self.assertQuerysetEqual(qs, [repr(a2)])
 }}}

 This patch skips putting the join on the subquery, but it breaks the test
 for #14511, where the join is desired on `exclude()`, so although it
 doesn't seem like the right patch it at least shows Chris where the
 changes are happening. If we need this join for `exclude()` but not for
 `filter()` I'm all ears for how we're going to tell that apart upstream.

 {{{
 diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
 index 4648daf395..fa707d6b04 100644
 --- a/django/db/models/sql/query.py
 +++ b/django/db/models/sql/query.py
 @@ -1792,10 +1792,12 @@ class Query(BaseExpression):
              lookup_class = select_field.get_lookup('exact')
              # Note that the query.select[0].alias is different from alias
              # due to bump_prefix above.
 -            lookup = lookup_class(pk.get_col(query.select[0].alias),
 -                                  pk.get_col(alias))
 -            query.where.add(lookup, AND)
 -            query.external_aliases[alias] = True
 +            col1 = pk.get_col(query.select[0].alias)
 +            col2 = pk.get_col(alias)
 +            if col1.target != col2.target:
 +                lookup = lookup_class(col1, col2)
 +                query.where.add(lookup, AND)
 +                query.external_aliases[alias] = True

          condition, needed_inner = self.build_filter(
              ('%s__in' % trimmed_prefix, query),
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31922#comment:6>
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.a41b09dd6922916a5835d99137a007fe%40djangoproject.com.

Reply via email to