db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmars...@apache.org
Subject svn commit: r423910 - in /db/derby/code/branches/10.1/java: client/org/apache/derby/client/am/PreparedStatement.java drda/org/apache/derby/impl/drda/DDMWriter.java testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java
Date Thu, 20 Jul 2006 11:47:54 GMT
Author: kmarsden
Date: Thu Jul 20 04:47:54 2006
New Revision: 423910

URL: http://svn.apache.org/viewvc?rev=423910&view=rev
Log:
DERBY-428 NetworkClient PreparedStatement.executeBatch() hangs if batch is too large (ArrayIndexOutOfBoundsException
in Network Server)

merged svn 387895 389836 from trunk
Contributed by Bryan Pendleton


Modified:
    db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
    db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DDMWriter.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java

Modified: db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java?rev=423910&r1=423909&r2=423910&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
(original)
+++ db/derby/code/branches/10.1/java/client/org/apache/derby/client/am/PreparedStatement.java
Thu Jul 20 04:47:54 2006
@@ -1468,6 +1468,12 @@
         if (batchSize == 0) {
             return updateCounts;
         }
+		// The network client has a hard limit of 65,534 commands in a single
+		// DRDA request. This is because DRDA uses a 2-byte correlation ID,
+		// and the values 0 and 0xffff are reserved as special values. So
+		// that imposes an upper limit on the batch size we can support:
+		if (batchSize > 65534)
+            throw new BatchUpdateException(agent_.logWriter_, "No more than 65534 commands
may be added to a single batch", updateCounts);
 
         // Initialize all the updateCounts to indicate failure
         // This is done to account for "chain-breaking" errors where we cannot

Modified: db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DDMWriter.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DDMWriter.java?rev=423910&r1=423909&r2=423910&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DDMWriter.java (original)
+++ db/derby/code/branches/10.1/java/drda/org/apache/derby/impl/drda/DDMWriter.java Thu Jul
20 04:47:54 2006
@@ -330,6 +330,7 @@
 		// save the location of the beginning of the collection so
 		// that we can come back and fill in the length bytes
 		markStack[top++] = offset;
+		ensureLength (4); // verify space for length bytes and code point
 		offset += 2; // move past the length bytes before writing the code point
 		bytes[offset] = (byte) ((codePoint >>> 8) & 0xff);
 		bytes[offset + 1] = (byte) (codePoint & 0xff);

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java?rev=423910&r1=423909&r2=423910&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java
(original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java
Thu Jul 20 04:47:54 2006
@@ -30,6 +30,7 @@
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.sql.SQLException;
+import java.sql.BatchUpdateException;
 import java.io.ByteArrayInputStream; 
 import java.io.InputStreamReader;
 import org.apache.derbyTesting.functionTests.util.TestUtil;
@@ -44,7 +45,6 @@
 {
 	private static Connection conn = null;
 
-
 	public static void main (String args[])
 	{
 		try
@@ -306,6 +306,7 @@
 			jira170Test(conn);
 			jira125Test(conn);
 			jira1454Test(conn);
+			jira428Test(conn);
 			conn.close();
 			System.out.println("prepStmt Test Ends");
         }
@@ -989,5 +990,59 @@
         while (rs.next());
         System.out.println("Iteration 1 successful: " + (nCols + 1) +
 			" parameter markers successfully prepared and executed.");
+    }
+    // Jira 428 involves large batch sizes for Statement.addBatch and
+    // Statement.executeBatch. Currently, there is a hard DRDA limit of
+    // 65535 statements per batch (prior to DERBY-428, the server failed
+    // at around 9000 statements). The different JDBC clients support slightly
+    // lower limits: the Network Client supports 65534
+    // statements in a single batch, the DB2JCC driver v2.4 supports
+    // 65532 statements, the DB2JCC driver v2.6 supports 32765 statements. 
+    // This test just verifies that a batch of 32765 statements works, 
+    // and that a batch of 100000 statements
+    // gets a BatchUpdateException from the Network Client.
+    private static void jira428Test(Connection conn)
+        throws Exception
+    {
+        Statement stmt = conn.createStatement();
+        PreparedStatement ps ;
+        try { stmt.execute("drop table jira428"); } catch (Throwable t) { }
+        stmt.execute("create table jira428 (i integer)");
+        boolean savedAutoCommit = conn.getAutoCommit();
+        conn.setAutoCommit(false);
+        ps = conn.prepareStatement("insert into jira428 values (?)");
+        for (int i = 0; i < 32765; i++)
+        {
+            ps.setInt(1, i);
+            ps.addBatch();
+        }
+        ps.executeBatch();
+        conn.commit();
+        // We don't run this part of the test for the JCC client because
+        // the exception forces the connection closed. For DerbyNetClient, it's
+        // a clean exception that we can catch and recover from, so we test
+        // that code path:
+        if (TestUtil.isDerbyNetClientFramework())
+        {
+            ps = conn.prepareStatement("insert into jira428 values (?)");
+            for (int i = 0; i < 100000; i++)
+            {
+                ps.setInt(1, i);
+                ps.addBatch();
+            }
+            try {
+                ps.executeBatch();
+                System.out.println("JIRA428 FAILURE: expected an exception saying no more
than 65534 statements in a single batch");
+            }
+            catch (BatchUpdateException bue)
+            {
+                // We don't print anything here because we use the same
+                // master files for DerbyNet and DerbyNetClient, and we only
+                // run this portion of the test for DerbyNetClient.
+                // The exception that we get says "no more than 65534 stmts".
+            }
+            conn.commit();
+        }
+        conn.setAutoCommit(savedAutoCommit);
     }
 }



Mime
View raw message