]> granicus.if.org Git - postgresql/commitdiff
Attached is a patch for JDBC's getColumn() function that was broken /
authorBruce Momjian <bruce@momjian.us>
Thu, 6 Sep 2001 03:20:30 +0000 (03:20 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 6 Sep 2001 03:20:30 +0000 (03:20 +0000)
flawed in the following ways:

1. Only returned columns that had a default value defined, rather than all
columns in a table
2. Used 2 * N + 1 queries to find out attributes, comments and typenames
for N columns.

By using some outer join syntax it is possible to retrieve all necessary
information in just one SQL statement. This means this version is only
suitable for PostgreSQL >= 7.1. Don't know whether that's a problem.

I've tested this function with current sources and 7.1.3 and patched both
jdbc1 and jdbc2. I haven't compiled nor tested the jdbc1 version though, as
I have no JDK 1.1 available.

Note the discussion in http://fts.postgresql.org/db/mw/msg.html?mid=1029626
regarding differences in obtaining comments on database object in 7.1 and
7.2. I was unable to use the following syntax (or similar ones):

select
     ...,
     description
from
     ...
     left outer join col_description(a.attrelid, a.attnum) description
order by
     c.relname, a.attnum;

(the error was parse error at or near '(') so I had to paste the actual
code for the col_description function into the left outer join. Maybe
someone who is more knowledgable about outer joins might provide me with a
better SQL statement.

Jeroen van Vianen

src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java

index e1187b30947b97157acb36e58125e94685a7b181..2d9ab35a93c7bf7bcc1f85448dcec125e3087915 100644 (file)
@@ -13,6 +13,8 @@ import org.postgresql.util.PSQLException;
 /**
  * This class provides information about the database as a whole.
  *
+ * $Id: DatabaseMetaData.java,v 1.30 2001/09/06 03:20:30 momjian Exp $
+ *
  * <p>Many of the methods here return lists of information in ResultSets.  You
  * can use the normal ResultSet methods such as getString and getInt to
  * retrieve the data from these ResultSets.  If a given form of metadata is
@@ -1893,21 +1895,19 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
    */
   public java.sql.ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException
   {
-    // the field descriptors for the new ResultSet
-    Field f[] = new Field[18];
-    java.sql.ResultSet r;      // ResultSet for the SQL query that we need to do
     Vector v = new Vector();           // The new ResultSet tuple stuff
-
-    f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
-    f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32);
-    f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, 32);
-    f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, 32);
-    f[4] = new Field(connection, "DATA_TYPE", iInt2Oid, 2);
-    f[5] = new Field(connection, "TYPE_NAME", iVarcharOid, 32);
-    f[6] = new Field(connection, "COLUMN_SIZE", iInt4Oid, 4);
-    f[7] = new Field(connection, "BUFFER_LENGTH", iVarcharOid, 32);
-    f[8] = new Field(connection, "DECIMAL_DIGITS", iInt4Oid, 4);
-    f[9] = new Field(connection, "NUM_PREC_RADIX", iInt4Oid, 4);
+       Field f[] = new Field[18];              // The field descriptors for the new ResultSet
+
+    f[ 0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
+    f[ 1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32);
+    f[ 2] = new Field(connection, "TABLE_NAME", iVarcharOid, 32);
+    f[ 3] = new Field(connection, "COLUMN_NAME", iVarcharOid, 32);
+    f[ 4] = new Field(connection, "DATA_TYPE", iInt2Oid, 2);
+    f[ 5] = new Field(connection, "TYPE_NAME", iVarcharOid, 32);
+    f[ 6] = new Field(connection, "COLUMN_SIZE", iInt4Oid, 4);
+    f[ 7] = new Field(connection, "BUFFER_LENGTH", iVarcharOid, 32);
+    f[ 8] = new Field(connection, "DECIMAL_DIGITS", iInt4Oid, 4);
+    f[ 9] = new Field(connection, "NUM_PREC_RADIX", iInt4Oid, 4);
     f[10] = new Field(connection, "NULLABLE", iInt4Oid, 4);
     f[11] = new Field(connection, "REMARKS", iVarcharOid, 32);
     f[12] = new Field(connection, "COLUMN_DEF", iVarcharOid, 32);
@@ -1917,91 +1917,110 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     f[16] = new Field(connection, "ORDINAL_POSITION", iInt4Oid,4);
     f[17] = new Field(connection, "IS_NULLABLE", iVarcharOid, 32);
 
-    // Added by Stefan Andreasen <stefan@linux.kapow.dk>
-    // If the pattern are  null then set them to %
-    if (tableNamePattern == null) tableNamePattern="%";
-    if (columnNamePattern == null) columnNamePattern="%";
-
-    // Now form the query
-       String query =
-           "select " +
-               (connection.haveMinimumServerVersion("7.2") ? "a.attrelid" : "a.oid") +
-               ",c.relname,a.attname,a.atttypid," +
-               "a.attnum,a.attnotnull,a.attlen,a.atttypmod,d.adsrc from pg_class c," +
-               "pg_attribute a,pg_attrdef d where a.attrelid=c.oid and " +
-               "c.relname like '"+tableNamePattern.toLowerCase()+"' and " +
-               "a.attname like '"+columnNamePattern.toLowerCase()+"' and " +
-               "a.attnum>0 and c.oid=d.adrelid and d.adnum=a.attnum " +
-               "order by c.relname,a.attnum";
-
-    r = connection.ExecSQL(query);
-
-    while(r.next()) {
-       byte[][] tuple = new byte[18][0];
-
-       // Fetch the description for the table (if any)
-       String getDescriptionStatement =
-               connection.haveMinimumServerVersion("7.2") ?
-               "select col_description(" + r.getInt(1) + "," + r.getInt(5) + ")" :
-           "select description from pg_description where objoid=" + r.getInt(1);
-
-       java.sql.ResultSet dr = connection.ExecSQL(getDescriptionStatement);
-
-       if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
-         dr.next();
-         tuple[11] = dr.getBytes(1);
-       } else
-               tuple[11] = null;
-       dr.close();
-
-       tuple[0] = "".getBytes();       // Catalog name
-       tuple[1] = "".getBytes();       // Schema name
-       tuple[2] = r.getBytes(2);       // Table name
-       tuple[3] = r.getBytes(3);       // Column name
-
-       dr = connection.ExecSQL("select typname from pg_type where oid = "+r.getString(4));
-       dr.next();
-       String typname=dr.getString(1);
-       dr.close();
-        tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();        // Data type
-       tuple[5] = typname.getBytes();  // Type name
-
-       // Column size
-       // Looking at the psql source,
-       // I think the length of a varchar as specified when the table was created
-       // should be extracted from atttypmod which contains this length + sizeof(int32)
-       if (typname.equals("bpchar") || typname.equals("varchar")) {
-         int atttypmod = r.getInt(8);
-         tuple[6] = Integer.toString(atttypmod != -1 ? atttypmod - VARHDRSZ : 0).getBytes();
-       } else
-         tuple[6] = r.getBytes(7);
-
-       tuple[7] = null;        // Buffer length
-
-       tuple[8] = "0".getBytes();      // Decimal Digits - how to get this?
-       tuple[9] = "10".getBytes();     // Num Prec Radix - assume decimal
-
-       // tuple[10] is below
-       // tuple[11] is above
-
-       tuple[12] = r.getBytes(9);      // column default
-
-       tuple[13] = null;       // sql data type (unused)
-       tuple[14] = null;       // sql datetime sub (unused)
+       StringBuffer sql = new StringBuffer(512);
+
+       sql.append("select " +
+               (connection.haveMinimumServerVersion("7.2") ? "a.attrelid, " : "a.oid, ") +
+               "    c.relname, " +
+               "    a.attname, " +
+               "    a.atttypid, " +
+               "    a.attnum, " +
+               "    a.attnotnull, " +
+               "    a.attlen, " +
+               "    a.atttypmod, " +
+               "    d.adsrc, " +
+               "    t.typname, " +
+               "    e.description " +
+               "from" +
+               "    (" +
+               "        (pg_class c inner join pg_attribute a on" +
+               "            (" +
+               "                a.attrelid=c.oid");
+
+       if ((tableNamePattern != null) && ! tableNamePattern.equals("%")) {
+               sql.append("                and c.relname like \'" + tableNamePattern + "\'");
+       }
 
-       tuple[15] = tuple[6];   // char octet length
+       if ((columnNamePattern != null) && ! columnNamePattern.equals("%")) {
+               sql.append("                and a.attname like \'" + columnNamePattern + "\'");
+       }
 
-       tuple[16] = r.getBytes(5);      // ordinal position
+       sql.append(
+               "                and a.attnum > 0" +
+               "            )" +
+               "        ) inner join pg_type t on" +
+               "            (" +
+               "                t.oid = a.atttypid" +
+               "            )" +
+               "    )" +
+               "    left outer join pg_attrdef d on" +
+               "        (" +
+               "            c.oid = d.adrelid" +
+               "            and a.attnum = d.adnum" +
+               "        )" +
+               "    left outer join pg_description e on" +
+               "        (" +
+               "            e.objoid = a.attrelid");
+
+       if (connection.haveMinimumServerVersion("7.2")) {
+               sql.append(
+                       "            and e.objsubid = a.attnum" +
+                       "            and e.classoid = (select oid from pg_class where relname = \'pg_class\')");
+       }
 
-       String nullFlag = r.getString(6);
-       tuple[10] = Integer.toString(nullFlag.equals("f")?java.sql.DatabaseMetaData.columnNullable:java.sql.DatabaseMetaData.columnNoNulls).getBytes(); // Nullable
-       tuple[17] = (nullFlag.equals("f")?"YES":"NO").getBytes();       // is nullable
+       sql.append(
+               "        ) " +
+               "order by" +
+               "    c.relname, a.attnum");
+
+       System.out.println(sql);
+
+       java.sql.ResultSet r = connection.ExecSQL(sql.toString());
+       while (r.next()) {
+               byte[][] tuple = new byte[18][0];
+
+               String nullFlag = r.getString(6);
+               String typname = r.getString(10);
+
+               tuple[0] = "".getBytes();                               // Catalog name
+               tuple[1] = "".getBytes();                               // Schema name
+               tuple[2] = r.getBytes(2);                               // Table name
+               tuple[3] = r.getBytes(3);                               // Column name
+               tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes(); // Data type
+               tuple[5] = typname.getBytes();                  // Type name
+
+               // Column size
+               // Looking at the psql source,
+               // I think the length of a varchar as specified when the table was created
+               // should be extracted from atttypmod which contains this length + sizeof(int32)
+               if (typname.equals("bpchar") || typname.equals("varchar")) {
+                       int atttypmod = r.getInt(8);
+                       tuple[6] = Integer.toString(atttypmod != -1 ? atttypmod - VARHDRSZ : 0).getBytes();
+               } else {
+                       tuple[6] = r.getBytes(7);
+               }
+
+               tuple[7] = null;                                                // Buffer length
+               tuple[8] = "0".getBytes();                              // Decimal Digits - how to get this?
+               tuple[9] = "10".getBytes();                             // Num Prec Radix - assume decimal
+               tuple[10] = Integer.toString(nullFlag.equals("f") ?
+                       java.sql.DatabaseMetaData.columnNullable :
+                       java.sql.DatabaseMetaData.columnNoNulls).getBytes();    // Nullable
+               tuple[11] = r.getBytes(11);                     // Description (if any)
+               tuple[12] = r.getBytes(9);                              // 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] = r.getBytes(5);                              // ordinal position
+               tuple[17] = (nullFlag.equals("f") ? "YES" : "NO").getBytes();   // Is nullable
+
+               v.addElement(tuple);
+       }
+       r.close();
 
-       v.addElement(tuple);
-      }
-    r.close();
     return new ResultSet(connection, f, v, "OK", 1);
   }
