You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2006/07/03 08:14:08 UTC

svn commit: r418692 - in /db/derby/code/trunk/java: build/org/apache/derbyBuild/ client/org/apache/derby/client/am/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/

Author: kahatlen
Date: Sun Jul  2 23:14:07 2006
New Revision: 418692

URL: http://svn.apache.org/viewvc?rev=418692&view=rev
Log:
DERBY-1364: Client driver does not roll back the effects of a stored
procedure when incorrectly invoked by executeQuery()/executeUpdate()

Description of the patch:

1. Checking of the number of result sets returned was moved from
   executeUpdate/executeQuery to a point in flowExecute where the
   transaction has not been auto-committed (otherwise, the transaction
   would already be committed when the exception was raised).

2. If the number of result sets does not match the execute type and
   auto-commit is enabled, the transaction is rolled back (otherwise,
   the transaction would be committed when the Statement was closed or
   re-executed).

3. All execute* methods in CallableStatement were removed since they
   have become identical to the methods in PreparedStatement. (Or
   almost identical. The methods in CallableStatement did not call
   checkStatementValidity() on errors, but that's probably a bug.)

4. SQL state for error message in executeQuery() was changed to match
   embedded (XJ201/XJ205 -> X0Y78). Updated English and Portuguese
   messages to use the new SQL state (no other translations existed
   for XJ201 and XJ205).

5. Added more rollback tests to jdbcapi/ProcedureTest.junit and
   enabled all test cases for DerbyNetClient.

Modified:
    db/derby/code/trunk/java/build/org/apache/derbyBuild/splitmessages.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_pt_BR.properties
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java

Modified: db/derby/code/trunk/java/build/org/apache/derbyBuild/splitmessages.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/build/org/apache/derbyBuild/splitmessages.java?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/build/org/apache/derbyBuild/splitmessages.java (original)
+++ db/derby/code/trunk/java/build/org/apache/derbyBuild/splitmessages.java Sun Jul  2 23:14:07 2006
@@ -84,6 +84,8 @@
         clientMessageIds.add(SQLState.NOGETCONN_ON_CLOSED_POOLED_CONNECTION);
         clientMessageIds.add(SQLState.LOB_METHOD_ON_CLOSED_CONNECTION);
         clientMessageIds.add(SQLState.QUERY_NOT_QUALIFIED_FOR_UPDATABLE_RESULTSET);
+        clientMessageIds.add(SQLState.MULTIPLE_RESULTS_ON_EXECUTE_QUERY);
+        clientMessageIds.add(SQLState.USE_EXECUTE_UPDATE_WITH_NO_RESULTS);
         clientMessageIds.add(SQLState.LANG_INVALID_CALL_TO_EXECUTE_UPDATE);
         clientMessageIds.add(SQLState.LANG_CANT_INVALIDATE_OPEN_RESULT_SET);
         clientMessageIds.add(SQLState.YEAR_EXCEEDS_MAXIMUM);

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/CallableStatement.java Sun Jul  2 23:14:07 2006
@@ -127,89 +127,6 @@
 
     //---------------------------entry points-------------------------------------
 
-    public boolean execute() throws SQLException {
-        try
-        {
-            synchronized (connection_) {
-                if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceEntry(this, "execute");
-                }
-                boolean b = executeX();
-                if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceExit(this, "execute", b);
-                }
-                return b;
-            }
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
-        }
-    }
-
-    // also used by SQLCA
-    boolean executeX() throws SqlException {
-        super.flowExecute(executeMethod__);
-        return resultSet_ != null;
-    }
-
-    public java.sql.ResultSet executeQuery() throws SQLException {
-        try
-        {
-            synchronized (connection_) {
-                if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceEntry(this, "executeQuery");
-                }
-                ResultSet resultSet = executeQueryX();
-                if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceExit(this, "executeQuery", resultSet);
-                }
-                return resultSet;
-            }
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
-        }
-    }
-
-    // also used by DBMD methods
-    ResultSet executeQueryX() throws SqlException {
-        super.flowExecute(executeQueryMethod__);
-        super.checkExecuteQueryPostConditions("java.sql.CallableStatement");
-        return resultSet_;
-    }
-
-    public int executeUpdate() throws SQLException {
-        try
-        {
-            synchronized (connection_) {
-                if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceEntry(this, "executeUpdate");
-                }
-                int updateValue = executeUpdateX();
-                if (agent_.loggingEnabled()) {
-                    agent_.logWriter_.traceExit(this, "executeUpdate", updateValue);
-                }
-                return updateValue;
-            }
-        }
-        catch ( SqlException se )
-        {
-            throw se.getSQLException();
-        }
-    }
-
-    int executeUpdateX() throws SqlException {
-        super.flowExecute(executeUpdateMethod__);
-
-        super.checkExecuteUpdatePostConditions("java.sql.CallableStatement");
-        // make sure update count >= 0 even if derby don't support update count for call
-        //return (updateCount_ < 0) ? 0 : updateCount_;
-        return updateCount_;
-    }
-
-
     public void clearParameters() throws SQLException {
         synchronized (connection_) {
             if (agent_.loggingEnabled()) {
@@ -1427,6 +1344,14 @@
     }
     
     //----------------------------helper methods----------------------------------
+
+    /**
+     * Returns the name of the java.sql interface implemented by this class.
+     * @return name of java.sql interface
+     */
+    protected String getJdbcStatementInterfaceName() {
+        return "java.sql.CallableStatement";
+    }
 
     private int checkForEscapedCallWithResult(int parameterIndex) throws SqlException {
         if (escapedProcedureCallWithResult_) {

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/PreparedStatement.java Sun Jul  2 23:14:07 2006
@@ -360,8 +360,6 @@
     // also called by some DBMD methods
     ResultSet executeQueryX() throws SqlException {
         flowExecute(executeQueryMethod__);
-
-        super.checkExecuteQueryPostConditions("java.sql.PreparedStatement");
         return resultSet_;
     }
 
@@ -388,7 +386,6 @@
 
     private int executeUpdateX() throws SqlException {
         flowExecute(executeUpdateMethod__);
-        checkExecuteUpdatePostConditions("java.sql.PreparedStatement");
         return updateCount_;
     }
 
@@ -1297,7 +1294,8 @@
         }
     }
 
-    private boolean executeX() throws SqlException {
+    // also used by SQLCA
+    boolean executeX() throws SqlException {
         flowExecute(executeMethod__);
 
         return resultSet_ != null;
@@ -1882,6 +1880,7 @@
 
             if (sqlMode_ == isCall__) {
                 parseStorProcReturnedScrollableRowset();
+                checkForStoredProcResultSetCount(executeType);
                 // When there are no result sets back, we will commit immediately when autocommit is true.
                 // make sure a commit is not performed when making the call to the sqlca message procedure
                 if (connection_.autoCommit_ && resultSet_ == null && resultSetList_ == null && isAutoCommittableStatement_) {
@@ -2106,6 +2105,14 @@
     }
 
     //----------------------------internal use only helper methods----------------
+
+    /**
+     * Returns the name of the java.sql interface implemented by this class.
+     * @return name of java.sql interface
+     */
+    protected String getJdbcStatementInterfaceName() {
+        return "java.sql.PreparedStatement";
+    }
 
     private int checkSetterPreconditions(int parameterIndex) throws SqlException {
         super.checkForClosedStatement();

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Statement.java Sun Jul  2 23:14:07 2006
@@ -419,26 +419,9 @@
 
     private ResultSet executeQueryX(String sql) throws SqlException {
         flowExecute(executeQueryMethod__, sql);
-
-        checkExecuteQueryPostConditions("java.sql.Statement");
         return resultSet_;
     }
 
-    void checkExecuteQueryPostConditions(String jdbcStatementInterfaceName) throws SqlException {
-        // We'll just rely on finalizers to close the dangling result sets.
-        if (resultSetList_ != null && resultSetList_.length != 1) {
-            throw new SqlException(agent_.logWriter_, 
-                new ClientMessageId(SQLState.MULTIPLE_RESULTS_ON_EXECUTE_QUERY),
-                jdbcStatementInterfaceName, jdbcStatementInterfaceName);
-        }
-
-        if (resultSet_ == null) {
-            throw new SqlException(agent_.logWriter_, 
-                new ClientMessageId(SQLState.USE_EXECUTE_UPDATE_WITH_NO_RESULTS),
-                jdbcStatementInterfaceName, jdbcStatementInterfaceName);
-        }
-    }
-
     public int executeUpdate(String sql) throws SQLException {
         try
         {
@@ -461,26 +444,9 @@
 
     private int executeUpdateX(String sql) throws SqlException {
         flowExecute(executeUpdateMethod__, sql);
-
-        checkExecuteUpdatePostConditions("java.sql.Statement");
         return updateCount_;
     }
 
-    void checkExecuteUpdatePostConditions(String jdbcStatementInterfaceName) throws SqlException {
-        // We'll just rely on finalizers to close the dangling result sets.
-        if (resultSetList_ != null) {
-            throw new SqlException(agent_.logWriter_, 
-                new ClientMessageId(SQLState.MULTIPLE_RESULTS_ON_EXECUTE_QUERY),
-                jdbcStatementInterfaceName, jdbcStatementInterfaceName);
-        }
-
-        // We'll just rely on the finalizer to close the dangling result set.
-        if (resultSet_ != null) {
-            throw new SqlException(agent_.logWriter_, 
-                new ClientMessageId(SQLState.LANG_INVALID_CALL_TO_EXECUTE_UPDATE));
-        }
-    }
-
     /**
      * Returns false unless <code>iface</code> is implemented 
      * 
@@ -2079,6 +2045,7 @@
         // In the case of executing a call to a stored procedure.
         if (sqlMode_ == isCall__) {
             parseStorProcReturnedScrollableRowset();
+            checkForStoredProcResultSetCount(executeType);
             // When there is no result sets back, we will commit immediately when autocommit is true.
             if (connection_.autoCommit_ && resultSet_ == null && resultSetList_ == null) {
                 connection_.flowAutoCommit();
@@ -2233,6 +2200,14 @@
 
     //-------------------------------helper methods-------------------------------
 
+    /**
+     * Returns the name of the java.sql interface implemented by this class.
+     * @return name of java.sql interface
+     */
+    protected String getJdbcStatementInterfaceName() {
+        return "java.sql.Statement";
+    }
+
     // Should investigate if it can be optimized..  if we can avoid this parsing..
     //
     void parseSqlAndSetSqlModes(String sql) throws SqlException {
@@ -2365,6 +2340,76 @@
         if (executeType == executeUpdateMethod__ && sqlMode == isQuery__) {
             throw new SqlException(agent_.logWriter_, 
                 new ClientMessageId(SQLState.LANG_INVALID_CALL_TO_EXECUTE_UPDATE));
+        }
+    }
+
+    /**
+     * Checks that the number of result sets returned by the statement
+     * is consistent with the executed type. <code>executeQuery()</code>
+     * should return exactly one result set and <code>executeUpdate()</code>
+     * none. Raises an exception if the result set count does not match the
+     * execute type.
+     *
+     * @param executeType one of <code>executeQueryMethod__</code>,
+     * <code>executeUpdateMethod__</code> and <code>executeMethod__</code>
+     * @exception SqlException if the number of result sets does not
+     *                         match the execute type
+     */
+    private void checkResultSetCount(int executeType) throws SqlException {
+        switch (executeType) {
+        case executeQueryMethod__:
+            // We'll just rely on finalizers to close the dangling result sets.
+            if (resultSetList_ != null && resultSetList_.length > 1) {
+                throw new
+                    SqlException(agent_.logWriter_,
+                                 new ClientMessageId(
+                                    SQLState.MULTIPLE_RESULTS_ON_EXECUTE_QUERY),
+                                 getJdbcStatementInterfaceName(),
+                                 getJdbcStatementInterfaceName());
+            }
+            if (resultSet_ == null || resultSetList_.length == 0) {
+                ClientMessageId messageId =
+                    new ClientMessageId(
+                                SQLState.USE_EXECUTE_UPDATE_WITH_NO_RESULTS);
+                throw new SqlException(agent_.logWriter_, messageId,
+                                       getJdbcStatementInterfaceName(),
+                                       getJdbcStatementInterfaceName());
+            }
+            break;
+        case executeUpdateMethod__:
+            // We'll just rely on finalizers to close the dangling result sets.
+            if (resultSet_ != null && resultSetList_.length > 0) {
+                ClientMessageId messageId =
+                    new ClientMessageId(
+                        SQLState.LANG_INVALID_CALL_TO_EXECUTE_UPDATE);
+                throw new SqlException(agent_.logWriter_, messageId);
+            }
+            break;
+        }
+    }
+
+    /**
+     * Checks that a stored procedure returns the correct number of
+     * result sets given its execute type. If the number is incorrect,
+     * make sure the transaction is rolled back when auto commit is
+     * enabled.
+     *
+     * @param executeType one of <code>executeQueryMethod__</code>,
+     * <code>executeUpdateMethod__</code> and <code>executeMethod__</code>
+     * @exception SqlException if the number of result sets does not
+     *                         match the execute type
+     * @see #checkResultSetCount(int)
+     */
+    protected final void checkForStoredProcResultSetCount(int executeType)
+        throws SqlException
+    {
+        try {
+            checkResultSetCount(executeType);
+        } catch (SqlException se) {
+            if (connection_.autoCommit_) {
+                connection_.flowRollback();
+            }
+            throw se;
         }
     }
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties Sun Jul  2 23:14:07 2006
@@ -1042,6 +1042,8 @@
 X0Y72.S=Bulk insert replace is not permitted on ''{0}'' because it has an enabled trigger ({1}).
 X0Y77.S=Cannot issue set transaction isolation statement on a global transaction that is in progress because it would have implicitly committed the global transaction.
 X0Y78.S=Statement.executeQuery() cannot be called with a statement that returns a row count.
+X0Y78.S.1={0}.executeQuery() cannot be called because multiple result sets were returned.  Use {1}.execute() to obtain multiple results.
+X0Y78.S.2={0}.executeQuery() was called but no result set was returned. Use {1}.executeUpdate() for non-queries.
 X0Y79.S=Statement.executeUpdate() cannot be called with a statement that returns a ResultSet.
 X0Y80.S=ALTER table ''{0}'' failed. Null data found in column ''{1}''.
 X0Y83.S=WARNING: While deleting a row from a table the index row for base table row {0} was not found in index with conglomerate id {1}.  This problem has automatically been corrected as part of the delete operation.
@@ -1232,11 +1234,9 @@
 XJ128.S=Unable to unwrap for ''{0}''
 
 XJ200.S=Exceeded maximum number of sections {0}
-XJ201.S={0}.executeQuery() cannot be called because multiple result sets were returned.  Use {1}.execute() to obtain multiple results.
 XJ202.S=Invalid cursor name ''{0}''.
 XJ203.S=Cursor name ''{0}'' is already in use
 XJ204.S=Unable to open result set with requested holdability {0}.
-XJ205.S={0}.executeQuery() was called but no result set was returned. Use {1}.executeUpdate() for non-queries."
 XJ206.S=SQL text ''{0}'' has no tokens.
 XJ207.S=executeQuery method can not be used for update.
 XJ208.S=Non-atomic batch failure.  The batch was submitted, but at least one exception occurred on an individual member of the batch. Use getNextException() to retrieve the exceptions for specific batched elements.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_pt_BR.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_pt_BR.properties?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_pt_BR.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages_pt_BR.properties Sun Jul  2 23:14:07 2006
@@ -1040,6 +1040,8 @@
 X0Y72.S=A substitui\u00e7\u00e3o em massa da inser\u00e7\u00e3o n\u00e3o \u00e9 permitida em ''{0}'', porque h\u00e1 o gatilho ativo ({1}).
 X0Y77.S=N\u00e3o \u00e9 poss\u00edvel emitir a instru\u00e7\u00e3o de isolamento de transa\u00e7\u00e3o em uma transa\u00e7\u00e3o global em andamento, porque isto efetivaria implicitamente a transa\u00e7\u00e3o global.
 X0Y78.S=N\u00e3o pode ser chamado Statement.executeQuery() com uma instru\u00e7\u00e3o que retorna contagem de linha.
+X0Y78.S.1=N\u00e3o p\u00f4de ser chamado {0}.executeQuery(), porque foram retornados v\u00e1rios conjuntos de resultados.  Para obter v\u00e1rios resultados deve ser utilizado {1}.execute().
+X0Y78.S.2=Foi chamado {0}.executeQuery(), mas n\u00e3o foi retornado nenhum resultado. Utilize {1}.executeUpdate() para o que n\u00e3o for consulta.
 X0Y79.S=N\u00e3o pode ser chamado Statement.executeUpdate() com uma instru\u00e7\u00e3o que retorna ResultSet.
 X0Y80.S=Falha na altera\u00e7\u00e3o da tabela ''{0}''. Encontrados valores nulos na coluna ''{1}''.
 X0Y83.S=ADVERT\u00caNCIA: Durante a exclus\u00e3o de uma linha da tabela, a linha do \u00edndice para a linha da tabela base {0} n\u00e3o foi encontrada no \u00edndice com id de conglomerado {1}.  Esse problema foi automaticamente corrigido como parte da opera\u00e7\u00e3o de exclus\u00e3o.
@@ -1230,11 +1232,9 @@
 XJ128.S=N\u00e3o foi poss\u00edvel desempacotar para ''{0}''
 
 XJ200.S=Foi excedido o n\u00famero m\u00e1ximo de sess\u00f5es {0}
-XJ201.S=N\u00e3o p\u00f4de ser chamado {0}.executeQuery(), porque foram retornados v\u00e1rios conjuntos de resultados.  Para obter v\u00e1rios resultados deve ser utilizado {1}.execute().
 XJ202.S=Nome inv\u00e1lido de cursor ''{0}''.
 XJ203.S=O cursor com nome ''{0}'' j\u00e1 est\u00e1 em uso.
 XJ204.S=N\u00e3o foi poss\u00edvel abrir o conjunto de resultados com a capacidade de reten\u00e7\u00e3o requisitada {0}.
-XJ205.S=Foi chamado {0}.executeQuery(), mas n\u00e3o foi retornado nenhum resultado. Utilize {1}.executeUpdate() para o que n\u00e3o for consulta."
 XJ206.S=O texto SQL ''{0}'' n\u00e3o possui elementos.
 XJ207.S=O m\u00e9todo ''executeQuery'' n\u00e3o pode ser utilizado para atualiza\u00e7\u00f5es.
 XJ208.S=Falha de lote n\u00e3o at\u00f4mica.  O lote foi submetido, mas ocorreu pelo menos uma exce\u00e7\u00e3o em um membro individual do lote. Utilize getNextException() para obter as exce\u00e7\u00f5es para os elementos do lote espec\u00edficos.

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Sun Jul  2 23:14:07 2006
@@ -1233,6 +1233,8 @@
 	String LANG_NO_BULK_INSERT_REPLACE_WITH_TRIGGER_DURING_EXECUTION   = "X0Y72.S";
 	String LANG_NO_SET_TRAN_ISO_IN_GLOBAL_CONNECTION                   = "X0Y77.S";
 	String LANG_INVALID_CALL_TO_EXECUTE_QUERY		                   = "X0Y78.S";
+    String MULTIPLE_RESULTS_ON_EXECUTE_QUERY = "X0Y78.S.1";
+    String USE_EXECUTE_UPDATE_WITH_NO_RESULTS = "X0Y78.S.2";
 	String LANG_INVALID_CALL_TO_EXECUTE_UPDATE		                   = "X0Y79.S";
 	String LANG_NULL_DATA_IN_NON_NULL_COLUMN               	   	   	   = "X0Y80.S";
     String LANG_IGNORE_MISSING_INDEX_ROW_DURING_DELETE                 = "X0Y83.S";
@@ -1454,11 +1456,9 @@
     String UNABLE_TO_UNWRAP = "XJ128.S";
     
     String EXCEEDED_MAX_SECTIONS = "XJ200.S";
-    String MULTIPLE_RESULTS_ON_EXECUTE_QUERY = "XJ201.S";
     String CURSOR_INVALID_NAME = "XJ202.S";
     String CURSOR_DUPLICATE_NAME = "XJ203.S";
     String UNABLE_TO_OPEN_RS_WITH_REQUESTED_HOLDABILITY = "XJ204.S";
-    String USE_EXECUTE_UPDATE_WITH_NO_RESULTS = "XJ205.S";
     String NO_TOKENS_IN_SQL_TEXT = "XJ206.S";
     String CANT_USE_EXEC_QUERY_FOR_UPDATE = "XJ207.S";
     String BATCH_NON_ATOMIC_FAILURE = "XJ208.S";

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java?rev=418692&r1=418691&r2=418692&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ProcedureTest.java Sun Jul  2 23:14:07 2006
@@ -373,7 +373,7 @@
      * <code>executeQuery()</code> are correctly rolled back when the
      * query fails because the number of returned result sets is zero.
      *
-     * <p> This test case fails with the client driver and JCC (DERBY-1364).
+     * <p> This test case fails with JCC.
      *
      * @exception SQLException if a database error occurs
      */
@@ -401,7 +401,7 @@
      * query fails because the number of returned result sets is more
      * than one.
      *
-     * <p> This test case fails with the client driver and JCC (DERBY-1364).
+     * <p> This test case fails with JCC.
      *
      * @exception SQLException if a database error occurs
      */
@@ -428,7 +428,7 @@
      * <code>executeUpdate()</code> are correctly rolled back when the
      * query fails because the stored procedure returned a result set.
      *
-     * <p> This test case fails with the client driver and JCC (DERBY-1364).
+     * <p> This test case fails with JCC.
      *
      * @exception SQLException if a database error occurs
      */
@@ -451,6 +451,101 @@
     }
 
     /**
+     * Tests that the effects of executing a stored procedure with
+     * <code>executeQuery()</code> are correctly rolled back when the
+     * query fails because the number of returned result sets is zero.
+     *
+     * <p> This test case fails with JCC.
+     *
+     * @exception SQLException if a database error occurs
+     */
+    public void xtestRollbackStoredProcWhenExecuteQueryReturnsNothing_prepared()
+        throws SQLException
+    {
+        conn.setAutoCommit(true);
+        PreparedStatement ps =
+            conn.prepareStatement("CALL PROC_WITH_SIDE_EFFECTS(?)");
+        ps.setInt(1, 0);
+        try {
+            ResultSet rs = ps.executeQuery();
+            fail("executeQuery() didn't fail.");
+        } catch (SQLException sqle) {
+            assertNoResultSetFromExecuteQuery(sqle);
+        }
+        Statement stmt = conn.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT * FROM SIMPLE_TABLE");
+        assertFalse("Side effects from stored procedure not rolled back.",
+                    rs.next());
+        rs.close();
+        ps.close();
+        stmt.close();
+    }
+
+    /**
+     * Tests that the effects of executing a stored procedure with
+     * <code>executeQuery()</code> are correctly rolled back when the
+     * query fails because the number of returned result sets is more
+     * than one.
+     *
+     * <p> This test case fails with JCC.
+     *
+     * @exception SQLException if a database error occurs
+     */
+    public void xtestRollbackStoredProcWhenExecuteQueryReturnsTooMuch_prepared()
+        throws SQLException
+    {
+        conn.setAutoCommit(true);
+        PreparedStatement ps =
+            conn.prepareStatement("CALL PROC_WITH_SIDE_EFFECTS(?)");
+        ps.setInt(1, 2);
+        try {
+            ResultSet rs = ps.executeQuery();
+            fail("executeQuery() didn't fail.");
+        } catch (SQLException sqle) {
+            assertMultipleResultsFromExecuteQuery(sqle);
+        }
+        Statement stmt = conn.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT * FROM SIMPLE_TABLE");
+        assertFalse("Side effects from stored procedure not rolled back.",
+                    rs.next());
+        rs.close();
+        ps.close();
+        stmt.close();
+    }
+
+    /**
+     * Tests that the effects of executing a stored procedure with
+     * <code>executeUpdate()</code> are correctly rolled back when the
+     * query fails because the stored procedure returned a result set.
+     *
+     * <p> This test case fails with JCC.
+     *
+     * @exception SQLException if a database error occurs
+     */
+    public void
+        xtestRollbackStoredProcWhenExecuteUpdateReturnsResults_prepared()
+        throws SQLException
+    {
+        conn.setAutoCommit(true);
+        PreparedStatement ps =
+            conn.prepareStatement("CALL PROC_WITH_SIDE_EFFECTS(?)");
+        ps.setInt(1, 1);
+        try {
+            ps.executeUpdate();
+            fail("executeUpdate() didn't fail.");
+        } catch (SQLException sqle) {
+            assertResultsFromExecuteUpdate(sqle);
+        }
+        Statement stmt = conn.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT * FROM SIMPLE_TABLE");
+        assertFalse("Side effects from stored procedure not rolled back.",
+                    rs.next());
+        rs.close();
+        ps.close();
+        stmt.close();
+    }
+
+    /**
      * Tests that closed result sets are not returned when calling
      * <code>executeQuery()</code>.
      * @exception SQLException if a database error occurs
@@ -521,14 +616,10 @@
      * @param sqle a <code>SQLException</code> value
      */
     private static void assertNoResultSetFromExecuteQuery(SQLException sqle) {
-        if (usingEmbedded()) {
-            assertSQLState("Unexpected SQL state.", "X0Y78", sqle);
-        } else if (usingDerbyNetClient()) {
-            assertSQLState("Unexpected SQL state.", "XJ205", sqle);
-        } else if (usingDerbyNet()) {
+        if (usingDerbyNet()) {
             assertNull("Unexpected SQL state.", sqle.getSQLState());
         } else {
-            fail("Unrecognized framework.");
+            assertSQLState("Unexpected SQL state.", "X0Y78", sqle);
         }
     }
 
@@ -540,14 +631,10 @@
      */
     private static void assertMultipleResultsFromExecuteQuery(SQLException sqle)
     {
-        if (usingEmbedded()) {
-            assertSQLState("Unexpected SQL state.", "X0Y78", sqle);
-        } else if (usingDerbyNetClient()) {
-            assertSQLState("Unexpected SQL state.", "XJ201", sqle);
-        } else if (usingDerbyNet()) {
+        if (usingDerbyNet()) {
             assertNull("Unexpected SQL state.", sqle.getSQLState());
         } else {
-            fail("Unrecognized framework.");
+            assertSQLState("Unexpected SQL state.", "X0Y78", sqle);
         }
     }
 
@@ -558,14 +645,10 @@
      * @param sqle a <code>SQLException</code> value
      */
     private static void assertResultsFromExecuteUpdate(SQLException sqle) {
-        if (usingEmbedded()) {
-            assertSQLState("Unexpected SQL state.", "X0Y79", sqle);
-        } else if (usingDerbyNetClient()) {
-            assertSQLState("Unexpected SQL state.", "XJ201", sqle);
-        } else if (usingDerbyNet()) {
+        if (usingDerbyNet()) {
             assertNull("Unexpected SQL state.", sqle.getSQLState());
         } else {
-            fail("Unrecognized framework.");
+            assertSQLState("Unexpected SQL state.", "X0Y79", sqle);
         }
 
     }
@@ -592,8 +675,6 @@
             suite.addTest
                 (new ProcedureTest
                  ("xtestExecuteUpdateWithNoDynamicResultSets_callable"));
-        }
-        if (usingEmbedded()) {
             suite.addTest
                 (new ProcedureTest
                  ("xtestRollbackStoredProcWhenExecuteQueryReturnsNothing"));
@@ -603,6 +684,18 @@
             suite.addTest
                 (new ProcedureTest
                  ("xtestRollbackStoredProcWhenExecuteUpdateReturnsResults"));
+            suite.addTest
+                (new ProcedureTest
+                 ("xtestRollbackStoredProcWhenExecuteQueryReturnsNothing" +
+                  "_prepared"));
+            suite.addTest
+                (new ProcedureTest
+                 ("xtestRollbackStoredProcWhenExecuteQueryReturnsTooMuch" +
+                  "_prepared"));
+            suite.addTest
+                (new ProcedureTest
+                 ("xtestRollbackStoredProcWhenExecuteUpdateReturnsResults" +
+                  "_prepared"));
         }
         return new TestSetup(suite) {
             public void setUp() throws Exception {