]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug where Postgresql dialect would fail to render an
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 16 Jan 2015 23:03:45 +0000 (18:03 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 16 Jan 2015 23:03:45 +0000 (18:03 -0500)
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

doc/build/changelog/changelog_09.rst
lib/sqlalchemy/dialects/postgresql/base.py
test/dialect/postgresql/test_compiler.py

index acead3011ce6b89eec0baa977910f7d41cc89740..d9cbd5032e7a15eae65dc698ff22fa2a2da14aa6 100644 (file)
 .. 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
index fa9a2cfd0537cfd00325d4ea18a9e691bb1fd91f..0817fe8371ca07ec6ece743ded8ba88368aebb59 100644 (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"]
index 6c4f3c8cccf270309f2c3086a53116845d183bf2..5717df9f76f314c000039aebeebe699b6bfcf9e9 100644 (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))