[ 
https://issues.apache.org/jira/browse/DERBY-2111?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12474369
 ] 

Øystein Grøvlen commented on DERBY-2111:
----------------------------------------

I am not quite sure how to fix this problem.  One way would be to make a copy 
of the stream when it is read the first time.  However, in most cases that 
would give an unecessary overhead since I would think most streams will only be 
used for a single row.  This could be improved a bit, if one only made a copy 
when the compiler cannot determine that only one row will be affected, but I 
suspect that this would not catch all cases, and that many existing 
applications would see reduced LOB performance. 

An alternative could be to not fix the problem, but to improve the error 
message to be more helpful to the users. 

> EOFException when using stream as parameter for multi-row update statement in 
> embedded driver
> ---------------------------------------------------------------------------------------------
>
>                 Key: DERBY-2111
>                 URL: https://issues.apache.org/jira/browse/DERBY-2111
>             Project: Derby
>          Issue Type: Bug
>    Affects Versions: 10.2.1.6, 10.3.0.0
>         Environment: Embedded JDBC driver
>            Reporter: Øystein Grøvlen
>            Priority: Minor
>         Attachments: streamtest.java
>
>
> If a stream is used as parameter to an update statement that will update 
> several rows, the update statement will fail.
> I will attach a JUNIT test that reproduces this error.  This only fails with 
> the embedded driver.  It works well with the client driver.  The exception I 
> get is:
> There was 1 error:
> 1) 
> testMultipleUpdates(org.apache.derbyTesting.functionTests.tests.jdbcapi.streamtest)ERROR
>  XSDA4: An unexpected exception was thrown
>        at 
> org.apache.derby.iapi.error.StandardException.newException(StandardException.java:298)
>        at 
> org.apache.derby.impl.store.raw.data.UpdateOperation.<init>(UpdateOperation.java:110)
>         at 
> org.apache.derby.impl.store.raw.data.LoggableActions.actionUpdate(LoggableActions.java:80)
>    at 
> org.apache.derby.impl.store.raw.data.StoredPage.doUpdateAtSlot(StoredPage.java:8537)
>  at 
> org.apache.derby.impl.store.raw.data.BasePage.updateAtSlot(BasePage.java:1111)
>        at 
> org.apache.derby.impl.store.access.conglomerate.GenericConglomerateController.replace(GenericConglomerateController.java:479)
>         at 
> org.apache.derby.impl.sql.execute.RowChangerImpl.updateRow(RowChangerImpl.java:523)
>   at 
> org.apache.derby.impl.sql.execute.UpdateResultSet.collectAffectedRows(UpdateResultSet.java:579)
>       at 
> org.apache.derby.impl.sql.execute.UpdateResultSet.open(UpdateResultSet.java:273)
>      at 
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:358)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1182)
>  at 
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java:1635)
>  at 
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(EmbedPreparedStatement.java:299)
>      at 
> org.apache.derbyTesting.functionTests.tests.jdbcapi.streamtest.testMultipleUpdates(streamtest.java:83)
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>   at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at 
> org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:76)
>      at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
>        at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
>       at junit.extensions.TestSetup.run(TestSetup.java:23)
> The underlying error is:
> .java.io.EOFException: Stream has already been read and end-of-file reached 
> and cannot be re-used.
>   at 
> org.apache.derby.iapi.types.ReaderToUTF8Stream.read(ReaderToUTF8Stream.java:185)
>      at 
> org.apache.derby.impl.store.raw.data.MemByteHolder.write(MemByteHolder.java:146)
>      at 
> org.apache.derby.impl.store.raw.data.RememberBytesInputStream.fillBuf(RememberBytesInputStream.java:135)
>      at 
> org.apache.derby.impl.store.raw.data.StoredPage.logColumn(StoredPage.java:6155)
>       at 
> org.apache.derby.impl.store.raw.data.StoredPage.logRow(StoredPage.java:3959)
>  at 
> org.apache.derby.impl.store.raw.data.UpdateOperation.writeOptionalDataToBuffer(UpdateOperation.java:255)
>      at 
> org.apache.derby.impl.store.raw.data.UpdateOperation.<init>(UpdateOperation.java:106)
>         at 
> org.apache.derby.impl.store.raw.data.LoggableActions.actionUpdate(LoggableActions.java:80)
>    at 
> org.apache.derby.impl.store.raw.data.StoredPage.doUpdateAtSlot(StoredPage.java:8537)
>  at 
> org.apache.derby.impl.store.raw.data.BasePage.updateAtSlot(BasePage.java:1111)
>        at 
> org.apache.derby.impl.store.access.conglomerate.GenericConglomerateController.replace(GenericConglomerateController.java:479)
>         at 
> org.apache.derby.impl.sql.execute.RowChangerImpl.updateRow(RowChangerImpl.java:523)
>   at 
> org.apache.derby.impl.sql.execute.UpdateResultSet.collectAffectedRows(UpdateResultSet.java:579)
>       at 
> org.apache.derby.impl.sql.execute.UpdateResultSet.open(UpdateResultSet.java:273)
>      at 
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:358)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1182)
>  at 
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java:1635)
>  at 
> org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeUpdate(EmbedPreparedStatement.java:299)
>      at 
> org.apache.derbyTesting.functionTests.tests.jdbcapi.streamtest.testMultipleUpdates(streamtest.java:83)
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>   at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:585)
>      at junit.framework.TestCase.runTest(TestCase.java:154)
>   at junit.framework.TestCase.runBare(TestCase.java:127)
>   at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:76)
>      at junit.framework.TestResult$1.protect(TestResult.java:106)
>     at junit.framework.TestResult.runProtected(TestResult.java:124)
>  at junit.framework.TestResult.run(TestResult.java:109)
>   at junit.framework.TestCase.run(TestCase.java:118)
>       at junit.framework.TestSuite.runTest(TestSuite.java:208)
>         at junit.framework.TestSuite.run(TestSuite.java:203)
>     at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
>        at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
>       at junit.framework.TestResult.runProtected(TestResult.java:124)
>  at junit.extensions.TestSetup.run(TestSetup.java:23)
>     at junit.framework.TestSuite.runTest(TestSuite.java:208)
>         at junit.framework.TestSuite.run(TestSuite.java:203)
>     at junit.textui.TestRunner.doRun(TestRunner.java:116)
>    at junit.textui.TestRunner.start(TestRunner.java:172)
>    at junit.textui.TestRunner.main(TestRunner.java:138)
> I assume this indicates that the stream is used directly to update a row, and 
> that it fails when trying to use the same stream for the second row. The 
> reason it does not fail in the client driver is that the stream is not passed 
> to the server, it  is just used to instantiate the LOB in memory.

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