drill-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject [04/27] drill git commit: DRILL-4994: Add back JDBC prepared statement for older servers
Date Thu, 02 Mar 2017 20:59:31 GMT
DRILL-4994: Add back JDBC prepared statement for older servers

When the JDBC client is connected to an older Drill server, it always
attempted to use server-side prepared statement with no fallback.

With this change, client will check server version and will fallback to the
previous client-side prepared statement (which is still limited to only execute
queries and does not provide metadata).

close #613


Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/16aa0810
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/16aa0810
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/16aa0810

Branch: refs/heads/master
Commit: 16aa0810c6b5ab7466b3b7eeaf8652b765da0f89
Parents: ab60855
Author: Laurent Goujon <laurent@dremio.com>
Authored: Fri Nov 4 17:36:42 2016 -0700
Committer: Jinfeng Ni <jni@apache.org>
Committed: Wed Mar 1 23:15:30 2017 -0800

----------------------------------------------------------------------
 .../java/org/apache/drill/common/Version.java   | 157 ++++
 .../org/apache/drill/common/TestVersion.java    | 103 +++
 contrib/native/client/src/protobuf/User.pb.cc   | 415 ++++++----
 contrib/native/client/src/protobuf/User.pb.h    | 159 +++-
 .../client/src/protobuf/UserBitShared.pb.cc     | 200 +++--
 .../client/src/protobuf/UserBitShared.pb.h      |  66 +-
 .../codegen/templates/DrillVersionInfo.java     |  44 +-
 .../apache/drill/exec/client/DrillClient.java   |  50 +-
 .../apache/drill/exec/client/ServerMethod.java  | 144 ++++
 .../apache/drill/exec/rpc/user/UserClient.java  |  45 +-
 .../drill/exec/rpc/user/UserRpcConfig.java      |  18 +-
 .../drill/exec/rpc/user/UserRpcUtils.java       |  16 +
 .../apache/drill/exec/rpc/user/UserServer.java  |   3 +-
 .../drill/jdbc/DrillConnectionConfig.java       |   4 +
 .../org/apache/drill/jdbc/impl/DrillCursor.java |  11 +-
 .../jdbc/impl/DrillDatabaseMetaDataImpl.java    |  35 +-
 .../drill/jdbc/impl/DrillJdbc41Factory.java     |  26 +-
 .../jdbc/impl/DrillPreparedStatementImpl.java   |   6 +-
 .../drill/jdbc/LegacyPreparedStatementTest.java | 130 ++++
 .../drill/exec/proto/SchemaUserProtos.java      |  21 +
 .../org/apache/drill/exec/proto/UserProtos.java | 751 +++++++++++++++----
 .../exec/proto/beans/BitToUserHandshake.java    |  30 +
 .../exec/proto/beans/RpcEndpointInfos.java      |  44 ++
 protocol/src/main/protobuf/User.proto           |  15 +-
 24 files changed, 2108 insertions(+), 385 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/common/src/main/java/org/apache/drill/common/Version.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/drill/common/Version.java b/common/src/main/java/org/apache/drill/common/Version.java
