db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Kristian Waagan (JIRA)" <j...@apache.org>
Subject [jira] Commented: (DERBY-2017) Client driver can insert and commit partial data when a LOB stream throws IOException or does not match the specified length
Date Wed, 17 Mar 2010 17:13:27 GMT

    [ https://issues.apache.org/jira/browse/DERBY-2017?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12846476#action_12846476
] 

Kristian Waagan commented on DERBY-2017:
----------------------------------------

Thanks for having a look, Knut Anders.

Knut Anders wrote:
-----
One question: If the user stream fails with an exception on the client side, will the original
exception be the one that's reported to the user, or will it be the synthetic exception produced
on the server? 
-----

With the current code (preview with some changes), where nothing has been done to the exception
handling, the following exceptions are produced for the embedded and the client driver:

---------> Client

----- SQLException -----
  SQLState:   XN015
  Error Code: 20000
  Message:    Network protocol error: the specified size of the InputStream, parameter #1,
is less than the actual InputStream length.
java.sql.SQLException: Network protocol error: the specified size of the InputStream, parameter
#1, is less than the actual InputStream length.
	at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:96)
	at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:358)
	at org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:399)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.test(StreamErrRepro.java:38)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.main(StreamErrRepro.java:21)
Caused by: org.apache.derby.client.am.SqlException: Network protocol error: the specified
size of the InputStream, parameter #1, is less than the actual InputStream length.
	at org.apache.derby.client.net.Request.writePlainScalarStream(Request.java:540)
	at org.apache.derby.client.net.Request.writeScalarStream(Request.java:264)
	at org.apache.derby.client.net.Request.writeScalarStream(Request.java:679)
	at org.apache.derby.client.net.NetStatementRequest.buildEXTDTA(NetStatementRequest.java:1011)
	at org.apache.derby.client.net.NetStatementRequest.writeExecute(NetStatementRequest.java:147)
	at org.apache.derby.client.net.NetPreparedStatement.writeExecute_(NetPreparedStatement.java:178)
	at org.apache.derby.client.am.PreparedStatement.writeExecute(PreparedStatement.java:1855)
	at org.apache.derby.client.am.PreparedStatement.flowExecute(PreparedStatement.java:2085)
	at org.apache.derby.client.am.PreparedStatement.executeUpdateX(PreparedStatement.java:404)
	at org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:390)
	... 2 more

----- SQLException -----
  SQLState:   XCL30
  Error Code: -1
  Message:    An IOException was thrown when reading a 'java.lang.String' from an InputStream.
java.sql.SQLException: An IOException was thrown when reading a 'java.lang.String' from an
InputStream.
	at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:96)
	at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:358)
	at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:367)
	at org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:399)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.test(StreamErrRepro.java:38)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.main(StreamErrRepro.java:21)
Caused by: org.apache.derby.client.am.SqlException: An IOException was thrown when reading
a 'java.lang.String' from an InputStream.
	at org.apache.derby.client.am.Statement.completeExecute(Statement.java:1601)
	at org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(NetStatementReply.java:322)
	at org.apache.derby.client.net.NetStatementReply.readExecute(NetStatementReply.java:71)
	at org.apache.derby.client.net.StatementReply.readExecute(StatementReply.java:55)
	at org.apache.derby.client.net.NetPreparedStatement.readExecute_(NetPreparedStatement.java:189)
	at org.apache.derby.client.am.PreparedStatement.readExecute(PreparedStatement.java:1865)
	at org.apache.derby.client.am.PreparedStatement.flowExecute(PreparedStatement.java:2162)
	at org.apache.derby.client.am.PreparedStatement.executeUpdateX(PreparedStatement.java:404)
	at org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:390)
	... 2 more
Caused by: org.apache.derby.client.am.SqlException: Java exception: 'Input stream did not
have exact amount of data as the requested length.: org.apache.derby.iapi.services.io.DerbyIOException'.
	... 11 more

----- SQLException -----
  SQLState:   XJ001
  Error Code: 99999
  Message:    Java exception: 'Input stream did not have exact amount of data as the requested
length.: org.apache.derby.iapi.services.io.DerbyIOException'.
java.sql.SQLNonTransientConnectionException: Java exception: 'Input stream did not have exact
amount of data as the requested length.: org.apache.derby.iapi.services.io.DerbyIOException'.
	at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:70)
	at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:358)
	at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:367)
	at org.apache.derby.client.am.SqlException.getSQLException(SqlException.java:367)
	at org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:399)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.test(StreamErrRepro.java:38)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.main(StreamErrRepro.java:21)
