summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-10-12 20:04:55 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-10-12 20:13:27 -0400
commitd8c17e2a6f41d0aad331678e916f1aa4f07e4f7b (patch)
treea8390553ad61d5da567dd5f03515b614da2f88b7
parente488bb47e4bd21ff0a09ce23e1adf00ba64d5d57 (diff)
downloadsqlalchemy-d8c17e2a6f41d0aad331678e916f1aa4f07e4f7b.tar.gz
- Fixed bug in default compiler plus those of postgresql, mysql, and
mssql to ensure that any literal SQL expression values are rendered directly as literals, instead of as bound parameters, within a CREATE INDEX statement. [ticket:2742] - don't need expression_as_ddl(); literal_binds and include_table take care of this functionality. Conflicts: lib/sqlalchemy/sql/util.py
-rw-r--r--doc/build/changelog/changelog_08.rst10
-rw-r--r--lib/sqlalchemy/dialects/mssql/base.py2
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py3
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py17
-rw-r--r--lib/sqlalchemy/sql/compiler.py7
-rw-r--r--lib/sqlalchemy/sql/util.py2
-rw-r--r--test/dialect/mssql/test_compiler.py10
-rw-r--r--test/dialect/mysql/test_compiler.py10
-rw-r--r--test/dialect/postgresql/test_compiler.py10
-rw-r--r--test/dialect/test_oracle.py11
-rw-r--r--test/sql/test_constraints.py21
11 files changed, 89 insertions, 14 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index 0937aaad5..3d2179f5a 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -12,6 +12,16 @@
.. change::
:tags: bug, sql
+ :tickets: 2742
+ :versions: 0.9.0
+
+ Fixed bug in default compiler plus those of postgresql, mysql, and
+ mssql to ensure that any literal SQL expression values are
+ rendered directly as literals, instead of as bound parameters,
+ within a CREATE INDEX statement.
+
+ .. change::
+ :tags: bug, sql
:tickets: 2815
:versions: 0.9.0
diff --git a/lib/sqlalchemy/dialects/mssql/base.py b/lib/sqlalchemy/dialects/mssql/base.py
index fc952f4b5..fa6db3453 100644
--- a/lib/sqlalchemy/dialects/mssql/base.py
+++ b/lib/sqlalchemy/dialects/mssql/base.py
@@ -1001,7 +1001,7 @@ class MSDDLCompiler(compiler.DDLCompiler):
preparer.format_table(index.table),
', '.join(
self.sql_compiler.process(expr,
- include_table=False) for
+ include_table=False, literal_binds=True) for
expr in index.expressions)
)
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index 0fe459503..8ead8f148 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -1532,7 +1532,8 @@ class MySQLDDLCompiler(compiler.DDLCompiler):
self._verify_index_table(index)
preparer = self.preparer
table = preparer.format_table(index.table)
- columns = [self.sql_compiler.process(expr, include_table=False)
+ columns = [self.sql_compiler.process(expr, include_table=False,
+ literal_binds=True)
for expr in index.expressions]
name = self._prepared_index_name(index)
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index 1c8a71fbd..2cbe7c830 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -1101,12 +1101,9 @@ class PGDDLCompiler(compiler.DDLCompiler):
text += "(%s)" \
% (
', '.join([
- self.sql_compiler.process(expr, include_table=False) +
-
-
+ self.sql_compiler.process(
+ expr, include_table=False, literal_binds=True) +
(c.key in ops and (' ' + ops[c.key]) or '')
-
-
for expr, c in zip(index.expressions, index.columns)])
)
@@ -1116,8 +1113,9 @@ class PGDDLCompiler(compiler.DDLCompiler):
whereclause = None
if whereclause is not None:
- whereclause = sql_util.expression_as_ddl(whereclause)
- where_compiled = self.sql_compiler.process(whereclause)
+ where_compiled = self.sql_compiler.process(
+ whereclause, include_table=False,
+ literal_binds=True)
text += " WHERE " + where_compiled
return text
@@ -1132,8 +1130,9 @@ class PGDDLCompiler(compiler.DDLCompiler):
elements.append(self.preparer.quote(c.name, c.quote)+' WITH '+op)
text += "EXCLUDE USING %s (%s)" % (constraint.using, ', '.join(elements))
if constraint.where is not None:
- sqltext = sql_util.expression_as_ddl(constraint.where)
- text += ' WHERE (%s)' % self.sql_compiler.process(sqltext)
+ text += ' WHERE (%s)' % self.sql_compiler.process(
+ constraint.where,
+ literal_binds=True)
text += self.define_constraint_deferrability(constraint)
return text
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 13bf47c0b..0a1fcdfab 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -2031,7 +2031,7 @@ class DDLCompiler(engine.Compiled):
use_schema=include_table_schema),
', '.join(
self.sql_compiler.process(expr,
- include_table=False) for
+ include_table=False, literal_binds=True) for
expr in index.expressions)
)
return text
@@ -2121,8 +2121,9 @@ class DDLCompiler(engine.Compiled):
if constraint.name is not None:
text += "CONSTRAINT %s " % \
self.preparer.format_constraint(constraint)
- sqltext = sql_util.expression_as_ddl(constraint.sqltext)
- text += "CHECK (%s)" % self.sql_compiler.process(sqltext)
+ text += "CHECK (%s)" % self.sql_compiler.process(constraint.sqltext,
+ include_table=False,
+ literal_binds=True)
text += self.define_constraint_deferrability(constraint)
return text
diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py
index fdc5bb372..ecb26e2ea 100644
--- a/lib/sqlalchemy/sql/util.py
+++ b/lib/sqlalchemy/sql/util.py
@@ -270,6 +270,8 @@ def expression_as_ddl(clause):
into detached column constructs so that the parent table
identifier is not included.
+ .. deprecated:: this function is removed in 0.9.0.
+
"""
def repl(element):
if isinstance(element, expression.BindParameter):
diff --git a/test/dialect/mssql/test_compiler.py b/test/dialect/mssql/test_compiler.py
index 87037c6a4..f218d9d0e 100644
--- a/test/dialect/mssql/test_compiler.py
+++ b/test/dialect/mssql/test_compiler.py
@@ -528,6 +528,16 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"CREATE INDEX foo ON test (x DESC, y)"
)
+ def test_create_index_expr(self):
+ m = MetaData()
+ t1 = Table('foo', m,
+ Column('x', Integer)
+ )
+ self.assert_compile(
+ schema.CreateIndex(Index("bar", t1.c.x > 5)),
+ "CREATE INDEX bar ON foo (x > 5)"
+ )
+
def test_index_extra_include_1(self):
metadata = MetaData()
tbl = Table('test', metadata,
diff --git a/test/dialect/mysql/test_compiler.py b/test/dialect/mysql/test_compiler.py
index a77a25cc4..d1488ed33 100644
--- a/test/dialect/mysql/test_compiler.py
+++ b/test/dialect/mysql/test_compiler.py
@@ -94,6 +94,16 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
"CREATE TABLE testtbl (data VARCHAR(255), "
"PRIMARY KEY (data) USING btree)")
+ def test_create_index_expr(self):
+ m = MetaData()
+ t1 = Table('foo', m,
+ Column('x', Integer)
+ )
+ self.assert_compile(
+ schema.CreateIndex(Index("bar", t1.c.x > 5)),
+ "CREATE INDEX bar ON foo (x > 5)"
+ )
+
def test_skip_deferrable_kw(self):
m = MetaData()
t1 = Table('t1', m, Column('id', Integer, primary_key=True))
diff --git a/test/dialect/postgresql/test_compiler.py b/test/dialect/postgresql/test_compiler.py
index 11661b11f..858f3e763 100644
--- a/test/dialect/postgresql/test_compiler.py
+++ b/test/dialect/postgresql/test_compiler.py
@@ -173,6 +173,16 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
'USING hash (data)',
dialect=postgresql.dialect())
+ def test_create_index_literals(self):
+ m = MetaData()
+ tbl = Table('testtbl', m, Column('data', Integer))
+
+ idx1 = Index('test_idx1', tbl.c.data + 5)
+ self.assert_compile(
+ schema.CreateIndex(idx1),
+ "CREATE INDEX test_idx1 ON testtbl (data + 5)"
+ )
+
def test_exclude_constraint_min(self):
m = MetaData()
tbl = Table('testtbl', m,
diff --git a/test/dialect/test_oracle.py b/test/dialect/test_oracle.py
index def4654f0..e3d35e394 100644
--- a/test/dialect/test_oracle.py
+++ b/test/dialect/test_oracle.py
@@ -552,6 +552,17 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
schema.CreateIndex(Index("bar", t1.c.x)),
"CREATE INDEX alt_schema.bar ON alt_schema.foo (x)"
)
+
+ def test_create_index_expr(self):
+ m = MetaData()
+ t1 = Table('foo', m,
+ Column('x', Integer)
+ )
+ self.assert_compile(
+ schema.CreateIndex(Index("bar", t1.c.x > 5)),
+ "CREATE INDEX bar ON foo (x > 5)"
+ )
+
class CompatFlagsTest(fixtures.TestBase, AssertsCompiledSQL):
__only_on__ = 'oracle'
diff --git a/test/sql/test_constraints.py b/test/sql/test_constraints.py
index b44a65190..393bcd448 100644
--- a/test/sql/test_constraints.py
+++ b/test/sql/test_constraints.py
@@ -726,6 +726,27 @@ class ConstraintCompilationTest(fixtures.TestBase, AssertsCompiledSQL):
"ALTER TABLE tbl ADD PRIMARY KEY (a)"
)
+ def test_render_check_constraint_sql_literal(self):
+ t, t2 = self._constraint_create_fixture()
+
+ constraint = CheckConstraint(t.c.a > 5)
+
+ self.assert_compile(
+ schema.AddConstraint(constraint),
+ "ALTER TABLE tbl ADD CHECK (a > 5)"
+ )
+
+ def test_render_index_sql_literal(self):
+ t, t2 = self._constraint_create_fixture()
+
+ constraint = Index('name', t.c.a + 5)
+
+ self.assert_compile(
+ schema.CreateIndex(constraint),
+ "CREATE INDEX name ON tbl (a + 5)"
+ )
+
+
class ConstraintAPITest(fixtures.TestBase):
def test_double_fk_usage_raises(self):
f = ForeignKey('b.id')