db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r1530704 - in /db/derby/code/trunk/java: client/org/apache/derby/client/am/ client/org/apache/derby/client/net/ engine/org/apache/derby/loc/ shared/org/apache/derby/shared/common/reference/ testing/org/apache/derbyTesting/functionTests/test...
Date Wed, 09 Oct 2013 16:40:31 GMT
Author: dyre
Date: Wed Oct  9 16:40:31 2013
New Revision: 1530704

URL: http://svn.apache.org/r1530704
Log:
DERBY-5317: Detect attempts to reuse a connection that in the middle of sending a request
to the server. Use this to provide a better error message and avoid the NPE.

Modified:
    db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java
    db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorReader.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java
    db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    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/lang/ErrorCodeTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/Agent.java Wed Oct  9 16:40:31
2013
@@ -267,9 +267,8 @@ public abstract class Agent {
         }
         connection_.completeChainBreakingDisconnect();
     }
-
-    public void beginWriteChainOutsideUOW() throws SqlException {
-    }
+    
+    abstract public void beginWriteChainOutsideUOW() throws SqlException;
 
     public void beginWriteChain(ClientStatement statement) throws SqlException {
         connection_.writeTransactionStart(statement);
@@ -280,10 +279,10 @@ public abstract class Agent {
         beginWriteChain(statement);
     }
 
-    protected void endWriteChain() {
-    }
+    abstract protected void endWriteChain();
 
     private final void endBatchedWriteChain() {
+        endWriteChain();
     }
 
     protected void beginReadChain(ClientStatement statement)

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java
(original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java
Wed Oct  9 16:40:31 2013
@@ -179,9 +179,10 @@ class BlobLocatorInputStream extends Inp
             currentPos += result.length;
             return result;       
         } catch (SqlException ex) {
-            IOException ioEx = new IOException();
-            ioEx.initCause(ex);
-            throw ioEx;
+            // Passing cause as ctor argument ensures that the IOException 
+            // inherits the cause's message, (unlike invoking initCause() on a 
+            // default-constructed IOException).
+            throw new IOException(ex);
         }
     }
 

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java
(original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java
Wed Oct  9 16:40:31 2013
@@ -153,9 +153,10 @@ class ClobLocatorInputStream extends Inp
             currentPos += result.length;
             return result;
         } catch (SqlException ex) {
-            IOException ioEx = new IOException();
-            ioEx.initCause(ex);
-            throw ioEx;
+            // Passing cause as ctor argument ensures that the IOException 
+            // inherits the cause's message, (unlike invoking initCause() on a 
+            // default-constructed IOException).
+            throw new IOException(ex);
         }
     }
 

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorReader.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorReader.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorReader.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/am/ClobLocatorReader.java Wed
Oct  9 16:40:31 2013
@@ -227,9 +227,10 @@ class ClobLocatorReader extends Reader {
             currentPos += result.length;
             return result;
         } catch (SqlException ex) {
-            IOException ioEx = new IOException();
-            ioEx.initCause(ex);
-            throw ioEx;
+            // Passing cause as ctor argument ensures that the IOException 
+            // inherits the cause's message, (unlike invoking initCause() on a 
+            // default-constructed IOException).
+            throw new IOException(ex);
         }
     }
 }

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/NetAgent.java Wed Oct  9 16:40:31
2013
@@ -107,6 +107,13 @@ public class NetAgent extends Agent {
     SqlException exceptionOpeningSocket_ = null;
     SqlException exceptionConvertingRdbnam = null;
     
+    /**
+     * Flag which indicates that a writeChain has been started and data sent to
+     * the server.
+     * If true, starting a new write chain will throw a DisconnectException. 
+     * It is cleared when the write chain is ended.
+     */
+    private boolean writeChainIsDirty_ = false;
     //---------------------constructors/finalizer---------------------------------
 
     // Only used for testing
@@ -462,23 +469,41 @@ public class NetAgent extends Agent {
             throw de;
         }
     }
-
+    /**
+     * Marks the agent's write chain as dirty. A write chain is dirty when data
+     * from it has been sent to the server. A dirty write chain cannot be reset 
+     * and reused for another request until the remaining data has been sent to
+     * the server and the write chain properly ended. 
+     * 
+     * Resetting a dirty chain will cause the new request to be appended to the 
+     * unfinished request already at the server, which will likely lead to 
+     * cryptic syntax errors.
+     */
+    void markWriteChainAsDirty() {    
+        writeChainIsDirty_ = true;
+    }
+    
+    private void verifyWriteChainIsClean() throws DisconnectException {
+        if (writeChainIsDirty_) { 
+            throw new DisconnectException(this, 
+                new ClientMessageId(SQLState.NET_WRITE_CHAIN_IS_DIRTY));
+        }
+    }
     public void beginWriteChainOutsideUOW() throws SqlException {
+        verifyWriteChainIsClean();
         request_.initialize();
         writeDeferredResetConnection();
-        super.beginWriteChainOutsideUOW();
     }
 
     public void beginWriteChain(ClientStatement statement) throws SqlException {
+        verifyWriteChainIsClean();
         request_.initialize();
         writeDeferredResetConnection();
         super.beginWriteChain(statement);
     }
 
-    protected void endWriteChain() {
-        super.endWriteChain();
-    }
-
+    protected void endWriteChain() {}
+    
     private void readDeferredResetConnection() throws SqlException {
         if (!netConnection_.resetConnectionAtFirstSql_) {
             return;
@@ -496,19 +521,19 @@ public class NetAgent extends Agent {
 
     protected void beginReadChain(ClientStatement statement)
             throws SqlException {
+        // Clear here as endWriteChain may not always be called
+        writeChainIsDirty_ = false;
         readDeferredResetConnection();
         super.beginReadChain(statement);
     }
 
     protected void beginReadChainOutsideUOW() throws SqlException {
+        // Clear here as endWriteChain may not always be called
+        writeChainIsDirty_ = false;
         readDeferredResetConnection();
         super.beginReadChainOutsideUOW();
     }
 
-    public void endReadChain() throws SqlException {
-        super.endReadChain();
-    }
-
     /**
      * Switches the current CCSID manager to UTF-8
      */

Modified: db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java (original)
+++ db/derby/code/trunk/java/client/org/apache/derby/client/net/Request.java Wed Oct  9 16:40:31
2013
@@ -41,6 +41,7 @@ import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
 import java.nio.charset.Charset;
 import java.util.Hashtable;
+import org.apache.derby.iapi.error.ExceptionUtil;
 
 
 class Request {
@@ -315,16 +316,36 @@ class Request {
                 try {
                     bytesRead =
                         in.read(buffer.array(), buffer.position(), bytesToRead);
-                } catch (Exception e) {
+                } catch (IOException ioe) {
+                    if (netAgent_.getOutputStream() == null) {
+                        // The exception has taken down the connection, so we 
+                        // check if it was caused by attempting to 
+                        // read the stream from our own connection...
+                        for (Throwable t = ioe; t != null; t = t.getCause()) {
+                            if (t instanceof SqlException
+                                    && ((SqlException) t).getSQLState().equals(ExceptionUtil.getSQLStateFromIdentifier(SQLState.NET_WRITE_CHAIN_IS_DIRTY)))
{
+                                throw new SqlException(netAgent_.logWriter_,
+                                        new ClientMessageId(SQLState.NET_LOCATOR_STREAM_PARAMS_NOT_SUPPORTED),
+                                        ioe, parameterIndex);
+                            }
+                        }
+                        // Something else has killed the connection, fast forward to despair...
+                        throw new SqlException(netAgent_.logWriter_,
+                                new ClientMessageId(SQLState.NET_DISCONNECT_EXCEPTION_ON_READ),
+                                ioe, parameterIndex, ioe.getMessage());
+                    }
+                    // The OutPutStream is still intact so try to finish request
+                    // with what we managed to read
+
                     status = DRDAConstants.STREAM_READ_ERROR;
                     padScalarStreamForError(leftToRead, bytesToRead,
                             writeEXTDTAStatusByte, status);
                     // set with SQLSTATE 01004: The value of a string was truncated when
assigned to a host variable.
                     netAgent_.accumulateReadException(
-                        new SqlException(
+                            new SqlException(
                             netAgent_.logWriter_,
                             new ClientMessageId(SQLState.NET_EXCEPTION_ON_READ),
-                            e, parameterIndex, e.getMessage()));
+                            ioe, parameterIndex, ioe.getMessage()));
 
                     return;
                 }
@@ -1176,6 +1197,7 @@ class Request {
     private void sendBytes(OutputStream socketOutputStream)
             throws IOException {
         try {
+            netAgent_.markWriteChainAsDirty();
             socketOutputStream.write(buffer.array(), 0, buffer.position());
             socketOutputStream.flush();
         } finally {

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Wed Oct  9 16:40:31
2013
@@ -5263,6 +5263,23 @@ ln=lower-case two-letter ISO-639 languag
                 <arg>targetClassName</arg>
             </msg>
 
+            <msg>
+                <name>XN022.C</name>
+                <text>A write chain that has transmitted data to the server cannot
be reset until the request is finished and the chain terminated.</text>
+            </msg>
+            
+            <msg>
+                <name>XN023.C</name>
+                <text>The stream specified by parameter #{0} is locator-based and requires
a nested request on the same connection to be materialized. This is not supported.</text>
+                <arg>number</arg>
+            </msg>
+            
+            <msg>
+                <name>XN024.C</name>
+                <text>Encountered an exception which terminated the connection, while
reading from the stream specified by parameter #{0}. The Exception had this message: '{1}'.</text>
+                <arg>number</arg>
+                <arg>messageText</arg>
+            </msg>
         </family>
 
 

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=1530704&r1=1530703&r2=1530704&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
Wed Oct  9 16:40:31 2013
@@ -1630,6 +1630,9 @@ public interface SQLState {
     String NET_XARETVAL_ERROR                                       = "XN019.S";
     String NET_MARSHALLING_UDT_ERROR                     = "XN020.S";
     String NET_UDT_COERCION_ERROR                               = "XN021.S";
+    String NET_WRITE_CHAIN_IS_DIRTY                                 = "XN022.C";
+    String NET_LOCATOR_STREAM_PARAMS_NOT_SUPPORTED                  = "XN023.C";
+    String NET_DISCONNECT_EXCEPTION_ON_READ                         = "XN024.C";
     
     // XML - Derby-specific XML errors not covered by
     // SQL standard.

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
Wed Oct  9 16:40:31 2013
@@ -201,6 +201,9 @@ public final class ErrorCodeTest extends
         		{"XJ05B","JDBC attribute '{0}' has an invalid value '{1}', valid values are '{2}'.","40000"},
         		{"XJ081","Conflicting create/restore/recovery attributes specified.","40000"},
         		{"XJ213","The traceLevel connection property does not have a valid format for a
number.","40000"},
+        		{"XN022","A write chain that has transmitted data to the server cannot be reset
until the request is finished and the chain terminated.","40000"},
+        		{"XN023","The stream specified by parameter #{0} is locator-based and requires
a nested request on the same connection to be materialized. This is not supported.","40000"},
+        		{"XN024","Encountered an exception which terminated the connection, while reading
from the stream specified by parameter #{0}. The Exception had this message: '{1}'.","40000"},
         		{"XRE20","Failover performed successfully for database '{0}', the database has
been shutdown.","45000"},
         		{"XSDB0","Unexpected exception on in-memory page {0}","45000"},
         		{"XSDB1","Unknown page format at page {0}","45000"},

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java?rev=1530704&r1=1530703&r2=1530704&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java
Wed Oct  9 16:40:31 2013
@@ -1082,18 +1082,22 @@ public class LobLimitsTest extends BaseJ
         long dlen = rs.getLong(2);
         assertEquals("FAIL - MISMATCH LENGTHS GOT " + l + " expected "
                 + dlen + " for row in CLOBTBL with ID=" + id, dlen, l);
-        // DERBY-5317 cannot use setCharacterStream with value from
-        // Clob.getCharacterStream because server will try to stream
-        // lob to and from server at the same time. setClob can be
-        // used as a work around.
-        if (!usingDerbyNetClient()) {
-            PreparedStatement psUpd =
-                    prepareStatement("update CLOBTBL set content=?, " +
-                            "dlen =? where id = ?");
-            psUpd.setCharacterStream(1, value.getCharacterStream(), (int) l);
-            psUpd.setLong(2, l);
-            psUpd.setInt(3, updateId);
-
+                
+        PreparedStatement psUpd =
+                prepareStatement("update CLOBTBL set content=?, "
+                + "dlen =? where id = ?");
+        psUpd.setCharacterStream(1, value.getCharacterStream(), (int) l);
+        psUpd.setLong(2, l);
+        psUpd.setInt(3, updateId);
+        if (usingDerbyNetClient()) {
+            // DERBY-5317 cannot use setCharacterStream with value from
+            // Clob.getCharacterStream because server will try to stream
+            // lob to and from server at the same time. setClob can be
+            // used as a work around.
+            // Verify that new error is thrown 
+            assertPreparedStatementError("XN023", psUpd);
+            return;
+        } else {
             assertUpdateCount(psUpd, 1);
         }
         commit();



Mime
View raw message