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

Kathey Marsden commented on DERBY-3732:
---------------------------------------

Looking at a possible quick fix approach as opposed to reworking the type code.

If I insert the lob using length, I should have a streamValueLength available.  
When we call getLength() stream is set but streamValueLength is not.  Below is 
the trace when the stream is set.   It seems to me readRecordFromArray should 
be able to tell the length and pass that to setStream().  Does that sound 
reasonable?

        SQLBlob(SQLBinary).setStream(InputStream) line: 563     
        StoredPage.readRecordFromArray(Object[], int, int[], int[], 
ArrayInputStream, StoredRecordHeader, RecordHandle) line: 5592      
        StoredPage.restoreRecordFromSlot(int, Object[], FetchDescriptor, 
RecordHandle, StoredRecordHeader, boolean) line: 1497  
        StoredPage(BasePage).fetchFromSlot(RecordHandle, int, Object[], 
FetchDescriptor, boolean) line: 459     
        HeapScan(GenericScanController).fetchRows(DataValueDescriptor[][], 
RowLocation[], BackingStoreHashtable, long, int[]) line: 759 
        HeapScan.fetchNextGroup(DataValueDescriptor[][], RowLocation[]) line: 
324       
        BulkTableScanResultSet.reloadArray() line: 327  
        BulkTableScanResultSet.getNextRowCore() line: 282       
        ProjectRestrictResultSet.getNextRowCore() line: 255     
        ProjectRestrictResultSet(BasicNoPutResultSetImpl).getNextRow() line: 
460        
        EmbedResultSet40(EmbedResultSet).movePosition(int, int, String) line: 
423       
        EmbedResultSet40(EmbedResultSet).next() line: 367       
        LengthLargeLob.main(String[]) line: 21  


> SQL Length function materializes lob into memory
> ------------------------------------------------
>
>                 Key: DERBY-3732
>                 URL: https://issues.apache.org/jira/browse/DERBY-3732
>             Project: Derby
>          Issue Type: Improvement
>          Components: SQL
>    Affects Versions: 10.3.3.0, 10.4.1.3, 10.5.0.0
>            Reporter: Kathey Marsden
>            Priority: Minor
>         Attachments: LengthLargeLob.zip, LengthThruBlob.java
>
>
> Currently the SQL length function materializes the entire lob into memory. In 
> SQLBinary.getLength() we have 
> public final int      getLength() throws StandardException
>       {
>               if (stream != null) {
>                       if (streamValueLength != -1)
>                               return streamValueLength;
>               }
>               return (getBytes() == null) ? 0 : getBytes().length;
>       }
> Which actually is doubly bad because we call getBytes twice and materialize 
> it twice.
> It would be good to read the length from the stream if available and 
> otherwise stream the value to get the length, rather than materializing it 
> into memory.
> To reproduce, run the attached repro.
> java -Xmx16M  LengthLargeLob
> It gives an out of memory exception
> Caused by: java.lang.OutOfMemoryError: Java heap space
>         at 
> org.apache.derby.iapi.types.SQLBinary.readFromStream(SQLBinary.java:415)
>         at 
> org.apache.derby.iapi.types.SQLBinary.readExternal(SQLBinary.java:318)
>         at org.apache.derby.iapi.types.SQLBinary.getValue(SQLBinary.java:220)
>         at org.apache.derby.iapi.types.SQLBinary.getBytes(SQLBinary.java:210)
>         at org.apache.derby.iapi.types.SQLBinary.getLength(SQLBinary.java:250)
>         at 
> org.apache.derby.impl.sql.execute.BaseActivation.getDB2Length(BaseActivation.java:1684)
>         at 
> org.apache.derby.exe.acf81e0010x011axa317x5db8x0000003d9dc81.e1(Unknown 
> Source)
>         at 
> org.apache.derby.impl.services.reflect.DirectCall.invoke(ReflectGeneratedClass.java:141)
>         at 
> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.doProjection(ProjectRestrictResultSet.java:497)
>         at 
> org.apache.derby.impl.sql.execute.ProjectRestrictResultSet.getNextRowCore(ProjectRestrictResultSet.java:291)
>         at 
> org.apache.derby.impl.sql.execute.BasicNoPutResultSetImpl.getNextRow(BasicNoPutResultSetImpl.java:460)
>         at 
> org.apache.derby.impl.jdbc.EmbedResultSet.movePosition(EmbedResultSet.java:423)
>         ... 2 more
> [
>  

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