Skip to content

Commit

Permalink
[3.0.x] Fixed #31312 -- Properly ordered temporal subtraction params …
Browse files Browse the repository at this point in the history
…on MySQL.

Regression in 9bcbcd5.

Thanks rick2ricks for the report.

Backport of 41ebe60 from master
  • Loading branch information
charettes authored and felixxm committed Feb 27, 2020
1 parent 59ac25c commit 16cacdc
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
2 changes: 1 addition & 1 deletion django/db/backends/mysql/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ def subtract_temporals(self, internal_type, lhs, rhs):
"((TIME_TO_SEC(%(lhs)s) * 1000000 + MICROSECOND(%(lhs)s)) -"
" (TIME_TO_SEC(%(rhs)s) * 1000000 + MICROSECOND(%(rhs)s)))"
) % {'lhs': lhs_sql, 'rhs': rhs_sql}, tuple(lhs_params) * 2 + tuple(rhs_params) * 2
params = (*lhs_params, *rhs_params)
params = (*rhs_params, *lhs_params)
return "TIMESTAMPDIFF(MICROSECOND, %s, %s)" % (rhs_sql, lhs_sql), params

def explain_query_prefix(self, format=None, **options):
Expand Down
4 changes: 4 additions & 0 deletions docs/releases/3.0.4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ Bugfixes

* Fixed a regression in Django 3.0 that caused misplacing parameters in logged
SQL queries on Oracle (:ticket:`31271`).

* Fixed a regression in Django 3.0.3 that caused misplacing parameters of SQL
queries when subtracting ``DateField`` or ``DateTimeField`` expressions on
MySQL (:ticket:`31312`).
23 changes: 20 additions & 3 deletions tests/expressions/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1221,13 +1221,13 @@ def setUpTestData(cls):

# e0: started same day as assigned, zero duration
end = stime + delta0
e0 = Experiment.objects.create(
cls.e0 = Experiment.objects.create(
name='e0', assigned=sday, start=stime, end=end,
completed=end.date(), estimated_time=delta0,
)
cls.deltas.append(delta0)
cls.delays.append(e0.start - datetime.datetime.combine(e0.assigned, midnight))
cls.days_long.append(e0.completed - e0.assigned)
cls.delays.append(cls.e0.start - datetime.datetime.combine(cls.e0.assigned, midnight))
cls.days_long.append(cls.e0.completed - cls.e0.assigned)

# e1: started one day after assigned, tiny duration, data
# set so that end time has no fractional seconds, which
Expand Down Expand Up @@ -1434,6 +1434,23 @@ def test_date_subquery_subtraction(self):
).filter(difference=datetime.timedelta())
self.assertTrue(queryset.exists())

@skipUnlessDBFeature('supports_temporal_subtraction')
def test_date_case_subtraction(self):
queryset = Experiment.objects.annotate(
date_case=Case(
When(Q(name='e0'), then=F('completed')),
output_field=DateField(),
),
completed_value=Value(
self.e0.completed,
output_field=DateField(),
),
difference=ExpressionWrapper(
F('date_case') - F('completed_value'), output_field=DurationField(),
),
).filter(difference=datetime.timedelta())
self.assertEqual(queryset.get(), self.e0)

@skipUnlessDBFeature('supports_temporal_subtraction')
def test_time_subtraction(self):
Time.objects.create(time=datetime.time(12, 30, 15, 2345))
Expand Down

0 comments on commit 16cacdc

Please sign in to comment.