]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- as the Concatenable mixin was changed to support calling down to
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 18 Aug 2015 16:40:18 +0000 (12:40 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 18 Aug 2015 16:40:18 +0000 (12:40 -0400)
"super" instead of hardcoding to "self.type" for the default return
value, the base Comparator was returning other_comparator.type.   It's
not clear what the rationale for this was, though in theory the
base Comparator should possibly even throw an exception if the two
types aren't the same (or of the same affinity?) .
- mysql.SET was broken on this because the bitwise version adds "0"
to the value to force an integer within column_expression, we are doing type_coerces here
now in any case so that there is no type ambiguity for this
operation

lib/sqlalchemy/dialects/mysql/base.py
lib/sqlalchemy/sql/type_api.py
test/sql/test_operators.py

index fee05fd2d5587c32283ed1443111681a413eb688..4b3e5bcd16594184015d460d9efa4d244d20c9b3 100644 (file)
@@ -1584,7 +1584,10 @@ class SET(_EnumeratedValues):
 
     def column_expression(self, colexpr):
         if self.retrieve_as_bitwise:
-            return colexpr + 0
+            return sql.type_coerce(
+                sql.type_coerce(colexpr, sqltypes.Integer) + 0,
+                self
+            )
         else:
             return colexpr
 
index 701e2a44ade726ae22f6b27ed97b343f5640879f..c4e830b7f3e8d49db614b1881b3a3a31634d0639 100644 (file)
@@ -91,7 +91,7 @@ class TypeEngine(Visitable):
             boolean comparison or special SQL keywords like MATCH or BETWEEN.
 
             """
-            return op, other_comparator.type
+            return op, self.type
 
         def __reduce__(self):
             return _reconstitute_comparator, (self.expr, )
index fbbdd7b62343239ec454a602a2d38560de8901eb..f3dfd2daf64398e3d0382e152ac652f3188f9563 100644 (file)
@@ -14,7 +14,7 @@ from sqlalchemy.sql.elements import _literal_as_text
 from sqlalchemy.schema import Column, Table, MetaData
 from sqlalchemy.sql import compiler
 from sqlalchemy.types import TypeEngine, TypeDecorator, UserDefinedType, \
-    Boolean, NullType, MatchType, Indexable
+    Boolean, NullType, MatchType, Indexable, Concatenable
 from sqlalchemy.dialects import mysql, firebird, postgresql, oracle, \
     sqlite, mssql
 from sqlalchemy import util
@@ -210,6 +210,60 @@ class DefaultColumnComparatorTest(fixtures.TestBase):
     def test_concat(self):
         self._do_operate_test(operators.concat_op)
 
+    def test_default_adapt(self):
+        class TypeOne(TypeEngine):
+            pass
+
+        class TypeTwo(TypeEngine):
+            pass
+
+        expr = column('x', TypeOne()) - column('y', TypeTwo())
+        is_(
+            expr.type._type_affinity, TypeOne
+        )
+
+    def test_concatenable_adapt(self):
+        class TypeOne(Concatenable, TypeEngine):
+            pass
+
+        class TypeTwo(Concatenable, TypeEngine):
+            pass
+
+        class TypeThree(TypeEngine):
+            pass
+
+        expr = column('x', TypeOne()) - column('y', TypeTwo())
+        is_(
+            expr.type._type_affinity, TypeOne
+        )
+        is_(
+            expr.operator, operator.sub
+        )
+
+        expr = column('x', TypeOne()) + column('y', TypeTwo())
+        is_(
+            expr.type._type_affinity, TypeOne
+        )
+        is_(
+            expr.operator, operators.concat_op
+        )
+
+        expr = column('x', TypeOne()) - column('y', TypeThree())
+        is_(
+            expr.type._type_affinity, TypeOne
+        )
+        is_(
+            expr.operator, operator.sub
+        )
+
+        expr = column('x', TypeOne()) + column('y', TypeThree())
+        is_(
+            expr.type._type_affinity, TypeOne
+        )
+        is_(
+            expr.operator, operator.add
+        )
+
 
 class CustomUnaryOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
     __dialect__ = 'default'