Return-Path: Delivered-To: apmail-db-derby-user-archive@www.apache.org Received: (qmail 16847 invoked from network); 4 Oct 2004 22:18:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 4 Oct 2004 22:18:55 -0000 Received: (qmail 79511 invoked by uid 500); 4 Oct 2004 22:18:50 -0000 Delivered-To: apmail-db-derby-user-archive@db.apache.org Received: (qmail 79398 invoked by uid 500); 4 Oct 2004 22:18:49 -0000 Mailing-List: contact derby-user-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: List-Id: Reply-To: "Derby Discussion" Delivered-To: mailing list derby-user@db.apache.org Delivered-To: moderator for derby-user@db.apache.org Received: (qmail 81146 invoked by uid 99); 4 Oct 2004 21:13:24 -0000 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests=RCVD_BY_IP,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (hermes.apache.org: domain of ralph.richard.cook@gmail.com designates 64.233.170.205 as permitted sender) Message-ID: <31fc914904100414135169ce6a@mail.gmail.com> Date: Mon, 4 Oct 2004 17:13:04 -0400 From: Ralph Richard Cook Reply-To: Ralph Richard Cook To: derby-user@db.apache.org Subject: Length of binary streams must match length parameter(?) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N I'm not sure if this is a bug or proper behavior, but here goes... For performance reasons, I'd like to reuse a byte array when inserting BLOBs into a derby database. I'm inserting with a PreparedStatement, making a new ByteArrayInputStream around a reused byte[] buffer, depending on the length parameter of the PreparedStatement.setBinaryStream method to say how many bytes to use out of the stream. However, if the length parameter doesn't match the actual length of the buffer used in the ByteArrayInputStream then derby complains, loudly. Here is a small sample program to show what I mean, followed by the Exception I get from it. Line 45 is the third call to PreparedStatement.execute. All that's needed to compile and run this in the classpath is derby.jar. Is this an actual bug, or are these two numbers supposed to match in all JDBC implementations? If they are supposed to match, why bother with the length parameter at all? Thanks for looking at this. import java.io.*; import java.sql.*; public class DerbyBlobTest { public static void main(String[] args) { try { byte[] buf = new byte[10]; Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); Connection connection = DriverManager.getConnection("jdbc:derby:blobtest;create=true"); Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE TABLE BLOBTEST ( ID VARCHAR(20) " + "NOT NULL PRIMARY KEY, DATA BLOB)"); stmt.close(); connection.setAutoCommit(false); PreparedStatement pstmt = connection.prepareStatement("INSERT INTO BLOBTEST " + "(ID, DATA) VALUES(?, ?)"); /* One to show it works... */ pstmt.setString(1, "BLOB1"); pstmt.setBinaryStream(2, new ByteArrayInputStream(buf), 10); pstmt.execute(); connection.commit(); /* * Another one to prove it wasn't a coincidence, we can * re-use the PreparedStatement, etc. */ pstmt.setString(1, "BLOB2"); pstmt.setBinaryStream(2, new ByteArrayInputStream(buf), 10); pstmt.execute(); connection.commit(); /* * This one fails because we want to use fewer bytes than * is in the buffer. The third call to execute is Line 45. */ pstmt.setString(1, "BLOB3"); pstmt.setBinaryStream(2, new ByteArrayInputStream(buf), 5); pstmt.execute(); connection.commit(); pstmt.close(); connection.close(); } catch (Exception ex) { ex.printStackTrace(); } } } ERROR XSDA4: An unexpected exception was thrown at org.apache.derby.iapi.error.StandardException.newException(StandardException.java) at org.apache.derby.impl.store.raw.data.InsertOperation.(InsertOperation.java) at org.apache.derby.impl.store.raw.data.LoggableActions.actionInsert(LoggableActions.java) at org.apache.derby.impl.store.raw.data.BasePage.insertNoOverflow(BasePage.java) at org.apache.derby.impl.store.raw.data.BasePage.insertAtSlot(BasePage.java) at org.apache.derby.impl.store.raw.data.StoredPage.insertAtSlot(StoredPage.java) at org.apache.derby.impl.store.raw.data.BasePage.insert(BasePage.java) at org.apache.derby.impl.store.access.heap.HeapController.doInsert(HeapController.java) at org.apache.derby.impl.store.access.heap.HeapController.insertAndFetchLocation(HeapController.java) at org.apache.derby.impl.sql.execute.RowChangerImpl.insertRow(RowChangerImpl.java) at org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(InsertResultSet.java) at org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java) at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java) at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java) at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java) at org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(EmbedPreparedStatement.java) at DerbyBlobTest.main(DerbyBlobTest.java:45)