diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
new file mode 100644
index 00000000000..4b9931084f0
--- /dev/null
+++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
@@ -0,0 +1,312 @@
+package org.postgresql.jdbc2;
+
+import java.text.*;
+import java.sql.*;
+import java.util.*;
+import java.math.BigDecimal;
+import org.postgresql.Field;
+import org.postgresql.util.*;
+
+/**
+ * Array is used collect one column of query result data.
+ *
+ *
Read a field of type Array into either a natively-typed
+ * Java array object or a ResultSet. Accessor methods provide
+ * the ability to capture array slices.
+ *
+ *
Other than the constructor all methods are direct implementations
+ * of those specified for java.sql.Array. Please refer to the javadoc
+ * for java.sql.Array for detailed descriptions of the functionality
+ * and parameters of the methods of this class.
+ *
+ * @see ResultSet#getArray
+ */
+
+
+public class Array implements java.sql.Array
+{
+ private org.postgresql.Connection conn = null;
+ private org.postgresql.Field field = null;
+ private org.postgresql.jdbc2.ResultSet rs = null;
+ private int idx = 0;
+
+ /**
+ * Create a new Array
+ *
+ * @param conn a database connection
+ * @param idx 1-based index of the query field to load into this Array
+ * @param field the Field descriptor for the field to load into this Array
+ * @param rs the ResultSet from which to get the data for this Array
+ */
+ public Array( org.postgresql.Connection conn, int idx, Field field, org.postgresql.jdbc2.ResultSet rs ) {
+ this.conn = conn;
+ this.field = field;
+ this.rs = rs;
+ this.idx = idx;
+ }
+
+ public Object getArray() throws SQLException {
+ return getArray( 1, 0, null );
+ }
+
+ public Object getArray(long index, int count) throws SQLException {
+ return getArray( index, count, null );
+ }
+
+ public Object getArray(Map map) throws SQLException {
+ return getArray( 1, 0, map );
+ }
+
+ public Object getArray(long index, int count, Map map) throws SQLException {
+ if( map != null ) // For now maps aren't supported.
+ throw org.postgresql.Driver.notImplemented();
+
+ if (index < 1)
+ throw new PSQLException("postgresql.arr.range");
+ Object retVal = null;
+
+ ArrayList array = new ArrayList();
+ String raw = rs.getFixedString(idx);
+ if( raw != null ) {
+ char[] chars = raw.toCharArray();
+ StringBuffer sbuf = new StringBuffer();
+ boolean foundOpen = false;
+ boolean insideString = false;
+ for( int i=0; i arrayContents.length )
+ throw new PSQLException("postgresql.arr.range");
+
+ int i = 0;
+ switch ( getBaseType() )
+ {
+ case Types.BIT:
+ retVal = new boolean[ count ];
+ for( ; count > 0; count-- )
+ ((boolean[])retVal)[i++] = ResultSet.toBoolean( arrayContents[(int)index++] );
+ break;
+ case Types.SMALLINT:
+ case Types.INTEGER:
+ retVal = new int[ count ];
+ for( ; count > 0; count-- )
+ ((int[])retVal)[i++] = ResultSet.toInt( arrayContents[(int)index++] );
+ break;
+ case Types.BIGINT:
+ retVal = new long[ count ];
+ for( ; count > 0; count-- )
+ ((long[])retVal)[i++] = ResultSet.toLong( arrayContents[(int)index++] );
+ break;
+ case Types.NUMERIC:
+ retVal = new BigDecimal[ count ];
+ for( ; count > 0; count-- )
+ ((BigDecimal[])retVal)[i] = ResultSet.toBigDecimal( arrayContents[(int)index++], 0 );
+ break;
+ case Types.REAL:
+ retVal = new float[ count ];
+ for( ; count > 0; count-- )
+ ((float[])retVal)[i++] = ResultSet.toFloat( arrayContents[(int)index++] );
+ break;
+ case Types.DOUBLE:
+ retVal = new double[ count ];
+ for( ; count > 0; count-- )
+ ((double[])retVal)[i++] = ResultSet.toDouble( arrayContents[(int)index++] );
+ break;
+ case Types.CHAR:
+ case Types.VARCHAR:
+ retVal = new String[ count ];
+ for( ; count > 0; count-- )
+ ((String[])retVal)[i++] = arrayContents[(int)index++];
+ break;
+ case Types.DATE:
+ retVal = new java.sql.Date[ count ];
+ for( ; count > 0; count-- )
+ ((java.sql.Date[])retVal)[i++] = ResultSet.toDate( arrayContents[(int)index++] );
+ break;
+ case Types.TIME:
+ retVal = new java.sql.Time[ count ];
+ for( ; count > 0; count-- )
+ ((java.sql.Time[])retVal)[i++] = ResultSet.toTime( arrayContents[(int)index++] );
+ break;
+ case Types.TIMESTAMP:
+ retVal = new Timestamp[ count ];
+ StringBuffer sbuf = null;
+ for( ; count > 0; count-- )
+ ((java.sql.Timestamp[])retVal)[i++] = ResultSet.toTimestamp( arrayContents[(int)index], rs );
+ break;
+
+ // Other datatypes not currently supported. If you are really using other types ask
+ // yourself if an array of non-trivial data types is really good database design.
+ default:
+ throw org.postgresql.Driver.notImplemented();
+ }
+ return retVal;
+ }
+
+ public int getBaseType() throws SQLException {
+ return Field.getSQLType( getBaseTypeName() );
+ }
+
+ public String getBaseTypeName() throws SQLException {
+ String fType = field.getTypeName();
+ if( fType.charAt(0) == '_' )
+ fType = fType.substring(1);
+ return fType;
+ }
+
+ public java.sql.ResultSet getResultSet() throws SQLException {
+ return getResultSet( 1, 0, null );
+ }
+
+ public java.sql.ResultSet getResultSet(long index, int count) throws SQLException {
+ return getResultSet( index, count, null );
+ }
+
+ public java.sql.ResultSet getResultSet(Map map) throws SQLException {
+ return getResultSet( 1, 0, map );
+ }
+
+ public java.sql.ResultSet getResultSet(long index, int count, java.util.Map map) throws SQLException {
+ Object array = getArray( index, count, map );
+ Vector rows = new Vector();
+ Field[] fields = new Field[2];
+ fields[0] = new Field(conn, "INDEX", field.getOID("int2"), 2);
+ switch ( getBaseType() )
+ {
+ case Types.BIT:
+ boolean[] booleanArray = (boolean[]) array;
+ fields[1] = new Field(conn, "VALUE", field.getOID("bool"), 1);
+ for( int i=0; i