#24705: Exception when negating Q object in annotate
-------------------------------------+-------------------------------------
Reporter: karyon | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.8
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by akaariai):
I know the reason for this, but can't work on a patch right now. The
reason is that _add_q() calls build_filter() with in_negated=True, and
build_filter() automatically pushes negated multijoin filters to
subqueries. This is correct when constructing a Where clause, but
incorrect for Case(When()).
To fix this in 1.8 we need to add a new kwarg to _add_q(), something like
disable_split_exclude, and add a similar kwarg to build_filter(). When Q()
objects are added to a query outside of filter() handling, we set this
flag to True (this is done in Q().resolve_expression()). This should
hopefully fix this issue.
For 1.9 this will be fixed by https://github.com/django/django/pull/4385.
We can of course add the 1.8 version to master, too, if pull 4385 hasn't
been committed by the time we fix this issue.
We need to also make sure Q() objects added for Case(When()) do not
regenerate aliases. They should use an existing alias, and multiple Q()
objects in the same annotation should use a single alias. So, for example:
{{{
.annotate(v=Case(When(friends__age=123), then=V(1)),
When(friends__age=321), then(V(2)))
}}}
should generate just one join to friends. If a join for friends pre-
exists, then that join should be reused.
I think I can try to work on this next week, but can't guarantee anything.
--
Ticket URL: <https://code.djangoproject.com/ticket/24705#comment:5>
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 post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.fc4bb879249cc6faebeb8ad3e9050820%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.