Thread: JDBC SQLStatus for Dynamic SQL, unsupported feature, invalid transaction state and others
JDBC SQLStatus for Dynamic SQL, unsupported feature, invalid transaction state and others
From
Fernando Nasser
Date:
This patch includes all the others and adds SQLState support for the following additional conditions: public static final PSQLState parameter_mismatch = new PSQLState("07001"); public static final PSQLState inv_parameter_type = new PSQLState("07006"); public static final PSQLState unable_to_connect = new PSQLState("08001"); public static final PSQLState inexistent_connection = new PSQLState("08003"); public static final PSQLState connection_rejected = new PSQLState("08004"); public static final PSQLState connection_failure = new PSQLState("08006"); public static final PSQLState feature_not_supported = new PSQLState("0A000"); public static final PSQLState data_exception = new PSQLState("22000"); public static final PSQLState inv_transaction_state = new PSQLState("25000"); -- Fernando Nasser Red Hat - Toronto E-Mail: fnasser@redhat.com 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9 ? src/interfaces/jdbc/org/postgresql/util/PSQLState.java Index: src/interfaces/jdbc/org/postgresql/PG_Stream.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/PG_Stream.java,v retrieving revision 1.17 diff -c -p -r1.17 PG_Stream.java *** src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/08/20 04:26:02 1.17 --- src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/11/25 22:17:47 *************** public class PG_Stream *** 137,147 **** { c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof"); } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return c; } --- 137,147 ---- { c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); } return c; } *************** public class PG_Stream *** 164,176 **** int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof"); n = n | (b << (8 * i)) ; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return n; } --- 164,176 ---- int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); n = n | (b << (8 * i)) ; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); } return n; } *************** public class PG_Stream *** 193,205 **** int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof"); n = b | (n << 8); } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return n; } --- 193,205 ---- int b = pg_input.read(); if (b < 0) ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); n = b | (n << 8); } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); } return n; } *************** public class PG_Stream *** 227,233 **** { int c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof"); else if (c == 0) { rst[s] = 0; --- 227,233 ---- { int c = pg_input.read(); if (c < 0) ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); else if (c == 0) { rst[s] = 0; *************** public class PG_Stream *** 250,256 **** } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } return encoding.decode(rst, 0, s); } --- 250,256 ---- } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); } return encoding.decode(rst, 0, s); } *************** public class PG_Stream *** 330,342 **** { int w = pg_input.read(b, off + s, siz - s); if (w < 0) ! throw new PSQLException("postgresql.stream.eof"); s += w; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", e); } } --- 330,342 ---- { int w = pg_input.read(b, off + s, siz - s); if (w < 0) ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); s += w; } } catch (IOException e) { ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); } } *************** public class PG_Stream *** 353,359 **** } catch (IOException e) { ! throw new PSQLException("postgresql.stream.flush", e); } } --- 353,359 ---- } catch (IOException e) { ! throw new PSQLException("postgresql.stream.flush", PSQLException.comm_link_error, e); } } Index: src/interfaces/jdbc/org/postgresql/errors.properties =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/errors.properties,v retrieving revision 1.15 diff -c -p -r1.15 errors.properties *** src/interfaces/jdbc/org/postgresql/errors.properties 2002/11/14 05:35:45 1.15 --- src/interfaces/jdbc/org/postgresql/errors.properties 2002/11/25 22:17:47 *************** postgresql.updateable.beforestartdelete: *** 83,89 **** postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). postgresql.updateable.notoninsertrow:Not on insert row. postgresql.updateable.inputstream:Input Stream is null. ! postgresql.updateable.ioerror:Input Stream Error. postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)'was made. postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. --- 83,89 ---- postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). postgresql.updateable.notoninsertrow:Not on insert row. postgresql.updateable.inputstream:Input Stream is null. ! postgresql.updateable.ioerror:Input Stream Error - {0} postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)'was made. postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. Index: src/interfaces/jdbc/org/postgresql/core/Encoding.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/Encoding.java,v retrieving revision 1.8 diff -c -p -r1.8 Encoding.java *** src/interfaces/jdbc/org/postgresql/core/Encoding.java 2002/11/14 05:35:45 1.8 --- src/interfaces/jdbc/org/postgresql/core/Encoding.java 2002/11/25 22:17:47 *************** public class Encoding *** 72,82 **** } /* ! * Get an Encoding for from the given database encoding and * the encoding passed in by the user. */ ! public static Encoding getEncoding(String databaseEncoding, ! String passedEncoding) { if (passedEncoding != null) { --- 72,82 ---- } /* ! * Get an Encoding from the given database encoding and * the encoding passed in by the user. + * Return null if cannot find a suitable one. */ ! public static Encoding getEncoding(String databaseEncoding, String passedEncoding) { if (passedEncoding != null) { *************** public class Encoding *** 86,121 **** } else { ! return defaultEncoding(); } } else { ! return encodingForDatabaseEncoding(databaseEncoding); ! } ! } ! ! /* ! * Get an Encoding matching the given database encoding. ! */ ! private static Encoding encodingForDatabaseEncoding(String databaseEncoding) ! { ! // If the backend encoding is known and there is a suitable ! // encoding in the JVM we use that. Otherwise we fall back ! // to the default encoding of the JVM. ! ! if (encodings.containsKey(databaseEncoding)) ! { ! String[] candidates = (String[]) encodings.get(databaseEncoding); ! for (int i = 0; i < candidates.length; i++) { ! if (isAvailable(candidates[i])) { ! return new Encoding(candidates[i]); } } } - return defaultEncoding(); } /* --- 86,116 ---- } else { ! // Requested encoding not available in the JVM ! return null; } } else { ! // Get an Encoding matching the given database encoding. ! // If the backend encoding is known and there is a suitable ! // encoding in the JVM we return that. ! ! if (encodings.containsKey(databaseEncoding)) { ! String[] candidates = (String[]) encodings.get(databaseEncoding); ! for (int i = 0; i < candidates.length; i++) { ! if (isAvailable(candidates[i])) ! { ! return new Encoding(candidates[i]); ! } } } + + // Bakend encoding UNKNOWN or not available in the JVM + return null; } } /* *************** public class Encoding *** 144,150 **** } catch (UnsupportedEncodingException e) { ! throw new PSQLException("postgresql.stream.encoding", e); } } --- 139,146 ---- } catch (UnsupportedEncodingException e) { ! // This will never happen as we made sure that the encoding is valid when the connection was created ! throw new PSQLException("postgresql.stream.encoding", PSQLException.data_exception, e); } } *************** public class Encoding *** 169,175 **** } catch (UnsupportedEncodingException e) { ! throw new PSQLException("postgresql.stream.encoding", e); } } --- 165,172 ---- } catch (UnsupportedEncodingException e) { ! // This will never happen as we made sure that the encoding is valid when the connection was created ! throw new PSQLException("postgresql.stream.encoding", PSQLException.data_exception, e); } } *************** public class Encoding *** 199,205 **** } catch (UnsupportedEncodingException e) { ! throw new PSQLException("postgresql.res.encoding", e); } } --- 196,203 ---- } catch (UnsupportedEncodingException e) { ! // This will never happen as we made sure that the encoding is valid when the connection was created ! throw new PSQLException("postgresql.res.encoding", PSQLException.data_exception, e); } } Index: src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java,v retrieving revision 1.17 diff -c -p -r1.17 QueryExecutor.java *** src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/14 05:35:45 1.17 --- src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/25 22:17:47 *************** public class QueryExecutor *** 61,67 **** if (pg_stream == null) { ! throw new PSQLException("postgresql.con.closed"); } synchronized (pg_stream) --- 61,67 ---- if (pg_stream == null) { ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); } synchronized (pg_stream) *************** public class QueryExecutor *** 120,126 **** l_endQuery = true; break; default: ! throw new PSQLException("postgresql.con.type", new Character((char) c)); } --- 120,126 ---- l_endQuery = true; break; default: ! throw new PSQLException("postgresql.con.type", PSQLException.connection_failure, new Character((char) c)); } *************** public class QueryExecutor *** 145,151 **** for (int i = 0 ; i < m_binds.length ; ++i) { if (m_binds[i] == null) ! throw new PSQLException("postgresql.prep.param", new Integer(i + 1)); pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i])); pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString())); } --- 145,151 ---- for (int i = 0 ; i < m_binds.length ; ++i) { if (m_binds[i] == null) ! throw new PSQLException("postgresql.prep.param", PSQLException.parameter_mismatch, new Integer(i +1)); pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i])); pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString())); } *************** public class QueryExecutor *** 156,162 **** } catch (IOException e) { ! throw new PSQLException("postgresql.con.ioerror", e); } } --- 156,162 ---- } catch (IOException e) { ! throw new PSQLException("postgresql.con.ioerror", PSQLException.comm_link_error, e); } } *************** public class QueryExecutor *** 168,174 **** private void receiveTuple(boolean isBinary) throws SQLException { if (fields == null) ! throw new PSQLException("postgresql.con.tuple"); Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary); if (isBinary) binaryCursor = true; --- 168,174 ---- private void receiveTuple(boolean isBinary) throws SQLException { if (fields == null) ! throw new PSQLException("postgresql.con.tuple", PSQLException.connection_failure); Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary); if (isBinary) binaryCursor = true; *************** public class QueryExecutor *** 199,205 **** } catch (NumberFormatException nfe) { ! throw new PSQLException("postgresql.con.fathom", status); } } --- 199,205 ---- } catch (NumberFormatException nfe) { ! throw new PSQLException("postgresql.con.fathom", PSQLException.connection_failure, status); } } *************** public class QueryExecutor *** 209,215 **** private void receiveFields() throws SQLException { if (fields != null) ! throw new PSQLException("postgresql.con.multres"); int size = pg_stream.ReceiveIntegerR(2); fields = new Field[size]; --- 209,215 ---- private void receiveFields() throws SQLException { if (fields != null) ! throw new PSQLException("postgresql.con.multres", PSQLException.connection_failure); int size = pg_stream.ReceiveIntegerR(2); fields = new Field[size]; Index: src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java,v retrieving revision 1.11 diff -c -p -r1.11 Fastpath.java *** src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java 2002/09/06 21:23:05 1.11 --- src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java 2002/11/25 22:17:47 *************** public class Fastpath *** 81,87 **** } catch (IOException ioe) { ! throw new PSQLException("postgresql.fp.send", new Integer(fnid), ioe); } // Now handle the result --- 81,89 ---- } catch (IOException ioe) { ! throw new PSQLException("postgresql.fp.send", ! PSQLException.comm_link_error, ! new Integer(fnid), ioe); } // Now handle the result Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java,v retrieving revision 1.13 diff -c -p -r1.13 AbstractJdbc1Connection.java *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java 2002/11/14 05:35:45 1.13 --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java 2002/11/25 22:17:47 *************** public abstract class AbstractJdbc1Conne *** 104,110 **** // This occasionally occurs when the client uses the properties version // of getConnection(), and is a common question on the email lists if (info.getProperty("user") == null) ! throw new PSQLException("postgresql.con.user"); this_driver = (org.postgresql.Driver)d; this_url = url; --- 104,110 ---- // This occasionally occurs when the client uses the properties version // of getConnection(), and is a common question on the email lists if (info.getProperty("user") == null) ! throw new PSQLException("postgresql.con.user", PSQLException.connection_rejected); this_driver = (org.postgresql.Driver)d; this_url = url; *************** public abstract class AbstractJdbc1Conne *** 164,174 **** // Added by Peter Mount <peter@retep.org.uk> // ConnectException is thrown when the connection cannot be made. // we trap this an return a more meaningful message for the end user ! throw new PSQLException ("postgresql.con.refused"); } catch (IOException e) { ! throw new PSQLException ("postgresql.con.failed", e); } // Now we need to construct and send a startup packet --- 164,174 ---- // Added by Peter Mount <peter@retep.org.uk> // ConnectException is thrown when the connection cannot be made. // we trap this an return a more meaningful message for the end user ! throw new PSQLException ("postgresql.con.refused", PSQLException.connection_rejected); } catch (IOException e) { ! throw new PSQLException ("postgresql.con.failed", PSQLException.unable_to_connect, e); } // Now we need to construct and send a startup packet *************** public abstract class AbstractJdbc1Conne *** 199,205 **** // The most common one to be thrown here is: // "User authentication failed" // ! throw new PSQLException("postgresql.con.misc", pg_stream.ReceiveString(encoding)); case 'R': // Get the type of request --- 199,206 ---- // The most common one to be thrown here is: // "User authentication failed" // ! throw new PSQLException("postgresql.con.misc", PSQLException.connection_rejected, ! pg_stream.ReceiveString(encoding)); case 'R': // Get the type of request *************** public abstract class AbstractJdbc1Conne *** 237,248 **** case AUTH_REQ_KRB4: if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB4"); ! throw new PSQLException("postgresql.con.kerb4"); case AUTH_REQ_KRB5: if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB5"); ! throw new PSQLException("postgresql.con.kerb5"); case AUTH_REQ_PASSWORD: if (org.postgresql.Driver.logDebug) --- 238,249 ---- case AUTH_REQ_KRB4: if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB4"); ! throw new PSQLException("postgresql.con.kerb4", PSQLException.connection_rejected); case AUTH_REQ_KRB5: if (org.postgresql.Driver.logDebug) org.postgresql.Driver.debug("postgresql: KRB5"); ! throw new PSQLException("postgresql.con.kerb5", PSQLException.connection_rejected); case AUTH_REQ_PASSWORD: if (org.postgresql.Driver.logDebug) *************** public abstract class AbstractJdbc1Conne *** 274,285 **** break; default: ! throw new PSQLException("postgresql.con.auth", new Integer(areq)); } break; default: ! throw new PSQLException("postgresql.con.authfail"); } } while (areq != AUTH_REQ_OK); --- 275,287 ---- break; default: ! throw new PSQLException("postgresql.con.auth", PSQLException.connection_rejected, ! new Integer(areq)); } break; default: ! throw new PSQLException("postgresql.con.authfail", PSQLException.connection_rejected); } } while (areq != AUTH_REQ_OK); *************** public abstract class AbstractJdbc1Conne *** 287,293 **** } catch (IOException e) { ! throw new PSQLException("postgresql.con.failed", e); } --- 289,295 ---- } catch (IOException e) { ! throw new PSQLException("postgresql.con.failed", PSQLException.unable_to_connect, e); } *************** public abstract class AbstractJdbc1Conne *** 303,314 **** ckey = pg_stream.ReceiveIntegerR(4); break; case 'E': ! throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding)); case 'N': addWarning(pg_stream.ReceiveString(encoding)); break; default: ! throw new PSQLException("postgresql.con.setup"); } } while (beresp == 'N'); --- 305,317 ---- ckey = pg_stream.ReceiveIntegerR(4); break; case 'E': ! throw new PSQLException("postgresql.con.backend", PSQLException.unable_to_connect, ! pg_stream.ReceiveString(encoding)); case 'N': addWarning(pg_stream.ReceiveString(encoding)); break; default: ! throw new PSQLException("postgresql.con.setup", PSQLException.unable_to_connect); } } while (beresp == 'N'); *************** public abstract class AbstractJdbc1Conne *** 325,333 **** addWarning(pg_stream.ReceiveString(encoding)); break; case 'E': ! throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding)); default: ! throw new PSQLException("postgresql.con.setup"); } } while (beresp == 'N'); --- 328,337 ---- addWarning(pg_stream.ReceiveString(encoding)); break; case 'E': ! throw new PSQLException("postgresql.con.backend", PSQLException.unable_to_connect, ! pg_stream.ReceiveString(encoding)); default: ! throw new PSQLException("postgresql.con.setup", PSQLException.unable_to_connect); } } while (beresp == 'N'); *************** public abstract class AbstractJdbc1Conne *** 355,367 **** if (! resultSet.next()) { ! throw new PSQLException("postgresql.con.failed", "failed getting backend encoding"); } String version = resultSet.getString(1); dbVersionNumber = extractVersionNumber(version); String dbEncoding = resultSet.getString(2); ! encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet")); //In 7.3 we are forced to do a second roundtrip to handle the case //where a database may not be running in autocommit mode //jdbc by default assumes autocommit is on until setAutoCommit(false) --- 359,372 ---- if (! resultSet.next()) { ! throw new PSQLException("postgresql.con.failed", PSQLException.unable_to_connect, ! "failed getting backend encoding"); } String version = resultSet.getString(1); dbVersionNumber = extractVersionNumber(version); String dbEncoding = resultSet.getString(2); ! //In 7.3 we are forced to do a second roundtrip to handle the case //where a database may not be running in autocommit mode //jdbc by default assumes autocommit is on until setAutoCommit(false) *************** public abstract class AbstractJdbc1Conne *** 377,386 **** //set encoding to be unicode encoding = Encoding.getEncoding("UNICODE", null); if (!acRset.next()) { ! throw new PSQLException("postgresql.con.failed", "failed getting autocommit status"); } //if autocommit is currently off we need to turn it on //note that we will be in a transaction because the select above --- 382,396 ---- //set encoding to be unicode encoding = Encoding.getEncoding("UNICODE", null); + if (info.getProperty("charSet") != null) + { + addWarning("Obsolete charSet connection property ignored"); + } if (!acRset.next()) { ! throw new PSQLException("postgresql.con.failed", PSQLException.unable_to_connect, ! "failed getting autocommit status"); } //if autocommit is currently off we need to turn it on //note that we will be in a transaction because the select above *************** public abstract class AbstractJdbc1Conne *** 391,396 **** --- 401,424 ---- ExecSQL("set autocommit = on; commit;"); } } + else + { + // Try setting the encoding to the requested encoding or backend encoding + encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet")); + + if (encoding == null) + { + if (info.getProperty("charSet") != null) + { + addWarning("Requested encoding not available in the JVM - using JVM default encoding"); + } + else + { + addWarning("Backend encoding unknown or not available in the JVM - using JVM default encoding"); + } + encoding = Encoding.defaultEncoding(); + } + } // Initialise object handling initObjectTypes(); *************** public abstract class AbstractJdbc1Conne *** 477,483 **** { if (isClosed()) { ! throw new PSQLException("postgresql.con.closed"); } return new QueryExecutor(new String[] {sql}, EMPTY_OBJECT_ARRAY, stat, pg_stream, (java.sql.Connection)this).execute(); } --- 505,511 ---- { if (isClosed()) { ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); } return new QueryExecutor(new String[] {sql}, EMPTY_OBJECT_ARRAY, stat, pg_stream, (java.sql.Connection)this).execute(); } *************** public abstract class AbstractJdbc1Conne *** 500,506 **** { if (isClosed()) { ! throw new PSQLException("postgresql.con.closed"); } return new QueryExecutor(p_sqlFragments, p_binds, stat, pg_stream, (java.sql.Connection)this).execute(); } --- 528,534 ---- { if (isClosed()) { ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); } return new QueryExecutor(p_sqlFragments, p_binds, stat, pg_stream, (java.sql.Connection)this).execute(); } *************** public abstract class AbstractJdbc1Conne *** 695,701 **** } catch (Exception ex) { ! throw new PSQLException("postgresql.con.creobj", type, ex); } // should never be reached --- 723,729 ---- } catch (Exception ex) { ! throw new PSQLException("postgresql.con.creobj", PSQLException.connection_failure, type, ex); } // should never be reached *************** public abstract class AbstractJdbc1Conne *** 744,750 **** return ((Serialize)x).storeObject(o); // Thow an exception because the type is unknown ! throw new PSQLException("postgresql.con.strobj"); } catch (SQLException sx) --- 772,778 ---- return ((Serialize)x).storeObject(o); // Thow an exception because the type is unknown ! throw new PSQLException("postgresql.con.strobj", PSQLException.data_exception); } catch (SQLException sx) *************** public abstract class AbstractJdbc1Conne *** 1117,1123 **** isolationLevelSQL += "SERIALIZABLE"; break; default: ! throw new PSQLException("postgresql.con.isolevel", new Integer(isolationLevel)); } } --- 1145,1151 ---- isolationLevelSQL += "SERIALIZABLE"; break; default: ! throw new PSQLException("postgresql.con.isolevel", PSQLException.inv_transaction_state, new Integer(isolationLevel)); } } *************** public abstract class AbstractJdbc1Conne *** 1154,1160 **** break; default: ! throw new PSQLException("postgresql.con.isolevel", new Integer(isolationLevel)); } return sb.toString(); } --- 1182,1189 ---- break; default: ! throw new PSQLException("postgresql.con.isolevel", PSQLException.inv_transaction_state, ! new Integer(isolationLevel)); } return sb.toString(); } Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java,v retrieving revision 1.7 diff -c -p -r1.7 AbstractJdbc1ResultSet.java *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java 2002/10/19 22:10:36 1.7 --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java 2002/11/25 22:17:48 *************** public abstract class AbstractJdbc1Resul *** 60,66 **** public boolean next() throws SQLException { if (rows == null) ! throw new PSQLException("postgresql.con.closed"); if (++current_row >= rows.size()) return false; --- 60,66 ---- public boolean next() throws SQLException { if (rows == null) ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); if (++current_row >= rows.size()) return false; Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java,v retrieving revision 1.14 diff -c -p -r1.14 AbstractJdbc1Statement.java *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2002/11/20 07:34:32 1.14 --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2002/11/25 22:17:48 *************** public abstract class AbstractJdbc1State *** 1378,1384 **** } else { ! throw new PSQLException("postgresql.prep.type"); } break; case Types.BINARY: --- 1378,1384 ---- } else { ! throw new PSQLException("postgresql.prep.type", PSQLException.inv_parameter_type); } break; case Types.BINARY: *************** public abstract class AbstractJdbc1State *** 1389,1395 **** setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT); break; default: ! throw new PSQLException("postgresql.prep.type"); } } --- 1389,1395 ---- setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT); break; default: ! throw new PSQLException("postgresql.prep.type", PSQLException.inv_parameter_type); } } *************** public abstract class AbstractJdbc1State *** 1798,1804 **** protected void bind(int paramIndex, Object s, String type) throws SQLException { if (paramIndex < 1 || paramIndex > m_binds.length) ! throw new PSQLException("postgresql.prep.range"); if (paramIndex == 1 && isFunction) // need to registerOut instead throw new PSQLException ("postgresql.call.funcover"); m_binds[paramIndex - 1] = s; --- 1798,1804 ---- protected void bind(int paramIndex, Object s, String type) throws SQLException { if (paramIndex < 1 || paramIndex > m_binds.length) ! throw new PSQLException("postgresql.prep.range", PSQLException.parameter_mismatch); if (paramIndex == 1 && isFunction) // need to registerOut instead throw new PSQLException ("postgresql.call.funcover"); m_binds[paramIndex - 1] = s; Index: src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v retrieving revision 1.2 diff -c -p -r1.2 AbstractJdbc2Connection.java *** src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java 2002/09/06 21:23:06 1.2 --- src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java 2002/11/25 22:17:48 *************** public abstract class AbstractJdbc2Conne *** 64,74 **** // Added by Peter Mount <peter@retep.org.uk> // ConnectException is thrown when the connection cannot be made. // we trap this an return a more meaningful message for the end user ! throw new PSQLException ("postgresql.con.refused"); } catch (IOException e) { ! throw new PSQLException ("postgresql.con.failed", e); } // Now we need to construct and send a cancel packet --- 64,74 ---- // Added by Peter Mount <peter@retep.org.uk> // ConnectException is thrown when the connection cannot be made. // we trap this an return a more meaningful message for the end user ! throw new PSQLException ("postgresql.con.refused", PSQLException.connection_rejected); } catch (IOException e) { ! throw new PSQLException ("postgresql.con.failed", PSQLException.unable_to_connect, e); } // Now we need to construct and send a cancel packet *************** public abstract class AbstractJdbc2Conne *** 82,88 **** } catch (IOException e) { ! throw new PSQLException("postgresql.con.failed", e); } finally { --- 82,88 ---- } catch (IOException e) { ! throw new PSQLException("postgresql.con.failed", PSQLException.comm_link_error, e); } finally { Index: src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java,v retrieving revision 1.10 diff -c -p -r1.10 AbstractJdbc2ResultSet.java *** src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 2002/11/04 06:42:33 1.10 --- src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 2002/11/25 22:17:48 *************** public abstract class AbstractJdbc2Resul *** 399,405 **** public Ref getRef(int i) throws SQLException { //The backend doesn't yet have SQL3 REF types ! throw new PSQLException("postgresql.psqlnotimp"); } --- 399,405 ---- public Ref getRef(int i) throws SQLException { //The backend doesn't yet have SQL3 REF types ! throw new PSQLException("postgresql.psqlnotimp", PSQLException.feature_not_supported); } *************** public abstract class AbstractJdbc2Resul *** 491,497 **** public void setFetchDirection(int direction) throws SQLException { ! throw new PSQLException("postgresql.psqlnotimp"); } --- 491,497 ---- public void setFetchDirection(int direction) throws SQLException { ! throw new PSQLException("postgresql.psqlnotimp", PSQLException.feature_not_supported); } *************** public abstract class AbstractJdbc2Resul *** 750,756 **** } catch (IOException ie) { ! throw new PSQLException("postgresql.updateable.ioerror" + ie); } updateValue(columnIndex, theData); --- 750,756 ---- } catch (IOException ie) { ! throw new PSQLException("postgresql.updateable.ioerror", ie); } updateValue(columnIndex, theData); *************** public abstract class AbstractJdbc2Resul *** 784,790 **** } catch (IOException ie) { ! throw new PSQLException("postgresql.updateable.ioerror" + ie); } updateValue(columnIndex, theData); --- 784,790 ---- } catch (IOException ie) { ! throw new PSQLException("postgresql.updateable.ioerror", ie); } updateValue(columnIndex, theData); *************** public abstract class AbstractJdbc2Resul *** 832,838 **** } catch (IOException ie) { ! throw new PSQLException("postgresql.updateable.ioerror" + ie); } updateValue(columnIndex, theData); } --- 832,838 ---- } catch (IOException ie) { ! throw new PSQLException("postgresql.updateable.ioerror", ie); } updateValue(columnIndex, theData); } Index: src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v retrieving revision 1.9 diff -c -p -r1.9 AbstractJdbc2Statement.java *** src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java 2002/11/20 07:34:32 1.9 --- src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java 2002/11/25 22:17:48 *************** public abstract class AbstractJdbc2State *** 128,134 **** public int getFetchDirection() throws SQLException { ! throw new PSQLException("postgresql.psqlnotimp"); } public int getFetchSize() throws SQLException --- 128,134 ---- public int getFetchDirection() throws SQLException { ! throw new PSQLException("postgresql.psqlnotimp", PSQLException.feature_not_supported); } public int getFetchSize() throws SQLException Index: src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java,v retrieving revision 1.2 diff -c -p -r1.2 AbstractJdbc3DatabaseMetaData.java *** src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java 2002/09/06 21:23:06 1.2 --- src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java 2002/11/25 22:17:49 *************** public abstract class AbstractJdbc3Datab *** 323,329 **** */ public int getSQLStateType() throws SQLException { ! throw org.postgresql.Driver.notImplemented(); } /** --- 323,329 ---- */ public int getSQLStateType() throws SQLException { ! return DatabaseMetaData.sqlStateXOpen; } /** Index: src/interfaces/jdbc/org/postgresql/util/PSQLException.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/util/PSQLException.java,v retrieving revision 1.7 diff -c -p -r1.7 PSQLException.java *** src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2001/11/19 22:33:39 1.7 --- src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2002/11/25 22:17:51 *************** public class PSQLException extends SQLEx *** 11,16 **** --- 11,33 ---- private String message; /* + * PSQLState constants + * + * Using the constants make the code more legible. + */ + + public static final PSQLState parameter_mismatch = new PSQLState("07001"); + public static final PSQLState inv_parameter_type = new PSQLState("07006"); + public static final PSQLState unable_to_connect = new PSQLState("08001"); + public static final PSQLState inexistent_connection = new PSQLState("08003"); + public static final PSQLState connection_rejected = new PSQLState("08004"); + public static final PSQLState connection_failure = new PSQLState("08006"); + public static final PSQLState comm_link_error = new PSQLState("08S01"); + public static final PSQLState feature_not_supported = new PSQLState("0A000"); + public static final PSQLState data_exception = new PSQLState("22000"); + public static final PSQLState inv_transaction_state = new PSQLState("25000"); + + /* * This provides the same functionality to SQLException * @param error Error string */ *************** public class PSQLException extends SQLEx *** 21,26 **** --- 38,54 ---- } /* + * Like the above, but sets SQLState + * @param error Error string + * @param sqlstate PSQLState constant + */ + public PSQLException(String error, PSQLState sqlstate) + { + super("", sqlstate.toString()); + translate(error, null); + } + + /* * A more generic entry point. * @param error Error string or standard message id * @param args Array of arguments *************** public class PSQLException extends SQLEx *** 74,84 **** --- 102,155 ---- } /* + * Like the above, but sets the SQLState + */ + public PSQLException(String error, PSQLState sqlstate, Exception ex) + { + super("", sqlstate.toString()); + + Object[] argv = new Object[1]; + + try + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintWriter pw = new PrintWriter(baos); + pw.println("Exception: " + ex.toString() + "\nStack Trace:\n"); + ex.printStackTrace(pw); + pw.println("End of Stack Trace"); + pw.flush(); + argv[0] = baos.toString(); + pw.close(); + baos.close(); + } + catch (Exception ioe) + { + argv[0] = ex.toString() + "\nIO Error on stack trace generation! " + ioe.toString(); + } + + translate(error, argv); + } + + /* * Helper version for 2 args */ public PSQLException(String error, Object arg1, Object arg2) { super(); + Object[] argv = new Object[2]; + argv[0] = arg1; + argv[1] = arg2; + translate(error, argv); + } + + /* + * Like the above, but sets SQLState + * @param error Error string + * @param sqlstate PSQLState constant + */ + public PSQLException(String error, PSQLState sqlstate, Object arg1, Object arg2) + { + super("", sqlstate.toString()); Object[] argv = new Object[2]; argv[0] = arg1; argv[1] = arg2;
Fernando, Can you provide a reason these patches are necessary? Are there some specific use cases that are trying to be addressed? I am very reluctant to apply all of this. The reason being, that without a commitment on how error codes are going to be implemented in the backend, I don't want to partially implement them in the jdbc driver. There needs to be a consistent implementation between the jdbc driver and the backend (since the jdbc driver will end up passing the backend's codes to the client). Depending on what the backend implementation is, that might even mean that the jdbc driver will support error codes in a non-standard way. I am much more concerned with consistency between the two sets of error codes than I am with following the standard at the moment. I really want to avoid needing to have the reinterpret all the backend error codes to conform to how these patches think error codes should be handled. That will be a maintenance nightmare. I think this patch goes beyond what I am comfortable applying without any guidance on how/when/if error codes are going to be implemented in the backend. thanks, --Barry Fernando Nasser wrote: > This patch includes all the others and adds SQLState support for the > following additional conditions: > > public static final PSQLState parameter_mismatch = new > PSQLState("07001"); > public static final PSQLState inv_parameter_type = new > PSQLState("07006"); > public static final PSQLState unable_to_connect = new > PSQLState("08001"); > public static final PSQLState inexistent_connection = new > PSQLState("08003"); > public static final PSQLState connection_rejected = new > PSQLState("08004"); > public static final PSQLState connection_failure = new > PSQLState("08006"); > public static final PSQLState feature_not_supported = new > PSQLState("0A000"); > public static final PSQLState data_exception = new PSQLState("22000"); > public static final PSQLState inv_transaction_state = new > PSQLState("25000"); > > > ------------------------------------------------------------------------ > > ? src/interfaces/jdbc/org/postgresql/util/PSQLState.java > Index: src/interfaces/jdbc/org/postgresql/PG_Stream.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/PG_Stream.java,v > retrieving revision 1.17 > diff -c -p -r1.17 PG_Stream.java > *** src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/08/20 04:26:02 1.17 > --- src/interfaces/jdbc/org/postgresql/PG_Stream.java 2002/11/25 22:17:47 > *************** public class PG_Stream > *** 137,147 **** > { > c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof"); > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", e); > } > return c; > } > --- 137,147 ---- > { > c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); > } > return c; > } > *************** public class PG_Stream > *** 164,176 **** > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof"); > n = n | (b << (8 * i)) ; > } > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", e); > } > return n; > } > --- 164,176 ---- > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); > n = n | (b << (8 * i)) ; > } > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); > } > return n; > } > *************** public class PG_Stream > *** 193,205 **** > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof"); > n = b | (n << 8); > } > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", e); > } > return n; > } > --- 193,205 ---- > int b = pg_input.read(); > > if (b < 0) > ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); > n = b | (n << 8); > } > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); > } > return n; > } > *************** public class PG_Stream > *** 227,233 **** > { > int c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof"); > else if (c == 0) > { > rst[s] = 0; > --- 227,233 ---- > { > int c = pg_input.read(); > if (c < 0) > ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); > else if (c == 0) > { > rst[s] = 0; > *************** public class PG_Stream > *** 250,256 **** > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", e); > } > return encoding.decode(rst, 0, s); > } > --- 250,256 ---- > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); > } > return encoding.decode(rst, 0, s); > } > *************** public class PG_Stream > *** 330,342 **** > { > int w = pg_input.read(b, off + s, siz - s); > if (w < 0) > ! throw new PSQLException("postgresql.stream.eof"); > s += w; > } > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", e); > } > } > > --- 330,342 ---- > { > int w = pg_input.read(b, off + s, siz - s); > if (w < 0) > ! throw new PSQLException("postgresql.stream.eof", PSQLException.comm_link_error); > s += w; > } > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.ioerror", PSQLException.comm_link_error, e); > } > } > > *************** public class PG_Stream > *** 353,359 **** > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.flush", e); > } > } > > --- 353,359 ---- > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.stream.flush", PSQLException.comm_link_error, e); > } > } > > Index: src/interfaces/jdbc/org/postgresql/errors.properties > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/errors.properties,v > retrieving revision 1.15 > diff -c -p -r1.15 errors.properties > *** src/interfaces/jdbc/org/postgresql/errors.properties 2002/11/14 05:35:45 1.15 > --- src/interfaces/jdbc/org/postgresql/errors.properties 2002/11/25 22:17:47 > *************** postgresql.updateable.beforestartdelete: > *** 83,89 **** > postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). > postgresql.updateable.notoninsertrow:Not on insert row. > postgresql.updateable.inputstream:Input Stream is null. > ! postgresql.updateable.ioerror:Input Stream Error. > postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)'was made. > postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) > postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. > --- 83,89 ---- > postgresql.updateable.afterlastdelete:After end of result set. Can not call deleteRow(). > postgresql.updateable.notoninsertrow:Not on insert row. > postgresql.updateable.inputstream:Input Stream is null. > ! postgresql.updateable.ioerror:Input Stream Error - {0} > postgresql.call.noreturntype:A CallableStatement Function was declared but no call to 'registerOutParameter (1, <some_type>)'was made. > postgresql.call.noinout:PostgreSQL only supports function return value [@ 1] (no OUT or INOUT arguments) > postgresql.call.procasfunc:This Statement [{0}] defines a procedure call (needs ?= call <stmt> to be considered a function. > Index: src/interfaces/jdbc/org/postgresql/core/Encoding.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/Encoding.java,v > retrieving revision 1.8 > diff -c -p -r1.8 Encoding.java > *** src/interfaces/jdbc/org/postgresql/core/Encoding.java 2002/11/14 05:35:45 1.8 > --- src/interfaces/jdbc/org/postgresql/core/Encoding.java 2002/11/25 22:17:47 > *************** public class Encoding > *** 72,82 **** > } > > /* > ! * Get an Encoding for from the given database encoding and > * the encoding passed in by the user. > */ > ! public static Encoding getEncoding(String databaseEncoding, > ! String passedEncoding) > { > if (passedEncoding != null) > { > --- 72,82 ---- > } > > /* > ! * Get an Encoding from the given database encoding and > * the encoding passed in by the user. > + * Return null if cannot find a suitable one. > */ > ! public static Encoding getEncoding(String databaseEncoding, String passedEncoding) > { > if (passedEncoding != null) > { > *************** public class Encoding > *** 86,121 **** > } > else > { > ! return defaultEncoding(); > } > } > else > { > ! return encodingForDatabaseEncoding(databaseEncoding); > ! } > ! } > ! > ! /* > ! * Get an Encoding matching the given database encoding. > ! */ > ! private static Encoding encodingForDatabaseEncoding(String databaseEncoding) > ! { > ! // If the backend encoding is known and there is a suitable > ! // encoding in the JVM we use that. Otherwise we fall back > ! // to the default encoding of the JVM. > ! > ! if (encodings.containsKey(databaseEncoding)) > ! { > ! String[] candidates = (String[]) encodings.get(databaseEncoding); > ! for (int i = 0; i < candidates.length; i++) > { > ! if (isAvailable(candidates[i])) > { > ! return new Encoding(candidates[i]); > } > } > } > - return defaultEncoding(); > } > > /* > --- 86,116 ---- > } > else > { > ! // Requested encoding not available in the JVM > ! return null; > } > } > else > { > ! // Get an Encoding matching the given database encoding. > ! // If the backend encoding is known and there is a suitable > ! // encoding in the JVM we return that. > ! > ! if (encodings.containsKey(databaseEncoding)) > { > ! String[] candidates = (String[]) encodings.get(databaseEncoding); > ! for (int i = 0; i < candidates.length; i++) > { > ! if (isAvailable(candidates[i])) > ! { > ! return new Encoding(candidates[i]); > ! } > } > } > + > + // Bakend encoding UNKNOWN or not available in the JVM > + return null; > } > } > > /* > *************** public class Encoding > *** 144,150 **** > } > catch (UnsupportedEncodingException e) > { > ! throw new PSQLException("postgresql.stream.encoding", e); > } > } > > --- 139,146 ---- > } > catch (UnsupportedEncodingException e) > { > ! // This will never happen as we made sure that the encoding is valid when the connection was created > ! throw new PSQLException("postgresql.stream.encoding", PSQLException.data_exception, e); > } > } > > *************** public class Encoding > *** 169,175 **** > } > catch (UnsupportedEncodingException e) > { > ! throw new PSQLException("postgresql.stream.encoding", e); > } > } > > --- 165,172 ---- > } > catch (UnsupportedEncodingException e) > { > ! // This will never happen as we made sure that the encoding is valid when the connection was created > ! throw new PSQLException("postgresql.stream.encoding", PSQLException.data_exception, e); > } > } > > *************** public class Encoding > *** 199,205 **** > } > catch (UnsupportedEncodingException e) > { > ! throw new PSQLException("postgresql.res.encoding", e); > } > } > > --- 196,203 ---- > } > catch (UnsupportedEncodingException e) > { > ! // This will never happen as we made sure that the encoding is valid when the connection was created > ! throw new PSQLException("postgresql.res.encoding", PSQLException.data_exception, e); > } > } > > Index: src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java,v > retrieving revision 1.17 > diff -c -p -r1.17 QueryExecutor.java > *** src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/14 05:35:45 1.17 > --- src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java 2002/11/25 22:17:47 > *************** public class QueryExecutor > *** 61,67 **** > > if (pg_stream == null) > { > ! throw new PSQLException("postgresql.con.closed"); > } > > synchronized (pg_stream) > --- 61,67 ---- > > if (pg_stream == null) > { > ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); > } > > synchronized (pg_stream) > *************** public class QueryExecutor > *** 120,126 **** > l_endQuery = true; > break; > default: > ! throw new PSQLException("postgresql.con.type", > new Character((char) c)); > } > > --- 120,126 ---- > l_endQuery = true; > break; > default: > ! throw new PSQLException("postgresql.con.type", PSQLException.connection_failure, > new Character((char) c)); > } > > *************** public class QueryExecutor > *** 145,151 **** > for (int i = 0 ; i < m_binds.length ; ++i) > { > if (m_binds[i] == null) > ! throw new PSQLException("postgresql.prep.param", new Integer(i + 1)); > pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i])); > pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString())); > } > --- 145,151 ---- > for (int i = 0 ; i < m_binds.length ; ++i) > { > if (m_binds[i] == null) > ! throw new PSQLException("postgresql.prep.param", PSQLException.parameter_mismatch, new Integer(i+ 1)); > pg_stream.Send(connection.getEncoding().encode(m_sqlFrags[i])); > pg_stream.Send(connection.getEncoding().encode(m_binds[i].toString())); > } > *************** public class QueryExecutor > *** 156,162 **** > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.ioerror", e); > } > } > > --- 156,162 ---- > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.ioerror", PSQLException.comm_link_error, e); > } > } > > *************** public class QueryExecutor > *** 168,174 **** > private void receiveTuple(boolean isBinary) throws SQLException > { > if (fields == null) > ! throw new PSQLException("postgresql.con.tuple"); > Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary); > if (isBinary) > binaryCursor = true; > --- 168,174 ---- > private void receiveTuple(boolean isBinary) throws SQLException > { > if (fields == null) > ! throw new PSQLException("postgresql.con.tuple", PSQLException.connection_failure); > Object tuple = pg_stream.ReceiveTuple(fields.length, isBinary); > if (isBinary) > binaryCursor = true; > *************** public class QueryExecutor > *** 199,205 **** > } > catch (NumberFormatException nfe) > { > ! throw new PSQLException("postgresql.con.fathom", status); > } > } > > --- 199,205 ---- > } > catch (NumberFormatException nfe) > { > ! throw new PSQLException("postgresql.con.fathom", PSQLException.connection_failure, status); > } > } > > *************** public class QueryExecutor > *** 209,215 **** > private void receiveFields() throws SQLException > { > if (fields != null) > ! throw new PSQLException("postgresql.con.multres"); > > int size = pg_stream.ReceiveIntegerR(2); > fields = new Field[size]; > --- 209,215 ---- > private void receiveFields() throws SQLException > { > if (fields != null) > ! throw new PSQLException("postgresql.con.multres", PSQLException.connection_failure); > > int size = pg_stream.ReceiveIntegerR(2); > fields = new Field[size]; > Index: src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java,v > retrieving revision 1.11 > diff -c -p -r1.11 Fastpath.java > *** src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java 2002/09/06 21:23:05 1.11 > --- src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java 2002/11/25 22:17:47 > *************** public class Fastpath > *** 81,87 **** > } > catch (IOException ioe) > { > ! throw new PSQLException("postgresql.fp.send", new Integer(fnid), ioe); > } > > // Now handle the result > --- 81,89 ---- > } > catch (IOException ioe) > { > ! throw new PSQLException("postgresql.fp.send", > ! PSQLException.comm_link_error, > ! new Integer(fnid), ioe); > } > > // Now handle the result > Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java,v > retrieving revision 1.13 > diff -c -p -r1.13 AbstractJdbc1Connection.java > *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java 2002/11/14 05:35:45 1.13 > --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Connection.java 2002/11/25 22:17:47 > *************** public abstract class AbstractJdbc1Conne > *** 104,110 **** > // This occasionally occurs when the client uses the properties version > // of getConnection(), and is a common question on the email lists > if (info.getProperty("user") == null) > ! throw new PSQLException("postgresql.con.user"); > > this_driver = (org.postgresql.Driver)d; > this_url = url; > --- 104,110 ---- > // This occasionally occurs when the client uses the properties version > // of getConnection(), and is a common question on the email lists > if (info.getProperty("user") == null) > ! throw new PSQLException("postgresql.con.user", PSQLException.connection_rejected); > > this_driver = (org.postgresql.Driver)d; > this_url = url; > *************** public abstract class AbstractJdbc1Conne > *** 164,174 **** > // Added by Peter Mount <peter@retep.org.uk> > // ConnectException is thrown when the connection cannot be made. > // we trap this an return a more meaningful message for the end user > ! throw new PSQLException ("postgresql.con.refused"); > } > catch (IOException e) > { > ! throw new PSQLException ("postgresql.con.failed", e); > } > > // Now we need to construct and send a startup packet > --- 164,174 ---- > // Added by Peter Mount <peter@retep.org.uk> > // ConnectException is thrown when the connection cannot be made. > // we trap this an return a more meaningful message for the end user > ! throw new PSQLException ("postgresql.con.refused", PSQLException.connection_rejected); > } > catch (IOException e) > { > ! throw new PSQLException ("postgresql.con.failed", PSQLException.unable_to_connect, e); > } > > // Now we need to construct and send a startup packet > *************** public abstract class AbstractJdbc1Conne > *** 199,205 **** > // The most common one to be thrown here is: > // "User authentication failed" > // > ! throw new PSQLException("postgresql.con.misc", pg_stream.ReceiveString(encoding)); > > case 'R': > // Get the type of request > --- 199,206 ---- > // The most common one to be thrown here is: > // "User authentication failed" > // > ! throw new PSQLException("postgresql.con.misc", PSQLException.connection_rejected, > ! pg_stream.ReceiveString(encoding)); > > case 'R': > // Get the type of request > *************** public abstract class AbstractJdbc1Conne > *** 237,248 **** > case AUTH_REQ_KRB4: > if (org.postgresql.Driver.logDebug) > org.postgresql.Driver.debug("postgresql: KRB4"); > ! throw new PSQLException("postgresql.con.kerb4"); > > case AUTH_REQ_KRB5: > if (org.postgresql.Driver.logDebug) > org.postgresql.Driver.debug("postgresql: KRB5"); > ! throw new PSQLException("postgresql.con.kerb5"); > > case AUTH_REQ_PASSWORD: > if (org.postgresql.Driver.logDebug) > --- 238,249 ---- > case AUTH_REQ_KRB4: > if (org.postgresql.Driver.logDebug) > org.postgresql.Driver.debug("postgresql: KRB4"); > ! throw new PSQLException("postgresql.con.kerb4", PSQLException.connection_rejected); > > case AUTH_REQ_KRB5: > if (org.postgresql.Driver.logDebug) > org.postgresql.Driver.debug("postgresql: KRB5"); > ! throw new PSQLException("postgresql.con.kerb5", PSQLException.connection_rejected); > > case AUTH_REQ_PASSWORD: > if (org.postgresql.Driver.logDebug) > *************** public abstract class AbstractJdbc1Conne > *** 274,285 **** > break; > > default: > ! throw new PSQLException("postgresql.con.auth", new Integer(areq)); > } > break; > > default: > ! throw new PSQLException("postgresql.con.authfail"); > } > } > while (areq != AUTH_REQ_OK); > --- 275,287 ---- > break; > > default: > ! throw new PSQLException("postgresql.con.auth", PSQLException.connection_rejected, > ! new Integer(areq)); > } > break; > > default: > ! throw new PSQLException("postgresql.con.authfail", PSQLException.connection_rejected); > } > } > while (areq != AUTH_REQ_OK); > *************** public abstract class AbstractJdbc1Conne > *** 287,293 **** > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.failed", e); > } > > > --- 289,295 ---- > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.failed", PSQLException.unable_to_connect, e); > } > > > *************** public abstract class AbstractJdbc1Conne > *** 303,314 **** > ckey = pg_stream.ReceiveIntegerR(4); > break; > case 'E': > ! throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding)); > case 'N': > addWarning(pg_stream.ReceiveString(encoding)); > break; > default: > ! throw new PSQLException("postgresql.con.setup"); > } > } > while (beresp == 'N'); > --- 305,317 ---- > ckey = pg_stream.ReceiveIntegerR(4); > break; > case 'E': > ! throw new PSQLException("postgresql.con.backend", PSQLException.unable_to_connect, > ! pg_stream.ReceiveString(encoding)); > case 'N': > addWarning(pg_stream.ReceiveString(encoding)); > break; > default: > ! throw new PSQLException("postgresql.con.setup", PSQLException.unable_to_connect); > } > } > while (beresp == 'N'); > *************** public abstract class AbstractJdbc1Conne > *** 325,333 **** > addWarning(pg_stream.ReceiveString(encoding)); > break; > case 'E': > ! throw new PSQLException("postgresql.con.backend", pg_stream.ReceiveString(encoding)); > default: > ! throw new PSQLException("postgresql.con.setup"); > } > } > while (beresp == 'N'); > --- 328,337 ---- > addWarning(pg_stream.ReceiveString(encoding)); > break; > case 'E': > ! throw new PSQLException("postgresql.con.backend", PSQLException.unable_to_connect, > ! pg_stream.ReceiveString(encoding)); > default: > ! throw new PSQLException("postgresql.con.setup", PSQLException.unable_to_connect); > } > } > while (beresp == 'N'); > *************** public abstract class AbstractJdbc1Conne > *** 355,367 **** > > if (! resultSet.next()) > { > ! throw new PSQLException("postgresql.con.failed", "failed getting backend encoding"); > } > String version = resultSet.getString(1); > dbVersionNumber = extractVersionNumber(version); > > String dbEncoding = resultSet.getString(2); > ! encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet")); > //In 7.3 we are forced to do a second roundtrip to handle the case > //where a database may not be running in autocommit mode > //jdbc by default assumes autocommit is on until setAutoCommit(false) > --- 359,372 ---- > > if (! resultSet.next()) > { > ! throw new PSQLException("postgresql.con.failed", PSQLException.unable_to_connect, > ! "failed getting backend encoding"); > } > String version = resultSet.getString(1); > dbVersionNumber = extractVersionNumber(version); > > String dbEncoding = resultSet.getString(2); > ! > //In 7.3 we are forced to do a second roundtrip to handle the case > //where a database may not be running in autocommit mode > //jdbc by default assumes autocommit is on until setAutoCommit(false) > *************** public abstract class AbstractJdbc1Conne > *** 377,386 **** > > //set encoding to be unicode > encoding = Encoding.getEncoding("UNICODE", null); > > if (!acRset.next()) > { > ! throw new PSQLException("postgresql.con.failed", "failed getting autocommit status"); > } > //if autocommit is currently off we need to turn it on > //note that we will be in a transaction because the select above > --- 382,396 ---- > > //set encoding to be unicode > encoding = Encoding.getEncoding("UNICODE", null); > + if (info.getProperty("charSet") != null) > + { > + addWarning("Obsolete charSet connection property ignored"); > + } > > if (!acRset.next()) > { > ! throw new PSQLException("postgresql.con.failed", PSQLException.unable_to_connect, > ! "failed getting autocommit status"); > } > //if autocommit is currently off we need to turn it on > //note that we will be in a transaction because the select above > *************** public abstract class AbstractJdbc1Conne > *** 391,396 **** > --- 401,424 ---- > ExecSQL("set autocommit = on; commit;"); > } > } > + else > + { > + // Try setting the encoding to the requested encoding or backend encoding > + encoding = Encoding.getEncoding(dbEncoding, info.getProperty("charSet")); > + > + if (encoding == null) > + { > + if (info.getProperty("charSet") != null) > + { > + addWarning("Requested encoding not available in the JVM - using JVM default encoding"); > + } > + else > + { > + addWarning("Backend encoding unknown or not available in the JVM - using JVM default encoding"); > + } > + encoding = Encoding.defaultEncoding(); > + } > + } > > // Initialise object handling > initObjectTypes(); > *************** public abstract class AbstractJdbc1Conne > *** 477,483 **** > { > if (isClosed()) > { > ! throw new PSQLException("postgresql.con.closed"); > } > return new QueryExecutor(new String[] {sql}, EMPTY_OBJECT_ARRAY, stat, pg_stream, (java.sql.Connection)this).execute(); > } > --- 505,511 ---- > { > if (isClosed()) > { > ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); > } > return new QueryExecutor(new String[] {sql}, EMPTY_OBJECT_ARRAY, stat, pg_stream, (java.sql.Connection)this).execute(); > } > *************** public abstract class AbstractJdbc1Conne > *** 500,506 **** > { > if (isClosed()) > { > ! throw new PSQLException("postgresql.con.closed"); > } > return new QueryExecutor(p_sqlFragments, p_binds, stat, pg_stream, (java.sql.Connection)this).execute(); > } > --- 528,534 ---- > { > if (isClosed()) > { > ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); > } > return new QueryExecutor(p_sqlFragments, p_binds, stat, pg_stream, (java.sql.Connection)this).execute(); > } > *************** public abstract class AbstractJdbc1Conne > *** 695,701 **** > } > catch (Exception ex) > { > ! throw new PSQLException("postgresql.con.creobj", type, ex); > } > > // should never be reached > --- 723,729 ---- > } > catch (Exception ex) > { > ! throw new PSQLException("postgresql.con.creobj", PSQLException.connection_failure, type, ex); > } > > // should never be reached > *************** public abstract class AbstractJdbc1Conne > *** 744,750 **** > return ((Serialize)x).storeObject(o); > > // Thow an exception because the type is unknown > ! throw new PSQLException("postgresql.con.strobj"); > > } > catch (SQLException sx) > --- 772,778 ---- > return ((Serialize)x).storeObject(o); > > // Thow an exception because the type is unknown > ! throw new PSQLException("postgresql.con.strobj", PSQLException.data_exception); > > } > catch (SQLException sx) > *************** public abstract class AbstractJdbc1Conne > *** 1117,1123 **** > isolationLevelSQL += "SERIALIZABLE"; > break; > default: > ! throw new PSQLException("postgresql.con.isolevel", > new Integer(isolationLevel)); > } > } > --- 1145,1151 ---- > isolationLevelSQL += "SERIALIZABLE"; > break; > default: > ! throw new PSQLException("postgresql.con.isolevel", PSQLException.inv_transaction_state, > new Integer(isolationLevel)); > } > } > *************** public abstract class AbstractJdbc1Conne > *** 1154,1160 **** > break; > > default: > ! throw new PSQLException("postgresql.con.isolevel", new Integer(isolationLevel)); > } > return sb.toString(); > } > --- 1182,1189 ---- > break; > > default: > ! throw new PSQLException("postgresql.con.isolevel", PSQLException.inv_transaction_state, > ! new Integer(isolationLevel)); > } > return sb.toString(); > } > Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java,v > retrieving revision 1.7 > diff -c -p -r1.7 AbstractJdbc1ResultSet.java > *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java 2002/10/19 22:10:36 1.7 > --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1ResultSet.java 2002/11/25 22:17:48 > *************** public abstract class AbstractJdbc1Resul > *** 60,66 **** > public boolean next() throws SQLException > { > if (rows == null) > ! throw new PSQLException("postgresql.con.closed"); > > if (++current_row >= rows.size()) > return false; > --- 60,66 ---- > public boolean next() throws SQLException > { > if (rows == null) > ! throw new PSQLException("postgresql.con.closed", PSQLException.inexistent_connection); > > if (++current_row >= rows.size()) > return false; > Index: src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java,v > retrieving revision 1.14 > diff -c -p -r1.14 AbstractJdbc1Statement.java > *** src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2002/11/20 07:34:32 1.14 > --- src/interfaces/jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java 2002/11/25 22:17:48 > *************** public abstract class AbstractJdbc1State > *** 1378,1384 **** > } > else > { > ! throw new PSQLException("postgresql.prep.type"); > } > break; > case Types.BINARY: > --- 1378,1384 ---- > } > else > { > ! throw new PSQLException("postgresql.prep.type", PSQLException.inv_parameter_type); > } > break; > case Types.BINARY: > *************** public abstract class AbstractJdbc1State > *** 1389,1395 **** > setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT); > break; > default: > ! throw new PSQLException("postgresql.prep.type"); > } > } > > --- 1389,1395 ---- > setString(parameterIndex, ((PGobject)x).getValue(), PG_TEXT); > break; > default: > ! throw new PSQLException("postgresql.prep.type", PSQLException.inv_parameter_type); > } > } > > *************** public abstract class AbstractJdbc1State > *** 1798,1804 **** > protected void bind(int paramIndex, Object s, String type) throws SQLException > { > if (paramIndex < 1 || paramIndex > m_binds.length) > ! throw new PSQLException("postgresql.prep.range"); > if (paramIndex == 1 && isFunction) // need to registerOut instead > throw new PSQLException ("postgresql.call.funcover"); > m_binds[paramIndex - 1] = s; > --- 1798,1804 ---- > protected void bind(int paramIndex, Object s, String type) throws SQLException > { > if (paramIndex < 1 || paramIndex > m_binds.length) > ! throw new PSQLException("postgresql.prep.range", PSQLException.parameter_mismatch); > if (paramIndex == 1 && isFunction) // need to registerOut instead > throw new PSQLException ("postgresql.call.funcover"); > m_binds[paramIndex - 1] = s; > Index: src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java,v > retrieving revision 1.2 > diff -c -p -r1.2 AbstractJdbc2Connection.java > *** src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java 2002/09/06 21:23:06 1.2 > --- src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Connection.java 2002/11/25 22:17:48 > *************** public abstract class AbstractJdbc2Conne > *** 64,74 **** > // Added by Peter Mount <peter@retep.org.uk> > // ConnectException is thrown when the connection cannot be made. > // we trap this an return a more meaningful message for the end user > ! throw new PSQLException ("postgresql.con.refused"); > } > catch (IOException e) > { > ! throw new PSQLException ("postgresql.con.failed", e); > } > > // Now we need to construct and send a cancel packet > --- 64,74 ---- > // Added by Peter Mount <peter@retep.org.uk> > // ConnectException is thrown when the connection cannot be made. > // we trap this an return a more meaningful message for the end user > ! throw new PSQLException ("postgresql.con.refused", PSQLException.connection_rejected); > } > catch (IOException e) > { > ! throw new PSQLException ("postgresql.con.failed", PSQLException.unable_to_connect, e); > } > > // Now we need to construct and send a cancel packet > *************** public abstract class AbstractJdbc2Conne > *** 82,88 **** > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.failed", e); > } > finally > { > --- 82,88 ---- > } > catch (IOException e) > { > ! throw new PSQLException("postgresql.con.failed", PSQLException.comm_link_error, e); > } > finally > { > Index: src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java,v > retrieving revision 1.10 > diff -c -p -r1.10 AbstractJdbc2ResultSet.java > *** src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 2002/11/04 06:42:33 1.10 > --- src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2ResultSet.java 2002/11/25 22:17:48 > *************** public abstract class AbstractJdbc2Resul > *** 399,405 **** > public Ref getRef(int i) throws SQLException > { > //The backend doesn't yet have SQL3 REF types > ! throw new PSQLException("postgresql.psqlnotimp"); > } > > > --- 399,405 ---- > public Ref getRef(int i) throws SQLException > { > //The backend doesn't yet have SQL3 REF types > ! throw new PSQLException("postgresql.psqlnotimp", PSQLException.feature_not_supported); > } > > > *************** public abstract class AbstractJdbc2Resul > *** 491,497 **** > > public void setFetchDirection(int direction) throws SQLException > { > ! throw new PSQLException("postgresql.psqlnotimp"); > } > > > --- 491,497 ---- > > public void setFetchDirection(int direction) throws SQLException > { > ! throw new PSQLException("postgresql.psqlnotimp", PSQLException.feature_not_supported); > } > > > *************** public abstract class AbstractJdbc2Resul > *** 750,756 **** > } > catch (IOException ie) > { > ! throw new PSQLException("postgresql.updateable.ioerror" + ie); > } > > updateValue(columnIndex, theData); > --- 750,756 ---- > } > catch (IOException ie) > { > ! throw new PSQLException("postgresql.updateable.ioerror", ie); > } > > updateValue(columnIndex, theData); > *************** public abstract class AbstractJdbc2Resul > *** 784,790 **** > } > catch (IOException ie) > { > ! throw new PSQLException("postgresql.updateable.ioerror" + ie); > } > updateValue(columnIndex, theData); > > --- 784,790 ---- > } > catch (IOException ie) > { > ! throw new PSQLException("postgresql.updateable.ioerror", ie); > } > updateValue(columnIndex, theData); > > *************** public abstract class AbstractJdbc2Resul > *** 832,838 **** > } > catch (IOException ie) > { > ! throw new PSQLException("postgresql.updateable.ioerror" + ie); > } > updateValue(columnIndex, theData); > } > --- 832,838 ---- > } > catch (IOException ie) > { > ! throw new PSQLException("postgresql.updateable.ioerror", ie); > } > updateValue(columnIndex, theData); > } > Index: src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v > retrieving revision 1.9 > diff -c -p -r1.9 AbstractJdbc2Statement.java > *** src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java 2002/11/20 07:34:32 1.9 > --- src/interfaces/jdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java 2002/11/25 22:17:48 > *************** public abstract class AbstractJdbc2State > *** 128,134 **** > > public int getFetchDirection() throws SQLException > { > ! throw new PSQLException("postgresql.psqlnotimp"); > } > > public int getFetchSize() throws SQLException > --- 128,134 ---- > > public int getFetchDirection() throws SQLException > { > ! throw new PSQLException("postgresql.psqlnotimp", PSQLException.feature_not_supported); > } > > public int getFetchSize() throws SQLException > Index: src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java,v > retrieving revision 1.2 > diff -c -p -r1.2 AbstractJdbc3DatabaseMetaData.java > *** src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java 2002/09/06 21:23:06 1.2 > --- src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java 2002/11/25 22:17:49 > *************** public abstract class AbstractJdbc3Datab > *** 323,329 **** > */ > public int getSQLStateType() throws SQLException > { > ! throw org.postgresql.Driver.notImplemented(); > } > > /** > --- 323,329 ---- > */ > public int getSQLStateType() throws SQLException > { > ! return DatabaseMetaData.sqlStateXOpen; > } > > /** > Index: src/interfaces/jdbc/org/postgresql/util/PSQLException.java > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/util/PSQLException.java,v > retrieving revision 1.7 > diff -c -p -r1.7 PSQLException.java > *** src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2001/11/19 22:33:39 1.7 > --- src/interfaces/jdbc/org/postgresql/util/PSQLException.java 2002/11/25 22:17:51 > *************** public class PSQLException extends SQLEx > *** 11,16 **** > --- 11,33 ---- > private String message; > > /* > + * PSQLState constants > + * > + * Using the constants make the code more legible. > + */ > + > + public static final PSQLState parameter_mismatch = new PSQLState("07001"); > + public static final PSQLState inv_parameter_type = new PSQLState("07006"); > + public static final PSQLState unable_to_connect = new PSQLState("08001"); > + public static final PSQLState inexistent_connection = new PSQLState("08003"); > + public static final PSQLState connection_rejected = new PSQLState("08004"); > + public static final PSQLState connection_failure = new PSQLState("08006"); > + public static final PSQLState comm_link_error = new PSQLState("08S01"); > + public static final PSQLState feature_not_supported = new PSQLState("0A000"); > + public static final PSQLState data_exception = new PSQLState("22000"); > + public static final PSQLState inv_transaction_state = new PSQLState("25000"); > + > + /* > * This provides the same functionality to SQLException > * @param error Error string > */ > *************** public class PSQLException extends SQLEx > *** 21,26 **** > --- 38,54 ---- > } > > /* > + * Like the above, but sets SQLState > + * @param error Error string > + * @param sqlstate PSQLState constant > + */ > + public PSQLException(String error, PSQLState sqlstate) > + { > + super("", sqlstate.toString()); > + translate(error, null); > + } > + > + /* > * A more generic entry point. > * @param error Error string or standard message id > * @param args Array of arguments > *************** public class PSQLException extends SQLEx > *** 74,84 **** > --- 102,155 ---- > } > > /* > + * Like the above, but sets the SQLState > + */ > + public PSQLException(String error, PSQLState sqlstate, Exception ex) > + { > + super("", sqlstate.toString()); > + > + Object[] argv = new Object[1]; > + > + try > + { > + ByteArrayOutputStream baos = new ByteArrayOutputStream(); > + PrintWriter pw = new PrintWriter(baos); > + pw.println("Exception: " + ex.toString() + "\nStack Trace:\n"); > + ex.printStackTrace(pw); > + pw.println("End of Stack Trace"); > + pw.flush(); > + argv[0] = baos.toString(); > + pw.close(); > + baos.close(); > + } > + catch (Exception ioe) > + { > + argv[0] = ex.toString() + "\nIO Error on stack trace generation! " + ioe.toString(); > + } > + > + translate(error, argv); > + } > + > + /* > * Helper version for 2 args > */ > public PSQLException(String error, Object arg1, Object arg2) > { > super(); > + Object[] argv = new Object[2]; > + argv[0] = arg1; > + argv[1] = arg2; > + translate(error, argv); > + } > + > + /* > + * Like the above, but sets SQLState > + * @param error Error string > + * @param sqlstate PSQLState constant > + */ > + public PSQLException(String error, PSQLState sqlstate, Object arg1, Object arg2) > + { > + super("", sqlstate.toString()); > Object[] argv = new Object[2]; > argv[0] = arg1; > argv[1] = arg2; > > > ------------------------------------------------------------------------ > > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
Barry Lind wrote: > Fernando, > > Can you provide a reason these patches are necessary? Are there some > specific use cases that are trying to be addressed? > The most concrete case for the need of SQLState is the one I gave in the first patch. We have a GUI tool that connects to remotes databases and, sometimes, due to a network problem or a backend problem (there was an assertion failure in one occasion and the backend was aborted), the connection goes away. Without a proper SQLState, we have to parse the error message to check if the connection is gone so that we can re-set the GUI properly (i.e., indicate that we are disconnected, disable some buttons etc.). If we don't do this, the user can continue to try and send things (as the GUI still reports being connected) and things get really inconsistent (nothing hapens, the previous error message is repeated when is not applicable anymore, stack traces show up in the console etc.). > I am very reluctant to apply all of this. The reason being, that > without a commitment on how error codes are going to be implemented in > the backend, I don't want to partially implement them in the jdbc > driver. All the error codes I've been adding so far are driver generated ones, i.e., conditions detected at the client side. They are not going to change regardless of whayt the backend does. Please read on for my thinking on the bacend part. > There needs to be a consistent implementation between the jdbc > driver and the backend (since the jdbc driver will end up passing the > backend's codes to the client). We have to be X/Open compliant anyway (for JDBC1 and JDBC2). We do have the option of using the ANSI codes for JDBC3, which would add a few extra standard error codes when compared with the X/Open. Most of the codes are common to both specs. > Depending on what the backend > implementation is, that might even mean that the jdbc driver will > support error codes in a non-standard way. I am much more concerned > with consistency between the two sets of error codes than I am with > following the standard at the moment. I really want to avoid needing to > have the reinterpret all the backend error codes to conform to how these > patches think error codes should be handled. That will be a maintenance > nightmare. > The backend will either follow the ANSI or the X/Open standards, and there are just a few extra ANSI codes that we would have to map back to X/Open or use implementation-defined codes. If the backend uses some non standard coding (which I doubt it will do as we are trying to get as SQL compliant as possible), it would not be advisable for the JDBC driver to blindly pass those on. Some of the value of the JDBC is to be as standard as possible. The codes that will have to be invented by the backend will follow the ANSI conventions for implementation-defined error codes. And here is were we are lucky: the rules are the same for both ANSI and X/Open. Any valid implementation-defined ANSI code is also a valid implementation-defined X/Open code. So, except for a few extra standard codes defined in the SQL99, we can pass all others on irrespectively of what we are using for JDBC3: X/Open or ANSI style SQLState. P.S. We can always decide to use ANSI style SQLState for JDBC3 if we want. We would have top abstract the PSQLException class but it is not difficult to support bothe the X/Open for JDBC1,2 and ANSI for JDBC3. I just find it very confusing for application to handle both sets and there is absolutely no advantage in switching to the ANSI one (just for a few extra codes). > I think this patch goes beyond what I am comfortable applying without > any guidance on how/when/if error codes are going to be implemented in > the backend. > I would say that it is independent of the backend. We only have two choices to be compliant with JDBC: X/Open and ANSI. All codes in the patch are both ANSI and X/Open standard (plus the de facto 08S01 one, which is an implementation-defined one anyway). The only real choice made was to return XOpen in the getSQLStateType() routine, which can be altered at any time (JDBC3 applications are supposed to check that anyway). -- Fernando Nasser Red Hat Canada Ltd. E-Mail: fnasser@redhat.com 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9