summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2016-09-30 09:23:50 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2016-09-30 09:23:50 -0400
commit079df65dc0f71ea4d1771b6ae17e13242c766517 (patch)
tree2b42abaa29461b6839b1c7115bad9a7faa3beae9
parent800a18aff2927433163afec3b7a4671eabe1c2e3 (diff)
downloadsqlalchemy-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.rst11
-rw-r--r--doc/build/changelog/migration_11.rst25
-rw-r--r--lib/sqlalchemy/sql/compiler.py3
-rw-r--r--test/sql/test_defaults.py28
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(