#33975: __in doesn't clear selected fields on the RHS when QuerySet.alias() is
used
after annotate().
-------------------------------------+-------------------------------------
Reporter: Gabriel Muj | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Database layer | Version: 4.0
(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 Simon Charette):
Whether or not the `In` lookups defaults a `Query` right-hand-side to
`.values('pk')` is based of `rhs.has_select_fields`
([https://github.com/django/django/blob/cd1afd553f9c175ebccfc0f50e72b43b9604bd97/django/db/models/lookups.py#L421-L425
source])
This dynamic property is based of `self.select or
self.annotation_select_mask` so I suspect that there might be some bad
logic in `Query.add_annotation`
([https://github.com/django/django/blob/b3db6c8dcb5145f7d45eff517bcd96460475c879/django/db/models/sql/query.py#L1109-L1119
source]) from the introduction of `QuerySet.alias` in
f4ac167119e8897c398527c392ed117326496652.
The
`self.set_annotation_mask(set(self.annotation_select).difference({alias}))`
[https://github.com/django/django/commit/f4ac167119e8897c398527c392ed117326496652
#diff-
fd2300283d1546e36141373b0621f142ed871e3e8856e07efe5a22ecc38ad620R1025
line] seems to be what causes the problem here. If `annotate` and `alias`
are used then `annotation_select_mask` will be materialized as a ''mask''
is required to keep track of which entries in `annotations` must be
selected and whatnot (not necessary if only using `alias` or `annotate` as
the first doesn't require any selecting and the second selects all
annotations)
The `add_annotation` logic relied on to implement `QuerySet.alias` is not
wrong per se it just happens to piggy back on the annotation masking logic
that only `Query.set_values` relied on previously an now happens to break
the heuristics in `Query.has_select_fields`.
The proper solutions is likely to replace `Query.has_select_fields` by a
class attribute that defaults to `False` and have `set_values` set it to
`True` and make sure `Query.clone` carries the attribute over. This seems
like a more durable options as that avoids trying to peek into internals
to determine if a `values` call was performed.
--
Ticket URL: <https://code.djangoproject.com/ticket/33975#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 view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018300ae8c8e-399e8bdc-ceaa-49b8-8638-5bc8ae44b337-000000%40eu-central-1.amazonses.com.