I was looking at DERBY-2349, and am looking at the simpler case of just selecting the BLOB column twice and performing getBinaryStream() on both columns. The program below does just that and prints the first 10 bytes of the stream.

With embedded the output is:
4 5 6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23
I am done

Two things seem to be happening with embedded.
1) Both getBinaryStream() calls are returning the same stream.
2) The second getBinaryStream() call throws away 4 bytes.


With client the output is:
Exception in thread "main" java.io.IOException: The object is already closed. at org.apache.derby.client.am.CloseFilterInputStream.read(CloseFilterInputStream.java:50)
       at DoubleSelect.printNextTen(DoubleSelect.java:53)
       at DoubleSelect.main(DoubleSelect.java:43)
0 1 2 3 4 5 6 7 8 9
So with client it looks like the second getBinaryStream() call closes the first stream but then returns the right result for the second stream.

So my question is, is this a legal case to select the Blob column twice? Should the embedded driver behave similar to the client and close and reopen the stream on the second getBinaryStream()?

Thanks for any advice.

Kathey

import java.io.*;
import java.sql.*;


public class DoubleSelect {
   public static void main(String[] args) throws Exception {
   String url;

   if (args.length > 0 && args[0].equals("client"))
   {
       Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
       url = "jdbc:derby://localhost:1527/testdb;create=true";
   } else {
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
       url = "jdbc:derby:testdb;create=true";
   }
       Connection c = DriverManager.getConnection(url);
       Statement s = c.createStatement();
       try {
           s.executeUpdate("drop table t_main");
       } catch (SQLException e) {}
       s.executeUpdate("CREATE TABLE T_MAIN(" +
               "ID INT  GENERATED ALWAYS AS IDENTITY PRIMARY KEY, " +
               "V BLOB(590473235) )");

       String ins1 = "INSERT INTO T_MAIN(V) VALUES (?)";
PreparedStatement ps;
       ps = c.prepareStatement(ins1);
   byte[] bytes = new byte[35000];
   for (int i = 0; i < 35000; i++)
       bytes[i] = (byte) i ;
   ps.setBytes(1, bytes);
       ps.executeUpdate();
       ps.close();

   Statement stmt = c.createStatement();
   ResultSet rs = stmt.executeQuery("SELECT 'I', V, ID, V from T_MAIN");
   rs.next();
   InputStream v1 = rs.getBinaryStream(2);
   InputStream v2 = rs.getBinaryStream(4);
   printNextTen(v1);
   printNextTen(v2);
System.out.println("I am done");
   }

   private static void printNextTen(InputStream s1)
   {
   try {
   for  (int i = 0; i < 10; i++)
       {
       int val = s1.read();
       System.out.print(val + " ");
       }
   System.out.println("");
   } catch (IOException ioe)
       {
       ioe.printStackTrace();
       }
   }
}


Reply via email to