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