[CALCITE-3338] Error with executeBatch and preparedStatement when using RemoteMeta (Xzh & Jin Xing)
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
index 147602a..8cc030e 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteConnectionImpl.java
@@ -297,18 +297,23 @@
CalciteStatement statement = (CalciteStatement) createStatement();
CalcitePrepare.CalciteSignature<T> signature =
statement.prepare(queryable);
- return enumerable(statement.handle, signature).enumerator();
+ return enumerable(statement.handle, signature, null).enumerator();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public <T> Enumerable<T> enumerable(Meta.StatementHandle handle,
- CalcitePrepare.CalciteSignature<T> signature) throws SQLException {
+ CalcitePrepare.CalciteSignature<T> signature,
+ @Nullable List<TypedValue> parameterValues0) throws SQLException {
Map<String, Object> map = new LinkedHashMap<>();
AvaticaStatement statement = lookupStatement(handle);
- final List<TypedValue> parameterValues =
- TROJAN.getParameterValues(statement);
+ final List<TypedValue> parameterValues;
+ if (parameterValues0 == null || parameterValues0.isEmpty()) {
+ parameterValues = TROJAN.getParameterValues(statement);
+ } else {
+ parameterValues = parameterValues0;
+ }
if (MetaImpl.checkParameterValueHasNull(parameterValues)) {
throw new SQLException("exception while executing query: unbound parameter");
diff --git a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
index 212cfe7..32289b7 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/CalciteMetaImpl.java
@@ -575,7 +575,7 @@
//noinspection unchecked
final CalcitePrepare.CalciteSignature<Object> calciteSignature =
(CalcitePrepare.CalciteSignature<Object>) signature;
- return getConnection().enumerable(handle, calciteSignature);
+ return getConnection().enumerable(handle, calciteSignature, parameterValues);
} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}
diff --git a/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java b/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java
index 97a360b..7780809 100644
--- a/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java
+++ b/core/src/test/java/org/apache/calcite/jdbc/CalciteRemoteDriverTest.java
@@ -880,6 +880,34 @@
assertThat(updateCount, is(1));
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-3338">[CALCITE-3338]
+ * Error with executeBatch and preparedStatement when using RemoteMeta</a>. */
+ @Test public void testInsertBatchWithPreparedStatement() throws Exception {
+ final Connection connection = DriverManager.getConnection(
+ "jdbc:avatica:remote:factory="
+ + LocalServiceModifiableFactory.class.getName());
+
+ PreparedStatement pst = connection.prepareStatement(
+ "insert into \"foo\".\"bar\" values (?, ?, ?, ?, ?)");
+ pst.setInt(1, 1);
+ pst.setInt(2, 1);
+ pst.setString(3, "second");
+ pst.setInt(4, 1);
+ pst.setInt(5, 1);
+ pst.addBatch();
+ pst.addBatch();
+
+ int[] updateCounts = pst.executeBatch();
+ assertThat(updateCounts.length, is(2));
+ assertThat(updateCounts[0], is(1));
+ assertThat(updateCounts[1], is(1));
+ ResultSet resultSet = pst.getResultSet();
+ assertThat(resultSet, nullValue());
+
+ connection.close();
+ }
+
/**
* Remote PreparedStatement insert WITH bind variables.
*/