Skip site navigation (1) Skip section navigation (2)

Fix database metadata tuple copying to work with binary data

From: Mikko Tiihonen <mikko(dot)tiihonen(at)iki(dot)fi>
To: pgsql-jdbc <pgsql-jdbc(at)postgresql(dot)org>
Subject: Fix database metadata tuple copying to work with binary data
Date: 2007-07-23 07:38:25
Message-ID: 1185176305.1632.97.camel@dual.local (view raw or flat)
Thread:
Lists: pgsql-jdbc
Hi,

The following patch makes DatabaseMetaData work if result set can contain tuples in binary format.
An alternative to copying the OID + format flag is to just always do getString() and re-encode it.
But it can be now changed easily in one place at the copyValue method.

The patch just fixes the only thing unit tests revealed when running with binary transfer patches.
Most probably the copyValue should be used in lots of other places too. If this patch is acceptable
I can comb through the remaining copies and convert them.

Index: org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java
===================================================================
RCS file: /usr/local/cvsroot/pgjdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java,v
retrieving revision 1.36
diff -u -r1.36 AbstractJdbc2DatabaseMetaData.java
--- org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java	15 Jul 2007 15:33:33 -0000	1.36
+++ org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java	23 Jul 2007 07:25:36 -0000
@@ -2321,9 +2321,9 @@
             int typeMod = rs.getInt("atttypmod");
 
             tuple[0] = null;     // Catalog name, not supported
-            tuple[1] = rs.getBytes("nspname"); // Schema
-            tuple[2] = rs.getBytes("relname"); // Table name
-            tuple[3] = rs.getBytes("attname"); // Column name
+            copyValue(rs, "nspname", 1, f, tuple); // Schema
+            copyValue(rs, "relname", 2, f, tuple); // Table name
+            copyValue(rs, "attname", 3, f, tuple); // Column name
             tuple[4] = connection.encodeString(Integer.toString(connection.getSQLType(typeOid)));
             String pgType = connection.getPGType(typeOid);
             tuple[5] = connection.encodeString(pgType); // Type name
@@ -2364,12 +2364,12 @@
             }
 
             tuple[10] = connection.encodeString(Integer.toString(rs.getBoolean("attnotnull") ? java.sql.DatabaseMetaData.columnNoNulls : java.sql.DatabaseMetaData.columnNullable)); // Nullable
-            tuple[11] = rs.getBytes("description");    // Description (if any)
-            tuple[12] = rs.getBytes("adsrc");    // Column default
+            copyValue(rs, "description", 11, f, tuple);    // Description (if any)
+            copyValue(rs, "adsrc", 12, f, tuple);          // Column default
             tuple[13] = null;      // sql data type (unused)
             tuple[14] = null;      // sql datetime sub (unused)
             tuple[15] = tuple[6];     // char octet length
-            tuple[16] = rs.getBytes("attnum");  // ordinal position
+            copyValue(rs, "attnum", 16, f, tuple); // ordinal position
             tuple[17] = connection.encodeString(rs.getBoolean("attnotnull") ? "NO" : "YES"); // Is nullable
 
             v.addElement(tuple);
@@ -4024,4 +4024,29 @@
         return ((AbstractJdbc2Connection)connection).createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
     }
 
+    /**
+     * Copies one value from real result set to target result set under
+     * construction.
+     * 
+     * @param rs The source.
+     * @param columnName The name of the column to copy.
+     * @param pos The position in target result set.
+     * @param f The fields of the target result set.
+     * @param tuple The values of the target result set.
+     * @throws SQLException If an error occurs.
+     */
+    protected void copyValue(ResultSet rs, String columnName, int pos,
+                             Field[] f, byte[][] tuple) throws SQLException {
+        int col = rs.findColumn(columnName) - 1;
+        AbstractJdbc2ResultSet res = (AbstractJdbc2ResultSet) rs;
+        Field fromField = res.fields[col];
+        if (fromField.getFormat() != Field.TEXT_FORMAT) {
+            // The OID must match for binary types
+            if (fromField.getOID() != f[pos].getOID()) {
+                f[pos] = new Field(f[pos].getColumnLabel(), fromField.getOID());
+            }
+            f[pos].setFormat(fromField.getFormat());
+        }
+        tuple[pos] = res.this_row[col];
+    }
 }



pgsql-jdbc by date

Next:From: Stefan ZweigDate: 2007-07-23 15:42:36
Subject: Problem with ResultSet retrieved with SELECT * FROM pg_indexes WHERE tablename
Previous:From: Mikko TiihonenDate: 2007-07-22 08:04:11
Subject: Re: Fix more unit test connection leaks

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group