You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by el...@apache.org on 2016/05/31 23:24:11 UTC
[13/14] calcite git commit: [CALCITE-1254] Implement
Statement#executeLargeBatch()
[CALCITE-1254] Implement Statement#executeLargeBatch()
Further work on executeLargeBatch with the help of jhyde:
* Remove usage of deprecated prepareAndExecute
* saturated cast long to int
* do not call deprecated methods internally
* make DatabaseMetaData.supportsBatchUpdates return true
* JdbcMeta calls executeLargeBatch if underlying DB supports it
* clarify javadoc of Meta.closeStatement
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/08c966b9
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/08c966b9
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/08c966b9
Branch: refs/heads/branch-avatica-1.8
Commit: 08c966b9828f534ba3d8d2ccf052de7d887c70ef
Parents: 48e4342
Author: Josh Elser <el...@apache.org>
Authored: Sat May 28 10:26:10 2016 -0700
Committer: Josh Elser <el...@apache.org>
Committed: Tue May 31 18:44:41 2016 -0400
----------------------------------------------------------------------
.../calcite/avatica/AvaticaConnection.java | 13 ++--
.../avatica/AvaticaDatabaseMetaData.java | 2 +-
.../avatica/AvaticaPreparedStatement.java | 7 ++-
.../calcite/avatica/AvaticaStatement.java | 20 +++---
.../apache/calcite/avatica/AvaticaUtils.java | 61 +++++++++++++++++++
.../java/org/apache/calcite/avatica/Meta.java | 35 +++++++----
.../apache/calcite/avatica/proto/Responses.java | 64 ++++++++++----------
.../calcite/avatica/remote/LocalService.java | 6 +-
.../calcite/avatica/remote/RemoteMeta.java | 9 ++-
.../apache/calcite/avatica/remote/Service.java | 11 ++--
avatica/core/src/main/protobuf/responses.proto | 2 +-
.../calcite/avatica/AvaticaStatementTest.java | 51 ++++++++++++++++
.../remote/ProtobufSerializationTest.java | 10 ++-
.../remote/ProtobufTranslationImplTest.java | 2 +-
.../calcite/avatica/test/AvaticaUtilsTest.java | 10 +++
.../apache/calcite/avatica/jdbc/JdbcMeta.java | 11 ++--
16 files changed, 233 insertions(+), 81 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
index 69a60ec..f0524e7 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaConnection.java
@@ -523,15 +523,12 @@ public abstract class AvaticaConnection implements Connection {
* @param pstmt The prepared statement.
* @return An array of update counts containing one element for each command in the batch.
*/
- protected int[] executeBatchUpdateInternal(AvaticaPreparedStatement pstmt) throws SQLException {
+ protected long[] executeBatchUpdateInternal(AvaticaPreparedStatement pstmt) throws SQLException {
try {
// Get the handle from the statement
Meta.StatementHandle handle = pstmt.handle;
// Execute it against meta
- final Meta.ExecuteBatchResult executeBatchResult =
- meta.executeBatch(handle, pstmt.getParameterValueBatch());
- // Send back just the update counts
- return executeBatchResult.updateCounts;
+ return meta.executeBatch(handle, pstmt.getParameterValueBatch()).updateCounts;
} catch (Exception e) {
throw helper.createException(e.getMessage(), e);
}
@@ -610,7 +607,11 @@ public abstract class AvaticaConnection implements Connection {
}
}
};
- return meta.prepareAndExecute(statement.handle, sql, maxRowCount, callback);
+ // The old semantics were that maxRowCount was also treated as the maximum number of
+ // elements in the first Frame of results. A value of -1 would also preserve this, but an
+ // explicit (positive) number is easier to follow, IMO.
+ return meta.prepareAndExecute(statement.handle, sql, maxRowCount,
+ AvaticaUtils.toSaturatedInt(maxRowCount), callback);
}
protected ExecuteBatchResult prepareAndUpdateBatch(final AvaticaStatement statement,
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
index 0345150..7182968 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaDatabaseMetaData.java
@@ -1100,7 +1100,7 @@ public class AvaticaDatabaseMetaData implements AvaticaSpecificDatabaseMetaData
}
public boolean supportsBatchUpdates() throws SQLException {
- return false;
+ return true;
}
public ResultSet getUDTs(
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/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 e83a785..5e25a03 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
@@ -244,10 +244,13 @@ public abstract class AvaticaPreparedStatement
}
@Override public int[] executeBatch() throws SQLException {
+ return AvaticaUtils.toSaturatedInts(executeLargeBatch());
+ }
+
+ public long[] executeLargeBatch() throws SQLException {
// Overriding the implementation in AvaticaStatement.
try {
- final int[] updateCounts = getConnection().executeBatchUpdateInternal(this);
- return updateCounts;
+ return getConnection().executeBatchUpdateInternal(this);
} finally {
// If we failed to send this batch, that's a problem for the user to handle, not us.
// Make sure we always clear the statements we collected to submit in one RPC.
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/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 82e4443..73c16cd 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
@@ -155,13 +155,12 @@ public abstract class AvaticaStatement
/**
* Executes a collection of updates in a single batch RPC.
*
- * @return an array of integers mapping to the update count per SQL command.
+ * @return an array of long mapping to the update count per SQL command.
*/
- protected int[] executeBatchInternal() throws SQLException {
+ protected long[] executeBatchInternal() throws SQLException {
for (int i = 0; i < connection.maxRetriesPerExecute; i++) {
try {
- Meta.ExecuteBatchResult result = connection.prepareAndUpdateBatch(this, batchedSql);
- return result.updateCounts;
+ return connection.prepareAndUpdateBatch(this, batchedSql).updateCounts;
} catch (NoSuchStatementException e) {
resetStatement();
}
@@ -219,7 +218,7 @@ public abstract class AvaticaStatement
}
public final int executeUpdate(String sql) throws SQLException {
- return (int) executeLargeUpdate(sql);
+ return AvaticaUtils.toSaturatedInt(executeLargeUpdate(sql));
}
public long executeLargeUpdate(String sql) throws SQLException {
@@ -266,7 +265,7 @@ public abstract class AvaticaStatement
}
public final int getMaxRows() {
- return (int) getLargeMaxRows();
+ return AvaticaUtils.toSaturatedInt(getLargeMaxRows());
}
public long getLargeMaxRows() {
@@ -346,7 +345,7 @@ public abstract class AvaticaStatement
}
public int getUpdateCount() throws SQLException {
- return (int) updateCount;
+ return AvaticaUtils.toSaturatedInt(updateCount);
}
public long getLargeUpdateCount() throws SQLException {
@@ -390,12 +389,16 @@ public abstract class AvaticaStatement
}
public int[] executeBatch() throws SQLException {
+ return AvaticaUtils.toSaturatedInts(executeLargeBatch());
+ }
+
+ public long[] executeLargeBatch() throws SQLException {
try {
return executeBatchInternal();
} finally {
// If we failed to send this batch, that's a problem for the user to handle, not us.
// Make sure we always clear the statements we collected to submit in one RPC.
- this.batchedSql.clear();
+ clearBatch();
}
}
@@ -551,6 +554,7 @@ public abstract class AvaticaStatement
}
return parameterValues;
}
+
}
// End AvaticaStatement.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
index a999f19..845dde5 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/AvaticaUtils.java
@@ -25,6 +25,7 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
+import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.AbstractList;
@@ -44,6 +45,8 @@ public class AvaticaUtils {
method(long.class, Statement.class, "getLargeMaxRows");
private static final MethodHandle GET_LARGE_UPDATE_COUNT =
method(void.class, Statement.class, "getLargeUpdateCount");
+ private static final MethodHandle EXECUTE_LARGE_BATCH =
+ method(long[].class, Statement.class, "executeLargeBatch");
private static final Set<String> UNIQUE_STRINGS = new HashSet<>();
@@ -311,6 +314,26 @@ public class AvaticaUtils {
return statement.getUpdateCount();
}
+ /** Invokes {@code Statement#executeLargeBatch}, falling back on
+ * {@link PreparedStatement#executeBatch} if the method does not exist
+ * (before JDK 1.8) or throws {@link UnsupportedOperationException}. */
+ public static long[] executeLargeBatch(Statement statement)
+ throws SQLException {
+ if (EXECUTE_LARGE_BATCH != null) {
+ try {
+ // Call Statement.executeLargeBatch
+ return (long[]) EXECUTE_LARGE_BATCH.invokeExact();
+ } catch (UnsupportedOperationException e) {
+ // ignore, and fall through to call Statement.executeBatch
+ } catch (Error | RuntimeException | SQLException e) {
+ throw e;
+ } catch (Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return toLongs(statement.executeBatch());
+ }
+
/** Generates a string that is unique in the execution of the JVM.
* It is used by tests to ensure that they create distinct temporary tables.
* The strings are never thrown away, so don't put too much in there!
@@ -324,6 +347,44 @@ public class AvaticaUtils {
return s;
}
}
+
+ /** Converts a {@code long} to {@code int}, rounding as little as possible
+ * if the value is outside the legal range for an {@code int}. */
+ public static int toSaturatedInt(long value) {
+ if (value > Integer.MAX_VALUE) {
+ return Integer.MAX_VALUE;
+ }
+ if (value < Integer.MIN_VALUE) {
+ return Integer.MIN_VALUE;
+ }
+ return (int) value;
+ }
+
+ /**
+ * Converts an array of {@code long} values to an array of {@code int}
+ * values, truncating values outside the legal range for an {@code int}
+ * to {@link Integer#MIN_VALUE} or {@link Integer#MAX_VALUE}.
+ *
+ * @param longs An array of {@code long}s
+ * @return An array of {@code int}s
+ */
+ public static int[] toSaturatedInts(long[] longs) {
+ final int[] ints = new int[longs.length];
+ for (int i = 0; i < longs.length; i++) {
+ ints[i] = toSaturatedInt(longs[i]);
+ }
+ return ints;
+ }
+
+ /** Converts an array of {@code int} values to an array of {@code long}
+ * values. */
+ public static long[] toLongs(int[] ints) {
+ final long[] longs = new long[ints.length];
+ for (int i = 0; i < ints.length; i++) {
+ longs[i] = ints[i];
+ }
+ return longs;
+ }
}
// End AvaticaUtils.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java b/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
index 829ab5a..c7df281 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/Meta.java
@@ -225,7 +225,8 @@ public interface Meta {
* first frame of data
* @deprecated See {@link #prepareAndExecute(StatementHandle, String, long, int, PrepareCallback)}
*/
- @Deprecated ExecuteResult prepareAndExecute(StatementHandle h, String sql,
+ @Deprecated // to be removed before 2.0
+ ExecuteResult prepareAndExecute(StatementHandle h, String sql,
long maxRowCount, PrepareCallback callback) throws NoSuchStatementException;
/** Prepares and executes a statement.
@@ -234,7 +235,9 @@ public interface Meta {
* @param sql SQL query
* @param maxRowCount Maximum number of rows for the entire query. Negative for no limit
* (different meaning than JDBC).
- * @param maxRowsInFirstFrame Maximum number of rows for the first frame.
+ * @param maxRowsInFirstFrame Maximum number of rows for the first frame. This value should
+ * always be less than or equal to {@code maxRowCount} as the number of results are guaranteed
+ * to be restricted by {@code maxRowCount} and the underlying database.
* @param callback Callback to lock, clear and assign cursor
*
* @return Result containing statement ID, and if a query, a result set and
@@ -288,7 +291,8 @@ public interface Meta {
* @return Execute result
* @deprecated See {@link #execute(StatementHandle, List, int)}
*/
- @Deprecated ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
+ @Deprecated // to be removed before 2.0
+ ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
long maxRowCount) throws NoSuchStatementException;
/** Executes a prepared statement.
@@ -307,7 +311,13 @@ public interface Meta {
*/
StatementHandle createStatement(ConnectionHandle ch);
- /** Closes a statement. */
+ /** Closes a statement.
+ *
+ * <p>If the statement handle is not known, or is already closed, does
+ * nothing.
+ *
+ * @param h Statement handle
+ */
void closeStatement(StatementHandle h);
/**
@@ -326,29 +336,30 @@ public interface Meta {
void closeConnection(ConnectionHandle ch);
/**
- * Re-set the {@link ResultSet} on a Statement. Not a JDBC method.
+ * Re-sets the {@link ResultSet} on a Statement. Not a JDBC method.
+ *
* @return True if there are results to fetch after resetting to the given offset. False otherwise
*/
boolean syncResults(StatementHandle sh, QueryState state, long offset)
throws NoSuchStatementException;
/**
- * Makes all changes since the last commit/rollback permanent. Analogy to
+ * Makes all changes since the last commit/rollback permanent. Analogous to
* {@link Connection#commit()}.
*
- * @param ch A reference to the real JDBC Connection.
+ * @param ch A reference to the real JDBC Connection
*/
void commit(ConnectionHandle ch);
/**
- * Undoes all changes since the last commit/rollback. Analogy to
+ * Undoes all changes since the last commit/rollback. Analogous to
* {@link Connection#rollback()};
*
- * @param ch A reference to the real JDBC Connection.
+ * @param ch A reference to the real JDBC Connection
*/
void rollback(ConnectionHandle ch);
- /** Sync client and server view of connection properties.
+ /** Synchronizes client and server view of connection properties.
*
* <p>Note: this interface is considered "experimental" and may undergo further changes as this
* functionality is extended to other aspects of state management for
@@ -522,9 +533,9 @@ public interface Meta {
* Response from a collection of SQL commands or parameter values in a single batch.
*/
class ExecuteBatchResult {
- public final int[] updateCounts;
+ public final long[] updateCounts;
- public ExecuteBatchResult(int[] updateCounts) {
+ public ExecuteBatchResult(long[] updateCounts) {
this.updateCounts = Objects.requireNonNull(updateCounts);
}
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java
index ca24f86..9070675 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/proto/Responses.java
@@ -11627,17 +11627,17 @@ package org.apache.calcite.avatica.proto;
int getStatementId();
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
- java.util.List<java.lang.Integer> getUpdateCountsList();
+ java.util.List<java.lang.Long> getUpdateCountsList();
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
int getUpdateCountsCount();
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
- int getUpdateCounts(int index);
+ long getUpdateCounts(int index);
/**
* <code>optional bool missing_statement = 4;</code>
@@ -11720,21 +11720,21 @@ package org.apache.calcite.avatica.proto;
}
case 24: {
if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
- updateCounts_ = new java.util.ArrayList<java.lang.Integer>();
+ updateCounts_ = new java.util.ArrayList<java.lang.Long>();
mutable_bitField0_ |= 0x00000004;
}
- updateCounts_.add(input.readUInt32());
+ updateCounts_.add(input.readUInt64());
break;
}
case 26: {
int length = input.readRawVarint32();
int limit = input.pushLimit(length);
if (!((mutable_bitField0_ & 0x00000004) == 0x00000004) && input.getBytesUntilLimit() > 0) {
- updateCounts_ = new java.util.ArrayList<java.lang.Integer>();
+ updateCounts_ = new java.util.ArrayList<java.lang.Long>();
mutable_bitField0_ |= 0x00000004;
}
while (input.getBytesUntilLimit() > 0) {
- updateCounts_.add(input.readUInt32());
+ updateCounts_.add(input.readUInt64());
}
input.popLimit(limit);
break;
@@ -11829,24 +11829,24 @@ package org.apache.calcite.avatica.proto;
}
public static final int UPDATE_COUNTS_FIELD_NUMBER = 3;
- private java.util.List<java.lang.Integer> updateCounts_;
+ private java.util.List<java.lang.Long> updateCounts_;
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
- public java.util.List<java.lang.Integer>
+ public java.util.List<java.lang.Long>
getUpdateCountsList() {
return updateCounts_;
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
public int getUpdateCountsCount() {
return updateCounts_.size();
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
- public int getUpdateCounts(int index) {
+ public long getUpdateCounts(int index) {
return updateCounts_.get(index);
}
private int updateCountsMemoizedSerializedSize = -1;
@@ -11909,7 +11909,7 @@ package org.apache.calcite.avatica.proto;
output.writeRawVarint32(updateCountsMemoizedSerializedSize);
}
for (int i = 0; i < updateCounts_.size(); i++) {
- output.writeUInt32NoTag(updateCounts_.get(i));
+ output.writeUInt64NoTag(updateCounts_.get(i));
}
if (missingStatement_ != false) {
output.writeBool(4, missingStatement_);
@@ -11935,7 +11935,7 @@ package org.apache.calcite.avatica.proto;
int dataSize = 0;
for (int i = 0; i < updateCounts_.size(); i++) {
dataSize += com.google.protobuf.CodedOutputStream
- .computeUInt32SizeNoTag(updateCounts_.get(i));
+ .computeUInt64SizeNoTag(updateCounts_.get(i));
}
size += dataSize;
if (!getUpdateCountsList().isEmpty()) {
@@ -12280,56 +12280,56 @@ package org.apache.calcite.avatica.proto;
return this;
}
- private java.util.List<java.lang.Integer> updateCounts_ = java.util.Collections.emptyList();
+ private java.util.List<java.lang.Long> updateCounts_ = java.util.Collections.emptyList();
private void ensureUpdateCountsIsMutable() {
if (!((bitField0_ & 0x00000004) == 0x00000004)) {
- updateCounts_ = new java.util.ArrayList<java.lang.Integer>(updateCounts_);
+ updateCounts_ = new java.util.ArrayList<java.lang.Long>(updateCounts_);
bitField0_ |= 0x00000004;
}
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
- public java.util.List<java.lang.Integer>
+ public java.util.List<java.lang.Long>
getUpdateCountsList() {
return java.util.Collections.unmodifiableList(updateCounts_);
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
public int getUpdateCountsCount() {
return updateCounts_.size();
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
- public int getUpdateCounts(int index) {
+ public long getUpdateCounts(int index) {
return updateCounts_.get(index);
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
public Builder setUpdateCounts(
- int index, int value) {
+ int index, long value) {
ensureUpdateCountsIsMutable();
updateCounts_.set(index, value);
onChanged();
return this;
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
- public Builder addUpdateCounts(int value) {
+ public Builder addUpdateCounts(long value) {
ensureUpdateCountsIsMutable();
updateCounts_.add(value);
onChanged();
return this;
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
public Builder addAllUpdateCounts(
- java.lang.Iterable<? extends java.lang.Integer> values) {
+ java.lang.Iterable<? extends java.lang.Long> values) {
ensureUpdateCountsIsMutable();
com.google.protobuf.AbstractMessageLite.Builder.addAll(
values, updateCounts_);
@@ -12337,7 +12337,7 @@ package org.apache.calcite.avatica.proto;
return this;
}
/**
- * <code>repeated uint32 update_counts = 3;</code>
+ * <code>repeated uint64 update_counts = 3;</code>
*/
public Builder clearUpdateCounts() {
updateCounts_ = java.util.Collections.emptyList();
@@ -12692,7 +12692,7 @@ package org.apache.calcite.avatica.proto;
"ress\030\001 \001(\t\"\020\n\016CommitResponse\"\022\n\020Rollback" +
"Response\"\225\001\n\024ExecuteBatchResponse\022\025\n\rcon" +
"nection_id\030\001 \001(\t\022\024\n\014statement_id\030\002 \001(\r\022\025",
- "\n\rupdate_counts\030\003 \003(\r\022\031\n\021missing_stateme" +
+ "\n\rupdate_counts\030\003 \003(\004\022\031\n\021missing_stateme" +
"nt\030\004 \001(\010\022\036\n\010metadata\030\005 \001(\0132\014.RpcMetadata" +
"B\"\n org.apache.calcite.avatica.protob\006pr" +
"oto3"
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
index a15d55f..1562446 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
@@ -16,8 +16,8 @@
*/
package org.apache.calcite.avatica.remote;
+import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.Meta;
-
import org.apache.calcite.avatica.Meta.ExecuteBatchResult;
import org.apache.calcite.avatica.MetaImpl;
import org.apache.calcite.avatica.MissingResultsException;
@@ -218,7 +218,7 @@ public class LocalService implements Service {
try {
final Meta.ExecuteResult executeResult =
meta.prepareAndExecute(sh, request.sql, request.maxRowCount,
- new Meta.PrepareCallback() {
+ request.maxRowsInFirstFrame, new Meta.PrepareCallback() {
@Override public Object getMonitor() {
return LocalService.class;
}
@@ -266,7 +266,7 @@ public class LocalService implements Service {
try (final Context ctx = executeTimer.start()) {
try {
final Meta.ExecuteResult executeResult = meta.execute(request.statementHandle,
- request.parameterValues, request.maxRowCount);
+ request.parameterValues, AvaticaUtils.toSaturatedInt(request.maxRowCount));
final List<ResultSetResponse> results = new ArrayList<>(executeResult.resultSets.size());
for (Meta.MetaResultSet metaResultSet : executeResult.resultSets) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
index de6419a..7ee2226 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
@@ -19,6 +19,7 @@ package org.apache.calcite.avatica.remote;
import org.apache.calcite.avatica.AvaticaConnection;
import org.apache.calcite.avatica.AvaticaConnection.CallableWithoutException;
import org.apache.calcite.avatica.AvaticaParameter;
+import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.ColumnMetaData;
import org.apache.calcite.avatica.ConnectionPropertiesImpl;
import org.apache.calcite.avatica.Meta;
@@ -245,7 +246,11 @@ class RemoteMeta extends MetaImpl {
@Override public ExecuteResult prepareAndExecute(StatementHandle h, String sql, long maxRowCount,
PrepareCallback callback) throws NoSuchStatementException {
- return prepareAndExecute(h, sql, maxRowCount, (int) maxRowCount, callback);
+ // The old semantics were that maxRowCount was also treated as the maximum number of
+ // elements in the first Frame of results. A value of -1 would also preserve this, but an
+ // explicit (positive) number is easier to follow, IMO.
+ return prepareAndExecute(h, sql, maxRowCount, AvaticaUtils.toSaturatedInt(maxRowCount),
+ callback);
}
@Override public ExecuteResult prepareAndExecute(final StatementHandle h, final String sql,
@@ -324,7 +329,7 @@ class RemoteMeta extends MetaImpl {
@Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
long maxRowCount) throws NoSuchStatementException {
- return execute(h, parameterValues, (int) maxRowCount);
+ return execute(h, parameterValues, AvaticaUtils.toSaturatedInt(maxRowCount));
}
@Override public ExecuteResult execute(final StatementHandle h,
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
index b3accd9..affed00 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/Service.java
@@ -19,6 +19,7 @@ package org.apache.calcite.avatica.remote;
import org.apache.calcite.avatica.AvaticaClientRuntimeException;
import org.apache.calcite.avatica.AvaticaConnection;
import org.apache.calcite.avatica.AvaticaSeverity;
+import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.BuiltInConnectionProperty;
import org.apache.calcite.avatica.ConnectionPropertiesImpl;
import org.apache.calcite.avatica.Meta;
@@ -904,7 +905,7 @@ public interface Service {
public PrepareAndExecuteRequest(String connectionId, int statementId, String sql,
long maxRowCount) {
- this(connectionId, statementId, sql, maxRowCount, (int) maxRowCount);
+ this(connectionId, statementId, sql, maxRowCount, AvaticaUtils.toSaturatedInt(maxRowCount));
}
@JsonCreator
@@ -3028,7 +3029,7 @@ public interface Service {
public final String connectionId;
public final int statementId;
- public final int[] updateCounts;
+ public final long[] updateCounts;
public final boolean missingStatement;
public final RpcMetadataResponse rpcMetadata;
@@ -3043,7 +3044,7 @@ public interface Service {
@JsonCreator
public ExecuteBatchResponse(@JsonProperty("connectionId") String connectionId,
@JsonProperty("statementId") int statementId,
- @JsonProperty("updateCounts") int[] updateCounts,
+ @JsonProperty("updateCounts") long[] updateCounts,
@JsonProperty("missingStatement") boolean missingStatement,
@JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
this.connectionId = connectionId;
@@ -3075,9 +3076,9 @@ public interface Service {
Responses.ExecuteBatchResponse msg = ProtobufService.castProtobufMessage(genericMsg,
Responses.ExecuteBatchResponse.class);
- int[] updateCounts = new int[msg.getUpdateCountsCount()];
+ long[] updateCounts = new long[msg.getUpdateCountsCount()];
int i = 0;
- for (Integer updateCount : msg.getUpdateCountsList()) {
+ for (Long updateCount : msg.getUpdateCountsList()) {
updateCounts[i++] = updateCount;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/main/protobuf/responses.proto
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/protobuf/responses.proto b/avatica/core/src/main/protobuf/responses.proto
index 47d73ab..a3cd3d2 100644
--- a/avatica/core/src/main/protobuf/responses.proto
+++ b/avatica/core/src/main/protobuf/responses.proto
@@ -129,7 +129,7 @@ message RollbackResponse {
message ExecuteBatchResponse {
string connection_id = 1;
uint32 statement_id = 2;
- repeated uint32 update_counts = 3;
+ repeated uint64 update_counts = 3;
bool missing_statement = 4; // Did the request fail because of no-cached statement
RpcMetadata metadata = 5;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaStatementTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaStatementTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaStatementTest.java
new file mode 100644
index 0000000..5f6b56a
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/AvaticaStatementTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.avatica;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.sql.SQLException;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Test class for AvaticaStatement
+ */
+public class AvaticaStatementTest {
+
+ private AvaticaStatement statement;
+
+ @Before public void setup() {
+ statement = mock(AvaticaStatement.class);
+ }
+
+ @Test public void testUpdateCounts() throws SQLException {
+ long[] longValues = new long[] {-1, -3, 1, 5, ((long) Integer.MAX_VALUE) + 1};
+ int[] intValues = new int[] {-1, -3, 1, 5, Integer.MAX_VALUE};
+ when(statement.executeBatch()).thenCallRealMethod();
+ when(statement.executeLargeBatch()).thenCallRealMethod();
+ when(statement.executeBatchInternal()).thenReturn(longValues);
+
+ assertArrayEquals(intValues, statement.executeBatch());
+ assertArrayEquals(longValues, statement.executeLargeBatch());
+ }
+}
+
+// End AvaticaStatementTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
index d439c83..b3a08c0 100644
--- a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufSerializationTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.calcite.avatica.remote;
+import org.apache.calcite.avatica.AvaticaUtils;
import org.apache.calcite.avatica.ColumnMetaData.Rep;
import org.apache.calcite.avatica.Meta.Signature;
import org.apache.calcite.avatica.Meta.StatementHandle;
@@ -130,7 +131,8 @@ public class ProtobufSerializationTest {
prepareAndExecuteReq.serialize();
assertEquals(maxRowCount, prepareAndExecuteProtoReq.getMaxRowCount());
assertEquals(maxRowCount, prepareAndExecuteProtoReq.getMaxRowsTotal());
- assertEquals((int) maxRowCount, prepareAndExecuteProtoReq.getFirstFrameMaxSize());
+ assertEquals(AvaticaUtils.toSaturatedInt(maxRowCount),
+ prepareAndExecuteProtoReq.getFirstFrameMaxSize());
assertEquals(prepareAndExecuteReq,
prepareAndExecuteReq.deserialize(prepareAndExecuteProtoReq));
@@ -175,7 +177,8 @@ public class ProtobufSerializationTest {
prepareAndExecuteReq = new Service.PrepareAndExecuteRequest().deserialize(protoPrepare);
assertEquals(maxRowCount, prepareAndExecuteReq.maxRowCount);
- assertEquals((int) maxRowCount, prepareAndExecuteReq.maxRowsInFirstFrame);
+ assertEquals(AvaticaUtils.toSaturatedInt(maxRowCount),
+ prepareAndExecuteReq.maxRowsInFirstFrame);
// Both the new and old provided should default to the new (firstFrameMaxSize should be the
// the same as what ultimately is set to maxRowCount)
@@ -185,7 +188,8 @@ public class ProtobufSerializationTest {
prepareAndExecuteReq = new Service.PrepareAndExecuteRequest().deserialize(protoPrepare);
assertEquals(maxRowCount, prepareAndExecuteReq.maxRowCount);
- assertEquals((int) maxRowCount, prepareAndExecuteReq.maxRowsInFirstFrame);
+ assertEquals(AvaticaUtils.toSaturatedInt(maxRowCount),
+ prepareAndExecuteReq.maxRowsInFirstFrame);
// Same as previous example, but explicitly setting maxRowsInFirstFrame too
protoPrepare = Requests.PrepareAndExecuteRequest.newBuilder().
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java
index 8dac427..5cf3208 100644
--- a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ProtobufTranslationImplTest.java
@@ -358,7 +358,7 @@ public class ProtobufTranslationImplTest<T> {
responses.add(new CommitResponse());
responses.add(new RollbackResponse());
- int[] updateCounts = new int[]{1, 0, 1, 1};
+ long[] updateCounts = new long[]{1, 0, 1, 1};
responses.add(
new ExecuteBatchResponse("connectionId", 12345, updateCounts, false, rpcMetadata));
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
index 8929400..8905508 100644
--- a/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/AvaticaUtilsTest.java
@@ -30,6 +30,7 @@ import java.util.Properties;
import java.util.Set;
import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
@@ -148,6 +149,15 @@ public class AvaticaUtilsTest {
assertThat(env.getString(), is(" "));
}
+ @Test public void testLongToIntegerTranslation() {
+ long[] longValues = new long[] {Integer.MIN_VALUE, -5, 0, 1, Integer.MAX_VALUE,
+ ((long) Integer.MAX_VALUE) + 1L, Long.MAX_VALUE};
+ int[] convertedValues = AvaticaUtils.toSaturatedInts(longValues);
+ int[] intValues = new int[] {Integer.MIN_VALUE, -5, 0, 1, Integer.MAX_VALUE,
+ Integer.MAX_VALUE, Integer.MAX_VALUE};
+ assertArrayEquals(convertedValues, intValues);
+ }
+
/** Dummy implementation of {@link ConnectionProperty}. */
private static class ConnectionPropertyImpl implements ConnectionProperty {
private final String name;
http://git-wip-us.apache.org/repos/asf/calcite/blob/08c966b9/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
----------------------------------------------------------------------
diff --git a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
index c68041f..204421f 100644
--- a/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
+++ b/avatica/server/src/main/java/org/apache/calcite/avatica/jdbc/JdbcMeta.java
@@ -710,7 +710,8 @@ public class JdbcMeta implements ProtobufMeta {
public ExecuteResult prepareAndExecute(StatementHandle h, String sql,
long maxRowCount, PrepareCallback callback) throws NoSuchStatementException {
- return prepareAndExecute(h, sql, maxRowCount, (int) maxRowCount, callback);
+ return prepareAndExecute(h, sql, maxRowCount, AvaticaUtils.toSaturatedInt(maxRowCount),
+ callback);
}
public ExecuteResult prepareAndExecute(StatementHandle h, String sql, long maxRowCount,
@@ -818,7 +819,7 @@ public class JdbcMeta implements ProtobufMeta {
@Override public ExecuteResult execute(StatementHandle h, List<TypedValue> parameterValues,
long maxRowCount) throws NoSuchStatementException {
- return execute(h, parameterValues, (int) maxRowCount);
+ return execute(h, parameterValues, AvaticaUtils.toSaturatedInt(maxRowCount));
}
@Override public ExecuteResult execute(StatementHandle h,
@@ -912,7 +913,7 @@ public class JdbcMeta implements ProtobufMeta {
}
// Execute the batch and return the results
- return new ExecuteBatchResult(stmt.executeBatch());
+ return new ExecuteBatchResult(AvaticaUtils.executeLargeBatch(stmt));
} catch (SQLException e) {
throw propagate(e);
}
@@ -944,7 +945,7 @@ public class JdbcMeta implements ProtobufMeta {
}
preparedStmt.addBatch();
}
- return new ExecuteBatchResult(preparedStmt.executeBatch());
+ return new ExecuteBatchResult(AvaticaUtils.executeLargeBatch(preparedStmt));
} catch (SQLException e) {
throw propagate(e);
}
@@ -967,7 +968,7 @@ public class JdbcMeta implements ProtobufMeta {
}
preparedStmt.addBatch();
}
- return new ExecuteBatchResult(preparedStmt.executeBatch());
+ return new ExecuteBatchResult(AvaticaUtils.executeLargeBatch(preparedStmt));
} catch (SQLException e) {
throw propagate(e);
}