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 mi...@apache.org on 2014/03/02 19:05:49 UTC
svn commit: r1573334 - in /db/derby/code/branches/10.10: ./
java/client/org/apache/derby/client/am/
java/client/org/apache/derby/client/net/ java/engine/org/apache/derby/loc/
java/shared/org/apache/derby/shared/common/reference/
java/testing/org/apache...
Author: mikem
Date: Sun Mar 2 18:05:49 2014
New Revision: 1573334
URL: http://svn.apache.org/r1573334
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.
DERBY-6386 - Errors in jdbc4.LobStreamTest if derbyclient.jar is first in the classpath
backported change #1530704 to fix DERBY-5317 from trunk to 10.10, needed some
hand merging to fix difference in argument ordering between 10.10 and trunk.
backported change #1534425 to fix DERBY-6386 which was caused by DERBY5317 fix.
Modified:
db/derby/code/branches/10.10/ (props changed)
db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/Agent.java
db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java
db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java
db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorReader.java
db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/NetAgent.java
db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/Request.java
db/derby/code/branches/10.10/java/engine/org/apache/derby/loc/messages.xml
db/derby/code/branches/10.10/java/shared/org/apache/derby/shared/common/reference/SQLState.java
db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java
Propchange: db/derby/code/branches/10.10/
------------------------------------------------------------------------------
Merged /db/derby/code/trunk:r1530704
Modified: db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/Agent.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/Agent.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/Agent.java (original)
+++ db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/Agent.java Sun Mar 2 18:05:49 2014
@@ -263,9 +263,8 @@ public abstract class Agent {
}
connection_.completeChainBreakingDisconnect();
}
-
- public void beginWriteChainOutsideUOW() throws SqlException {
- }
+
+ abstract public void beginWriteChainOutsideUOW() throws SqlException;
public void beginWriteChain(Statement statement) throws SqlException {
connection_.writeTransactionStart(statement);
@@ -275,10 +274,10 @@ public abstract class Agent {
beginWriteChain(statement);
}
- protected void endWriteChain() {
- }
+ abstract protected void endWriteChain();
protected final void endBatchedWriteChain() {
+ endWriteChain();
}
protected void beginReadChain(Statement statement) throws SqlException {
Modified: db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java (original)
+++ db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/BlobLocatorInputStream.java Sun Mar 2 18:05:49 2014
@@ -178,9 +178,10 @@ public class BlobLocatorInputStream exte
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/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java (original)
+++ db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorInputStream.java Sun Mar 2 18:05:49 2014
@@ -150,9 +150,10 @@ public class ClobLocatorInputStream exte
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/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorReader.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorReader.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorReader.java (original)
+++ db/derby/code/branches/10.10/java/client/org/apache/derby/client/am/ClobLocatorReader.java Sun Mar 2 18:05:49 2014
@@ -226,9 +226,10 @@ public class ClobLocatorReader extends j
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/branches/10.10/java/client/org/apache/derby/client/net/NetAgent.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/NetAgent.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/NetAgent.java (original)
+++ db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/NetAgent.java Sun Mar 2 18:05:49 2014
@@ -102,6 +102,13 @@ public class NetAgent extends Agent {
public SqlException exceptionOpeningSocket_ = null;
public 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---------------------------------
public NetAgent(NetConnection netConnection,
org.apache.derby.client.am.LogWriter logWriter) throws SqlException {
@@ -461,23 +468,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(org.apache.derby.client.am.Statement 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;
@@ -494,19 +519,19 @@ public class NetAgent extends Agent {
}
protected void beginReadChain(org.apache.derby.client.am.Statement 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/branches/10.10/java/client/org/apache/derby/client/net/Request.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/Request.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/Request.java (original)
+++ db/derby/code/branches/10.10/java/client/org/apache/derby/client/net/Request.java Sun Mar 2 18:05:49 2014
@@ -36,6 +36,7 @@ import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
+import org.apache.derby.shared.common.error.ExceptionUtil;
public class Request {
@@ -318,7 +319,27 @@ public 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);
@@ -327,7 +348,7 @@ public class Request {
new SqlException(
netAgent_.logWriter_,
new ClientMessageId(SQLState.NET_EXCEPTION_ON_READ),
- parameterIndex, e.getMessage(), e));
+ parameterIndex, ioe.getMessage(), ioe));
return;
}
@@ -1207,6 +1228,7 @@ public class Request {
protected void sendBytes(java.io.OutputStream socketOutputStream) throws java.io.IOException {
try {
+ netAgent_.markWriteChainAsDirty();
socketOutputStream.write(buffer.array(), 0, buffer.position());
socketOutputStream.flush();
} finally {
Modified: db/derby/code/branches/10.10/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/engine/org/apache/derby/loc/messages.xml?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/branches/10.10/java/engine/org/apache/derby/loc/messages.xml Sun Mar 2 18:05:49 2014
@@ -5216,6 +5216,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/branches/10.10/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/branches/10.10/java/shared/org/apache/derby/shared/common/reference/SQLState.java Sun Mar 2 18:05:49 2014
@@ -1620,6 +1620,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/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java (original)
+++ db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/lang/ErrorCodeTest.java Sun Mar 2 18:05:49 2014
@@ -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/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java?rev=1573334&r1=1573333&r2=1573334&view=diff
==============================================================================
--- db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java (original)
+++ db/derby/code/branches/10.10/java/testing/org/apache/derbyTesting/functionTests/tests/largedata/LobLimitsTest.java Sun Mar 2 18:05:49 2014
@@ -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();