#29396 closed Bug (fixed)
The __year lookp crashes with IndexError when passed a non-direct values/expression.
| Reported by: | Dmitry Shachnev | Owned by: | Windson yang |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description
With the following models:
class ModelWithDate(models.Model): id = models.AutoField(primary_key=True) date = models.DateField() class ModelWithYear(models.Model): id = models.AutoField(primary_key=True) year = models.IntegerField() date_ref = models.ForeignKey(to=ModelWithDate, on_delete=models.CASCADE)
the following code:
>>> dates = ModelWithDate.objects.filter(date__year__gte=OuterRef("year")) >>> dates_subq = Subquery(dates.values("id")) >>> ModelWithYear.objects.filter(date_ref__in=dates_subq)
causes an exception:
Traceback (most recent call last): ... File "/usr/lib/python3/dist-packages/django/db/models/lookups.py", line 90, in process_rhs sql, params = compiler.compile(value) File "/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py", line 391, in compile sql, params = node.as_sql(self, self.connection) File "/usr/lib/python3/dist-packages/django/db/models/expressions.py", line 1041, in as_sql template_params['subquery'], sql_params = self.queryset.query.get_compiler(connection=connection).as_sql() File "/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py", line 459, in as_sql where, w_params = self.compile(self.where) if self.where is not None else ("", []) File "/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py", line 391, in compile sql, params = node.as_sql(self, self.connection) File "/usr/lib/python3/dist-packages/django/db/models/sql/where.py", line 80, in as_sql sql, params = compiler.compile(child) File "/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py", line 391, in compile sql, params = node.as_sql(self, self.connection) File "/usr/lib/python3/dist-packages/django/db/models/lookups.py", line 523, in as_sql start, finish = self.year_lookup_bounds(connection, rhs_params[0]) IndexError: list index out of range
The same happens if I create an annotation using ExtractYear and use it directly.
A small test project is attached. The bug can be reproduced with “DJANGO_SETTINGS_MODULE=settings python3 ./test.py”. Tested with Django 2.0.5 and 1.11.13.
Attachments (1)
Change History (10)
by , 8 years ago
| Attachment: | test-project.tar.gz added |
|---|
comment:1 by , 8 years ago
I should add that it happens only with gte/lte comparisons. If I replace date__year__gte with date__year__exact, then the code works as expected.
comment:2 by , 8 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|---|
| Version: | → master |
Reproduced on master at 9c4ea63e878c053600c284e32d5f32d27a59b63a.
comment:3 by , 7 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:4 by , 7 years ago
Please tell me if I'm doing wrong, Just like YearExact, We should adding the same try-except block to handle when rhs_params[0] doesn't exist. In the except part, should we just raise an error like below? Or we have to overwrite GreaterThanOrEqual and LessThanOrEqual class?
raise ValueError(
'The QuerySet value for an exact lookup must be limited to '
'one result using slicing.'
)
comment:6 by , 7 years ago
| Has patch: | set |
|---|---|
| Patch needs improvement: | set |
comment:7 by , 6 years ago
| Summary: | Using date__year comparisons together with OuterRef causes an IndexError → The __year lookp crashes with IndexError when passed a non-direct values/expression. |
|---|
As I commented on the PR the bug has little to do with subquery usage; __year lookup simply never supported non-direct values and OuterRef happens to implement the expression API in this particular case.
Both this issue and #30494 which was for the year__exact case are handled by https://github.com/django/django/pull/11393.
Test project to reproduce the bug