]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
SQL Server is not native boolean; add new flag for CHECK constraint
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 10 May 2018 15:39:06 +0000 (11:39 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 10 May 2018 19:27:05 +0000 (15:27 -0400)
Fixed a 1.2 regression caused by :ticket:`4061` where the SQL Server
"BIT" type would be considered to be "native boolean".  The goal here
was to avoid creating a CHECK constraint on the column, however the bigger
issue is that the BIT value does not behave like a true/false constant
and cannot be interpreted as a standalone expression, e.g.
"WHERE <column>".   The SQL Server dialect now goes back to being
non-native boolean, but with an extra flag that still avoids creating
the CHECK constraint.

Change-Id: I4765d2a2a00b0d14f50282603cc4d48d4739dac1
Fixes: #4250
doc/build/changelog/unreleased_12/4250.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/mssql/base.py
lib/sqlalchemy/engine/default.py
lib/sqlalchemy/sql/sqltypes.py
lib/sqlalchemy/testing/suite/test_types.py

diff --git a/doc/build/changelog/unreleased_12/4250.rst b/doc/build/changelog/unreleased_12/4250.rst
new file mode 100644 (file)
index 0000000..d28bc1d
--- /dev/null
@@ -0,0 +1,12 @@
+.. change::
+    :tags: bug, mssql
+    :tickets: 4250
+
+    Fixed a 1.2 regression caused by :ticket:`4061` where the SQL Server
+    "BIT" type would be considered to be "native boolean".  The goal here
+    was to avoid creating a CHECK constraint on the column, however the bigger
+    issue is that the BIT value does not behave like a true/false constant
+    and cannot be interpreted as a standalone expression, e.g.
+    "WHERE <column>".   The SQL Server dialect now goes back to being
+    non-native boolean, but with an extra flag that still avoids creating
+    the CHECK constraint.
index f55f7e74df48d11a33afb0d8c46c6239f61c4fee..2975a6c69336935ec827db4d30906bb2c16fd58d 100644 (file)
@@ -1820,7 +1820,8 @@ class MSDialect(default.DefaultDialect):
 
     ischema_names = ischema_names
 
-    supports_native_boolean = True
+    supports_native_boolean = False
+    non_native_boolean_check_constraint = False
     supports_unicode_binds = True
     postfetch_lastrowid = True
 
index 5806fe2a93887031dac6e133d22144948ca6c17c..099e694b6841738434c73483e8e9ee29f1818152 100644 (file)
@@ -63,6 +63,7 @@ class DefaultDialect(interfaces.Dialect):
 
     supports_native_enum = False
     supports_native_boolean = False
+    non_native_boolean_check_constraint = True
 
     supports_simple_order_by_label = True
 
index 573fda98fc6ced86844bd6d87e5fc37f84c69560..a2ae9de5023117868bd546054a96f4f68350ca2a 100644 (file)
@@ -1643,7 +1643,8 @@ class Boolean(Emulated, TypeEngine, SchemaType):
     def _should_create_constraint(self, compiler, **kw):
         if not self._is_impl_for_variant(compiler.dialect, kw):
             return False
-        return not compiler.dialect.supports_native_boolean
+        return not compiler.dialect.supports_native_boolean and \
+            compiler.dialect.non_native_boolean_check_constraint
 
     @util.dependencies("sqlalchemy.sql.schema")
     def _set_table(self, schema, column, table):
index b9458c5706b8797c4bd2db84b243d15e8875ba75..4cdf14dc9e46bd964034eb6678955136c035fba9 100644 (file)
@@ -612,6 +612,48 @@ class BooleanTest(_LiteralRoundTripFixture, fixtures.TablesTest):
             (None, None)
         )
 
+    def test_whereclause(self):
+        # testing "WHERE <column>" renders a compatible expression
+        boolean_table = self.tables.boolean_table
+
+        with config.db.connect() as conn:
+            conn.execute(
+                boolean_table.insert(),
+                [
+                    {'id': 1, 'value': True, 'unconstrained_value': True},
+                    {'id': 2, 'value': False, 'unconstrained_value': False}
+                ]
+            )
+
+            eq_(
+                conn.scalar(
+                    select([boolean_table.c.id]).where(boolean_table.c.value)
+                ),
+                1
+            )
+            eq_(
+                conn.scalar(
+                    select([boolean_table.c.id]).where(
+                        boolean_table.c.unconstrained_value)
+                ),
+                1
+            )
+            eq_(
+                conn.scalar(
+                    select([boolean_table.c.id]).where(~boolean_table.c.value)
+                ),
+                2
+            )
+            eq_(
+                conn.scalar(
+                    select([boolean_table.c.id]).where(
+                        ~boolean_table.c.unconstrained_value)
+                ),
+                2
+            )
+
+
+
 
 class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
     __requires__ = 'json_type',