JDBC Emit SQLError code for communication errors - Mailing list pgsql-patches

From Fernando Nasser
Subject JDBC Emit SQLError code for communication errors
Date
Msg-id 3DDAC2EC.1010401@redhat.com
Whole thread Raw
List pgsql-patches
Applications can't rely on the text of the SQLException error message to
detect that there was a communication error as it is localized (and
error messages are prone to change anyway).  So, a JDBC application
cannot take the appropriate actions when an IO error occurs.

This patch makes the JDBC driver report an eof and other communication
errors using the standard SQLSTATE value:

   "08S01"  (connection exception-communication link failure)

which can be safely tested for in applications.  Without this patch we
get null, instead of the "08S01" string, when calling getSQLState() as
the driver never sets that value.

The behavior of applications when we lose connection with the backend is
currently very bad, as there is no way to distinguish this problem from
a regular SQL error.

--
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/19 22:21:33
*************** public class PG_Stream
*** 137,143 ****
          {
              c = pg_input.read();
              if (c < 0)
!                 throw new PSQLException("postgresql.stream.eof");
          }
          catch (IOException e)
          {
--- 137,143 ----
          {
              c = pg_input.read();
              if (c < 0)
!                 throw new PSQLException("postgresql.stream.eof", "08S01");
          }
          catch (IOException e)
          {
*************** public class PG_Stream
*** 164,170 ****
                  int b = pg_input.read();

                  if (b < 0)
!                     throw new PSQLException("postgresql.stream.eof");
                  n = n | (b << (8 * i)) ;
              }
          }
--- 164,170 ----
                  int b = pg_input.read();

                  if (b < 0)
!                     throw new PSQLException("postgresql.stream.eof", "08S01");
                  n = n | (b << (8 * i)) ;
              }
          }
*************** public class PG_Stream
*** 193,199 ****
                  int b = pg_input.read();

                  if (b < 0)
!                     throw new PSQLException("postgresql.stream.eof");
                  n = b | (n << 8);
              }
          }
--- 193,199 ----
                  int b = pg_input.read();

                  if (b < 0)
!                     throw new PSQLException("postgresql.stream.eof", "08S01");
                  n = b | (n << 8);
              }
          }
*************** 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", "08S01");
                      else if (c == 0)
                      {
                          rst[s] = 0;
*************** public class PG_Stream
*** 330,336 ****
              {
                  int w = pg_input.read(b, off + s, siz - s);
                  if (w < 0)
!                     throw new PSQLException("postgresql.stream.eof");
                  s += w;
              }
          }
--- 330,336 ----
              {
                  int w = pg_input.read(b, off + s, siz - s);
                  if (w < 0)
!                     throw new PSQLException("postgresql.stream.eof", "08S01");
                  s += w;
              }
          }
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/19 22:21:33
*************** 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", "08S01", e);
          }
      }

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/19 22:21:33
*************** public class PSQLException extends SQLEx
*** 21,26 ****
--- 21,37 ----
      }

      /*
+      * Like the above, but sets SQLState
+      * @param error Error string
+      * @param sqlstate SQLState string
+      */
+     public PSQLException(String error, String sqlstate)
+     {
+         super("", sqlstate);
+         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
*** 50,55 ****
--- 61,95 ----
      public PSQLException(String error, Exception ex)
      {
          super();
+
+         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);
+     }
+
+     /*
+      * Like the above, but sets the SQLState
+      */
+     public PSQLException(String error, String sqlstate, Exception ex)
+     {
+         super("", sqlstate);

          Object[] argv = new Object[1];


pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: standardize on "canceled"
Next
From: Fernando Nasser
Date:
Subject: Re: JDBC Emit SQLError code for communication errors