new file mode 100644
index 0000000..fdd9f84
--- /dev/null
+++ b/common/src/main/java/org/apache/drill/common/Version.java
@@ -0,0 +1,157 @@
+/*
+ * 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.drill.common;
+
+import java.util.Comparator;
+import java.util.Locale;
+import java.util.Objects;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ComparisonChain;
+
+/**
+ * Encapsulates version information and provides ordering
+ *
+ */
+public final class Version implements Comparable<Version> {
+  private final String version;
+  private final int major;
+  private final int minor;
+  private final int patch;
+  private final int buildNumber;
+  private final String qualifier;
+  private final String lcQualifier; // lower-case qualifier for comparison
+
+  public Version(String version, int major, int minor, int patch, int buildNumber,
+      String qualifier) {
+    this.version = version;
+    this.major = major;
+    this.minor = minor;
+    this.patch = patch;
+    this.buildNumber = buildNumber;
+    this.qualifier = qualifier;
+    this.lcQualifier = qualifier.toLowerCase(Locale.ENGLISH);
+  }
+
+  /**
+   * Get the version string
+   *
+   * @return the version number as x.y.z
+   */
+  public String getVersion() {
+    return version;
+  }
+
+  /**
+   * Get the major version
+   *
+   * @return x if assuming the version number is x.y.z
+   */
+  public int getMajorVersion() {
+    return major;
+  }
+
+  /**
+   * Get the minor version
+   *
+   * @return y if assuming the version number is x.y.z
+   */
+  public int getMinorVersion() {
+    return minor;
+  }
+
+  /**
+   * Get the patch version
+   *
+   * @return z if assuming the version number is x.y.z(-suffix)
+   */
+  public int getPatchVersion() {
+    return patch;
+  }
+
+  /**
+   * Get the build number
+   *
+   * @return b if assuming the version number is x.y.z(.b)(-suffix)
+   */
+  public int getBuildNumber() {
+    return buildNumber;
+  }
+
+  /**
+   * Get the version qualifier
+   *
+   * @return b if assuming the version number is x.y.z(.b)(-suffix)
+   */
+  public String getQualifier() {
+    return qualifier;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(major, minor, patch, buildNumber, lcQualifier);
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (!(obj instanceof Version)) {
+      return false;
+    }
+    Version dvi = (Version) obj;
+    return this.major == dvi.major
+        && this.minor == dvi.minor
+        && this.patch == dvi.patch
+        && this.buildNumber == dvi.buildNumber
+        && Objects.equals(this.lcQualifier, dvi.lcQualifier);
+  }
+
+  @Override
+  public String toString() {
+    return String.format("Version; %s", version);
+  }
+
+  private static final Comparator<String> QUALIFIER_COMPARATOR = new Comparator<String>() {
+    @Override public int compare(String q1, String q2) {
+      if (q1.equals(q2)) {
+        return 0;
+      }
+
+      if ("snapshot".equals(q1)) {
+        return -1;
+      }
+
+      if ("snapshot".equals(q2)) {
+        return 1;
+      }
+
+      return q1.compareTo(q2);
+    }
+  };
+
+  @Override
+  public int compareTo(Version o) {
+    Preconditions.checkNotNull(o);
+    return ComparisonChain.start()
+        .compare(this.major, o.major)
+        .compare(this.minor, o.minor)
+        .compare(this.patch, o.patch)
+        .compare(this.buildNumber, o.buildNumber)
+        .compare(this.lcQualifier, o.lcQualifier, QUALIFIER_COMPARATOR)
+        .result();
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/common/src/test/java/org/apache/drill/common/TestVersion.java
----------------------------------------------------------------------
diff --git a/common/src/test/java/org/apache/drill/common/TestVersion.java b/common/src/test/java/org/apache/drill/common/TestVersion.java
new file mode 100644
index 0000000..cabacb3
--- /dev/null
+++ b/common/src/test/java/org/apache/drill/common/TestVersion.java
@@ -0,0 +1,103 @@
+/*
+ * 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.drill.common;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Test class for {@code Version}
+ *
+ */
+public class TestVersion {
+
+  @Test
+  public void testSnapshotVersion() {
+    Version version = new Version("1.2.3-SNAPSHOT", 1, 2, 3, 0, "SNAPSHOT");
+
+    assertEquals("1.2.3-SNAPSHOT", version.getVersion());
+    assertEquals(1, version.getMajorVersion());
+    assertEquals(2, version.getMinorVersion());
+    assertEquals(3, version.getPatchVersion());
+    assertEquals(0, version.getBuildNumber());
+    assertEquals("SNAPSHOT", version.getQualifier());
+  }
+
+  @Test
+  public void testReleaseVersion() {
+    Version version = new Version("2.1.4", 2, 1, 4, 0, "");
+
+    assertEquals("2.1.4", version.getVersion());
+    assertEquals(2, version.getMajorVersion());
+    assertEquals(1, version.getMinorVersion());
+    assertEquals(4, version.getPatchVersion());
+    assertEquals(0, version.getBuildNumber());
+    assertEquals("", version.getQualifier());
+  }
+
+  @Test
+  public void testBuildNumberVersion() {
+    Version version = new Version("3.1.5-2-BUGFIX", 3, 1, 5, 2, "BUGFIX");
+
+    assertEquals("3.1.5-2-BUGFIX", version.getVersion());
+    assertEquals(3, version.getMajorVersion());
+    assertEquals(1, version.getMinorVersion());
+    assertEquals(5, version.getPatchVersion());
+    assertEquals(2, version.getBuildNumber());
+    assertEquals("BUGFIX", version.getQualifier());
+  }
+
+  private final Version v1 = new Version("1.2.3-SNAPSHOT", 1, 2, 3, 0, "SNAPSHOT");
+  private final Version v2 = new Version("2.1.4", 2, 1, 4, 0, "");
+  private final Version v3 = new Version("3.1.5-2-BUGFIX", 3, 1, 5, 2, "BUGFIX");
+  private final Version v4 = new Version("1.2.3-snapshot", 1, 2, 3, 0, "snapshot");
+  private final Version v5 = new Version("1.2.3", 1, 2, 3, 0, "");
+
+  @Test
+  public void testEquals() {
+    assertEquals(v1, v1);
+    assertNotEquals(v1, v2);
+    assertNotEquals(v1, v3);
+    assertEquals(v1, v4);
+    assertNotEquals(v1, v5);
+    assertNotEquals(v1, null);
+    assertNotEquals(v1, new Object());
+  }
+
+  @Test
+  public void testHashcode() {
+    assertEquals(v1.hashCode(), v1.hashCode());
+    assertNotEquals(v1.hashCode(), v2.hashCode());
+    assertNotEquals(v1.hashCode(), v3.hashCode());
+    assertEquals(v1.hashCode(), v4.hashCode());
+    assertNotEquals(v1.hashCode(), v5.hashCode());
+  }
+
+  @Test
+  public void testCompareTo() {
+    assertTrue(v1.compareTo(v1) == 0);
+    assertTrue(v1.compareTo(v2) < 0);
+    assertTrue(v1.compareTo(v3) < 0);
+    assertTrue(v1.compareTo(v4) == 0);
+    assertTrue(v1.compareTo(v5) < 0);
+    assertTrue(v1.compareTo(new Version("1.2", 1, 2, 0, 0, "")) > 0);
+  }
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/contrib/native/client/src/protobuf/User.pb.cc
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/protobuf/User.pb.cc b/contrib/native/client/src/protobuf/User.pb.cc
index a292b38..aee70b8 100644
--- a/contrib/native/client/src/protobuf/User.pb.cc
+++ b/contrib/native/client/src/protobuf/User.pb.cc
@@ -151,13 +151,15 @@ void protobuf_AssignDesc_User_2eproto() {
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(UserProperties));
   RpcEndpointInfos_descriptor_ = file->message_type(2);
-  static const int RpcEndpointInfos_offsets_[6] = {
+  static const int RpcEndpointInfos_offsets_[8] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, name_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, version_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, majorversion_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, minorversion_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, patchversion_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, application_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, buildnumber_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(RpcEndpointInfos, versionqualifier_),
   };
   RpcEndpointInfos_reflection_ =
     new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -245,13 +247,14 @@ void protobuf_AssignDesc_User_2eproto() {
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(QueryPlanFragments));
   BitToUserHandshake_descriptor_ = file->message_type(7);
-  static const int BitToUserHandshake_offsets_[6] = {
+  static const int BitToUserHandshake_offsets_[7] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, rpc_version_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, status_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, errorid_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, errormessage_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, server_infos_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, authenticationmechanisms_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BitToUserHandshake, supported_methods_),
   };
   BitToUserHandshake_reflection_ =
     new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -766,136 +769,138 @@ void protobuf_AddDesc_User_2eproto() {
     "tControl.proto\032\025ExecutionProtos.proto\"&\n"
     "\010Property\022\013\n\003key\030\001 \002(\t\022\r\n\005value\030\002 \002(\t\"9\n"
     "\016UserProperties\022\'\n\nproperties\030\001 \003(\0132\023.ex"
-    "ec.user.Property\"\210\001\n\020RpcEndpointInfos\022\014\n"
+    "ec.user.Property\"\267\001\n\020RpcEndpointInfos\022\014\n"
     "\004name\030\001 \001(\t\022\017\n\007version\030\002 \001(\t\022\024\n\014majorVer"
     "sion\030\003 \001(\r\022\024\n\014minorVersion\030\004 \001(\r\022\024\n\014patc"
-    "hVersion\030\005 \001(\r\022\023\n\013application\030\006 \001(\t\"\375\002\n\022"
-    "UserToBitHandshake\022.\n\007channel\030\001 \001(\0162\027.ex"
-    "ec.shared.RpcChannel:\004USER\022\031\n\021support_li"
-    "stening\030\002 \001(\010\022\023\n\013rpc_version\030\003 \001(\005\0221\n\013cr"
-    "edentials\030\004 \001(\0132\034.exec.shared.UserCreden"
-    "tials\022-\n\nproperties\030\005 \001(\0132\031.exec.user.Us"
-    "erProperties\022$\n\025support_complex_types\030\006 "
-    "\001(\010:\005false\022\036\n\017support_timeout\030\007 \001(\010:\005fal"
-    "se\0221\n\014client_infos\030\010 \001(\0132\033.exec.user.Rpc"
-    "EndpointInfos\022,\n\014sasl_support\030\t \001(\0162\026.ex"
-    "ec.user.SaslSupport\"S\n\016RequestResults\022&\n"
-    "\010query_id\030\001 \001(\0132\024.exec.shared.QueryId\022\031\n"
-    "\021maximum_responses\030\002 \001(\005\"g\n\025GetQueryPlan"
-    "Fragments\022\r\n\005query\030\001 \002(\t\022$\n\004type\030\002 \001(\0162\026"
-    ".exec.shared.QueryType\022\031\n\nsplit_plan\030\003 \001"
-    "(\010:\005false\"\316\001\n\022QueryPlanFragments\0223\n\006stat"
-    "us\030\001 \002(\0162#.exec.shared.QueryResult.Query"
-    "State\022&\n\010query_id\030\002 \001(\0132\024.exec.shared.Qu"
-    "eryId\0221\n\tfragments\030\003 \003(\0132\036.exec.bit.cont"
-    "rol.PlanFragment\022(\n\005error\030\004 \001(\0132\031.exec.s"
-    "hared.DrillPBError\"\321\001\n\022BitToUserHandshak"
-    "e\022\023\n\013rpc_version\030\002 \001(\005\022*\n\006status\030\003 \001(\0162\032"
-    ".exec.user.HandshakeStatus\022\017\n\007errorId\030\004 "
-    "\001(\t\022\024\n\014errorMessage\030\005 \001(\t\0221\n\014server_info"
-    "s\030\006 \001(\0132\033.exec.user.RpcEndpointInfos\022 \n\030"
-    "authenticationMechanisms\030\007 \003(\t\"-\n\nLikeFi"
-    "lter\022\017\n\007pattern\030\001 \001(\t\022\016\n\006escape\030\002 \001(\t\"D\n"
-    "\016GetCatalogsReq\0222\n\023catalog_name_filter\030\001"
-    " \001(\0132\025.exec.user.LikeFilter\"M\n\017CatalogMe"
-    "tadata\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013descript"
-    "ion\030\002 \001(\t\022\017\n\007connect\030\003 \001(\t\"\223\001\n\017GetCatalo"
-    "gsResp\022(\n\006status\030\001 \001(\0162\030.exec.user.Reque"
-    "stStatus\022,\n\010catalogs\030\002 \003(\0132\032.exec.user.C"
-    "atalogMetadata\022(\n\005error\030\003 \001(\0132\031.exec.sha"
-    "red.DrillPBError\"v\n\rGetSchemasReq\0222\n\023cat"
-    "alog_name_filter\030\001 \001(\0132\025.exec.user.LikeF"
-    "ilter\0221\n\022schema_name_filter\030\002 \001(\0132\025.exec"
-    ".user.LikeFilter\"i\n\016SchemaMetadata\022\024\n\014ca"
-    "talog_name\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\r\n"
-    "\005owner\030\003 \001(\t\022\014\n\004type\030\004 \001(\t\022\017\n\007mutable\030\005 "
-    "\001(\t\"\220\001\n\016GetSchemasResp\022(\n\006status\030\001 \001(\0162\030"
-    ".exec.user.RequestStatus\022*\n\007schemas\030\002 \003("
-    "\0132\031.exec.user.SchemaMetadata\022(\n\005error\030\003 "
-    "\001(\0132\031.exec.shared.DrillPBError\"\302\001\n\014GetTa"
-    "blesReq\0222\n\023catalog_name_filter\030\001 \001(\0132\025.e"
+    "hVersion\030\005 \001(\r\022\023\n\013application\030\006 \001(\t\022\023\n\013b"
+    "uildNumber\030\007 \001(\r\022\030\n\020versionQualifier\030\010 \001"
+    "(\t\"\375\002\n\022UserToBitHandshake\022.\n\007channel\030\001 \001"
+    "(\0162\027.exec.shared.RpcChannel:\004USER\022\031\n\021sup"
+    "port_listening\030\002 \001(\010\022\023\n\013rpc_version\030\003 \001("
+    "\005\0221\n\013credentials\030\004 \001(\0132\034.exec.shared.Use"
+    "rCredentials\022-\n\nproperties\030\005 \001(\0132\031.exec."
+    "user.UserProperties\022$\n\025support_complex_t"
+    "ypes\030\006 \001(\010:\005false\022\036\n\017support_timeout\030\007 \001"
+    "(\010:\005false\0221\n\014client_infos\030\010 \001(\0132\033.exec.u"
+    "ser.RpcEndpointInfos\022,\n\014sasl_support\030\t \001"
+    "(\0162\026.exec.user.SaslSupport\"S\n\016RequestRes"
+    "ults\022&\n\010query_id\030\001 \001(\0132\024.exec.shared.Que"
+    "ryId\022\031\n\021maximum_responses\030\002 \001(\005\"g\n\025GetQu"
+    "eryPlanFragments\022\r\n\005query\030\001 \002(\t\022$\n\004type\030"
+    "\002 \001(\0162\026.exec.shared.QueryType\022\031\n\nsplit_p"
+    "lan\030\003 \001(\010:\005false\"\316\001\n\022QueryPlanFragments\022"
+    "3\n\006status\030\001 \002(\0162#.exec.shared.QueryResul"
+    "t.QueryState\022&\n\010query_id\030\002 \001(\0132\024.exec.sh"
+    "ared.QueryId\0221\n\tfragments\030\003 \003(\0132\036.exec.b"
+    "it.control.PlanFragment\022(\n\005error\030\004 \001(\0132\031"
+    ".exec.shared.DrillPBError\"\200\002\n\022BitToUserH"
+    "andshake\022\023\n\013rpc_version\030\002 \001(\005\022*\n\006status\030"
+    "\003 \001(\0162\032.exec.user.HandshakeStatus\022\017\n\007err"
+    "orId\030\004 \001(\t\022\024\n\014errorMessage\030\005 \001(\t\0221\n\014serv"
+    "er_infos\030\006 \001(\0132\033.exec.user.RpcEndpointIn"
+    "fos\022 \n\030authenticationMechanisms\030\007 \003(\t\022-\n"
+    "\021supported_methods\030\010 \003(\0162\022.exec.user.Rpc"
+    "Type\"-\n\nLikeFilter\022\017\n\007pattern\030\001 \001(\t\022\016\n\006e"
+    "scape\030\002 \001(\t\"D\n\016GetCatalogsReq\0222\n\023catalog"
+    "_name_filter\030\001 \001(\0132\025.exec.user.LikeFilte"
+    "r\"M\n\017CatalogMetadata\022\024\n\014catalog_name\030\001 \001"
+    "(\t\022\023\n\013description\030\002 \001(\t\022\017\n\007connect\030\003 \001(\t"
+    "\"\223\001\n\017GetCatalogsResp\022(\n\006status\030\001 \001(\0162\030.e"
+    "xec.user.RequestStatus\022,\n\010catalogs\030\002 \003(\013"
+    "2\032.exec.user.CatalogMetadata\022(\n\005error\030\003 "
+    "\001(\0132\031.exec.shared.DrillPBError\"v\n\rGetSch"
+    "emasReq\0222\n\023catalog_name_filter\030\001 \001(\0132\025.e"
     "xec.user.LikeFilter\0221\n\022schema_name_filte"
-    "r\030\002 \001(\0132\025.exec.user.LikeFilter\0220\n\021table_"
-    "name_filter\030\003 \001(\0132\025.exec.user.LikeFilter"
-    "\022\031\n\021table_type_filter\030\004 \003(\t\"\\\n\rTableMeta"
-    "data\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013schema_nam"
-    "e\030\002 \001(\t\022\022\n\ntable_name\030\003 \001(\t\022\014\n\004type\030\004 \001("
-    "\t\"\215\001\n\rGetTablesResp\022(\n\006status\030\001 \001(\0162\030.ex"
-    "ec.user.RequestStatus\022(\n\006tables\030\002 \003(\0132\030."
-    "exec.user.TableMetadata\022(\n\005error\030\003 \001(\0132\031"
-    ".exec.shared.DrillPBError\"\333\001\n\rGetColumns"
-    "Req\0222\n\023catalog_name_filter\030\001 \001(\0132\025.exec."
-    "user.LikeFilter\0221\n\022schema_name_filter\030\002 "
-    "\001(\0132\025.exec.user.LikeFilter\0220\n\021table_name"
-    "_filter\030\003 \001(\0132\025.exec.user.LikeFilter\0221\n\022"
-    "column_name_filter\030\004 \001(\0132\025.exec.user.Lik"
-    "eFilter\"\251\003\n\016ColumnMetadata\022\024\n\014catalog_na"
-    "me\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\022\n\ntable_n"
-    "ame\030\003 \001(\t\022\023\n\013column_name\030\004 \001(\t\022\030\n\020ordina"
-    "l_position\030\005 \001(\005\022\025\n\rdefault_value\030\006 \001(\t\022"
-    "\023\n\013is_nullable\030\007 \001(\010\022\021\n\tdata_type\030\010 \001(\t\022"
-    "\027\n\017char_max_length\030\t \001(\005\022\031\n\021char_octet_l"
-    "ength\030\n \001(\005\022\031\n\021numeric_precision\030\013 \001(\005\022\037"
-    "\n\027numeric_precision_radix\030\014 \001(\005\022\025\n\rnumer"
-    "ic_scale\030\r \001(\005\022\033\n\023date_time_precision\030\016 "
-    "\001(\005\022\025\n\rinterval_type\030\017 \001(\t\022\032\n\022interval_p"
-    "recision\030\020 \001(\005\022\023\n\013column_size\030\021 \001(\005\"\220\001\n\016"
-    "GetColumnsResp\022(\n\006status\030\001 \001(\0162\030.exec.us"
-    "er.RequestStatus\022*\n\007columns\030\002 \003(\0132\031.exec"
-    ".user.ColumnMetadata\022(\n\005error\030\003 \001(\0132\031.ex"
-    "ec.shared.DrillPBError\"/\n\032CreatePrepared"
-    "StatementReq\022\021\n\tsql_query\030\001 \001(\t\"\326\003\n\024Resu"
-    "ltColumnMetadata\022\024\n\014catalog_name\030\001 \001(\t\022\023"
-    "\n\013schema_name\030\002 \001(\t\022\022\n\ntable_name\030\003 \001(\t\022"
-    "\023\n\013column_name\030\004 \001(\t\022\r\n\005label\030\005 \001(\t\022\021\n\td"
-    "ata_type\030\006 \001(\t\022\023\n\013is_nullable\030\007 \001(\010\022\021\n\tp"
-    "recision\030\010 \001(\005\022\r\n\005scale\030\t \001(\005\022\016\n\006signed\030"
-    "\n \001(\010\022\024\n\014display_size\030\013 \001(\005\022\022\n\nis_aliase"
-    "d\030\014 \001(\010\0225\n\rsearchability\030\r \001(\0162\036.exec.us"
-    "er.ColumnSearchability\0223\n\014updatability\030\016"
-    " \001(\0162\035.exec.user.ColumnUpdatability\022\026\n\016a"
-    "uto_increment\030\017 \001(\010\022\030\n\020case_sensitivity\030"
-    "\020 \001(\010\022\020\n\010sortable\030\021 \001(\010\022\022\n\nclass_name\030\022 "
-    "\001(\t\022\023\n\013is_currency\030\024 \001(\010\".\n\027PreparedStat"
-    "ementHandle\022\023\n\013server_info\030\001 \001(\014\"\200\001\n\021Pre"
-    "paredStatement\0220\n\007columns\030\001 \003(\0132\037.exec.u"
-    "ser.ResultColumnMetadata\0229\n\rserver_handl"
-    "e\030\002 \001(\0132\".exec.user.PreparedStatementHan"
-    "dle\"\253\001\n\033CreatePreparedStatementResp\022(\n\006s"
-    "tatus\030\001 \001(\0162\030.exec.user.RequestStatus\0228\n"
-    "\022prepared_statement\030\002 \001(\0132\034.exec.user.Pr"
-    "eparedStatement\022(\n\005error\030\003 \001(\0132\031.exec.sh"
-    "ared.DrillPBError\"\353\001\n\010RunQuery\0221\n\014result"
-    "s_mode\030\001 \001(\0162\033.exec.user.QueryResultsMod"
-    "e\022$\n\004type\030\002 \001(\0162\026.exec.shared.QueryType\022"
-    "\014\n\004plan\030\003 \001(\t\0221\n\tfragments\030\004 \003(\0132\036.exec."
-    "bit.control.PlanFragment\022E\n\031prepared_sta"
-    "tement_handle\030\005 \001(\0132\".exec.user.Prepared"
-    "StatementHandle*\332\003\n\007RpcType\022\r\n\tHANDSHAKE"
-    "\020\000\022\007\n\003ACK\020\001\022\013\n\007GOODBYE\020\002\022\r\n\tRUN_QUERY\020\003\022"
-    "\020\n\014CANCEL_QUERY\020\004\022\023\n\017REQUEST_RESULTS\020\005\022\027"
-    "\n\023RESUME_PAUSED_QUERY\020\013\022\034\n\030GET_QUERY_PLA"
-    "N_FRAGMENTS\020\014\022\020\n\014GET_CATALOGS\020\016\022\017\n\013GET_S"
-    "CHEMAS\020\017\022\016\n\nGET_TABLES\020\020\022\017\n\013GET_COLUMNS\020"
-    "\021\022\035\n\031CREATE_PREPARED_STATEMENT\020\026\022\016\n\nQUER"
-    "Y_DATA\020\006\022\020\n\014QUERY_HANDLE\020\007\022\030\n\024QUERY_PLAN"
-    "_FRAGMENTS\020\r\022\014\n\010CATALOGS\020\022\022\013\n\007SCHEMAS\020\023\022"
-    "\n\n\006TABLES\020\024\022\013\n\007COLUMNS\020\025\022\026\n\022PREPARED_STA"
-    "TEMENT\020\027\022\026\n\022REQ_META_FUNCTIONS\020\010\022\026\n\022RESP"
-    "_FUNCTION_LIST\020\t\022\020\n\014QUERY_RESULT\020\n\022\020\n\014SA"
-    "SL_MESSAGE\020\030*6\n\013SaslSupport\022\030\n\024UNKNOWN_S"
-    "ASL_SUPPORT\020\000\022\r\n\tSASL_AUTH\020\001*#\n\020QueryRes"
-    "ultsMode\022\017\n\013STREAM_FULL\020\001*q\n\017HandshakeSt"
-    "atus\022\013\n\007SUCCESS\020\001\022\030\n\024RPC_VERSION_MISMATC"
-    "H\020\002\022\017\n\013AUTH_FAILED\020\003\022\023\n\017UNKNOWN_FAILURE\020"
-    "\004\022\021\n\rAUTH_REQUIRED\020\005*D\n\rRequestStatus\022\022\n"
-    "\016UNKNOWN_STATUS\020\000\022\006\n\002OK\020\001\022\n\n\006FAILED\020\002\022\013\n"
-    "\007TIMEOUT\020\003*Y\n\023ColumnSearchability\022\031\n\025UNK"
-    "NOWN_SEARCHABILITY\020\000\022\010\n\004NONE\020\001\022\010\n\004CHAR\020\002"
-    "\022\n\n\006NUMBER\020\003\022\007\n\003ALL\020\004*K\n\022ColumnUpdatabil"
-    "ity\022\030\n\024UNKNOWN_UPDATABILITY\020\000\022\r\n\tREAD_ON"
-    "LY\020\001\022\014\n\010WRITABLE\020\002B+\n\033org.apache.drill.e"
-    "xec.protoB\nUserProtosH\001", 5383);
+    "r\030\002 \001(\0132\025.exec.user.LikeFilter\"i\n\016Schema"
+    "Metadata\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013schema"
+    "_name\030\002 \001(\t\022\r\n\005owner\030\003 \001(\t\022\014\n\004type\030\004 \001(\t"
+    "\022\017\n\007mutable\030\005 \001(\t\"\220\001\n\016GetSchemasResp\022(\n\006"
+    "status\030\001 \001(\0162\030.exec.user.RequestStatus\022*"
+    "\n\007schemas\030\002 \003(\0132\031.exec.user.SchemaMetada"
+    "ta\022(\n\005error\030\003 \001(\0132\031.exec.shared.DrillPBE"
+    "rror\"\302\001\n\014GetTablesReq\0222\n\023catalog_name_fi"
+    "lter\030\001 \001(\0132\025.exec.user.LikeFilter\0221\n\022sch"
+    "ema_name_filter\030\002 \001(\0132\025.exec.user.LikeFi"
+    "lter\0220\n\021table_name_filter\030\003 \001(\0132\025.exec.u"
+    "ser.LikeFilter\022\031\n\021table_type_filter\030\004 \003("
+    "\t\"\\\n\rTableMetadata\022\024\n\014catalog_name\030\001 \001(\t"
+    "\022\023\n\013schema_name\030\002 \001(\t\022\022\n\ntable_name\030\003 \001("
+    "\t\022\014\n\004type\030\004 \001(\t\"\215\001\n\rGetTablesResp\022(\n\006sta"
+    "tus\030\001 \001(\0162\030.exec.user.RequestStatus\022(\n\006t"
+    "ables\030\002 \003(\0132\030.exec.user.TableMetadata\022(\n"
+    "\005error\030\003 \001(\0132\031.exec.shared.DrillPBError\""
+    "\333\001\n\rGetColumnsReq\0222\n\023catalog_name_filter"
+    "\030\001 \001(\0132\025.exec.user.LikeFilter\0221\n\022schema_"
+    "name_filter\030\002 \001(\0132\025.exec.user.LikeFilter"
+    "\0220\n\021table_name_filter\030\003 \001(\0132\025.exec.user."
+    "LikeFilter\0221\n\022column_name_filter\030\004 \001(\0132\025"
+    ".exec.user.LikeFilter\"\251\003\n\016ColumnMetadata"
+    "\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013schema_name\030\002 "
+    "\001(\t\022\022\n\ntable_name\030\003 \001(\t\022\023\n\013column_name\030\004"
+    " \001(\t\022\030\n\020ordinal_position\030\005 \001(\005\022\025\n\rdefaul"
+    "t_value\030\006 \001(\t\022\023\n\013is_nullable\030\007 \001(\010\022\021\n\tda"
+    "ta_type\030\010 \001(\t\022\027\n\017char_max_length\030\t \001(\005\022\031"
+    "\n\021char_octet_length\030\n \001(\005\022\031\n\021numeric_pre"
+    "cision\030\013 \001(\005\022\037\n\027numeric_precision_radix\030"
+    "\014 \001(\005\022\025\n\rnumeric_scale\030\r \001(\005\022\033\n\023date_tim"
+    "e_precision\030\016 \001(\005\022\025\n\rinterval_type\030\017 \001(\t"
+    "\022\032\n\022interval_precision\030\020 \001(\005\022\023\n\013column_s"
+    "ize\030\021 \001(\005\"\220\001\n\016GetColumnsResp\022(\n\006status\030\001"
+    " \001(\0162\030.exec.user.RequestStatus\022*\n\007column"
+    "s\030\002 \003(\0132\031.exec.user.ColumnMetadata\022(\n\005er"
+    "ror\030\003 \001(\0132\031.exec.shared.DrillPBError\"/\n\032"
+    "CreatePreparedStatementReq\022\021\n\tsql_query\030"
+    "\001 \001(\t\"\326\003\n\024ResultColumnMetadata\022\024\n\014catalo"
+    "g_name\030\001 \001(\t\022\023\n\013schema_name\030\002 \001(\t\022\022\n\ntab"
+    "le_name\030\003 \001(\t\022\023\n\013column_name\030\004 \001(\t\022\r\n\005la"
+    "bel\030\005 \001(\t\022\021\n\tdata_type\030\006 \001(\t\022\023\n\013is_nulla"
+    "ble\030\007 \001(\010\022\021\n\tprecision\030\010 \001(\005\022\r\n\005scale\030\t "
+    "\001(\005\022\016\n\006signed\030\n \001(\010\022\024\n\014display_size\030\013 \001("
+    "\005\022\022\n\nis_aliased\030\014 \001(\010\0225\n\rsearchability\030\r"
+    " \001(\0162\036.exec.user.ColumnSearchability\0223\n\014"
+    "updatability\030\016 \001(\0162\035.exec.user.ColumnUpd"
+    "atability\022\026\n\016auto_increment\030\017 \001(\010\022\030\n\020cas"
+    "e_sensitivity\030\020 \001(\010\022\020\n\010sortable\030\021 \001(\010\022\022\n"
+    "\nclass_name\030\022 \001(\t\022\023\n\013is_currency\030\024 \001(\010\"."
+    "\n\027PreparedStatementHandle\022\023\n\013server_info"
+    "\030\001 \001(\014\"\200\001\n\021PreparedStatement\0220\n\007columns\030"
+    "\001 \003(\0132\037.exec.user.ResultColumnMetadata\0229"
+    "\n\rserver_handle\030\002 \001(\0132\".exec.user.Prepar"
+    "edStatementHandle\"\253\001\n\033CreatePreparedStat"
+    "ementResp\022(\n\006status\030\001 \001(\0162\030.exec.user.Re"
+    "questStatus\0228\n\022prepared_statement\030\002 \001(\0132"
+    "\034.exec.user.PreparedStatement\022(\n\005error\030\003"
+    " \001(\0132\031.exec.shared.DrillPBError\"\353\001\n\010RunQ"
+    "uery\0221\n\014results_mode\030\001 \001(\0162\033.exec.user.Q"
+    "ueryResultsMode\022$\n\004type\030\002 \001(\0162\026.exec.sha"
+    "red.QueryType\022\014\n\004plan\030\003 \001(\t\0221\n\tfragments"
+    "\030\004 \003(\0132\036.exec.bit.control.PlanFragment\022E"
+    "\n\031prepared_statement_handle\030\005 \001(\0132\".exec"
+    ".user.PreparedStatementHandle*\332\003\n\007RpcTyp"
+    "e\022\r\n\tHANDSHAKE\020\000\022\007\n\003ACK\020\001\022\013\n\007GOODBYE\020\002\022\r"
+    "\n\tRUN_QUERY\020\003\022\020\n\014CANCEL_QUERY\020\004\022\023\n\017REQUE"
+    "ST_RESULTS\020\005\022\027\n\023RESUME_PAUSED_QUERY\020\013\022\034\n"
+    "\030GET_QUERY_PLAN_FRAGMENTS\020\014\022\020\n\014GET_CATAL"
+    "OGS\020\016\022\017\n\013GET_SCHEMAS\020\017\022\016\n\nGET_TABLES\020\020\022\017"
+    "\n\013GET_COLUMNS\020\021\022\035\n\031CREATE_PREPARED_STATE"
+    "MENT\020\026\022\016\n\nQUERY_DATA\020\006\022\020\n\014QUERY_HANDLE\020\007"
+    "\022\030\n\024QUERY_PLAN_FRAGMENTS\020\r\022\014\n\010CATALOGS\020\022"
+    "\022\013\n\007SCHEMAS\020\023\022\n\n\006TABLES\020\024\022\013\n\007COLUMNS\020\025\022\026"
+    "\n\022PREPARED_STATEMENT\020\027\022\026\n\022REQ_META_FUNCT"
+    "IONS\020\010\022\026\n\022RESP_FUNCTION_LIST\020\t\022\020\n\014QUERY_"
+    "RESULT\020\n\022\020\n\014SASL_MESSAGE\020\030*6\n\013SaslSuppor"
+    "t\022\030\n\024UNKNOWN_SASL_SUPPORT\020\000\022\r\n\tSASL_AUTH"
+    "\020\001*#\n\020QueryResultsMode\022\017\n\013STREAM_FULL\020\001*"
+    "q\n\017HandshakeStatus\022\013\n\007SUCCESS\020\001\022\030\n\024RPC_V"
+    "ERSION_MISMATCH\020\002\022\017\n\013AUTH_FAILED\020\003\022\023\n\017UN"
+    "KNOWN_FAILURE\020\004\022\021\n\rAUTH_REQUIRED\020\005*D\n\rRe"
+    "questStatus\022\022\n\016UNKNOWN_STATUS\020\000\022\006\n\002OK\020\001\022"
+    "\n\n\006FAILED\020\002\022\013\n\007TIMEOUT\020\003*Y\n\023ColumnSearch"
+    "ability\022\031\n\025UNKNOWN_SEARCHABILITY\020\000\022\010\n\004NO"
+    "NE\020\001\022\010\n\004CHAR\020\002\022\n\n\006NUMBER\020\003\022\007\n\003ALL\020\004*K\n\022C"
+    "olumnUpdatability\022\030\n\024UNKNOWN_UPDATABILIT"
+    "Y\020\000\022\r\n\tREAD_ONLY\020\001\022\014\n\010WRITABLE\020\002B+\n\033org."
+    "apache.drill.exec.protoB\nUserProtosH\001", 5477);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "User.proto", &protobuf_RegisterTypes);
   Property::default_instance_ = new Property();
@@ -1589,6 +1594,8 @@ const int RpcEndpointInfos::kMajorVersionFieldNumber;
 const int RpcEndpointInfos::kMinorVersionFieldNumber;
 const int RpcEndpointInfos::kPatchVersionFieldNumber;
 const int RpcEndpointInfos::kApplicationFieldNumber;
+const int RpcEndpointInfos::kBuildNumberFieldNumber;
+const int RpcEndpointInfos::kVersionQualifierFieldNumber;
 #endif  // !_MSC_VER
 
 RpcEndpointInfos::RpcEndpointInfos()
@@ -1613,6 +1620,8 @@ void RpcEndpointInfos::SharedCtor() {
   minorversion_ = 0u;
   patchversion_ = 0u;
   application_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+  buildnumber_ = 0u;
+  versionqualifier_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
@@ -1630,6 +1639,9 @@ void RpcEndpointInfos::SharedDtor() {
   if (application_ != &::google::protobuf::internal::kEmptyString) {
     delete application_;
   }
+  if (versionqualifier_ != &::google::protobuf::internal::kEmptyString) {
+    delete versionqualifier_;
+  }
   if (this != default_instance_) {
   }
 }
@@ -1675,6 +1687,12 @@ void RpcEndpointInfos::Clear() {
         application_->clear();
       }
     }
