regression in supporting reflection on PostgreSQL 8.4

Issue #3343 resolved
Jon Nelson created an issue

In ..../postgresql/base.py a change was made ( #3184, pull request bitbucket:30 ) to support additional smarts in reflecting indices and unique constraints in PostgreSQL. Unfortunately, this change is not compatible with PostgreSQL 8.4 which does not have a 'conindid' column.

While it's not elegant, I whipped up the following patch:

diff -ur SQLAlchemy-1.0.0b3.orig/lib/sqlalchemy/dialects/postgresql/base.py SQLAlchemy-1.0.0b3/lib/sqlalchemy/dialects/postgresql/base.py
--- SQLAlchemy-1.0.0b3.orig/lib/sqlalchemy/dialects/postgresql/base.py  2015-03-24 09:51:23.850734852 -0500
+++ SQLAlchemy-1.0.0b3/lib/sqlalchemy/dialects/postgresql/base.py   2015-03-24 09:59:38.201019680 -0500
@@ -2605,7 +2605,7 @@
           SELECT
               i.relname as relname,
               ix.indisunique, ix.indexprs, ix.indpred,
-              a.attname, a.attnum, c.conrelid, ix.indkey%s
+              a.attname, a.attnum, %s, ix.indkey%s
           FROM
               pg_class t
                     join pg_index ix on t.oid = ix.indrelid
@@ -2613,11 +2613,7 @@
                     left outer join
                         pg_attribute a
                         on t.oid = a.attrelid and %s
-                    left outer join
-                        pg_constraint c
-                        on (ix.indrelid = c.conrelid and
-                            ix.indexrelid = c.conindid and
-                            c.contype in ('p', 'u', 'x'))
+                    %s
           WHERE
               t.relkind IN ('r', 'v', 'f', 'm')
               and t.oid = :table_oid
@@ -2629,8 +2625,14 @@
             # version 8.3 here was based on observing the
             # cast does not work in PG 8.2.4, does work in 8.3.0.
             # nothing in PG changelogs regarding this.
+            "c.conrelid" if self.server_version_info >= (9, 0) else "NULL as conrelid",
             "::varchar" if self.server_version_info >= (8, 3) else "",
-            self._pg_index_any("a.attnum", "ix.indkey")
+            self._pg_index_any("a.attnum", "ix.indkey"),
+            """left outer join
+                        pg_constraint c
+                        on (ix.indrelid = c.conrelid and
+                            ix.indexrelid = c.conindid and
+                            c.contype in ('p', 'u', 'x'))""" if self.server_version_info >= (9, 0) else ""
         )

         t = sql.text(IDX_SQL, typemap={'attname': sqltypes.Unicode})

If you would prefer a pull request, I might be able to do that.

Comments (9)

  1. Jon Nelson reporter

    That seems to work. Thanks! I'm curious if you'd help me to understand what made my proposed patch less optimal than 3343.patch. Thank you!

  2. Mike Bayer repo owner

    well it just seemed like the <=8.4 version was really accumulating a bunch of conditionals and I wanted to keep the modern version and the older version of the query easier to read, as well as shield the "legacy" version from any future changes as PG adds new bells and whistles constantly. (we'll want to reflect functional indexes and such in the future, etc).

  3. Mike Bayer repo owner
    • Fixed bug where updated PG index reflection as a result of 🎫3184 would cause index operations to fail on Postgresql versions 8.4 and earlier. The enhancements are now disabled when using an older version of Postgresql. fixes #3343

    → <<cset 4b164935481c>>

  4. Log in to comment