#29229: QuerySet.values_list() combined with .extra() or .annotate() may produce
wrong .union()
-------------------------------------+-------------------------------------
               Reporter:  master     |          Owner:  nobody
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  master
  layer (models, ORM)                |
               Severity:  Release    |       Keywords:  union values_list
  blocker                            |
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  1
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Regression introduced in 2.0, still present in 2.0.3.

 Easy context to reproduce the problem: suppose a Message model, in a
 postman app. Only one ordinary field is enough for the demo.

 {{{#!python
 qs1 = Message.objects.extra(select={'count': 0}).values_list('id',
 'count').order_by()
 print(qs1.query)  # as expected:
 # SELECT (0) AS "count", "postman_message"."id"
 # FROM "postman_message"

 qs2 =
 
Message.objects.values('somefield').annotate(count=models.Count('pk')).annotate(id=models.Max('pk')).values_list('id',
 'count').order_by()
 print(qs2.query)  # as expected:
 # SELECT COUNT("postman_message"."id") AS "count",
 MAX("postman_message"."id") AS "id"
 # FROM "postman_message" GROUP BY "postman_message"."somefield"

 print(qs1.union(qs2).query)  # !! WRONG !! the qs2 part is truncated:
 # SELECT (0) AS "count", "postman_message"."id" FROM "postman_message"
 # UNION
 # SELECT MAX("postman_message"."id") AS "id" FROM "postman_message" GROUP
 BY "postman_message"."somefield"
 }}}

 Compared to version 1.11, it comes from this addition in
 db/models/sql/compiler.py/get_combinator_sql():
 {{{#!python
 if not compiler.query.values_select and self.query.values_select:
     compiler.query.set_values(self.query.values_select)
 }}}
 Here, self.query.values_select is ('id',).
 For qs2, values_select is indeed empty, as coded in
 db/models/sql/query.py/set_values(),
 because in this case the two values_list() arguments are managed in
 annotation_names[].

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29229>
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 post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/049.ca95a93910f4ed2445e879ee1ae5f5c0%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to