mirror of https://github.com/django/django.git
Fixed #24959 -- Fixed queries using negative timedeltas on MySQL and Oracle.
This commit is contained in:
parent
2742901ac2
commit
b63d0c54b0
|
@ -94,8 +94,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
return "TIME(%s)" % (field_name)
|
return "TIME(%s)" % (field_name)
|
||||||
|
|
||||||
def date_interval_sql(self, timedelta):
|
def date_interval_sql(self, timedelta):
|
||||||
return "INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND" % (
|
return "INTERVAL '%06f' SECOND_MICROSECOND" % (timedelta.total_seconds()), []
|
||||||
timedelta.days, timedelta.seconds, timedelta.microseconds), []
|
|
||||||
|
|
||||||
def format_for_duration_arithmetic(self, sql):
|
def format_for_duration_arithmetic(self, sql):
|
||||||
if self.connection.features.supports_microsecond_precision:
|
if self.connection.features.supports_microsecond_precision:
|
||||||
|
|
|
@ -93,16 +93,9 @@ WHEN (new.%(col_name)s IS NULL)
|
||||||
|
|
||||||
def date_interval_sql(self, timedelta):
|
def date_interval_sql(self, timedelta):
|
||||||
"""
|
"""
|
||||||
Implements the interval functionality for expressions
|
NUMTODSINTERVAL converts number to INTERVAL DAY TO SECOND literal.
|
||||||
format for Oracle:
|
|
||||||
INTERVAL '3 00:03:20.000000' DAY(1) TO SECOND(6)
|
|
||||||
"""
|
"""
|
||||||
minutes, seconds = divmod(timedelta.seconds, 60)
|
return "NUMTODSINTERVAL(%06f, 'SECOND')" % (timedelta.total_seconds()), []
|
||||||
hours, minutes = divmod(minutes, 60)
|
|
||||||
days = str(timedelta.days)
|
|
||||||
day_precision = len(days)
|
|
||||||
fmt = "INTERVAL '%s %02d:%02d:%02d.%06d' DAY(%d) TO SECOND(6)"
|
|
||||||
return fmt % (days, hours, minutes, seconds, timedelta.microseconds, day_precision), []
|
|
||||||
|
|
||||||
def date_trunc_sql(self, lookup_type, field_name):
|
def date_trunc_sql(self, lookup_type, field_name):
|
||||||
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
|
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
|
||||||
|
|
|
@ -1043,6 +1043,26 @@ class FTimeDeltaTests(TestCase):
|
||||||
).order_by('name')
|
).order_by('name')
|
||||||
self.assertQuerysetEqual(over_estimate, ['e3', 'e4'], lambda e: e.name)
|
self.assertQuerysetEqual(over_estimate, ['e3', 'e4'], lambda e: e.name)
|
||||||
|
|
||||||
|
def test_negative_timedelta_update(self):
|
||||||
|
# subtract 30 seconds, 30 minutes, 2 hours and 2 days
|
||||||
|
experiments = Experiment.objects.filter(name='e0').annotate(
|
||||||
|
start_sub_seconds=F('start') + datetime.timedelta(seconds=-30),
|
||||||
|
).annotate(
|
||||||
|
start_sub_minutes=F('start_sub_seconds') + datetime.timedelta(minutes=-30),
|
||||||
|
).annotate(
|
||||||
|
start_sub_hours=F('start_sub_minutes') + datetime.timedelta(hours=-2),
|
||||||
|
).annotate(
|
||||||
|
new_start=F('start_sub_hours') + datetime.timedelta(days=-2),
|
||||||
|
)
|
||||||
|
expected_start = datetime.datetime(2010, 6, 23, 9, 45, 0)
|
||||||
|
if connection.features.supports_microsecond_precision:
|
||||||
|
# subtract 30 microseconds
|
||||||
|
experiments = experiments.annotate(new_start=F('new_start') + datetime.timedelta(microseconds=-30))
|
||||||
|
expected_start += datetime.timedelta(microseconds=+746970)
|
||||||
|
experiments.update(start=F('new_start'))
|
||||||
|
e0 = Experiment.objects.get(name='e0')
|
||||||
|
self.assertEqual(e0.start, expected_start)
|
||||||
|
|
||||||
|
|
||||||
class ValueTests(TestCase):
|
class ValueTests(TestCase):
|
||||||
def test_update_TimeField_using_Value(self):
|
def test_update_TimeField_using_Value(self):
|
||||||
|
|
Loading…
Reference in New Issue