You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by "Kristian Waagan (JIRA)" <ji...@apache.org> on 2011/06/28 15:34:18 UTC

[jira] [Updated] (DERBY-5090) Retrieving BLOB fields sometimes fails

     [ https://issues.apache.org/jira/browse/DERBY-5090?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Kristian Waagan updated DERBY-5090:
-----------------------------------

    Attachment: derby-5090-2a-test.stat
                derby-5090-2a-test.diff
                derby-5090-1a-fix.stat
                derby-5090-1a-fix.diff

Attaching patches 1a and 2a.
Patch 1a is the fix, including some clean-up:

* java/engine/org/apache/derby/impl/jdbc/EmbedResultSet.java
Replace NewByteArrayInputStream with ByteArrayInputStream
Wrap the above stream in CloseFilterInputStream

* java/engine/org/apache/derby/iapi/services/io/CloseFilterInputStream.java
Added filter stream that will throw exception after being closed. Modeled after the equally named class in the client.

* java/engine/org/apache/derby/iapi/services/io/NewByteArrayInputStream.java
Deleted this class, use a standard API-class instead.

* java/engine/org/apache/derby/iapi/services/io/AccessibleByteArrayOutputStream.java
Replace NewByteArrayInputStream with ByteArrayInputStream

* java/client/org/apache/derby/client/am/ResultSet.java
Renamed is_ to currentStream.
Added instance variable currentReader
Renamed method closeCloseFilterInputStream to closeOpenStreams
Modified closeOpenStream to close both currentStream and currentReader (only one will be non-null at any time)
Assigned reader to currentReader in getCharacterStream

Patch 2b adds two tests, but I'm a bit unsure if I want to keep JDBCSetGet as a separate class. Will anyone else use it?
If not, it might be better to keep them as private classes in the test class.
If we want to add it as a JUnit utility class, should it be split in two, i.e. JDBCGet and JDBCSet? Also, if keeping I'd like to make it possible to obtain the name of the last called getter to improve the error reporting.

Patches ready for review.



> Retrieving BLOB fields sometimes fails
> --------------------------------------
>
>                 Key: DERBY-5090
>                 URL: https://issues.apache.org/jira/browse/DERBY-5090
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions: 10.7.1.1
>         Environment: JDBC derby embedded driver
>            Reporter: Unai Vivi
>            Assignee: Kristian Waagan
>              Labels: BLOB, exception, null, read
>         Attachments: Derby5090.java, Derby5090_2.java, Derby5090_3.java, derby-5090-1a-fix.diff, derby-5090-1a-fix.stat, derby-5090-2a-test.diff, derby-5090-2a-test.stat
>
>
> This is my first issue report, so please be understanding if I'm posting the wrong thing, in the wrong place or in the wrong way. I just want to help. :)
> While iterating through a ResultSet, when accessing a BLOB field to read its contents via an InputStream, I noticed that:
> - if the current ResultSet's has been "warmed up" by retrieving another column first, everything it's fine;
> - if, on the other hand, you first-thing access the BLOB (and read other columns later), then upon reading the first byte out the InputStream bound to the BLOB field (ResultSet.getBinaryStream("col_name")) an IOException is thrown (and IOException's getMessage() method returns null).
> Following is an example, taken from a real application. The two code segments only differ in the fact that a SMALLINT & VARCHAR read is done before/after the BLOB read.
> --Working snippet--
> [...]
>                     icRelPath[i] = "imm" + File.separator + "ic" + "_" + rs.getShort("setIcone") + "_" + i + "." + rs.getString("estensione");
>                     AutoCloseInputStream acis = new AutoCloseInputStream(rs.getBinaryStream("ic" + i));
>                     if (rs.wasNull())
>                         icRelPath[i] = null;
>                     else
>                     {
>                         //icRelPath[i] = "imm" + File.separator + "ic" + "_" + rs.getShort("setIcone") + "_" + i + "." + rs.getString("estensione");
>                         BufferedInputStream bis = new BufferedInputStream(acis);
>                         int b = bis.read();//READS FINE
> [...]
> --Broken snippet--
> [...]
>                     //icRelPath[i] = "imm" + File.separator + "ic" + "_" + rs.getShort("setIcone") + "_" + i + "." + rs.getString("estensione");
>                     AutoCloseInputStream acis = new AutoCloseInputStream(rs.getBinaryStream("ic" + i));
>                     if (rs.wasNull())
>                         icRelPath[i] = null;
>                     else
>                     {
>                         icRelPath[i] = "imm" + File.separator + "ic" + "_" + rs.getShort("setIcone") + "_" + i + "." + rs.getString("estensione");
>                         BufferedInputStream bis = new BufferedInputStream(acis);
>                         int b = bis.read();//THROWS IOException WITH A null ERROR MESSAGE STRING
> [...]

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira