#36349: Queryset.values() followed by annotate may crash depending of values
parameters order
-------------------------------------+-------------------------------------
     Reporter:  Zankroh              |                    Owner:  (none)
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  5.2
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  values annotate      |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Zankroh:

Old description:

> Since Django 5.2, the order of values can crash if annotate is used
> after.
>
> Imagine the following "AgentAmount" model:
>
> {{{
> +---------------------+--------------+------+-----+---------+----------------+
> | Field               | Type         | Null | Key | Default | Extra
> |
> +---------------------+--------------+------+-----+---------+----------------+
> | id                  | bigint       | NO   | PRI | NULL    |
> auto_increment |
> | uid_agent           | varchar(64)  | NO   | MUL | NULL    |
> |
> | amount              | int          | NO   |     | NULL    |
> |
> | status              | varchar(60)  | NO   | MUL | NULL    |
> |
> | last                | tinyint(1)   | NO   | MUL | NULL    |
> |
> | created_at          | datetime(6)  | NO   | MUL | NULL    |
> |
> +---------------------+--------------+------+-----+---------+----------------+
> }}}
>

> The following query will crash :
> {{{#!python
> AgentAmount.objects.filter(
>     uid_agent="SMP43279",
>     last=True
> ).values(
>     "created_at__date",
>     "status",
> ).annotate(
>     sum_amount=Sum("amount")
> )
> }}}
>
> Here the traceback:
>
> {{{
> Traceback (most recent call last):
>   File "<console>", line 1, in <module>
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\query.py", line 360, in __repr__
>     data = list(self[: REPR_OUTPUT_SIZE + 1])
>            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\query.py", line 384, in __iter__
>     self._fetch_all()
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\query.py", line 1935, in _fetch_all
>     self._result_cache = list(self._iterable_class(self))
>                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\query.py", line 216, in __iter__
>     for row in compiler.results_iter(
>                ^^^^^^^^^^^^^^^^^^^^^^
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\sql\compiler.py", line 1571, in results_iter
>     results = self.execute_sql(
>               ^^^^^^^^^^^^^^^^^
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\sql\compiler.py", line 1609, in execute_sql
>     sql, params = self.as_sql()
>                   ^^^^^^^^^^^^^
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\sql\compiler.py", line 765, in as_sql
>     extra_select, order_by, group_by = self.pre_sql_setup(
>                                        ^^^^^^^^^^^^^^^^^^^
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\sql\compiler.py", line 85, in pre_sql_setup
>     self.setup_query(with_col_aliases=with_col_aliases)
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\sql\compiler.py", line 74, in setup_query
>     self.select, self.klass_info, self.annotation_col_map =
> self.get_select(
> ^^^^^^^^^^^^^^^^
>   File "C:\Users\xxx\Projects\env\Lib\site-
> packages\django\db\models\sql\compiler.py", line 286, in get_select
>     expression = cols[expression]
>                  ~~~~^^^^^^^^^^^^
> IndexError: tuple index out of range
> }}}
>

> But if I do this query
>
> {{{#!python
> models.AgentHistory.objects.filter(
>     uid_agent="SMP43279",
>     last=True
> ).values(
>     "status",
>     "created_at__date",
> ).annotate(
>     sum_amount=Sum("amount")
> )
> }}}
> Everything is fine

New description:

 Since Django 5.2, the order of values can crash if annotate is used after.

 Imagine the following "AgentAmount" model:

 {{{
 +---------------------+--------------+------+-----+---------+----------------+
 | Field               | Type         | Null | Key | Default | Extra
 |
 +---------------------+--------------+------+-----+---------+----------------+
 | id                  | bigint       | NO   | PRI | NULL    |
 auto_increment |
 | uid_agent           | varchar(64)  | NO   | MUL | NULL    |
 |
 | amount              | int          | NO   |     | NULL    |
 |
 | status              | varchar(60)  | NO   | MUL | NULL    |
 |
 | last                | tinyint(1)   | NO   | MUL | NULL    |
 |
 | created_at          | datetime(6)  | NO   | MUL | NULL    |
 |
 +---------------------+--------------+------+-----+---------+----------------+
 }}}


 The following query will crash :
 {{{#!python
 AgentAmount.objects.filter(
     uid_agent="SMP43279",
     last=True
 ).values(
     "created_at__date",
     "status",
 ).annotate(
     sum_amount=Sum("amount")
 )
 }}}

 Here the traceback:

 {{{
 Traceback (most recent call last):
   File "<console>", line 1, in <module>
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\query.py", line 360, in __repr__
     data = list(self[: REPR_OUTPUT_SIZE + 1])
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\query.py", line 384, in __iter__
     self._fetch_all()
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\query.py", line 1935, in _fetch_all
     self._result_cache = list(self._iterable_class(self))
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\query.py", line 216, in __iter__
     for row in compiler.results_iter(
                ^^^^^^^^^^^^^^^^^^^^^^
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\sql\compiler.py", line 1571, in results_iter
     results = self.execute_sql(
               ^^^^^^^^^^^^^^^^^
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\sql\compiler.py", line 1609, in execute_sql
     sql, params = self.as_sql()
                   ^^^^^^^^^^^^^
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\sql\compiler.py", line 765, in as_sql
     extra_select, order_by, group_by = self.pre_sql_setup(
                                        ^^^^^^^^^^^^^^^^^^^
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\sql\compiler.py", line 85, in pre_sql_setup
     self.setup_query(with_col_aliases=with_col_aliases)
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\sql\compiler.py", line 74, in setup_query
     self.select, self.klass_info, self.annotation_col_map =
 self.get_select(
 ^^^^^^^^^^^^^^^^
   File "C:\Users\xxx\Projects\env\Lib\site-
 packages\django\db\models\sql\compiler.py", line 286, in get_select
     expression = cols[expression]
                  ~~~~^^^^^^^^^^^^
 IndexError: tuple index out of range
 }}}


 But if I do this query

 {{{#!python
 AgentAmount.objects.filter(
     uid_agent="SMP43279",
     last=True
 ).values(
     "status",
     "created_at__date",
 ).annotate(
     sum_amount=Sum("amount")
 )
 }}}
 Everything is fine

--
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36349#comment:1>
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 visit 
https://groups.google.com/d/msgid/django-updates/010701966201dd9d-0eac4600-5c69-4650-8e23-1d0e5cbe1133-000000%40eu-central-1.amazonses.com.

Reply via email to