Thread: patch for JDBC1 build problems

patch for JDBC1 build problems

From
Barry Lind
Date:
Attached is a patch to fix the current issues with building under jdbc1.
  This patch moves the logic that looks up TypeOid, PGTypeName, and
SQLTypeName from Field to Connection.  It is moved to connection since
it needs to differ from the jdbc1 to jdbc2 versions and Connection
already has different subclasses for the two driver versions.  It also
made sense to move the logic to Connection as some of the logic was
already there anyway.

thanks,
--Barry
*** ./src/interfaces/jdbc/org/postgresql/Connection.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/Connection.java    Wed Aug 22 03:08:37 2001
***************
*** 69,79 ****
    // New for 6.3, salt value for crypt authorisation
    private String salt;

!   // This is used by Field to cache oid -> names.
!   // It's here, because it's shared across this connection only.
!   // Hence it cannot be static within the Field class, because it would then
!   // be across all connections, which could be to different backends.
!   public Hashtable fieldCache = new Hashtable();

    // Now handle notices as warnings, so things like "show" now work
    public SQLWarning firstWarning = null;
--- 69,78 ----
    // New for 6.3, salt value for crypt authorisation
    private String salt;

!   // These are used to cache oids, PGTypes and SQLTypes
!   private static Hashtable sqlTypeCache = new Hashtable();  // oid -> SQLType
!   private static Hashtable pgTypeCache = new Hashtable();  // oid -> PGType
!   private static Hashtable typeOidCache = new Hashtable();  //PGType -> oid

    // Now handle notices as warnings, so things like "show" now work
    public SQLWarning firstWarning = null;
***************
*** 1108,1112 ****
--- 1107,1192 ----
    {
        return (getDBVersionNumber().compareTo(ver) >= 0);
    }
+
+
+   /**
+    * This returns the java.sql.Types type for a PG type oid
+    *
+    * @param oid PostgreSQL type oid
+    * @return the java.sql.Types type
+    * @exception SQLException if a database access error occurs
+    */
+   public int getSQLType(int oid) throws SQLException
+   {
+     Integer sqlType = (Integer)typeOidCache.get(new Integer(oid));
+
+     // it's not in the cache, so perform a query, and add the result to the cache
+     if(sqlType==null) {
+       ResultSet result = (org.postgresql.ResultSet)ExecSQL("select typname from pg_type where oid = " + oid);
+       if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+         throw new PSQLException("postgresql.unexpected");
+       result.next();
+       String pgType = result.getString(1);
+       Integer iOid = new Integer(oid);
+       sqlType = new Integer(getSQLType(result.getString(1)));
+       sqlTypeCache.put(iOid,sqlType);
+       pgTypeCache.put(iOid,pgType);
+       result.close();
+     }
+
+     return sqlType.intValue();
+   }
+
+   /**
+    * This returns the java.sql.Types type for a PG type
+    *
+    * @param pgTypeName PostgreSQL type name
+    * @return the java.sql.Types type
+    */
+   public abstract int getSQLType(String pgTypeName);
+
+   /**
+    * This returns the oid for a given PG data type
+    * @param typeName PostgreSQL type name
+    * @return PostgreSQL oid value for a field of this type
+    */
+   public int getOID(String typeName) throws SQLException
+   {
+         int oid = -1;
+         if(typeName != null) {
+           Integer oidValue = (Integer) typeOidCache.get(typeName);
+           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)ExecSQL("select oid from pg_type where typname='"
+                                 + typeName + "'");
+             if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
+               throw new PSQLException("postgresql.unexpected");
+             result.next();
+             oid = Integer.parseInt(result.getString(1));
+             typeOidCache.put(typeName, new Integer(oid));
+             result.close();
+           }
+         }
+         return oid;
+   }
+
+   /**
+    * We also need to get the PG type name as returned by the back end.
+    *
+    * @return the String representation of the type of this field
+    * @exception SQLException if a database access error occurs
+    */
+   public String getPGType(int oid) throws SQLException
+   {
+     String pgType = (String) pgTypeCache.get(new Integer(oid));
+     if(pgType == null) {
+       getSQLType(oid);
+       pgType = (String) pgTypeCache.get(new Integer(oid));
+     }
+     return pgType;
+   }
+
  }

*** ./src/interfaces/jdbc/org/postgresql/Field.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/Field.java    Wed Aug 22 03:12:33 2001
***************
*** 12,28 ****
   */
  public class Field
  {
!   public int length;        // Internal Length of this field
!   public int oid;        // OID of the type
!   public int mod;        // type modifier of this field
!   public String name;        // Name of this field

!   protected Connection conn;    // Connection Instantation

-   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.
--- 12,24 ----
   */
  public class Field
  {
!   private int length;        // Internal Length of this field
!   private int oid;        // OID of the type
!   private int mod;        // type modifier of this field
!   private String name;        // Name of this field

!   private Connection conn;    // Connection Instantation


    /**
     * Construct a field based on the information fed to it.
***************
*** 63,202 ****
    }

    /**
!    * the ResultSet and ResultMetaData both need to handle the SQL
!    * type, which is gained from another query.  Note that we cannot
!    * use getObject() in this, since getObject uses getSQLType().
!    *
!    * @return the entry in Types that refers to this field
!    * @exception SQLException if a database access error occurs
     */
!   public int getSQLType() throws SQLException
    {
!     if(sql_type == -1) {
!       type_name = (String)conn.fieldCache.get(new Integer(oid));
!
!       // it's not in the cache, so perform a query, and add the result to
!       // the cache
!       if(type_name==null) {
!     ResultSet result = (org.postgresql.ResultSet)conn.ExecSQL("select typname from pg_type where oid = " + oid);
!     if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
!       throw new PSQLException("postgresql.unexpected");
!     result.next();
!     type_name = result.getString(1);
!     conn.fieldCache.put(new Integer(oid),type_name);
!     result.close();
!       }
!
!       sql_type = getSQLType(type_name);
!     }
!     return sql_type;
    }

    /**
!    * This returns the SQL type. It is called by the Field and DatabaseMetaData classes
!    * @param type_name PostgreSQL type name
!    * @return java.sql.Types value for oid
!    */
!   public static int getSQLType(String type_name)
!   {
!     int sql_type = Types.OTHER; // default value
!     for(int i=0;i<types.length;i++)
!       if(type_name.equals(types[i]))
!     sql_type=typei[i];
!     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.
!    * They default automatically to Types.OTHER
!    *
!    * Note: This must be in the same order as below.
     *
!    * Tip: keep these grouped together by the Types. value
     */
!   private static final String types[] = {
!     "int2",
!     "int4","oid",
!     "int8",
!     "cash","money",
!     "numeric",
!     "float4",
!     "float8",
!     "bpchar","char","char2","char4","char8","char16",
!     "varchar","text","name","filename",
!     "bool",
!     "date",
!     "time",
!     "abstime","timestamp",
!     "_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
!     "_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
!   };

    /**
!    * This table holds the JDBC type for each entry above.
     *
!    * Note: This must be in the same order as above
!    *
!    * Tip: keep these grouped together by the Types. value
!    */
!   private static final int typei[] = {
!     Types.SMALLINT,
!     Types.INTEGER,Types.INTEGER,
!     Types.BIGINT,
!     Types.DOUBLE,Types.DOUBLE,
!     Types.NUMERIC,
!     Types.REAL,
!     Types.DOUBLE,
!     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
!     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
!     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
!   };
!
!   /**
!    * We also need to get the type name as returned by the back end.
!    * This is held in type_name AFTER a call to getSQLType.  Since
!    * we get this information within getSQLType (if it isn't already
!    * done), we can just call getSQLType and throw away the result.
!    *
!    * @return the String representation of the type of this field
     * @exception SQLException if a database access error occurs
     */
!   public String getTypeName() throws SQLException
    {
!     int sql = getSQLType();
!     return type_name;
    }
  }
--- 59,107 ----
    }

    /**
!    * @return the mod of this Field's data type
     */
!   public int getMod()
    {
!     return mod;
    }

    /**
!    * @return the name of this Field's data type
!    */
!   public String getName()
!   {
!     return name;
    }

    /**
!    * @return the length of this Field's data type
!    */
!   public int getLength()
!   {
!     return length;
    }

    /**
!    * We also need to get the PG type name as returned by the back end.
     *
!    * @return the String representation of the PG type of this field
!    * @exception SQLException if a database access error occurs
     */
!   public String getPGType() throws SQLException
!   {
!     return conn.getPGType(oid);
!   }

    /**
!    * We also need to get the java.sql.types type.
     *
!    * @return the int representation of the java.sql.types type of this field
     * @exception SQLException if a database access error occurs
     */
!   public int getSQLType() throws SQLException
    {
!     return conn.getSQLType(oid);
    }
+
  }
*** ./src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java    Wed Aug 22 03:11:30 2001
***************
*** 136,141 ****
--- 136,208 ----
        // in jdbc1 stat is ignored.
          return new
org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn,fields,tuples,status,updateCount,insertOID);
      }
+
+
+   /* An implementation of the abstract method in the parent class.
+    * This implemetation uses the jdbc1Types array to support the jdbc1
+    * datatypes.  Basically jdbc1 and jdbc2 are the same, except that
+    * jdbc2 adds the Array types.
+    */
+   public int getSQLType(String pgTypeName)
+   {
+     int sqlType = Types.OTHER; // default value
+     for(int i=0;i<jdbc1Types.length;i++) {
+       if(pgTypeName.equals(jdbc1Types[i])) {
+         sqlType=jdbc1Typei[i];
+         break;
+       }
+     }
+     return sqlType;
+   }
+
+   /**
+    * 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
+    *
+    * Note: This must be in the same order as below.
+    *
+    * Tip: keep these grouped together by the Types. value
+    */
+   private static final String jdbc1Types[] = {
+     "int2",
+     "int4","oid",
+     "int8",
+     "cash","money",
+     "numeric",
+     "float4",
+     "float8",
+     "bpchar","char","char2","char4","char8","char16",
+     "varchar","text","name","filename",
+     "bool",
+     "date",
+     "time",
+     "abstime","timestamp"
+   };
+
+   /**
+    * This table holds the JDBC type for each entry above.
+    *
+    * Note: This must be in the same order as above
+    *
+    * Tip: keep these grouped together by the Types. value
+    */
+   private static final int jdbc1Typei[] = {
+     Types.SMALLINT,
+     Types.INTEGER,Types.INTEGER,
+     Types.BIGINT,
+     Types.DOUBLE,Types.DOUBLE,
+     Types.NUMERIC,
+     Types.REAL,
+     Types.DOUBLE,
+     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
+     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
+     Types.BIT,
+     Types.DATE,
+     Types.TIME,
+     Types.TIMESTAMP,Types.TIMESTAMP
+   };
+

  }

