- Fixed bug where Postgresql dialect would fail to render an

expression in an :class:`.Index` that did not correspond directly
to a table-bound column; typically when a :func:`.text` construct
was one of the expressions within the index; or could misinterpret the
list of expressions if one or more of them were such an expression.
fixes #3174
This commit is contained in:
Mike Bayer
2015-01-16 18:03:45 -05:00
parent 41307cd733
commit 79fa69f1f3
3 changed files with 71 additions and 3 deletions
+11
View File
@@ -14,6 +14,17 @@
.. changelog::
:version: 0.9.9
.. change::
:tags: bug, postgresql
:versions: 1.0.0
:tickets: 3174
Fixed bug where Postgresql dialect would fail to render an
expression in an :class:`.Index` that did not correspond directly
to a table-bound column; typically when a :func:`.text` construct
was one of the expressions within the index; or could misinterpret the
list of expressions if one or more of them were such an expression.
.. change::
:tags: bug, orm
:versions: 1.0.0
+7 -2
View File
@@ -1477,8 +1477,13 @@ class PGDDLCompiler(compiler.DDLCompiler):
if not isinstance(expr, expression.ColumnClause)
else 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)])
(
(' ' + ops[expr.key])
if hasattr(expr, 'key')
and expr.key in ops else ''
)
for expr in index.expressions
])
)
whereclause = index.dialect_options["postgresql"]["where"]
+53 -1
View File
@@ -5,7 +5,7 @@ from sqlalchemy.testing.assertions import AssertsCompiledSQL, is_, \
from sqlalchemy.testing import engines, fixtures
from sqlalchemy import testing
from sqlalchemy import Sequence, Table, Column, Integer, update, String,\
insert, func, MetaData, Enum, Index, and_, delete, select, cast
insert, func, MetaData, Enum, Index, and_, delete, select, cast, text
from sqlalchemy.dialects.postgresql import ExcludeConstraint, array
from sqlalchemy import exc, schema
from sqlalchemy.dialects.postgresql import base as postgresql
@@ -296,6 +296,58 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL):
'(data text_pattern_ops, data2 int4_ops)',
dialect=postgresql.dialect())
def test_create_index_with_text_or_composite(self):
m = MetaData()
tbl = Table('testtbl', m,
Column('d1', String),
Column('d2', Integer))
idx = Index('test_idx1', text('x'))
tbl.append_constraint(idx)
idx2 = Index('test_idx2', text('y'), tbl.c.d2)
idx3 = Index(
'test_idx2', tbl.c.d1, text('y'), tbl.c.d2,
postgresql_ops={'d1': 'x1', 'd2': 'x2'}
)
idx4 = Index(
'test_idx2', tbl.c.d1, tbl.c.d2 > 5, text('q'),
postgresql_ops={'d1': 'x1', 'd2': 'x2'}
)
idx5 = Index(
'test_idx2', tbl.c.d1, (tbl.c.d2 > 5).label('g'), text('q'),
postgresql_ops={'d1': 'x1', 'g': 'x2'}
)
self.assert_compile(
schema.CreateIndex(idx),
"CREATE INDEX test_idx1 ON testtbl (x)"
)
self.assert_compile(
schema.CreateIndex(idx2),
"CREATE INDEX test_idx2 ON testtbl (y, d2)"
)
self.assert_compile(
schema.CreateIndex(idx3),
"CREATE INDEX test_idx2 ON testtbl (d1 x1, y, d2 x2)"
)
# note that at the moment we do not expect the 'd2' op to
# pick up on the "d2 > 5" expression
self.assert_compile(
schema.CreateIndex(idx4),
"CREATE INDEX test_idx2 ON testtbl (d1 x1, (d2 > 5), q)"
)
# however it does work if we label!
self.assert_compile(
schema.CreateIndex(idx5),
"CREATE INDEX test_idx2 ON testtbl (d1 x1, (d2 > 5) x2, q)"
)
def test_create_index_with_using(self):
m = MetaData()
tbl = Table('testtbl', m, Column('data', String))