summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2021-05-07 08:46:22 +0200
committerCarlton Gibson <carlton@noumenal.es>2021-05-11 09:19:25 +0200
commitb1a4b1f0bdf05adbd3dc4dde14228e68da54c1a3 (patch)
treeb940d09f1b6d4e8070821f475b72488daf48a3f5
parent205c36b58fed5a1a0ff462593fc61b58189027d8 (diff)
Fixed #32722 -- Fixed comparing to TruncTime() on Oracle.
-rw-r--r--django/db/backends/oracle/features.py4
-rw-r--r--django/db/backends/oracle/operations.py12
-rw-r--r--tests/db_functions/datetime/test_extract_trunc.py21
3 files changed, 24 insertions, 13 deletions
diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py
index 604f2316bc..07f16eee71 100644
--- a/django/db/backends/oracle/features.py
+++ b/django/db/backends/oracle/features.py
@@ -87,10 +87,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
'Raises ORA-00600: internal error code.': {
'model_fields.test_jsonfield.TestQuerying.test_usage_in_subquery',
},
- "Comparing to TruncTime() doesn't work on Oracle (#32722).": {
- 'db_functions.datetime.test_extract_trunc.DateFunctionWithTimeZoneTests.test_trunc_time_no_microseconds',
- 'db_functions.datetime.test_extract_trunc.DateFunctionTests.test_trunc_time_no_microseconds',
- },
}
django_test_expected_failures = {
# A bug in Django/cx_Oracle with respect to string handling (#23843).
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index d48c8dd868..095a125ced 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -135,9 +135,15 @@ END;
return 'TRUNC(%s)' % field_name
def datetime_cast_time_sql(self, field_name, tzname):
- # Since `TimeField` values are stored as TIMESTAMP where only the date
- # part is ignored, convert the field to the specified timezone.
- return self._convert_field_to_tz(field_name, tzname)
+ # Since `TimeField` values are stored as TIMESTAMP change to the
+ # default date and convert the field to the specified timezone.
+ convert_datetime_sql = (
+ "TO_TIMESTAMP(CONCAT('1900-01-01 ', TO_CHAR(%s, 'HH24:MI:SS.FF')), "
+ "'YYYY-MM-DD HH24:MI:SS.FF')"
+ ) % self._convert_field_to_tz(field_name, tzname)
+ return "CASE WHEN %s IS NOT NULL THEN %s ELSE NULL END" % (
+ field_name, convert_datetime_sql,
+ )
def datetime_extract_sql(self, lookup_type, field_name, tzname):
field_name = self._convert_field_to_tz(field_name, tzname)
diff --git a/tests/db_functions/datetime/test_extract_trunc.py b/tests/db_functions/datetime/test_extract_trunc.py
index 75b8a4f0f9..fe80904330 100644
--- a/tests/db_functions/datetime/test_extract_trunc.py
+++ b/tests/db_functions/datetime/test_extract_trunc.py
@@ -923,19 +923,28 @@ class DateFunctionTests(TestCase):
self.create_model(None, None)
self.assertIsNone(DTModel.objects.annotate(truncated=TruncTime('start_datetime')).first().truncated)
- def test_trunc_time_no_microseconds(self):
- start_datetime = datetime(2015, 6, 15, 14, 30, 26)
+ def test_trunc_time_comparison(self):
+ start_datetime = datetime(2015, 6, 15, 14, 30, 26) # 0 microseconds.
+ end_datetime = datetime(2015, 6, 15, 14, 30, 26, 321)
if settings.USE_TZ:
start_datetime = timezone.make_aware(start_datetime, is_dst=False)
- self.create_model(start_datetime, None)
+ end_datetime = timezone.make_aware(end_datetime, is_dst=False)
+ self.create_model(start_datetime, end_datetime)
self.assertIs(
- DTModel.objects.filter(start_datetime__time=start_datetime.time()).exists(),
+ DTModel.objects.filter(
+ start_datetime__time=start_datetime.time(),
+ end_datetime__time=end_datetime.time(),
+ ).exists(),
True,
)
self.assertIs(
DTModel.objects.annotate(
- extracted=TruncTime('start_datetime'),
- ).filter(extracted=start_datetime.time()).exists(),
+ extracted_start=TruncTime('start_datetime'),
+ extracted_end=TruncTime('end_datetime'),
+ ).filter(
+ extracted_start=start_datetime.time(),
+ extracted_end=end_datetime.time(),
+ ).exists(),
True,
)