[ 
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.

Reply via email to