Caused by: org.apache.derby.client.am.SqlException: Java exception: 'Input stream did not
have exact amount of data as the requested length.: org.apache.derby.iapi.services.io.DerbyIOException'.
	at org.apache.derby.client.am.Statement.completeExecute(Statement.java:1601)
	at org.apache.derby.client.net.NetStatementReply.parseEXCSQLSTTreply(NetStatementReply.java:322)
	at org.apache.derby.client.net.NetStatementReply.readExecute(NetStatementReply.java:71)
	at org.apache.derby.client.net.StatementReply.readExecute(StatementReply.java:55)
	at org.apache.derby.client.net.NetPreparedStatement.readExecute_(NetPreparedStatement.java:189)
	at org.apache.derby.client.am.PreparedStatement.readExecute(PreparedStatement.java:1865)
	at org.apache.derby.client.am.PreparedStatement.flowExecute(PreparedStatement.java:2162)
	at org.apache.derby.client.am.PreparedStatement.executeUpdateX(PreparedStatement.java:404)
	at org.apache.derby.client.am.PreparedStatement.executeUpdate(PreparedStatement.java:390)
	... 2 more



---------> Embedded

java.sql.SQLException: An IOException was thrown when reading a 'java.lang.String' from an
InputStream.

----- SQLException -----
  SQLState:   XCL30
  Error Code: 20000
  Message:    An IOException was thrown when reading a 'java.lang.String' from an InputStream.
java.sql.SQLException: An IOException was thrown when reading a 'java.lang.String' from an
InputStream.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:95)
	at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:142)
	at org.apache.derby.impl.jdbc.Util.seeNextException(Util.java:278)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:398)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:346)
	at org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2269)
	at org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:81)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1321)
	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java:1673)
	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(EmbedPreparedStatement.java:303)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.test(StreamErrRepro.java:38)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.main(StreamErrRepro.java:22)
Caused by: java.sql.SQLException: An IOException was thrown when reading a 'java.lang.String'
from an InputStream.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:45)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory40.java:119)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:70)
	... 11 more
Caused by: java.sql.SQLException: Java exception: 'Input stream did not have exact amount
of data as the requested length.: org.apache.derby.iapi.services.io.DerbyIOException'.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:45)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory40.java:119)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:70)
	at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:142)
	at org.apache.derby.impl.jdbc.Util.javaException(Util.java:299)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:403)
	... 9 more
Caused by: org.apache.derby.iapi.services.io.DerbyIOException: Input stream did not have exact
amount of data as the requested length.
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.checkSufficientData(ReaderToUTF8Stream.java:420)
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.fillBuffer(ReaderToUTF8Stream.java:378)
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.read(ReaderToUTF8Stream.java:197)
	at java.io.DataInputStream.readUnsignedShort(Unknown Source)
	at org.apache.derby.iapi.types.SQLChar.readExternal(SQLChar.java:1050)
	at org.apache.derby.iapi.types.SQLChar.getString(SQLChar.java:695)
	at org.apache.derby.iapi.types.SQLVarchar.normalize(SQLVarchar.java:148)
	at org.apache.derby.iapi.types.DataTypeDescriptor.normalize(DataTypeDescriptor.java:648)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.normalizeColumn(NormalizeResultSet.java:329)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.normalizeRow(NormalizeResultSet.java:373)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.getNextRowCore(NormalizeResultSet.java:188)
	at org.apache.derby.impl.sql.execute.DMLWriteResultSet.getNextRowCore(DMLWriteResultSet.java:127)
	at org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:494)
	at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:436)
	at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:317)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1232)
	... 4 more

----- SQLException -----
  SQLState:   XJ001
  Error Code: 0
  Message:    Java exception: 'Input stream did not have exact amount of data as the requested
length.: org.apache.derby.iapi.services.io.DerbyIOException'.
java.sql.SQLException: Java exception: 'Input stream did not have exact amount of data as
the requested length.: org.apache.derby.iapi.services.io.DerbyIOException'.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:95)
	at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Util.java:142)
	at org.apache.derby.impl.jdbc.Util.javaException(Util.java:299)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:403)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(TransactionResourceImpl.java:398)
	at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(TransactionResourceImpl.java:346)
	at org.apache.derby.impl.jdbc.EmbedConnection.handleException(EmbedConnection.java:2269)
	at org.apache.derby.impl.jdbc.ConnectionChild.handleException(ConnectionChild.java:81)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1321)
	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java:1673)
	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(EmbedPreparedStatement.java:303)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.test(StreamErrRepro.java:38)
	at org.apache.derbyTesting.functionTests.tests.jdbcapi.StreamErrRepro.main(StreamErrRepro.java:22)
Caused by: java.sql.SQLException: Java exception: 'Input stream did not have exact amount
of data as the requested length.: org.apache.derby.iapi.services.io.DerbyIOException'.
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(SQLExceptionFactory.java:45)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(SQLExceptionFactory40.java:119)
	at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(SQLExceptionFactory40.java:70)
	... 12 more
