]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- The String type now generates VARCHAR2 on Oracle
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 24 Sep 2011 15:02:29 +0000 (11:02 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 24 Sep 2011 15:02:29 +0000 (11:02 -0400)
    which is recommended as the default VARCHAR.
    Added an explicit VARCHAR2 and NVARCHAR2 to the Oracle
    dialect as well.   Using NVARCHAR still generates
    "NVARCHAR2" - there is no "NVARCHAR" on Oracle -
    this remains a slight breakage of the "uppercase types
    always give exactly that" policy.  VARCHAR still
    generates "VARCHAR", keeping with the policy.   If
    Oracle were to ever define "VARCHAR" as something
    different as they claim (IMHO this will never happen),
    the type would be available.  [ticket:2252]

CHANGES
lib/sqlalchemy/dialects/oracle/base.py
test/dialect/test_oracle.py

diff --git a/CHANGES b/CHANGES
index d3a5e4a33f3dcd2df5763690d4c35c519d001448..7b5b76089c6b3b2f81d7ae3eb0174c610971ff4a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -238,6 +238,18 @@ CHANGES
   - Fixed ReturningResultProxy for zxjdbc dialect.
     [ticket:2272].  Regression from 0.6.
 
+  - The String type now generates VARCHAR2 on Oracle
+    which is recommended as the default VARCHAR.
+    Added an explicit VARCHAR2 and NVARCHAR2 to the Oracle
+    dialect as well.   Using NVARCHAR still generates
+    "NVARCHAR2" - there is no "NVARCHAR" on Oracle -
+    this remains a slight breakage of the "uppercase types
+    always give exactly that" policy.  VARCHAR still 
+    generates "VARCHAR", keeping with the policy.   If
+    Oracle were to ever define "VARCHAR" as something 
+    different as they claim (IMHO this will never happen), 
+    the type would be available.  [ticket:2252]
+
 - ext
   - Added local_attr, remote_attr, attr accessors
     to AssociationProxy, providing quick access
index ff702085178db78ce71ccbd03f858105dbd5c1ff..91be5a95d132eec7be701156a05a0f257160375b 100644 (file)
@@ -170,7 +170,9 @@ OracleRaw = RAW
 class NCLOB(sqltypes.Text):
     __visit_name__ = 'NCLOB'
 
-VARCHAR2 = VARCHAR
+class VARCHAR2(VARCHAR):
+    __visit_name__ = 'VARCHAR2'
+
 NVARCHAR2 = NVARCHAR
 
 class NUMBER(sqltypes.Numeric, sqltypes.Integer):
@@ -293,9 +295,9 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler):
 
     def visit_unicode(self, type_):
         if self.dialect._supports_nchar:
-            return self.visit_NVARCHAR(type_)
+            return self.visit_NVARCHAR2(type_)
         else:
-            return self.visit_VARCHAR(type_)
+            return self.visit_VARCHAR2(type_)
 
     def visit_INTERVAL(self, type_):
         return "INTERVAL DAY%s TO SECOND%s" % (
@@ -333,14 +335,27 @@ class OracleTypeCompiler(compiler.GenericTypeCompiler):
         else:
             return "%(name)s(%(precision)s, %(scale)s)" % {'name':name,'precision': precision, 'scale' : scale}
 
+    def visit_string(self, type_): 
+        return self.visit_VARCHAR2(type_)
+
+    def visit_VARCHAR2(self, type_):
+        return self._visit_varchar(type_, '', '2')
+
+    def visit_NVARCHAR2(self, type_):
+        return self._visit_varchar(type_, 'N', '2')
+    visit_NVARCHAR = visit_NVARCHAR2
+
     def visit_VARCHAR(self, type_):
-        if self.dialect._supports_char_length:
-            return "VARCHAR(%(length)s CHAR)" % {'length' : type_.length}
-        else:
-            return "VARCHAR(%(length)s)" % {'length' : type_.length}
+        return self._visit_varchar(type_, '', '')
 
-    def visit_NVARCHAR(self, type_):
-        return "NVARCHAR2(%(length)s)" % {'length' : type_.length}
+    def _visit_varchar(self, type_, n, num):
+        if not n and self.dialect._supports_char_length:
+            return "VARCHAR%(two)s(%(length)s CHAR)" % {
+                                                    'length' : type_.length, 
+                                                    'two':num}
+        else:
+            return "%(n)sVARCHAR%(two)s(%(length)s)" % {'length' : type_.length, 
+                                                        'two':num, 'n':n}
 
     def visit_text(self, type_):
         return self.visit_CLOB(type_)
index 4b53500b3590ae6d389af616cfa6c98680329c5a..f12b355932a6e35bb876edd65b9268da63bd7bdd 100644 (file)
@@ -436,8 +436,8 @@ class CompatFlagsTest(fixtures.TestBase, AssertsCompiledSQL):
         assert not dialect._supports_char_length
         assert not dialect._supports_nchar
         assert not dialect.use_ansi
-        self.assert_compile(String(50),"VARCHAR(50)",dialect=dialect)
-        self.assert_compile(Unicode(50),"VARCHAR(50)",dialect=dialect)
+        self.assert_compile(String(50),"VARCHAR2(50)",dialect=dialect)
+        self.assert_compile(Unicode(50),"VARCHAR2(50)",dialect=dialect)
         self.assert_compile(UnicodeText(),"CLOB",dialect=dialect)
 
         dialect = oracle.dialect(implicit_returning=True, 
@@ -454,7 +454,7 @@ class CompatFlagsTest(fixtures.TestBase, AssertsCompiledSQL):
         assert dialect._supports_char_length
         assert dialect._supports_nchar
         assert dialect.use_ansi
-        self.assert_compile(String(50),"VARCHAR(50 CHAR)",dialect=dialect)
+        self.assert_compile(String(50),"VARCHAR2(50 CHAR)",dialect=dialect)
         self.assert_compile(Unicode(50),"NVARCHAR2(50)",dialect=dialect)
         self.assert_compile(UnicodeText(),"NCLOB",dialect=dialect)
 
@@ -467,7 +467,7 @@ class CompatFlagsTest(fixtures.TestBase, AssertsCompiledSQL):
         assert dialect._supports_char_length
         assert dialect._supports_nchar
         assert dialect.use_ansi
-        self.assert_compile(String(50),"VARCHAR(50 CHAR)",dialect=dialect)
+        self.assert_compile(String(50),"VARCHAR2(50 CHAR)",dialect=dialect)
         self.assert_compile(Unicode(50),"NVARCHAR2(50)",dialect=dialect)
         self.assert_compile(UnicodeText(),"NCLOB",dialect=dialect)
 
@@ -1086,7 +1086,19 @@ class TypesTest(fixtures.TestBase, AssertsCompiledSQL):
             eq_(t2.c.c3.type.length, 200)
         finally:
             t1.drop()
+
+    def test_varchar_types(self):
+        dialect = oracle.dialect()
+        for typ, exp in [
+            (String(50), "VARCHAR2(50 CHAR)"),
+            (Unicode(50), "NVARCHAR2(50)"),
+            (NVARCHAR(50), "NVARCHAR2(50)"),
+            (VARCHAR(50), "VARCHAR(50 CHAR)"),
+            (oracle.NVARCHAR2(50), "NVARCHAR2(50)"),
+            (oracle.VARCHAR2(50), "VARCHAR2(50 CHAR)"),
+        ]:
+            self.assert_compile(typ, exp, dialect=dialect)
+
     def test_longstring(self):
         metadata = MetaData(testing.db)
         testing.db.execute("""