Fix database metadata tuple copying to work with binary data

Поиск
Список
Период
Сортировка
От Mikko Tiihonen
Тема Fix database metadata tuple copying to work with binary data
Дата
Msg-id 1185176305.1632.97.camel@dual.local
обсуждение исходный текст
Список 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 по дате отправления:

Предыдущее
От: Dave Cramer
Дата:
Сообщение: Re: Problem with ResultSet retrieved with SELECT * FROM pg_indexes WHERE tablename
Следующее
От: Mikko Tiihonen
Дата:
Сообщение: Make time/timestamp tests fair for binary transfers