From 76a6da8a1b01e23091da65f5e167d67f5274d740 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 24 Aug 2001 16:50:18 +0000 Subject: [PATCH] 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. Barry Lind --- .../jdbc/org/postgresql/Connection.java | 92 ++++++++++- src/interfaces/jdbc/org/postgresql/Field.java | 147 ++++-------------- .../jdbc/org/postgresql/jdbc1/Connection.java | 69 +++++++- .../postgresql/jdbc1/DatabaseMetaData.java | 4 +- .../jdbc/org/postgresql/jdbc1/ResultSet.java | 6 +- .../postgresql/jdbc1/ResultSetMetaData.java | 16 +- .../jdbc/org/postgresql/jdbc1/Statement.java | 2 +- .../jdbc/org/postgresql/jdbc2/Array.java | 30 ++-- .../jdbc/org/postgresql/jdbc2/Connection.java | 73 ++++++++- .../postgresql/jdbc2/DatabaseMetaData.java | 4 +- .../jdbc/org/postgresql/jdbc2/ResultSet.java | 6 +- .../postgresql/jdbc2/ResultSetMetaData.java | 16 +- 12 files changed, 294 insertions(+), 171 deletions(-) diff --git a/src/interfaces/jdbc/org/postgresql/Connection.java b/src/interfaces/jdbc/org/postgresql/Connection.java index b08de0d53e..8218f517ef 100644 --- a/src/interfaces/jdbc/org/postgresql/Connection.java +++ b/src/interfaces/jdbc/org/postgresql/Connection.java @@ -11,7 +11,7 @@ import org.postgresql.util.*; import org.postgresql.core.Encoding; /** - * $Id: Connection.java,v 1.25 2001/08/10 14:42:07 momjian Exp $ + * $Id: Connection.java,v 1.26 2001/08/24 16:50:12 momjian Exp $ * * This abstract class is used by org.postgresql.Driver to open either the JDBC1 or * JDBC2 versions of the Connection class. @@ -69,11 +69,10 @@ public abstract class Connection // 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(); + // 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,5 +1107,86 @@ public abstract class Connection { 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; + } + } diff --git a/src/interfaces/jdbc/org/postgresql/Field.java b/src/interfaces/jdbc/org/postgresql/Field.java index 8b4dcb868e..1bbc272aa8 100644 --- a/src/interfaces/jdbc/org/postgresql/Field.java +++ b/src/interfaces/jdbc/org/postgresql/Field.java @@ -12,17 +12,13 @@ import org.postgresql.util.*; */ 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 + 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 - protected Connection conn; // Connection Instantation + private 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. @@ -63,140 +59,49 @@ public class Field } /** - * 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 + * @return the mod of this Field's data type */ - public int getSQLType() throws SQLException + public int getMod() { - 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; + return mod; } /** - * 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 + * @return the name of this Field's data type */ - public static int getSQLType(String type_name) + public String getName() { - int sql_type = Types.OTHER; // default value - for(int i=0;i>16; + return ((0xFFFF0000)&f.getMod())>>16; else return 0; default: @@ -330,7 +330,7 @@ public class ResultSetMetaData implements java.sql.ResultSetMetaData case Types.NUMERIC: Field f = getField(column); if(f != null) - return (((0x0000FFFF)&f.mod)-4); + return (((0x0000FFFF)&f.getMod())-4); else return 0; default: @@ -389,7 +389,7 @@ public class ResultSetMetaData implements java.sql.ResultSetMetaData */ public String getColumnTypeName(int column) throws SQLException { - return getField(column).getTypeName(); + return getField(column).getPGType(); } /** diff --git a/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java b/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java index 7ffe96a91c..436d815d68 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java @@ -109,7 +109,7 @@ public class Statement extends org.postgresql.Statement implements java.sql.Stat public boolean execute(String sql) throws SQLException { if (escapeProcessing) - sql = escapeSql(sql); + sql = escapeSQL(sql); result = connection.ExecSQL(sql); return (result != null && ((org.postgresql.ResultSet)result).reallyResultSet()); } diff --git a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java index 5e0f86ea35..16015b881b 100644 --- a/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java +++ b/src/interfaces/jdbc/org/postgresql/jdbc2/Array.java @@ -169,11 +169,11 @@ public class Array implements java.sql.Array } public int getBaseType() throws SQLException { - return Field.getSQLType( getBaseTypeName() ); + return conn.getSQLType(getBaseTypeName()); } public String getBaseTypeName() throws SQLException { - String fType = field.getTypeName(); + String fType = field.getPGType(); if( fType.charAt(0) == '_' ) fType = fType.substring(1); return fType; @@ -195,12 +195,12 @@ public class Array implements java.sql.Array 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); + 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", field.getOID("bool"), 1); + fields[1] = new Field(conn, "VALUE", conn.getOID("bool"), 1); for( int i=0; i>16; + return ((0xFFFF0000)&f.getMod())>>16; else return 0; default: @@ -325,7 +325,7 @@ public class ResultSetMetaData implements java.sql.ResultSetMetaData case Types.NUMERIC: Field f = getField(column); if(f != null) - return (((0x0000FFFF)&f.mod)-4); + return (((0x0000FFFF)&f.getMod())-4); else return 0; default: @@ -384,7 +384,7 @@ public class ResultSetMetaData implements java.sql.ResultSetMetaData */ public String getColumnTypeName(int column) throws SQLException { - return getField(column).getTypeName(); + return getField(column).getPGType(); } /** -- 2.40.0