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

Reply via email to