*** ./src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java    Wed Aug 22 02:28:33 2001
***************
*** 1963,1969 ****
      dr.next();
      String typname=dr.getString(1);
      dr.close();
!     tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes();    // Data type
      tuple[5] = typname.getBytes();    // Type name

      // Column size
--- 1963,1969 ----
          dr.next();
          String typname=dr.getString(1);
          dr.close();
!         tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();    // Data type
          tuple[5] = typname.getBytes();    // Type name

          // Column size
***************
*** 2596,2602 ****
      byte[][] tuple = new byte[18][];
      String typname=rs.getString(1);
      tuple[0] = typname.getBytes();
!     tuple[1] = Integer.toString(Field.getSQLType(typname)).getBytes();
      tuple[2] = b9;    // for now
      tuple[6] = bnn; // for now
      tuple[7] = bf; // false for now - not case sensitive
--- 2596,2602 ----
          byte[][] tuple = new byte[18][];
          String typname=rs.getString(1);
          tuple[0] = typname.getBytes();
!         tuple[1] = Integer.toString(connection.getSQLType(typname)).getBytes();
          tuple[2] = b9;    // for now
          tuple[6] = bnn; // for now
          tuple[7] = bf; // false for now - not case sensitive
*** ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java    Wed Aug 22 02:27:56 2001
***************
*** 782,788 ****
        case Types.BIGINT:
      return new Long(getLong(columnIndex));
        case Types.NUMERIC:
!     return getBigDecimal(columnIndex, ((field.mod-4) & 0xffff));
        case Types.REAL:
      return new Float(getFloat(columnIndex));
        case Types.DOUBLE:
--- 782,788 ----
        case Types.BIGINT:
          return new Long(getLong(columnIndex));
        case Types.NUMERIC:
!         return getBigDecimal(columnIndex, ((field.getMod()-4) & 0xffff));
        case Types.REAL:
          return new Float(getFloat(columnIndex));
        case Types.DOUBLE:
***************
*** 800,806 ****
        case Types.VARBINARY:
      return getBytes(columnIndex);
        default:
!     return connection.getObject(field.getTypeName(), getString(columnIndex));
        }
    }

--- 800,806 ----
        case Types.VARBINARY:
          return getBytes(columnIndex);
        default:
!         return connection.getObject(field.getPGType(), getString(columnIndex));
        }
    }

***************
*** 836,842 ****
      int i;

      for (i = 0 ; i < fields.length; ++i)
!       if (fields[i].name.equalsIgnoreCase(columnName))
      return (i+1);
      throw new PSQLException ("postgresql.res.colname",columnName);
    }
--- 836,842 ----
      int i;

      for (i = 0 ; i < fields.length; ++i)
!       if (fields[i].getName().equalsIgnoreCase(columnName))
          return (i+1);
      throw new PSQLException ("postgresql.res.colname",columnName);
    }
*** ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSetMetaData.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSetMetaData.java    Wed Aug 22 02:26:05 2001
***************
*** 130,136 ****
     */
    public boolean isCurrency(int column) throws SQLException
    {
!     String type_name = getField(column).getTypeName();

      return type_name.equals("cash") || type_name.equals("money");
    }
--- 130,136 ----
     */
    public boolean isCurrency(int column) throws SQLException
    {
!     String type_name = getField(column).getPGType();

      return type_name.equals("cash") || type_name.equals("money");
    }
***************
*** 189,197 ****
    public int getColumnDisplaySize(int column) throws SQLException
    {
      Field f = getField(column);
!     String type_name = f.getTypeName();
      int sql_type = f.getSQLType();
!     int typmod = f.mod;

      // I looked at other JDBC implementations and couldn't find a consistent
      // interpretation of the "display size" for numeric values, so this is our's
--- 189,197 ----
    public int getColumnDisplaySize(int column) throws SQLException
    {
      Field f = getField(column);
!     String type_name = f.getPGType();
      int sql_type = f.getSQLType();
!     int typmod = f.getMod();

      // I looked at other JDBC implementations and couldn't find a consistent
      // interpretation of the "display size" for numeric values, so this is our's
***************
*** 219,225 ****
                                             + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s digits)

      // if we don't know better
!     return f.length;
    }

    /**
--- 219,225 ----
                                             + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s digits)

      // if we don't know better
!     return f.getLength();
    }

    /**
***************
*** 246,252 ****
    {
      Field f = getField(column);
      if(f!=null)
!       return f.name;
      return "field"+column;
    }

--- 246,252 ----
    {
      Field f = getField(column);
      if(f!=null)
!       return f.getName();
      return "field"+column;
    }

***************
*** 293,299 ****
        case Types.NUMERIC:
      Field f = getField(column);
      if(f != null)
!             return ((0xFFFF0000)&f.mod)>>16;
      else
          return 0;
        default:
--- 293,299 ----
        case Types.NUMERIC:
          Field f = getField(column);
          if(f != null)
!                 return ((0xFFFF0000)&f.getMod())>>16;
          else
                  return 0;
        default:
***************
*** 330,336 ****
        case Types.NUMERIC:
      Field f = getField(column);
      if(f != null)
!         return (((0x0000FFFF)&f.mod)-4);
      else
          return 0;
        default:
--- 330,336 ----
        case Types.NUMERIC:
          Field f = getField(column);
          if(f != null)
!                 return (((0x0000FFFF)&f.getMod())-4);
          else
                  return 0;
        default:
***************
*** 389,395 ****
     */
    public String getColumnTypeName(int column) throws SQLException
    {
!     return getField(column).getTypeName();
    }

    /**
--- 389,395 ----
     */
    public String getColumnTypeName(int column) throws SQLException
    {
!     return getField(column).getPGType();
    }

    /**
*** ./src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java    Wed Aug 22 03:19:58 2001
***************
*** 109,115 ****
      public boolean execute(String sql) throws SQLException
      {
            if (escapeProcessing)
!           sql = escapeSql(sql);
            result = connection.ExecSQL(sql);
            return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
      }
--- 109,115 ----
          public boolean execute(String sql) throws SQLException
          {
            if (escapeProcessing)
!               sql = escapeSQL(sql);
            result = connection.ExecSQL(sql);
            return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
          }
*** ./src/interfaces/jdbc/org/postgresql/jdbc2/Array.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc2/Array.java    Wed Aug 22 02:03:38 2001
***************
*** 169,179 ****
      }

      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;
--- 169,179 ----
          }

          public int getBaseType() throws SQLException {
!                 return conn.getSQLType(getBaseTypeName());
          }

          public String getBaseTypeName() throws SQLException {
!                 String fType = field.getPGType();
                  if( fType.charAt(0) == '_' )
                          fType = fType.substring(1);
                  return fType;
***************
*** 195,206 ****
          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<booleanArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 195,206 ----
                  Object array = getArray( index, count, map );
                  Vector rows = new Vector();
                  Field[] fields = new Field[2];
!                 fields[0] = new Field(conn, "INDEX", conn.getOID("int2"), 2);
                  switch ( getBaseType() )
                  {
                          case Types.BIT:
                                  boolean[] booleanArray = (boolean[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("bool"), 1);
                                  for( int i=0; i<booleanArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 208,218 ****
                      rows.addElement(tuple);
                  }
              case Types.SMALLINT:
!                 fields[1] = new Field(conn, "VALUE", field.getOID("int2"), 2);
              case Types.INTEGER:
                  int[] intArray = (int[]) array;
                  if( fields[1] == null )
!                     fields[1] = new Field(conn, "VALUE", field.getOID("int4"), 4);
                  for( int i=0; i<intArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 208,218 ----
                                          rows.addElement(tuple);
                                  }
                          case Types.SMALLINT:
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("int2"), 2);
                          case Types.INTEGER:
                                  int[] intArray = (int[]) array;
                                  if( fields[1] == null )
!                                         fields[1] = new Field(conn, "VALUE", conn.getOID("int4"), 4);
                                  for( int i=0; i<intArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 222,228 ****
                  break;
              case Types.BIGINT:
                  long[] longArray = (long[]) array;
!                 fields[1] = new Field(conn, "VALUE", field.getOID("int8"), 8);
                  for( int i=0; i<longArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 222,228 ----
                                  break;
                          case Types.BIGINT:
                                  long[] longArray = (long[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("int8"), 8);
                                  for( int i=0; i<longArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 232,238 ****
                  break;
              case Types.NUMERIC:
                  BigDecimal[] bdArray = (BigDecimal[]) array;
!                 fields[1] = new Field(conn, "VALUE", field.getOID("numeric"), -1);
                  for( int i=0; i<bdArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 232,238 ----
                                  break;
                          case Types.NUMERIC:
                                  BigDecimal[] bdArray = (BigDecimal[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("numeric"), -1);
                                  for( int i=0; i<bdArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 242,248 ****
                  break;
              case Types.REAL:
                  float[] floatArray = (float[]) array;
!                 fields[1] = new Field(conn, "VALUE", field.getOID("float4"), 4);
                  for( int i=0; i<floatArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 242,248 ----
                                  break;
                          case Types.REAL:
                                  float[] floatArray = (float[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("float4"), 4);
                                  for( int i=0; i<floatArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 252,258 ****
                  break;
              case Types.DOUBLE:
                  double[] doubleArray = (double[]) array;
!                 fields[1] = new Field(conn, "VALUE", field.getOID("float8"), 8);
                  for( int i=0; i<doubleArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 252,258 ----
                                  break;
                          case Types.DOUBLE:
                                  double[] doubleArray = (double[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("float8"), 8);
                                  for( int i=0; i<doubleArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 261,271 ****
                  }
                  break;
              case Types.CHAR:
!                 fields[1] = new Field(conn, "VALUE", field.getOID("char"), 1);
              case Types.VARCHAR:
                  String[] strArray = (String[]) array;
                  if( fields[1] == null )
!                     fields[1] = new Field(conn, "VALUE", field.getOID("varchar"), -1);
                  for( int i=0; i<strArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 261,271 ----
                                  }
                                  break;
                          case Types.CHAR:
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("char"), 1);
                          case Types.VARCHAR:
                                  String[] strArray = (String[]) array;
                                  if( fields[1] == null )
!                                         fields[1] = new Field(conn, "VALUE", conn.getOID("varchar"), -1);
                                  for( int i=0; i<strArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 275,281 ****
                  break;
              case Types.DATE:
                  java.sql.Date[] dateArray = (java.sql.Date[]) array;
!                 fields[1] = new Field(conn, "VALUE", field.getOID("date"), 4);
                  for( int i=0; i<dateArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 275,281 ----
                                  break;
                          case Types.DATE:
                                  java.sql.Date[] dateArray = (java.sql.Date[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("date"), 4);
                                  for( int i=0; i<dateArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 285,291 ****
                  break;
              case Types.TIME:
                  java.sql.Time[] timeArray = (java.sql.Time[]) array;
!                 fields[1] = new Field(conn, "VALUE", field.getOID("time"), 8);
                  for( int i=0; i<timeArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 285,291 ----
                                  break;
                          case Types.TIME:
                                  java.sql.Time[] timeArray = (java.sql.Time[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("time"), 8);
                                  for( int i=0; i<timeArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
***************
*** 295,301 ****
                  break;
              case Types.TIMESTAMP:
                  java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
!                 fields[1] = new Field(conn, "VALUE", field.getOID("timestamp"), 8);
                  for( int i=0; i<timestampArray.length; i++ ) {
                      byte[][] tuple = new byte[2][0];
                        tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
--- 295,301 ----
                                  break;
                          case Types.TIMESTAMP:
                                  java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
!                                 fields[1] = new Field(conn, "VALUE", conn.getOID("timestamp"), 8);
                                  for( int i=0; i<timestampArray.length; i++ ) {
                                          byte[][] tuple = new byte[2][0];
                                          tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
*** ./src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java.orig    Wed Aug 22 02:56:24 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java    Wed Aug 22 03:12:10 2001
***************
*** 254,259 ****
--- 254,330 ----
        // Default to the original method
        return super.getObject(type,value);
      }
+
+   /* An implementation of the abstract method in the parent class.
+    * This implemetation uses the jdbc2Types array to support the jdbc2
+    * datatypes.  Basically jdbc1 and jdbc2 are the same, except that
+    * jdbc2 adds the Array types.
+    */
+   public int getSQLType(String pgTypeName)
+   {
+     int sqlType = Types.OTHER; // default value
+     for(int i=0;i<jdbc2Types.length;i++) {
+       if(pgTypeName.equals(jdbc2Types[i])) {
+         sqlType=jdbc2Typei[i];
+         break;
+       }
+     }
+     return sqlType;
+   }
+
+   /**
+    * 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
+    *
+    * Note: This must be in the same order as below.
+    *
+    * Tip: keep these grouped together by the Types. value
+    */
+   private static final String jdbc2Types[] = {
+     "int2",
+     "int4","oid",
+     "int8",
+     "cash","money",
+     "numeric",
+     "float4",
+     "float8",
+     "bpchar","char","char2","char4","char8","char16",
+     "varchar","text","name","filename",
+     "bool",
+     "date",
+     "time",
+     "abstime","timestamp",
+     "_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
+     "_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
+   };
+
+   /**
+    * This table holds the JDBC type for each entry above.
+    *
+    * Note: This must be in the same order as above
+    *
+    * Tip: keep these grouped together by the Types. value
+    */
+   private static final int jdbc2Typei[] = {
+     Types.SMALLINT,
+     Types.INTEGER,Types.INTEGER,
+     Types.BIGINT,
+     Types.DOUBLE,Types.DOUBLE,
+     Types.NUMERIC,
+     Types.REAL,
+     Types.DOUBLE,
+     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
+     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
+     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
+   };
+
+
  }

  // ***********************************************************************
