Re: [JDBC] Anoter JDBC Error - Mailing list pgsql-patches
From | Barry Lind |
---|---|
Subject | Re: [JDBC] Anoter JDBC Error |
Date | |
Msg-id | 3DB8B329.7020506@xythos.com Whole thread Raw |
In response to | Re: [JDBC] Anoter JDBC Error (Kris Jurka <books@ejurka.com>) |
List | pgsql-patches |
Patch applied. thanks, --Barry Kris Jurka wrote: > The following patch fixes this bug and the potential source of similar > bugs. When creating the ResultSets for DatabaseMetaData calls, the code > creates byte arrays for each row something like... > > byte tuple[][] = new byte[18][0]; > > Unless a call "tuple[n] = null;" is made then it has an array of zero > length which does in fact get turned into the zero length string being > seen. I have changed these allocations to... > > byte tuple[][] = new byte[18][]; > > Kris Jurka > > > On Sat, 19 Oct 2002, Aaron Mulder wrote: > > >> Ahh, never mind. I tried again a few minutes later, and got the >>new behavior, which is to say a SQLException. But I don't >>understand why this is happening. Here's what I'm doing: >> >> I create the database "test" (in my PG 7.2.2 DB) with a table with >>3 columns, all integers. I connect using the JDBC3 driver, get a >>connection, get the databasemetadata, call >> >> dbmd.getColumns("test",null,"tablename","%"); >> >> I get back a ResultSet. Column 9 is an integer column, >>DECIMAL_DIGITS. If I call getObject, it tries to get an Integer object, >>so even the ResultSet thinks it's an integer column. However, the result >>of getString/getFixedString used for new Integer(getFixedString()) is >>apparently an empty String, causing the SQLException due to a badly >>formatted Integer value. >> >> So now I'm confused. What's an empty String doing in an integer >>column when (if you believe the logic in getFixedString) the value was not >>null? Is this broken null handling? Test program and results attached... >> >>Aaron >> >>import java.sql.*; >> >>public class PostgresTest{ >> public static void main(String args[]) { >> try { >> Class.forName("org.postgresql.Driver"); >> Connection con = >>DriverManager.getConnection("jdbc:postgresql://localhost/test", "test", >>"password"); >> DatabaseMetaData dmd = con.getMetaData(); >> ResultSet rs = dmd.getColumns("test", null, "tablename", "%"); >> rs.next(); >> System.out.println("Col 9: "+rs.getInt(9)); // getObject(9) >> rs.close(); >> con.close(); >> } catch(Exception e) { >> e.printStackTrace(); >> } >> } >>} >> >> >>Bad Integer >> at >>org.postgresql.jdbc1.AbstractJdbc1ResultSet.toInt(AbstractJdbc1ResultSet.java:708) >> at >>org.postgresql.jdbc1.AbstractJdbc1ResultSet.getInt(AbstractJdbc1ResultSet.java:148) >> at PostgresTest.main(PostgresTest.java:12) >> >> >>---------------------------(end of broadcast)--------------------------- >>TIP 6: Have you searched our list archives? >> >>http://archives.postgresql.org >> > > > > ------------------------------------------------------------------------ > > Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java,v > retrieving revision 1.8 > diff -c -r1.8 AbstractJdbc1DatabaseMetaData.java > *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java 2002/10/08 01:47:55 1.8 > --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1DatabaseMetaData.java 2002/10/22 21:00:52 > *************** > *** 1854,1860 **** > > // decide if we are returning a single column result. > if (!returnTypeType.equals("c")) { > ! byte[][] tuple = new byte[13][0]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = procedureName; > --- 1854,1860 ---- > > // decide if we are returning a single column result. > if (!returnTypeType.equals("c")) { > ! byte[][] tuple = new byte[13][]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = procedureName; > *************** > *** 1874,1880 **** > // Add a row for each argument. > for (int i=0; i<argTypes.size(); i++) { > int argOid = ((Integer)argTypes.elementAt(i)).intValue(); > ! byte[][] tuple = new byte[13][0]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = procedureName; > --- 1874,1880 ---- > // Add a row for each argument. > for (int i=0; i<argTypes.size(); i++) { > int argOid = ((Integer)argTypes.elementAt(i)).intValue(); > ! byte[][] tuple = new byte[13][]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = procedureName; > *************** > *** 1897,1903 **** > ResultSet columnrs = connection.createStatement().executeQuery(columnsql); > while (columnrs.next()) { > int columnTypeOid = columnrs.getInt("atttypid"); > ! byte[][] tuple = new byte[13][0]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = procedureName; > --- 1897,1903 ---- > ResultSet columnrs = connection.createStatement().executeQuery(columnsql); > while (columnrs.next()) { > int columnTypeOid = columnrs.getInt("atttypid"); > ! byte[][] tuple = new byte[13][]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = procedureName; > *************** > *** 2199,2205 **** > f[0] = new Field(connection, new String("TABLE_TYPE"), iVarcharOid, getMaxNameLength()); > for (i=0; i < types.length; i++) > { > ! byte[][] tuple = new byte[1][0]; > tuple[0] = types[i].getBytes(); > v.addElement(tuple); > } > --- 2199,2205 ---- > f[0] = new Field(connection, new String("TABLE_TYPE"), iVarcharOid, getMaxNameLength()); > for (i=0; i < types.length; i++) > { > ! byte[][] tuple = new byte[1][]; > tuple[0] = types[i].getBytes(); > v.addElement(tuple); > } > *************** > *** 2318,2324 **** > ResultSet rs = connection.createStatement().executeQuery(sql); > while (rs.next()) > { > ! byte[][] tuple = new byte[18][0]; > int typeOid = rs.getInt("atttypid"); > > tuple[0] = null; // Catalog name, not supported > --- 2318,2324 ---- > ResultSet rs = connection.createStatement().executeQuery(sql); > while (rs.next()) > { > ! byte[][] tuple = new byte[18][]; > int typeOid = rs.getInt("atttypid"); > > tuple[0] = null; // Catalog name, not supported > *************** > *** 2329,2334 **** > --- 2329,2339 ---- > String pgType = connection.getPGType(typeOid); > tuple[5] = pgType.getBytes(); // Type name > > + // by default no decimal_digits > + // if the type is numeric or decimal we will > + // overwrite later. > + tuple[8] = "0".getBytes(); > + > if (pgType.equals("bpchar") || pgType.equals("varchar")) > { > int atttypmod = rs.getInt("atttypmod"); > *************** > *** 2465,2471 **** > for (int j=0; j<grantees.size(); j++) { > String grantee = (String)grantees.elementAt(j); > String grantable = owner.equals(grantee) ? "YES" : "NO"; > ! byte[][] tuple = new byte[8][0]; > tuple[0] = null; > tuple[1] = schemaName; > tuple[2] = tableName; > --- 2470,2476 ---- > for (int j=0; j<grantees.size(); j++) { > String grantee = (String)grantees.elementAt(j); > String grantable = owner.equals(grantee) ? "YES" : "NO"; > ! byte[][] tuple = new byte[8][]; > tuple[0] = null; > tuple[1] = schemaName; > tuple[2] = tableName; > *************** > *** 2567,2573 **** > for (int j=0; j<grantees.size(); j++) { > String grantee = (String)grantees.elementAt(j); > String grantable = owner.equals(grantee) ? "YES" : "NO"; > ! byte[][] tuple = new byte[7][0]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = table; > --- 2572,2578 ---- > for (int j=0; j<grantees.size(); j++) { > String grantee = (String)grantees.elementAt(j); > String grantable = owner.equals(grantee) ? "YES" : "NO"; > ! byte[][] tuple = new byte[7][]; > tuple[0] = null; > tuple[1] = schema; > tuple[2] = table; > *************** > *** 2819,2825 **** > f[6] = new Field(connection, "DECIMAL_DIGITS", iInt2Oid, 2); > f[7] = new Field(connection, "PSEUDO_COLUMN", iInt2Oid, 2); > > ! byte tuple[][] = new byte[8][0]; > > /* Postgresql does not have any column types that are > * automatically updated like some databases' timestamp type. > --- 2824,2830 ---- > f[6] = new Field(connection, "DECIMAL_DIGITS", iInt2Oid, 2); > f[7] = new Field(connection, "PSEUDO_COLUMN", iInt2Oid, 2); > > ! byte tuple[][] = new byte[8][]; > > /* Postgresql does not have any column types that are > * automatically updated like some databases' timestamp type. > > > ------------------------------------------------------------------------ > > > ---------------------------(end of broadcast)--------------------------- > TIP 5: Have you checked our extensive FAQ? > > http://www.postgresql.org/users-lounge/docs/faq.html
pgsql-patches by date: