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/03/24 05:26:09 UTC
[2/4] calcite git commit: [CALCITE-1128] Implement JDBC batch update
methods in remote driver
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/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 cd3d0cf..a26e096 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
@@ -11607,6 +11607,957 @@ package org.apache.calcite.avatica.proto;
}
+ public interface ExecuteBatchResponseOrBuilder extends
+ // @@protoc_insertion_point(interface_extends:ExecuteBatchResponse)
+ com.google.protobuf.MessageOrBuilder {
+
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ java.lang.String getConnectionId();
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ com.google.protobuf.ByteString
+ getConnectionIdBytes();
+
+ /**
+ * <code>optional uint32 statement_id = 2;</code>
+ */
+ int getStatementId();
+
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ java.util.List<java.lang.Integer> getUpdateCountsList();
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ int getUpdateCountsCount();
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ int getUpdateCounts(int index);
+
+ /**
+ * <code>optional bool missing_statement = 4;</code>
+ *
+ * <pre>
+ * Did the request fail because of no-cached statement
+ * </pre>
+ */
+ boolean getMissingStatement();
+
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ boolean hasMetadata();
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata();
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder();
+ }
+ /**
+ * Protobuf type {@code ExecuteBatchResponse}
+ *
+ * <pre>
+ * Response to a batch update request
+ * </pre>
+ */
+ public static final class ExecuteBatchResponse extends
+ com.google.protobuf.GeneratedMessage implements
+ // @@protoc_insertion_point(message_implements:ExecuteBatchResponse)
+ ExecuteBatchResponseOrBuilder {
+ // Use ExecuteBatchResponse.newBuilder() to construct.
+ private ExecuteBatchResponse(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+ super(builder);
+ }
+ private ExecuteBatchResponse() {
+ connectionId_ = "";
+ statementId_ = 0;
+ updateCounts_ = java.util.Collections.emptyList();
+ missingStatement_ = false;
+ }
+
+ @java.lang.Override
+ public final com.google.protobuf.UnknownFieldSet
+ getUnknownFields() {
+ return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+ }
+ private ExecuteBatchResponse(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry) {
+ this();
+ int mutable_bitField0_ = 0;
+ try {
+ boolean done = false;
+ while (!done) {
+ int tag = input.readTag();
+ switch (tag) {
+ case 0:
+ done = true;
+ break;
+ default: {
+ if (!input.skipField(tag)) {
+ done = true;
+ }
+ break;
+ }
+ case 10: {
+ String s = input.readStringRequireUtf8();
+
+ connectionId_ = s;
+ break;
+ }
+ case 16: {
+
+ statementId_ = input.readUInt32();
+ break;
+ }
+ case 24: {
+ if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+ updateCounts_ = new java.util.ArrayList<java.lang.Integer>();
+ mutable_bitField0_ |= 0x00000004;
+ }
+ updateCounts_.add(input.readUInt32());
+ 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>();
+ mutable_bitField0_ |= 0x00000004;
+ }
+ while (input.getBytesUntilLimit() > 0) {
+ updateCounts_.add(input.readUInt32());
+ }
+ input.popLimit(limit);
+ break;
+ }
+ case 32: {
+
+ missingStatement_ = input.readBool();
+ break;
+ }
+ case 42: {
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder subBuilder = null;
+ if (metadata_ != null) {
+ subBuilder = metadata_.toBuilder();
+ }
+ metadata_ = input.readMessage(org.apache.calcite.avatica.proto.Responses.RpcMetadata.parser(), extensionRegistry);
+ if (subBuilder != null) {
+ subBuilder.mergeFrom(metadata_);
+ metadata_ = subBuilder.buildPartial();
+ }
+
+ break;
+ }
+ }
+ }
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ throw new RuntimeException(e.setUnfinishedMessage(this));
+ } catch (java.io.IOException e) {
+ throw new RuntimeException(
+ new com.google.protobuf.InvalidProtocolBufferException(
+ e.getMessage()).setUnfinishedMessage(this));
+ } finally {
+ if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
+ updateCounts_ = java.util.Collections.unmodifiableList(updateCounts_);
+ }
+ makeExtensionsImmutable();
+ }
+ }
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteBatchResponse_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteBatchResponse_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse.class, org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse.Builder.class);
+ }
+
+ private int bitField0_;
+ public static final int CONNECTION_ID_FIELD_NUMBER = 1;
+ private volatile java.lang.Object connectionId_;
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ public java.lang.String getConnectionId() {
+ java.lang.Object ref = connectionId_;
+ if (ref instanceof java.lang.String) {
+ return (java.lang.String) ref;
+ } else {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ connectionId_ = s;
+ return s;
+ }
+ }
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ public com.google.protobuf.ByteString
+ getConnectionIdBytes() {
+ java.lang.Object ref = connectionId_;
+ if (ref instanceof java.lang.String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ connectionId_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+
+ public static final int STATEMENT_ID_FIELD_NUMBER = 2;
+ private int statementId_;
+ /**
+ * <code>optional uint32 statement_id = 2;</code>
+ */
+ public int getStatementId() {
+ return statementId_;
+ }
+
+ public static final int UPDATE_COUNTS_FIELD_NUMBER = 3;
+ private java.util.List<java.lang.Integer> updateCounts_;
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public java.util.List<java.lang.Integer>
+ getUpdateCountsList() {
+ return updateCounts_;
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public int getUpdateCountsCount() {
+ return updateCounts_.size();
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public int getUpdateCounts(int index) {
+ return updateCounts_.get(index);
+ }
+ private int updateCountsMemoizedSerializedSize = -1;
+
+ public static final int MISSING_STATEMENT_FIELD_NUMBER = 4;
+ private boolean missingStatement_;
+ /**
+ * <code>optional bool missing_statement = 4;</code>
+ *
+ * <pre>
+ * Did the request fail because of no-cached statement
+ * </pre>
+ */
+ public boolean getMissingStatement() {
+ return missingStatement_;
+ }
+
+ public static final int METADATA_FIELD_NUMBER = 5;
+ private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_;
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public boolean hasMetadata() {
+ return metadata_ != null;
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
+ return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
+ return getMetadata();
+ }
+
+ private byte memoizedIsInitialized = -1;
+ public final boolean isInitialized() {
+ byte isInitialized = memoizedIsInitialized;
+ if (isInitialized == 1) return true;
+ if (isInitialized == 0) return false;
+
+ memoizedIsInitialized = 1;
+ return true;
+ }
+
+ public void writeTo(com.google.protobuf.CodedOutputStream output)
+ throws java.io.IOException {
+ getSerializedSize();
+ if (!getConnectionIdBytes().isEmpty()) {
+ com.google.protobuf.GeneratedMessage.writeString(output, 1, connectionId_);
+ }
+ if (statementId_ != 0) {
+ output.writeUInt32(2, statementId_);
+ }
+ if (getUpdateCountsList().size() > 0) {
+ output.writeRawVarint32(26);
+ output.writeRawVarint32(updateCountsMemoizedSerializedSize);
+ }
+ for (int i = 0; i < updateCounts_.size(); i++) {
+ output.writeUInt32NoTag(updateCounts_.get(i));
+ }
+ if (missingStatement_ != false) {
+ output.writeBool(4, missingStatement_);
+ }
+ if (metadata_ != null) {
+ output.writeMessage(5, getMetadata());
+ }
+ }
+
+ public int getSerializedSize() {
+ int size = memoizedSize;
+ if (size != -1) return size;
+
+ size = 0;
+ if (!getConnectionIdBytes().isEmpty()) {
+ size += com.google.protobuf.GeneratedMessage.computeStringSize(1, connectionId_);
+ }
+ if (statementId_ != 0) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeUInt32Size(2, statementId_);
+ }
+ {
+ int dataSize = 0;
+ for (int i = 0; i < updateCounts_.size(); i++) {
+ dataSize += com.google.protobuf.CodedOutputStream
+ .computeUInt32SizeNoTag(updateCounts_.get(i));
+ }
+ size += dataSize;
+ if (!getUpdateCountsList().isEmpty()) {
+ size += 1;
+ size += com.google.protobuf.CodedOutputStream
+ .computeInt32SizeNoTag(dataSize);
+ }
+ updateCountsMemoizedSerializedSize = dataSize;
+ }
+ if (missingStatement_ != false) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeBoolSize(4, missingStatement_);
+ }
+ if (metadata_ != null) {
+ size += com.google.protobuf.CodedOutputStream
+ .computeMessageSize(5, getMetadata());
+ }
+ memoizedSize = size;
+ return size;
+ }
+
+ private static final long serialVersionUID = 0L;
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(
+ com.google.protobuf.ByteString data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(
+ com.google.protobuf.ByteString data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(byte[] data)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(
+ byte[] data,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ return PARSER.parseFrom(data, extensionRegistry);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseDelimitedFrom(java.io.InputStream input)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseDelimitedFrom(
+ java.io.InputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseDelimitedFrom(input, extensionRegistry);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(
+ com.google.protobuf.CodedInputStream input)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input);
+ }
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parseFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ return PARSER.parseFrom(input, extensionRegistry);
+ }
+
+ public Builder newBuilderForType() { return newBuilder(); }
+ public static Builder newBuilder() {
+ return DEFAULT_INSTANCE.toBuilder();
+ }
+ public static Builder newBuilder(org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse prototype) {
+ return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+ }
+ public Builder toBuilder() {
+ return this == DEFAULT_INSTANCE
+ ? new Builder() : new Builder().mergeFrom(this);
+ }
+
+ @java.lang.Override
+ protected Builder newBuilderForType(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ Builder builder = new Builder(parent);
+ return builder;
+ }
+ /**
+ * Protobuf type {@code ExecuteBatchResponse}
+ *
+ * <pre>
+ * Response to a batch update request
+ * </pre>
+ */
+ public static final class Builder extends
+ com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+ // @@protoc_insertion_point(builder_implements:ExecuteBatchResponse)
+ org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponseOrBuilder {
+ public static final com.google.protobuf.Descriptors.Descriptor
+ getDescriptor() {
+ return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteBatchResponse_descriptor;
+ }
+
+ protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internalGetFieldAccessorTable() {
+ return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteBatchResponse_fieldAccessorTable
+ .ensureFieldAccessorsInitialized(
+ org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse.class, org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse.Builder.class);
+ }
+
+ // Construct using org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse.newBuilder()
+ private Builder() {
+ maybeForceBuilderInitialization();
+ }
+
+ private Builder(
+ com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+ super(parent);
+ maybeForceBuilderInitialization();
+ }
+ private void maybeForceBuilderInitialization() {
+ if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+ }
+ }
+ public Builder clear() {
+ super.clear();
+ connectionId_ = "";
+
+ statementId_ = 0;
+
+ updateCounts_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000004);
+ missingStatement_ = false;
+
+ if (metadataBuilder_ == null) {
+ metadata_ = null;
+ } else {
+ metadata_ = null;
+ metadataBuilder_ = null;
+ }
+ return this;
+ }
+
+ public com.google.protobuf.Descriptors.Descriptor
+ getDescriptorForType() {
+ return org.apache.calcite.avatica.proto.Responses.internal_static_ExecuteBatchResponse_descriptor;
+ }
+
+ public org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse getDefaultInstanceForType() {
+ return org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse.getDefaultInstance();
+ }
+
+ public org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse build() {
+ org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse result = buildPartial();
+ if (!result.isInitialized()) {
+ throw newUninitializedMessageException(result);
+ }
+ return result;
+ }
+
+ public org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse buildPartial() {
+ org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse result = new org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse(this);
+ int from_bitField0_ = bitField0_;
+ int to_bitField0_ = 0;
+ result.connectionId_ = connectionId_;
+ result.statementId_ = statementId_;
+ if (((bitField0_ & 0x00000004) == 0x00000004)) {
+ updateCounts_ = java.util.Collections.unmodifiableList(updateCounts_);
+ bitField0_ = (bitField0_ & ~0x00000004);
+ }
+ result.updateCounts_ = updateCounts_;
+ result.missingStatement_ = missingStatement_;
+ if (metadataBuilder_ == null) {
+ result.metadata_ = metadata_;
+ } else {
+ result.metadata_ = metadataBuilder_.build();
+ }
+ result.bitField0_ = to_bitField0_;
+ onBuilt();
+ return result;
+ }
+
+ public Builder mergeFrom(com.google.protobuf.Message other) {
+ if (other instanceof org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse) {
+ return mergeFrom((org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse)other);
+ } else {
+ super.mergeFrom(other);
+ return this;
+ }
+ }
+
+ public Builder mergeFrom(org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse other) {
+ if (other == org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse.getDefaultInstance()) return this;
+ if (!other.getConnectionId().isEmpty()) {
+ connectionId_ = other.connectionId_;
+ onChanged();
+ }
+ if (other.getStatementId() != 0) {
+ setStatementId(other.getStatementId());
+ }
+ if (!other.updateCounts_.isEmpty()) {
+ if (updateCounts_.isEmpty()) {
+ updateCounts_ = other.updateCounts_;
+ bitField0_ = (bitField0_ & ~0x00000004);
+ } else {
+ ensureUpdateCountsIsMutable();
+ updateCounts_.addAll(other.updateCounts_);
+ }
+ onChanged();
+ }
+ if (other.getMissingStatement() != false) {
+ setMissingStatement(other.getMissingStatement());
+ }
+ if (other.hasMetadata()) {
+ mergeMetadata(other.getMetadata());
+ }
+ onChanged();
+ return this;
+ }
+
+ public final boolean isInitialized() {
+ return true;
+ }
+
+ public Builder mergeFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws java.io.IOException {
+ org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse parsedMessage = null;
+ try {
+ parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+ } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+ parsedMessage = (org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse) e.getUnfinishedMessage();
+ throw e;
+ } finally {
+ if (parsedMessage != null) {
+ mergeFrom(parsedMessage);
+ }
+ }
+ return this;
+ }
+ private int bitField0_;
+
+ private java.lang.Object connectionId_ = "";
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ public java.lang.String getConnectionId() {
+ java.lang.Object ref = connectionId_;
+ if (!(ref instanceof java.lang.String)) {
+ com.google.protobuf.ByteString bs =
+ (com.google.protobuf.ByteString) ref;
+ java.lang.String s = bs.toStringUtf8();
+ connectionId_ = s;
+ return s;
+ } else {
+ return (java.lang.String) ref;
+ }
+ }
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ public com.google.protobuf.ByteString
+ getConnectionIdBytes() {
+ java.lang.Object ref = connectionId_;
+ if (ref instanceof String) {
+ com.google.protobuf.ByteString b =
+ com.google.protobuf.ByteString.copyFromUtf8(
+ (java.lang.String) ref);
+ connectionId_ = b;
+ return b;
+ } else {
+ return (com.google.protobuf.ByteString) ref;
+ }
+ }
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ public Builder setConnectionId(
+ java.lang.String value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+
+ connectionId_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ public Builder clearConnectionId() {
+
+ connectionId_ = getDefaultInstance().getConnectionId();
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional string connection_id = 1;</code>
+ */
+ public Builder setConnectionIdBytes(
+ com.google.protobuf.ByteString value) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ checkByteStringIsUtf8(value);
+
+ connectionId_ = value;
+ onChanged();
+ return this;
+ }
+
+ private int statementId_ ;
+ /**
+ * <code>optional uint32 statement_id = 2;</code>
+ */
+ public int getStatementId() {
+ return statementId_;
+ }
+ /**
+ * <code>optional uint32 statement_id = 2;</code>
+ */
+ public Builder setStatementId(int value) {
+
+ statementId_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional uint32 statement_id = 2;</code>
+ */
+ public Builder clearStatementId() {
+
+ statementId_ = 0;
+ onChanged();
+ return this;
+ }
+
+ private java.util.List<java.lang.Integer> updateCounts_ = java.util.Collections.emptyList();
+ private void ensureUpdateCountsIsMutable() {
+ if (!((bitField0_ & 0x00000004) == 0x00000004)) {
+ updateCounts_ = new java.util.ArrayList<java.lang.Integer>(updateCounts_);
+ bitField0_ |= 0x00000004;
+ }
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public java.util.List<java.lang.Integer>
+ getUpdateCountsList() {
+ return java.util.Collections.unmodifiableList(updateCounts_);
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public int getUpdateCountsCount() {
+ return updateCounts_.size();
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public int getUpdateCounts(int index) {
+ return updateCounts_.get(index);
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public Builder setUpdateCounts(
+ int index, int value) {
+ ensureUpdateCountsIsMutable();
+ updateCounts_.set(index, value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public Builder addUpdateCounts(int value) {
+ ensureUpdateCountsIsMutable();
+ updateCounts_.add(value);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public Builder addAllUpdateCounts(
+ java.lang.Iterable<? extends java.lang.Integer> values) {
+ ensureUpdateCountsIsMutable();
+ com.google.protobuf.AbstractMessageLite.Builder.addAll(
+ values, updateCounts_);
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>repeated uint32 update_counts = 3;</code>
+ */
+ public Builder clearUpdateCounts() {
+ updateCounts_ = java.util.Collections.emptyList();
+ bitField0_ = (bitField0_ & ~0x00000004);
+ onChanged();
+ return this;
+ }
+
+ private boolean missingStatement_ ;
+ /**
+ * <code>optional bool missing_statement = 4;</code>
+ *
+ * <pre>
+ * Did the request fail because of no-cached statement
+ * </pre>
+ */
+ public boolean getMissingStatement() {
+ return missingStatement_;
+ }
+ /**
+ * <code>optional bool missing_statement = 4;</code>
+ *
+ * <pre>
+ * Did the request fail because of no-cached statement
+ * </pre>
+ */
+ public Builder setMissingStatement(boolean value) {
+
+ missingStatement_ = value;
+ onChanged();
+ return this;
+ }
+ /**
+ * <code>optional bool missing_statement = 4;</code>
+ *
+ * <pre>
+ * Did the request fail because of no-cached statement
+ * </pre>
+ */
+ public Builder clearMissingStatement() {
+
+ missingStatement_ = false;
+ onChanged();
+ return this;
+ }
+
+ private org.apache.calcite.avatica.proto.Responses.RpcMetadata metadata_ = null;
+ private com.google.protobuf.SingleFieldBuilder<
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder> metadataBuilder_;
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public boolean hasMetadata() {
+ return metadataBuilder_ != null || metadata_ != null;
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public org.apache.calcite.avatica.proto.Responses.RpcMetadata getMetadata() {
+ if (metadataBuilder_ == null) {
+ return metadata_ == null ? org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+ } else {
+ return metadataBuilder_.getMessage();
+ }
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public Builder setMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
+ if (metadataBuilder_ == null) {
+ if (value == null) {
+ throw new NullPointerException();
+ }
+ metadata_ = value;
+ onChanged();
+ } else {
+ metadataBuilder_.setMessage(value);
+ }
+
+ return this;
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public Builder setMetadata(
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder builderForValue) {
+ if (metadataBuilder_ == null) {
+ metadata_ = builderForValue.build();
+ onChanged();
+ } else {
+ metadataBuilder_.setMessage(builderForValue.build());
+ }
+
+ return this;
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public Builder mergeMetadata(org.apache.calcite.avatica.proto.Responses.RpcMetadata value) {
+ if (metadataBuilder_ == null) {
+ if (metadata_ != null) {
+ metadata_ =
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata.newBuilder(metadata_).mergeFrom(value).buildPartial();
+ } else {
+ metadata_ = value;
+ }
+ onChanged();
+ } else {
+ metadataBuilder_.mergeFrom(value);
+ }
+
+ return this;
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public Builder clearMetadata() {
+ if (metadataBuilder_ == null) {
+ metadata_ = null;
+ onChanged();
+ } else {
+ metadata_ = null;
+ metadataBuilder_ = null;
+ }
+
+ return this;
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder getMetadataBuilder() {
+
+ onChanged();
+ return getMetadataFieldBuilder().getBuilder();
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ public org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder getMetadataOrBuilder() {
+ if (metadataBuilder_ != null) {
+ return metadataBuilder_.getMessageOrBuilder();
+ } else {
+ return metadata_ == null ?
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata.getDefaultInstance() : metadata_;
+ }
+ }
+ /**
+ * <code>optional .RpcMetadata metadata = 5;</code>
+ */
+ private com.google.protobuf.SingleFieldBuilder<
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder>
+ getMetadataFieldBuilder() {
+ if (metadataBuilder_ == null) {
+ metadataBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+ org.apache.calcite.avatica.proto.Responses.RpcMetadata, org.apache.calcite.avatica.proto.Responses.RpcMetadata.Builder, org.apache.calcite.avatica.proto.Responses.RpcMetadataOrBuilder>(
+ getMetadata(),
+ getParentForChildren(),
+ isClean());
+ metadata_ = null;
+ }
+ return metadataBuilder_;
+ }
+ public final Builder setUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return this;
+ }
+
+ public final Builder mergeUnknownFields(
+ final com.google.protobuf.UnknownFieldSet unknownFields) {
+ return this;
+ }
+
+
+ // @@protoc_insertion_point(builder_scope:ExecuteBatchResponse)
+ }
+
+ // @@protoc_insertion_point(class_scope:ExecuteBatchResponse)
+ private static final org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse DEFAULT_INSTANCE;
+ static {
+ DEFAULT_INSTANCE = new org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse();
+ }
+
+ public static org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse getDefaultInstance() {
+ return DEFAULT_INSTANCE;
+ }
+
+ private static final com.google.protobuf.Parser<ExecuteBatchResponse>
+ PARSER = new com.google.protobuf.AbstractParser<ExecuteBatchResponse>() {
+ public ExecuteBatchResponse parsePartialFrom(
+ com.google.protobuf.CodedInputStream input,
+ com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+ throws com.google.protobuf.InvalidProtocolBufferException {
+ try {
+ return new ExecuteBatchResponse(input, extensionRegistry);
+ } catch (RuntimeException e) {
+ if (e.getCause() instanceof
+ com.google.protobuf.InvalidProtocolBufferException) {
+ throw (com.google.protobuf.InvalidProtocolBufferException)
+ e.getCause();
+ }
+ throw e;
+ }
+ }
+ };
+
+ public static com.google.protobuf.Parser<ExecuteBatchResponse> parser() {
+ return PARSER;
+ }
+
+ @java.lang.Override
+ public com.google.protobuf.Parser<ExecuteBatchResponse> getParserForType() {
+ return PARSER;
+ }
+
+ public org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse getDefaultInstanceForType() {
+ return DEFAULT_INSTANCE;
+ }
+
+ }
+
private static com.google.protobuf.Descriptors.Descriptor
internal_static_ResultSetResponse_descriptor;
private static
@@ -11687,6 +12638,11 @@ package org.apache.calcite.avatica.proto;
private static
com.google.protobuf.GeneratedMessage.FieldAccessorTable
internal_static_RollbackResponse_fieldAccessorTable;
+ private static com.google.protobuf.Descriptors.Descriptor
+ internal_static_ExecuteBatchResponse_descriptor;
+ private static
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable
+ internal_static_ExecuteBatchResponse_fieldAccessorTable;
public static com.google.protobuf.Descriptors.FileDescriptor
getDescriptor() {
@@ -11734,8 +12690,12 @@ package org.apache.calcite.avatica.proto;
"\014more_results\030\002 \001(\010\022\036\n\010metadata\030\003 \001(\0132\014." +
"RpcMetadata\"%\n\013RpcMetadata\022\026\n\016server_add" +
"ress\030\001 \001(\t\"\020\n\016CommitResponse\"\022\n\020Rollback" +
- "ResponseB\"\n org.apache.calcite.avatica.p" +
- "rotob\006proto3"
+ "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" +
+ "nt\030\004 \001(\010\022\036\n\010metadata\030\005 \001(\0132\014.RpcMetadata" +
+ "B\"\n org.apache.calcite.avatica.protob\006pr" +
+ "oto3"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new com.google.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
@@ -11846,6 +12806,12 @@ package org.apache.calcite.avatica.proto;
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_RollbackResponse_descriptor,
new java.lang.String[] { });
+ internal_static_ExecuteBatchResponse_descriptor =
+ getDescriptor().getMessageTypes().get(16);
+ internal_static_ExecuteBatchResponse_fieldAccessorTable = new
+ com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+ internal_static_ExecuteBatchResponse_descriptor,
+ new java.lang.String[] { "ConnectionId", "StatementId", "UpdateCounts", "MissingStatement", "Metadata", });
org.apache.calcite.avatica.proto.Common.getDescriptor();
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
index 668b3be..19c95e7 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
@@ -222,6 +222,22 @@ public abstract class JsonService extends AbstractService {
throw handle(e);
}
}
+
+ public ExecuteBatchResponse apply(PrepareAndExecuteBatchRequest request) {
+ try {
+ return decode(apply(encode(request)), ExecuteBatchResponse.class);
+ } catch (IOException e) {
+ throw handle(e);
+ }
+ }
+
+ public ExecuteBatchResponse apply(ExecuteBatchRequest request) {
+ try {
+ return decode(apply(encode(request)), ExecuteBatchResponse.class);
+ } catch (IOException e) {
+ throw handle(e);
+ }
+ }
}
// End JsonService.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/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 c070ec0..a15d55f 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
@@ -18,6 +18,7 @@ package org.apache.calcite.avatica.remote;
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;
import org.apache.calcite.avatica.NoSuchStatementException;
@@ -353,6 +354,37 @@ public class LocalService implements Service {
// If rollback() errors, let the ErrorResponse be sent back via an uncaught Exception.
return new RollbackResponse();
}
+
+ public ExecuteBatchResponse apply(PrepareAndExecuteBatchRequest request) {
+ final Meta.StatementHandle h = new Meta.StatementHandle(request.connectionId,
+ request.statementId, null);
+ try {
+ ExecuteBatchResult result = meta.prepareAndExecuteBatch(h, request.sqlCommands);
+ return new ExecuteBatchResponse(request.connectionId, request.statementId,
+ result.updateCounts, false, serverLevelRpcMetadata);
+ } catch (NoSuchStatementException e) {
+ return new ExecuteBatchResponse(request.connectionId, request.statementId, null, true,
+ serverLevelRpcMetadata);
+ }
+ }
+
+ public ExecuteBatchResponse apply(ExecuteBatchRequest request) {
+ final Meta.StatementHandle h = new Meta.StatementHandle(request.connectionId,
+ request.statementId, null);
+ try {
+ ExecuteBatchResult result;
+ if (request.hasProtoUpdateBatches() && meta instanceof ProtobufMeta) {
+ result = ((ProtobufMeta) meta).executeBatchProtobuf(h, request.getProtoUpdateBatches());
+ } else {
+ result = meta.executeBatch(h, request.parameterValues);
+ }
+ return new ExecuteBatchResponse(request.connectionId, request.statementId,
+ result.updateCounts, false, serverLevelRpcMetadata);
+ } catch (NoSuchStatementException e) {
+ return new ExecuteBatchResponse(request.connectionId, request.statementId, null, true,
+ serverLevelRpcMetadata);
+ }
+ }
}
// End LocalService.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufMeta.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufMeta.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufMeta.java
new file mode 100644
index 0000000..375ae80
--- /dev/null
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufMeta.java
@@ -0,0 +1,45 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.Meta;
+import org.apache.calcite.avatica.NoSuchStatementException;
+import org.apache.calcite.avatica.proto.Requests;
+
+import java.util.List;
+
+/**
+ * An extension of {@link Meta} which allows for native processing of calls with the Protobuf
+ * API objects instead of the POJOS (to avoid object translation). In the write-path, performing
+ * this conversion tends to represent a signficant portion of execution time. The introduction
+ * of this interface is to serve the purose of gradual migration to Meta implementations that
+ * can naturally function over Protobuf objects instead of the POJOs.
+ */
+public interface ProtobufMeta extends Meta {
+
+ /**
+ * Executes a batch of commands on a prepared statement.
+ *
+ * @param h Statement handle
+ * @param parameterValues A collection of list of typed values, one list per batch
+ * @return An array of update counts containing one element for each command in the batch.
+ */
+ ExecuteBatchResult executeBatchProtobuf(StatementHandle h, List<Requests.UpdateBatch>
+ parameterValues) throws NoSuchStatementException;
+}
+
+// End ProtobufMeta.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
index 56ba125..d694440 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
@@ -109,6 +109,14 @@ public abstract class ProtobufService extends AbstractService {
return (RollbackResponse) _apply(request);
}
+ @Override public ExecuteBatchResponse apply(PrepareAndExecuteBatchRequest request) {
+ return (ExecuteBatchResponse) _apply(request);
+ }
+
+ @Override public ExecuteBatchResponse apply(ExecuteBatchRequest request) {
+ return (ExecuteBatchResponse) _apply(request);
+ }
+
/**
* Checks if the provided {@link Message} is an instance of the Class given by
* <code>expectedType</code>. Throws an IllegalArgumentException if the message is not of the
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
index 80d2b22..b9c57c5 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
@@ -25,9 +25,11 @@ import org.apache.calcite.avatica.proto.Requests.CommitRequest;
import org.apache.calcite.avatica.proto.Requests.ConnectionSyncRequest;
import org.apache.calcite.avatica.proto.Requests.CreateStatementRequest;
import org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest;
+import org.apache.calcite.avatica.proto.Requests.ExecuteBatchRequest;
import org.apache.calcite.avatica.proto.Requests.ExecuteRequest;
import org.apache.calcite.avatica.proto.Requests.FetchRequest;
import org.apache.calcite.avatica.proto.Requests.OpenConnectionRequest;
+import org.apache.calcite.avatica.proto.Requests.PrepareAndExecuteBatchRequest;
import org.apache.calcite.avatica.proto.Requests.PrepareAndExecuteRequest;
import org.apache.calcite.avatica.proto.Requests.PrepareRequest;
import org.apache.calcite.avatica.proto.Requests.RollbackRequest;
@@ -43,6 +45,7 @@ import org.apache.calcite.avatica.proto.Responses.ConnectionSyncResponse;
import org.apache.calcite.avatica.proto.Responses.CreateStatementResponse;
import org.apache.calcite.avatica.proto.Responses.DatabasePropertyResponse;
import org.apache.calcite.avatica.proto.Responses.ErrorResponse;
+import org.apache.calcite.avatica.proto.Responses.ExecuteBatchResponse;
import org.apache.calcite.avatica.proto.Responses.ExecuteResponse;
import org.apache.calcite.avatica.proto.Responses.FetchResponse;
import org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse;
@@ -126,6 +129,12 @@ public class ProtobufTranslationImpl implements ProtobufTranslation {
new RequestTranslator(CommitRequest.parser(), new Service.CommitRequest()));
reqParsers.put(RollbackRequest.class.getName(),
new RequestTranslator(RollbackRequest.parser(), new Service.RollbackRequest()));
+ reqParsers.put(PrepareAndExecuteBatchRequest.class.getName(),
+ new RequestTranslator(PrepareAndExecuteBatchRequest.parser(),
+ new Service.PrepareAndExecuteBatchRequest()));
+ reqParsers.put(ExecuteBatchRequest.class.getName(),
+ new RequestTranslator(ExecuteBatchRequest.parser(),
+ new Service.ExecuteBatchRequest()));
REQUEST_PARSERS = Collections.unmodifiableMap(reqParsers);
@@ -166,6 +175,8 @@ public class ProtobufTranslationImpl implements ProtobufTranslation {
new ResponseTranslator(CommitResponse.parser(), new Service.CommitResponse()));
respParsers.put(RollbackResponse.class.getName(),
new ResponseTranslator(RollbackResponse.parser(), new Service.RollbackResponse()));
+ respParsers.put(ExecuteBatchResponse.class.getName(),
+ new ResponseTranslator(ExecuteBatchResponse.parser(), new Service.ExecuteBatchResponse()));
RESPONSE_PARSERS = Collections.unmodifiableMap(respParsers);
@@ -197,6 +208,9 @@ public class ProtobufTranslationImpl implements ProtobufTranslation {
messageClasses.add(TableTypesRequest.class);
messageClasses.add(TablesRequest.class);
messageClasses.add(TypeInfoRequest.class);
+ messageClasses.add(PrepareAndExecuteBatchRequest.class);
+ messageClasses.add(ExecuteBatchRequest.class);
+
messageClasses.add(CloseConnectionResponse.class);
messageClasses.add(CloseStatementResponse.class);
messageClasses.add(CommitResponse.class);
@@ -212,6 +226,7 @@ public class ProtobufTranslationImpl implements ProtobufTranslation {
messageClasses.add(RollbackResponse.class);
messageClasses.add(RpcMetadata.class);
messageClasses.add(SyncResultsResponse.class);
+ messageClasses.add(ExecuteBatchResponse.class);
return messageClasses;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/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 463985a..152e0ca 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
@@ -390,6 +390,29 @@ class RemoteMeta extends MetaImpl {
}
});
}
+
+ @Override public ExecuteBatchResult prepareAndExecuteBatch(final StatementHandle h,
+ final List<String> sqlCommands) throws NoSuchStatementException {
+ return connection.invokeWithRetries(new CallableWithoutException<ExecuteBatchResult>() {
+ @Override public ExecuteBatchResult call() {
+ Service.ExecuteBatchResponse response =
+ service.apply(
+ new Service.PrepareAndExecuteBatchRequest(h.connectionId, h.id, sqlCommands));
+ return new ExecuteBatchResult(response.updateCounts);
+ }
+ });
+ }
+
+ @Override public ExecuteBatchResult executeBatch(final StatementHandle h,
+ final List<List<TypedValue>> parameterValues) throws NoSuchStatementException {
+ return connection.invokeWithRetries(new CallableWithoutException<ExecuteBatchResult>() {
+ @Override public ExecuteBatchResult call() {
+ Service.ExecuteBatchResponse response =
+ service.apply(new Service.ExecuteBatchRequest(h.connectionId, h.id, parameterValues));
+ return new ExecuteBatchResult(response.updateCounts);
+ }
+ });
+ }
}
// End RemoteMeta.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/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 5790848..078e63e 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
@@ -28,6 +28,7 @@ import org.apache.calcite.avatica.proto.Requests;
import org.apache.calcite.avatica.proto.Responses;
import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@@ -40,6 +41,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -71,6 +73,8 @@ public interface Service {
DatabasePropertyResponse apply(DatabasePropertyRequest request);
CommitResponse apply(CommitRequest request);
RollbackResponse apply(RollbackRequest request);
+ ExecuteBatchResponse apply(PrepareAndExecuteBatchRequest request);
+ ExecuteBatchResponse apply(ExecuteBatchRequest request);
/**
* Sets server-level metadata for RPCs. This includes information that is static across all RPCs.
@@ -134,7 +138,10 @@ public interface Service {
@JsonSubTypes.Type(value = DatabasePropertyRequest.class, name = "databaseProperties"),
@JsonSubTypes.Type(value = SyncResultsRequest.class, name = "syncResults"),
@JsonSubTypes.Type(value = CommitRequest.class, name = "commit"),
- @JsonSubTypes.Type(value = RollbackRequest.class, name = "rollback") })
+ @JsonSubTypes.Type(value = RollbackRequest.class, name = "rollback"),
+ @JsonSubTypes.Type(value = PrepareAndExecuteBatchRequest.class,
+ name = "prepareAndExecuteBatch"),
+ @JsonSubTypes.Type(value = ExecuteBatchRequest.class, name = "executeBatch") })
abstract class Request extends Base {
abstract Response accept(Service service);
abstract Request deserialize(Message genericMsg);
@@ -164,7 +171,8 @@ public interface Service {
@JsonSubTypes.Type(value = SyncResultsResponse.class, name = "syncResults"),
@JsonSubTypes.Type(value = RpcMetadataResponse.class, name = "rpcMetadata"),
@JsonSubTypes.Type(value = CommitResponse.class, name = "commit"),
- @JsonSubTypes.Type(value = RollbackResponse.class, name = "rollback") })
+ @JsonSubTypes.Type(value = RollbackResponse.class, name = "rollback"),
+ @JsonSubTypes.Type(value = ExecuteBatchResponse.class, name = "executeBatch") })
abstract class Response extends Base {
abstract Response deserialize(Message genericMsg);
abstract Message serialize();
@@ -2766,6 +2774,270 @@ public interface Service {
}
}
+ /**
+ * Request to prepare a statement and execute a series of batch commands in one call.
+ */
+ class PrepareAndExecuteBatchRequest extends Request {
+ public final String connectionId;
+ public final List<String> sqlCommands;
+ public final int statementId;
+
+ PrepareAndExecuteBatchRequest() {
+ connectionId = null;
+ statementId = 0;
+ sqlCommands = null;
+ }
+
+ @JsonCreator
+ public PrepareAndExecuteBatchRequest(@JsonProperty("connectionId") String connectionId,
+ @JsonProperty("statementId") int statementId, @JsonProperty("sqlCommands") List<String>
+ sqlCommands) {
+ this.connectionId = connectionId;
+ this.sqlCommands = sqlCommands;
+ this.statementId = statementId;
+ }
+
+ @Override public ExecuteBatchResponse accept(Service service) {
+ return service.apply(this);
+ }
+
+ @Override public Requests.PrepareAndExecuteBatchRequest serialize() {
+ Requests.PrepareAndExecuteBatchRequest.Builder builder =
+ Requests.PrepareAndExecuteBatchRequest.newBuilder();
+
+ if (null != connectionId) {
+ builder.setConnectionId(connectionId);
+ }
+
+ if (null != sqlCommands) {
+ builder.addAllSqlCommands(sqlCommands);
+ }
+
+ return builder.setStatementId(statementId).build();
+ }
+
+ @Override public PrepareAndExecuteBatchRequest deserialize(Message genericMsg) {
+ final Requests.PrepareAndExecuteBatchRequest msg =
+ ProtobufService.castProtobufMessage(genericMsg,
+ Requests.PrepareAndExecuteBatchRequest.class);
+
+ List<String> sqlCommands = new ArrayList<>(msg.getSqlCommandsList());
+
+ return new PrepareAndExecuteBatchRequest(msg.getConnectionId(), msg.getStatementId(),
+ sqlCommands);
+ }
+
+ @Override public int hashCode() {
+ int result = 1;
+ result = p(result, connectionId);
+ result = p(result, statementId);
+ result = p(result, sqlCommands);
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ return this == o
+ || o instanceof PrepareAndExecuteBatchRequest
+ && Objects.equals(connectionId, ((PrepareAndExecuteBatchRequest) o).connectionId)
+ && statementId == ((PrepareAndExecuteBatchRequest) o).statementId
+ && Objects.equals(sqlCommands, ((PrepareAndExecuteBatchRequest) o).sqlCommands);
+
+ }
+ }
+
+ /**
+ * Request object to execute a batch of commands.
+ */
+ class ExecuteBatchRequest extends Request {
+ private static final FieldDescriptor UPDATE_BATCH_FIELD_DESCRIPTOR = Requests
+ .ExecuteBatchRequest.getDescriptor()
+ .findFieldByNumber(Requests.ExecuteBatchRequest.UPDATES_FIELD_NUMBER);
+
+ public final String connectionId;
+ public final int statementId;
+ // Each update in a batch has a list of TypedValue's
+ public final List<List<TypedValue>> parameterValues;
+ // Avoid deserializing every parameter list from pb to pojo
+ @JsonIgnore
+ private List<Requests.UpdateBatch> protoParameterValues = null;
+
+ ExecuteBatchRequest() {
+ this.connectionId = null;
+ this.statementId = 0;
+ this.parameterValues = null;
+ }
+
+ @JsonCreator
+ public ExecuteBatchRequest(@JsonProperty("connectionId") String connectionId,
+ @JsonProperty("statementId") int statementId,
+ @JsonProperty("parameterValues") List<List<TypedValue>> parameterValues) {
+ this.connectionId = connectionId;
+ this.statementId = statementId;
+ this.parameterValues = parameterValues;
+ }
+
+ ExecuteBatchRequest(String connectionId, int statementId) {
+ this.connectionId = connectionId;
+ this.statementId = statementId;
+ this.parameterValues = null;
+ }
+
+ /**
+ * Does this instance contain protobuf update batches.
+ * @return True if <code>protoUpdateBatches</code> is non-null.
+ */
+ public boolean hasProtoUpdateBatches() {
+ return null != protoParameterValues;
+ }
+
+ /**
+ * @return The protobuf update batches.
+ */
+ // JsonIgnore on the getter, otherwise Jackson will try to serialize it
+ @JsonIgnore
+ public List<Requests.UpdateBatch> getProtoUpdateBatches() {
+ return protoParameterValues;
+ }
+
+ @Override public ExecuteBatchResponse accept(Service service) {
+ return service.apply(this);
+ }
+
+ @Override ExecuteBatchRequest deserialize(Message genericMsg) {
+ Requests.ExecuteBatchRequest msg = ProtobufService.castProtobufMessage(genericMsg,
+ Requests.ExecuteBatchRequest.class);
+
+ List<Requests.UpdateBatch> updateBatches = msg.getUpdatesList();
+
+ ExecuteBatchRequest pojo =
+ new ExecuteBatchRequest(msg.getConnectionId(), msg.getStatementId());
+ pojo.protoParameterValues = updateBatches;
+ return pojo;
+ }
+
+ @Override Requests.ExecuteBatchRequest serialize() {
+ Requests.ExecuteBatchRequest.Builder builder = Requests.ExecuteBatchRequest.newBuilder();
+
+ if (hasProtoUpdateBatches()) {
+ builder.addAllUpdates(protoParameterValues);
+ } else if (null != parameterValues) {
+ for (List<TypedValue> updateBatch : parameterValues) {
+ Requests.UpdateBatch.Builder batchBuilder = Requests.UpdateBatch.newBuilder();
+ for (TypedValue update : updateBatch) {
+ batchBuilder.addParameterValues(update.toProto());
+ }
+ builder.addUpdates(batchBuilder.build());
+ }
+ }
+
+ return builder.setConnectionId(connectionId).setStatementId(statementId).build();
+ }
+
+ @Override public int hashCode() {
+ int result = 1;
+ result = p(result, connectionId);
+ result = p(result, statementId);
+ result = p(result, parameterValues);
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ return this == o
+ || o instanceof ExecuteBatchRequest
+ && Objects.equals(connectionId, ((ExecuteBatchRequest) o).connectionId)
+ && statementId == ((ExecuteBatchRequest) o).statementId
+ && Objects.equals(protoParameterValues, ((ExecuteBatchRequest) o).protoParameterValues)
+ && Objects.equals(parameterValues, ((ExecuteBatchRequest) o).parameterValues);
+ }
+ }
+
+ /**
+ * Response object for executing a batch of commands.
+ */
+ class ExecuteBatchResponse extends Response {
+ private static final FieldDescriptor RPC_METADATA_DESCRIPTOR = Responses.ExecuteBatchResponse
+ .getDescriptor().findFieldByNumber(Responses.ExecuteBatchResponse.METADATA_FIELD_NUMBER);
+
+ public final String connectionId;
+ public final int statementId;
+ public final int[] updateCounts;
+ public final boolean missingStatement;
+ public final RpcMetadataResponse rpcMetadata;
+
+ ExecuteBatchResponse() {
+ connectionId = null;
+ statementId = 0;
+ updateCounts = null;
+ missingStatement = false;
+ rpcMetadata = null;
+ }
+
+ @JsonCreator
+ public ExecuteBatchResponse(@JsonProperty("connectionId") String connectionId,
+ @JsonProperty("statementId") int statementId,
+ @JsonProperty("updateCounts") int[] updateCounts,
+ @JsonProperty("missingStatement") boolean missingStatement,
+ @JsonProperty("rpcMetadata") RpcMetadataResponse rpcMetadata) {
+ this.connectionId = connectionId;
+ this.statementId = statementId;
+ this.updateCounts = updateCounts;
+ this.missingStatement = missingStatement;
+ this.rpcMetadata = rpcMetadata;
+ }
+
+ @Override public int hashCode() {
+ int result = 1;
+ result = p(result, connectionId);
+ result = p(result, statementId);
+ result = p(result, updateCounts);
+ result = p(result, missingStatement);
+ return result;
+ }
+
+ @Override public boolean equals(Object o) {
+ return this == o
+ || o instanceof ExecuteBatchResponse
+ && Arrays.equals(updateCounts, ((ExecuteBatchResponse) o).updateCounts)
+ && Objects.equals(connectionId, ((ExecuteBatchResponse) o).connectionId)
+ && statementId == ((ExecuteBatchResponse) o).statementId
+ && missingStatement == ((ExecuteBatchResponse) o).missingStatement;
+ }
+
+ @Override ExecuteBatchResponse deserialize(Message genericMsg) {
+ Responses.ExecuteBatchResponse msg = ProtobufService.castProtobufMessage(genericMsg,
+ Responses.ExecuteBatchResponse.class);
+
+ int[] updateCounts = new int[msg.getUpdateCountsCount()];
+ int i = 0;
+ for (Integer updateCount : msg.getUpdateCountsList()) {
+ updateCounts[i++] = updateCount;
+ }
+
+ RpcMetadataResponse metadata = null;
+ if (msg.hasField(RPC_METADATA_DESCRIPTOR)) {
+ metadata = RpcMetadataResponse.fromProto(msg.getMetadata());
+ }
+
+ return new ExecuteBatchResponse(msg.getConnectionId(), msg.getStatementId(), updateCounts,
+ msg.getMissingStatement(), metadata);
+ }
+
+ @Override Responses.ExecuteBatchResponse serialize() {
+ Responses.ExecuteBatchResponse.Builder builder = Responses.ExecuteBatchResponse.newBuilder();
+
+ if (null != updateCounts) {
+ for (int i = 0; i < updateCounts.length; i++) {
+ builder.addUpdateCounts(updateCounts[i]);
+ }
+ }
+
+ if (null != rpcMetadata) {
+ builder.setMetadata(rpcMetadata.serialize());
+ }
+
+ return builder.setConnectionId(connectionId).setStatementId(statementId).build();
+ }
+ }
}
// End Service.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
index d96293b..1146a47 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/remote/TypedValue.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
+import java.util.Objects;
/** Value and type.
*
@@ -244,6 +245,40 @@ public class TypedValue {
}
}
+ private static Object protoSerialToLocal(Common.Rep rep, Object value) {
+ switch (rep) {
+ case BYTE:
+ return ((Number) value).byteValue();
+ case SHORT:
+ return ((Number) value).shortValue();
+ case INTEGER:
+ case JAVA_SQL_DATE:
+ case JAVA_SQL_TIME:
+ return ((Number) value).intValue();
+ case LONG:
+ case JAVA_UTIL_DATE:
+ case JAVA_SQL_TIMESTAMP:
+ return ((Number) value).longValue();
+ case FLOAT:
+ return ((Number) value).floatValue();
+ case DOUBLE:
+ return ((Number) value).doubleValue();
+ case NUMBER:
+ return value instanceof BigDecimal ? value
+ : value instanceof BigInteger ? new BigDecimal((BigInteger) value)
+ : value instanceof Double ? new BigDecimal((Double) value)
+ : value instanceof Float ? new BigDecimal((Float) value)
+ : new BigDecimal(((Number) value).longValue());
+ case BYTE_STRING:
+ return (byte[]) value;
+ case STRING:
+ return (String) value;
+ default:
+ throw new IllegalArgumentException("cannot convert " + value + " ("
+ + value.getClass() + ") to " + rep);
+ }
+ }
+
/** Converts the value into the JDBC representation.
*
* <p>For example, a byte string is represented as a {@link ByteString};
@@ -276,6 +311,22 @@ public class TypedValue {
}
}
+ private static Object protoSerialToJdbc(Common.Rep type, Object value, Calendar calendar) {
+ switch (type) {
+ case JAVA_UTIL_DATE:
+ return new java.util.Date(adjust((Number) value, calendar));
+ case JAVA_SQL_DATE:
+ return new java.sql.Date(
+ adjust(((Number) value).longValue() * DateTimeUtils.MILLIS_PER_DAY, calendar));
+ case JAVA_SQL_TIME:
+ return new java.sql.Time(adjust((Number) value, calendar));
+ case JAVA_SQL_TIMESTAMP:
+ return new java.sql.Timestamp(adjust((Number) value, calendar));
+ default:
+ return protoSerialToLocal(type, value);
+ }
+ }
+
private static long adjust(Number number, Calendar calendar) {
long t = number.longValue();
if (calendar != null) {
@@ -332,6 +383,10 @@ public class TypedValue {
return list;
}
+ /**
+ * Creates a protocol buffer equivalent object for <code>this</code>.
+ * @return A protobuf TypedValue equivalent for <code>this</code>
+ */
public Common.TypedValue toProto() {
final Common.TypedValue.Builder builder = Common.TypedValue.newBuilder();
@@ -419,83 +474,99 @@ public class TypedValue {
return builder.build();
}
+ /**
+ * Constructs a {@link TypedValue} from the protocol buffer representation.
+ *
+ * @param proto The protobuf Typedvalue
+ * @return A {@link TypedValue} instance
+ */
public static TypedValue fromProto(Common.TypedValue proto) {
ColumnMetaData.Rep rep = ColumnMetaData.Rep.fromProto(proto.getType());
+ Object value = getValue(proto);
- Object value = null;
+ return new TypedValue(rep, value);
+ }
+ /**
+ * Converts the serialized value into the appropriate primitive/object.
+ *
+ * @param protoValue The serialized TypedValue.
+ * @return The appropriate concrete type for the parameter value (as an Object).
+ */
+ public static Object getValue(Common.TypedValue protoValue) {
// Deserialize the value again
- switch (proto.getType()) {
+ switch (protoValue.getType()) {
case BOOLEAN:
case PRIMITIVE_BOOLEAN:
- value = proto.getBoolValue();
- break;
+ return protoValue.getBoolValue();
case BYTE_STRING:
case STRING:
- value = proto.getStringValue();
- break;
+ // TypedValue is still going to expect a string for BYTE_STRING even though we sent it
+ // across the wire natively as bytes.
+ return protoValue.getStringValue();
case PRIMITIVE_CHAR:
case CHARACTER:
- value = proto.getStringValue().charAt(0);
- break;
+ return protoValue.getStringValue().charAt(0);
case BYTE:
case PRIMITIVE_BYTE:
- value = Long.valueOf(proto.getNumberValue()).byteValue();
- break;
+ return Long.valueOf(protoValue.getNumberValue()).byteValue();
case DOUBLE:
case PRIMITIVE_DOUBLE:
- value = proto.getDoubleValue();
- break;
+ return protoValue.getDoubleValue();
case FLOAT:
case PRIMITIVE_FLOAT:
- value = Float.intBitsToFloat((int) proto.getNumberValue());
- break;
+ return Float.intBitsToFloat((int) protoValue.getNumberValue());
case INTEGER:
case PRIMITIVE_INT:
- value = Long.valueOf(proto.getNumberValue()).intValue();
- break;
+ return Long.valueOf(protoValue.getNumberValue()).intValue();
case PRIMITIVE_SHORT:
case SHORT:
- value = Long.valueOf(proto.getNumberValue()).shortValue();
- break;
+ return Long.valueOf(protoValue.getNumberValue()).shortValue();
case LONG:
case PRIMITIVE_LONG:
- value = Long.valueOf(proto.getNumberValue());
- break;
+ return Long.valueOf(protoValue.getNumberValue());
case JAVA_SQL_DATE:
case JAVA_SQL_TIME:
- value = Long.valueOf(proto.getNumberValue()).intValue();
- break;
+ return Long.valueOf(protoValue.getNumberValue()).intValue();
case JAVA_SQL_TIMESTAMP:
case JAVA_UTIL_DATE:
- value = proto.getNumberValue();
- break;
+ return protoValue.getNumberValue();
case BIG_INTEGER:
- value = new BigInteger(proto.getBytesValues().toByteArray());
- break;
+ return new BigInteger(protoValue.getBytesValues().toByteArray());
case BIG_DECIMAL:
- BigInteger bigInt = new BigInteger(proto.getBytesValues().toByteArray());
- value = new BigDecimal(bigInt, (int) proto.getNumberValue());
- break;
+ BigInteger bigInt = new BigInteger(protoValue.getBytesValues().toByteArray());
+ return new BigDecimal(bigInt, (int) protoValue.getNumberValue());
case NUMBER:
- value = Long.valueOf(proto.getNumberValue());
- break;
+ return Long.valueOf(protoValue.getNumberValue());
case OBJECT:
- if (proto.getNull()) {
- value = null;
- break;
+ if (protoValue.getNull()) {
+ return null;
}
// Intentional fall through to RTE. If we sent an object over the wire, it could only
// possibly be null (at this point). Anything else has to be an error.
case UNRECOGNIZED:
// Fail?
- throw new RuntimeException("Unhandled type: " + proto.getType());
+ throw new RuntimeException("Unhandled type: " + protoValue.getType());
default:
// Fail?
- throw new RuntimeException("Unknown type: " + proto.getType());
+ throw new RuntimeException("Unknown type: " + protoValue.getType());
}
+ }
- return new TypedValue(rep, value);
+ /**
+ * Extracts the JDBC value from protobuf-TypedValue representation.
+ *
+ * @param protoValue Protobuf TypedValue
+ * @param calendar Instance of a calendar
+ * @return The JDBC representation of this TypedValue
+ */
+ public static Object protoToJdbc(Common.TypedValue protoValue, Calendar calendar) {
+ Object o = getValue(Objects.requireNonNull(protoValue));
+ // Shortcircuit the null
+ if (null == o) {
+ return o;
+ }
+ return protoSerialToJdbc(protoValue.getType(), o, Objects.requireNonNull(calendar));
}
@Override public int hashCode() {
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/avatica/core/src/main/protobuf/requests.proto
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/protobuf/requests.proto b/avatica/core/src/main/protobuf/requests.proto
index 31b0941..afa8aec 100644
--- a/avatica/core/src/main/protobuf/requests.proto
+++ b/avatica/core/src/main/protobuf/requests.proto
@@ -143,3 +143,21 @@ message CommitRequest {
message RollbackRequest {
string connection_id = 1;
}
+
+// Request to prepare and execute a collection of sql statements.
+message PrepareAndExecuteBatchRequest {
+ string connection_id = 1;
+ uint32 statement_id = 2;
+ repeated string sql_commands = 3;
+}
+
+// Each command is a list of TypedValues
+message UpdateBatch {
+ repeated TypedValue parameter_values = 1;
+}
+
+message ExecuteBatchRequest {
+ string connection_id = 1;
+ uint32 statement_id = 2;
+ repeated UpdateBatch updates = 3; // A batch of updates is a list<list<typevalue>>
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/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 01a62ed..47d73ab 100644
--- a/avatica/core/src/main/protobuf/responses.proto
+++ b/avatica/core/src/main/protobuf/responses.proto
@@ -124,3 +124,12 @@ message CommitResponse {
message RollbackResponse {
}
+
+// Response to a batch update request
+message ExecuteBatchResponse {
+ string connection_id = 1;
+ uint32 statement_id = 2;
+ repeated uint32 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/5dfa3f1e/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ExecuteBatchRequestTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ExecuteBatchRequestTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ExecuteBatchRequestTest.java
new file mode 100644
index 0000000..134ea15
--- /dev/null
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/remote/ExecuteBatchRequestTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.remote;
+
+import org.apache.calcite.avatica.ColumnMetaData.Rep;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.proto.Requests;
+import org.apache.calcite.avatica.proto.Requests.UpdateBatch;
+import org.apache.calcite.avatica.remote.Service.ExecuteBatchRequest;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class for ExecuteBatchRequest
+ */
+public class ExecuteBatchRequestTest {
+
+ private ExecuteBatchRequest identityRequest = new ExecuteBatchRequest();
+ private List<TypedValue> paramValues =
+ Arrays.asList(TypedValue.create(Rep.BOOLEAN.name(), Boolean.TRUE),
+ TypedValue.create(Rep.STRING.name(), "string"));
+
+ @Test public void testConversionFromProtobuf() {
+ ExecuteBatchRequest request = new ExecuteBatchRequest("connectionId", 12345,
+ Arrays.asList(paramValues, paramValues, paramValues));
+
+ assertFalse("A request with the POJO TypedValue list should return false",
+ request.hasProtoUpdateBatches());
+
+ // Everything will be serialized via protobuf
+ Requests.ExecuteBatchRequest protoRequest = request.serialize();
+
+ ExecuteBatchRequest copy = identityRequest.deserialize(protoRequest);
+
+ assertNull("Parameter values (pojo) list should be null", copy.parameterValues);
+ assertTrue("hasProtoUpdateBatches() should return true", copy.hasProtoUpdateBatches());
+ List<UpdateBatch> protoParameterValues = copy.getProtoUpdateBatches();
+ assertNotNull("Protobuf serialized parameterValues should not be null", protoParameterValues);
+
+ assertEquals(request.parameterValues.size(), protoParameterValues.size());
+
+ for (int i = 0; i < request.parameterValues.size(); i++) {
+ List<TypedValue> orig = request.parameterValues.get(i);
+ List<Common.TypedValue> proto = protoParameterValues.get(i).getParameterValuesList();
+ assertEquals("Mismatch in length of TypedValues at index " + i, orig.size(), proto.size());
+
+ // Don't re-test TypedValue serialization
+ }
+
+ // Everything else should be equivalent.
+ assertEquals(request.connectionId, copy.connectionId);
+ assertEquals(request.statementId, copy.statementId);
+ }
+}
+
+// End ExecuteBatchRequestTest.java
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/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 c75bdb0..8dac427 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
@@ -44,11 +44,13 @@ import org.apache.calcite.avatica.remote.Service.CreateStatementResponse;
import org.apache.calcite.avatica.remote.Service.DatabasePropertyRequest;
import org.apache.calcite.avatica.remote.Service.DatabasePropertyResponse;
import org.apache.calcite.avatica.remote.Service.ErrorResponse;
+import org.apache.calcite.avatica.remote.Service.ExecuteBatchResponse;
import org.apache.calcite.avatica.remote.Service.ExecuteResponse;
import org.apache.calcite.avatica.remote.Service.FetchRequest;
import org.apache.calcite.avatica.remote.Service.FetchResponse;
import org.apache.calcite.avatica.remote.Service.OpenConnectionRequest;
import org.apache.calcite.avatica.remote.Service.OpenConnectionResponse;
+import org.apache.calcite.avatica.remote.Service.PrepareAndExecuteBatchRequest;
import org.apache.calcite.avatica.remote.Service.PrepareAndExecuteRequest;
import org.apache.calcite.avatica.remote.Service.PrepareRequest;
import org.apache.calcite.avatica.remote.Service.PrepareResponse;
@@ -216,6 +218,11 @@ public class ProtobufTranslationImplTest<T> {
requests.add(new CommitRequest("connectionId"));
requests.add(new RollbackRequest("connectionId"));
+ // ExecuteBatchRequest omitted because of the special protobuf conversion it does
+
+ List<String> commands = Arrays.asList("command1", "command2", "command3");
+ requests.add(new PrepareAndExecuteBatchRequest("connectionId", 12345, commands));
+
return requests;
}
@@ -351,6 +358,10 @@ public class ProtobufTranslationImplTest<T> {
responses.add(new CommitResponse());
responses.add(new RollbackResponse());
+ int[] updateCounts = new int[]{1, 0, 1, 1};
+ responses.add(
+ new ExecuteBatchResponse("connectionId", 12345, updateCounts, false, rpcMetadata));
+
return responses;
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java b/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java
index 57cf60a..7afa000 100644
--- a/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java
+++ b/avatica/core/src/test/java/org/apache/calcite/avatica/test/JsonHandlerTest.java
@@ -129,6 +129,14 @@ public class JsonHandlerTest {
@Override public RollbackResponse apply(RollbackRequest request) {
return null;
}
+
+ @Override public ExecuteBatchResponse apply(ExecuteBatchRequest request) {
+ return null;
+ }
+
+ @Override public ExecuteBatchResponse apply(PrepareAndExecuteBatchRequest request) {
+ return null;
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/calcite/blob/5dfa3f1e/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 dfe7f99..4e6c67f 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
@@ -31,6 +31,9 @@ import org.apache.calcite.avatica.SqlType;
import org.apache.calcite.avatica.metrics.Gauge;
import org.apache.calcite.avatica.metrics.MetricsSystem;
import org.apache.calcite.avatica.metrics.noop.NoopMetricsSystem;
+import org.apache.calcite.avatica.proto.Common;
+import org.apache.calcite.avatica.proto.Requests;
+import org.apache.calcite.avatica.remote.ProtobufMeta;
import org.apache.calcite.avatica.remote.TypedValue;
import com.google.common.cache.Cache;
@@ -66,7 +69,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/** Implementation of {@link Meta} upon an existing JDBC data source. */
-public class JdbcMeta implements Meta {
+public class JdbcMeta implements ProtobufMeta {
private static final Logger LOG = LoggerFactory.getLogger(JdbcMeta.class);
private static final String CONN_CACHE_KEY_BASE = "avatica.connectioncache";
@@ -852,6 +855,83 @@ public class JdbcMeta implements Meta {
}
}
+ @Override public ExecuteBatchResult prepareAndExecuteBatch(StatementHandle h,
+ List<String> sqlCommands) throws NoSuchStatementException {
+ try {
+ // Get the statement
+ final StatementInfo info = statementCache.getIfPresent(h.id);
+ if (info == null) {
+ throw new NoSuchStatementException(h);
+ }
+
+ // addBatch() for each sql command
+ final Statement stmt = info.statement;
+ for (String sqlCommand : sqlCommands) {
+ stmt.addBatch(sqlCommand);
+ }
+
+ // Execute the batch and return the results
+ return new ExecuteBatchResult(stmt.executeBatch());
+ } catch (SQLException e) {
+ throw propagate(e);
+ }
+ }
+
+ @Override public ExecuteBatchResult executeBatch(StatementHandle h,
+ List<List<TypedValue>> updateBatches) throws NoSuchStatementException {
+ try {
+ final StatementInfo info = statementCache.getIfPresent(h.id);
+ if (null == info) {
+ throw new NoSuchStatementException(h);
+ }
+
+ final PreparedStatement preparedStmt = (PreparedStatement) info.statement;
+ int rowUpdate = 1;
+ for (List<TypedValue> batch : updateBatches) {
+ int i = 1;
+ for (TypedValue value : batch) {
+ // Set the TypedValue in the PreparedStatement
+ try {
+ preparedStmt.setObject(i, value.toJdbc(calendar));
+ i++;
+ } catch (SQLException e) {
+ throw new RuntimeException("Failed to set value on row #" + rowUpdate
+ + " and column #" + i, e);
+ }
+ // Track the update number for better error messages
+ rowUpdate++;
+ }
+ preparedStmt.addBatch();
+ }
+ return new ExecuteBatchResult(preparedStmt.executeBatch());
+ } catch (SQLException e) {
+ throw propagate(e);
+ }
+ }
+
+ @Override public ExecuteBatchResult executeBatchProtobuf(StatementHandle h,
+ List<Requests.UpdateBatch> updateBatches) throws NoSuchStatementException {
+ try {
+ final StatementInfo info = statementCache.getIfPresent(h.id);
+ if (null == info) {
+ throw new NoSuchStatementException(h);
+ }
+
+ final PreparedStatement preparedStmt = (PreparedStatement) info.statement;
+ for (Requests.UpdateBatch update : updateBatches) {
+ int i = 1;
+ for (Common.TypedValue value : update.getParameterValuesList()) {
+ // Use the value and then increment
+ preparedStmt.setObject(i++, TypedValue.protoToJdbc(value, calendar));
+ }
+ preparedStmt.addBatch();
+ }
+ return new ExecuteBatchResult(preparedStmt.executeBatch());
+ } catch (SQLException e) {
+ throw propagate(e);
+ }
+ }
+
/** Configurable statement cache settings. */
public enum StatementCacheSettings {
/** JDBC connection property for setting connection cache concurrency level. */