Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.2.X] Fixed #14149: Initialize the Oracle connection.operators at c…

…onnection time since some systems don't seem to like the "TRANSLATE" trick.

Backport of r15299 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15300 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5f923671e5e1b5ddce3c19cd195e236df8b7fd88 1 parent 63536a8
Ian Kelly authored January 24, 2011

Showing 1 changed file with 42 additions and 1 deletion. Show diff stats Hide diff stats

  1. 43  django/db/backends/oracle/base.py
43  django/db/backends/oracle/base.py
@@ -335,9 +335,24 @@ def combine_expression(self, connector, sub_expressions):
335 335
         return super(DatabaseOperations, self).combine_expression(connector, sub_expressions)
336 336
 
337 337
 
  338
+class _UninitializedOperatorsDescriptor(object):
  339
+
  340
+    def __get__(self, instance, owner):
  341
+        # If connection.operators is looked up before a connection has been
  342
+        # created, transparently initialize connection.operators to avert an
  343
+        # AttributeError.
  344
+        if instance is None:
  345
+            raise AttributeError("operators not available as class attribute")
  346
+        # Creating a cursor will initialize the operators.
  347
+        instance.cursor().close()
  348
+        return instance.__dict__['operators']
  349
+
  350
+
338 351
 class DatabaseWrapper(BaseDatabaseWrapper):
339 352
 
340  
-    operators = {
  353
+    operators = _UninitializedOperatorsDescriptor()
  354
+
  355
+    _standard_operators = {
341 356
         'exact': '= %s',
342 357
         'iexact': '= UPPER(%s)',
343 358
         'contains': "LIKE TRANSLATE(%s USING NCHAR_CS) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
@@ -352,6 +367,16 @@ class DatabaseWrapper(BaseDatabaseWrapper):
352 367
         'iendswith': "LIKE UPPER(TRANSLATE(%s USING NCHAR_CS)) ESCAPE TRANSLATE('\\' USING NCHAR_CS)",
353 368
     }
354 369
 
  370
+    _likec_operators = _standard_operators.copy()
  371
+    _likec_operators.update({
  372
+        'contains': "LIKEC %s ESCAPE '\\'",
  373
+        'icontains': "LIKEC UPPER(%s) ESCAPE '\\'",
  374
+        'startswith': "LIKEC %s ESCAPE '\\'",
  375
+        'endswith': "LIKEC %s ESCAPE '\\'",
  376
+        'istartswith': "LIKEC UPPER(%s) ESCAPE '\\'",
  377
+        'iendswith': "LIKEC UPPER(%s) ESCAPE '\\'",
  378
+    })
  379
+
355 380
     def __init__(self, *args, **kwargs):
356 381
         super(DatabaseWrapper, self).__init__(*args, **kwargs)
357 382
 
@@ -391,6 +416,22 @@ def _cursor(self):
391 416
             cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS' "
392 417
                            "NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF' "
393 418
                            "NLS_TERRITORY = 'AMERICA'")
  419
+
  420
+            if 'operators' not in self.__dict__:
  421
+                # Ticket #14149: Check whether our LIKE implementation will
  422
+                # work for this connection or we need to fall back on LIKEC.
  423
+                # This check is performed only once per DatabaseWrapper
  424
+                # instance per thread, since subsequent connections will use
  425
+                # the same settings.
  426
+                try:
  427
+                    cursor.execute("SELECT 1 FROM DUAL WHERE DUMMY %s"
  428
+                                   % self._standard_operators['contains'],
  429
+                                   ['X'])
  430
+                except utils.DatabaseError:
  431
+                    self.operators = self._likec_operators
  432
+                else:
  433
+                    self.operators = self._standard_operators
  434
+
394 435
             try:
395 436
                 self.oracle_version = int(self.connection.version.split('.')[0])
396 437
                 # There's no way for the DatabaseOperations class to know the

0 notes on commit 5f92367

Please sign in to comment.
Something went wrong with that request. Please try again.