*** ./src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java.orig    Wed Aug 22 02:56:25 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java    Wed Aug 22 02:07:40 2001
***************
*** 1963,1969 ****
      dr.next();
      String typname=dr.getString(1);
      dr.close();
!     tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes();    // Data type
      tuple[5] = typname.getBytes();    // Type name

      // Column size
--- 1963,1969 ----
          dr.next();
          String typname=dr.getString(1);
          dr.close();
!         tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();    // Data type
          tuple[5] = typname.getBytes();    // Type name

          // Column size
***************
*** 2600,2606 ****
      byte[][] tuple = new byte[18][];
      String typname=rs.getString(1);
      tuple[0] = typname.getBytes();
!     tuple[1] = Integer.toString(Field.getSQLType(typname)).getBytes();
      tuple[2] = b9;    // for now
      tuple[6] = bnn; // for now
      tuple[7] = bf; // false for now - not case sensitive
--- 2600,2606 ----
          byte[][] tuple = new byte[18][];
          String typname=rs.getString(1);
          tuple[0] = typname.getBytes();
!         tuple[1] = Integer.toString(connection.getSQLType(typname)).getBytes();
          tuple[2] = b9;    // for now
          tuple[6] = bnn; // for now
          tuple[7] = bf; // false for now - not case sensitive
*** ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java.orig    Wed Aug 22 02:56:25 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java    Wed Aug 22 02:10:57 2001
***************
*** 657,663 ****
      return new Long(getLong(columnIndex));
        case Types.NUMERIC:
      return getBigDecimal
!         (columnIndex, (field.mod==-1)?-1:((field.mod-4) & 0xffff));
        case Types.REAL:
      return new Float(getFloat(columnIndex));
        case Types.DOUBLE:
--- 657,663 ----
          return new Long(getLong(columnIndex));
        case Types.NUMERIC:
          return getBigDecimal
!             (columnIndex, (field.getMod()==-1)?-1:((field.getMod()-4) & 0xffff));
        case Types.REAL:
          return new Float(getFloat(columnIndex));
        case Types.DOUBLE:
***************
*** 675,681 ****
        case Types.VARBINARY:
      return getBytes(columnIndex);
        default:
!     return connection.getObject(field.getTypeName(), getString(columnIndex));
        }
    }

--- 675,681 ----
        case Types.VARBINARY:
          return getBytes(columnIndex);
        default:
!         return connection.getObject(field.getPGType(), getString(columnIndex));
        }
    }

***************
*** 711,717 ****
      int i;

      for (i = 0 ; i < fields.length; ++i)
!       if (fields[i].name.equalsIgnoreCase(columnName))
      return (i+1);
      throw new PSQLException ("postgresql.res.colname",columnName);
    }
--- 711,717 ----
      int i;

      for (i = 0 ; i < fields.length; ++i)
!       if (fields[i].getName().equalsIgnoreCase(columnName))
          return (i+1);
      throw new PSQLException ("postgresql.res.colname",columnName);
    }
*** ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSetMetaData.java.orig    Wed Aug 22 02:56:25 2001
--- ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSetMetaData.java    Wed Aug 22 02:26:49 2001
***************
*** 125,131 ****
     */
    public boolean isCurrency(int column) throws SQLException
    {
!     String type_name = getField(column).getTypeName();

      return type_name.equals("cash") || type_name.equals("money");
    }
--- 125,131 ----
     */
    public boolean isCurrency(int column) throws SQLException
    {
!     String type_name = getField(column).getPGType();

      return type_name.equals("cash") || type_name.equals("money");
    }