+    buildnumber_ = 0u;
+    if (has_versionqualifier()) {
+      if (versionqualifier_ != &::google::protobuf::internal::kEmptyString) {
+        versionqualifier_->clear();
+      }
+    }
   }
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   mutable_unknown_fields()->Clear();
@@ -1780,6 +1798,39 @@ bool RpcEndpointInfos::MergePartialFromCodedStream(
         } else {
           goto handle_uninterpreted;
         }
+        if (input->ExpectTag(56)) goto parse_buildNumber;
+        break;
+      }
+
+      // optional uint32 buildNumber = 7;
+      case 7: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_buildNumber:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &buildnumber_)));
+          set_has_buildnumber();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(66)) goto parse_versionQualifier;
+        break;
+      }
+
+      // optional string versionQualifier = 8;
+      case 8: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_versionQualifier:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_versionqualifier()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+            this->versionqualifier().data(), this->versionqualifier().length(),
+            ::google::protobuf::internal::WireFormat::PARSE);
+        } else {
+          goto handle_uninterpreted;
+        }
         if (input->ExpectAtEnd()) return true;
         break;
       }
@@ -1844,6 +1895,20 @@ void RpcEndpointInfos::SerializeWithCachedSizes(
       6, this->application(), output);
   }
 
+  // optional uint32 buildNumber = 7;
+  if (has_buildnumber()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->buildnumber(), output);
+  }
+
+  // optional string versionQualifier = 8;
+  if (has_versionqualifier()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+      this->versionqualifier().data(), this->versionqualifier().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE);
+    ::google::protobuf::internal::WireFormatLite::WriteString(
+      8, this->versionqualifier(), output);
+  }
+
   if (!unknown_fields().empty()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
@@ -1897,6 +1962,21 @@ void RpcEndpointInfos::SerializeWithCachedSizes(
         6, this->application(), target);
   }
 
+  // optional uint32 buildNumber = 7;
+  if (has_buildnumber()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->buildnumber(), target);
+  }
+
+  // optional string versionQualifier = 8;
+  if (has_versionqualifier()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
+      this->versionqualifier().data(), this->versionqualifier().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE);
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        8, this->versionqualifier(), target);
+  }
+
   if (!unknown_fields().empty()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
@@ -1950,6 +2030,20 @@ int RpcEndpointInfos::ByteSize() const {
           this->application());
     }
 
+    // optional uint32 buildNumber = 7;
+    if (has_buildnumber()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt32Size(
+          this->buildnumber());
+    }
+
+    // optional string versionQualifier = 8;
+    if (has_versionqualifier()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->versionqualifier());
+    }
+
   }
   if (!unknown_fields().empty()) {
     total_size +=
@@ -1995,6 +2089,12 @@ void RpcEndpointInfos::MergeFrom(const RpcEndpointInfos& from) {
     if (from.has_application()) {
       set_application(from.application());
     }
+    if (from.has_buildnumber()) {
+      set_buildnumber(from.buildnumber());
+    }
+    if (from.has_versionqualifier()) {
+      set_versionqualifier(from.versionqualifier());
+    }
   }
   mutable_unknown_fields()->MergeFrom(from.unknown_fields());
 }
@@ -2024,6 +2124,8 @@ void RpcEndpointInfos::Swap(RpcEndpointInfos* other) {
     std::swap(minorversion_, other->minorversion_);
     std::swap(patchversion_, other->patchversion_);
     std::swap(application_, other->application_);
+    std::swap(buildnumber_, other->buildnumber_);
+    std::swap(versionqualifier_, other->versionqualifier_);
     std::swap(_has_bits_[0], other->_has_bits_[0]);
     _unknown_fields_.Swap(&other->_unknown_fields_);
     std::swap(_cached_size_, other->_cached_size_);
@@ -3514,6 +3616,7 @@ const int BitToUserHandshake::kErrorIdFieldNumber;
 const int BitToUserHandshake::kErrorMessageFieldNumber;
 const int BitToUserHandshake::kServerInfosFieldNumber;
 const int BitToUserHandshake::kAuthenticationMechanismsFieldNumber;
+const int BitToUserHandshake::kSupportedMethodsFieldNumber;
 #endif  // !_MSC_VER
 
 BitToUserHandshake::BitToUserHandshake()
@@ -3597,6 +3700,7 @@ void BitToUserHandshake::Clear() {
     }
   }
   authenticationmechanisms_.Clear();
+  supported_methods_.Clear();
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   mutable_unknown_fields()->Clear();
 }
@@ -3706,6 +3810,35 @@ bool BitToUserHandshake::MergePartialFromCodedStream(
           goto handle_uninterpreted;
         }
         if (input->ExpectTag(58)) goto parse_authenticationMechanisms;
+        if (input->ExpectTag(64)) goto parse_supported_methods;
+        break;
+      }
+
+      // repeated .exec.user.RpcType supported_methods = 8;
+      case 8: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_supported_methods:
+          int value;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          if (::exec::user::RpcType_IsValid(value)) {
+            add_supported_methods(static_cast< ::exec::user::RpcType >(value));
+          } else {
+            mutable_unknown_fields()->AddVarint(8, value);
+          }
+        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
+                   == ::google::protobuf::internal::WireFormatLite::
+                      WIRETYPE_LENGTH_DELIMITED) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(
+                 input,
+                 &::exec::user::RpcType_IsValid,
+                 this->mutable_supported_methods())));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(64)) goto parse_supported_methods;
         if (input->ExpectAtEnd()) return true;
         break;
       }
@@ -3772,6 +3905,12 @@ void BitToUserHandshake::SerializeWithCachedSizes(
       7, this->authenticationmechanisms(i), output);
   }
 
+  // repeated .exec.user.RpcType supported_methods = 8;
+  for (int i = 0; i < this->supported_methods_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      8, this->supported_methods(i), output);
+  }
+
   if (!unknown_fields().empty()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
@@ -3827,6 +3966,12 @@ void BitToUserHandshake::SerializeWithCachedSizes(
       WriteStringToArray(7, this->authenticationmechanisms(i), target);
   }
 
+  // repeated .exec.user.RpcType supported_methods = 8;
+  for (int i = 0; i < this->supported_methods_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      8, this->supported_methods(i), target);
+  }
+
   if (!unknown_fields().empty()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
@@ -3880,6 +4025,16 @@ int BitToUserHandshake::ByteSize() const {
       this->authenticationmechanisms(i));
   }
 