+
   /**
    * Get a description of the access rights for a table's columns.
    *
index 6e4c01c3331f03177d9fc355c1b6aa6ce791d5ee..b41f446f975c2533b0f44acf4f20fd8d92fa1a96 100644 (file)
@@ -13,6 +13,8 @@ import org.postgresql.util.PSQLException;
 /**
  * This class provides information about the database as a whole.
  *
+ * $Id: DatabaseMetaData.java,v 1.34 2001/09/06 03:20:30 momjian Exp $
+ *
  * <p>Many of the methods here return lists of information in ResultSets.  You
  * can use the normal ResultSet methods such as getString and getInt to
  * retrieve the data from these ResultSets.  If a given form of metadata is
@@ -677,9 +679,9 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
 
   /**
    * Does this driver support the ANSI-92 entry level SQL grammar?
-   * All JDBC Compliant drivers must return true.  We currently 
-   * report false until 'schema' support is added.  Then this 
-   * should be changed to return true, since we will be mostly 
+   * All JDBC Compliant drivers must return true.  We currently
+   * report false until 'schema' support is added.  Then this
+   * should be changed to return true, since we will be mostly
    * compliant (probably more compliant than many other databases)
    * And since this is a requirement for all JDBC drivers we
    * need to get to the point where we can return true.
@@ -1893,21 +1895,19 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
    */
   public java.sql.ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException
   {
-    // the field descriptors for the new ResultSet
-    Field f[] = new Field[18];
-    java.sql.ResultSet r;      // ResultSet for the SQL query that we need to do
     Vector v = new Vector();           // The new ResultSet tuple stuff
-
-    f[0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
-    f[1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32);
-    f[2] = new Field(connection, "TABLE_NAME", iVarcharOid, 32);
-    f[3] = new Field(connection, "COLUMN_NAME", iVarcharOid, 32);
-    f[4] = new Field(connection, "DATA_TYPE", iInt2Oid, 2);
-    f[5] = new Field(connection, "TYPE_NAME", iVarcharOid, 32);
-    f[6] = new Field(connection, "COLUMN_SIZE", iInt4Oid, 4);
-    f[7] = new Field(connection, "BUFFER_LENGTH", iVarcharOid, 32);
-    f[8] = new Field(connection, "DECIMAL_DIGITS", iInt4Oid, 4);
-    f[9] = new Field(connection, "NUM_PREC_RADIX", iInt4Oid, 4);
+       Field f[] = new Field[18];              // The field descriptors for the new ResultSet
+
+    f[ 0] = new Field(connection, "TABLE_CAT", iVarcharOid, 32);
+    f[ 1] = new Field(connection, "TABLE_SCHEM", iVarcharOid, 32);
+    f[ 2] = new Field(connection, "TABLE_NAME", iVarcharOid, 32);
+    f[ 3] = new Field(connection, "COLUMN_NAME", iVarcharOid, 32);
+    f[ 4] = new Field(connection, "DATA_TYPE", iInt2Oid, 2);
+    f[ 5] = new Field(connection, "TYPE_NAME", iVarcharOid, 32);
+    f[ 6] = new Field(connection, "COLUMN_SIZE", iInt4Oid, 4);
+    f[ 7] = new Field(connection, "BUFFER_LENGTH", iVarcharOid, 32);
+    f[ 8] = new Field(connection, "DECIMAL_DIGITS", iInt4Oid, 4);
+    f[ 9] = new Field(connection, "NUM_PREC_RADIX", iInt4Oid, 4);
     f[10] = new Field(connection, "NULLABLE", iInt4Oid, 4);
     f[11] = new Field(connection, "REMARKS", iVarcharOid, 32);
     f[12] = new Field(connection, "COLUMN_DEF", iVarcharOid, 32);
@@ -1917,89 +1917,107 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
     f[16] = new Field(connection, "ORDINAL_POSITION", iInt4Oid,4);
     f[17] = new Field(connection, "IS_NULLABLE", iVarcharOid, 32);
 
-    // Added by Stefan Andreasen <stefan@linux.kapow.dk>
-    // If the pattern are  null then set them to %
-    if (tableNamePattern == null) tableNamePattern="%";
-    if (columnNamePattern == null) columnNamePattern="%";
-
-    // Now form the query
-       String query =
-           "select " +
-               (connection.haveMinimumServerVersion("7.2") ? "a.attrelid" : "a.oid") +
-               ",c.relname,a.attname,a.atttypid," +
-               "a.attnum,a.attnotnull,a.attlen,a.atttypmod,d.adsrc from pg_class c," +
-               "pg_attribute a,pg_attrdef d where a.attrelid=c.oid and " +
-               "c.relname like '"+tableNamePattern.toLowerCase()+"' and " +
-               "a.attname like '"+columnNamePattern.toLowerCase()+"' and " +
-               "a.attnum>0 and c.oid=d.adrelid and d.adnum=a.attnum " +
-               "order by c.relname,a.attnum";
-
-    r = connection.ExecSQL(query);
-
-    while(r.next()) {
-       byte[][] tuple = new byte[18][0];
-
-       // Fetch the description for the table (if any)
-       String getDescriptionStatement =
-               connection.haveMinimumServerVersion("7.2") ?
-               "select col_description(" + r.getInt(1) + "," + r.getInt(5) + ")" :
-           "select description from pg_description where objoid=" + r.getInt(1);
-
-       java.sql.ResultSet dr = connection.ExecSQL(getDescriptionStatement);
-
-       if(((org.postgresql.ResultSet)dr).getTupleCount()==1) {
-         dr.next();
-         tuple[11] = dr.getBytes(1);
-       } else
-               tuple[11] = null;
-       dr.close();
-
-       tuple[0] = "".getBytes();       // Catalog name
-       tuple[1] = "".getBytes();       // Schema name
-       tuple[2] = r.getBytes(2);       // Table name
-       tuple[3] = r.getBytes(3);       // Column name
-
-       dr = connection.ExecSQL("select typname from pg_type where oid = "+r.getString(4));
-       dr.next();
-       String typname=dr.getString(1);
-       dr.close();
-        tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();        // Data type
-       tuple[5] = typname.getBytes();  // Type name
-
-       // Column size
-       // Looking at the psql source,
-       // I think the length of a varchar as specified when the table was created
-       // should be extracted from atttypmod which contains this length + sizeof(int32)
-       if (typname.equals("bpchar") || typname.equals("varchar")) {
-         int atttypmod = r.getInt(8);
-         tuple[6] = Integer.toString(atttypmod != -1 ? atttypmod - VARHDRSZ : 0).getBytes();
-       } else
-         tuple[6] = r.getBytes(7);
-
-       tuple[7] = null;        // Buffer length
-
-       tuple[8] = "0".getBytes();      // Decimal Digits - how to get this?
-       tuple[9] = "10".getBytes();     // Num Prec Radix - assume decimal
-
-       // tuple[10] is below
-       // tuple[11] is above
-
-       tuple[12] = r.getBytes(9);      // column default
-
-       tuple[13] = null;       // sql data type (unused)
-       tuple[14] = null;       // sql datetime sub (unused)
+       StringBuffer sql = new StringBuffer(512);
+
+       sql.append("select " +
+               (connection.haveMinimumServerVersion("7.2") ? "a.attrelid, " : "a.oid, ") +
+               "    c.relname, " +
+               "    a.attname, " +
+               "    a.atttypid, " +
+               "    a.attnum, " +
+               "    a.attnotnull, " +
+               "    a.attlen, " +
+               "    a.atttypmod, " +
+               "    d.adsrc, " +
+               "    t.typname, " +
+               "    e.description " +
+               "from" +
+               "    (" +
+               "        (pg_class c inner join pg_attribute a on" +
+               "            (" +
+               "                a.attrelid=c.oid");
+
+       if ((tableNamePattern != null) && ! tableNamePattern.equals("%")) {
+               sql.append("                and c.relname like \'" + tableNamePattern + "\'");
+       }
 
-       tuple[15] = tuple[6];   // char octet length
+       if ((columnNamePattern != null) && ! columnNamePattern.equals("%")) {
+               sql.append("                and a.attname like \'" + columnNamePattern + "\'");
+       }
 
-       tuple[16] = r.getBytes(5);      // ordinal position
+       sql.append(
+               "                and a.attnum > 0" +
+               "            )" +
+               "        ) inner join pg_type t on" +
+               "            (" +
+               "                t.oid = a.atttypid" +
+               "            )" +
+               "    )" +
+               "    left outer join pg_attrdef d on" +
+               "        (" +
+               "            c.oid = d.adrelid" +
+               "            and a.attnum = d.adnum" +
+               "        )" +
+               "    left outer join pg_description e on" +
+               "        (" +
+               "            e.objoid = a.attrelid");
+
+       if (connection.haveMinimumServerVersion("7.2")) {
+               sql.append(
+                       "            and e.objsubid = a.attnum" +
+                       "            and e.classoid = (select oid from pg_class where relname = \'pg_class\')");
+       }
 
-       String nullFlag = r.getString(6);
-       tuple[10] = Integer.toString(nullFlag.equals("f")?java.sql.DatabaseMetaData.columnNullable:java.sql.DatabaseMetaData.columnNoNulls).getBytes(); // Nullable
-       tuple[17] = (nullFlag.equals("f")?"YES":"NO").getBytes();       // is nullable
+       sql.append(
+               "        ) " +
+               "order by" +
+               "    c.relname, a.attnum");
+
+       System.out.println(sql);
+
+       java.sql.ResultSet r = connection.ExecSQL(sql.toString());
+       while (r.next()) {
+               byte[][] tuple = new byte[18][0];
+
+               String nullFlag = r.getString(6);
+               String typname = r.getString(10);
+
+               tuple[0] = "".getBytes();                               // Catalog name
+               tuple[1] = "".getBytes();                               // Schema name
+               tuple[2] = r.getBytes(2);                               // Table name
+               tuple[3] = r.getBytes(3);                               // Column name
+               tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes(); // Data type
+               tuple[5] = typname.getBytes();                  // Type name
+
+               // Column size
+               // Looking at the psql source,
+               // I think the length of a varchar as specified when the table was created
+               // should be extracted from atttypmod which contains this length + sizeof(int32)
+               if (typname.equals("bpchar") || typname.equals("varchar")) {
+                       int atttypmod = r.getInt(8);
+                       tuple[6] = Integer.toString(atttypmod != -1 ? atttypmod - VARHDRSZ : 0).getBytes();
+               } else {
+                       tuple[6] = r.getBytes(7);
+               }
+
+               tuple[7] = null;                                                // Buffer length
+               tuple[8] = "0".getBytes();                              // Decimal Digits - how to get this?
+               tuple[9] = "10".getBytes();                             // Num Prec Radix - assume decimal
+               tuple[10] = Integer.toString(nullFlag.equals("f") ?
+                       java.sql.DatabaseMetaData.columnNullable :
+                       java.sql.DatabaseMetaData.columnNoNulls).getBytes();    // Nullable
+               tuple[11] = r.getBytes(11);                     // Description (if any)
+               tuple[12] = r.getBytes(9);                              // 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] = r.getBytes(5);                              // ordinal position
+               tuple[17] = (nullFlag.equals("f") ? "YES" : "NO").getBytes();   // Is nullable
+
+               v.addElement(tuple);
+       }
+       r.close();
 
-       v.addElement(tuple);
-      }
-    r.close();
     return new ResultSet(connection, f, v, "OK", 1);
   }
 
@@ -2387,9 +2405,9 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
            "from pg_class as c, pg_trigger as t "+
            "where c.relname like '"+table+"' and c.relfilenode=t.tgrelid");
     Vector tuples=new Vector();
-    
+
     while (rs.next()) {
-           tuples.addAll(importLoop(rs));      
+           tuples.addAll(importLoop(rs));
     }
 
     rsret=new ResultSet(connection, f, tuples, "OK", 1);
@@ -2707,7 +2725,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
                                " AND (i.oid = x.indexrelid) " +
                                " AND (i.relam = a.oid)) " +
                                "ORDER BY x.indisunique DESC, " +
-                               " x.indisclustered, a.amname, i.relname");  
+                               " x.indisclustered, a.amname, i.relname");
     while (r.next()) {
         // indkey is an array of column ordinals (integers).  In the JDBC
         // interface, this has to be separated out into a separate
@@ -2722,7 +2740,7 @@ public class DatabaseMetaData implements java.sql.DatabaseMetaData
         }
         for (int i = 0; i < columnOrdinals.length; i++) {
             byte [] [] tuple = new byte [13] [];
-            tuple[0] = "".getBytes(); 
+            tuple[0] = "".getBytes();
             tuple[1] = "".getBytes();
             tuple[2] = r.getBytes(1);
             tuple[3] = r.getBoolean(2) ? "f".getBytes() : "t".getBytes();