#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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.a41b09dd6922916a5835d99137a007fe%40djangoproject.com.

Reply via email to