***************
*** 184,192 ****
    public int getColumnDisplaySize(int column) throws SQLException
    {
      Field f = getField(column);
!     String type_name = f.getTypeName();
      int sql_type = f.getSQLType();
!     int typmod = f.mod;

      // I looked at other JDBC implementations and couldn't find a consistent
      // interpretation of the "display size" for numeric values, so this is our's
--- 184,192 ----
    public int getColumnDisplaySize(int column) throws SQLException
    {
      Field f = getField(column);
!     String type_name = f.getPGType();
      int sql_type = f.getSQLType();
!     int typmod = f.getMod();

      // I looked at other JDBC implementations and couldn't find a consistent
      // interpretation of the "display size" for numeric values, so this is our's
***************
*** 214,220 ****
                                             + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s digits)

      // if we don't know better
!     return f.length;
    }

    /**
--- 214,220 ----
                                             + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s digits)

      // if we don't know better
!     return f.getLength();
    }

    /**
***************
*** 241,247 ****
    {
      Field f = getField(column);
      if(f!=null)
!       return f.name;
      return "field"+column;
    }

--- 241,247 ----
    {
      Field f = getField(column);
      if(f!=null)
!       return f.getName();
      return "field"+column;
    }

***************
*** 288,294 ****
        case Types.NUMERIC:
      Field f = getField(column);
      if(f != null)
!             return ((0xFFFF0000)&f.mod)>>16;
      else
          return 0;
        default:
--- 288,294 ----
        case Types.NUMERIC:
          Field f = getField(column);
          if(f != null)
!                 return ((0xFFFF0000)&f.getMod())>>16;
          else
                  return 0;
        default:
***************
*** 325,331 ****
        case Types.NUMERIC:
      Field f = getField(column);
      if(f != null)
!         return (((0x0000FFFF)&f.mod)-4);
      else
          return 0;
        default:
--- 325,331 ----
        case Types.NUMERIC:
          Field f = getField(column);
          if(f != null)
!                 return (((0x0000FFFF)&f.getMod())-4);
          else
                  return 0;
        default:
***************
*** 384,390 ****
     */
    public String getColumnTypeName(int column) throws SQLException
    {
!     return getField(column).getTypeName();
    }

    /**
--- 384,390 ----
     */
    public String getColumnTypeName(int column) throws SQLException
    {
!     return getField(column).getPGType();
    }

    /**

Re: [PATCHES] patch for JDBC1 build problems

From
Bruce Momjian
Date:
Your patch has been added to the PostgreSQL unapplied patches list at:

    http://candle.pha.pa.us/cgi-bin/pgpatches

I will try to apply it within the next 48 hours.

>
> Attached is a patch to fix the current issues with building under jdbc1.
>   This patch moves the logic that looks up TypeOid, PGTypeName, and
> SQLTypeName from Field to Connection.  It is moved to connection since
> it needs to differ from the jdbc1 to jdbc2 versions and Connection
> already has different subclasses for the two driver versions.  It also
> made sense to move the logic to Connection as some of the logic was
> already there anyway.
>
> thanks,
> --Barry

> *** ./src/interfaces/jdbc/org/postgresql/Connection.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/Connection.java    Wed Aug 22 03:08:37 2001
> ***************
> *** 69,79 ****
>     // New for 6.3, salt value for crypt authorisation
>     private String salt;
>
> !   // This is used by Field to cache oid -> names.
> !   // It's here, because it's shared across this connection only.
> !   // Hence it cannot be static within the Field class, because it would then
> !   // be across all connections, which could be to different backends.
> !   public Hashtable fieldCache = new Hashtable();
>
>     // Now handle notices as warnings, so things like "show" now work
>     public SQLWarning firstWarning = null;
> --- 69,78 ----
>     // New for 6.3, salt value for crypt authorisation
>     private String salt;
>
> !   // These are used to cache oids, PGTypes and SQLTypes
> !   private static Hashtable sqlTypeCache = new Hashtable();  // oid -> SQLType
> !   private static Hashtable pgTypeCache = new Hashtable();  // oid -> PGType
> !   private static Hashtable typeOidCache = new Hashtable();  //PGType -> oid
>
>     // Now handle notices as warnings, so things like "show" now work
>     public SQLWarning firstWarning = null;
> ***************
> *** 1108,1112 ****
> --- 1107,1192 ----
>     {
>         return (getDBVersionNumber().compareTo(ver) >= 0);
>     }
> +
> +
> +   /**
> +    * This returns the java.sql.Types type for a PG type oid
> +    *
> +    * @param oid PostgreSQL type oid
> +    * @return the java.sql.Types type
> +    * @exception SQLException if a database access error occurs
> +    */
> +   public int getSQLType(int oid) throws SQLException
> +   {
> +     Integer sqlType = (Integer)typeOidCache.get(new Integer(oid));
> +
> +     // it's not in the cache, so perform a query, and add the result to the cache
> +     if(sqlType==null) {
> +       ResultSet result = (org.postgresql.ResultSet)ExecSQL("select typname from pg_type where oid = " + oid);
> +       if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
> +         throw new PSQLException("postgresql.unexpected");
> +       result.next();
> +       String pgType = result.getString(1);
> +       Integer iOid = new Integer(oid);
> +       sqlType = new Integer(getSQLType(result.getString(1)));
> +       sqlTypeCache.put(iOid,sqlType);
> +       pgTypeCache.put(iOid,pgType);
> +       result.close();
> +     }
> +
> +     return sqlType.intValue();
> +   }
> +
> +   /**
> +    * This returns the java.sql.Types type for a PG type
> +    *
> +    * @param pgTypeName PostgreSQL type name
> +    * @return the java.sql.Types type
> +    */
> +   public abstract int getSQLType(String pgTypeName);
> +
> +   /**
> +    * This returns the oid for a given PG data type
> +    * @param typeName PostgreSQL type name
> +    * @return PostgreSQL oid value for a field of this type
> +    */
> +   public int getOID(String typeName) throws SQLException
> +   {
> +         int oid = -1;
> +         if(typeName != null) {
> +           Integer oidValue = (Integer) typeOidCache.get(typeName);
> +           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)ExecSQL("select oid from pg_type where typname='"
> +                                 + typeName + "'");
> +             if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
> +               throw new PSQLException("postgresql.unexpected");
> +             result.next();
> +             oid = Integer.parseInt(result.getString(1));
> +             typeOidCache.put(typeName, new Integer(oid));
> +             result.close();
> +           }
> +         }
> +         return oid;
> +   }
> +
> +   /**
> +    * We also need to get the PG type name as returned by the back end.
> +    *
> +    * @return the String representation of the type of this field
> +    * @exception SQLException if a database access error occurs
> +    */
> +   public String getPGType(int oid) throws SQLException
> +   {
> +     String pgType = (String) pgTypeCache.get(new Integer(oid));
> +     if(pgType == null) {
> +       getSQLType(oid);
> +       pgType = (String) pgTypeCache.get(new Integer(oid));
> +     }
> +     return pgType;
> +   }
> +
>   }
>
> *** ./src/interfaces/jdbc/org/postgresql/Field.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/Field.java    Wed Aug 22 03:12:33 2001
> ***************
> *** 12,28 ****
>    */
>   public class Field
>   {
> !   public int length;        // Internal Length of this field
> !   public int oid;        // OID of the type
> !   public int mod;        // type modifier of this field
> !   public String name;        // Name of this field
>
> !   protected Connection conn;    // Connection Instantation
>
> -   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.
> --- 12,24 ----
>    */
>   public class Field
>   {
> !   private int length;        // Internal Length of this field
> !   private int oid;        // OID of the type
> !   private int mod;        // type modifier of this field
> !   private String name;        // Name of this field
>
> !   private Connection conn;    // Connection Instantation
>
>
>     /**
>      * Construct a field based on the information fed to it.
> ***************
> *** 63,202 ****
>     }
>
>     /**
> !    * the ResultSet and ResultMetaData both need to handle the SQL
> !    * type, which is gained from another query.  Note that we cannot
> !    * use getObject() in this, since getObject uses getSQLType().
> !    *
> !    * @return the entry in Types that refers to this field
> !    * @exception SQLException if a database access error occurs
>      */
> !   public int getSQLType() throws SQLException
>     {
> !     if(sql_type == -1) {
> !       type_name = (String)conn.fieldCache.get(new Integer(oid));
> !
> !       // it's not in the cache, so perform a query, and add the result to
> !       // the cache
> !       if(type_name==null) {
> !     ResultSet result = (org.postgresql.ResultSet)conn.ExecSQL("select typname from pg_type where oid = " + oid);
> !     if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
> !       throw new PSQLException("postgresql.unexpected");
> !     result.next();
> !     type_name = result.getString(1);
> !     conn.fieldCache.put(new Integer(oid),type_name);
> !     result.close();
> !       }
> !
> !       sql_type = getSQLType(type_name);
> !     }
> !     return sql_type;
>     }
>
>     /**
> !    * This returns the SQL type. It is called by the Field and DatabaseMetaData classes
> !    * @param type_name PostgreSQL type name
> !    * @return java.sql.Types value for oid
> !    */
> !   public static int getSQLType(String type_name)
> !   {
> !     int sql_type = Types.OTHER; // default value
> !     for(int i=0;i<types.length;i++)
> !       if(type_name.equals(types[i]))
> !     sql_type=typei[i];
> !     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.
> !    * They default automatically to Types.OTHER
> !    *
> !    * Note: This must be in the same order as below.
>      *
> !    * Tip: keep these grouped together by the Types. value
>      */
> !   private static final String types[] = {
> !     "int2",
> !     "int4","oid",
> !     "int8",
> !     "cash","money",
> !     "numeric",
> !     "float4",
> !     "float8",
> !     "bpchar","char","char2","char4","char8","char16",
> !     "varchar","text","name","filename",
> !     "bool",
> !     "date",
> !     "time",
> !     "abstime","timestamp",
> !     "_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
> !     "_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
> !   };
>
>     /**
> !    * This table holds the JDBC type for each entry above.
>      *
> !    * Note: This must be in the same order as above
> !    *
> !    * Tip: keep these grouped together by the Types. value
> !    */
> !   private static final int typei[] = {
> !     Types.SMALLINT,
> !     Types.INTEGER,Types.INTEGER,
> !     Types.BIGINT,
> !     Types.DOUBLE,Types.DOUBLE,
> !     Types.NUMERIC,
> !     Types.REAL,
> !     Types.DOUBLE,
> !     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
> !     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
> !     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
> !   };
> !
> !   /**
> !    * We also need to get the type name as returned by the back end.
> !    * This is held in type_name AFTER a call to getSQLType.  Since
> !    * we get this information within getSQLType (if it isn't already
> !    * done), we can just call getSQLType and throw away the result.
> !    *
> !    * @return the String representation of the type of this field
>      * @exception SQLException if a database access error occurs
>      */
> !   public String getTypeName() throws SQLException
>     {
> !     int sql = getSQLType();
> !     return type_name;
>     }
>   }
> --- 59,107 ----
>     }
>
>     /**
> !    * @return the mod of this Field's data type
>      */
> !   public int getMod()
>     {
> !     return mod;
>     }
>
>     /**
> !    * @return the name of this Field's data type
> !    */
> !   public String getName()
> !   {
> !     return name;
>     }
>
>     /**
> !    * @return the length of this Field's data type
> !    */
> !   public int getLength()
> !   {
> !     return length;
>     }
>
>     /**
> !    * We also need to get the PG type name as returned by the back end.
>      *
> !    * @return the String representation of the PG type of this field
> !    * @exception SQLException if a database access error occurs
>      */
> !   public String getPGType() throws SQLException
> !   {
> !     return conn.getPGType(oid);
> !   }
>
>     /**
> !    * We also need to get the java.sql.types type.
>      *
> !    * @return the int representation of the java.sql.types type of this field
>      * @exception SQLException if a database access error occurs
>      */
> !   public int getSQLType() throws SQLException
>     {
> !     return conn.getSQLType(oid);
>     }
> +
>   }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java    Wed Aug 22 03:11:30 2001
> ***************
> *** 136,141 ****
> --- 136,208 ----
>         // in jdbc1 stat is ignored.
>           return new
org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn,fields,tuples,status,updateCount,insertOID);
>       }
> +
> +
> +   /* An implementation of the abstract method in the parent class.
> +    * This implemetation uses the jdbc1Types array to support the jdbc1
> +    * datatypes.  Basically jdbc1 and jdbc2 are the same, except that
> +    * jdbc2 adds the Array types.
> +    */
> +   public int getSQLType(String pgTypeName)
> +   {
> +     int sqlType = Types.OTHER; // default value
> +     for(int i=0;i<jdbc1Types.length;i++) {
> +       if(pgTypeName.equals(jdbc1Types[i])) {
> +         sqlType=jdbc1Typei[i];
> +         break;
> +       }
> +     }
> +     return sqlType;
> +   }
> +
> +   /**
> +    * 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
> +    *
> +    * Note: This must be in the same order as below.
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final String jdbc1Types[] = {
> +     "int2",
> +     "int4","oid",
> +     "int8",
> +     "cash","money",
> +     "numeric",
> +     "float4",
> +     "float8",
> +     "bpchar","char","char2","char4","char8","char16",
> +     "varchar","text","name","filename",
> +     "bool",
> +     "date",
> +     "time",
> +     "abstime","timestamp"
> +   };
> +
> +   /**
> +    * This table holds the JDBC type for each entry above.
> +    *
> +    * Note: This must be in the same order as above
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final int jdbc1Typei[] = {
> +     Types.SMALLINT,
> +     Types.INTEGER,Types.INTEGER,
> +     Types.BIGINT,
> +     Types.DOUBLE,Types.DOUBLE,
> +     Types.NUMERIC,
> +     Types.REAL,
> +     Types.DOUBLE,
> +     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
> +     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
> +     Types.BIT,
> +     Types.DATE,
> +     Types.TIME,
> +     Types.TIMESTAMP,Types.TIMESTAMP
> +   };
> +
>
>   }
>
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java    Wed Aug 22 02:28:33 2001
> ***************
> *** 1963,1969 ****
>       dr.next();
>       String typname=dr.getString(1);
>       dr.close();
> !     tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes();    // Data type
>       tuple[5] = typname.getBytes();    // Type name
>
>       // Column size
> --- 1963,1969 ----
>           dr.next();
>           String typname=dr.getString(1);
>           dr.close();
> !         tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();    // Data type
>           tuple[5] = typname.getBytes();    // Type name
>
>           // Column size
> ***************
> *** 2596,2602 ****
>       byte[][] tuple = new byte[18][];
>       String typname=rs.getString(1);
>       tuple[0] = typname.getBytes();
> !     tuple[1] = Integer.toString(Field.getSQLType(typname)).getBytes();
>       tuple[2] = b9;    // for now
>       tuple[6] = bnn; // for now
>       tuple[7] = bf; // false for now - not case sensitive
> --- 2596,2602 ----
>           byte[][] tuple = new byte[18][];
>           String typname=rs.getString(1);
>           tuple[0] = typname.getBytes();
> !         tuple[1] = Integer.toString(connection.getSQLType(typname)).getBytes();
>           tuple[2] = b9;    // for now
>           tuple[6] = bnn; // for now
>           tuple[7] = bf; // false for now - not case sensitive
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java    Wed Aug 22 02:27:56 2001
> ***************
> *** 782,788 ****
>         case Types.BIGINT:
>       return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
> !     return getBigDecimal(columnIndex, ((field.mod-4) & 0xffff));
>         case Types.REAL:
>       return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> --- 782,788 ----
>         case Types.BIGINT:
>           return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
> !         return getBigDecimal(columnIndex, ((field.getMod()-4) & 0xffff));
>         case Types.REAL:
>           return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> ***************
> *** 800,806 ****
>         case Types.VARBINARY:
>       return getBytes(columnIndex);
>         default:
> !     return connection.getObject(field.getTypeName(), getString(columnIndex));
>         }
>     }
>
> --- 800,806 ----
>         case Types.VARBINARY:
>           return getBytes(columnIndex);
>         default:
> !         return connection.getObject(field.getPGType(), getString(columnIndex));
>         }
>     }
>
> ***************
> *** 836,842 ****
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].name.equalsIgnoreCase(columnName))
>       return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> --- 836,842 ----
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].getName().equalsIgnoreCase(columnName))
>           return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSetMetaData.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSetMetaData.java    Wed Aug 22 02:26:05 2001
> ***************
> *** 130,136 ****
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getTypeName();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> --- 130,136 ----
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getPGType();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> ***************
> *** 189,197 ****
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getTypeName();
>       int sql_type = f.getSQLType();
> !     int typmod = f.mod;
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> --- 189,197 ----
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getPGType();
>       int sql_type = f.getSQLType();
> !     int typmod = f.getMod();
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> ***************
> *** 219,225 ****
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.length;
>     }
>
>     /**
> --- 219,225 ----
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.getLength();
>     }
>
>     /**
> ***************
> *** 246,252 ****
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.name;
>       return "field"+column;
>     }
>
> --- 246,252 ----
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.getName();
>       return "field"+column;
>     }
>
> ***************
> *** 293,299 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !             return ((0xFFFF0000)&f.mod)>>16;
>       else
>           return 0;
>         default:
> --- 293,299 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return ((0xFFFF0000)&f.getMod())>>16;
>           else
>                   return 0;
>         default:
> ***************
> *** 330,336 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !         return (((0x0000FFFF)&f.mod)-4);
>       else
>           return 0;
>         default:
> --- 330,336 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return (((0x0000FFFF)&f.getMod())-4);
>           else
>                   return 0;
>         default:
> ***************
> *** 389,395 ****
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getTypeName();
>     }
>
>     /**
> --- 389,395 ----
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getPGType();
>     }
>
>     /**
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java    Wed Aug 22 03:19:58 2001
> ***************
> *** 109,115 ****
>       public boolean execute(String sql) throws SQLException
>       {
>             if (escapeProcessing)
> !           sql = escapeSql(sql);
>             result = connection.ExecSQL(sql);
>             return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
>       }
> --- 109,115 ----
>           public boolean execute(String sql) throws SQLException
>           {
>             if (escapeProcessing)
> !               sql = escapeSQL(sql);
>             result = connection.ExecSQL(sql);
>             return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
>           }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/Array.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/Array.java    Wed Aug 22 02:03:38 2001
> ***************
> *** 169,179 ****
>       }
>
>       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;
> --- 169,179 ----
>           }
>
>           public int getBaseType() throws SQLException {
> !                 return conn.getSQLType(getBaseTypeName());
>           }
>
>           public String getBaseTypeName() throws SQLException {
> !                 String fType = field.getPGType();
>                   if( fType.charAt(0) == '_' )
>                           fType = fType.substring(1);
>                   return fType;
> ***************
> *** 195,206 ****
>           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<booleanArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 195,206 ----
>                   Object array = getArray( index, count, map );
>                   Vector rows = new Vector();
>                   Field[] fields = new Field[2];
> !                 fields[0] = new Field(conn, "INDEX", conn.getOID("int2"), 2);
>                   switch ( getBaseType() )
>                   {
>                           case Types.BIT:
>                                   boolean[] booleanArray = (boolean[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("bool"), 1);
>                                   for( int i=0; i<booleanArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 208,218 ****
>                       rows.addElement(tuple);
>                   }
>               case Types.SMALLINT:
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("int2"), 2);
>               case Types.INTEGER:
>                   int[] intArray = (int[]) array;
>                   if( fields[1] == null )
> !                     fields[1] = new Field(conn, "VALUE", field.getOID("int4"), 4);
>                   for( int i=0; i<intArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 208,218 ----
>                                           rows.addElement(tuple);
>                                   }
>                           case Types.SMALLINT:
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("int2"), 2);
>                           case Types.INTEGER:
>                                   int[] intArray = (int[]) array;
>                                   if( fields[1] == null )
> !                                         fields[1] = new Field(conn, "VALUE", conn.getOID("int4"), 4);
>                                   for( int i=0; i<intArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 222,228 ****
>                   break;
>               case Types.BIGINT:
>                   long[] longArray = (long[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("int8"), 8);
>                   for( int i=0; i<longArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 222,228 ----
>                                   break;
>                           case Types.BIGINT:
>                                   long[] longArray = (long[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("int8"), 8);
>                                   for( int i=0; i<longArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 232,238 ****
>                   break;
>               case Types.NUMERIC:
>                   BigDecimal[] bdArray = (BigDecimal[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("numeric"), -1);
>                   for( int i=0; i<bdArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 232,238 ----
>                                   break;
>                           case Types.NUMERIC:
>                                   BigDecimal[] bdArray = (BigDecimal[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("numeric"), -1);
>                                   for( int i=0; i<bdArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 242,248 ****
>                   break;
>               case Types.REAL:
>                   float[] floatArray = (float[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("float4"), 4);
>                   for( int i=0; i<floatArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 242,248 ----
>                                   break;
>                           case Types.REAL:
>                                   float[] floatArray = (float[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("float4"), 4);
>                                   for( int i=0; i<floatArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 252,258 ****
>                   break;
>               case Types.DOUBLE:
>                   double[] doubleArray = (double[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("float8"), 8);
>                   for( int i=0; i<doubleArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 252,258 ----
>                                   break;
>                           case Types.DOUBLE:
>                                   double[] doubleArray = (double[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("float8"), 8);
>                                   for( int i=0; i<doubleArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 261,271 ****
>                   }
>                   break;
>               case Types.CHAR:
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("char"), 1);
>               case Types.VARCHAR:
>                   String[] strArray = (String[]) array;
>                   if( fields[1] == null )
> !                     fields[1] = new Field(conn, "VALUE", field.getOID("varchar"), -1);
>                   for( int i=0; i<strArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 261,271 ----
>                                   }
>                                   break;
>                           case Types.CHAR:
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("char"), 1);
>                           case Types.VARCHAR:
>                                   String[] strArray = (String[]) array;
>                                   if( fields[1] == null )
> !                                         fields[1] = new Field(conn, "VALUE", conn.getOID("varchar"), -1);
>                                   for( int i=0; i<strArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 275,281 ****
>                   break;
>               case Types.DATE:
>                   java.sql.Date[] dateArray = (java.sql.Date[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("date"), 4);
>                   for( int i=0; i<dateArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 275,281 ----
>                                   break;
>                           case Types.DATE:
>                                   java.sql.Date[] dateArray = (java.sql.Date[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("date"), 4);
>                                   for( int i=0; i<dateArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 285,291 ****
>                   break;
>               case Types.TIME:
>                   java.sql.Time[] timeArray = (java.sql.Time[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("time"), 8);
>                   for( int i=0; i<timeArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 285,291 ----
>                                   break;
>                           case Types.TIME:
>                                   java.sql.Time[] timeArray = (java.sql.Time[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("time"), 8);
>                                   for( int i=0; i<timeArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 295,301 ****
>                   break;
>               case Types.TIMESTAMP:
>                   java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("timestamp"), 8);
>                   for( int i=0; i<timestampArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 295,301 ----
>                                   break;
>                           case Types.TIMESTAMP:
>                                   java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("timestamp"), 8);
>                                   for( int i=0; i<timestampArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java    Wed Aug 22 03:12:10 2001
> ***************
> *** 254,259 ****
> --- 254,330 ----
>         // Default to the original method
>         return super.getObject(type,value);
>       }
> +
> +   /* An implementation of the abstract method in the parent class.
> +    * This implemetation uses the jdbc2Types array to support the jdbc2
> +    * datatypes.  Basically jdbc1 and jdbc2 are the same, except that
> +    * jdbc2 adds the Array types.
> +    */
> +   public int getSQLType(String pgTypeName)
> +   {
> +     int sqlType = Types.OTHER; // default value
> +     for(int i=0;i<jdbc2Types.length;i++) {
> +       if(pgTypeName.equals(jdbc2Types[i])) {
> +         sqlType=jdbc2Typei[i];
> +         break;
> +       }
> +     }
> +     return sqlType;
> +   }
> +
> +   /**
> +    * 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
> +    *
> +    * Note: This must be in the same order as below.
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final String jdbc2Types[] = {
> +     "int2",
> +     "int4","oid",
> +     "int8",
> +     "cash","money",
> +     "numeric",
> +     "float4",
> +     "float8",
> +     "bpchar","char","char2","char4","char8","char16",
> +     "varchar","text","name","filename",
> +     "bool",
> +     "date",
> +     "time",
> +     "abstime","timestamp",
> +     "_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
> +     "_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
> +   };
> +
> +   /**
> +    * This table holds the JDBC type for each entry above.
> +    *
> +    * Note: This must be in the same order as above
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final int jdbc2Typei[] = {
> +     Types.SMALLINT,
> +     Types.INTEGER,Types.INTEGER,
> +     Types.BIGINT,
> +     Types.DOUBLE,Types.DOUBLE,
> +     Types.NUMERIC,
> +     Types.REAL,
> +     Types.DOUBLE,
> +     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
> +     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
> +     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
> +   };
> +
> +
>   }
>
>   // ***********************************************************************
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java.orig    Wed Aug 22 02:56:25 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java    Wed Aug 22 02:07:40 2001
> ***************
> *** 1963,1969 ****
>       dr.next();
>       String typname=dr.getString(1);
>       dr.close();
> !     tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes();    // Data type
>       tuple[5] = typname.getBytes();    // Type name
>
>       // Column size
> --- 1963,1969 ----
>           dr.next();
>           String typname=dr.getString(1);
>           dr.close();
> !         tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();    // Data type
>           tuple[5] = typname.getBytes();    // Type name
>
>           // Column size
> ***************
> *** 2600,2606 ****
>       byte[][] tuple = new byte[18][];
>       String typname=rs.getString(1);
>       tuple[0] = typname.getBytes();
> !     tuple[1] = Integer.toString(Field.getSQLType(typname)).getBytes();
>       tuple[2] = b9;    // for now
>       tuple[6] = bnn; // for now
>       tuple[7] = bf; // false for now - not case sensitive
> --- 2600,2606 ----
>           byte[][] tuple = new byte[18][];
>           String typname=rs.getString(1);
>           tuple[0] = typname.getBytes();
> !         tuple[1] = Integer.toString(connection.getSQLType(typname)).getBytes();
>           tuple[2] = b9;    // for now
>           tuple[6] = bnn; // for now
>           tuple[7] = bf; // false for now - not case sensitive
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java.orig    Wed Aug 22 02:56:25 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java    Wed Aug 22 02:10:57 2001
> ***************
> *** 657,663 ****
>       return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
>       return getBigDecimal
> !         (columnIndex, (field.mod==-1)?-1:((field.mod-4) & 0xffff));
>         case Types.REAL:
>       return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> --- 657,663 ----
>           return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
>           return getBigDecimal
> !             (columnIndex, (field.getMod()==-1)?-1:((field.getMod()-4) & 0xffff));
>         case Types.REAL:
>           return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> ***************
> *** 675,681 ****
>         case Types.VARBINARY:
>       return getBytes(columnIndex);
>         default:
> !     return connection.getObject(field.getTypeName(), getString(columnIndex));
>         }
>     }
>
> --- 675,681 ----
>         case Types.VARBINARY:
>           return getBytes(columnIndex);
>         default:
> !         return connection.getObject(field.getPGType(), getString(columnIndex));
>         }
>     }
>
> ***************
> *** 711,717 ****
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].name.equalsIgnoreCase(columnName))
>       return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> --- 711,717 ----
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].getName().equalsIgnoreCase(columnName))
>           return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSetMetaData.java.orig    Wed Aug 22 02:56:25 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSetMetaData.java    Wed Aug 22 02:26:49 2001
> ***************
> *** 125,131 ****
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getTypeName();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> --- 125,131 ----
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getPGType();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> ***************
> *** 184,192 ****
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getTypeName();
>       int sql_type = f.getSQLType();
> !     int typmod = f.mod;
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> --- 184,192 ----
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getPGType();
>       int sql_type = f.getSQLType();
> !     int typmod = f.getMod();
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> ***************
> *** 214,220 ****
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.length;
>     }
>
>     /**
> --- 214,220 ----
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.getLength();
>     }
>
>     /**
> ***************
> *** 241,247 ****
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.name;
>       return "field"+column;
>     }
>
> --- 241,247 ----
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.getName();
>       return "field"+column;
>     }
>
> ***************
> *** 288,294 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !             return ((0xFFFF0000)&f.mod)>>16;
>       else
>           return 0;
>         default:
> --- 288,294 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return ((0xFFFF0000)&f.getMod())>>16;
>           else
>                   return 0;
>         default:
> ***************
> *** 325,331 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !         return (((0x0000FFFF)&f.mod)-4);
>       else
>           return 0;
>         default:
> --- 325,331 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return (((0x0000FFFF)&f.getMod())-4);
>           else
>                   return 0;
>         default:
> ***************
> *** 384,390 ****
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getTypeName();
>     }
>
>     /**
> --- 384,390 ----
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getPGType();
>     }
>
>     /**

>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Re: [PATCHES] patch for JDBC1 build problems

From
Bruce Momjian
Date:
Thanks.  Patch applied.


>
> Attached is a patch to fix the current issues with building under jdbc1.
>   This patch moves the logic that looks up TypeOid, PGTypeName, and
> SQLTypeName from Field to Connection.  It is moved to connection since
> it needs to differ from the jdbc1 to jdbc2 versions and Connection
> already has different subclasses for the two driver versions.  It also
> made sense to move the logic to Connection as some of the logic was
> already there anyway.
>
> thanks,
> --Barry

> *** ./src/interfaces/jdbc/org/postgresql/Connection.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/Connection.java    Wed Aug 22 03:08:37 2001
> ***************
> *** 69,79 ****
>     // New for 6.3, salt value for crypt authorisation
>     private String salt;
>
> !   // This is used by Field to cache oid -> names.
> !   // It's here, because it's shared across this connection only.
> !   // Hence it cannot be static within the Field class, because it would then
> !   // be across all connections, which could be to different backends.
> !   public Hashtable fieldCache = new Hashtable();
>
>     // Now handle notices as warnings, so things like "show" now work
>     public SQLWarning firstWarning = null;
> --- 69,78 ----
>     // New for 6.3, salt value for crypt authorisation
>     private String salt;
>
> !   // These are used to cache oids, PGTypes and SQLTypes
> !   private static Hashtable sqlTypeCache = new Hashtable();  // oid -> SQLType
> !   private static Hashtable pgTypeCache = new Hashtable();  // oid -> PGType
> !   private static Hashtable typeOidCache = new Hashtable();  //PGType -> oid
>
>     // Now handle notices as warnings, so things like "show" now work
>     public SQLWarning firstWarning = null;
> ***************
> *** 1108,1112 ****
> --- 1107,1192 ----
>     {
>         return (getDBVersionNumber().compareTo(ver) >= 0);
>     }
> +
> +
> +   /**
> +    * This returns the java.sql.Types type for a PG type oid
> +    *
> +    * @param oid PostgreSQL type oid
> +    * @return the java.sql.Types type
> +    * @exception SQLException if a database access error occurs
> +    */
> +   public int getSQLType(int oid) throws SQLException
> +   {
> +     Integer sqlType = (Integer)typeOidCache.get(new Integer(oid));
> +
> +     // it's not in the cache, so perform a query, and add the result to the cache
> +     if(sqlType==null) {
> +       ResultSet result = (org.postgresql.ResultSet)ExecSQL("select typname from pg_type where oid = " + oid);
> +       if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
> +         throw new PSQLException("postgresql.unexpected");
> +       result.next();
> +       String pgType = result.getString(1);
> +       Integer iOid = new Integer(oid);
> +       sqlType = new Integer(getSQLType(result.getString(1)));
> +       sqlTypeCache.put(iOid,sqlType);
> +       pgTypeCache.put(iOid,pgType);
> +       result.close();
> +     }
> +
> +     return sqlType.intValue();
> +   }
> +
> +   /**
> +    * This returns the java.sql.Types type for a PG type
> +    *
> +    * @param pgTypeName PostgreSQL type name
> +    * @return the java.sql.Types type
> +    */
> +   public abstract int getSQLType(String pgTypeName);
> +
> +   /**
> +    * This returns the oid for a given PG data type
> +    * @param typeName PostgreSQL type name
> +    * @return PostgreSQL oid value for a field of this type
> +    */
> +   public int getOID(String typeName) throws SQLException
> +   {
> +         int oid = -1;
> +         if(typeName != null) {
> +           Integer oidValue = (Integer) typeOidCache.get(typeName);
> +           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)ExecSQL("select oid from pg_type where typname='"
> +                                 + typeName + "'");
> +             if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
> +               throw new PSQLException("postgresql.unexpected");
> +             result.next();
> +             oid = Integer.parseInt(result.getString(1));
> +             typeOidCache.put(typeName, new Integer(oid));
> +             result.close();
> +           }
> +         }
> +         return oid;
> +   }
> +
> +   /**
> +    * We also need to get the PG type name as returned by the back end.
> +    *
> +    * @return the String representation of the type of this field
> +    * @exception SQLException if a database access error occurs
> +    */
> +   public String getPGType(int oid) throws SQLException
> +   {
> +     String pgType = (String) pgTypeCache.get(new Integer(oid));
> +     if(pgType == null) {
> +       getSQLType(oid);
> +       pgType = (String) pgTypeCache.get(new Integer(oid));
> +     }
> +     return pgType;
> +   }
> +
>   }
>
> *** ./src/interfaces/jdbc/org/postgresql/Field.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/Field.java    Wed Aug 22 03:12:33 2001
> ***************
> *** 12,28 ****
>    */
>   public class Field
>   {
> !   public int length;        // Internal Length of this field
> !   public int oid;        // OID of the type
> !   public int mod;        // type modifier of this field
> !   public String name;        // Name of this field
>
> !   protected Connection conn;    // Connection Instantation
>
> -   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.
> --- 12,24 ----
>    */
>   public class Field
>   {
> !   private int length;        // Internal Length of this field
> !   private int oid;        // OID of the type
> !   private int mod;        // type modifier of this field
> !   private String name;        // Name of this field
>
> !   private Connection conn;    // Connection Instantation
>
>
>     /**
>      * Construct a field based on the information fed to it.
> ***************
> *** 63,202 ****
>     }
>
>     /**
> !    * the ResultSet and ResultMetaData both need to handle the SQL
> !    * type, which is gained from another query.  Note that we cannot
> !    * use getObject() in this, since getObject uses getSQLType().
> !    *
> !    * @return the entry in Types that refers to this field
> !    * @exception SQLException if a database access error occurs
>      */
> !   public int getSQLType() throws SQLException
>     {
> !     if(sql_type == -1) {
> !       type_name = (String)conn.fieldCache.get(new Integer(oid));
> !
> !       // it's not in the cache, so perform a query, and add the result to
> !       // the cache
> !       if(type_name==null) {
> !     ResultSet result = (org.postgresql.ResultSet)conn.ExecSQL("select typname from pg_type where oid = " + oid);
> !     if (result.getColumnCount() != 1 || result.getTupleCount() != 1)
> !       throw new PSQLException("postgresql.unexpected");
> !     result.next();
> !     type_name = result.getString(1);
> !     conn.fieldCache.put(new Integer(oid),type_name);
> !     result.close();
> !       }
> !
> !       sql_type = getSQLType(type_name);
> !     }
> !     return sql_type;
>     }
>
>     /**
> !    * This returns the SQL type. It is called by the Field and DatabaseMetaData classes
> !    * @param type_name PostgreSQL type name
> !    * @return java.sql.Types value for oid
> !    */
> !   public static int getSQLType(String type_name)
> !   {
> !     int sql_type = Types.OTHER; // default value
> !     for(int i=0;i<types.length;i++)
> !       if(type_name.equals(types[i]))
> !     sql_type=typei[i];
> !     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.
> !    * They default automatically to Types.OTHER
> !    *
> !    * Note: This must be in the same order as below.
>      *
> !    * Tip: keep these grouped together by the Types. value
>      */
> !   private static final String types[] = {
> !     "int2",
> !     "int4","oid",
> !     "int8",
> !     "cash","money",
> !     "numeric",
> !     "float4",
> !     "float8",
> !     "bpchar","char","char2","char4","char8","char16",
> !     "varchar","text","name","filename",
> !     "bool",
> !     "date",
> !     "time",
> !     "abstime","timestamp",
> !     "_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
> !     "_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
> !   };
>
>     /**
> !    * This table holds the JDBC type for each entry above.
>      *
> !    * Note: This must be in the same order as above
> !    *
> !    * Tip: keep these grouped together by the Types. value
> !    */
> !   private static final int typei[] = {
> !     Types.SMALLINT,
> !     Types.INTEGER,Types.INTEGER,
> !     Types.BIGINT,
> !     Types.DOUBLE,Types.DOUBLE,
> !     Types.NUMERIC,
> !     Types.REAL,
> !     Types.DOUBLE,
> !     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
> !     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
> !     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
> !   };
> !
> !   /**
> !    * We also need to get the type name as returned by the back end.
> !    * This is held in type_name AFTER a call to getSQLType.  Since
> !    * we get this information within getSQLType (if it isn't already
> !    * done), we can just call getSQLType and throw away the result.
> !    *
> !    * @return the String representation of the type of this field
>      * @exception SQLException if a database access error occurs
>      */
> !   public String getTypeName() throws SQLException
>     {
> !     int sql = getSQLType();
> !     return type_name;
>     }
>   }
> --- 59,107 ----
>     }
>
>     /**
> !    * @return the mod of this Field's data type
>      */
> !   public int getMod()
>     {
> !     return mod;
>     }
>
>     /**
> !    * @return the name of this Field's data type
> !    */
> !   public String getName()
> !   {
> !     return name;
>     }
>
>     /**
> !    * @return the length of this Field's data type
> !    */
> !   public int getLength()
> !   {
> !     return length;
>     }
>
>     /**
> !    * We also need to get the PG type name as returned by the back end.
>      *
> !    * @return the String representation of the PG type of this field
> !    * @exception SQLException if a database access error occurs
>      */
> !   public String getPGType() throws SQLException
> !   {
> !     return conn.getPGType(oid);
> !   }
>
>     /**
> !    * We also need to get the java.sql.types type.
>      *
> !    * @return the int representation of the java.sql.types type of this field
>      * @exception SQLException if a database access error occurs
>      */
> !   public int getSQLType() throws SQLException
>     {
> !     return conn.getSQLType(oid);
>     }
> +
>   }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java    Wed Aug 22 03:11:30 2001
> ***************
> *** 136,141 ****
> --- 136,208 ----
>         // in jdbc1 stat is ignored.
>           return new
org.postgresql.jdbc1.ResultSet((org.postgresql.jdbc1.Connection)conn,fields,tuples,status,updateCount,insertOID);
>       }
> +
> +
> +   /* An implementation of the abstract method in the parent class.
> +    * This implemetation uses the jdbc1Types array to support the jdbc1
> +    * datatypes.  Basically jdbc1 and jdbc2 are the same, except that
> +    * jdbc2 adds the Array types.
> +    */
> +   public int getSQLType(String pgTypeName)
> +   {
> +     int sqlType = Types.OTHER; // default value
> +     for(int i=0;i<jdbc1Types.length;i++) {
> +       if(pgTypeName.equals(jdbc1Types[i])) {
> +         sqlType=jdbc1Typei[i];
> +         break;
> +       }
> +     }
> +     return sqlType;
> +   }
> +
> +   /**
> +    * 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
> +    *
> +    * Note: This must be in the same order as below.
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final String jdbc1Types[] = {
> +     "int2",
> +     "int4","oid",
> +     "int8",
> +     "cash","money",
> +     "numeric",
> +     "float4",
> +     "float8",
> +     "bpchar","char","char2","char4","char8","char16",
> +     "varchar","text","name","filename",
> +     "bool",
> +     "date",
> +     "time",
> +     "abstime","timestamp"
> +   };
> +
> +   /**
> +    * This table holds the JDBC type for each entry above.
> +    *
> +    * Note: This must be in the same order as above
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final int jdbc1Typei[] = {
> +     Types.SMALLINT,
> +     Types.INTEGER,Types.INTEGER,
> +     Types.BIGINT,
> +     Types.DOUBLE,Types.DOUBLE,
> +     Types.NUMERIC,
> +     Types.REAL,
> +     Types.DOUBLE,
> +     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
> +     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
> +     Types.BIT,
> +     Types.DATE,
> +     Types.TIME,
> +     Types.TIMESTAMP,Types.TIMESTAMP
> +   };
> +
>
>   }
>
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java    Wed Aug 22 02:28:33 2001
> ***************
> *** 1963,1969 ****
>       dr.next();
>       String typname=dr.getString(1);
>       dr.close();
> !     tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes();    // Data type
>       tuple[5] = typname.getBytes();    // Type name
>
>       // Column size
> --- 1963,1969 ----
>           dr.next();
>           String typname=dr.getString(1);
>           dr.close();
> !         tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();    // Data type
>           tuple[5] = typname.getBytes();    // Type name
>
>           // Column size
> ***************
> *** 2596,2602 ****
>       byte[][] tuple = new byte[18][];
>       String typname=rs.getString(1);
>       tuple[0] = typname.getBytes();
> !     tuple[1] = Integer.toString(Field.getSQLType(typname)).getBytes();
>       tuple[2] = b9;    // for now
>       tuple[6] = bnn; // for now
>       tuple[7] = bf; // false for now - not case sensitive
> --- 2596,2602 ----
>           byte[][] tuple = new byte[18][];
>           String typname=rs.getString(1);
>           tuple[0] = typname.getBytes();
> !         tuple[1] = Integer.toString(connection.getSQLType(typname)).getBytes();
>           tuple[2] = b9;    // for now
>           tuple[6] = bnn; // for now
>           tuple[7] = bf; // false for now - not case sensitive
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java    Wed Aug 22 02:27:56 2001
> ***************
> *** 782,788 ****
>         case Types.BIGINT:
>       return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
> !     return getBigDecimal(columnIndex, ((field.mod-4) & 0xffff));
>         case Types.REAL:
>       return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> --- 782,788 ----
>         case Types.BIGINT:
>           return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
> !         return getBigDecimal(columnIndex, ((field.getMod()-4) & 0xffff));
>         case Types.REAL:
>           return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> ***************
> *** 800,806 ****
>         case Types.VARBINARY:
>       return getBytes(columnIndex);
>         default:
> !     return connection.getObject(field.getTypeName(), getString(columnIndex));
>         }
>     }
>
> --- 800,806 ----
>         case Types.VARBINARY:
>           return getBytes(columnIndex);
>         default:
> !         return connection.getObject(field.getPGType(), getString(columnIndex));
>         }
>     }
>
> ***************
> *** 836,842 ****
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].name.equalsIgnoreCase(columnName))
>       return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> --- 836,842 ----
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].getName().equalsIgnoreCase(columnName))
>           return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSetMetaData.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/ResultSetMetaData.java    Wed Aug 22 02:26:05 2001
> ***************
> *** 130,136 ****
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getTypeName();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> --- 130,136 ----
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getPGType();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> ***************
> *** 189,197 ****
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getTypeName();
>       int sql_type = f.getSQLType();
> !     int typmod = f.mod;
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> --- 189,197 ----
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getPGType();
>       int sql_type = f.getSQLType();
> !     int typmod = f.getMod();
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> ***************
> *** 219,225 ****
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.length;
>     }
>
>     /**
> --- 219,225 ----
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.getLength();
>     }
>
>     /**
> ***************
> *** 246,252 ****
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.name;
>       return "field"+column;
>     }
>
> --- 246,252 ----
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.getName();
>       return "field"+column;
>     }
>
> ***************
> *** 293,299 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !             return ((0xFFFF0000)&f.mod)>>16;
>       else
>           return 0;
>         default:
> --- 293,299 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return ((0xFFFF0000)&f.getMod())>>16;
>           else
>                   return 0;
>         default:
> ***************
> *** 330,336 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !         return (((0x0000FFFF)&f.mod)-4);
>       else
>           return 0;
>         default:
> --- 330,336 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return (((0x0000FFFF)&f.getMod())-4);
>           else
>                   return 0;
>         default:
> ***************
> *** 389,395 ****
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getTypeName();
>     }
>
>     /**
> --- 389,395 ----
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getPGType();
>     }
>
>     /**
> *** ./src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java    Wed Aug 22 03:19:58 2001
> ***************
> *** 109,115 ****
>       public boolean execute(String sql) throws SQLException
>       {
>             if (escapeProcessing)
> !           sql = escapeSql(sql);
>             result = connection.ExecSQL(sql);
>             return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
>       }
> --- 109,115 ----
>           public boolean execute(String sql) throws SQLException
>           {
>             if (escapeProcessing)
> !               sql = escapeSQL(sql);
>             result = connection.ExecSQL(sql);
>             return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet());
>           }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/Array.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/Array.java    Wed Aug 22 02:03:38 2001
> ***************
> *** 169,179 ****
>       }
>
>       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;
> --- 169,179 ----
>           }
>
>           public int getBaseType() throws SQLException {
> !                 return conn.getSQLType(getBaseTypeName());
>           }
>
>           public String getBaseTypeName() throws SQLException {
> !                 String fType = field.getPGType();
>                   if( fType.charAt(0) == '_' )
>                           fType = fType.substring(1);
>                   return fType;
> ***************
> *** 195,206 ****
>           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<booleanArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 195,206 ----
>                   Object array = getArray( index, count, map );
>                   Vector rows = new Vector();
>                   Field[] fields = new Field[2];
> !                 fields[0] = new Field(conn, "INDEX", conn.getOID("int2"), 2);
>                   switch ( getBaseType() )
>                   {
>                           case Types.BIT:
>                                   boolean[] booleanArray = (boolean[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("bool"), 1);
>                                   for( int i=0; i<booleanArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 208,218 ****
>                       rows.addElement(tuple);
>                   }
>               case Types.SMALLINT:
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("int2"), 2);
>               case Types.INTEGER:
>                   int[] intArray = (int[]) array;
>                   if( fields[1] == null )
> !                     fields[1] = new Field(conn, "VALUE", field.getOID("int4"), 4);
>                   for( int i=0; i<intArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 208,218 ----
>                                           rows.addElement(tuple);
>                                   }
>                           case Types.SMALLINT:
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("int2"), 2);
>                           case Types.INTEGER:
>                                   int[] intArray = (int[]) array;
>                                   if( fields[1] == null )
> !                                         fields[1] = new Field(conn, "VALUE", conn.getOID("int4"), 4);
>                                   for( int i=0; i<intArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 222,228 ****
>                   break;
>               case Types.BIGINT:
>                   long[] longArray = (long[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("int8"), 8);
>                   for( int i=0; i<longArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 222,228 ----
>                                   break;
>                           case Types.BIGINT:
>                                   long[] longArray = (long[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("int8"), 8);
>                                   for( int i=0; i<longArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 232,238 ****
>                   break;
>               case Types.NUMERIC:
>                   BigDecimal[] bdArray = (BigDecimal[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("numeric"), -1);
>                   for( int i=0; i<bdArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 232,238 ----
>                                   break;
>                           case Types.NUMERIC:
>                                   BigDecimal[] bdArray = (BigDecimal[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("numeric"), -1);
>                                   for( int i=0; i<bdArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 242,248 ****
>                   break;
>               case Types.REAL:
>                   float[] floatArray = (float[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("float4"), 4);
>                   for( int i=0; i<floatArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 242,248 ----
>                                   break;
>                           case Types.REAL:
>                                   float[] floatArray = (float[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("float4"), 4);
>                                   for( int i=0; i<floatArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 252,258 ****
>                   break;
>               case Types.DOUBLE:
>                   double[] doubleArray = (double[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("float8"), 8);
>                   for( int i=0; i<doubleArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 252,258 ----
>                                   break;
>                           case Types.DOUBLE:
>                                   double[] doubleArray = (double[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("float8"), 8);
>                                   for( int i=0; i<doubleArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 261,271 ****
>                   }
>                   break;
>               case Types.CHAR:
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("char"), 1);
>               case Types.VARCHAR:
>                   String[] strArray = (String[]) array;
>                   if( fields[1] == null )
> !                     fields[1] = new Field(conn, "VALUE", field.getOID("varchar"), -1);
>                   for( int i=0; i<strArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 261,271 ----
>                                   }
>                                   break;
>                           case Types.CHAR:
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("char"), 1);
>                           case Types.VARCHAR:
>                                   String[] strArray = (String[]) array;
>                                   if( fields[1] == null )
> !                                         fields[1] = new Field(conn, "VALUE", conn.getOID("varchar"), -1);
>                                   for( int i=0; i<strArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 275,281 ****
>                   break;
>               case Types.DATE:
>                   java.sql.Date[] dateArray = (java.sql.Date[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("date"), 4);
>                   for( int i=0; i<dateArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 275,281 ----
>                                   break;
>                           case Types.DATE:
>                                   java.sql.Date[] dateArray = (java.sql.Date[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("date"), 4);
>                                   for( int i=0; i<dateArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 285,291 ****
>                   break;
>               case Types.TIME:
>                   java.sql.Time[] timeArray = (java.sql.Time[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("time"), 8);
>                   for( int i=0; i<timeArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 285,291 ----
>                                   break;
>                           case Types.TIME:
>                                   java.sql.Time[] timeArray = (java.sql.Time[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("time"), 8);
>                                   for( int i=0; i<timeArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> ***************
> *** 295,301 ****
>                   break;
>               case Types.TIMESTAMP:
>                   java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
> !                 fields[1] = new Field(conn, "VALUE", field.getOID("timestamp"), 8);
>                   for( int i=0; i<timestampArray.length; i++ ) {
>                       byte[][] tuple = new byte[2][0];
>                         tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); // Index
> --- 295,301 ----
>                                   break;
>                           case Types.TIMESTAMP:
>                                   java.sql.Timestamp[] timestampArray = (java.sql.Timestamp[]) array;
> !                                 fields[1] = new Field(conn, "VALUE", conn.getOID("timestamp"), 8);
>                                   for( int i=0; i<timestampArray.length; i++ ) {
>                                           byte[][] tuple = new byte[2][0];
>                                           tuple[0] = conn.getEncoding().encode( Integer.toString((int)index+i) ); //
Index
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java.orig    Wed Aug 22 02:56:24 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java    Wed Aug 22 03:12:10 2001
> ***************
> *** 254,259 ****
> --- 254,330 ----
>         // Default to the original method
>         return super.getObject(type,value);
>       }
> +
> +   /* An implementation of the abstract method in the parent class.
> +    * This implemetation uses the jdbc2Types array to support the jdbc2
> +    * datatypes.  Basically jdbc1 and jdbc2 are the same, except that
> +    * jdbc2 adds the Array types.
> +    */
> +   public int getSQLType(String pgTypeName)
> +   {
> +     int sqlType = Types.OTHER; // default value
> +     for(int i=0;i<jdbc2Types.length;i++) {
> +       if(pgTypeName.equals(jdbc2Types[i])) {
> +         sqlType=jdbc2Typei[i];
> +         break;
> +       }
> +     }
> +     return sqlType;
> +   }
> +
> +   /**
> +    * 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
> +    *
> +    * Note: This must be in the same order as below.
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final String jdbc2Types[] = {
> +     "int2",
> +     "int4","oid",
> +     "int8",
> +     "cash","money",
> +     "numeric",
> +     "float4",
> +     "float8",
> +     "bpchar","char","char2","char4","char8","char16",
> +     "varchar","text","name","filename",
> +     "bool",
> +     "date",
> +     "time",
> +     "abstime","timestamp",
> +     "_bool", "_char", "_int2", "_int4", "_text", "_oid", "_varchar", "_int8",
> +     "_float4", "_float8", "_abstime", "_date", "_time", "_timestamp", "_numeric"
> +   };
> +
> +   /**
> +    * This table holds the JDBC type for each entry above.
> +    *
> +    * Note: This must be in the same order as above
> +    *
> +    * Tip: keep these grouped together by the Types. value
> +    */
> +   private static final int jdbc2Typei[] = {
> +     Types.SMALLINT,
> +     Types.INTEGER,Types.INTEGER,
> +     Types.BIGINT,
> +     Types.DOUBLE,Types.DOUBLE,
> +     Types.NUMERIC,
> +     Types.REAL,
> +     Types.DOUBLE,
> +     Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,Types.CHAR,
> +     Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,Types.VARCHAR,
> +     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
> +   };
> +
> +
>   }
>
>   // ***********************************************************************
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java.orig    Wed Aug 22 02:56:25 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java    Wed Aug 22 02:07:40 2001
> ***************
> *** 1963,1969 ****
>       dr.next();
>       String typname=dr.getString(1);
>       dr.close();
> !     tuple[4] = Integer.toString(Field.getSQLType(typname)).getBytes();    // Data type
>       tuple[5] = typname.getBytes();    // Type name
>
>       // Column size
> --- 1963,1969 ----
>           dr.next();
>           String typname=dr.getString(1);
>           dr.close();
> !         tuple[4] = Integer.toString(connection.getSQLType(typname)).getBytes();    // Data type
>           tuple[5] = typname.getBytes();    // Type name
>
>           // Column size
> ***************
> *** 2600,2606 ****
>       byte[][] tuple = new byte[18][];
>       String typname=rs.getString(1);
>       tuple[0] = typname.getBytes();
> !     tuple[1] = Integer.toString(Field.getSQLType(typname)).getBytes();
>       tuple[2] = b9;    // for now
>       tuple[6] = bnn; // for now
>       tuple[7] = bf; // false for now - not case sensitive
> --- 2600,2606 ----
>           byte[][] tuple = new byte[18][];
>           String typname=rs.getString(1);
>           tuple[0] = typname.getBytes();
> !         tuple[1] = Integer.toString(connection.getSQLType(typname)).getBytes();
>           tuple[2] = b9;    // for now
>           tuple[6] = bnn; // for now
>           tuple[7] = bf; // false for now - not case sensitive
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java.orig    Wed Aug 22 02:56:25 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java    Wed Aug 22 02:10:57 2001
> ***************
> *** 657,663 ****
>       return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
>       return getBigDecimal
> !         (columnIndex, (field.mod==-1)?-1:((field.mod-4) & 0xffff));
>         case Types.REAL:
>       return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> --- 657,663 ----
>           return new Long(getLong(columnIndex));
>         case Types.NUMERIC:
>           return getBigDecimal
> !             (columnIndex, (field.getMod()==-1)?-1:((field.getMod()-4) & 0xffff));
>         case Types.REAL:
>           return new Float(getFloat(columnIndex));
>         case Types.DOUBLE:
> ***************
> *** 675,681 ****
>         case Types.VARBINARY:
>       return getBytes(columnIndex);
>         default:
> !     return connection.getObject(field.getTypeName(), getString(columnIndex));
>         }
>     }
>
> --- 675,681 ----
>         case Types.VARBINARY:
>           return getBytes(columnIndex);
>         default:
> !         return connection.getObject(field.getPGType(), getString(columnIndex));
>         }
>     }
>
> ***************
> *** 711,717 ****
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].name.equalsIgnoreCase(columnName))
>       return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> --- 711,717 ----
>       int i;
>
>       for (i = 0 ; i < fields.length; ++i)
> !       if (fields[i].getName().equalsIgnoreCase(columnName))
>           return (i+1);
>       throw new PSQLException ("postgresql.res.colname",columnName);
>     }
> *** ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSetMetaData.java.orig    Wed Aug 22 02:56:25 2001
> --- ./src/interfaces/jdbc/org/postgresql/jdbc2/ResultSetMetaData.java    Wed Aug 22 02:26:49 2001
> ***************
> *** 125,131 ****
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getTypeName();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> --- 125,131 ----
>      */
>     public boolean isCurrency(int column) throws SQLException
>     {
> !     String type_name = getField(column).getPGType();
>
>       return type_name.equals("cash") || type_name.equals("money");
>     }
> ***************
> *** 184,192 ****
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getTypeName();
>       int sql_type = f.getSQLType();
> !     int typmod = f.mod;
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> --- 184,192 ----
>     public int getColumnDisplaySize(int column) throws SQLException
>     {
>       Field f = getField(column);
> !     String type_name = f.getPGType();
>       int sql_type = f.getSQLType();
> !     int typmod = f.getMod();
>
>       // I looked at other JDBC implementations and couldn't find a consistent
>       // interpretation of the "display size" for numeric values, so this is our's
> ***************
> *** 214,220 ****
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.length;
>     }
>
>     /**
> --- 214,220 ----
>                                              + 1 + ( typmod        & 0xffff ); // DECIMAL(p,s) = (p digits).(s
digits)
>
>       // if we don't know better
> !     return f.getLength();
>     }
>
>     /**
> ***************
> *** 241,247 ****
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.name;
>       return "field"+column;
>     }
>
> --- 241,247 ----
>     {
>       Field f = getField(column);
>       if(f!=null)
> !       return f.getName();
>       return "field"+column;
>     }
>
> ***************
> *** 288,294 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !             return ((0xFFFF0000)&f.mod)>>16;
>       else
>           return 0;
>         default:
> --- 288,294 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return ((0xFFFF0000)&f.getMod())>>16;
>           else
>                   return 0;
>         default:
> ***************
> *** 325,331 ****
>         case Types.NUMERIC:
>       Field f = getField(column);
>       if(f != null)
> !         return (((0x0000FFFF)&f.mod)-4);
>       else
>           return 0;
>         default:
> --- 325,331 ----
>         case Types.NUMERIC:
>           Field f = getField(column);
>           if(f != null)
> !                 return (((0x0000FFFF)&f.getMod())-4);
>           else
>                   return 0;
>         default:
> ***************
> *** 384,390 ****
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getTypeName();
>     }
>
>     /**
> --- 384,390 ----
>      */
>     public String getColumnTypeName(int column) throws SQLException
>     {
> !     return getField(column).getPGType();
>     }
>
>     /**

>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026