diff --git a/src/interfaces/jdbc/org/postgresql/Field.java b/src/interfaces/jdbc/org/postgresql/Field.java
index 6450858843c4d11c2dc421a6a46865856a8ade60..8b4dcb868e4b0d137b85a0216416d43a6a19d51b 100644
--- a/src/interfaces/jdbc/org/postgresql/Field.java
+++ b/src/interfaces/jdbc/org/postgresql/Field.java
@@ -22,6 +22,8 @@ public class Field
   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.
    *
@@ -104,6 +106,33 @@ public class Field
     return sql_type;
   }
 
+  /**
+   * 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.
@@ -126,7 +155,9 @@ public class Field
     "bool",
     "date",
     "time",
-    "abstime","timestamp"
+    "abstime","timestamp",
+	"_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
+	"_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
   };
 
   /**
@@ -149,7 +180,9 @@ public class Field
     Types.BIT,
     Types.DATE,
     Types.TIME,
-    Types.TIMESTAMP,Types.TIMESTAMP
+    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
   };
 
   /**
diff --git a/src/interfaces/jdbc/org/postgresql/errors.properties b/src/interfaces/jdbc/org/postgresql/errors.properties
index f1e2c5ce61fd5090c2bf10e5056369c8d9e54bd6..e5d35871554bc9efb4d3ca4adc67a28b3ab95552 100644
--- a/src/interfaces/jdbc/org/postgresql/errors.properties
+++ b/src/interfaces/jdbc/org/postgresql/errors.properties
@@ -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.
diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java b/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
index 868f404c77bd0319f23e562905ee122daa91fa75..6ff3b60a7453663b6cb4c3d994e3268b92e6b72c 100644
--- a/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
@@ -61,10 +61,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
 {
   protected org.postgresql.jdbc2.Statement statement;
 
-  /**
-   * StringBuffer used by getTimestamp
-   */
-  private StringBuffer sbuf;
+  private StringBuffer sbuf = null;
 
   /**
    * Create a new ResultSet - Note that we create ResultSets to
@@ -185,14 +182,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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
+	return toBoolean( getString(columnIndex) );
   }
 
   /**
@@ -250,18 +240,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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
+    return toInt( getFixedString(columnIndex) );
   }
 
   /**
@@ -273,18 +252,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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
+    return toLong( getFixedString(columnIndex) );
   }
 
   /**
@@ -296,18 +264,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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
+    return toFloat( getFixedString(columnIndex) );
   }
 
   /**
@@ -319,18 +276,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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
+    return toDouble( getFixedString(columnIndex) );
   }
 
   /**
@@ -345,27 +291,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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
+    return toBigDecimal( getFixedString(columnIndex), scale );
   }
 
   /**
@@ -412,16 +338,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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);
-    }
+    return toDate( getString(columnIndex) );
   }
 
   /**
@@ -434,17 +351,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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);
-    }
+    return toTime( getString(columnIndex) );
   }
 
   /**
@@ -457,90 +364,7 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
    */
   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);
-      }
-    }
+    return toTimestamp( getString(columnIndex), this );
   }
 
   /**
@@ -960,14 +784,16 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
 	return true;
     }
 
-    public Array getArray(String colName) throws SQLException
+    public java.sql.Array getArray(String colName) throws SQLException
     {
 	return getArray(findColumn(colName));
     }
 
-    public Array getArray(int i) throws SQLException
+    public java.sql.Array getArray(int i) throws SQLException
     {
-	throw org.postgresql.Driver.notImplemented();
+    	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,5 +1312,173 @@ public class ResultSet extends org.postgresql.ResultSet implements java.sql.Resu
       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);
+			}
+		}
+	}
 }