From 77b269e875661d72ba7fc0926a5bb8d3d6d8b09d Mon Sep 17 00:00:00 2001 From: Ian Kelly Date: Tue, 21 Jul 2009 21:25:48 +0000 Subject: [PATCH] Fixed #11487: pass long strings to Oracle as CLOB rather than NCLOB to prevent an encoding bug that occurs in some installations. Backport of [11285] from trunk. git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@11286 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/backends/oracle/base.py | 6 +++--- tests/regressiontests/backends/tests.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 29201cef11..1f60a1a515 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -319,7 +319,7 @@ class OracleParam(object): """ Wrapper object for formatting parameters for Oracle. If the string representation of the value is large enough (greater than 4000 characters) - the input size needs to be set as NCLOB. Alternatively, if the parameter + the input size needs to be set as CLOB. Alternatively, if the parameter has an `input_size` attribute, then the value of the `input_size` attribute will be used instead. Otherwise, no input size will be set for the parameter when executing the query. @@ -331,8 +331,8 @@ class OracleParam(object): # If parameter has `input_size` attribute, use that. self.input_size = param.input_size elif isinstance(param, basestring) and len(param) > 4000: - # Mark any string param greater than 4000 characters as an NCLOB. - self.input_size = Database.NCLOB + # Mark any string param greater than 4000 characters as a CLOB. + self.input_size = Database.CLOB else: self.input_size = None diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py index 5dec9feee6..03fc3ff7cd 100644 --- a/tests/regressiontests/backends/tests.py +++ b/tests/regressiontests/backends/tests.py @@ -20,7 +20,21 @@ class Callproc(unittest.TestCase): return True else: return True + +class LongString(unittest.TestCase): + def test_long_string(self): + # If the backend is Oracle, test that we can save a text longer + # than 4000 chars and read it properly + if settings.DATABASE_ENGINE == 'oracle': + c = connection.cursor() + c.execute('CREATE TABLE ltext ("TEXT" NCLOB)') + long_str = ''.join([unicode(x) for x in xrange(4000)]) + c.execute('INSERT INTO ltext VALUES (%s)',[long_str]) + c.execute('SELECT text FROM ltext') + row = c.fetchone() + c.execute('DROP TABLE ltext') + self.assertEquals(long_str, row[0].read()) if __name__ == '__main__': unittest.main()