]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Convert expression type for concat + Enum
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 20 Oct 2016 19:59:46 +0000 (15:59 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 20 Oct 2016 19:59:46 +0000 (15:59 -0400)
Fixed bug involving new value translation and validation feature
in :class:`.Enum` whereby using the enum object in a string
concatenation would maintain the :class:`.Enum` type as the type
of the expression overall, producing missing lookups.  A string
concatenation against an :class:`.Enum`-typed column now uses
:class:`.String` as the datatype of the expression itself.

Change-Id: Id402054e3ef008e0250c740dbb7e1c80f339fe78
Fixes: #3833
doc/build/changelog/changelog_11.rst
lib/sqlalchemy/sql/sqltypes.py
test/sql/test_types.py

index 3c00736c7bcdf733343b3e4f98284de8cbf3a7bc..6dd09c4d981a40510e9c83080db5def6cec2adc1 100644 (file)
 .. changelog::
     :version: 1.1.3
 
+    .. change::
+        :tags: bug, sql
+        :tickets: 3833
+
+        Fixed bug involving new value translation and validation feature
+        in :class:`.Enum` whereby using the enum object in a string
+        concatenation would maintain the :class:`.Enum` type as the type
+        of the expression overall, producing missing lookups.  A string
+        concatenation against an :class:`.Enum`-typed column now uses
+        :class:`.String` as the datatype of the expression itself.
+
     .. change::
         :tags: bug, sql
         :tickets: 3832
index cae23902b01b976a674088080f60f72ac8a1a9cd..ef1624fa009e1d972fc987c50174a664b64c8210 100644 (file)
@@ -1296,6 +1296,19 @@ class Enum(String, SchemaType):
                 raise LookupError(
                     '"%s" is not among the defined enum values' % elem)
 
+    class Comparator(String.Comparator):
+
+        def _adapt_expression(self, op, other_comparator):
+            op, typ = super(Enum.Comparator, self)._adapt_expression(
+                op, other_comparator)
+            if op is operators.concat_op:
+                typ = String(
+                    self.type.length,
+                    convert_unicode=self.type.convert_unicode)
+            return op, typ
+
+    comparator_factory = Comparator
+
     def _object_value_for_elem(self, elem):
         try:
             return self._object_lookup[elem]
index 3374a67213163831adafe96228ae12f2b1ebcb9e..7f49991e6f425e56f3601a16a936b20cb71b2831 100644 (file)
@@ -1264,6 +1264,25 @@ class EnumTest(AssertsCompiledSQL, fixtures.TablesTest):
             ]
         )
 
+    def test_validators_not_in_concatenate_roundtrip(self):
+        enum_table = self.tables['non_native_enum_table']
+
+        enum_table.insert().execute([
+            {'id': 1, 'someenum': 'two'},
+            {'id': 2, 'someenum': 'two'},
+            {'id': 3, 'someenum': 'one'},
+        ])
+
+        eq_(
+            select(['foo' + enum_table.c.someenum]).
+            order_by(enum_table.c.id).execute().fetchall(),
+            [
+                ('footwo', ),
+                ('footwo', ),
+                ('fooone', )
+            ]
+        )
+
     @testing.fails_on(
         'postgresql+zxjdbc',
         'zxjdbc fails on ENUM: column "XXX" is of type XXX '