Caused by: org.apache.derby.iapi.services.io.DerbyIOException: Input stream did not have exact
amount of data as the requested length.
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.checkSufficientData(ReaderToUTF8Stream.java:420)
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.fillBuffer(ReaderToUTF8Stream.java:378)
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.read(ReaderToUTF8Stream.java:197)
	at java.io.DataInputStream.readUnsignedShort(Unknown Source)
	at org.apache.derby.iapi.types.SQLChar.readExternal(SQLChar.java:1050)
	at org.apache.derby.iapi.types.SQLChar.getString(SQLChar.java:695)
	at org.apache.derby.iapi.types.SQLVarchar.normalize(SQLVarchar.java:148)
	at org.apache.derby.iapi.types.DataTypeDescriptor.normalize(DataTypeDescriptor.java:648)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.normalizeColumn(NormalizeResultSet.java:329)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.normalizeRow(NormalizeResultSet.java:373)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.getNextRowCore(NormalizeResultSet.java:188)
	at org.apache.derby.impl.sql.execute.DMLWriteResultSet.getNextRowCore(DMLWriteResultSet.java:127)
	at org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:494)
	at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:436)
	at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:317)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1232)
	... 4 more


When using the client driver, the following stack trace is written to derby.log:
============= begin nested exception, level (1) ===========
org.apache.derby.iapi.services.io.DerbyIOException: Input stream did not have exact amount
of data as the requested length.
	at org.apache.derby.impl.drda.EXTDTAReaderInputStream.checkStatus(EXTDTAReaderInputStream.java:173)
	at org.apache.derby.impl.drda.StandardEXTDTAReaderInputStream.read(StandardEXTDTAReaderInputStream.java:146)
	at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
	at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
	at sun.nio.cs.StreamDecoder.read(Unknown Source)
	at sun.nio.cs.StreamDecoder.read0(Unknown Source)
	at sun.nio.cs.StreamDecoder.read(Unknown Source)
	at java.io.InputStreamReader.read(Unknown Source)
	at org.apache.derby.iapi.services.io.LimitReader.read(LimitReader.java:57)
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.fillBuffer(ReaderToUTF8Stream.java:352)
	at org.apache.derby.iapi.types.ReaderToUTF8Stream.read(ReaderToUTF8Stream.java:197)
	at java.io.DataInputStream.readUnsignedShort(Unknown Source)
	at org.apache.derby.iapi.types.SQLChar.readExternal(SQLChar.java:1050)
	at org.apache.derby.iapi.types.SQLChar.getString(SQLChar.java:695)
	at org.apache.derby.iapi.types.SQLVarchar.normalize(SQLVarchar.java:148)
	at org.apache.derby.iapi.types.DataTypeDescriptor.normalize(DataTypeDescriptor.java:648)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.normalizeColumn(NormalizeResultSet.java:329)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.normalizeRow(NormalizeResultSet.java:373)
	at org.apache.derby.impl.sql.execute.NormalizeResultSet.getNextRowCore(NormalizeResultSet.java:188)
	at org.apache.derby.impl.sql.execute.DMLWriteResultSet.getNextRowCore(DMLWriteResultSet.java:127)
	at org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:494)
	at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:436)
	at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:317)
	at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1232)
	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java:1673)
	at org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(EmbedPreparedStatement.java:1328)
	at org.apache.derby.impl.drda.DRDAStatement.execute(DRDAStatement.java:672)
	at org.apache.derby.impl.drda.DRDAConnThread.parseEXCSQLSTTobjects(DRDAConnThread.java:4262)
	at org.apache.derby.impl.drda.DRDAConnThread.parseEXCSQLSTT(DRDAConnThread.java:4085)
	at org.apache.derby.impl.drda.DRDAConnThread.processCommands(DRDAConnThread.java:1004)
	at org.apache.derby.impl.drda.DRDAConnThread.run(DRDAConnThread.java:291)
============= end nested exception, level (1) ===========


If we disable the use of the accumulated exception mechanism on the client (when sending the
status byte, i.e. server and client at 10.6+), we get the same SQL states (XCL30 and XJ001)
in both drivers. Looking at the traces, I do see DerbyIOException. This was introduced to
make Derby able to rewrite IOException to SQLException with the correct state, but this is
obviously not done for this code path. For instance, we may want to differentiate between
a generic read error from a user stream and an error thrown by Derby due to a mismatch between
the specified and the actual stream length.

I would prefer to throw a different exception than the generic XJ001, but I think this can
be handled under a different Jira. For instance, XJ023 may be better suited.

> Client driver can insert and commit partial data when a LOB stream throws IOException
or does not match the specified length
> ----------------------------------------------------------------------------------------------------------------------------
>
>                 Key: DERBY-2017
>                 URL: https://issues.apache.org/jira/browse/DERBY-2017
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC, Network Client
>    Affects Versions: 10.2.1.6
>            Reporter: Knut Anders Hatlen
>            Assignee: Kristian Waagan
>         Attachments: derby-2017-2a-regression_test.diff, derby-2017-stream_status_preview.diff,
derby2017_try1.diff, Derby_2017_v1.diff, Derby_2017_v1.stat, StreamErrRepro.java
>
>
> When a LOB stream throws an exception or does not match the specified length, the client
driver does not raise an exception until it has finished executing the statement. Therefore,
the statement will be executed (and possibly committed) on the server even though the client
reports that the statement failed.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message