JDBC Emit SQLStatus for communication link errors - Mailing list pgsql-patches
From | Fernando Nasser |
---|---|
Subject | JDBC Emit SQLStatus for communication link errors |
Date | |
Msg-id | 3DDE71E5.3040906@redhat.com Whole thread Raw |
List | pgsql-patches |
This is a repost of a previous patch with enhancements. I had to create a specific object for SQLStatus as there are many calls to PSQLException that pass a string as well, and it is not a SQLStatus code. Also, the code gets more legible with constants instead of just the 5 character strings, so I've added those to PSQLException. I've found 2 more cases where the "08S01" (communication link error) apply, so I've added those as well. I guess I've found all "08S01" now. I will proceed with the other "08xxx" cases, now that I have the official X/Open document in hands. And so one until all cases where we don't depend on the backend information are covered. Answering Barry's question with some more detail: The X/Open codes are basically the same as the ANSI (SQL99) ones. They do not coder all cases, of course, so there is a provision for implementation defined codes (some letters are reserved for this purpose). The "08S01" is not in the standard, but is so common that it is used everywhere. ODBC defines it, as does DB2 and consequently IBM's JDBC. Somehow people using MySQL see the same code, but I am not sure how they were connected, so it may be just an ODBC code. IMO we should use this value for portability of applications. BTW, Oracle 8i did not implement SQLStatus (I don't know if that changed). We will eventually need more custom codes. I will see if the X/Open CLI spec defines some more codes that we can use. We can also re-use the ODBC ones that match before inventing new ones. I will also check how other vendors organized their custom codes. Anyway, the current patch is just for communication link errors and the applications really need to be able to detect that the communication link is broken -- they behave very badly otherwise. Regards, Fernando -- Fernando Nasser Red Hat Canada Ltd. E-Mail: fnasser@redhat.com 2323 Yonge Street, Suite #300 Toronto, Ontario M4P 2C9 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/22 17:32:35 *************** 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/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/22 17:32:35 *************** 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); } } 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/22 17:32:35 *************** 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/jdbc3/AbstractJdbc3DatabaseMetaData.java =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java,v retrieving revision 1.3 diff -c -p -r1.3 AbstractJdbc3DatabaseMetaData.java *** src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java 2002/11/20 20:37:53 1.3 --- src/interfaces/jdbc/org/postgresql/jdbc3/AbstractJdbc3DatabaseMetaData.java 2002/11/22 17:32:35 *************** 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/22 17:32:35 *************** public class PSQLException extends SQLEx *** 11,16 **** --- 11,24 ---- private String message; /* + * PSQLState constants + * + * Using the constants make the code more legible. + */ + + public static final PSQLState comm_link_error = new PSQLState("08S01"); + + /* * This provides the same functionality to SQLException * @param error Error string */ *************** public class PSQLException extends SQLEx *** 21,26 **** --- 29,45 ---- } /* + * 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 **** --- 93,146 ---- } /* + * 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; New file: src/interfaces/jdbc/org/postgresql/util/PSQLState.java =================================================================== package org.postgresql.util; /* * This class encapsulates a String, so that SQLState arguments have their own type * (for method overload resolution) */ public class PSQLState extends Object { private String sqlstate; /* * We only instantiate this with the X/Open strintgs, * so we only provide this constructor. * @param sqlstate PSQLState constant */ public PSQLState(String sqlstate) { this.sqlstate = sqlstate; } public String toString() { return sqlstate; } public boolean equals(String other) { return sqlstate.equals(other); } }
pgsql-patches by date: