]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- MySQL boolean symbols "true", "false" work again. 0.9's change
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 5 Sep 2014 20:44:42 +0000 (16:44 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 5 Sep 2014 20:44:42 +0000 (16:44 -0400)
in :ticket:`2682` disallowed the MySQL dialect from making use of the
"true" and "false" symbols in the context of "IS" / "IS NOT", but
MySQL supports this syntax even though it has no boolean type.
MySQL remains "non native boolean", but the :func:`.true`
and :func:`.false` symbols again produce the
keywords "true" and "false", so that an expression like
``column.is_(true())`` again works on MySQL.
fixes #3186

doc/build/changelog/changelog_10.rst
doc/build/changelog/migration_10.rst
lib/sqlalchemy/dialects/mysql/base.py
test/dialect/mysql/test_query.py

index e9b78fe78663c9fb951a726ae186e45c98ab60b1..55a2756598e67ad1908a394009da3a63548f548d 100644 (file)
     series as well.  For changes that are specific to 1.0 with an emphasis
     on compatibility concerns, see :doc:`/changelog/migration_10`.
 
+    .. change::
+        :tags: bug, mysql
+        :tickets: 3186
+
+        MySQL boolean symbols "true", "false" work again.  0.9's change
+        in :ticket:`2682` disallowed the MySQL dialect from making use of the
+        "true" and "false" symbols in the context of "IS" / "IS NOT", but
+        MySQL supports this syntax even though it has no boolean type.
+        MySQL remains "non native boolean", but the :func:`.true`
+        and :func:`.false` symbols again produce the
+        keywords "true" and "false", so that an expression like
+        ``column.is_(true())`` again works on MySQL.
+
+        .. seealso::
+
+            :ref:`bug_3186`
+
     .. change::
         :tags: changed, mssql
         :tickets: 3182
index 58aa42df064861097a0c494c83b1c96c36eb82ab..2b9e5f0fd59d188fb682cfc2778b46d6a113daf7 100644 (file)
@@ -808,6 +808,25 @@ a cursor to be closed unless all results are fully fetched.
 
 :ticket:`2515`
 
+.. _bug_3186:
+
+MySQL boolean symbols "true", "false" work again
+------------------------------------------------
+
+0.9's overhaul of the IS/IS NOT operators as well as boolean types in
+:ticket:`2682` disallowed the MySQL dialect from making use of the
+"true" and "false" symbols in the context of "IS" / "IS NOT".  Apparently,
+even though MySQL has no "boolean" type, it supports IS / IS NOT when the
+special "true" and "false" symbols are used, even though these are otherwise
+synonymous with "1" and "0" (and IS/IS NOT don't work with the numerics).
+
+So the change here is that the MySQL dialect remains "non native boolean",
+but the :func:`.true` and :func:`.false` symbols again produce the
+keywords "true" and "false", so that an expression like ``column.is_(true())``
+again works on MySQL.
+
+:ticket:`3186`
+
 .. _change_3182:
 
 PyODBC driver name is required with hostname-based SQL Server connections
index 4dccd2760eb3059be120277e39bef7225dd098ce..247b7a1434061fe6250be9525fc573e043d4a7d6 100644 (file)
@@ -1637,6 +1637,14 @@ class MySQLCompiler(compiler.SQLCompiler):
             value = value.replace('\\', '\\\\')
         return value
 
+    # override native_boolean=False behavior here, as
+    # MySQL still supports native boolean
+    def visit_true(self, element, **kw):
+        return "true"
+
+    def visit_false(self, element, **kw):
+        return "false"
+
     def get_select_precolumns(self, select):
         """Add special MySQL keywords in place of DISTINCT.
 
@@ -2215,6 +2223,10 @@ class MySQLDialect(default.DefaultDialect):
     name = 'mysql'
     supports_alter = True
 
+    # MySQL has no true "boolean" type; we
+    # allow for the "true" and "false" keywords, however
+    supports_native_boolean = False
+
     # identifiers are 64, however aliases can be 255...
     max_identifier_length = 255
     max_index_name_length = 64
index dd11fe2b4965af30b2f2f74029513091df876b50..e085d86c125af917fcbbe5d57310a4414a26d2d3 100644 (file)
@@ -1,11 +1,32 @@
 # coding: utf-8
 
-from sqlalchemy.testing import eq_
+from sqlalchemy.testing import eq_, is_
 from sqlalchemy import *
 from sqlalchemy.testing import fixtures, AssertsCompiledSQL
 from sqlalchemy import testing
 
 
+class IdiosyncrasyTest(fixtures.TestBase, AssertsCompiledSQL):
+    __only_on__ = 'mysql'
+    __backend__ = True
+
+    def test_is_boolean_symbols_despite_no_native(self):
+        is_(
+            testing.db.scalar(select([cast(true().is_(true()), Boolean)])),
+            True
+        )
+
+        is_(
+            testing.db.scalar(select([cast(true().isnot(true()), Boolean)])),
+            False
+        )
+
+        is_(
+            testing.db.scalar(select([cast(false().is_(false()), Boolean)])),
+            True
+        )
+
+
 class MatchTest(fixtures.TestBase, AssertsCompiledSQL):
     __only_on__ = 'mysql'
     __backend__ = True