Just from the point of view of a happy derby user with no affiliation to either Derby or Sun and who subscribes to this list because I use Derby and want to be aware of issues, good tricks, and other good tidbits, I suspect the author of the original report did not intend it to be a slam at Sun (and it certainly did not strike me as one at Derby).  Just sounded as if he had yanked some of his hair out with a frustrating problem and had a little tongue-in-cheek expression thereof.  So, while he can probably speak for himself, I doubt that he intended for anyone's kickers to get in a twist!  (Plus, he got a helpful answer immediately!)

Cheers (and thanks to all for a product I truly enjoy using!)
Richard

On Mon, Feb 16, 2009 at 2:10 PM, Lance Andersen <Lance.Andersen@sun.com> wrote:

On Feb 16, 2009, at 12:17 AM, Daniel Noll wrote:

Hi all.

I'm baffled.  I'm trying to use Blob.getBinaryStream(long, long) to read a slice of data out of a blob, and I'm sure this is just another of Sun's conspiracies to make our life harder than it needs to be.

Is it really necessary to say there is some conspiracy or intentional just to make your life harder?



The Javadoc is as follows:

http://java.sun.com/javase/6/docs/api/java/sql/Blob.html#getBinaryStream()

  InputStream getBinaryStream(long pos, long length)
      throws SQLException

  Returns an InputStream object that contains a partial Blob value,
  starting with the byte specified by pos, which is length bytes in
  length.

  Parameters:

      pos - the offset to the first byte of the partial value to be
            retrieved. The first byte in the Blob is at position 1

      length - the length in bytes of the partial value to be
               retrieved

  Returns:

      InputStream through which the partial Blob value can be read.

  Throws:

      SQLException - if pos is less than 1 or if pos is greater than
      the number of bytes in the Blob or if pos + length is greater
      than the number of bytes in the Blob

  (cutting the rest)


You have discovered a typo in the javadocs that was not caught by anyone.  I will address in the next update of the JDBC javadocs which will occur for Java SE 7


If everything in this Javadoc is true then it is in fact *impossible* to read the final byte of the blob.

Suppose you have a blob of length 20, and you want to read bytes 11 through 20.  You pass 11 as the starting position (indexed from 1, so it's actually byte 10 of the original byte array) and length 10.  This then throws an SQLException, because 11 + 10 = 21, which is greater than 20, so you can't do that.

And Derby is completely faithful to this seemingly ridiculous rule:

  java.sql.SQLException: Sum of position('11') and length('10') is
      greater than the size of the LOB.

So what are we supposed to do, use this method to read all chunks *except* the last one, and then use getBytes(long,long) to read the last chunk?

Daniel


P.S. you can pass length 9 here to make Derby happy.  Then you receive an InputStream where you can only read 9 bytes before the read loop goes into an infinite loop, due to Derby's read(byte[],int,int) returning 0 at EOS instead of -1.  I assume that this last bit is a bug -- everything above this paragraph appears to be an error in the JDBC API itself, which Derby has blindingly followed, leading to a nearly useless method.

Please just ask a question and not slam Derby or Sun as it really adds no value to the issue at hand and makes it less likely that people will want to try and assist.

Regards
Lance





--
Daniel Noll                            Forensic and eDiscovery Software
Senior Developer                              The world's most advanced
Nuix                                                email data analysis
http://nuix.com/                                and eDiscovery software