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

Kristian Waagan commented on DERBY-3844:
----------------------------------------

Your understanding is correct, Bryan.

Something along the lines you describe will most probably work, but may require 
changes to the stream class down in store. You have one real source stream, but 
other streams may be "spliced off" from it. Add another couple of layers and 
you're up into the outer JDBC realm :)

Unfortunately, I think we have issues we cannot address at this level. I don't 
have a deep enough understanding of what's going on yet, but I hope to spend 
some more time investigating soon.
One thing we have to do, is to agree on what is going to be allowed. From the 
realm of Blobs, consider these pieces of pseudo-code:

1) select blob as b1, blob as b2 from blobtable

2) // Pattern where the Blob references aren't kept. GC has side-effects 
currently.
    stream = rs.getBlob(1).getBinaryStream()
    length = rs.getBlob(1).length()
    // Do something here, assume GC / finalization will take place.
    // Now read from the stream.
    stream.read(buf) // <-- fails

3) Blob b1 = rs.getBlob(1)
    // Process b1.
    // Note sure if b2 will be invalid if b1.free() is called here, or if 
obtaining b2 will latch/lock the resources again.
    // If you obtain b1 and b2 at the same time, and then call free on one of 
them, the other will be invalidated.
    Blob b2 = rs.getBlob(1)
    // Process b2.

4) Blob b1 = rs.getBlob(1)
    stream1 = b1.getBinaryStream(1024, 4096)
    stream2 = b1.getBinaryStream(10240, 2048)
    // Process both streams "concurrently"

- (1) is definitely allowed by SQL. This is the simple example, a cross join is 
more complex and may end up referencing the same Blob multiple times (in 
different rows of the result).
- In (2), should it be forbidden to call getBlob(1) multiple times, should we 
return the same Blob object, or should the two Blobs be independent on each 
other? This gets worse if updates come into play...
- Case (3) is much like (2), but the effects on the two Blob objects are caused 
by explicit method calls only.
- (4) adds yet another level, and here we support update-aware streams 
currently. In this case I believe we're talking about changes to this specific 
Blob-instance.

I think (1) and (4) may be the more natural use-cases, whereas (2) and (3) can 
be categorized as corner cases (?). All issues here are related to having 
several handles to the same source data.
With the exception of class (1), the user can work around these issues by 
changing the application code (unless a framework generates / uses code that 
trigger these issues). The whole thing would just be simpler to deal with if 
there were clear rules :)


Related Jiras: DERBY-3645, DERBY-3646 and DERBY-3650 (there are probably more)

> ASSERT failure in BasePage.unlatch() when running LobStreamsTest
> ----------------------------------------------------------------
>
>                 Key: DERBY-3844
>                 URL: https://issues.apache.org/jira/browse/DERBY-3844
>             Project: Derby
>          Issue Type: Bug
>          Components: Store
>    Affects Versions: 10.5.1.1
>         Environment: Solaris 10, AMD Opteron with 2 CPUs, Java(TM) SE Runtime 
> Environment (build 1.6.0_06-b02), Derby trunk revision 686755
>            Reporter: Knut Anders Hatlen
>         Attachments: derby-3844-1a-repro_test.diff
>
>
> I saw this failure when running suites.All to test the patch 
> nested_transaction_v2.diff which is posted on DERBY-3693. The failure did not 
> occur when I reran the test, and I don't believe the patch should have any 
> effect on the code that failed. The ASSERT that is triggered is this one 
> (which indicates that we're trying to unlatch a page that's not latched):
>               if (SanityManager.DEBUG) {
>                       SanityManager.ASSERT(isLatched());
>               }
> Here's the full stack trace and thread dump:
> 1) 
> testBlobWrite3Param(org.apache.derbyTesting.functionTests.tests.jdbcapi.LobStreamsTest)org.apache.derby.shared.common.sanity.AssertFailure:
>  ASSERT FAILED
>       at 
> org.apache.derby.shared.common.sanity.SanityManager.ASSERT(SanityManager.java:98)
>       at 
> org.apache.derby.impl.store.raw.data.BasePage.unlatch(BasePage.java:1319)
>       at 
> org.apache.derby.impl.store.raw.data.OverflowInputStream.fillByteHolder(OverflowInputStream.java:152)
>       at 
> org.apache.derby.impl.store.raw.data.BufferedByteHolderInputStream.read(BufferedByteHolderInputStream.java:44)
>       at java.io.DataInputStream.read(DataInputStream.java:132)
>       at 
> org.apache.derby.impl.jdbc.PositionedStoreStream.read(PositionedStoreStream.java:106)
>       at 
> org.apache.derby.impl.jdbc.AutoPositioningStream.read(AutoPositioningStream.java:113)
>       at 
> org.apache.derby.impl.jdbc.UpdatableBlobStream.read(UpdatableBlobStream.java:194)
>       at 
> org.apache.derbyTesting.functionTests.tests.jdbcapi.LobStreamsTest.readBytesFromStream(LobStreamsTest.java:463)
>       at 
> org.apache.derbyTesting.functionTests.tests.jdbcapi.LobStreamsTest.compareLob2File(LobStreamsTest.java:488)
>       at 
> org.apache.derbyTesting.functionTests.tests.jdbcapi.LobStreamsTest.testBlobWrite3Param(LobStreamsTest.java:130)
>       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:104)
>       at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
>       at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
>       at junit.extensions.TestSetup.run(TestSetup.java:25)
>       at 
> org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
> ---------------
> Stack traces for all live threads:
> Thread name=derby.antiGC id=280 priority=1 state=WAITING isdaemon=true
>       java.lang.Object.wait(Native Method)
>       java.lang.Object.wait(Object.java:485)
>       org.apache.derby.impl.services.monitor.AntiGC.run(BaseMonitor.java:2217)
>       java.lang.Thread.run(Thread.java:619)
> Thread name=Signal Dispatcher id=4 priority=9 state=RUNNABLE isdaemon=true
> Thread name=main id=1 priority=5 state=RUNNABLE isdaemon=false
>       java.lang.Thread.dumpThreads(Native Method)
>       java.lang.Thread.getAllStackTraces(Thread.java:1477)
>       
> org.apache.derby.shared.common.sanity.ThreadDump.getStackDumpString(ThreadDump.java:34)
>       sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>       
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>       
> org.apache.derby.shared.common.sanity.AssertFailure$1.run(AssertFailure.java:165)
>       java.security.AccessController.doPrivileged(Native Method)
>       
> org.apache.derby.shared.common.sanity.AssertFailure.dumpThreads(AssertFailure.java:159)
>       
> org.apache.derby.shared.common.sanity.AssertFailure.<init>(AssertFailure.java:82)
>       
> org.apache.derby.shared.common.sanity.SanityManager.ASSERT(SanityManager.java:98)
>       
> org.apache.derby.impl.store.raw.data.BasePage.unlatch(BasePage.java:1319)
>       
> org.apache.derby.impl.store.raw.data.OverflowInputStream.fillByteHolder(OverflowInputStream.java:152)
>       
> org.apache.derby.impl.store.raw.data.BufferedByteHolderInputStream.read(BufferedByteHolderInputStream.java:44)
>       java.io.DataInputStream.read(DataInputStream.java:132)
>       
> org.apache.derby.impl.jdbc.PositionedStoreStream.read(PositionedStoreStream.java:106)
>       
> org.apache.derby.impl.jdbc.AutoPositioningStream.read(AutoPositioningStream.java:113)
>       
> org.apache.derby.impl.jdbc.UpdatableBlobStream.read(UpdatableBlobStream.java:194)
>       
> org.apache.derbyTesting.functionTests.tests.jdbcapi.LobStreamsTest.readBytesFromStream(LobStreamsTest.java:463)
>       
> org.apache.derbyTesting.functionTests.tests.jdbcapi.LobStreamsTest.compareLob2File(LobStreamsTest.java:488)
>       
> org.apache.derbyTesting.functionTests.tests.jdbcapi.LobStreamsTest.testBlobWrite3Param(LobStreamsTest.java:130)
>       sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>       
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>       
> org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:104)
>       junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
>       junit.extensions.TestSetup$1.protect(TestSetup.java:21)
>       junit.extensions.TestSetup.run(TestSetup.java:25)
>       org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
> Thread name=derby.rawStoreDaemon id=941 priority=5 state=TIMED_WAITING 
> isdaemon=true
>       java.lang.Object.wait(Native Method)
>       
> org.apache.derby.impl.services.daemon.BasicDaemon.rest(BasicDaemon.java:571)
>       
> org.apache.derby.impl.services.daemon.BasicDaemon.run(BasicDaemon.java:388)
>       java.lang.Thread.run(Thread.java:619)
> Thread name=Timer-3 id=281 priority=5 state=WAITING isdaemon=true
>       java.lang.Object.wait(Native Method)
>       java.lang.Object.wait(Object.java:485)
>       java.util.TimerThread.mainLoop(Timer.java:483)
>       java.util.TimerThread.run(Timer.java:462)
> Thread name=Finalizer id=3 priority=8 state=WAITING isdaemon=true
>       java.lang.Object.wait(Native Method)
>       java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
>       java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
>       java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
> Thread name=Reference Handler id=2 priority=10 state=WAITING isdaemon=true
>       java.lang.Object.wait(Native Method)
>       java.lang.Object.wait(Object.java:485)
>       java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
> Thread name=derby.rawStoreDaemon id=933 priority=5 state=TIMED_WAITING 
> isdaemon=true
>       java.lang.Object.wait(Native Method)
>       
> org.apache.derby.impl.services.daemon.BasicDaemon.rest(BasicDaemon.java:571)
>       
> org.apache.derby.impl.services.daemon.BasicDaemon.run(BasicDaemon.java:388)
>       java.lang.Thread.run(Thread.java:619)
> ---------------

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