]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- VARCHAR/NVARCHAR will not render without a length, raises
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 22 Nov 2009 22:11:41 +0000 (22:11 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 22 Nov 2009 22:11:41 +0000 (22:11 +0000)
an error before passing to MySQL.   Doesn't impact
CAST since VARCHAR is not allowed in MySQL CAST anyway,
the dialect renders CHAR/NCHAR in those cases.
[ticket:1252]

CHANGES
lib/sqlalchemy/dialects/mysql/base.py
test/dialect/test_mysql.py
test/sql/test_types.py

diff --git a/CHANGES b/CHANGES
index 989e6145d1f44cdbf3ad97949ffc70c65d18e450..0f19a1f0e446d72e8b5ac9610d5f91532f2123ee 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -513,6 +513,11 @@ CHANGES
     - New dialects: oursql, a new native dialect, 
       MySQL Connector/Python, a native Python port of MySQLdb,
       and of course zxjdbc on Jython.
+    
+    - VARCHAR/NVARCHAR will not render without a length, raises
+      an error before passing to MySQL.   Doesn't impact 
+      CAST since VARCHAR is not allowed in MySQL CAST anyway,
+      the dialect renders CHAR/NCHAR in those cases.
       
     - all the _detect_XXX() functions now run once underneath
       dialect.initialize()
index a9acc2a013aba1b5970821fac669a926c1fd76ec..d5ee4f5bb4c329dbc95f768e6c0e7060abfbbe82 100644 (file)
@@ -1561,19 +1561,28 @@ class MySQLTypeCompiler(compiler.GenericTypeCompiler):
         if type_.length:
             return self._extend_string(type_, {}, "VARCHAR(%d)" % type_.length)
         else:
-            return self._extend_string(type_, {}, "VARCHAR")
+            raise exc.InvalidRequestError("VARCHAR requires a length when rendered on MySQL")
     
     def visit_CHAR(self, type_):
-        return self._extend_string(type_, {'national':True}, "CHAR(%(length)s)" % {'length' : type_.length})
-
+        if type_.length:
+            return self._extend_string(type_, {}, "CHAR(%(length)s)" % {'length' : type_.length})
+        else:
+            return self._extend_string(type_, {}, "CHAR")
+            
     def visit_NVARCHAR(self, type_):
         # We'll actually generate the equiv. "NATIONAL VARCHAR" instead
         # of "NVARCHAR".
-        return self._extend_string(type_, {'national':True}, "VARCHAR(%(length)s)" % {'length': type_.length})
+        if type_.length:
+            return self._extend_string(type_, {'national':True}, "VARCHAR(%(length)s)" % {'length': type_.length})
+        else:
+            raise exc.InvalidRequestError("NVARCHAR requires a length when rendered on MySQL")
     
     def visit_NCHAR(self, type_):
         # We'll actually generate the equiv. "NATIONAL CHAR" instead of "NCHAR".
-        return self._extend_string(type_, {'national':True}, "CHAR(%(length)s)" % {'length': type_.length})
+        if type_.length:
+            return self._extend_string(type_, {'national':True}, "CHAR(%(length)s)" % {'length': type_.length})
+        else:
+            return self._extend_string(type_, {'national':True}, "CHAR")
     
     def visit_VARBINARY(self, type_):
         if type_.length:
index b65ab6312df06c24bfadff84a4a6722b481495ae..325f518daa8779f5a2e1cc0ad6f9737c62a574c1 100644 (file)
@@ -7,7 +7,7 @@ import sets
 # end Py2K
 
 from sqlalchemy import *
-from sqlalchemy import sql, exc, schema
+from sqlalchemy import sql, exc, schema, types as sqltypes
 from sqlalchemy.dialects.mysql import base as mysql
 from sqlalchemy.test.testing import eq_
 from sqlalchemy.test import *
@@ -948,7 +948,20 @@ class SQLTest(TestBase, AssertsCompiledSQL):
             select([t]).offset(10),
             "SELECT t.col1, t.col2 FROM t  LIMIT 10, 18446744073709551615"
             )
-
+    
+    def test_varchar_raise(self):
+        for type_ in (
+            String,
+            VARCHAR,
+            String(),
+            VARCHAR(),
+            NVARCHAR(),
+            Unicode,
+            Unicode(),
+        ):
+            type_ = sqltypes.to_instance(type_)
+            assert_raises(exc.InvalidRequestError, type_.compile, dialect=mysql.dialect())
+            
     def test_update_limit(self):
         t = sql.table('t', sql.column('col1'), sql.column('col2'))
 
index 332e02ef5f9b90562ca798ec711d0e0c79d9f408..04c193e01f569ebe9ff6416555fc9295690e6791 100644 (file)
@@ -42,8 +42,8 @@ class AdaptTest(TestBase):
                 (DATE, "DATE"),
                 (TIME, "TIME"),
                 (CLOB, "CLOB"),
-                (VARCHAR, "VARCHAR"),
-                (NVARCHAR, ("NVARCHAR", "NATIONAL VARCHAR")),
+                (VARCHAR(10), "VARCHAR(10)"),
+                (NVARCHAR(10), ("NVARCHAR(10)", "NATIONAL VARCHAR(10)", "NVARCHAR2(10)")),
                 (CHAR, "CHAR"),
                 (NCHAR, ("NCHAR", "NATIONAL CHAR")),
                 (BLOB, "BLOB"),
@@ -52,7 +52,7 @@ class AdaptTest(TestBase):
                 if isinstance(expected, str):
                     expected = (expected, )
                 for exp in expected:
-                    compiled = type_().compile(dialect=dialect)
+                    compiled = types.to_instance(type_).compile(dialect=dialect)
                     if exp in compiled:
                         break
                 else: