Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#34267 closed Bug (fixed)

QuerySet.union() crashes with IndexError when getting cached results.

Reported by: Raphaël Stefanini Owned by: Francesco Panico
Component: Database layer (models, ORM) Version: 4.2
Severity: Release blocker Keywords:
Cc: Simon Charette Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Raphaël Stefanini)

I tried 4.2a1 today on my project and I noticed pagination was broken on one view.

After little investigation I manage to reproduce an error:

Event is a model with set a Foreignkey

>> events = Event.objects.all()
>> events_without_set = events.filter(set__isnull=True)
>> one_event_of_each_set = (
        events.filter(set__isnull=False)
               .order_by("set_id")
               .distinct("set_id")
)
>> my_list = events_without_set.union(one_event_of_each_set)
>> my_list.count()
212
>> my_list[2]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/venv/lib/python3.11/site-packages/django/db/models/query.py", line 450, in __getitem__
    return qs._result_cache[0]
           ~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

With django 4.1.5 my_list[2] returns an event.

Change History (11)

comment:1 by Raphaël Stefanini, 4 years ago

Description: modified (diff)

comment:2 by Raphaël Stefanini, 4 years ago

Component: Uncategorized → Database layer (models, ORM)

comment:3 by Mariusz Felisiak, 4 years ago

Cc: Simon Charette added
Severity: Normal → Release blocker
Summary: Error with Union queryset not being paginable → QuerySet.union() crashes with IndexError when getting cached results.
Triage Stage: Unreviewed → Accepted

Thanks for testing the alpha release!

Regression in 3d734c09ff0138441dfe0a59010435871d17950f.

comment:4 by Francesco Panico, 4 years ago

Owner: changed from nobody to Francesco Panico
Status: new → assigned

comment:5 by Simon Charette, 4 years ago

It seems that the issue is likely due the ​if sliced branch which was hoping to port the optimization that made union().exists() have all the involved subqueries augmented with LIMIT 1 if supported by the backend.

I believe that this optimization can likely be removed since backends are likely smart enough to perform this optimization themselves when EXISTS is used.

comment:6 by Francesco Panico, 4 years ago

Has patch: set

comment:7 by Mariusz Felisiak, 4 years ago

Patch needs improvement: set

comment:8 by Francesco Panico, 4 years ago

Patch needs improvement: unset

comment:9 by Mariusz Felisiak, 4 years ago

Triage Stage: Accepted → Ready for checkin

comment:10 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: → fixed
Status: assigned → closed

In cc8aa6bf:

Fixed #34267 -- Fixed sliced QuerySet.union() crash.

Regression in 3d734c09ff0138441dfe0a59010435871d17950f.

Thanks Raphaël Stefanini for the report.

comment:11 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

In 84927e1:

[4.2.x] Fixed #34267 -- Fixed sliced QuerySet.union() crash.

Regression in 3d734c09ff0138441dfe0a59010435871d17950f.

Thanks Raphaël Stefanini for the report.

Backport of cc8aa6bf9c127a493e6dd005012b9e6397b3f319 from main

Note: See TracTickets for help on using tickets.
Back to Top