http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java 
b/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java
index bed750b..2fceb8a 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/proto/Responses.java
@@ -3497,6 +3497,312 @@ package org.apache.calcite.avatica.proto;
 
   }
 
+  public interface OpenConnectionResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:OpenConnectionResponse)
+      com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code OpenConnectionResponse}
+   *
+   * <pre>
+   * Response to OpenConnectionRequest {
+   * </pre>
+   */
+  public  static final class OpenConnectionResponse extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:OpenConnectionResponse)
+      OpenConnectionResponseOrBuilder {
+    // Use OpenConnectionResponse.newBuilder() to construct.
+    private 
OpenConnectionResponse(com.google.protobuf.GeneratedMessage.Builder builder) {
+      super(builder);
+    }
+    private OpenConnectionResponse() {
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private OpenConnectionResponse(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      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;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return 
org.apache.calcite.avatica.proto.Responses.internal_static_OpenConnectionResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return 
org.apache.calcite.avatica.proto.Responses.internal_static_OpenConnectionResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse.class, 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse.Builder.class);
+    }
+
+    public static final com.google.protobuf.Parser<OpenConnectionResponse> 
PARSER =
+        new com.google.protobuf.AbstractParser<OpenConnectionResponse>() {
+      public OpenConnectionResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new OpenConnectionResponse(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<OpenConnectionResponse> 
getParserForType() {
+      return PARSER;
+    }
+
+    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();
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 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.OpenConnectionResponse 
parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 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.OpenConnectionResponse 
parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 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.OpenConnectionResponse 
parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
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.OpenConnectionResponse parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return new Builder(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder 
newBuilder(org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code OpenConnectionResponse}
+     *
+     * <pre>
+     * Response to OpenConnectionRequest {
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:OpenConnectionResponse)
+        
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return 
org.apache.calcite.avatica.proto.Responses.internal_static_OpenConnectionResponse_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return 
org.apache.calcite.avatica.proto.Responses.internal_static_OpenConnectionResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse.class, 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse.Builder.class);
+      }
+
+      // Construct using 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse.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();
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return 
org.apache.calcite.avatica.proto.Responses.internal_static_OpenConnectionResponse_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
getDefaultInstanceForType() {
+        return 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
build() {
+        org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
buildPartial() {
+        org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
result = new 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse(this);
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse) {
+          return 
mergeFrom((org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder 
mergeFrom(org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
other) {
+        if (other == 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse.getDefaultInstance())
 return this;
+        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.OpenConnectionResponse 
parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = 
(org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse) 
e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      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:OpenConnectionResponse)
+    }
+
+    // @@protoc_insertion_point(class_scope:OpenConnectionResponse)
+    private static final 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
defaultInstance;static {
+      defaultInstance = new 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse();
+    }
+
+    public static 
org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse 
getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+  }
+
   public interface CloseConnectionResponseOrBuilder extends
       // @@protoc_insertion_point(interface_extends:CloseConnectionResponse)
       com.google.protobuf.MessageOrBuilder {
@@ -5633,13 +5939,449 @@ package org.apache.calcite.avatica.proto;
 
   }
 
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_ResultSetResponse_descriptor;
-  private static
-    com.google.protobuf.GeneratedMessage.FieldAccessorTable
-      internal_static_ResultSetResponse_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_ExecuteResponse_descriptor;
+  public interface ErrorResponseOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:ErrorResponse)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>optional string message = 1;</code>
+     */
+    java.lang.String getMessage();
+    /**
+     * <code>optional string message = 1;</code>
+     */
+    com.google.protobuf.ByteString
+        getMessageBytes();
+  }
+  /**
+   * Protobuf type {@code ErrorResponse}
+   */
+  public  static final class ErrorResponse extends
+      com.google.protobuf.GeneratedMessage implements
+      // @@protoc_insertion_point(message_implements:ErrorResponse)
+      ErrorResponseOrBuilder {
+    // Use ErrorResponse.newBuilder() to construct.
+    private ErrorResponse(com.google.protobuf.GeneratedMessage.Builder 
builder) {
+      super(builder);
+    }
+    private ErrorResponse() {
+      message_ = "";
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return com.google.protobuf.UnknownFieldSet.getDefaultInstance();
+    }
+    private ErrorResponse(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      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: {
+              com.google.protobuf.ByteString bs = input.readBytes();
+
+              message_ = bs;
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return 
org.apache.calcite.avatica.proto.Responses.internal_static_ErrorResponse_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return 
org.apache.calcite.avatica.proto.Responses.internal_static_ErrorResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.calcite.avatica.proto.Responses.ErrorResponse.class, 
org.apache.calcite.avatica.proto.Responses.ErrorResponse.Builder.class);
+    }
+
+    public static final com.google.protobuf.Parser<ErrorResponse> PARSER =
+        new com.google.protobuf.AbstractParser<ErrorResponse>() {
+      public ErrorResponse parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new ErrorResponse(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<ErrorResponse> getParserForType() {
+      return PARSER;
+    }
+
+    public static final int MESSAGE_FIELD_NUMBER = 1;
+    private java.lang.Object message_;
+    /**
+     * <code>optional string message = 1;</code>
+     */
+    public java.lang.String getMessage() {
+      java.lang.Object ref = message_;
+      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();
+        if (bs.isValidUtf8()) {
+          message_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string message = 1;</code>
+     */
+    public com.google.protobuf.ByteString
+        getMessageBytes() {
+      java.lang.Object ref = message_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        message_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    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 (!getMessageBytes().isEmpty()) {
+        output.writeBytes(1, getMessageBytes());
+      }
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getMessageBytes().isEmpty()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(1, getMessageBytes());
+      }
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    public static org.apache.calcite.avatica.proto.Responses.ErrorResponse 
parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ErrorResponse 
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.ErrorResponse 
parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ErrorResponse 
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.ErrorResponse 
parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ErrorResponse 
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.ErrorResponse 
parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ErrorResponse 
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.ErrorResponse 
parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.calcite.avatica.proto.Responses.ErrorResponse 
parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return new Builder(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder 
newBuilder(org.apache.calcite.avatica.proto.Responses.ErrorResponse prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code ErrorResponse}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:ErrorResponse)
+        org.apache.calcite.avatica.proto.Responses.ErrorResponseOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return 
org.apache.calcite.avatica.proto.Responses.internal_static_ErrorResponse_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return 
org.apache.calcite.avatica.proto.Responses.internal_static_ErrorResponse_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                
org.apache.calcite.avatica.proto.Responses.ErrorResponse.class, 
org.apache.calcite.avatica.proto.Responses.ErrorResponse.Builder.class);
+      }
+
+      // Construct using 
org.apache.calcite.avatica.proto.Responses.ErrorResponse.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();
+        message_ = "";
+
+        return this;
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return 
org.apache.calcite.avatica.proto.Responses.internal_static_ErrorResponse_descriptor;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ErrorResponse 
getDefaultInstanceForType() {
+        return 
org.apache.calcite.avatica.proto.Responses.ErrorResponse.getDefaultInstance();
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ErrorResponse build() {
+        org.apache.calcite.avatica.proto.Responses.ErrorResponse result = 
buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.calcite.avatica.proto.Responses.ErrorResponse 
buildPartial() {
+        org.apache.calcite.avatica.proto.Responses.ErrorResponse result = new 
org.apache.calcite.avatica.proto.Responses.ErrorResponse(this);
+        result.message_ = message_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof 
org.apache.calcite.avatica.proto.Responses.ErrorResponse) {
+          return 
mergeFrom((org.apache.calcite.avatica.proto.Responses.ErrorResponse)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder 
mergeFrom(org.apache.calcite.avatica.proto.Responses.ErrorResponse other) {
+        if (other == 
org.apache.calcite.avatica.proto.Responses.ErrorResponse.getDefaultInstance()) 
return this;
+        if (!other.getMessage().isEmpty()) {
+          message_ = other.message_;
+          onChanged();
+        }
+        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.ErrorResponse parsedMessage 
= null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = 
(org.apache.calcite.avatica.proto.Responses.ErrorResponse) 
e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object message_ = "";
+      /**
+       * <code>optional string message = 1;</code>
+       */
+      public java.lang.String getMessage() {
+        java.lang.Object ref = message_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (bs.isValidUtf8()) {
+            message_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string message = 1;</code>
+       */
+      public com.google.protobuf.ByteString
+          getMessageBytes() {
+        java.lang.Object ref = message_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          message_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string message = 1;</code>
+       */
+      public Builder setMessage(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        message_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string message = 1;</code>
+       */
+      public Builder clearMessage() {
+        
+        message_ = getDefaultInstance().getMessage();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string message = 1;</code>
+       */
+      public Builder setMessageBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        message_ = value;
+        onChanged();
+        return this;
+      }
+      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:ErrorResponse)
+    }
+
+    // @@protoc_insertion_point(class_scope:ErrorResponse)
+    private static final 
org.apache.calcite.avatica.proto.Responses.ErrorResponse defaultInstance;static 
{
+      defaultInstance = new 
org.apache.calcite.avatica.proto.Responses.ErrorResponse();
+    }
+
+    public static org.apache.calcite.avatica.proto.Responses.ErrorResponse 
getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public org.apache.calcite.avatica.proto.Responses.ErrorResponse 
getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_ResultSetResponse_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_ResultSetResponse_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_ExecuteResponse_descriptor;
   private static
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
       internal_static_ExecuteResponse_fieldAccessorTable;
@@ -5664,6 +6406,11 @@ package org.apache.calcite.avatica.proto;
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
       internal_static_CloseStatementResponse_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_OpenConnectionResponse_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_OpenConnectionResponse_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_CloseConnectionResponse_descriptor;
   private static
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
@@ -5683,6 +6430,11 @@ package org.apache.calcite.avatica.proto;
   private static
     com.google.protobuf.GeneratedMessage.FieldAccessorTable
       internal_static_DatabasePropertyResponse_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_ErrorResponse_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_ErrorResponse_fieldAccessorTable;
 
   public static com.google.protobuf.Descriptors.FileDescriptor
       getDescriptor() {
@@ -5703,14 +6455,16 @@ package org.apache.calcite.avatica.proto;
       "etchResponse\022\025\n\005frame\030\001 \001(\0132\006.Frame\"F\n\027C" 
+
       "reateStatementResponse\022\025\n\rconnection_id\030",
       "\001 \001(\t\022\024\n\014statement_id\030\002 
\001(\r\"\030\n\026CloseStat" +
-      "ementResponse\"\031\n\027CloseConnectionResponse" +
-      "\"C\n\026ConnectionSyncResponse\022)\n\nconn_props" +
-      "\030\001 \001(\0132\025.ConnectionProperties\"U\n\027Databas" +
-      "ePropertyElement\022\036\n\003key\030\001 \001(\0132\021.Database" +
-      "Property\022\032\n\005value\030\002 \001(\0132\013.TypedValue\"C\n\030" 
+
-      "DatabasePropertyResponse\022\'\n\005props\030\001 \003(\0132" +
-      "\030.DatabasePropertyElementB\"\n org.apache." +
-      "calcite.avatica.protob\006proto3"
+      "ementResponse\"\030\n\026OpenConnectionResponse\"" +
+      "\031\n\027CloseConnectionResponse\"C\n\026Connection" +
+      "SyncResponse\022)\n\nconn_props\030\001 \001(\0132\025.Conne" +
+      "ctionProperties\"U\n\027DatabasePropertyEleme" +
+      "nt\022\036\n\003key\030\001 
\001(\0132\021.DatabaseProperty\022\032\n\005va" +
+      "lue\030\002 \001(\0132\013.TypedValue\"C\n\030DatabaseProper" +
+      "tyResponse\022\'\n\005props\030\001 \003(\0132\030.DatabaseProp" +
+      "ertyElement\" \n\rErrorResponse\022\017\n\007message\030" +
+      "\001 \001(\tB\"\n org.apache.calcite.avatica.prot",
+      "ob\006proto3"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner 
assigner =
         new com.google.protobuf.Descriptors.FileDescriptor.    
InternalDescriptorAssigner() {
@@ -5761,30 +6515,42 @@ package org.apache.calcite.avatica.proto;
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_CloseStatementResponse_descriptor,
         new java.lang.String[] { });
-    internal_static_CloseConnectionResponse_descriptor =
+    internal_static_OpenConnectionResponse_descriptor =
       getDescriptor().getMessageTypes().get(6);
+    internal_static_OpenConnectionResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_OpenConnectionResponse_descriptor,
+        new java.lang.String[] { });
+    internal_static_CloseConnectionResponse_descriptor =
+      getDescriptor().getMessageTypes().get(7);
     internal_static_CloseConnectionResponse_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_CloseConnectionResponse_descriptor,
         new java.lang.String[] { });
     internal_static_ConnectionSyncResponse_descriptor =
-      getDescriptor().getMessageTypes().get(7);
+      getDescriptor().getMessageTypes().get(8);
     internal_static_ConnectionSyncResponse_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_ConnectionSyncResponse_descriptor,
         new java.lang.String[] { "ConnProps", });
     internal_static_DatabasePropertyElement_descriptor =
-      getDescriptor().getMessageTypes().get(8);
+      getDescriptor().getMessageTypes().get(9);
     internal_static_DatabasePropertyElement_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_DatabasePropertyElement_descriptor,
         new java.lang.String[] { "Key", "Value", });
     internal_static_DatabasePropertyResponse_descriptor =
-      getDescriptor().getMessageTypes().get(9);
+      getDescriptor().getMessageTypes().get(10);
     internal_static_DatabasePropertyResponse_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessage.FieldAccessorTable(
         internal_static_DatabasePropertyResponse_descriptor,
         new java.lang.String[] { "Props", });
+    internal_static_ErrorResponse_descriptor =
+      getDescriptor().getMessageTypes().get(11);
+    internal_static_ErrorResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+        internal_static_ErrorResponse_descriptor,
+        new java.lang.String[] { "Message", });
     org.apache.calcite.avatica.proto.Common.getDescriptor();
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java
index 7d8c058..ea5561d 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/Driver.java
@@ -26,10 +26,15 @@ import org.apache.calcite.avatica.UnregisteredDriver;
 
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Properties;
 
 /**
  * Avatica Remote JDBC driver.
@@ -76,6 +81,15 @@ public class Driver extends UnregisteredDriver {
 
   @Override public Meta createMeta(AvaticaConnection connection) {
     final ConnectionConfig config = connection.config();
+    final Service service = createService(config);
+    return new RemoteMeta(connection, service);
+  }
+
+  private Service createService(ConnectionConfig config) {
+    // Exploit that none of the factory implementations currently rely
+    // on connection being there.
+    AvaticaConnection connection = null;
+
     final Service.Factory metaFactory = config.factory();
     final Service service;
     if (metaFactory != null) {
@@ -103,7 +117,40 @@ public class Driver extends UnregisteredDriver {
     } else {
       service = new MockJsonService(Collections.<String, String>emptyMap());
     }
-    return new RemoteMeta(connection, service);
+    return service;
+  }
+
+  @Override
+  public Connection connect(String url, Properties info) throws SQLException {
+    AvaticaConnection conn = (AvaticaConnection) super.connect(url, info);
+    if (conn == null) {
+      // It's not an url for our driver
+      return null;
+    }
+
+    // Create the corresponding remote connection
+    ConnectionConfig config = conn.config();
+    Service service = createService(config);
+
+    Map<String, String> infoAsString = new HashMap<>();
+    for (Map.Entry<Object, Object> entry : info.entrySet()) {
+      // Determine if this is a property we want to forward to the server
+      boolean localProperty = false;
+      for (BuiltInConnectionProperty prop : 
BuiltInConnectionProperty.values()) {
+        if (prop.camelName().equals(entry.getKey())) {
+          localProperty = true;
+          break;
+        }
+      }
+
+      if (!localProperty) {
+        infoAsString.put(entry.getKey().toString(), 
entry.getValue().toString());
+      }
+    }
+
+    service.apply(new Service.OpenConnectionRequest(conn.id, infoAsString));
+
+    return conn;
   }
 
   private Serialization getSerialization(ConnectionConfig config) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
index f59218f..be1f5a7 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonHandler.java
@@ -51,7 +51,13 @@ public class JsonHandler implements Handler<String> {
     return MAPPER.readValue(request, valueType);
   }
 
-  private <T> String encode(T response) throws IOException {
+  /**
+   * Serializes the provided object as JSON.
+   *
+   * @param response The object to serialize.
+   * @return A JSON string.
+   */
+  public <T> String encode(T response) throws IOException {
     final StringWriter w = new StringWriter();
     MAPPER.writeValue(w, response);
     return w.toString();

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
index b56ed4a..1bdb4a6 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/JsonService.java
@@ -156,6 +156,14 @@ public abstract class JsonService extends AbstractService {
     }
   }
 
+  public OpenConnectionResponse apply(OpenConnectionRequest request) {
+    try {
+      return decode(apply(encode(request)), OpenConnectionResponse.class);
+    } catch (IOException e) {
+      throw handle(e);
+    }
+  }
+
   public CloseConnectionResponse apply(CloseConnectionRequest request) {
     try {
       return decode(apply(encode(request)), CloseConnectionResponse.class);

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
index 12006ba..34bdf97 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/LocalService.java
@@ -110,19 +110,22 @@ public class LocalService implements Service {
   }
 
   public ResultSetResponse apply(CatalogsRequest request) {
-    final Meta.MetaResultSet resultSet = meta.getCatalogs();
+    final Meta.MetaResultSet resultSet =
+        meta.getCatalogs(new Meta.ConnectionHandle(request.connectionId));
     return toResponse(resultSet);
   }
 
   public ResultSetResponse apply(SchemasRequest request) {
     final Meta.MetaResultSet resultSet =
-        meta.getSchemas(request.catalog, Meta.Pat.of(request.schemaPattern));
+        meta.getSchemas(new Meta.ConnectionHandle(request.connectionId),
+            request.catalog, Meta.Pat.of(request.schemaPattern));
     return toResponse(resultSet);
   }
 
   public ResultSetResponse apply(TablesRequest request) {
     final Meta.MetaResultSet resultSet =
-        meta.getTables(request.catalog,
+        meta.getTables(new Meta.ConnectionHandle(request.connectionId),
+            request.catalog,
             Meta.Pat.of(request.schemaPattern),
             Meta.Pat.of(request.tableNamePattern),
             request.typeList);
@@ -130,18 +133,22 @@ public class LocalService implements Service {
   }
 
   public ResultSetResponse apply(TableTypesRequest request) {
-    final Meta.MetaResultSet resultSet = meta.getTableTypes();
+    final Meta.MetaResultSet resultSet = meta.getTableTypes(
+        new Meta.ConnectionHandle(request.connectionId));
     return toResponse(resultSet);
   }
 
   public ResultSetResponse apply(TypeInfoRequest request) {
-    final Meta.MetaResultSet resultSet = meta.getTypeInfo();
+    final Meta.MetaResultSet resultSet = meta.getTypeInfo(
+        new Meta.ConnectionHandle(request.connectionId));
     return toResponse(resultSet);
   }
 
   public ResultSetResponse apply(ColumnsRequest request) {
     final Meta.MetaResultSet resultSet =
-        meta.getColumns(request.catalog,
+        meta.getColumns(
+            new Meta.ConnectionHandle(request.connectionId),
+            request.catalog,
             Meta.Pat.of(request.schemaPattern),
             Meta.Pat.of(request.tableNamePattern),
             Meta.Pat.of(request.columnNamePattern));
@@ -217,6 +224,11 @@ public class LocalService implements Service {
     return new CloseStatementResponse();
   }
 
+  public OpenConnectionResponse apply(OpenConnectionRequest request) {
+    meta.openConnection(new Meta.ConnectionHandle(request.connectionId), 
request.info);
+    return new OpenConnectionResponse();
+  }
+
   public CloseConnectionResponse apply(CloseConnectionRequest request) {
     meta.closeConnection(new Meta.ConnectionHandle(request.connectionId));
     return new CloseConnectionResponse();
@@ -229,7 +241,8 @@ public class LocalService implements Service {
   }
 
   public DatabasePropertyResponse apply(DatabasePropertyRequest request) {
-    return new DatabasePropertyResponse(meta.getDatabaseProperties());
+    return new DatabasePropertyResponse(meta.getDatabaseProperties(
+        new Meta.ConnectionHandle(request.connectionId)));
   }
 }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
index 6e278a1..6d87122 100644
--- 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
+++ 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/MockJsonService.java
@@ -18,6 +18,9 @@ package org.apache.calcite.avatica.remote;
 
 import org.apache.calcite.avatica.AvaticaConnection;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -30,16 +33,14 @@ import java.util.Map;
  */
 public class MockJsonService extends JsonService {
   private final Map<String, String> map;
+  private final ObjectMapper mapper = new ObjectMapper();
 
   public MockJsonService(Map<String, String> map) {
     this.map = map;
   }
 
   @Override public String apply(String request) {
-    String response = map.get(request);
-    if (response == null) {
-      response = handleCloseConnection(request);
-    }
+    String response = map.get(canonicalizeConnectionId(request));
     if (response == null) {
       throw new RuntimeException("No response for " + request);
     }
@@ -47,14 +48,22 @@ public class MockJsonService extends JsonService {
   }
 
   /**
-   * Special case for closeConnection because connection IDs are random.
-   * @return response if is a CloseConnectionRequest, null otherwise.
+   * The connection id is always different, therefore when present in the 
request,
+   * set it to 0.
    */
-  private static String handleCloseConnection(String request) {
-    if (request.contains("closeConnection")) {
-      return "{\"response\":\"closeConnection\"}";
+  private String canonicalizeConnectionId(String request) {
+    ObjectNode jsonRequest;
+    try {
+      jsonRequest = (ObjectNode) mapper.readTree(request);
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+    if (jsonRequest.get("connectionId") != null) {
+      jsonRequest.put("connectionId", "0");
+      return jsonRequest.toString();
+    } else {
+      return request;
     }
-    return null;
   }
 
   /** Factory that creates a {@code MockJsonService}. */
@@ -63,14 +72,20 @@ public class MockJsonService extends JsonService {
       final Map<String, String> map1 = new HashMap<>();
       try {
         map1.put(
+            
"{\"request\":\"openConnection\",\"connectionId\":\"0\",\"info\":{}}",
+            "{\"response\":\"openConnection\"}");
+        map1.put(
+            "{\"request\":\"closeConnection\",\"connectionId\":\"0\"}",
+            "{\"response\":\"closeConnection\"}");
+        map1.put(
             
"{\"request\":\"getSchemas\",\"catalog\":null,\"schemaPattern\":{\"s\":null}}",
             "{\"response\":\"resultSet\", updateCount: -1, firstFrame: 
{offset: 0, done: true, rows: []}}");
         map1.put(
-            JsonService.encode(new SchemasRequest(null, null)),
+            JsonService.encode(new SchemasRequest("0", null, null)),
             "{\"response\":\"resultSet\", updateCount: -1, firstFrame: 
{offset: 0, done: true, rows: []}}");
         map1.put(
             JsonService.encode(
-                new TablesRequest(null, null, null, Arrays.<String>asList())),
+                new TablesRequest("0", null, null, null, 
Arrays.<String>asList())),
             "{\"response\":\"resultSet\", updateCount: -1, firstFrame: 
{offset: 0, done: true, rows: []}}");
         map1.put(
             "{\"request\":\"createStatement\",\"connectionId\":0}",

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
index d031527..fe357fd 100644
--- 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
+++ 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/MockProtobufService.java
@@ -40,13 +40,17 @@ public class MockProtobufService extends ProtobufService {
 
     // Add in mappings
 
+    mappings.put(
+        new OpenConnectionRequest("0", new HashMap<String, String>()),
+        new OpenConnectionResponse());
+
     // Get the schema, no.. schema..?
     mappings.put(
-        new SchemasRequest(null, null),
+        new SchemasRequest("0", null, null),
         new ResultSetResponse(null, 1, true, null, Meta.Frame.EMPTY, -1));
 
     // Get the tables, no tables exist
-    mappings.put(new TablesRequest(null, null, null, 
Collections.<String>emptyList()),
+    mappings.put(new TablesRequest("0", null, null, null, 
Collections.<String>emptyList()),
         new ResultSetResponse(null, 150, true, null, Meta.Frame.EMPTY, -1));
 
     // Create a statement, get back an id
@@ -109,6 +113,19 @@ public class MockProtobufService extends ProtobufService {
    * @throws RuntimeException if no mapping is found for the request
    */
   private Response dispatch(Request request) {
+    // Canonicalize connectionId's to 0
+    if (request instanceof OpenConnectionRequest) {
+      OpenConnectionRequest req = (OpenConnectionRequest) request;
+      request = new OpenConnectionRequest("0", req.info);
+    } else if (request instanceof TablesRequest) {
+      TablesRequest req = (TablesRequest) request;
+      request = new TablesRequest("0", req.catalog, req.schemaPattern,
+          req.tableNamePattern, req.typeList);
+    } else if (request instanceof SchemasRequest) {
+      SchemasRequest req = (SchemasRequest) request;
+      request = new SchemasRequest("0", req.catalog, req.schemaPattern);
+    }
+
     Response response = MAPPING.get(request);
 
     if (null == response) {

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
index 2ab7fa0..e41e9f6 100644
--- 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
+++ 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufService.java
@@ -74,6 +74,11 @@ public abstract class ProtobufService extends 
AbstractService {
     return (CloseStatementResponse) _apply(request);
   }
 
+  @Override
+  public OpenConnectionResponse apply(OpenConnectionRequest request) {
+    return (OpenConnectionResponse) _apply(request);
+  }
+
   @Override public CloseConnectionResponse apply(CloseConnectionRequest 
request) {
     return (CloseConnectionResponse) _apply(request);
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
index bfe4aca..a121ad3 100644
--- 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
+++ 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/ProtobufTranslationImpl.java
@@ -26,6 +26,7 @@ import 
org.apache.calcite.avatica.proto.Requests.CreateStatementRequest;
 import org.apache.calcite.avatica.proto.Requests.DatabasePropertyRequest;
 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.PrepareAndExecuteRequest;
 import org.apache.calcite.avatica.proto.Requests.PrepareRequest;
 import org.apache.calcite.avatica.proto.Requests.SchemasRequest;
@@ -37,8 +38,10 @@ import 
org.apache.calcite.avatica.proto.Responses.CloseStatementResponse;
 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.ExecuteResponse;
 import org.apache.calcite.avatica.proto.Responses.FetchResponse;
+import org.apache.calcite.avatica.proto.Responses.OpenConnectionResponse;
 import org.apache.calcite.avatica.proto.Responses.PrepareResponse;
 import org.apache.calcite.avatica.proto.Responses.ResultSetResponse;
 import org.apache.calcite.avatica.remote.Service.Request;
@@ -69,6 +72,8 @@ public class ProtobufTranslationImpl implements 
ProtobufTranslation {
     HashMap<String, RequestTranslator> reqParsers = new HashMap<>();
     reqParsers.put(CatalogsRequest.class.getName(),
         new RequestTranslator(CatalogsRequest.PARSER, new 
Service.CatalogsRequest()));
+    reqParsers.put(OpenConnectionRequest.class.getName(),
+        new RequestTranslator(OpenConnectionRequest.PARSER, new 
Service.OpenConnectionRequest()));
     reqParsers.put(CloseConnectionRequest.class.getName(),
         new RequestTranslator(CloseConnectionRequest.PARSER, new 
Service.CloseConnectionRequest()));
     reqParsers.put(CloseStatementRequest.class.getName(),
@@ -103,6 +108,9 @@ public class ProtobufTranslationImpl implements 
ProtobufTranslation {
     REQUEST_PARSERS = Collections.unmodifiableMap(reqParsers);
 
     HashMap<String, ResponseTranslator> respParsers = new HashMap<>();
+    respParsers.put(OpenConnectionResponse.class.getName(),
+        new ResponseTranslator(OpenConnectionResponse.PARSER,
+            new Service.OpenConnectionResponse()));
     respParsers.put(CloseConnectionResponse.class.getName(),
         new ResponseTranslator(CloseConnectionResponse.PARSER,
             new Service.CloseConnectionResponse()));
@@ -126,6 +134,8 @@ public class ProtobufTranslationImpl implements 
ProtobufTranslation {
         new ResponseTranslator(PrepareResponse.PARSER, new 
Service.PrepareResponse()));
     respParsers.put(ResultSetResponse.class.getName(),
         new ResponseTranslator(ResultSetResponse.PARSER, new 
Service.ResultSetResponse()));
+    respParsers.put(ErrorResponse.class.getName(),
+        new ResponseTranslator(ErrorResponse.PARSER, new 
Service.ErrorResponse()));
 
     RESPONSE_PARSERS = Collections.unmodifiableMap(respParsers);
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
index 154d807..e82b7ef 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteMeta.java
@@ -64,12 +64,12 @@ class RemoteMeta extends MetaImpl {
         response.ownStatement, signature0, response.firstFrame);
   }
 
-  @Override public Map<DatabaseProperty, Object> getDatabaseProperties() {
+  @Override public Map<DatabaseProperty, Object> 
getDatabaseProperties(ConnectionHandle ch) {
     synchronized (this) {
       // Compute map on first use, and cache
       if (databaseProperties == null) {
         databaseProperties =
-            service.apply(new Service.DatabasePropertyRequest()).map;
+            service.apply(new Service.DatabasePropertyRequest(ch.id)).map;
       }
       return databaseProperties;
     }
@@ -88,6 +88,11 @@ class RemoteMeta extends MetaImpl {
         service.apply(new Service.CloseStatementRequest(h.connectionId, h.id));
   }
 
+  @Override public void openConnection(ConnectionHandle ch, Map<String, 
String> info) {
+    final Service.OpenConnectionResponse response =
+        service.apply(new Service.OpenConnectionRequest(ch.id, info));
+  }
+
   @Override public void closeConnection(ConnectionHandle ch) {
     final Service.CloseConnectionResponse response =
         service.apply(new Service.CloseConnectionRequest(ch.id));
@@ -117,44 +122,45 @@ class RemoteMeta extends MetaImpl {
     }
   }
 
-  @Override public MetaResultSet getCatalogs() {
+  @Override public MetaResultSet getCatalogs(ConnectionHandle ch) {
     final Service.ResultSetResponse response =
-        service.apply(new Service.CatalogsRequest());
+        service.apply(new Service.CatalogsRequest(ch.id));
     return toResultSet(MetaCatalog.class, response);
   }
 
-  @Override public MetaResultSet getSchemas(String catalog, Pat schemaPattern) 
{
+  @Override public MetaResultSet getSchemas(ConnectionHandle ch, String 
catalog,
+      Pat schemaPattern) {
     final Service.ResultSetResponse response =
-        service.apply(new Service.SchemasRequest(catalog, schemaPattern.s));
+        service.apply(new Service.SchemasRequest(ch.id, catalog, 
schemaPattern.s));
     return toResultSet(MetaSchema.class, response);
   }
 
-  @Override public MetaResultSet getTables(String catalog, Pat schemaPattern,
+  @Override public MetaResultSet getTables(ConnectionHandle ch, String 
catalog, Pat schemaPattern,
       Pat tableNamePattern, List<String> typeList) {
     final Service.ResultSetResponse response =
         service.apply(
-            new Service.TablesRequest(catalog, schemaPattern.s,
+            new Service.TablesRequest(ch.id, catalog, schemaPattern.s,
                 tableNamePattern.s, typeList));
     return toResultSet(MetaTable.class, response);
   }
 
-  @Override public MetaResultSet getTableTypes() {
+  @Override public MetaResultSet getTableTypes(ConnectionHandle ch) {
     final Service.ResultSetResponse response =
-        service.apply(new Service.TableTypesRequest());
+        service.apply(new Service.TableTypesRequest(ch.id));
     return toResultSet(MetaTableType.class, response);
   }
 
-  @Override public MetaResultSet getTypeInfo() {
+  @Override public MetaResultSet getTypeInfo(ConnectionHandle ch) {
     final Service.ResultSetResponse response =
-        service.apply(new Service.TypeInfoRequest());
+        service.apply(new Service.TypeInfoRequest(ch.id));
     return toResultSet(MetaTypeInfo.class, response);
   }
 
-  @Override public MetaResultSet getColumns(String catalog, Pat schemaPattern,
+  @Override public MetaResultSet getColumns(ConnectionHandle ch, String 
catalog, Pat schemaPattern,
       Pat tableNamePattern, Pat columnNamePattern) {
     final Service.ResultSetResponse response =
         service.apply(
-            new Service.ColumnsRequest(catalog, schemaPattern.s,
+            new Service.ColumnsRequest(ch.id, catalog, schemaPattern.s,
                 tableNamePattern.s, columnNamePattern.s));
     return toResultSet(MetaColumn.class, response);
   }

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
index cb1a468..8cf0f0d 100644
--- 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
+++ 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteProtobufService.java
@@ -52,7 +52,14 @@ public class RemoteProtobufService extends ProtobufService {
       }
       final int responseCode = connection.getResponseCode();
       if (responseCode != HttpURLConnection.HTTP_OK) {
-        throw new RuntimeException("response code " + responseCode);
+        InputStream errorStream = connection.getErrorStream();
+        if (errorStream != null) {
+          byte[] errorResponse = AvaticaUtils.readFullyToBytes(errorStream);
+          ErrorResponse response = (ErrorResponse) 
translation.parseResponse(errorResponse);
+          throw new RuntimeException("Remote driver error: " + 
response.message);
+        } else {
+          throw new RuntimeException("response code " + responseCode);
+        }
       }
       final InputStream inputStream = connection.getInputStream();
       // Read the (serialized protobuf) response off the wire and convert it 
back to a Response

http://git-wip-us.apache.org/repos/asf/calcite/blob/a63639b1/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
----------------------------------------------------------------------
diff --git 
a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java 
b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
index a5896f2..298aa95 100644
--- a/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
+++ b/avatica/src/main/java/org/apache/calcite/avatica/remote/RemoteService.java
@@ -53,9 +53,16 @@ public class RemoteService extends JsonService {
           wr.close();
         }
       }
-      final int responseCode = connection.getResponseCode();
+      int responseCode = connection.getResponseCode();
       if (responseCode != HttpURLConnection.HTTP_OK) {
-        throw new RuntimeException("response code " + responseCode);
+        InputStream errorStream = connection.getErrorStream();
+        if (errorStream != null) {
+          String errorResponse = AvaticaUtils.readFully(errorStream);
+          ErrorResponse response = decode(errorResponse, ErrorResponse.class);
+          throw new RuntimeException("Remote driver error: " + 
response.message);
+        } else {
+          throw new RuntimeException("response code " + responseCode);
+        }
       }
       final InputStream inputStream = connection.getInputStream();
       return AvaticaUtils.readFully(inputStream);

Reply via email to