#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 django-updates+unsubscr...@googlegroups.com. 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.