[1.5.x] Fixed Oracle failure for "%" in table name

Backpatch of 2249bd275c
This commit is contained in:
Anssi Kääriäinen 2012-10-27 04:51:14 +03:00
parent c902623d50
commit 18357bf3ac
3 changed files with 19 additions and 4 deletions

View File

@ -256,6 +256,10 @@ WHEN (new.%(col_name)s IS NULL)
if not name.startswith('"') and not name.endswith('"'): if not name.startswith('"') and not name.endswith('"'):
name = '"%s"' % util.truncate_name(name.upper(), name = '"%s"' % util.truncate_name(name.upper(),
self.max_name_length()) self.max_name_length())
# Oracle puts the query text into a (query % args) construct, so % signs
# in names need to be escaped. The '%%' will be collapsed back to '%' at
# that stage so we aren't really making the name longer here.
name = name.replace('%','%%')
return name.upper() return name.upper()
def random_function_sql(self): def random_function_sql(self):

View File

@ -25,6 +25,14 @@ from . import models
class OracleChecks(unittest.TestCase): class OracleChecks(unittest.TestCase):
@unittest.skipUnless(connection.vendor == 'oracle',
"No need to check Oracle quote_name semantics")
def test_quote_name(self):
# Check that '%' chars are escaped for query execution.
name = '"SOME%NAME"'
quoted_name = connection.ops.quote_name(name)
self.assertEquals(quoted_name % (), name)
@unittest.skipUnless(connection.vendor == 'oracle', @unittest.skipUnless(connection.vendor == 'oracle',
"No need to check Oracle cursor semantics") "No need to check Oracle cursor semantics")
def test_dbms_session(self): def test_dbms_session(self):

View File

@ -1,6 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.core.management import call_command from django.core.management import call_command
from django.db import connection
from django.test import TestCase, skipUnlessDBFeature from django.test import TestCase, skipUnlessDBFeature
from django.utils.six import StringIO from django.utils.six import StringIO
@ -60,14 +61,16 @@ class InspectDBTestCase(TestCase):
self.assertIn("number_45extra = models.CharField", output) self.assertIn("number_45extra = models.CharField", output)
def test_special_column_name_introspection(self): def test_special_column_name_introspection(self):
"""Introspection of column names containing special characters, """
Introspection of column names containing special characters,
unsuitable for Python identifiers unsuitable for Python identifiers
""" """
out = StringIO() out = StringIO()
call_command('inspectdb', stdout=out) call_command('inspectdb', stdout=out)
output = out.getvalue() output = out.getvalue()
base_name = 'Field' if connection.vendor != 'oracle' else 'field'
self.assertIn("field = models.IntegerField()", output) self.assertIn("field = models.IntegerField()", output)
self.assertIn("field_field = models.IntegerField(db_column='Field_')", output) self.assertIn("field_field = models.IntegerField(db_column='%s_')" % base_name, output)
self.assertIn("field_field_0 = models.IntegerField(db_column='Field__')", output) self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output)
self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output) self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output)
self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output) self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output)