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