diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-09-30 09:23:50 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-09-30 09:23:50 -0400 |
commit | 079df65dc0f71ea4d1771b6ae17e13242c766517 (patch) | |
tree | 2b42abaa29461b6839b1c7115bad9a7faa3beae9 | |
parent | 800a18aff2927433163afec3b7a4671eabe1c2e3 (diff) | |
download | sqlalchemy-079df65dc0f71ea4d1771b6ae17e13242c766517.tar.gz |
Escape literal string values passed to server_default
A string sent as a column default via the
:paramref:`.Column.server_default` parameter is now escaped for quotes.
This change is backwards compatible with code that may have been
working around this previously.
Change-Id: I341298a76cc67bc0a53df4ab51ab9379f2294cdd
Fixes: #3809
-rw-r--r-- | doc/build/changelog/changelog_11.rst | 11 | ||||
-rw-r--r-- | doc/build/changelog/migration_11.rst | 25 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 3 | ||||
-rw-r--r-- | test/sql/test_defaults.py | 28 |
4 files changed, 66 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst index af22fd6bc..af2171707 100644 --- a/doc/build/changelog/changelog_11.rst +++ b/doc/build/changelog/changelog_11.rst @@ -22,6 +22,17 @@ :version: 1.1.0 .. change:: + :tags: bug, sql + :tickets: 3809 + + A string sent as a column default via the + :paramref:`.Column.server_default` parameter is now escaped for quotes. + + .. seealso:: + + :ref:`change_3809` + + .. change:: :tags: bug, postgresql :tickets: 3807 diff --git a/doc/build/changelog/migration_11.rst b/doc/build/changelog/migration_11.rst index c85f1bf1f..e514f4dbb 100644 --- a/doc/build/changelog/migration_11.rst +++ b/doc/build/changelog/migration_11.rst @@ -1180,6 +1180,31 @@ statement:: :ticket:`2551` +.. _change_3809: + +String server_default now literal quoted +---------------------------------------- + +A server default passed to :paramref:`.Column.server_default` as a plain +Python string that has quotes embedded is now +passed through the literal quoting system:: + + >>> from sqlalchemy.schema import MetaData, Table, Column, CreateTable + >>> from sqlalchemy.types import String + >>> t = Table('t', MetaData(), Column('x', String(), server_default="hi ' there")) + >>> print CreateTable(t) + + CREATE TABLE t ( + x VARCHAR DEFAULT 'hi '' there' + ) + +Previously the quote would render directly. This change may be backwards +incompatible for applications with such a use case who were working around +the issue. + + +:ticket:`3809` + .. _change_3049: Support for RANGE and ROWS specification within window functions diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index a7954f10a..a2dbcee5c 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -2494,7 +2494,8 @@ class DDLCompiler(Compiled): def get_column_default_string(self, column): if isinstance(column.server_default, schema.DefaultClause): if isinstance(column.server_default.arg, util.string_types): - return "'%s'" % column.server_default.arg + return self.sql_compiler.render_literal_value( + column.server_default.arg, sqltypes.STRINGTYPE) else: return self.sql_compiler.process( column.server_default.arg, literal_binds=True) diff --git a/test/sql/test_defaults.py b/test/sql/test_defaults.py index 57af1e536..1b033fce8 100644 --- a/test/sql/test_defaults.py +++ b/test/sql/test_defaults.py @@ -24,6 +24,9 @@ class DDLTest(fixtures.TestBase, AssertsCompiledSQL): __dialect__ = 'default' def test_string(self): + # note: that the datatype is an Integer here doesn't matter, + # the server_default is interpreted independently of the + # column's datatype. m = MetaData() t = Table('t', m, Column('x', Integer, server_default='5')) self.assert_compile( @@ -31,6 +34,14 @@ class DDLTest(fixtures.TestBase, AssertsCompiledSQL): "CREATE TABLE t (x INTEGER DEFAULT '5')" ) + def test_string_w_quotes(self): + m = MetaData() + t = Table('t', m, Column('x', Integer, server_default="5'6")) + self.assert_compile( + CreateTable(t), + "CREATE TABLE t (x INTEGER DEFAULT '5''6')" + ) + def test_text(self): m = MetaData() t = Table('t', m, Column('x', Integer, server_default=text('5 + 8'))) @@ -39,6 +50,23 @@ class DDLTest(fixtures.TestBase, AssertsCompiledSQL): "CREATE TABLE t (x INTEGER DEFAULT 5 + 8)" ) + def test_text_w_quotes(self): + m = MetaData() + t = Table('t', m, Column('x', Integer, server_default=text("5 ' 8"))) + self.assert_compile( + CreateTable(t), + "CREATE TABLE t (x INTEGER DEFAULT 5 ' 8)" + ) + + def test_literal_binds_w_quotes(self): + m = MetaData() + t = Table('t', m, Column('x', Integer, + server_default=literal("5 ' 8"))) + self.assert_compile( + CreateTable(t), + """CREATE TABLE t (x INTEGER DEFAULT '5 '' 8')""" + ) + def test_text_literal_binds(self): m = MetaData() t = Table( |