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
Views: Raw Message | Whole Thread | Download mbox | Resend email
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];
+ }
}

Browse pgsql-jdbc by date

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