]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Repair PG BIGSERIAL w/ TypeDecorator, Variant
authorMike Bayer <mike_mp@zzzcomputing.com>
Mon, 4 Jul 2016 20:37:26 +0000 (16:37 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 4 Jul 2016 20:51:48 +0000 (16:51 -0400)
Some of the dialect impl memoization for TypeDecorator
necessarily keeps the top-level TypeDecorator type
around, since a user-defined type will have bind and result
set processing behavior.  For both TypeDecorator and Variant,
PG dialect needs to ensure it's looking at the SQLAlchemy
type to check for SmallInteger / BigInteger.

Fixes: 3739
Change-Id: I2d45fb997f17c6272d6bb826a77d2dba665adae7

doc/build/changelog/changelog_10.rst
lib/sqlalchemy/dialects/postgresql/base.py
test/dialect/postgresql/test_dialect.py

index a1e7d367891b9cae79816cbd0906a3fbe6d5999e..7240e8e685ea16b26c5a574d7f16ae317526d836 100644 (file)
 .. changelog::
     :version: 1.0.14
 
+    .. change::
+        :tags: bug, postgresql
+        :tickets: 3739
+        :versions: 1.1.0b3
+
+        Fixed bug whereby :class:`.TypeDecorator` and :class:`.Variant`
+        types were not deeply inspected enough by the Postgresql dialect
+        to determine if SMALLSERIAL or BIGSERIAL needed to be rendered
+        rather than SERIAL.
+
     .. change::
         :tags: bug, sql
         :tickets: 3735
index 8c676a39c547f77d9a4485bad411318bfbff1164..766847c76df4073d2fc761242cf200063217b535 100644 (file)
@@ -1578,6 +1578,9 @@ class PGDDLCompiler(compiler.DDLCompiler):
 
         colspec = self.preparer.format_column(column)
         impl_type = column.type.dialect_impl(self.dialect)
+        if isinstance(impl_type, sqltypes.TypeDecorator):
+            impl_type = impl_type.impl
+
         if column.primary_key and \
             column is column.table._autoincrement_column and \
             (
index 52620bb78bb03f7af9f0a5f5b554e0b524a90214..1171144584d1a13de7343d732c0b2ed0c284ccd7 100644 (file)
@@ -8,7 +8,7 @@ from sqlalchemy import testing
 import datetime
 from sqlalchemy import (
     Table, Column, select, MetaData, text, Integer, String, Sequence, Numeric,
-    DateTime, BigInteger, func, extract, SmallInteger)
+    DateTime, BigInteger, func, extract, SmallInteger, TypeDecorator)
 from sqlalchemy import exc, schema
 from sqlalchemy.dialects.postgresql import base as postgresql
 import logging
@@ -242,6 +242,15 @@ class MiscTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         "postgresql >= 8.2", "requires standard_conforming_strings")
     def test_serial_integer(self):
 
+        class BITD(TypeDecorator):
+            impl = Integer
+
+            def load_dialect_impl(self, dialect):
+                if dialect.name == 'postgresql':
+                    return BigInteger()
+                else:
+                    return Integer()
+
         for version, type_, expected in [
             (None, Integer, 'SERIAL'),
             (None, BigInteger, 'BIGSERIAL'),
@@ -249,6 +258,16 @@ class MiscTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL):
             ((9, 2), SmallInteger, 'SMALLSERIAL'),
             (None, postgresql.INTEGER, 'SERIAL'),
             (None, postgresql.BIGINT, 'BIGSERIAL'),
+            (
+                None, Integer().with_variant(BigInteger(), 'postgresql'),
+                'BIGSERIAL'),
+            (
+                None, Integer().with_variant(postgresql.BIGINT, 'postgresql'),
+                'BIGSERIAL'),
+            (
+                (9, 2), Integer().with_variant(SmallInteger, 'postgresql'),
+                'SMALLSERIAL'),
+            (None, BITD(), 'BIGSERIAL')
         ]:
             m = MetaData()