Uploaded image for project: 'Derby'
  1. Derby
  2. DERBY-3732

SQL Length function materializes BLOB into memory

Attach filesAttach ScreenshotVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 10.3.3.0, 10.4.1.3, 10.5.1.1
    • 10.3.3.1, 10.4.2.0, 10.5.1.1
    • SQL
    • None
    • High Value Fix

    Description

      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
      [

      Attachments

        1. LengthLargeLob.zip
          1 kB
          Katherine Marsden
        2. LengthThruBlob.java
          0.9 kB
          Katherine Marsden
        3. derby-3732_proto_diff.txt
          2 kB
          Katherine Marsden
        4. derby-3732_diff.txt
          17 kB
          Katherine Marsden
        5. derby-3732_skip_diff.txt
          17 kB
          Katherine Marsden
        6. derby-3732_skip2_diff.txt
          19 kB
          Katherine Marsden
        7. derby-3732_skip3_diff.txt
          14 kB
          Katherine Marsden

        Issue Links

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            kmarsden Katherine Marsden
            kmarsden Katherine Marsden
            Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment