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