From 66773a8801a584d36b514e22a03d92d66fb2931b Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 30 Nov 2013 13:53:26 -0500 Subject: [PATCH] - Fixed bug where values within an ENUM weren't escaped for single quote signs. Note that this is backwards-incompatible for existing workarounds that manually escape the single quotes. [ticket:2878] --- doc/build/changelog/changelog_09.rst | 12 ++++++++++++ doc/build/changelog/migration_09.rst | 18 ++++++++++++++++++ lib/sqlalchemy/dialects/postgresql/base.py | 4 +++- test/dialect/postgresql/test_compiler.py | 16 ++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/doc/build/changelog/changelog_09.rst b/doc/build/changelog/changelog_09.rst index 08b815a11f..158a140584 100644 --- a/doc/build/changelog/changelog_09.rst +++ b/doc/build/changelog/changelog_09.rst @@ -14,6 +14,18 @@ .. changelog:: :version: 0.9.0b2 + .. change:: + :tags: bug, postgresql + :tickets: 2878 + + Fixed bug where values within an ENUM weren't escaped for single + quote signs. Note that this is backwards-incompatible for existing + workarounds that manually escape the single quotes. + + .. seealso:: + + :ref:`migration_2878` + .. change:: :tags: bug, orm, declarative diff --git a/doc/build/changelog/migration_09.rst b/doc/build/changelog/migration_09.rst index d0d901626f..1b0a4fc25b 100644 --- a/doc/build/changelog/migration_09.rst +++ b/doc/build/changelog/migration_09.rst @@ -692,6 +692,24 @@ an ``__lt__()`` method has been added:: :ticket:`2848` +.. _migration_2878: + +Postgresql CREATE TYPE AS ENUM now applies quoting to values +---------------------------------------------------------------- + +The :class:`.postgresql.ENUM` type will now apply escaping to single quote +signs within the enumerated values:: + + >>> from sqlalchemy.dialects import postgresql + >>> type = postgresql.ENUM('one', 'two', "three's", name="myenum") + >>> from sqlalchemy.dialects.postgresql import base + >>> print base.CreateEnumType(type).compile(dialect=postgresql.dialect()) + CREATE TYPE myenum AS ENUM ('one','two','three''s') + +Existing workarounds which already escape single quote signs will need to be +modified, else they will now double-escape. + +:ticket:`2878` New Features ============ diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 8bcfcbf7cf..b80f269c14 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -1090,7 +1090,9 @@ class PGDDLCompiler(compiler.DDLCompiler): return "CREATE TYPE %s AS ENUM (%s)" % ( self.preparer.format_type(type_), - ",".join("'%s'" % e for e in type_.enums) + ", ".join( + self.sql_compiler.process(sql.literal(e), literal_binds=True) + for e in type_.enums) ) def visit_drop_enum_type(self, drop): diff --git a/test/dialect/postgresql/test_compiler.py b/test/dialect/postgresql/test_compiler.py index 409d6f03a2..dd7df2be37 100644 --- a/test/dialect/postgresql/test_compiler.py +++ b/test/dialect/postgresql/test_compiler.py @@ -16,6 +16,7 @@ from sqlalchemy.dialects.postgresql import base as postgresql from sqlalchemy.dialects.postgresql import TSRANGE from sqlalchemy.orm import mapper, aliased, Session from sqlalchemy.sql import table, column, operators +from sqlalchemy.util import u class SequenceTest(fixtures.TestBase, AssertsCompiledSQL): @@ -106,6 +107,21 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): 'AS length_1', dialect=dialect) + def test_create_enum(self): + # test escaping and unicode within CREATE TYPE for ENUM + typ = postgresql.ENUM( + "val1", "val2", "val's 3", u('méil'), name="myname") + self.assert_compile(postgresql.CreateEnumType(typ), + u("CREATE TYPE myname AS ENUM ('val1', 'val2', 'val''s 3', 'méil')") + ) + + typ = postgresql.ENUM( + "val1", "val2", "val's 3", name="PleaseQuoteMe") + self.assert_compile(postgresql.CreateEnumType(typ), + "CREATE TYPE \"PleaseQuoteMe\" AS ENUM " + "('val1', 'val2', 'val''s 3')" + ) + def test_create_partial_index(self): m = MetaData() tbl = Table('testtbl', m, Column('data', Integer)) -- 2.47.3