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. */
