From d66f470326c59330e323ad470d6014d2adbba729 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 3 Jan 2010 18:53:41 +0000 Subject: [PATCH] fixed DDL quoting with literal strings that have ' [ticket:1640] --- CHANGES | 3 +++ lib/sqlalchemy/sql/util.py | 9 ++++++++- test/dialect/test_postgresql.py | 7 +++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index db902e79d8..140bd058c9 100644 --- a/CHANGES +++ b/CHANGES @@ -524,6 +524,9 @@ CHANGES "postgres_where" names still work with a deprecation warning. + - "postgresql_where" now accepts SQL expressions which + can also include literals, which will be quoted as needed. + - The psycopg2 dialect now uses psycopg2's "unicode extension" on all new connections, which allows all String/Text/etc. types to skip the need to post-process bytestrings into diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 1b4bc67fcc..821b3a3d12 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -172,6 +172,13 @@ def find_columns(clause): visitors.traverse(clause, {}, {'column':cols.add}) return cols +def _quote_ddl_expr(element): + if isinstance(element, basestring): + element = element.replace("'", "''") + return "'%s'" % element + else: + return repr(element) + def expression_as_ddl(clause): """Given a SQL expression, convert for usage in DDL, such as CREATE INDEX and CHECK CONSTRAINT. @@ -183,7 +190,7 @@ def expression_as_ddl(clause): """ def repl(element): if isinstance(element, expression._BindParamClause): - return expression.literal_column(repr(element.value)) + return expression.literal_column(_quote_ddl_expr(element.value)) elif isinstance(element, expression.ColumnClause) and \ element.table is not None: return expression.column(element.name) diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py index bc181810e6..9833042fed 100644 --- a/test/dialect/test_postgresql.py +++ b/test/dialect/test_postgresql.py @@ -87,9 +87,16 @@ class CompileTest(TestBase, AssertsCompiledSQL): m = MetaData() tbl = Table('testtbl', m, Column('data',Integer)) idx = Index('test_idx1', tbl.c.data, postgresql_where=and_(tbl.c.data > 5, tbl.c.data < 10)) + idx = Index('test_idx1', tbl.c.data, postgresql_where=and_(tbl.c.data > 5, tbl.c.data < 10)) + + # test quoting and all that + idx2 = Index('test_idx2', tbl.c.data, postgresql_where=and_(tbl.c.data > 'a', tbl.c.data < "b's")) self.assert_compile(schema.CreateIndex(idx), "CREATE INDEX test_idx1 ON testtbl (data) WHERE data > 5 AND data < 10", dialect=postgresql.dialect()) + + self.assert_compile(schema.CreateIndex(idx2), + "CREATE INDEX test_idx2 ON testtbl (data) WHERE data > 'a' AND data < 'b''s'", dialect=postgresql.dialect()) @testing.uses_deprecated(r".*'postgres_where' argument has been renamed.*") def test_old_create_partial_index(self): -- 2.47.3