Skip site navigation (1) Skip section navigation (2)

Re: [PATCHES] Anoter JDBC Error

From: Barry Lind <blind(at)xythos(dot)com>
To: Kris Jurka <books(at)ejurka(dot)com>
Cc: Aaron Mulder <ammulder(at)alumni(dot)princeton(dot)edu>,PostgreSQL JDBC <pgsql-jdbc(at)postgresql(dot)org>,pgsql-patches(at)postgresql(dot)org
Subject: Re: [PATCHES] Anoter JDBC Error
Date: 2002-10-25 02:57:45
Message-ID: 3DB8B329.7020506@xythos.com (view raw or flat)
Thread:
Lists: pgsql-jdbcpgsql-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



In response to

pgsql-patches by date

Next:From: Dennis BjörklundDate: 2002-10-26 05:30:36
Subject: Re: swedish translation
Previous:From: Bruce MomjianDate: 2002-10-23 23:33:01
Subject: Re: patch for pgsql/doc/src/sgml/ref/postgres-ref.sgml

pgsql-jdbc by date

Next:From: Dave CramerDate: 2002-10-25 09:23:48
Subject: Re: UPDATE_RULE
Previous:From: RaymundDate: 2002-10-24 08:20:37
Subject: how to insert the letter "ñ"

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group