diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 64e038e1a6..b90f6ea155 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -479,13 +479,19 @@ class DatabaseWrapper(BaseDatabaseWrapper): del conn_params['use_returning_into'] self.connection = Database.connect(conn_string, **conn_params) cursor = FormatStylePlaceholderCursor(self.connection) + # Set the territory first. The territory overrides NLS_DATE_FORMAT + # and NLS_TIMESTAMP_FORMAT to the territory default. When all of + # these are set in single statement it isn't clear what is supposed + # to happen. + cursor.execute("ALTER SESSION SET NLS_TERRITORY = 'AMERICA'") # Set oracle date to ansi date format. This only needs to execute # once when we create a new connection. We also set the Territory - # to 'AMERICA' which forces Sunday to evaluate to a '1' in TO_CHAR(). - cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" - " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'" - " NLS_TERRITORY = 'AMERICA'" - + (" TIME_ZONE = 'UTC'" if settings.USE_TZ else '')) + # to 'AMERICA' which forces Sunday to evaluate to a '1' in + # TO_CHAR(). + cursor.execute( + "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" + " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'" + + (" TIME_ZONE = 'UTC'" if settings.USE_TZ else '')) if 'operators' not in self.__dict__: # Ticket #14149: Check whether our LIKE implementation will diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py index c6d28ab135..cb25ac0a32 100644 --- a/tests/regressiontests/backends/tests.py +++ b/tests/regressiontests/backends/tests.py @@ -66,6 +66,18 @@ class OracleChecks(unittest.TestCase): self.assertEqual(connection.connection.encoding, "UTF-8") self.assertEqual(connection.connection.nencoding, "UTF-8") + @unittest.skipUnless(connection.vendor == 'oracle', + "No need to check Oracle connection semantics") + def test_order_of_nls_parameters(self): + # an 'almost right' datetime should work with configured + # NLS parameters as per #18465. + c = connection.cursor() + query = "select 1 from dual where '1936-12-29 00:00' < sysdate" + # Test that the query succeeds without errors - pre #18465 this + # wasn't the case. + c.execute(query) + self.assertEqual(c.fetchone()[0], 1) + class MySQLTests(TestCase): @unittest.skipUnless(connection.vendor == 'mysql', "Test valid only for MySQL")