Index: src/interfaces/jdbc/org/postgresql/Field.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Field.java,v
retrieving revision 1.4
diff -c -r1.4 Field.java
*** src/interfaces/jdbc/org/postgresql/Field.java	2001/02/13 16:39:00	1.4
--- src/interfaces/jdbc/org/postgresql/Field.java	2001/08/17 14:43:48
***************
*** 22,27 ****
--- 22,29 ----
    public int sql_type = -1;	// The entry in java.sql.Types for this field
    public String type_name = null;// The sql type name
  
+   private static Hashtable oidCache = new Hashtable();
+ 
    /**
     * Construct a field based on the information fed to it.
     *
***************
*** 105,110 ****
--- 107,139 ----
    }
  
    /**
+    * This returns the oid for a field of a given data type
+    * @param type_name PostgreSQL type name
+    * @return PostgreSQL oid value for a field of this type
+    */
+   public int getOID( String type_name ) throws SQLException
+   {
+ 	int oid = -1;
+ 	if(type_name != null) {
+ 		Integer oidValue = (Integer) oidCache.get( type_name );
+ 		if( oidValue != null ) 
+ 			oid = oidValue.intValue();
+ 		else {
+ 			// it's not in the cache, so perform a query, and add the result to the cache
+ 			ResultSet result = (org.postgresql.ResultSet)conn.ExecSQL("select oid from pg_type where typname='" 
+ 				+ type_name + "'");
+ 			if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+ 				throw new PSQLException("postgresql.unexpected");
+ 			result.next();
+ 			oid = Integer.parseInt(result.getString(1));
+ 			oidCache.put( type_name, new Integer(oid) );
+ 			result.close();
+ 		}
+ 	}
+ 	return oid;
+   }
+ 
+   /**
     * This table holds the org.postgresql names for the types supported.
     * Any types that map to Types.OTHER (eg POINT) don't go into this table.
     * They default automatically to Types.OTHER
***************
*** 126,132 ****
      "bool",
      "date",
      "time",
!     "abstime","timestamp"
    };
  
    /**
--- 155,163 ----
      "bool",
      "date",
      "time",
!     "abstime","timestamp",
! 	"_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
! 	"_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
    };
  
    /**
***************
*** 149,155 ****
      Types.BIT,
      Types.DATE,
      Types.TIME,
!     Types.TIMESTAMP,Types.TIMESTAMP
    };
  
    /**
--- 180,188 ----
      Types.BIT,
      Types.DATE,
      Types.TIME,
!     Types.TIMESTAMP,Types.TIMESTAMP,
! 	Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY,
! 	Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY, Types.ARRAY
    };
  
    /**
Index: src/interfaces/jdbc/org/postgresql/errors.properties
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/errors.properties,v
retrieving revision 1.4
diff -c -r1.4 errors.properties
*** src/interfaces/jdbc/org/postgresql/errors.properties	2001/01/18 17:37:13	1.4
--- src/interfaces/jdbc/org/postgresql/errors.properties	2001/08/17 14:43:48
***************
*** 1,4 ****
--- 1,5 ----
  # This is the default errors
+ postgresql.arr.range:The array index is out of range.
  postgresql.drv.version:An internal error has occured. Please recompile the driver.
  postgresql.con.auth:The authentication type {0} is not supported. Check that you have configured the pg_hba.conf file to include the client's IP address or Subnet, and that it is using an authentication scheme supported by the driver.
  postgresql.con.authfail:An error occured while getting the authentication request.
Index: src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java,v
retrieving revision 1.28
diff -c -r1.28 ResultSet.java
*** src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java	2001/07/21 18:52:11	1.28
--- src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java	2001/08/17 14:43:49
***************
*** 61,70 ****
  {
    protected org.postgresql.jdbc2.Statement statement;
  
!   /**
!    * StringBuffer used by getTimestamp
!    */
!   private StringBuffer sbuf;
  
    /**
     * Create a new ResultSet - Note that we create ResultSets to
--- 61,67 ----
  {
    protected org.postgresql.jdbc2.Statement statement;
  
!   private StringBuffer sbuf = null;
  
    /**
     * Create a new ResultSet - Note that we create ResultSets to
***************
*** 185,198 ****
     */
    public boolean getBoolean(int columnIndex) throws SQLException
    {
!     String s = getString(columnIndex);
! 
!     if (s != null)
!       {
! 	int c = s.charAt(0);
! 	return ((c == 't') || (c == 'T') || (c == '1'));
!       }
!     return false;		// SQL NULL
    }
  
    /**
--- 182,188 ----
     */
    public boolean getBoolean(int columnIndex) throws SQLException
    {
! 	return toBoolean( getString(columnIndex) );
    }
  
    /**
***************
*** 250,267 ****
     */
    public int getInt(int columnIndex) throws SQLException
    {
!     String s = getFixedString(columnIndex);
! 
!     if (s != null)
!       {
! 	try
! 	  {
! 	    return Integer.parseInt(s);
! 	  } catch (NumberFormatException e) {
! 	    throw new PSQLException ("postgresql.res.badint",s);
! 	  }
!       }
!     return 0;		// SQL NULL
    }
  
    /**
--- 240,246 ----
     */
    public int getInt(int columnIndex) throws SQLException
    {
!     return toInt( getFixedString(columnIndex) );
    }
  
    /**
***************
*** 273,290 ****
     */
    public long getLong(int columnIndex) throws SQLException
    {
!     String s = getFixedString(columnIndex);
! 
!     if (s != null)
!       {
! 	try
! 	  {
! 	    return Long.parseLong(s);
! 	  } catch (NumberFormatException e) {
! 	    throw new PSQLException ("postgresql.res.badlong",s);
! 	  }
!       }
!     return 0;		// SQL NULL
    }
  
    /**
--- 252,258 ----
     */
    public long getLong(int columnIndex) throws SQLException
    {
!     return toLong( getFixedString(columnIndex) );
    }
  
    /**
***************
*** 296,313 ****
     */
    public float getFloat(int columnIndex) throws SQLException
    {
!     String s = getFixedString(columnIndex);
! 
!     if (s != null)
!       {
! 	try
! 	  {
! 	    return Float.valueOf(s).floatValue();
! 	  } catch (NumberFormatException e) {
! 	    throw new PSQLException ("postgresql.res.badfloat",s);
! 	  }
!       }
!     return 0;		// SQL NULL
    }
  
    /**
--- 264,270 ----
     */
    public float getFloat(int columnIndex) throws SQLException
    {
!     return toFloat( getFixedString(columnIndex) );
    }
  
    /**
***************
*** 319,336 ****
     */
    public double getDouble(int columnIndex) throws SQLException
    {
!     String s = getFixedString(columnIndex);
! 
!     if (s != null)
!       {
! 	try
! 	  {
! 	    return Double.valueOf(s).doubleValue();
! 	  } catch (NumberFormatException e) {
! 	    throw new PSQLException ("postgresql.res.baddouble",s);
! 	  }
!       }
!     return 0;		// SQL NULL
    }
  
    /**
--- 276,282 ----
     */
    public double getDouble(int columnIndex) throws SQLException
    {
!     return toDouble( getFixedString(columnIndex) );
    }
  
    /**
***************
*** 345,371 ****
     */
    public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException
    {
!     String s = getFixedString(columnIndex);
!     BigDecimal val;
! 
!     if (s != null)
!       {
! 
!         try
!           {
! 	    val = new BigDecimal(s);
! 	  } catch (NumberFormatException e) {
! 	    throw new PSQLException ("postgresql.res.badbigdec",s);
! 	  }
! 	if (scale==-1) return val;
! 	  try
! 	    {
! 	      return val.setScale(scale);
! 	    } catch (ArithmeticException e) {
! 	      throw new PSQLException ("postgresql.res.badbigdec",s);
! 	    }
!       }
!     return null;		// SQL NULL
    }
  
    /**
--- 291,297 ----
     */
    public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException
    {
!     return toBigDecimal( getFixedString(columnIndex), scale );
    }
  
    /**
***************
*** 412,427 ****
     */
    public java.sql.Date getDate(int columnIndex) throws SQLException
    {
!     String s = getString(columnIndex);
!     if(s==null)
!       return null;
!     // length == 10: SQL Date
!     // length >  10: SQL Timestamp, assumes PGDATESTYLE=ISO
!     try {
!       return java.sql.Date.valueOf((s.length() == 10) ? s : s.substring(0,10));
!     } catch (NumberFormatException e) {
!       throw new PSQLException("postgresql.res.baddate", s);
!     }
    }
  
    /**
--- 338,344 ----
     */
    public java.sql.Date getDate(int columnIndex) throws SQLException
    {
!     return toDate( getString(columnIndex) );
    }
  
    /**
***************
*** 434,450 ****
     */
    public Time getTime(int columnIndex) throws SQLException
    {
!     String s = getString(columnIndex);
! 
!     if(s==null)
!       return null; // SQL NULL
!     // length == 8: SQL Time
!     // length >  8: SQL Timestamp
!     try {
!       return java.sql.Time.valueOf((s.length() == 8) ? s : s.substring(11,19));
!     } catch (NumberFormatException e) {
!       throw new PSQLException("postgresql.res.badtime",s);
!     }
    }
  
    /**
--- 351,357 ----
     */
    public Time getTime(int columnIndex) throws SQLException
    {
!     return toTime( getString(columnIndex) );
    }
  
    /**
***************
*** 457,546 ****
     */
    public Timestamp getTimestamp(int columnIndex) throws SQLException
    {
!     String s = getString(columnIndex);
!     if(s==null)
! 	return null;
! 
!     boolean subsecond;
!     //if string contains a '.' we have fractional seconds
!     if (s.indexOf('.') == -1) {
!       subsecond = false;
!     } else {
!       subsecond = true;
!     }
! 
!     //here we are modifying the string from ISO format to a format java can understand
!     //java expects timezone info as 'GMT-08:00' instead of '-08' in postgres ISO format
!     //and java expects three digits if fractional seconds are present instead of two for postgres
!     //so this code strips off timezone info and adds on the GMT+/-...
!     //as well as adds a third digit for partial seconds if necessary
!     synchronized(this) {
!       // We must be synchronized here incase more theads access the ResultSet
!       // bad practice but possible. Anyhow this is to protect sbuf and
!       // SimpleDateFormat objects
! 
!       // First time?
!       if(sbuf==null)
!         sbuf = new StringBuffer();
! 
!       sbuf.setLength(0);
!       sbuf.append(s);
! 
!       //we are looking to see if the backend has appended on a timezone.
!       //currently postgresql will return +/-HH:MM or +/-HH for timezone offset
!       //(i.e. -06, or +06:30, note the expectation of the leading zero for the
!       //hours, and the use of the : for delimiter between hours and minutes)
!       //if the backend ISO format changes in the future this code will
!       //need to be changed as well
!       char sub = sbuf.charAt(sbuf.length()-3);
!       if (sub == '+' || sub == '-') {
!         //we have found timezone info of format +/-HH
!         sbuf.setLength(sbuf.length()-3);
!         if (subsecond)  {
!           sbuf.append('0').append("GMT").append(s.substring(s.length()-3)).append(":00");
!         } else {
!           sbuf.append("GMT").append(s.substring(s.length()-3)).append(":00");
!         }
!       } else if (sub == ':') {
!         //we may have found timezone info of format +/-HH:MM, or there is no
!         //timezone info at all and this is the : preceding the seconds
!         char sub2 = sbuf.charAt(sbuf.length()-5);
!         if (sub2 == '+' || sub2 == '-') {
!           //we have found timezone info of format +/-HH:MM
!           sbuf.setLength(sbuf.length()-5);
!           if (subsecond)  {
!             sbuf.append('0').append("GMT").append(s.substring(s.length()-5));
!           } else {
!             sbuf.append("GMT").append(s.substring(s.length()-5));
!           }
!         } else if (subsecond) {
!           sbuf.append('0');
!         }
!       } else if (subsecond) {
!         sbuf.append('0');
!       }
! 
!       // could optimize this a tad to remove too many object creations...
!       SimpleDateFormat df = null;
! 
!       if (sbuf.length()>23 && subsecond) {
!         df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSzzzzzzzzz");
!       } else if (sbuf.length()>23 && !subsecond) {
!         df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzzzzzzzz");
!       } else if (sbuf.length()>10 && subsecond) {
!         df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
!       } else if (sbuf.length()>10 && !subsecond) {
!         df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
!       } else {
!         df = new SimpleDateFormat("yyyy-MM-dd");
!       }
! 
!       try {
!           return new Timestamp(df.parse(sbuf.toString()).getTime());
!       } catch(ParseException e) {
!           throw new PSQLException("postgresql.res.badtimestamp",new Integer(e.getErrorOffset()),s);
!       }
!     }
    }
  
    /**
--- 364,370 ----
     */
    public Timestamp getTimestamp(int columnIndex) throws SQLException
    {
!     return toTimestamp( getString(columnIndex), this );
    }
  
    /**
***************
*** 960,973 ****
  	return true;
      }
  
!     public Array getArray(String colName) throws SQLException
      {
  	return getArray(findColumn(colName));
      }
  
!     public Array getArray(int i) throws SQLException
      {
! 	throw org.postgresql.Driver.notImplemented();
      }
  
      public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException
--- 784,799 ----
  	return true;
      }
  
!     public java.sql.Array getArray(String colName) throws SQLException
      {
  	return getArray(findColumn(colName));
      }
  
!     public java.sql.Array getArray(int i) throws SQLException
      {
!     	if (i < 1 || i > fields.length)
!       		throw new PSQLException("postgresql.res.colrange");
! 		return (java.sql.Array) new org.postgresql.jdbc2.Array( connection, i, fields[i-1], this );
      }
  
      public java.math.BigDecimal getBigDecimal(int columnIndex) throws SQLException
***************
*** 1486,1490 ****
--- 1312,1484 ----
        this.statement=statement;
      }
  
+ 	//----------------- Formatting Methods -------------------
+ 
+ 	public static boolean toBoolean(String s)
+ 	{
+ 		if (s != null)
+ 		{
+ 			int c = s.charAt(0);
+ 			return ((c == 't') || (c == 'T'));
+ 		}
+ 		return false;		// SQL NULL
+ 	}
+ 
+ 	public static int toInt(String s) throws SQLException
+ 	{
+ 		if (s != null)
+ 		{
+ 			try
+ 			{
+ 				return Integer.parseInt(s);
+ 			} catch (NumberFormatException e) {
+ 				throw new PSQLException ("postgresql.res.badint",s);
+ 			}
+ 		}
+ 		return 0;		// SQL NULL
+ 	}
+ 
+ 	public static long toLong(String s) throws SQLException
+ 	{
+ 		if (s != null)
+ 		{
+ 			try
+ 			{
+ 				return Long.parseLong(s);
+ 			} catch (NumberFormatException e) {
+ 				throw new PSQLException ("postgresql.res.badlong",s);
+ 			}
+ 		}
+ 		return 0;		// SQL NULL
+ 	}
+ 
+ 	public static BigDecimal toBigDecimal(String s, int scale) throws SQLException
+ 	{
+ 		BigDecimal val;
+ 		if (s != null)
+ 		{
+ 			try
+ 			{
+ 				val = new BigDecimal(s);
+ 			} catch (NumberFormatException e) {
+ 				throw new PSQLException ("postgresql.res.badbigdec",s);
+ 			}
+ 			if (scale==-1) return val;
+ 			try
+ 			{
+ 				return val.setScale(scale);
+ 			} catch (ArithmeticException e) {
+ 				throw new PSQLException ("postgresql.res.badbigdec",s);
+ 			}
+ 		}
+ 		return null;		// SQL NULL
+ 	}
+ 
+ 	public static float toFloat(String s) throws SQLException
+ 	{
+ 		if (s != null)
+ 		{
+ 			try
+ 			{
+ 				return Float.valueOf(s).floatValue();
+ 			} catch (NumberFormatException e) {
+ 				throw new PSQLException ("postgresql.res.badfloat",s);
+ 			}
+ 		}
+ 		return 0;		// SQL NULL
+ 	}
+ 
+ 	public static double toDouble(String s) throws SQLException
+ 	{
+ 		if (s != null)
+ 		{
+ 			try
+ 			{
+ 				return Double.valueOf(s).doubleValue();
+ 			} catch (NumberFormatException e) {
+ 				throw new PSQLException ("postgresql.res.baddouble",s);
+ 			}
+ 		}
+ 		return 0;		// SQL NULL
+ 	}
+ 
+ 	public static java.sql.Date toDate(String s) throws SQLException
+ 	{
+ 		if(s==null)
+ 			return null;
+ 		return java.sql.Date.valueOf(s);
+ 	}
+ 
+ 	public static Time toTime(String s) throws SQLException
+ 	{
+ 		if(s==null)
+ 			return null; // SQL NULL
+ 		return java.sql.Time.valueOf(s);
+ 	}
+ 
+ 	public static Timestamp toTimestamp(String s, ResultSet resultSet) throws SQLException
+ 	{
+ 		if(s==null)
+ 			return null;
+ 
+ 		boolean subsecond;
+ 		//if string contains a '.' we have fractional seconds
+ 		if (s.indexOf('.') == -1) {
+ 			subsecond = false;
+ 		} else {
+ 			subsecond = true;
+ 		}
+ 
+ 		//here we are modifying the string from ISO format to a format java can understand
+ 		//java expects timezone info as 'GMT-08:00' instead of '-08' in postgres ISO format
+ 		//and java expects three digits if fractional seconds are present instead of two for postgres
+ 		//so this code strips off timezone info and adds on the GMT+/-...
+ 		//as well as adds a third digit for partial seconds if necessary
+ 		synchronized(resultSet) {
+ 			// We must be synchronized here incase more theads access the ResultSet
+ 			// bad practice but possible. Anyhow this is to protect sbuf and
+ 			// SimpleDateFormat objects
+ 
+ 			// First time?
+ 			if(resultSet.sbuf==null)
+ 				resultSet.sbuf = new StringBuffer();
+ 
+ 			resultSet.sbuf.setLength(0);
+ 			resultSet.sbuf.append(s);
+ 
+ 			char sub = resultSet.sbuf.charAt(resultSet.sbuf.length()-3);
+ 			if (sub == '+' || sub == '-') {
+ 				resultSet.sbuf.setLength(resultSet.sbuf.length()-3);
+ 				if (subsecond)  {
+ 					resultSet.sbuf.append('0').append("GMT").append(s.substring(s.length()-3)).append(":00");
+ 				} else {
+ 					resultSet.sbuf.append("GMT").append(s.substring(s.length()-3)).append(":00");
+ 				}
+ 			} else if (subsecond) {
+ 				resultSet.sbuf.append('0');
+ 			}
+ 
+ 			// could optimize this a tad to remove too many object creations...
+ 			SimpleDateFormat df = null;
+ 
+ 			if (resultSet.sbuf.length()>23 && subsecond) {
+ 				df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSzzzzzzzzz");
+ 			} else if (resultSet.sbuf.length()>23 && !subsecond) {
+ 				df = new SimpleDateFormat("yyyy-MM-dd HH:mm:sszzzzzzzzz");
+ 			} else if (resultSet.sbuf.length()>10 && subsecond) {
+ 				df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ 			} else if (resultSet.sbuf.length()>10 && !subsecond) {
+ 				df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ 			} else {
+ 				df = new SimpleDateFormat("yyyy-MM-dd");
+ 			}
+ 
+ 			try {
+ 				return new Timestamp(df.parse(resultSet.sbuf.toString()).getTime());
+ 			} catch(ParseException e) {
+ 				throw new PSQLException("postgresql.res.badtimestamp",new Integer(e.getErrorOffset()),s);
+ 			}
+ 		}
+ 	}
  }
  
