Opened 17 months ago

Closed 16 months ago

Last modified 16 months ago

#27828 closed Bug (fixed)

ORM crash on F('date_field') - F('int_field') on PostgreSQL

Reported by: Vytis Banaitis Owned by: Vytis Banaitis
Component: Database layer (models, ORM) Version: 1.10
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

PostgreSQL allows to use subtraction with a date and an int, returning a date. The integer is taken as a time delta in days.

I was trying to use this in Django.

class DateModel(models.Model):
    date_field = models.DateField()
    int_field = models.IntegerField()
In [3]: qs = DateModel.objects.annotate(result=ExpressionWrapper(F('date_field') - F('int_field'), output_field=DateField()))

However, this query crashes:

In [4]: qs.all()
Out[4]: ---------------------------------------------------------------------------
ProgrammingError                          Traceback (most recent call last)
/home/vytis/src/django/django/db/backends/utils.py in execute(self, sql, params)
     61             else:
---> 62                 return self.cursor.execute(sql, params)
     63 

ProgrammingError: function age(date, integer) does not exist
LINE 1: ...del"."date_field", "myapp_datemodel"."int_field", age("myapp...
                                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

Generated SQL:

SELECT "myapp_datemodel"."id", "myapp_datemodel"."date_field", "myapp_datemodel"."int_field", age("myapp_datemodel"."date_field", "myapp_datemodel"."int_field") AS "result" FROM "myapp_datemodel"

While looking for a solution, I came across a typo in django/db/models/expressions.py (introduced in 766afc22):
https://github.com/django/django/blob/9718fa2e8abe430c3526a9278dd976443d4ae3c6/django/db/models/expressions.py#L386
Note the lhs_output on both sides of operation.

Fixing this typo resolves the crash.

Change History (5)

comment:1 Changed 17 months ago by Vytis Banaitis

Has patch: set
Owner: changed from nobody to Vytis Banaitis
Status: newassigned

comment:2 Changed 17 months ago by Tim Graham

Triage Stage: UnreviewedAccepted

comment:3 Changed 16 months ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In d5088f83:

Fixed #27828 -- Fixed a crash when subtracting Integer/DurationField from DateField on Oracle/PostgreSQL.

comment:4 Changed 16 months ago by Tim Graham <timograham@…>

In eedf276e:

[1.11.x] Fixed #27828 -- Fixed a crash when subtracting Integer/DurationField from DateField on Oracle/PostgreSQL.

Backport of d5088f838d837fc9e3109c828f18511055f20bea from master

comment:5 Changed 16 months ago by Tim Graham <timograham@…>

In 75327b88:

[1.10.x] Fixed #27828 -- Fixed a crash when subtracting Integer/DurationField from DateField on Oracle/PostgreSQL.

Thanks Mariusz Felisiak for the Oracle workaround.

Backport of d5088f838d837fc9e3109c828f18511055f20bea from master

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