Index: pgjdbc/org/postgresql/core/Field.java =================================================================== --- pgjdbc.orig/org/postgresql/core/Field.java +++ pgjdbc/org/postgresql/core/Field.java @@ -197,4 +197,9 @@ public class Field return schemaName; } + public String toString() { + return "Field("+ (columnName != null ? columnName : "") + "," + + Oid.toString(oid) + "," + length + "," + + (format == TEXT_FORMAT ? 'T' : 'B') + ")"; + } } Index: pgjdbc/org/postgresql/core/Oid.java =================================================================== --- pgjdbc.orig/org/postgresql/core/Oid.java +++ pgjdbc/org/postgresql/core/Oid.java @@ -9,6 +9,8 @@ */ package org.postgresql.core; +import java.lang.reflect.Field; + /** * Provides constants for well-known backend OIDs for the types we commonly * use. @@ -67,4 +69,24 @@ public class Oid { public static final int XML = 142; public static final int XML_ARRAY = 143; + /** + * Returns the name of the oid as string. + * + * @param oid The oid to convert to name. + * @return The name of the oid or "" if oid no constant for + * oid value has been defined. + */ + public static String toString(int oid) { + try { + Field[] fields = Oid.class.getFields(); + for (int i = 0; i < fields.length; ++i) { + if (fields[i].getInt(null) == oid) { + return fields[i].getName(); + } + } + } catch (IllegalAccessException e) { + // never happens + } + return ""; + } } Index: pgjdbc/org/postgresql/core/v3/QueryExecutorImpl.java =================================================================== --- pgjdbc.orig/org/postgresql/core/v3/QueryExecutorImpl.java +++ pgjdbc/org/postgresql/core/v3/QueryExecutorImpl.java @@ -1851,7 +1851,7 @@ public class QueryExecutorImpl implement break; case 'D': // Data Transfer (ongoing Execute response) - Object tuple = null; + byte[][] tuple = null; try { tuple = pgStream.ReceiveTupleV3(); } catch(OutOfMemoryError oome) { @@ -1868,8 +1868,19 @@ public class QueryExecutorImpl implement tuples.addElement(tuple); } - if (logger.logDebug()) - logger.debug(" <=BE DataRow"); + if (logger.logDebug()) { + int length; + if (tuple == null) { + length = -1; + } else { + length = 0; + for (int i=0; i< tuple.length; ++i) { + if (tuple[i] == null) continue; + length += tuple[i].length; + } + } + logger.debug(" <=BE DataRow(len=" + length + ")"); + } break; @@ -2113,6 +2124,9 @@ public class QueryExecutorImpl implement "", /* name not yet determined */ typeOid, typeLength, typeModifier, tableOid, positionInTable); fields[i].setFormat(formatType); + + if (logger.logDebug()) + logger.debug(" " + fields[i]); } return fields; Index: pgjdbc/org/postgresql/core/v3/SimpleQuery.java =================================================================== --- pgjdbc.orig/org/postgresql/core/v3/SimpleQuery.java +++ pgjdbc/org/postgresql/core/v3/SimpleQuery.java @@ -120,9 +120,21 @@ class SimpleQuery implements V3Query { return encodedStatementName; } + /** + * Sets the fields that this query will return. + * + * @param fields The fields that this query will return. + */ void setFields(Field[] fields) { this.fields = fields; } + + /** + * Returns the fields that this query will return. If the result set fields + * are not known returns null. + * + * @return the fields that this query will return. + */ Field[] getFields() { return fields; } @@ -171,6 +183,10 @@ class SimpleQuery implements V3Query { private final ProtocolConnectionImpl protoConnection; private String statementName; private byte[] encodedStatementName; + /** + * The stored fields from previous query of a prepared statement, + * if executed before. Always null for non-prepared statements. + */ private Field[] fields; private boolean portalDescribed; private boolean statementDescribed; Index: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java =================================================================== --- pgjdbc.orig/org/postgresql/jdbc2/AbstractJdbc2Connection.java +++ pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java @@ -158,6 +158,8 @@ public abstract class AbstractJdbc2Conne logger.debug(" compatible = " + compatible); logger.debug(" loglevel = " + logLevel); logger.debug(" prepare threshold = " + prepareThreshold); + logger.debug(" types using binary send = " + oidsToString(useBinarySendForOids)); + logger.debug(" types using binary receive = " + oidsToString(useBinaryReceiveForOids)); } // @@ -204,6 +206,21 @@ public abstract class AbstractJdbc2Conne } } + private String oidsToString(BitSet oids) { + StringBuffer sb = new StringBuffer(); + int oid = -1; + while ((oid = oids.nextSetBit(oid + 1)) != -1) { + sb.append(Oid.toString(oid)); + sb.append(','); + } + if (sb.length() > 0) { + sb.setLength(sb.length() - 1); + } else { + sb.append(" "); + } + return sb.toString(); + } + private final TimestampUtils timestampUtils; public TimestampUtils getTimestampUtils() { return timestampUtils; }