+  // repeated .exec.user.RpcType supported_methods = 8;
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->supported_methods_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(
+        this->supported_methods(i));
+    }
+    total_size += 1 * this->supported_methods_size() + data_size;
+  }
+
   if (!unknown_fields().empty()) {
     total_size +=
       ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
@@ -3906,6 +4061,7 @@ void BitToUserHandshake::MergeFrom(const ::google::protobuf::Message& from) {
 void BitToUserHandshake::MergeFrom(const BitToUserHandshake& from) {
   GOOGLE_CHECK_NE(&from, this);
   authenticationmechanisms_.MergeFrom(from.authenticationmechanisms_);
+  supported_methods_.MergeFrom(from.supported_methods_);
   if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
     if (from.has_rpc_version()) {
       set_rpc_version(from.rpc_version());
@@ -3951,6 +4107,7 @@ void BitToUserHandshake::Swap(BitToUserHandshake* other) {
     std::swap(errormessage_, other->errormessage_);
     std::swap(server_infos_, other->server_infos_);
     authenticationmechanisms_.Swap(&other->authenticationmechanisms_);
+    supported_methods_.Swap(&other->supported_methods_);
     std::swap(_has_bits_[0], other->_has_bits_[0]);
     _unknown_fields_.Swap(&other->_unknown_fields_);
     std::swap(_cached_size_, other->_cached_size_);

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/contrib/native/client/src/protobuf/User.pb.h
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/protobuf/User.pb.h b/contrib/native/client/src/protobuf/User.pb.h
index bd050ee..d332c36 100644
--- a/contrib/native/client/src/protobuf/User.pb.h
+++ b/contrib/native/client/src/protobuf/User.pb.h
@@ -532,6 +532,25 @@ class RpcEndpointInfos : public ::google::protobuf::Message {
   inline ::std::string* release_application();
   inline void set_allocated_application(::std::string* application);
 
+  // optional uint32 buildNumber = 7;
+  inline bool has_buildnumber() const;
+  inline void clear_buildnumber();
+  static const int kBuildNumberFieldNumber = 7;
+  inline ::google::protobuf::uint32 buildnumber() const;
+  inline void set_buildnumber(::google::protobuf::uint32 value);
+
+  // optional string versionQualifier = 8;
+  inline bool has_versionqualifier() const;
+  inline void clear_versionqualifier();
+  static const int kVersionQualifierFieldNumber = 8;
+  inline const ::std::string& versionqualifier() const;
+  inline void set_versionqualifier(const ::std::string& value);
+  inline void set_versionqualifier(const char* value);
+  inline void set_versionqualifier(const char* value, size_t size);
+  inline ::std::string* mutable_versionqualifier();
+  inline ::std::string* release_versionqualifier();
+  inline void set_allocated_versionqualifier(::std::string* versionqualifier);
+
   // @@protoc_insertion_point(class_scope:exec.user.RpcEndpointInfos)
  private:
   inline void set_has_name();
@@ -546,6 +565,10 @@ class RpcEndpointInfos : public ::google::protobuf::Message {
   inline void clear_has_patchversion();
   inline void set_has_application();
   inline void clear_has_application();
+  inline void set_has_buildnumber();
+  inline void clear_has_buildnumber();
+  inline void set_has_versionqualifier();
+  inline void clear_has_versionqualifier();
 
   ::google::protobuf::UnknownFieldSet _unknown_fields_;
 
@@ -555,9 +578,11 @@ class RpcEndpointInfos : public ::google::protobuf::Message {
   ::google::protobuf::uint32 minorversion_;
   ::std::string* application_;
   ::google::protobuf::uint32 patchversion_;
+  ::google::protobuf::uint32 buildnumber_;
+  ::std::string* versionqualifier_;
 
   mutable int _cached_size_;
-  ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32];
+  ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
 
   friend void  protobuf_AddDesc_User_2eproto();
   friend void protobuf_AssignDesc_User_2eproto();
@@ -1173,6 +1198,16 @@ class BitToUserHandshake : public ::google::protobuf::Message {
   inline const ::google::protobuf::RepeatedPtrField< ::std::string>& authenticationmechanisms() const;
   inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_authenticationmechanisms();
 
+  // repeated .exec.user.RpcType supported_methods = 8;
+  inline int supported_methods_size() const;
+  inline void clear_supported_methods();
+  static const int kSupportedMethodsFieldNumber = 8;
+  inline ::exec::user::RpcType supported_methods(int index) const;
+  inline void set_supported_methods(int index, ::exec::user::RpcType value);
+  inline void add_supported_methods(::exec::user::RpcType value);
+  inline const ::google::protobuf::RepeatedField<int>& supported_methods() const;
+  inline ::google::protobuf::RepeatedField<int>* mutable_supported_methods();
+
   // @@protoc_insertion_point(class_scope:exec.user.BitToUserHandshake)
  private:
   inline void set_has_rpc_version();
@@ -1194,9 +1229,10 @@ class BitToUserHandshake : public ::google::protobuf::Message {
   ::std::string* errormessage_;
   ::exec::user::RpcEndpointInfos* server_infos_;
   ::google::protobuf::RepeatedPtrField< ::std::string> authenticationmechanisms_;
+  ::google::protobuf::RepeatedField<int> supported_methods_;
 
   mutable int _cached_size_;
-  ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32];
+  ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
 
   friend void  protobuf_AddDesc_User_2eproto();
   friend void protobuf_AssignDesc_User_2eproto();
@@ -4095,6 +4131,98 @@ inline void RpcEndpointInfos::set_allocated_application(::std::string* applicati
   }
 }
 
+// optional uint32 buildNumber = 7;
+inline bool RpcEndpointInfos::has_buildnumber() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void RpcEndpointInfos::set_has_buildnumber() {
+  _has_bits_[0] |= 0x00000040u;
+}
+inline void RpcEndpointInfos::clear_has_buildnumber() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+inline void RpcEndpointInfos::clear_buildnumber() {
+  buildnumber_ = 0u;
+  clear_has_buildnumber();
+}
+inline ::google::protobuf::uint32 RpcEndpointInfos::buildnumber() const {
+  return buildnumber_;
+}
+inline void RpcEndpointInfos::set_buildnumber(::google::protobuf::uint32 value) {
+  set_has_buildnumber();
+  buildnumber_ = value;
+}
+
+// optional string versionQualifier = 8;
+inline bool RpcEndpointInfos::has_versionqualifier() const {
+  return (_has_bits_[0] & 0x00000080u) != 0;
+}
+inline void RpcEndpointInfos::set_has_versionqualifier() {
+  _has_bits_[0] |= 0x00000080u;
+}
+inline void RpcEndpointInfos::clear_has_versionqualifier() {
+  _has_bits_[0] &= ~0x00000080u;
+}
+inline void RpcEndpointInfos::clear_versionqualifier() {
+  if (versionqualifier_ != &::google::protobuf::internal::kEmptyString) {
+    versionqualifier_->clear();
+  }
+  clear_has_versionqualifier();
+}
+inline const ::std::string& RpcEndpointInfos::versionqualifier() const {
+  return *versionqualifier_;
+}
+inline void RpcEndpointInfos::set_versionqualifier(const ::std::string& value) {
+  set_has_versionqualifier();
+  if (versionqualifier_ == &::google::protobuf::internal::kEmptyString) {
+    versionqualifier_ = new ::std::string;
+  }
+  versionqualifier_->assign(value);
+}
+inline void RpcEndpointInfos::set_versionqualifier(const char* value) {
+  set_has_versionqualifier();
+  if (versionqualifier_ == &::google::protobuf::internal::kEmptyString) {
+    versionqualifier_ = new ::std::string;
+  }
+  versionqualifier_->assign(value);
+}
+inline void RpcEndpointInfos::set_versionqualifier(const char* value, size_t size) {
+  set_has_versionqualifier();
+  if (versionqualifier_ == &::google::protobuf::internal::kEmptyString) {
+    versionqualifier_ = new ::std::string;
+  }
+  versionqualifier_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* RpcEndpointInfos::mutable_versionqualifier() {
+  set_has_versionqualifier();
+  if (versionqualifier_ == &::google::protobuf::internal::kEmptyString) {
+    versionqualifier_ = new ::std::string;
+  }
+  return versionqualifier_;
+}
+inline ::std::string* RpcEndpointInfos::release_versionqualifier() {
+  clear_has_versionqualifier();
+  if (versionqualifier_ == &::google::protobuf::internal::kEmptyString) {
+    return NULL;
+  } else {
+    ::std::string* temp = versionqualifier_;
+    versionqualifier_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+    return temp;
+  }
+}
+inline void RpcEndpointInfos::set_allocated_versionqualifier(::std::string* versionqualifier) {
+  if (versionqualifier_ != &::google::protobuf::internal::kEmptyString) {
+    delete versionqualifier_;
+  }
+  if (versionqualifier) {
+    set_has_versionqualifier();
+    versionqualifier_ = versionqualifier;
+  } else {
+    clear_has_versionqualifier();
+    versionqualifier_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+  }
+}
+
 // -------------------------------------------------------------------
 
 // UserToBitHandshake
@@ -4929,6 +5057,33 @@ BitToUserHandshake::mutable_authenticationmechanisms() {
   return &authenticationmechanisms_;
 }
 
+// repeated .exec.user.RpcType supported_methods = 8;
+inline int BitToUserHandshake::supported_methods_size() const {
+  return supported_methods_.size();
+}
+inline void BitToUserHandshake::clear_supported_methods() {
+  supported_methods_.Clear();
+}
+inline ::exec::user::RpcType BitToUserHandshake::supported_methods(int index) const {
+  return static_cast< ::exec::user::RpcType >(supported_methods_.Get(index));
+}
+inline void BitToUserHandshake::set_supported_methods(int index, ::exec::user::RpcType value) {
+  assert(::exec::user::RpcType_IsValid(value));
+  supported_methods_.Set(index, value);
+}
+inline void BitToUserHandshake::add_supported_methods(::exec::user::RpcType value) {
+  assert(::exec::user::RpcType_IsValid(value));
+  supported_methods_.Add(value);
+}
+inline const ::google::protobuf::RepeatedField<int>&
+BitToUserHandshake::supported_methods() const {
+  return supported_methods_;
+}
+inline ::google::protobuf::RepeatedField<int>*
+BitToUserHandshake::mutable_supported_methods() {
+  return &supported_methods_;
+}
+
 // -------------------------------------------------------------------
 
 // LikeFilter

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/contrib/native/client/src/protobuf/UserBitShared.pb.cc
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/protobuf/UserBitShared.pb.cc b/contrib/native/client/src/protobuf/UserBitShared.pb.cc
index 2fcf116..0745228 100644
--- a/contrib/native/client/src/protobuf/UserBitShared.pb.cc
+++ b/contrib/native/client/src/protobuf/UserBitShared.pb.cc
@@ -339,7 +339,7 @@ void protobuf_AssignDesc_UserBitShared_2eproto() {
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(QueryInfo));
   QueryProfile_descriptor_ = file->message_type(13);
-  static const int QueryProfile_offsets_[17] = {
+  static const int QueryProfile_offsets_[19] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, id_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, type_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, start_),
@@ -357,6 +357,8 @@ void protobuf_AssignDesc_UserBitShared_2eproto() {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, error_id_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, error_node_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, options_json_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, planend_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(QueryProfile, queuewaitend_),
   };
   QueryProfile_reflection_ =
     new ::google::protobuf::internal::GeneratedMessageReflection(
@@ -690,7 +692,7 @@ void protobuf_AddDesc_UserBitShared_2eproto() {
     "rt\030\002 \001(\003\0222\n\005state\030\003 \001(\0162#.exec.shared.Qu"
     "eryResult.QueryState\022\017\n\004user\030\004 \001(\t:\001-\022\'\n"
     "\007foreman\030\005 \001(\0132\026.exec.DrillbitEndpoint\022\024"
-    "\n\014options_json\030\006 \001(\t\"\320\003\n\014QueryProfile\022 \n"
+    "\n\014options_json\030\006 \001(\t\"\367\003\n\014QueryProfile\022 \n"
     "\002id\030\001 \001(\0132\024.exec.shared.QueryId\022$\n\004type\030"
     "\002 \001(\0162\026.exec.shared.QueryType\022\r\n\005start\030\003"
     " \001(\003\022\013\n\003end\030\004 \001(\003\022\r\n\005query\030\005 \001(\t\022\014\n\004plan"
@@ -702,63 +704,63 @@ void protobuf_AddDesc_UserBitShared_2eproto() {
     "agmentProfile\022\017\n\004user\030\014 \001(\t:\001-\022\r\n\005error\030"
     "\r \001(\t\022\024\n\014verboseError\030\016 \001(\t\022\020\n\010error_id\030"
     "\017 \001(\t\022\022\n\nerror_node\030\020 \001(\t\022\024\n\014options_jso"
-    "n\030\021 \001(\t\"t\n\024MajorFragmentProfile\022\031\n\021major"
-    "_fragment_id\030\001 \001(\005\022A\n\026minor_fragment_pro"
-    "file\030\002 \003(\0132!.exec.shared.MinorFragmentPr"
-    "ofile\"\350\002\n\024MinorFragmentProfile\022)\n\005state\030"
-    "\001 \001(\0162\032.exec.shared.FragmentState\022(\n\005err"
-    "or\030\002 \001(\0132\031.exec.shared.DrillPBError\022\031\n\021m"
-    "inor_fragment_id\030\003 \001(\005\0226\n\020operator_profi"
-    "le\030\004 \003(\0132\034.exec.shared.OperatorProfile\022\022"
-    "\n\nstart_time\030\005 \001(\003\022\020\n\010end_time\030\006 \001(\003\022\023\n\013"
-    "memory_used\030\007 \001(\003\022\027\n\017max_memory_used\030\010 \001"
-    "(\003\022(\n\010endpoint\030\t \001(\0132\026.exec.DrillbitEndp"
-    "oint\022\023\n\013last_update\030\n \001(\003\022\025\n\rlast_progre"
-    "ss\030\013 \001(\003\"\377\001\n\017OperatorProfile\0221\n\rinput_pr"
-    "ofile\030\001 \003(\0132\032.exec.shared.StreamProfile\022"
-    "\023\n\013operator_id\030\003 \001(\005\022\025\n\roperator_type\030\004 "
-    "\001(\005\022\023\n\013setup_nanos\030\005 \001(\003\022\025\n\rprocess_nano"
-    "s\030\006 \001(\003\022#\n\033peak_local_memory_allocated\030\007"
-    " \001(\003\022(\n\006metric\030\010 \003(\0132\030.exec.shared.Metri"
-    "cValue\022\022\n\nwait_nanos\030\t \001(\003\"B\n\rStreamProf"
-    "ile\022\017\n\007records\030\001 \001(\003\022\017\n\007batches\030\002 \001(\003\022\017\n"
-    "\007schemas\030\003 \001(\003\"J\n\013MetricValue\022\021\n\tmetric_"
-    "id\030\001 \001(\005\022\022\n\nlong_value\030\002 \001(\003\022\024\n\014double_v"
-    "alue\030\003 \001(\001\")\n\010Registry\022\035\n\003jar\030\001 \003(\0132\020.ex"
-    "ec.shared.Jar\"/\n\003Jar\022\014\n\004name\030\001 \001(\t\022\032\n\022fu"
-    "nction_signature\030\002 \003(\t\"W\n\013SaslMessage\022\021\n"
-    "\tmechanism\030\001 \001(\t\022\014\n\004data\030\002 \001(\014\022\'\n\006status"
-    "\030\003 \001(\0162\027.exec.shared.SaslStatus*5\n\nRpcCh"
-    "annel\022\017\n\013BIT_CONTROL\020\000\022\014\n\010BIT_DATA\020\001\022\010\n\004"
-    "USER\020\002*V\n\tQueryType\022\007\n\003SQL\020\001\022\013\n\007LOGICAL\020"
-    "\002\022\014\n\010PHYSICAL\020\003\022\r\n\tEXECUTION\020\004\022\026\n\022PREPAR"
-    "ED_STATEMENT\020\005*\207\001\n\rFragmentState\022\013\n\007SEND"
-    "ING\020\000\022\027\n\023AWAITING_ALLOCATION\020\001\022\013\n\007RUNNIN"
-    "G\020\002\022\014\n\010FINISHED\020\003\022\r\n\tCANCELLED\020\004\022\n\n\006FAIL"
-    "ED\020\005\022\032\n\026CANCELLATION_REQUESTED\020\006*\335\005\n\020Cor"
-    "eOperatorType\022\021\n\rSINGLE_SENDER\020\000\022\024\n\020BROA"
-    "DCAST_SENDER\020\001\022\n\n\006FILTER\020\002\022\022\n\016HASH_AGGRE"
-    "GATE\020\003\022\r\n\tHASH_JOIN\020\004\022\016\n\nMERGE_JOIN\020\005\022\031\n"
-    "\025HASH_PARTITION_SENDER\020\006\022\t\n\005LIMIT\020\007\022\024\n\020M"
-    "ERGING_RECEIVER\020\010\022\034\n\030ORDERED_PARTITION_S"
-    "ENDER\020\t\022\013\n\007PROJECT\020\n\022\026\n\022UNORDERED_RECEIV"
-    "ER\020\013\022\020\n\014RANGE_SENDER\020\014\022\n\n\006SCREEN\020\r\022\034\n\030SE"
-    "LECTION_VECTOR_REMOVER\020\016\022\027\n\023STREAMING_AG"
-    "GREGATE\020\017\022\016\n\nTOP_N_SORT\020\020\022\021\n\rEXTERNAL_SO"
-    "RT\020\021\022\t\n\005TRACE\020\022\022\t\n\005UNION\020\023\022\014\n\010OLD_SORT\020\024"
-    "\022\032\n\026PARQUET_ROW_GROUP_SCAN\020\025\022\021\n\rHIVE_SUB"
-    "_SCAN\020\026\022\025\n\021SYSTEM_TABLE_SCAN\020\027\022\021\n\rMOCK_S"
-    "UB_SCAN\020\030\022\022\n\016PARQUET_WRITER\020\031\022\023\n\017DIRECT_"
-    "SUB_SCAN\020\032\022\017\n\013TEXT_WRITER\020\033\022\021\n\rTEXT_SUB_"
-    "SCAN\020\034\022\021\n\rJSON_SUB_SCAN\020\035\022\030\n\024INFO_SCHEMA"
-    "_SUB_SCAN\020\036\022\023\n\017COMPLEX_TO_JSON\020\037\022\025\n\021PROD"
-    "UCER_CONSUMER\020 \022\022\n\016HBASE_SUB_SCAN\020!\022\n\n\006W"
-    "INDOW\020\"\022\024\n\020NESTED_LOOP_JOIN\020#\022\021\n\rAVRO_SU"
-    "B_SCAN\020$*g\n\nSaslStatus\022\020\n\014SASL_UNKNOWN\020\000"
-    "\022\016\n\nSASL_START\020\001\022\024\n\020SASL_IN_PROGRESS\020\002\022\020"
-    "\n\014SASL_SUCCESS\020\003\022\017\n\013SASL_FAILED\020\004B.\n\033org"
-    ".apache.drill.exec.protoB\rUserBitSharedH"
-    "\001", 4801);
+    "n\030\021 \001(\t\022\017\n\007planEnd\030\022 \001(\003\022\024\n\014queueWaitEnd"
+    "\030\023 \001(\003\"t\n\024MajorFragmentProfile\022\031\n\021major_"
+    "fragment_id\030\001 \001(\005\022A\n\026minor_fragment_prof"
+    "ile\030\002 \003(\0132!.exec.shared.MinorFragmentPro"
+    "file\"\350\002\n\024MinorFragmentProfile\022)\n\005state\030\001"
+    " \001(\0162\032.exec.shared.FragmentState\022(\n\005erro"
+    "r\030\002 \001(\0132\031.exec.shared.DrillPBError\022\031\n\021mi"
+    "nor_fragment_id\030\003 \001(\005\0226\n\020operator_profil"
+    "e\030\004 \003(\0132\034.exec.shared.OperatorProfile\022\022\n"
+    "\nstart_time\030\005 \001(\003\022\020\n\010end_time\030\006 \001(\003\022\023\n\013m"
+    "emory_used\030\007 \001(\003\022\027\n\017max_memory_used\030\010 \001("
+    "\003\022(\n\010endpoint\030\t \001(\0132\026.exec.DrillbitEndpo"
+    "int\022\023\n\013last_update\030\n \001(\003\022\025\n\rlast_progres"
+    "s\030\013 \001(\003\"\377\001\n\017OperatorProfile\0221\n\rinput_pro"
+    "file\030\001 \003(\0132\032.exec.shared.StreamProfile\022\023"
+    "\n\013operator_id\030\003 \001(\005\022\025\n\roperator_type\030\004 \001"
+    "(\005\022\023\n\013setup_nanos\030\005 \001(\003\022\025\n\rprocess_nanos"
+    "\030\006 \001(\003\022#\n\033peak_local_memory_allocated\030\007 "
+    "\001(\003\022(\n\006metric\030\010 \003(\0132\030.exec.shared.Metric"
+    "Value\022\022\n\nwait_nanos\030\t \001(\003\"B\n\rStreamProfi"
+    "le\022\017\n\007records\030\001 \001(\003\022\017\n\007batches\030\002 \001(\003\022\017\n\007"
+    "schemas\030\003 \001(\003\"J\n\013MetricValue\022\021\n\tmetric_i"
+    "d\030\001 \001(\005\022\022\n\nlong_value\030\002 \001(\003\022\024\n\014double_va"
+    "lue\030\003 \001(\001\")\n\010Registry\022\035\n\003jar\030\001 \003(\0132\020.exe"
+    "c.shared.Jar\"/\n\003Jar\022\014\n\004name\030\001 \001(\t\022\032\n\022fun"
+    "ction_signature\030\002 \003(\t\"W\n\013SaslMessage\022\021\n\t"
+    "mechanism\030\001 \001(\t\022\014\n\004data\030\002 \001(\014\022\'\n\006status\030"
+    "\003 \001(\0162\027.exec.shared.SaslStatus*5\n\nRpcCha"
+    "nnel\022\017\n\013BIT_CONTROL\020\000\022\014\n\010BIT_DATA\020\001\022\010\n\004U"
+    "SER\020\002*V\n\tQueryType\022\007\n\003SQL\020\001\022\013\n\007LOGICAL\020\002"
+    "\022\014\n\010PHYSICAL\020\003\022\r\n\tEXECUTION\020\004\022\026\n\022PREPARE"
+    "D_STATEMENT\020\005*\207\001\n\rFragmentState\022\013\n\007SENDI"
+    "NG\020\000\022\027\n\023AWAITING_ALLOCATION\020\001\022\013\n\007RUNNING"
+    "\020\002\022\014\n\010FINISHED\020\003\022\r\n\tCANCELLED\020\004\022\n\n\006FAILE"
+    "D\020\005\022\032\n\026CANCELLATION_REQUESTED\020\006*\335\005\n\020Core"
+    "OperatorType\022\021\n\rSINGLE_SENDER\020\000\022\024\n\020BROAD"
+    "CAST_SENDER\020\001\022\n\n\006FILTER\020\002\022\022\n\016HASH_AGGREG"
+    "ATE\020\003\022\r\n\tHASH_JOIN\020\004\022\016\n\nMERGE_JOIN\020\005\022\031\n\025"
+    "HASH_PARTITION_SENDER\020\006\022\t\n\005LIMIT\020\007\022\024\n\020ME"
+    "RGING_RECEIVER\020\010\022\034\n\030ORDERED_PARTITION_SE"
+    "NDER\020\t\022\013\n\007PROJECT\020\n\022\026\n\022UNORDERED_RECEIVE"
+    "R\020\013\022\020\n\014RANGE_SENDER\020\014\022\n\n\006SCREEN\020\r\022\034\n\030SEL"
+    "ECTION_VECTOR_REMOVER\020\016\022\027\n\023STREAMING_AGG"
+    "REGATE\020\017\022\016\n\nTOP_N_SORT\020\020\022\021\n\rEXTERNAL_SOR"
+    "T\020\021\022\t\n\005TRACE\020\022\022\t\n\005UNION\020\023\022\014\n\010OLD_SORT\020\024\022"
+    "\032\n\026PARQUET_ROW_GROUP_SCAN\020\025\022\021\n\rHIVE_SUB_"
+    "SCAN\020\026\022\025\n\021SYSTEM_TABLE_SCAN\020\027\022\021\n\rMOCK_SU"
+    "B_SCAN\020\030\022\022\n\016PARQUET_WRITER\020\031\022\023\n\017DIRECT_S"
+    "UB_SCAN\020\032\022\017\n\013TEXT_WRITER\020\033\022\021\n\rTEXT_SUB_S"
+    "CAN\020\034\022\021\n\rJSON_SUB_SCAN\020\035\022\030\n\024INFO_SCHEMA_"
+    "SUB_SCAN\020\036\022\023\n\017COMPLEX_TO_JSON\020\037\022\025\n\021PRODU"
+    "CER_CONSUMER\020 \022\022\n\016HBASE_SUB_SCAN\020!\022\n\n\006WI"
+    "NDOW\020\"\022\024\n\020NESTED_LOOP_JOIN\020#\022\021\n\rAVRO_SUB"
+    "_SCAN\020$*g\n\nSaslStatus\022\020\n\014SASL_UNKNOWN\020\000\022"
+    "\016\n\nSASL_START\020\001\022\024\n\020SASL_IN_PROGRESS\020\002\022\020\n"
+    "\014SASL_SUCCESS\020\003\022\017\n\013SASL_FAILED\020\004B.\n\033org."
+    "apache.drill.exec.protoB\rUserBitSharedH\001", 4840);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "UserBitShared.proto", &protobuf_RegisterTypes);
   UserCredentials::default_instance_ = new UserCredentials();
@@ -5423,6 +5425,8 @@ const int QueryProfile::kVerboseErrorFieldNumber;
 const int QueryProfile::kErrorIdFieldNumber;
 const int QueryProfile::kErrorNodeFieldNumber;
 const int QueryProfile::kOptionsJsonFieldNumber;
+const int QueryProfile::kPlanEndFieldNumber;
+const int QueryProfile::kQueueWaitEndFieldNumber;
 #endif  // !_MSC_VER
 
 QueryProfile::QueryProfile()
@@ -5459,6 +5463,8 @@ void QueryProfile::SharedCtor() {
   error_id_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
   error_node_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
   options_json_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+  planend_ = GOOGLE_LONGLONG(0);
+  queuewaitend_ = GOOGLE_LONGLONG(0);
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
@@ -5576,6 +5582,8 @@ void QueryProfile::Clear() {
         options_json_->clear();
       }
     }
+    planend_ = GOOGLE_LONGLONG(0);
+    queuewaitend_ = GOOGLE_LONGLONG(0);
   }
   fragment_profile_.Clear();
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -5868,6 +5876,38 @@ bool QueryProfile::MergePartialFromCodedStream(
         } else {
           goto handle_uninterpreted;
         }
+        if (input->ExpectTag(144)) goto parse_planEnd;
+        break;
+      }
+
+      // optional int64 planEnd = 18;
+      case 18: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_planEnd:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
+                 input, &planend_)));
+          set_has_planend();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(152)) goto parse_queueWaitEnd;
+        break;
+      }
+
+      // optional int64 queueWaitEnd = 19;
+      case 19: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_queueWaitEnd:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
+                 input, &queuewaitend_)));
+          set_has_queuewaitend();
+        } else {
+          goto handle_uninterpreted;
+        }
         if (input->ExpectAtEnd()) return true;
         break;
       }
@@ -6012,6 +6052,16 @@ void QueryProfile::SerializeWithCachedSizes(
       17, this->options_json(), output);
   }
 
+  // optional int64 planEnd = 18;
+  if (has_planend()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt64(18, this->planend(), output);
+  }
+
+  // optional int64 queueWaitEnd = 19;
+  if (has_queuewaitend()) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt64(19, this->queuewaitend(), output);
+  }
+
   if (!unknown_fields().empty()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
@@ -6153,6 +6203,16 @@ void QueryProfile::SerializeWithCachedSizes(
         17, this->options_json(), target);
   }
 
+  // optional int64 planEnd = 18;
+  if (has_planend()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(18, this->planend(), target);
+  }
+
+  // optional int64 queueWaitEnd = 19;
+  if (has_queuewaitend()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(19, this->queuewaitend(), target);
+  }
+
   if (!unknown_fields().empty()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
@@ -6278,6 +6338,20 @@ int QueryProfile::ByteSize() const {
           this->options_json());
     }
 
+    // optional int64 planEnd = 18;
+    if (has_planend()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::Int64Size(
+          this->planend());
+    }
+
+    // optional int64 queueWaitEnd = 19;
+    if (has_queuewaitend()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::Int64Size(
+          this->queuewaitend());
+    }
+
   }
   // repeated .exec.shared.MajorFragmentProfile fragment_profile = 11;
   total_size += 1 * this->fragment_profile_size();
