[libpostgresql-jdbc-java] 07/22: Fix the ORDINAL_POSITION in the DatabaseMetaData.getColumns. Previously we were returning simply pg_attribute.attnum, but that doesn't work in the presence of dropped columns because later columns don't get their attnum decremented if a preceding column is dropped. Instead use the row_number window function for 8.4 and later servers to figure out the live column position.

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Mon Jan 9 10:20:52 UTC 2017


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to tag REL8_4_702
in repository libpostgresql-jdbc-java.

commit 19c3c0448cadab20f10d8d39039a0f824d374da2
Author: Kris Jurka <books at ejurka.com>
Date:   Wed Dec 9 01:06:41 2009 +0000

    Fix the ORDINAL_POSITION in the DatabaseMetaData.getColumns.
    Previously we were returning simply pg_attribute.attnum, but that
    doesn't work in the presence of dropped columns because later
    columns don't get their attnum decremented if a preceding column
    is dropped.  Instead use the row_number window function for 8.4
    and later servers to figure out the live column position.
    
    I got this idea after reading a -hackers message suggesting doing
    the same thing to the information_schema.
---
 .../jdbc2/AbstractJdbc2DatabaseMetaData.java       | 40 +++++++++++++++++++---
 .../test/jdbc2/DatabaseMetaDataTest.java           | 37 +++++++++++++++++++-
 2 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java b/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java
index 8af40e9..90e14fb 100644
--- a/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java
+++ b/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java
@@ -3,7 +3,7 @@
 * Copyright (c) 2004-2008, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
-*   $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java,v 1.51.2.1 2009/12/04 19:48:01 jurka Exp $
+*   $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java,v 1.51.2.2 2009/12/04 21:22:02 jurka Exp $
 *
 *-------------------------------------------------------------------------
 */
@@ -2249,7 +2249,27 @@ public abstract class AbstractJdbc2DatabaseMetaData
         String sql;
         if (connection.haveMinimumServerVersion("7.3"))
         {
-            sql = "SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype " +
+            // a.attnum isn't decremented when preceding columns are dropped,
+            // so the only way to calculate the correct column number is with
+            // window functions, new in 8.4.
+            // 
+            // We want to push as much predicate information below the window
+            // function as possible (schema/table names), but must leave
+            // column name outside so we correctly count the other columns.
+            //
+            if (connection.haveMinimumServerVersion("8.4"))
+                sql = "SELECT * FROM (";
+            else
+                sql = "";
+
+            sql += "SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,";
+            
+            if (connection.haveMinimumServerVersion("8.4"))
+                sql += "row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, ";
+            else
+                sql += "a.attnum,";
+            
+            sql += "pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype " +
                   " FROM pg_catalog.pg_namespace n " +
                   " JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) " +
                   " JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) " +
@@ -2259,10 +2279,20 @@ public abstract class AbstractJdbc2DatabaseMetaData
                   " LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') " +
                   " LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog') " +
                   " WHERE a.attnum > 0 AND NOT a.attisdropped ";
+
             if (schemaPattern != null && !"".equals(schemaPattern))
             {
                 sql += " AND n.nspname LIKE '" + escapeQuotes(schemaPattern) + "' ";
             }
+
+            if (tableNamePattern != null && !"".equals(tableNamePattern))
+            {
+                sql += " AND c.relname LIKE '" + escapeQuotes(tableNamePattern) + "' ";
+            }
+
+            if (connection.haveMinimumServerVersion("8.4"))
+                sql += ") v WHERE true ";
+
         }
         else if (connection.haveMinimumServerVersion("7.2"))
         {
@@ -2292,13 +2322,13 @@ public abstract class AbstractJdbc2DatabaseMetaData
                   " WHERE a.attrelid=c.oid AND a.attnum > 0 ";
         }
 
-        if (tableNamePattern != null && !"".equals(tableNamePattern))
+        if (!connection.haveMinimumServerVersion("7.3") && tableNamePattern != null && !"".equals(tableNamePattern))
         {
-            sql += " AND c.relname LIKE '" + escapeQuotes(tableNamePattern) + "' ";
+            sql += " AND relname LIKE '" + escapeQuotes(tableNamePattern) + "' ";
         }
         if (columnNamePattern != null && !"".equals(columnNamePattern))
         {
-            sql += " AND a.attname LIKE '" + escapeQuotes(columnNamePattern) + "' ";
+            sql += " AND attname LIKE '" + escapeQuotes(columnNamePattern) + "' ";
         }
         sql += " ORDER BY nspname,relname,attnum ";
 
diff --git a/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java b/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
index 7e96add..9b40d5c 100644
--- a/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
+++ b/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
@@ -3,7 +3,7 @@
 * Copyright (c) 2004-2008, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
-*   $PostgreSQL: pgjdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java,v 1.44 2008/11/07 09:11:37 jurka Exp $
+*   $PostgreSQL: pgjdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java,v 1.44.2.1 2009/12/04 21:22:02 jurka Exp $
 *
 *-------------------------------------------------------------------------
 */
@@ -326,6 +326,41 @@ public class DatabaseMetaDataTest extends TestCase
         rs.close();
     }
 
+    public void testDroppedColumns() throws SQLException
+    {
+        if (!TestUtil.haveMinimumServerVersion(con, "8.4"))
+            return;
+
+        Statement stmt = con.createStatement();
+        stmt.execute("ALTER TABLE testmetadata DROP name");
+        stmt.execute("ALTER TABLE testmetadata DROP colour");
+        stmt.close();
+
+        DatabaseMetaData dbmd = con.getMetaData();
+        ResultSet rs = dbmd.getColumns(null, null, "testmetadata", null);
+
+        assertTrue(rs.next());
+        assertEquals("id", rs.getString("COLUMN_NAME"));
+        assertEquals(1, rs.getInt("ORDINAL_POSITION"));
+
+        assertTrue(rs.next());
+        assertEquals("updated", rs.getString("COLUMN_NAME"));
+        assertEquals(2, rs.getInt("ORDINAL_POSITION"));
+
+        assertTrue(rs.next());
+        assertEquals("quest", rs.getString("COLUMN_NAME"));
+        assertEquals(3, rs.getInt("ORDINAL_POSITION"));
+
+        rs.close();
+
+        rs = dbmd.getColumns(null, null, "testmetadata", "quest");
+        assertTrue(rs.next());
+        assertEquals("quest", rs.getString("COLUMN_NAME"));
+        assertEquals(3, rs.getInt("ORDINAL_POSITION"));
+        assertTrue(!rs.next());
+        rs.close();
+    }
+
     public void testSerialColumns() throws SQLException
     {
         DatabaseMetaData dbmd = con.getMetaData();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libpostgresql-jdbc-java.git



More information about the pkg-java-commits mailing list