Repository: calcite
Updated Branches:
  refs/heads/master 37ed160f4 -> 889b9a88b


[CALCITE-1180] Implement Statement.clearBatch() in Avatica

A simple omission in the original batch support and a trivial
fix for the Avatica Statement and PreparedStatement impls.
Includes a test for both as well.


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/889b9a88
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/889b9a88
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/889b9a88

Branch: refs/heads/master
Commit: 889b9a88b2bff748c4d6a31d369fc03d56ef958d
Parents: 37ed160
Author: Josh Elser <[email protected]>
Authored: Mon Apr 4 13:39:53 2016 -0400
Committer: Josh Elser <[email protected]>
Committed: Mon Apr 4 14:01:36 2016 -0400

----------------------------------------------------------------------
 .../avatica/AvaticaPreparedStatement.java       |   4 +
 .../calcite/avatica/AvaticaStatement.java       |   2 +-
 .../calcite/avatica/RemoteDriverTest.java       | 107 +++++++++++++++++++
 3 files changed, 112 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/889b9a88/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
----------------------------------------------------------------------
diff --git 
a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
 
b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
index 9b8a292..e83a785 100644
--- 
a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
+++ 
b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaPreparedStatement.java
@@ -239,6 +239,10 @@ public abstract class AvaticaPreparedStatement
     this.parameterValueBatch.add(copyParameterValues());
   }
 
+  @Override public void clearBatch() {
+    this.parameterValueBatch.clear();
+  }
+
   @Override public int[] executeBatch() throws SQLException {
     // Overriding the implementation in AvaticaStatement.
     try {

http://git-wip-us.apache.org/repos/asf/calcite/blob/889b9a88/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
----------------------------------------------------------------------
diff --git 
a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java 
b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
index a58fc15..82e4443 100644
--- 
a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
+++ 
b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaStatement.java
@@ -386,7 +386,7 @@ public abstract class AvaticaStatement
   }
 
   public void clearBatch() throws SQLException {
-    throw connection.helper.unsupported();
+    this.batchedSql.clear();
   }
 
   public int[] executeBatch() throws SQLException {

http://git-wip-us.apache.org/repos/asf/calcite/blob/889b9a88/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
----------------------------------------------------------------------
diff --git 
a/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java 
b/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
index 193d098..c32a54c 100644
--- 
a/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
+++ 
b/avatica/server/src/test/java/org/apache/calcite/avatica/RemoteDriverTest.java
@@ -1501,6 +1501,113 @@ public class RemoteDriverTest {
     }
   }
 
+  @Test public void testPreparedClearBatches() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      eachConnection(
+          new ConnectionFunction() {
+            public void apply(Connection c1) throws Exception {
+              executePreparedBatchClears(c1);
+            }
+          }, getLocalConnection());
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void executePreparedBatchClears(Connection conn) throws Exception {
+    final int numRows = 10;
+    final String tableName = AvaticaUtils.unique("BATCH_CLEARS");
+    LOG.info("Creating table {}", tableName);
+    try (Statement stmt = conn.createStatement()) {
+      final String createCommand = String.format("create table if not exists 
%s ("
+          + "id int not null, "
+          + "msg varchar(10) not null)", tableName);
+      assertFalse("Failed to create table", stmt.execute(createCommand));
+    }
+
+    final String insertSql = String.format("INSERT INTO %s values(?, ?)", 
tableName);
+    try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
+      // Add batches with the prepared statement
+      for (int i = 0; i < numRows; i++) {
+        pstmt.setInt(1, i);
+        pstmt.setString(2, Integer.toString(i));
+        pstmt.addBatch();
+
+        if (numRows / 2 - 1 == i) {
+          // Clear the first 5 entries in the batch
+          pstmt.clearBatch();
+        }
+      }
+
+      int[] updateCounts = pstmt.executeBatch();
+      assertEquals("Unexpected number of update counts returned", numRows / 2, 
updateCounts.length);
+      for (int i = 0; i < updateCounts.length; i++) {
+        assertEquals("Unexpected update count at index " + i, 1, 
updateCounts[i]);
+      }
+    }
+
+    try (Statement stmt = conn.createStatement()) {
+      ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName + " ORDER 
BY id asc");
+      assertNotNull("ResultSet was null", rs);
+      for (int i = 0 + (numRows / 2); i < numRows; i++) {
+        assertTrue("ResultSet should have a result", rs.next());
+        assertEquals("Wrong integer value for row " + i, i, rs.getInt(1));
+        assertEquals("Wrong string value for row " + i, Integer.toString(i), 
rs.getString(2));
+      }
+      assertFalse("ResultSet should have no more records", rs.next());
+    }
+  }
+
+  @Test public void testBatchClear() throws Exception {
+    ConnectionSpec.getDatabaseLock().lock();
+    try {
+      eachConnection(
+          new ConnectionFunction() {
+            public void apply(Connection c1) throws Exception {
+              executeBatchClear(c1);
+            }
+          }, getLocalConnection());
+    } finally {
+      ConnectionSpec.getDatabaseLock().unlock();
+    }
+  }
+
+  private void executeBatchClear(Connection conn) throws Exception {
+    final int numRows = 10;
+    try (Statement stmt = conn.createStatement()) {
+      final String tableName = AvaticaUtils.unique("BATCH_EXECUTE");
+      LOG.info("Creating table {}", tableName);
+      final String createCommand = String.format("create table if not exists 
%s ("
+          + "id int not null, "
+          + "msg varchar(10) not null)", tableName);
+      assertFalse("Failed to create table", stmt.execute(createCommand));
+
+      final String updatePrefix = String.format("INSERT INTO %s values(", 
tableName);
+      for (int i = 0; i < numRows;  i++) {
+        stmt.addBatch(updatePrefix + i + ", '" + Integer.toString(i) + "')");
+        if (numRows / 2 - 1 == i) {
+          stmt.clearBatch();
+        }
+      }
+
+      int[] updateCounts = stmt.executeBatch();
+      assertEquals("Unexpected number of update counts returned", numRows / 2, 
updateCounts.length);
+      for (int i = 0; i < updateCounts.length; i++) {
+        assertEquals("Unexpected update count at index " + i, 1, 
updateCounts[i]);
+      }
+
+      ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName + " ORDER 
BY id asc");
+      assertNotNull("ResultSet was null", rs);
+      for (int i = 0 + (numRows / 2); i < numRows; i++) {
+        assertTrue("ResultSet should have a result", rs.next());
+        assertEquals("Wrong integer value for row " + i, i, rs.getInt(1));
+        assertEquals("Wrong string value for row " + i, Integer.toString(i), 
rs.getString(2));
+      }
+      assertFalse("ResultSet should have no more records", rs.next());
+    }
+  }
+
   /**
    * Factory that creates a service based on a local JDBC connection.
    */

Reply via email to