@@ -6366,6 +6440,12 @@ void QueryProfile::MergeFrom(const QueryProfile& from) {
     if (from.has_options_json()) {
       set_options_json(from.options_json());
     }
+    if (from.has_planend()) {
+      set_planend(from.planend());
+    }
+    if (from.has_queuewaitend()) {
+      set_queuewaitend(from.queuewaitend());
+    }
   }
   mutable_unknown_fields()->MergeFrom(from.unknown_fields());
 }
@@ -6406,6 +6486,8 @@ void QueryProfile::Swap(QueryProfile* other) {
     std::swap(error_id_, other->error_id_);
     std::swap(error_node_, other->error_node_);
     std::swap(options_json_, other->options_json_);
+    std::swap(planend_, other->planend_);
+    std::swap(queuewaitend_, other->queuewaitend_);
     std::swap(_has_bits_[0], other->_has_bits_[0]);
     _unknown_fields_.Swap(&other->_unknown_fields_);
     std::swap(_cached_size_, other->_cached_size_);

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/contrib/native/client/src/protobuf/UserBitShared.pb.h
----------------------------------------------------------------------
diff --git a/contrib/native/client/src/protobuf/UserBitShared.pb.h b/contrib/native/client/src/protobuf/UserBitShared.pb.h
index a2d0607..ad32959 100644
--- a/contrib/native/client/src/protobuf/UserBitShared.pb.h
+++ b/contrib/native/client/src/protobuf/UserBitShared.pb.h
@@ -2096,6 +2096,20 @@ class QueryProfile : public ::google::protobuf::Message {
   inline ::std::string* release_options_json();
   inline void set_allocated_options_json(::std::string* options_json);
 
+  // optional int64 planEnd = 18;
+  inline bool has_planend() const;
+  inline void clear_planend();
+  static const int kPlanEndFieldNumber = 18;
+  inline ::google::protobuf::int64 planend() const;
+  inline void set_planend(::google::protobuf::int64 value);
+
+  // optional int64 queueWaitEnd = 19;
+  inline bool has_queuewaitend() const;
+  inline void clear_queuewaitend();
+  static const int kQueueWaitEndFieldNumber = 19;
+  inline ::google::protobuf::int64 queuewaitend() const;
+  inline void set_queuewaitend(::google::protobuf::int64 value);
+
   // @@protoc_insertion_point(class_scope:exec.shared.QueryProfile)
  private:
   inline void set_has_id();
@@ -2130,6 +2144,10 @@ class QueryProfile : public ::google::protobuf::Message {
   inline void clear_has_error_node();
   inline void set_has_options_json();
   inline void clear_has_options_json();
+  inline void set_has_planend();
+  inline void clear_has_planend();
+  inline void set_has_queuewaitend();
+  inline void clear_has_queuewaitend();
 
   ::google::protobuf::UnknownFieldSet _unknown_fields_;
 
@@ -2151,9 +2169,11 @@ class QueryProfile : public ::google::protobuf::Message {
   ::std::string* error_id_;
   ::std::string* error_node_;
   ::std::string* options_json_;
+  ::google::protobuf::int64 planend_;
+  ::google::protobuf::int64 queuewaitend_;
 
   mutable int _cached_size_;
-  ::google::protobuf::uint32 _has_bits_[(17 + 31) / 32];
+  ::google::protobuf::uint32 _has_bits_[(19 + 31) / 32];
 
   friend void  protobuf_AddDesc_UserBitShared_2eproto();
   friend void protobuf_AssignDesc_UserBitShared_2eproto();
@@ -5774,6 +5794,50 @@ inline void QueryProfile::set_allocated_options_json(::std::string* options_json
   }
 }
 
+// optional int64 planEnd = 18;
+inline bool QueryProfile::has_planend() const {
+  return (_has_bits_[0] & 0x00020000u) != 0;
+}
+inline void QueryProfile::set_has_planend() {
+  _has_bits_[0] |= 0x00020000u;
+}
+inline void QueryProfile::clear_has_planend() {
+  _has_bits_[0] &= ~0x00020000u;
+}
+inline void QueryProfile::clear_planend() {
+  planend_ = GOOGLE_LONGLONG(0);
+  clear_has_planend();
+}
+inline ::google::protobuf::int64 QueryProfile::planend() const {
+  return planend_;
+}
+inline void QueryProfile::set_planend(::google::protobuf::int64 value) {
+  set_has_planend();
+  planend_ = value;
+}
+
+// optional int64 queueWaitEnd = 19;
+inline bool QueryProfile::has_queuewaitend() const {
+  return (_has_bits_[0] & 0x00040000u) != 0;
+}
+inline void QueryProfile::set_has_queuewaitend() {
+  _has_bits_[0] |= 0x00040000u;
+}
+inline void QueryProfile::clear_has_queuewaitend() {
+  _has_bits_[0] &= ~0x00040000u;
+}
+inline void QueryProfile::clear_queuewaitend() {
+  queuewaitend_ = GOOGLE_LONGLONG(0);
+  clear_has_queuewaitend();
+}
+inline ::google::protobuf::int64 QueryProfile::queuewaitend() const {
+  return queuewaitend_;
+}
+inline void QueryProfile::set_queuewaitend(::google::protobuf::int64 value) {
+  set_has_queuewaitend();
+  queuewaitend_ = value;
+}
+
 // -------------------------------------------------------------------
 
 // MajorFragmentProfile

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/exec/java-exec/src/main/codegen/templates/DrillVersionInfo.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/codegen/templates/DrillVersionInfo.java b/exec/java-exec/src/main/codegen/templates/DrillVersionInfo.java
index 7b4b222..c7ff4c7 100644
--- a/exec/java-exec/src/main/codegen/templates/DrillVersionInfo.java
+++ b/exec/java-exec/src/main/codegen/templates/DrillVersionInfo.java
@@ -24,8 +24,7 @@
 
 package org.apache.drill.common.util;
 
-import java.text.MessageFormat;
-import java.text.ParseException;
+import org.apache.drill.common.Version;
 
 /*
  * This file is generated with Freemarker using the template src/main/codegen/templates/DrillVersionInfo.java
@@ -39,18 +38,24 @@ import java.text.ParseException;
  *
  */
 public class DrillVersionInfo {
-  private static final String VERSION = "${maven.project.version}";
-
-  private static final int MAJOR_VERSION = ${maven.project.artifact.selectedVersion.majorVersion};
-  private static final int MINOR_VERSION = ${maven.project.artifact.selectedVersion.minorVersion};
-  private static final int PATCH_VERSION = ${maven.project.artifact.selectedVersion.incrementalVersion};
+  /**
+   * The version extracted from Maven POM file at build time.
+   */
+  public static final Version VERSION = new Version(
+      "${maven.project.version}",
+      ${maven.project.artifact.selectedVersion.majorVersion},
+      ${maven.project.artifact.selectedVersion.minorVersion},
+      ${maven.project.artifact.selectedVersion.incrementalVersion},
+      ${maven.project.artifact.selectedVersion.buildNumber},
+      "${maven.project.artifact.selectedVersion.qualifier!}"
+  );
 
   /**
    * Get the Drill version from pom
    * @return the version number as x.y.z
    */
   public static String getVersion() {
-    return VERSION;
+    return VERSION.getVersion();
   }
 
   /**
@@ -58,7 +63,7 @@ public class DrillVersionInfo {
    *  @return x if assuming the version number is x.y.z
    */
   public static int getMajorVersion() {
-    return MAJOR_VERSION;
+    return VERSION.getMajorVersion();
   }
 
   /**
@@ -66,7 +71,7 @@ public class DrillVersionInfo {
    *  @return y if assuming the version number is x.y.z
    */
   public static int getMinorVersion() {
-    return MINOR_VERSION;
+    return VERSION.getMinorVersion();
   }
 
   /**
@@ -74,6 +79,23 @@ public class DrillVersionInfo {
    *  @return z if assuming the version number is x.y.z(-suffix)
    */
   public static int getPatchVersion() {
-    return PATCH_VERSION;
+    return VERSION.getPatchVersion();
+  }
+
+  /**
+   *  Get the Drill build number from pom
+   *  @return z if assuming the version number is x.y.z(.b)(-suffix)
+   */
+  public static int getBuildNumber() {
+    return VERSION.getPatchVersion();
+  }
+
+  /**
+   *  Get the Drill version qualifier from pom
+   *  @return suffix if assuming the version number is x.y.z(-suffix), or an empty string
+   */
+  public static String getQualifier() {
+    return VERSION.getQualifier();
   }
 }
+

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/exec/java-exec/src/main/java/org/apache/drill/exec/client/DrillClient.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/client/DrillClient.java b/exec/java-exec/src/main/java/org/apache/drill/exec/client/DrillClient.java
index 508c722..0b5bf30 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/client/DrillClient.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/client/DrillClient.java
@@ -23,15 +23,13 @@ import static com.google.common.base.Preconditions.checkState;
 import static org.apache.drill.exec.proto.UserProtos.QueryResultsMode.STREAM_FULL;
 import static org.apache.drill.exec.proto.UserProtos.RunQuery.newBuilder;
 
-import com.google.common.base.Strings;
-import io.netty.channel.EventLoopGroup;
-
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Properties;
+import java.util.Set;
 import java.util.Vector;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.SynchronousQueue;
@@ -39,8 +37,9 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
 import org.apache.drill.common.DrillAutoCloseables;
-import org.apache.drill.common.config.DrillProperties;
+import org.apache.drill.common.Version;
 import org.apache.drill.common.config.DrillConfig;
+import org.apache.drill.common.config.DrillProperties;
 import org.apache.drill.common.exceptions.UserException;
 import org.apache.drill.exec.ExecConstants;
 import org.apache.drill.exec.coord.ClusterCoordinator;
@@ -78,20 +77,23 @@ import org.apache.drill.exec.rpc.ChannelClosedException;
 import org.apache.drill.exec.rpc.ConnectionThrottle;
 import org.apache.drill.exec.rpc.DrillRpcFuture;
 import org.apache.drill.exec.rpc.NamedThreadFactory;
+import org.apache.drill.exec.rpc.NonTransientRpcException;
 import org.apache.drill.exec.rpc.RpcException;
 import org.apache.drill.exec.rpc.TransportCheck;
-import org.apache.drill.exec.rpc.NonTransientRpcException;
 import org.apache.drill.exec.rpc.user.QueryDataBatch;
 import org.apache.drill.exec.rpc.user.UserClient;
 import org.apache.drill.exec.rpc.user.UserResultsListener;
+import org.apache.drill.exec.rpc.user.UserRpcUtils;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.google.common.annotations.VisibleForTesting;
-
+import com.google.common.base.Strings;
 import com.google.common.util.concurrent.SettableFuture;
 
+import io.netty.channel.EventLoopGroup;
+
 /**
  * Thin wrapper around a UserClient that handles connect/close and transforms
  * String into ByteBuf.
@@ -475,12 +477,48 @@ public class DrillClient implements Closeable, ConnectionThrottle {
    *
    * @return the server informations, or null if not connected or if the server
    *         doesn't provide the information
+   * @deprecated use {@code DrillClient#getServerVersion()}
    */
+  @Deprecated
   public RpcEndpointInfos getServerInfos() {
     return client != null ? client.getServerInfos() : null;
   }
 
   /**
+   * Return the server name. Only available after connecting
+   *
+   * The result might be null if the server doesn't provide the name information.
+   *
+   * @return the server name, or null if not connected or if the server
+   *         doesn't provide the name
+   * @return
+   */
+  public String getServerName() {
+    return (client != null && client.getServerInfos() != null) ? client.getServerInfos().getName() : null;
+  }
+
+  /**
+   * Return the server version. Only available after connecting
+   *
+   * The result might be null if the server doesn't provide the version information.
+   *
+   * @return the server version, or null if not connected or if the server
+   *         doesn't provide the version
+   * @return
+   */
+  public Version getServerVersion() {
+    return (client != null && client.getServerInfos() != null) ? UserRpcUtils.getVersion(client.getServerInfos()) : null;
+  }
+  /**
+   * Returns the list of methods supported by the server based on its advertised information.
+   *
+   * @return a immutable set of capabilities
+   */
+  public Set<ServerMethod> getSupportedMethods() {
+    return client != null ? ServerMethod.getSupportedMethods(client.getSupportedMethods(), client.getServerInfos()) : null;
+  }
+
+  /**
    * Submits a string based query plan for execution and returns the result batches. Supported query types are:
    * <p><ul>
    *  <li>{@link QueryType#LOGICAL}

http://git-wip-us.apache.org/repos/asf/drill/blob/16aa0810/exec/java-exec/src/main/java/org/apache/drill/exec/client/ServerMethod.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/client/ServerMethod.java b/exec/java-exec/src/main/java/org/apache/drill/exec/client/ServerMethod.java
new file mode 100644
index 0000000..5c6640d
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/client/ServerMethod.java
@@ -0,0 +1,144 @@
+/*
+ * 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.drill.exec.client;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.drill.common.Version;
+import org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos;
+import org.apache.drill.exec.proto.UserProtos.RpcType;
+import org.apache.drill.exec.rpc.user.UserRpcUtils;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * A enumeration of server methods, and the version they were introduced
+ *
+ * it allows to introduce new methods without changing the protocol, with client
+ * being able to gracefully handle cases were method is not handled by the server.
+ */
+public enum ServerMethod {
+  /**
+   * Submitting a query
+   */
+  RUN_QUERY(RpcType.RUN_QUERY, Constants.DRILL_0_0_0),
+
+  /**
+   * Plan a query without executing it
+   */
+  PLAN_QUERY(RpcType.QUERY_PLAN_FRAGMENTS, Constants.DRILL_0_0_0),
+
+  /**
+   * Cancel an existing query
+   */
+  CANCEL_QUERY(RpcType.CANCEL_QUERY, Constants.DRILL_0_0_0),
+
+  /**
+   * Resume a query
+   */
+  RESUME_PAUSED_QUERY(RpcType.RESUME_PAUSED_QUERY, Constants.DRILL_0_0_0),
+
+  /**
+   * Prepare a query for deferred execution
+   */
+  PREPARED_STATEMENT(RpcType.CREATE_PREPARED_STATEMENT, Constants.DRILL_1_8_0),
+
+  /**
+   * Get catalog metadata
+   */
+  GET_CATALOGS(RpcType.GET_CATALOGS, Constants.DRILL_1_8_0),
+
+  /**
+   * Get schemas metadata
+   */
+  GET_SCHEMAS(RpcType.GET_SCHEMAS, Constants.DRILL_1_8_0),
+
+  /**
+   * Get tables metadata
+   */
+  GET_TABLES(RpcType.GET_TABLES, Constants.DRILL_1_8_0),
+
+  /**
+   * Get columns metadata
+   */
+  GET_COLUMNS(RpcType.GET_COLUMNS, Constants.DRILL_1_8_0);
+
+  private static class Constants {
+    private static final Version DRILL_0_0_0 = new Version("0.0.0", 0, 0, 0, 0, "");
+
+    private static final Version DRILL_1_8_0 = new Version("1.8.0", 1, 8, 0, 0, "");
+  }
+
+  private static final Map<RpcType, ServerMethod> REVERSE_MAPPING;
+  static {
+    ImmutableMap.Builder<RpcType, ServerMethod> builder = ImmutableMap.builder();
+    for(ServerMethod method: values()) {
+      builder.put(method.rpcType, method);
+    }
+    REVERSE_MAPPING = Maps.immutableEnumMap(builder.build());
+  }
+
+  private final RpcType rpcType;
+  private final Version minVersion;
+
+  private ServerMethod(RpcType rpcType, Version minVersion) {
+    this.rpcType = rpcType;
+    this.minVersion = minVersion;
+  }
+
+  public Version getMinVersion() {
+    return minVersion;
+  }
+
+  /**
+   * Returns the list of methods supported by the server based on its advertised information.
+   *
+   * @param serverInfos the server information
+   * @return a immutable set of capabilities
+   */
+  static final Set<ServerMethod> getSupportedMethods(Iterable<RpcType> supportedMethods, RpcEndpointInfos serverInfos) {
+    ImmutableSet.Builder<ServerMethod> builder = ImmutableSet.builder();
+
+    for(RpcType supportedMethod: supportedMethods) {
+      ServerMethod method = REVERSE_MAPPING.get(supportedMethod);
+      if (method == null) {
+        // The server might have newer methods we don't know how to handle yet.
+        continue;
+      }
+      builder.add(method);
+    }
+
+    // Fallback to version detection to cover the gap between Drill 1.8.0 and Drill 1.10.0
+    if (serverInfos == null) {
+      return Sets.immutableEnumSet(builder.build());
+    }
+
+    Version serverVersion = UserRpcUtils.getVersion(serverInfos);
+    for(ServerMethod capability: ServerMethod.values()) {
+      if (serverVersion.compareTo(capability.getMinVersion()) >= 0) {
+        builder.add(capability);
+      }
+    }
+
+    return Sets.immutableEnumSet(builder.build());
+  }
+}


Mime
View raw message