/*
 * 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.
 */
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: User.proto

package org.apache.drill.exec.proto;

public final class UserProtos {
  private UserProtos() {}
  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistryLite registry) {
  }

  public static void registerAllExtensions(
      com.google.protobuf.ExtensionRegistry registry) {
    registerAllExtensions(
        (com.google.protobuf.ExtensionRegistryLite) registry);
  }
  /**
   * <pre>
   *&#47;/// User &lt;-&gt; Bit RPC ///////
   * </pre>
   *
   * Protobuf enum {@code exec.user.RpcType}
   */
  public enum RpcType
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>HANDSHAKE = 0;</code>
     */
    HANDSHAKE(0),
    /**
     * <code>ACK = 1;</code>
     */
    ACK(1),
    /**
     * <code>GOODBYE = 2;</code>
     */
    GOODBYE(2),
    /**
     * <pre>
     * user to bit
     * </pre>
     *
     * <code>RUN_QUERY = 3;</code>
     */
    RUN_QUERY(3),
    /**
     * <pre>
     * user is sending a query cancellation request to the drillbit
     * </pre>
     *
     * <code>CANCEL_QUERY = 4;</code>
     */
    CANCEL_QUERY(4),
    /**
     * <code>REQUEST_RESULTS = 5;</code>
     */
    REQUEST_RESULTS(5),
    /**
     * <pre>
     * user is sending a query resume request to the drillbit
     * </pre>
     *
     * <code>RESUME_PAUSED_QUERY = 11;</code>
     */
    RESUME_PAUSED_QUERY(11),
    /**
     * <pre>
     * to get plan fragments from query
     * </pre>
     *
     * <code>GET_QUERY_PLAN_FRAGMENTS = 12;</code>
     */
    GET_QUERY_PLAN_FRAGMENTS(12),
    /**
     * <pre>
     * user is requesting metadata of catalog(s).
     * </pre>
     *
     * <code>GET_CATALOGS = 14;</code>
     */
    GET_CATALOGS(14),
    /**
     * <pre>
     * user is requesting metadata of schema(s)
     * </pre>
     *
     * <code>GET_SCHEMAS = 15;</code>
     */
    GET_SCHEMAS(15),
    /**
     * <pre>
     * user is requesting metadata of table(s)
     * </pre>
     *
     * <code>GET_TABLES = 16;</code>
     */
    GET_TABLES(16),
    /**
     * <pre>
     * user is requesting metadata of column(s)
     * </pre>
     *
     * <code>GET_COLUMNS = 17;</code>
     */
    GET_COLUMNS(17),
    /**
     * <pre>
     * user is sending a request to create prepared statement
     * </pre>
     *
     * <code>CREATE_PREPARED_STATEMENT = 22;</code>
     */
    CREATE_PREPARED_STATEMENT(22),
    /**
     * <pre>
     * user is sending a request to receive server metadata
     * </pre>
     *
     * <code>GET_SERVER_META = 8;</code>
     */
    GET_SERVER_META(8),
    /**
     * <pre>
     * bit to user
     * </pre>
     *
     * <code>QUERY_DATA = 6;</code>
     */
    QUERY_DATA(6),
    /**
     * <code>QUERY_HANDLE = 7;</code>
     */
    QUERY_HANDLE(7),
    /**
     * <pre>
     * return plan fragments
     * </pre>
     *
     * <code>QUERY_PLAN_FRAGMENTS = 13;</code>
     */
    QUERY_PLAN_FRAGMENTS(13),
    /**
     * <pre>
     * return catalogs metadata in response to GET_CATALOGS
     * </pre>
     *
     * <code>CATALOGS = 18;</code>
     */
    CATALOGS(18),
    /**
     * <pre>
     * return schema metadata in response to GET_SCHEMAS
     * </pre>
     *
     * <code>SCHEMAS = 19;</code>
     */
    SCHEMAS(19),
    /**
     * <pre>
     * return table metadata in response to GET_TABLES
     * </pre>
     *
     * <code>TABLES = 20;</code>
     */
    TABLES(20),
    /**
     * <pre>
     * return column metadata in response to GET_COLUMNS
     * </pre>
     *
     * <code>COLUMNS = 21;</code>
     */
    COLUMNS(21),
    /**
     * <pre>
     * return preparated statement in response to CREATE_PREPARED_STATEMENT
     * </pre>
     *
     * <code>PREPARED_STATEMENT = 23;</code>
     */
    PREPARED_STATEMENT(23),
    /**
     * <pre>
     * return server infos in respose to GET_SERVER_META
     * </pre>
     *
     * <code>SERVER_META = 9;</code>
     */
    SERVER_META(9),
    /**
     * <pre>
     * drillbit is reporting a query status change, most likely a terminal message, to the user
     * </pre>
     *
     * <code>QUERY_RESULT = 10;</code>
     */
    QUERY_RESULT(10),
    /**
     * <pre>
     * user to bit and bit to user
     * </pre>
     *
     * <code>SASL_MESSAGE = 24;</code>
     */
    SASL_MESSAGE(24),
    ;

    /**
     * <code>HANDSHAKE = 0;</code>
     */
    public static final int HANDSHAKE_VALUE = 0;
    /**
     * <code>ACK = 1;</code>
     */
    public static final int ACK_VALUE = 1;
    /**
     * <code>GOODBYE = 2;</code>
     */
    public static final int GOODBYE_VALUE = 2;
    /**
     * <pre>
     * user to bit
     * </pre>
     *
     * <code>RUN_QUERY = 3;</code>
     */
    public static final int RUN_QUERY_VALUE = 3;
    /**
     * <pre>
     * user is sending a query cancellation request to the drillbit
     * </pre>
     *
     * <code>CANCEL_QUERY = 4;</code>
     */
    public static final int CANCEL_QUERY_VALUE = 4;
    /**
     * <code>REQUEST_RESULTS = 5;</code>
     */
    public static final int REQUEST_RESULTS_VALUE = 5;
    /**
     * <pre>
     * user is sending a query resume request to the drillbit
     * </pre>
     *
     * <code>RESUME_PAUSED_QUERY = 11;</code>
     */
    public static final int RESUME_PAUSED_QUERY_VALUE = 11;
    /**
     * <pre>
     * to get plan fragments from query
     * </pre>
     *
     * <code>GET_QUERY_PLAN_FRAGMENTS = 12;</code>
     */
    public static final int GET_QUERY_PLAN_FRAGMENTS_VALUE = 12;
    /**
     * <pre>
     * user is requesting metadata of catalog(s).
     * </pre>
     *
     * <code>GET_CATALOGS = 14;</code>
     */
    public static final int GET_CATALOGS_VALUE = 14;
    /**
     * <pre>
     * user is requesting metadata of schema(s)
     * </pre>
     *
     * <code>GET_SCHEMAS = 15;</code>
     */
    public static final int GET_SCHEMAS_VALUE = 15;
    /**
     * <pre>
     * user is requesting metadata of table(s)
     * </pre>
     *
     * <code>GET_TABLES = 16;</code>
     */
    public static final int GET_TABLES_VALUE = 16;
    /**
     * <pre>
     * user is requesting metadata of column(s)
     * </pre>
     *
     * <code>GET_COLUMNS = 17;</code>
     */
    public static final int GET_COLUMNS_VALUE = 17;
    /**
     * <pre>
     * user is sending a request to create prepared statement
     * </pre>
     *
     * <code>CREATE_PREPARED_STATEMENT = 22;</code>
     */
    public static final int CREATE_PREPARED_STATEMENT_VALUE = 22;
    /**
     * <pre>
     * user is sending a request to receive server metadata
     * </pre>
     *
     * <code>GET_SERVER_META = 8;</code>
     */
    public static final int GET_SERVER_META_VALUE = 8;
    /**
     * <pre>
     * bit to user
     * </pre>
     *
     * <code>QUERY_DATA = 6;</code>
     */
    public static final int QUERY_DATA_VALUE = 6;
    /**
     * <code>QUERY_HANDLE = 7;</code>
     */
    public static final int QUERY_HANDLE_VALUE = 7;
    /**
     * <pre>
     * return plan fragments
     * </pre>
     *
     * <code>QUERY_PLAN_FRAGMENTS = 13;</code>
     */
    public static final int QUERY_PLAN_FRAGMENTS_VALUE = 13;
    /**
     * <pre>
     * return catalogs metadata in response to GET_CATALOGS
     * </pre>
     *
     * <code>CATALOGS = 18;</code>
     */
    public static final int CATALOGS_VALUE = 18;
    /**
     * <pre>
     * return schema metadata in response to GET_SCHEMAS
     * </pre>
     *
     * <code>SCHEMAS = 19;</code>
     */
    public static final int SCHEMAS_VALUE = 19;
    /**
     * <pre>
     * return table metadata in response to GET_TABLES
     * </pre>
     *
     * <code>TABLES = 20;</code>
     */
    public static final int TABLES_VALUE = 20;
    /**
     * <pre>
     * return column metadata in response to GET_COLUMNS
     * </pre>
     *
     * <code>COLUMNS = 21;</code>
     */
    public static final int COLUMNS_VALUE = 21;
    /**
     * <pre>
     * return preparated statement in response to CREATE_PREPARED_STATEMENT
     * </pre>
     *
     * <code>PREPARED_STATEMENT = 23;</code>
     */
    public static final int PREPARED_STATEMENT_VALUE = 23;
    /**
     * <pre>
     * return server infos in respose to GET_SERVER_META
     * </pre>
     *
     * <code>SERVER_META = 9;</code>
     */
    public static final int SERVER_META_VALUE = 9;
    /**
     * <pre>
     * drillbit is reporting a query status change, most likely a terminal message, to the user
     * </pre>
     *
     * <code>QUERY_RESULT = 10;</code>
     */
    public static final int QUERY_RESULT_VALUE = 10;
    /**
     * <pre>
     * user to bit and bit to user
     * </pre>
     *
     * <code>SASL_MESSAGE = 24;</code>
     */
    public static final int SASL_MESSAGE_VALUE = 24;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static RpcType valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static RpcType forNumber(int value) {
      switch (value) {
        case 0: return HANDSHAKE;
        case 1: return ACK;
        case 2: return GOODBYE;
        case 3: return RUN_QUERY;
        case 4: return CANCEL_QUERY;
        case 5: return REQUEST_RESULTS;
        case 11: return RESUME_PAUSED_QUERY;
        case 12: return GET_QUERY_PLAN_FRAGMENTS;
        case 14: return GET_CATALOGS;
        case 15: return GET_SCHEMAS;
        case 16: return GET_TABLES;
        case 17: return GET_COLUMNS;
        case 22: return CREATE_PREPARED_STATEMENT;
        case 8: return GET_SERVER_META;
        case 6: return QUERY_DATA;
        case 7: return QUERY_HANDLE;
        case 13: return QUERY_PLAN_FRAGMENTS;
        case 18: return CATALOGS;
        case 19: return SCHEMAS;
        case 20: return TABLES;
        case 21: return COLUMNS;
        case 23: return PREPARED_STATEMENT;
        case 9: return SERVER_META;
        case 10: return QUERY_RESULT;
        case 24: return SASL_MESSAGE;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<RpcType>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        RpcType> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<RpcType>() {
            public RpcType findValueByNumber(int number) {
              return RpcType.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(0);
    }

    private static final RpcType[] VALUES = values();

    public static RpcType valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private RpcType(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.RpcType)
  }

  /**
   * Protobuf enum {@code exec.user.SaslSupport}
   */
  public enum SaslSupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>UNKNOWN_SASL_SUPPORT = 0;</code>
     */
    UNKNOWN_SASL_SUPPORT(0),
    /**
     * <code>SASL_AUTH = 1;</code>
     */
    SASL_AUTH(1),
    /**
     * <code>SASL_PRIVACY = 2;</code>
     */
    SASL_PRIVACY(2),
    ;

    /**
     * <code>UNKNOWN_SASL_SUPPORT = 0;</code>
     */
    public static final int UNKNOWN_SASL_SUPPORT_VALUE = 0;
    /**
     * <code>SASL_AUTH = 1;</code>
     */
    public static final int SASL_AUTH_VALUE = 1;
    /**
     * <code>SASL_PRIVACY = 2;</code>
     */
    public static final int SASL_PRIVACY_VALUE = 2;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static SaslSupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static SaslSupport forNumber(int value) {
      switch (value) {
        case 0: return UNKNOWN_SASL_SUPPORT;
        case 1: return SASL_AUTH;
        case 2: return SASL_PRIVACY;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<SaslSupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        SaslSupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<SaslSupport>() {
            public SaslSupport findValueByNumber(int number) {
              return SaslSupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(1);
    }

    private static final SaslSupport[] VALUES = values();

    public static SaslSupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private SaslSupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.SaslSupport)
  }

  /**
   * Protobuf enum {@code exec.user.QueryResultsMode}
   */
  public enum QueryResultsMode
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Server will inform the client regularly on the status of the query. Once the query is completed, service will inform the client as each query chunk is made available.
     * </pre>
     *
     * <code>STREAM_FULL = 1;</code>
     */
    STREAM_FULL(1),
    ;

    /**
     * <pre>
     * Server will inform the client regularly on the status of the query. Once the query is completed, service will inform the client as each query chunk is made available.
     * </pre>
     *
     * <code>STREAM_FULL = 1;</code>
     */
    public static final int STREAM_FULL_VALUE = 1;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static QueryResultsMode valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static QueryResultsMode forNumber(int value) {
      switch (value) {
        case 1: return STREAM_FULL;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<QueryResultsMode>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        QueryResultsMode> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<QueryResultsMode>() {
            public QueryResultsMode findValueByNumber(int number) {
              return QueryResultsMode.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(2);
    }

    private static final QueryResultsMode[] VALUES = values();

    public static QueryResultsMode valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private QueryResultsMode(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.QueryResultsMode)
  }

  /**
   * Protobuf enum {@code exec.user.HandshakeStatus}
   */
  public enum HandshakeStatus
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Handshake is successful (including authentication if any)
     * </pre>
     *
     * <code>SUCCESS = 1;</code>
     */
    SUCCESS(1),
    /**
     * <pre>
     * Client and Server RPC versions are different
     * </pre>
     *
     * <code>RPC_VERSION_MISMATCH = 2;</code>
     */
    RPC_VERSION_MISMATCH(2),
    /**
     * <pre>
     * User authentication failed
     * </pre>
     *
     * <code>AUTH_FAILED = 3;</code>
     */
    AUTH_FAILED(3),
    /**
     * <pre>
     * Unknown failure, refer to the error message for more details
     * </pre>
     *
     * <code>UNKNOWN_FAILURE = 4;</code>
     */
    UNKNOWN_FAILURE(4),
    /**
     * <pre>
     * User authentication required
     * </pre>
     *
     * <code>AUTH_REQUIRED = 5;</code>
     */
    AUTH_REQUIRED(5),
    ;

    /**
     * <pre>
     * Handshake is successful (including authentication if any)
     * </pre>
     *
     * <code>SUCCESS = 1;</code>
     */
    public static final int SUCCESS_VALUE = 1;
    /**
     * <pre>
     * Client and Server RPC versions are different
     * </pre>
     *
     * <code>RPC_VERSION_MISMATCH = 2;</code>
     */
    public static final int RPC_VERSION_MISMATCH_VALUE = 2;
    /**
     * <pre>
     * User authentication failed
     * </pre>
     *
     * <code>AUTH_FAILED = 3;</code>
     */
    public static final int AUTH_FAILED_VALUE = 3;
    /**
     * <pre>
     * Unknown failure, refer to the error message for more details
     * </pre>
     *
     * <code>UNKNOWN_FAILURE = 4;</code>
     */
    public static final int UNKNOWN_FAILURE_VALUE = 4;
    /**
     * <pre>
     * User authentication required
     * </pre>
     *
     * <code>AUTH_REQUIRED = 5;</code>
     */
    public static final int AUTH_REQUIRED_VALUE = 5;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static HandshakeStatus valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static HandshakeStatus forNumber(int value) {
      switch (value) {
        case 1: return SUCCESS;
        case 2: return RPC_VERSION_MISMATCH;
        case 3: return AUTH_FAILED;
        case 4: return UNKNOWN_FAILURE;
        case 5: return AUTH_REQUIRED;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<HandshakeStatus>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        HandshakeStatus> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<HandshakeStatus>() {
            public HandshakeStatus findValueByNumber(int number) {
              return HandshakeStatus.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(3);
    }

    private static final HandshakeStatus[] VALUES = values();

    public static HandshakeStatus valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private HandshakeStatus(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.HandshakeStatus)
  }

  /**
   * <pre>
   * Enum indicating the request status.
   * </pre>
   *
   * Protobuf enum {@code exec.user.RequestStatus}
   */
  public enum RequestStatus
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>UNKNOWN_STATUS = 0;</code>
     */
    UNKNOWN_STATUS(0),
    /**
     * <code>OK = 1;</code>
     */
    OK(1),
    /**
     * <code>FAILED = 2;</code>
     */
    FAILED(2),
    /**
     * <pre>
     **
     * Request timed out. Futher attempts can change any API specific parameters and retry or just retry the request.
     * </pre>
     *
     * <code>TIMEOUT = 3;</code>
     */
    TIMEOUT(3),
    ;

    /**
     * <code>UNKNOWN_STATUS = 0;</code>
     */
    public static final int UNKNOWN_STATUS_VALUE = 0;
    /**
     * <code>OK = 1;</code>
     */
    public static final int OK_VALUE = 1;
    /**
     * <code>FAILED = 2;</code>
     */
    public static final int FAILED_VALUE = 2;
    /**
     * <pre>
     **
     * Request timed out. Futher attempts can change any API specific parameters and retry or just retry the request.
     * </pre>
     *
     * <code>TIMEOUT = 3;</code>
     */
    public static final int TIMEOUT_VALUE = 3;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static RequestStatus valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static RequestStatus forNumber(int value) {
      switch (value) {
        case 0: return UNKNOWN_STATUS;
        case 1: return OK;
        case 2: return FAILED;
        case 3: return TIMEOUT;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<RequestStatus>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        RequestStatus> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<RequestStatus>() {
            public RequestStatus findValueByNumber(int number) {
              return RequestStatus.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(4);
    }

    private static final RequestStatus[] VALUES = values();

    public static RequestStatus valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private RequestStatus(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.RequestStatus)
  }

  /**
   * <pre>
   * How a column can be used in WHERE clause
   * </pre>
   *
   * Protobuf enum {@code exec.user.ColumnSearchability}
   */
  public enum ColumnSearchability
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>UNKNOWN_SEARCHABILITY = 0;</code>
     */
    UNKNOWN_SEARCHABILITY(0),
    /**
     * <pre>
     * can't be used in WHERE clause
     * </pre>
     *
     * <code>NONE = 1;</code>
     */
    NONE(1),
    /**
     * <pre>
     * can be used in WHERE clause but only with LIKE predicate
     * </pre>
     *
     * <code>CHAR = 2;</code>
     */
    CHAR(2),
    /**
     * <pre>
     * can be used in a WHERE clause with all the comparison operators except LIKE
     * </pre>
     *
     * <code>NUMBER = 3;</code>
     */
    NUMBER(3),
    /**
     * <pre>
     * can be used in a WHERE clause with all the comparison operators
     * </pre>
     *
     * <code>ALL = 4;</code>
     */
    ALL(4),
    ;

    /**
     * <code>UNKNOWN_SEARCHABILITY = 0;</code>
     */
    public static final int UNKNOWN_SEARCHABILITY_VALUE = 0;
    /**
     * <pre>
     * can't be used in WHERE clause
     * </pre>
     *
     * <code>NONE = 1;</code>
     */
    public static final int NONE_VALUE = 1;
    /**
     * <pre>
     * can be used in WHERE clause but only with LIKE predicate
     * </pre>
     *
     * <code>CHAR = 2;</code>
     */
    public static final int CHAR_VALUE = 2;
    /**
     * <pre>
     * can be used in a WHERE clause with all the comparison operators except LIKE
     * </pre>
     *
     * <code>NUMBER = 3;</code>
     */
    public static final int NUMBER_VALUE = 3;
    /**
     * <pre>
     * can be used in a WHERE clause with all the comparison operators
     * </pre>
     *
     * <code>ALL = 4;</code>
     */
    public static final int ALL_VALUE = 4;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static ColumnSearchability valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static ColumnSearchability forNumber(int value) {
      switch (value) {
        case 0: return UNKNOWN_SEARCHABILITY;
        case 1: return NONE;
        case 2: return CHAR;
        case 3: return NUMBER;
        case 4: return ALL;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<ColumnSearchability>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        ColumnSearchability> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<ColumnSearchability>() {
            public ColumnSearchability findValueByNumber(int number) {
              return ColumnSearchability.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(5);
    }

    private static final ColumnSearchability[] VALUES = values();

    public static ColumnSearchability valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private ColumnSearchability(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.ColumnSearchability)
  }

  /**
   * <pre>
   * Whether a column can be updatable.
   * </pre>
   *
   * Protobuf enum {@code exec.user.ColumnUpdatability}
   */
  public enum ColumnUpdatability
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <code>UNKNOWN_UPDATABILITY = 0;</code>
     */
    UNKNOWN_UPDATABILITY(0),
    /**
     * <code>READ_ONLY = 1;</code>
     */
    READ_ONLY(1),
    /**
     * <code>WRITABLE = 2;</code>
     */
    WRITABLE(2),
    ;

    /**
     * <code>UNKNOWN_UPDATABILITY = 0;</code>
     */
    public static final int UNKNOWN_UPDATABILITY_VALUE = 0;
    /**
     * <code>READ_ONLY = 1;</code>
     */
    public static final int READ_ONLY_VALUE = 1;
    /**
     * <code>WRITABLE = 2;</code>
     */
    public static final int WRITABLE_VALUE = 2;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static ColumnUpdatability valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static ColumnUpdatability forNumber(int value) {
      switch (value) {
        case 0: return UNKNOWN_UPDATABILITY;
        case 1: return READ_ONLY;
        case 2: return WRITABLE;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<ColumnUpdatability>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        ColumnUpdatability> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<ColumnUpdatability>() {
            public ColumnUpdatability findValueByNumber(int number) {
              return ColumnUpdatability.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(6);
    }

    private static final ColumnUpdatability[] VALUES = values();

    public static ColumnUpdatability valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private ColumnUpdatability(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.ColumnUpdatability)
  }

  /**
   * Protobuf enum {@code exec.user.CollateSupport}
   */
  public enum CollateSupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>CS_UNKNOWN = 0;</code>
     */
    CS_UNKNOWN(0),
    /**
     * <pre>
     * COLLATE clause can be added after each grouping column
     * </pre>
     *
     * <code>CS_GROUP_BY = 1;</code>
     */
    CS_GROUP_BY(1),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>CS_UNKNOWN = 0;</code>
     */
    public static final int CS_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * COLLATE clause can be added after each grouping column
     * </pre>
     *
     * <code>CS_GROUP_BY = 1;</code>
     */
    public static final int CS_GROUP_BY_VALUE = 1;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static CollateSupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static CollateSupport forNumber(int value) {
      switch (value) {
        case 0: return CS_UNKNOWN;
        case 1: return CS_GROUP_BY;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<CollateSupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        CollateSupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<CollateSupport>() {
            public CollateSupport findValueByNumber(int number) {
              return CollateSupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(7);
    }

    private static final CollateSupport[] VALUES = values();

    public static CollateSupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private CollateSupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.CollateSupport)
  }

  /**
   * Protobuf enum {@code exec.user.CorrelationNamesSupport}
   */
  public enum CorrelationNamesSupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Correlation names are not supported
     * </pre>
     *
     * <code>CN_NONE = 1;</code>
     */
    CN_NONE(1),
    /**
     * <pre>
     * Correlation names are supported, but names have to
     * </pre>
     *
     * <code>CN_DIFFERENT_NAMES = 2;</code>
     */
    CN_DIFFERENT_NAMES(2),
    /**
     * <pre>
     * be different from the tables they represent
     * </pre>
     *
     * <code>CN_ANY = 3;</code>
     */
    CN_ANY(3),
    ;

    /**
     * <pre>
     * Correlation names are not supported
     * </pre>
     *
     * <code>CN_NONE = 1;</code>
     */
    public static final int CN_NONE_VALUE = 1;
    /**
     * <pre>
     * Correlation names are supported, but names have to
     * </pre>
     *
     * <code>CN_DIFFERENT_NAMES = 2;</code>
     */
    public static final int CN_DIFFERENT_NAMES_VALUE = 2;
    /**
     * <pre>
     * be different from the tables they represent
     * </pre>
     *
     * <code>CN_ANY = 3;</code>
     */
    public static final int CN_ANY_VALUE = 3;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static CorrelationNamesSupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static CorrelationNamesSupport forNumber(int value) {
      switch (value) {
        case 1: return CN_NONE;
        case 2: return CN_DIFFERENT_NAMES;
        case 3: return CN_ANY;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<CorrelationNamesSupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        CorrelationNamesSupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<CorrelationNamesSupport>() {
            public CorrelationNamesSupport findValueByNumber(int number) {
              return CorrelationNamesSupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(8);
    }

    private static final CorrelationNamesSupport[] VALUES = values();

    public static CorrelationNamesSupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private CorrelationNamesSupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.CorrelationNamesSupport)
  }

  /**
   * Protobuf enum {@code exec.user.DateTimeLiteralsSupport}
   */
  public enum DateTimeLiteralsSupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>DL_UNKNOWN = 0;</code>
     */
    DL_UNKNOWN(0),
    /**
     * <pre>
     * DATE literal is supported
     * </pre>
     *
     * <code>DL_DATE = 1;</code>
     */
    DL_DATE(1),
    /**
     * <pre>
     * TIME literal is supported
     * </pre>
     *
     * <code>DL_TIME = 2;</code>
     */
    DL_TIME(2),
    /**
     * <pre>
     * TIMESTAMP literal is supported
     * </pre>
     *
     * <code>DL_TIMESTAMP = 3;</code>
     */
    DL_TIMESTAMP(3),
    /**
     * <pre>
     * INTERVAL YEAR literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_YEAR = 4;</code>
     */
    DL_INTERVAL_YEAR(4),
    /**
     * <pre>
     * INTERVAL MONTH literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_MONTH = 5;</code>
     */
    DL_INTERVAL_MONTH(5),
    /**
     * <pre>
     * INTERVAL DAY literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY = 6;</code>
     */
    DL_INTERVAL_DAY(6),
    /**
     * <pre>
     * INTERVAL HOUR literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_HOUR = 7;</code>
     */
    DL_INTERVAL_HOUR(7),
    /**
     * <pre>
     * INTERVAL MINUTE literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_MINUTE = 8;</code>
     */
    DL_INTERVAL_MINUTE(8),
    /**
     * <pre>
     * INTERVAL SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_SECOND = 9;</code>
     */
    DL_INTERVAL_SECOND(9),
    /**
     * <pre>
     * INTERVAL YEAR TO MONTH literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_YEAR_TO_MONTH = 10;</code>
     */
    DL_INTERVAL_YEAR_TO_MONTH(10),
    /**
     * <pre>
     * INTERVAL DAY TO HOUR literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY_TO_HOUR = 11;</code>
     */
    DL_INTERVAL_DAY_TO_HOUR(11),
    /**
     * <pre>
     * INTERVAL DAY TO MINUTE literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY_TO_MINUTE = 12;</code>
     */
    DL_INTERVAL_DAY_TO_MINUTE(12),
    /**
     * <pre>
     * INTERVAL DAY TO SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY_TO_SECOND = 13;</code>
     */
    DL_INTERVAL_DAY_TO_SECOND(13),
    /**
     * <pre>
     * INTERVAL HOUR TO MINUTE literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_HOUR_TO_MINUTE = 14;</code>
     */
    DL_INTERVAL_HOUR_TO_MINUTE(14),
    /**
     * <pre>
     * INTERVAL HOUR TO SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_HOUR_TO_SECOND = 15;</code>
     */
    DL_INTERVAL_HOUR_TO_SECOND(15),
    /**
     * <pre>
     * INTERVAL MINUTE TO SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_MINUTE_TO_SECOND = 16;</code>
     */
    DL_INTERVAL_MINUTE_TO_SECOND(16),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>DL_UNKNOWN = 0;</code>
     */
    public static final int DL_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * DATE literal is supported
     * </pre>
     *
     * <code>DL_DATE = 1;</code>
     */
    public static final int DL_DATE_VALUE = 1;
    /**
     * <pre>
     * TIME literal is supported
     * </pre>
     *
     * <code>DL_TIME = 2;</code>
     */
    public static final int DL_TIME_VALUE = 2;
    /**
     * <pre>
     * TIMESTAMP literal is supported
     * </pre>
     *
     * <code>DL_TIMESTAMP = 3;</code>
     */
    public static final int DL_TIMESTAMP_VALUE = 3;
    /**
     * <pre>
     * INTERVAL YEAR literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_YEAR = 4;</code>
     */
    public static final int DL_INTERVAL_YEAR_VALUE = 4;
    /**
     * <pre>
     * INTERVAL MONTH literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_MONTH = 5;</code>
     */
    public static final int DL_INTERVAL_MONTH_VALUE = 5;
    /**
     * <pre>
     * INTERVAL DAY literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY = 6;</code>
     */
    public static final int DL_INTERVAL_DAY_VALUE = 6;
    /**
     * <pre>
     * INTERVAL HOUR literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_HOUR = 7;</code>
     */
    public static final int DL_INTERVAL_HOUR_VALUE = 7;
    /**
     * <pre>
     * INTERVAL MINUTE literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_MINUTE = 8;</code>
     */
    public static final int DL_INTERVAL_MINUTE_VALUE = 8;
    /**
     * <pre>
     * INTERVAL SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_SECOND = 9;</code>
     */
    public static final int DL_INTERVAL_SECOND_VALUE = 9;
    /**
     * <pre>
     * INTERVAL YEAR TO MONTH literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_YEAR_TO_MONTH = 10;</code>
     */
    public static final int DL_INTERVAL_YEAR_TO_MONTH_VALUE = 10;
    /**
     * <pre>
     * INTERVAL DAY TO HOUR literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY_TO_HOUR = 11;</code>
     */
    public static final int DL_INTERVAL_DAY_TO_HOUR_VALUE = 11;
    /**
     * <pre>
     * INTERVAL DAY TO MINUTE literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY_TO_MINUTE = 12;</code>
     */
    public static final int DL_INTERVAL_DAY_TO_MINUTE_VALUE = 12;
    /**
     * <pre>
     * INTERVAL DAY TO SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_DAY_TO_SECOND = 13;</code>
     */
    public static final int DL_INTERVAL_DAY_TO_SECOND_VALUE = 13;
    /**
     * <pre>
     * INTERVAL HOUR TO MINUTE literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_HOUR_TO_MINUTE = 14;</code>
     */
    public static final int DL_INTERVAL_HOUR_TO_MINUTE_VALUE = 14;
    /**
     * <pre>
     * INTERVAL HOUR TO SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_HOUR_TO_SECOND = 15;</code>
     */
    public static final int DL_INTERVAL_HOUR_TO_SECOND_VALUE = 15;
    /**
     * <pre>
     * INTERVAL MINUTE TO SECOND literal is supported
     * </pre>
     *
     * <code>DL_INTERVAL_MINUTE_TO_SECOND = 16;</code>
     */
    public static final int DL_INTERVAL_MINUTE_TO_SECOND_VALUE = 16;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static DateTimeLiteralsSupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static DateTimeLiteralsSupport forNumber(int value) {
      switch (value) {
        case 0: return DL_UNKNOWN;
        case 1: return DL_DATE;
        case 2: return DL_TIME;
        case 3: return DL_TIMESTAMP;
        case 4: return DL_INTERVAL_YEAR;
        case 5: return DL_INTERVAL_MONTH;
        case 6: return DL_INTERVAL_DAY;
        case 7: return DL_INTERVAL_HOUR;
        case 8: return DL_INTERVAL_MINUTE;
        case 9: return DL_INTERVAL_SECOND;
        case 10: return DL_INTERVAL_YEAR_TO_MONTH;
        case 11: return DL_INTERVAL_DAY_TO_HOUR;
        case 12: return DL_INTERVAL_DAY_TO_MINUTE;
        case 13: return DL_INTERVAL_DAY_TO_SECOND;
        case 14: return DL_INTERVAL_HOUR_TO_MINUTE;
        case 15: return DL_INTERVAL_HOUR_TO_SECOND;
        case 16: return DL_INTERVAL_MINUTE_TO_SECOND;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<DateTimeLiteralsSupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        DateTimeLiteralsSupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<DateTimeLiteralsSupport>() {
            public DateTimeLiteralsSupport findValueByNumber(int number) {
              return DateTimeLiteralsSupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(9);
    }

    private static final DateTimeLiteralsSupport[] VALUES = values();

    public static DateTimeLiteralsSupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private DateTimeLiteralsSupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.DateTimeLiteralsSupport)
  }

  /**
   * Protobuf enum {@code exec.user.GroupBySupport}
   */
  public enum GroupBySupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Group by is not supported
     * </pre>
     *
     * <code>GB_NONE = 1;</code>
     */
    GB_NONE(1),
    /**
     * <pre>
     * Group by supported with non aggregated columns in select
     * </pre>
     *
     * <code>GB_SELECT_ONLY = 2;</code>
     */
    GB_SELECT_ONLY(2),
    /**
     * <pre>
     * Group by supported with columns absent from the select list
     *if all the non-aggregated colums from the select list are also added 
     * </pre>
     *
     * <code>GB_BEYOND_SELECT = 3;</code>
     */
    GB_BEYOND_SELECT(3),
    /**
     * <pre>
     * Group by supported with columns absent from the select list
     * </pre>
     *
     * <code>GB_UNRELATED = 4;</code>
     */
    GB_UNRELATED(4),
    ;

    /**
     * <pre>
     * Group by is not supported
     * </pre>
     *
     * <code>GB_NONE = 1;</code>
     */
    public static final int GB_NONE_VALUE = 1;
    /**
     * <pre>
     * Group by supported with non aggregated columns in select
     * </pre>
     *
     * <code>GB_SELECT_ONLY = 2;</code>
     */
    public static final int GB_SELECT_ONLY_VALUE = 2;
    /**
     * <pre>
     * Group by supported with columns absent from the select list
     *if all the non-aggregated colums from the select list are also added 
     * </pre>
     *
     * <code>GB_BEYOND_SELECT = 3;</code>
     */
    public static final int GB_BEYOND_SELECT_VALUE = 3;
    /**
     * <pre>
     * Group by supported with columns absent from the select list
     * </pre>
     *
     * <code>GB_UNRELATED = 4;</code>
     */
    public static final int GB_UNRELATED_VALUE = 4;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static GroupBySupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static GroupBySupport forNumber(int value) {
      switch (value) {
        case 1: return GB_NONE;
        case 2: return GB_SELECT_ONLY;
        case 3: return GB_BEYOND_SELECT;
        case 4: return GB_UNRELATED;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<GroupBySupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        GroupBySupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<GroupBySupport>() {
            public GroupBySupport findValueByNumber(int number) {
              return GroupBySupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(10);
    }

    private static final GroupBySupport[] VALUES = values();

    public static GroupBySupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private GroupBySupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.GroupBySupport)
  }

  /**
   * Protobuf enum {@code exec.user.IdentifierCasing}
   */
  public enum IdentifierCasing
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>IC_UNKNOWN = 0;</code>
     */
    IC_UNKNOWN(0),
    /**
     * <pre>
     * Mixed case identifier is treated as case insensitive
     *and stored in lower case 
     * </pre>
     *
     * <code>IC_STORES_LOWER = 1;</code>
     */
    IC_STORES_LOWER(1),
    /**
     * <pre>
     * Mixed case identifier is treated as case insensitive
     *and stored in mixed case 
     * </pre>
     *
     * <code>IC_STORES_MIXED = 2;</code>
     */
    IC_STORES_MIXED(2),
    /**
     * <pre>
     * Mixed case identifier is treated as case insensitive
     *and stored in upper case 
     * </pre>
     *
     * <code>IC_STORES_UPPER = 3;</code>
     */
    IC_STORES_UPPER(3),
    /**
     * <pre>
     * Mixed case identifier is treated as case sensitive
     *and stored in mixed case 
     * </pre>
     *
     * <code>IC_SUPPORTS_MIXED = 4;</code>
     */
    IC_SUPPORTS_MIXED(4),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>IC_UNKNOWN = 0;</code>
     */
    public static final int IC_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * Mixed case identifier is treated as case insensitive
     *and stored in lower case 
     * </pre>
     *
     * <code>IC_STORES_LOWER = 1;</code>
     */
    public static final int IC_STORES_LOWER_VALUE = 1;
    /**
     * <pre>
     * Mixed case identifier is treated as case insensitive
     *and stored in mixed case 
     * </pre>
     *
     * <code>IC_STORES_MIXED = 2;</code>
     */
    public static final int IC_STORES_MIXED_VALUE = 2;
    /**
     * <pre>
     * Mixed case identifier is treated as case insensitive
     *and stored in upper case 
     * </pre>
     *
     * <code>IC_STORES_UPPER = 3;</code>
     */
    public static final int IC_STORES_UPPER_VALUE = 3;
    /**
     * <pre>
     * Mixed case identifier is treated as case sensitive
     *and stored in mixed case 
     * </pre>
     *
     * <code>IC_SUPPORTS_MIXED = 4;</code>
     */
    public static final int IC_SUPPORTS_MIXED_VALUE = 4;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static IdentifierCasing valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static IdentifierCasing forNumber(int value) {
      switch (value) {
        case 0: return IC_UNKNOWN;
        case 1: return IC_STORES_LOWER;
        case 2: return IC_STORES_MIXED;
        case 3: return IC_STORES_UPPER;
        case 4: return IC_SUPPORTS_MIXED;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<IdentifierCasing>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        IdentifierCasing> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<IdentifierCasing>() {
            public IdentifierCasing findValueByNumber(int number) {
              return IdentifierCasing.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(11);
    }

    private static final IdentifierCasing[] VALUES = values();

    public static IdentifierCasing valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private IdentifierCasing(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.IdentifierCasing)
  }

  /**
   * Protobuf enum {@code exec.user.NullCollation}
   */
  public enum NullCollation
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>NC_UNKNOWN = 0;</code>
     */
    NC_UNKNOWN(0),
    /**
     * <pre>
     * NULL values are sorted at the start regardless of the order
     * </pre>
     *
     * <code>NC_AT_START = 1;</code>
     */
    NC_AT_START(1),
    /**
     * <pre>
     * NULL values are sorted at the end regardless of the order
     * </pre>
     *
     * <code>NC_AT_END = 2;</code>
     */
    NC_AT_END(2),
    /**
     * <pre>
     * NULL is the highest value
     * </pre>
     *
     * <code>NC_HIGH = 3;</code>
     */
    NC_HIGH(3),
    /**
     * <pre>
     * NULL is the lowest value
     * </pre>
     *
     * <code>NC_LOW = 4;</code>
     */
    NC_LOW(4),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>NC_UNKNOWN = 0;</code>
     */
    public static final int NC_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * NULL values are sorted at the start regardless of the order
     * </pre>
     *
     * <code>NC_AT_START = 1;</code>
     */
    public static final int NC_AT_START_VALUE = 1;
    /**
     * <pre>
     * NULL values are sorted at the end regardless of the order
     * </pre>
     *
     * <code>NC_AT_END = 2;</code>
     */
    public static final int NC_AT_END_VALUE = 2;
    /**
     * <pre>
     * NULL is the highest value
     * </pre>
     *
     * <code>NC_HIGH = 3;</code>
     */
    public static final int NC_HIGH_VALUE = 3;
    /**
     * <pre>
     * NULL is the lowest value
     * </pre>
     *
     * <code>NC_LOW = 4;</code>
     */
    public static final int NC_LOW_VALUE = 4;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static NullCollation valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static NullCollation forNumber(int value) {
      switch (value) {
        case 0: return NC_UNKNOWN;
        case 1: return NC_AT_START;
        case 2: return NC_AT_END;
        case 3: return NC_HIGH;
        case 4: return NC_LOW;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<NullCollation>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        NullCollation> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<NullCollation>() {
            public NullCollation findValueByNumber(int number) {
              return NullCollation.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(12);
    }

    private static final NullCollation[] VALUES = values();

    public static NullCollation valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private NullCollation(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.NullCollation)
  }

  /**
   * Protobuf enum {@code exec.user.OrderBySupport}
   */
  public enum OrderBySupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>OB_UNKNOWN = 0;</code>
     */
    OB_UNKNOWN(0),
    /**
     * <pre>
     * ORDER BY supported with columns not in SELECT list
     * </pre>
     *
     * <code>OB_UNRELATED = 1;</code>
     */
    OB_UNRELATED(1),
    /**
     * <pre>
     * ORDER BY with expressions is supported
     * </pre>
     *
     * <code>OB_EXPRESSION = 2;</code>
     */
    OB_EXPRESSION(2),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>OB_UNKNOWN = 0;</code>
     */
    public static final int OB_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * ORDER BY supported with columns not in SELECT list
     * </pre>
     *
     * <code>OB_UNRELATED = 1;</code>
     */
    public static final int OB_UNRELATED_VALUE = 1;
    /**
     * <pre>
     * ORDER BY with expressions is supported
     * </pre>
     *
     * <code>OB_EXPRESSION = 2;</code>
     */
    public static final int OB_EXPRESSION_VALUE = 2;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static OrderBySupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static OrderBySupport forNumber(int value) {
      switch (value) {
        case 0: return OB_UNKNOWN;
        case 1: return OB_UNRELATED;
        case 2: return OB_EXPRESSION;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<OrderBySupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        OrderBySupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<OrderBySupport>() {
            public OrderBySupport findValueByNumber(int number) {
              return OrderBySupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(13);
    }

    private static final OrderBySupport[] VALUES = values();

    public static OrderBySupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private OrderBySupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.OrderBySupport)
  }

  /**
   * Protobuf enum {@code exec.user.OuterJoinSupport}
   */
  public enum OuterJoinSupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>OJ_UNKNOWN = 0;</code>
     */
    OJ_UNKNOWN(0),
    /**
     * <pre>
     * Left outer join is supported
     * </pre>
     *
     * <code>OJ_LEFT = 1;</code>
     */
    OJ_LEFT(1),
    /**
     * <pre>
     * Right outer join is supported
     * </pre>
     *
     * <code>OJ_RIGHT = 2;</code>
     */
    OJ_RIGHT(2),
    /**
     * <pre>
     * Full outer join is supported
     * </pre>
     *
     * <code>OJ_FULL = 3;</code>
     */
    OJ_FULL(3),
    /**
     * <pre>
     * Nested outer join is supported
     * </pre>
     *
     * <code>OJ_NESTED = 4;</code>
     */
    OJ_NESTED(4),
    /**
     * <pre>
     * Column names in the ON clause don't have to share the same order
     *as their respective table names in the OUTER JOIN clase 
     * </pre>
     *
     * <code>OJ_NOT_ORDERED = 5;</code>
     */
    OJ_NOT_ORDERED(5),
    /**
     * <pre>
     * Inner table can also be used in an inner join
     * </pre>
     *
     * <code>OJ_INNER = 6;</code>
     */
    OJ_INNER(6),
    /**
     * <pre>
     * Any comparison operator is supported in the ON clause
     * </pre>
     *
     * <code>OJ_ALL_COMPARISON_OPS = 7;</code>
     */
    OJ_ALL_COMPARISON_OPS(7),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>OJ_UNKNOWN = 0;</code>
     */
    public static final int OJ_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * Left outer join is supported
     * </pre>
     *
     * <code>OJ_LEFT = 1;</code>
     */
    public static final int OJ_LEFT_VALUE = 1;
    /**
     * <pre>
     * Right outer join is supported
     * </pre>
     *
     * <code>OJ_RIGHT = 2;</code>
     */
    public static final int OJ_RIGHT_VALUE = 2;
    /**
     * <pre>
     * Full outer join is supported
     * </pre>
     *
     * <code>OJ_FULL = 3;</code>
     */
    public static final int OJ_FULL_VALUE = 3;
    /**
     * <pre>
     * Nested outer join is supported
     * </pre>
     *
     * <code>OJ_NESTED = 4;</code>
     */
    public static final int OJ_NESTED_VALUE = 4;
    /**
     * <pre>
     * Column names in the ON clause don't have to share the same order
     *as their respective table names in the OUTER JOIN clase 
     * </pre>
     *
     * <code>OJ_NOT_ORDERED = 5;</code>
     */
    public static final int OJ_NOT_ORDERED_VALUE = 5;
    /**
     * <pre>
     * Inner table can also be used in an inner join
     * </pre>
     *
     * <code>OJ_INNER = 6;</code>
     */
    public static final int OJ_INNER_VALUE = 6;
    /**
     * <pre>
     * Any comparison operator is supported in the ON clause
     * </pre>
     *
     * <code>OJ_ALL_COMPARISON_OPS = 7;</code>
     */
    public static final int OJ_ALL_COMPARISON_OPS_VALUE = 7;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static OuterJoinSupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static OuterJoinSupport forNumber(int value) {
      switch (value) {
        case 0: return OJ_UNKNOWN;
        case 1: return OJ_LEFT;
        case 2: return OJ_RIGHT;
        case 3: return OJ_FULL;
        case 4: return OJ_NESTED;
        case 5: return OJ_NOT_ORDERED;
        case 6: return OJ_INNER;
        case 7: return OJ_ALL_COMPARISON_OPS;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<OuterJoinSupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        OuterJoinSupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<OuterJoinSupport>() {
            public OuterJoinSupport findValueByNumber(int number) {
              return OuterJoinSupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(14);
    }

    private static final OuterJoinSupport[] VALUES = values();

    public static OuterJoinSupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private OuterJoinSupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.OuterJoinSupport)
  }

  /**
   * Protobuf enum {@code exec.user.SubQuerySupport}
   */
  public enum SubQuerySupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>SQ_UNKNOWN = 0;</code>
     */
    SQ_UNKNOWN(0),
    /**
     * <pre>
     * Correlated subquery is supported
     * </pre>
     *
     * <code>SQ_CORRELATED = 1;</code>
     */
    SQ_CORRELATED(1),
    /**
     * <pre>
     * Subquery in comparison expression is supported
     * </pre>
     *
     * <code>SQ_IN_COMPARISON = 2;</code>
     */
    SQ_IN_COMPARISON(2),
    /**
     * <pre>
     * Subquery in EXISTS expression is supported
     * </pre>
     *
     * <code>SQ_IN_EXISTS = 3;</code>
     */
    SQ_IN_EXISTS(3),
    /**
     * <pre>
     * Subquery in INSERT expression is supported
     * </pre>
     *
     * <code>SQ_IN_INSERT = 4;</code>
     */
    SQ_IN_INSERT(4),
    /**
     * <pre>
     * Subquery in quantified expression is supported
     * </pre>
     *
     * <code>SQ_IN_QUANTIFIED = 5;</code>
     */
    SQ_IN_QUANTIFIED(5),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>SQ_UNKNOWN = 0;</code>
     */
    public static final int SQ_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * Correlated subquery is supported
     * </pre>
     *
     * <code>SQ_CORRELATED = 1;</code>
     */
    public static final int SQ_CORRELATED_VALUE = 1;
    /**
     * <pre>
     * Subquery in comparison expression is supported
     * </pre>
     *
     * <code>SQ_IN_COMPARISON = 2;</code>
     */
    public static final int SQ_IN_COMPARISON_VALUE = 2;
    /**
     * <pre>
     * Subquery in EXISTS expression is supported
     * </pre>
     *
     * <code>SQ_IN_EXISTS = 3;</code>
     */
    public static final int SQ_IN_EXISTS_VALUE = 3;
    /**
     * <pre>
     * Subquery in INSERT expression is supported
     * </pre>
     *
     * <code>SQ_IN_INSERT = 4;</code>
     */
    public static final int SQ_IN_INSERT_VALUE = 4;
    /**
     * <pre>
     * Subquery in quantified expression is supported
     * </pre>
     *
     * <code>SQ_IN_QUANTIFIED = 5;</code>
     */
    public static final int SQ_IN_QUANTIFIED_VALUE = 5;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static SubQuerySupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static SubQuerySupport forNumber(int value) {
      switch (value) {
        case 0: return SQ_UNKNOWN;
        case 1: return SQ_CORRELATED;
        case 2: return SQ_IN_COMPARISON;
        case 3: return SQ_IN_EXISTS;
        case 4: return SQ_IN_INSERT;
        case 5: return SQ_IN_QUANTIFIED;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<SubQuerySupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        SubQuerySupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<SubQuerySupport>() {
            public SubQuerySupport findValueByNumber(int number) {
              return SubQuerySupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(15);
    }

    private static final SubQuerySupport[] VALUES = values();

    public static SubQuerySupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private SubQuerySupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.SubQuerySupport)
  }

  /**
   * Protobuf enum {@code exec.user.UnionSupport}
   */
  public enum UnionSupport
      implements com.google.protobuf.ProtocolMessageEnum {
    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>U_UNKNOWN = 0;</code>
     */
    U_UNKNOWN(0),
    /**
     * <pre>
     * UNION is supported
     * </pre>
     *
     * <code>U_UNION = 1;</code>
     */
    U_UNION(1),
    /**
     * <pre>
     * UNION_ALL is supported
     * </pre>
     *
     * <code>U_UNION_ALL = 2;</code>
     */
    U_UNION_ALL(2),
    ;

    /**
     * <pre>
     * Unknown support (for forward compatibility)
     * </pre>
     *
     * <code>U_UNKNOWN = 0;</code>
     */
    public static final int U_UNKNOWN_VALUE = 0;
    /**
     * <pre>
     * UNION is supported
     * </pre>
     *
     * <code>U_UNION = 1;</code>
     */
    public static final int U_UNION_VALUE = 1;
    /**
     * <pre>
     * UNION_ALL is supported
     * </pre>
     *
     * <code>U_UNION_ALL = 2;</code>
     */
    public static final int U_UNION_ALL_VALUE = 2;


    public final int getNumber() {
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static UnionSupport valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static UnionSupport forNumber(int value) {
      switch (value) {
        case 0: return U_UNKNOWN;
        case 1: return U_UNION;
        case 2: return U_UNION_ALL;
        default: return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<UnionSupport>
        internalGetValueMap() {
      return internalValueMap;
    }
    private static final com.google.protobuf.Internal.EnumLiteMap<
        UnionSupport> internalValueMap =
          new com.google.protobuf.Internal.EnumLiteMap<UnionSupport>() {
            public UnionSupport findValueByNumber(int number) {
              return UnionSupport.forNumber(number);
            }
          };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor
        getValueDescriptor() {
      return getDescriptor().getValues().get(ordinal());
    }
    public final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptorForType() {
      return getDescriptor();
    }
    public static final com.google.protobuf.Descriptors.EnumDescriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.getDescriptor().getEnumTypes().get(16);
    }

    private static final UnionSupport[] VALUES = values();

    public static UnionSupport valueOf(
        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException(
          "EnumValueDescriptor is not for this type.");
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private UnionSupport(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:exec.user.UnionSupport)
  }

  public interface PropertyOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.Property)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>required string key = 1;</code>
     * @return Whether the key field is set.
     */
    boolean hasKey();
    /**
     * <code>required string key = 1;</code>
     * @return The key.
     */
    java.lang.String getKey();
    /**
     * <code>required string key = 1;</code>
     * @return The bytes for key.
     */
    com.google.protobuf.ByteString
        getKeyBytes();

    /**
     * <code>required string value = 2;</code>
     * @return Whether the value field is set.
     */
    boolean hasValue();
    /**
     * <code>required string value = 2;</code>
     * @return The value.
     */
    java.lang.String getValue();
    /**
     * <code>required string value = 2;</code>
     * @return The bytes for value.
     */
    com.google.protobuf.ByteString
        getValueBytes();
  }
  /**
   * Protobuf type {@code exec.user.Property}
   */
  public static final class Property extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.Property)
      PropertyOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use Property.newBuilder() to construct.
    private Property(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private Property() {
      key_ = "";
      value_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new Property();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_Property_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_Property_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.Property.class, org.apache.drill.exec.proto.UserProtos.Property.Builder.class);
    }

    private int bitField0_;
    public static final int KEY_FIELD_NUMBER = 1;
    private volatile java.lang.Object key_;
    /**
     * <code>required string key = 1;</code>
     * @return Whether the key field is set.
     */
    @java.lang.Override
    public boolean hasKey() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>required string key = 1;</code>
     * @return The key.
     */
    @java.lang.Override
    public java.lang.String getKey() {
      java.lang.Object ref = key_;
      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()) {
          key_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string key = 1;</code>
     * @return The bytes for key.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getKeyBytes() {
      java.lang.Object ref = key_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        key_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int VALUE_FIELD_NUMBER = 2;
    private volatile java.lang.Object value_;
    /**
     * <code>required string value = 2;</code>
     * @return Whether the value field is set.
     */
    @java.lang.Override
    public boolean hasValue() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>required string value = 2;</code>
     * @return The value.
     */
    @java.lang.Override
    public java.lang.String getValue() {
      java.lang.Object ref = value_;
      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()) {
          value_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string value = 2;</code>
     * @return The bytes for value.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getValueBytes() {
      java.lang.Object ref = value_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        value_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasKey()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasValue()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, key_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, value_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, key_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, value_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.Property)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.Property other = (org.apache.drill.exec.proto.UserProtos.Property) obj;

      if (hasKey() != other.hasKey()) return false;
      if (hasKey()) {
        if (!getKey()
            .equals(other.getKey())) return false;
      }
      if (hasValue() != other.hasValue()) return false;
      if (hasValue()) {
        if (!getValue()
            .equals(other.getValue())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasKey()) {
        hash = (37 * hash) + KEY_FIELD_NUMBER;
        hash = (53 * hash) + getKey().hashCode();
      }
      if (hasValue()) {
        hash = (37 * hash) + VALUE_FIELD_NUMBER;
        hash = (53 * hash) + getValue().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property 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.drill.exec.proto.UserProtos.Property parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.Property parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.Property prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.Property}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.Property)
        org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_Property_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_Property_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.Property.class, org.apache.drill.exec.proto.UserProtos.Property.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.Property.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        key_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        value_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_Property_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.Property getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.Property.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.Property build() {
        org.apache.drill.exec.proto.UserProtos.Property result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.Property buildPartial() {
        org.apache.drill.exec.proto.UserProtos.Property result = new org.apache.drill.exec.proto.UserProtos.Property(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.key_ = key_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.value_ = value_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.Property) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.Property)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.Property other) {
        if (other == org.apache.drill.exec.proto.UserProtos.Property.getDefaultInstance()) return this;
        if (other.hasKey()) {
          bitField0_ |= 0x00000001;
          key_ = other.key_;
          onChanged();
        }
        if (other.hasValue()) {
          bitField0_ |= 0x00000002;
          value_ = other.value_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        if (!hasKey()) {
          return false;
        }
        if (!hasValue()) {
          return false;
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                key_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                value_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object key_ = "";
      /**
       * <code>required string key = 1;</code>
       * @return Whether the key field is set.
       */
      public boolean hasKey() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>required string key = 1;</code>
       * @return The key.
       */
      public java.lang.String getKey() {
        java.lang.Object ref = key_;
        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()) {
            key_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string key = 1;</code>
       * @return The bytes for key.
       */
      public com.google.protobuf.ByteString
          getKeyBytes() {
        java.lang.Object ref = key_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          key_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string key = 1;</code>
       * @param value The key to set.
       * @return This builder for chaining.
       */
      public Builder setKey(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        key_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string key = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearKey() {
        bitField0_ = (bitField0_ & ~0x00000001);
        key_ = getDefaultInstance().getKey();
        onChanged();
        return this;
      }
      /**
       * <code>required string key = 1;</code>
       * @param value The bytes for key to set.
       * @return This builder for chaining.
       */
      public Builder setKeyBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        key_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object value_ = "";
      /**
       * <code>required string value = 2;</code>
       * @return Whether the value field is set.
       */
      public boolean hasValue() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>required string value = 2;</code>
       * @return The value.
       */
      public java.lang.String getValue() {
        java.lang.Object ref = value_;
        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()) {
            value_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string value = 2;</code>
       * @return The bytes for value.
       */
      public com.google.protobuf.ByteString
          getValueBytes() {
        java.lang.Object ref = value_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          value_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string value = 2;</code>
       * @param value The value to set.
       * @return This builder for chaining.
       */
      public Builder setValue(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        value_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string value = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearValue() {
        bitField0_ = (bitField0_ & ~0x00000002);
        value_ = getDefaultInstance().getValue();
        onChanged();
        return this;
      }
      /**
       * <code>required string value = 2;</code>
       * @param value The bytes for value to set.
       * @return This builder for chaining.
       */
      public Builder setValueBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        value_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.Property)
    }

    // @@protoc_insertion_point(class_scope:exec.user.Property)
    private static final org.apache.drill.exec.proto.UserProtos.Property DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.Property();
    }

    public static org.apache.drill.exec.proto.UserProtos.Property getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<Property>
        PARSER = new com.google.protobuf.AbstractParser<Property>() {
      @java.lang.Override
      public Property parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<Property> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<Property> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.Property getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface UserPropertiesOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.UserProperties)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.Property> 
        getPropertiesList();
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.Property getProperties(int index);
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    int getPropertiesCount();
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder> 
        getPropertiesOrBuilderList();
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder getPropertiesOrBuilder(
        int index);
  }
  /**
   * Protobuf type {@code exec.user.UserProperties}
   */
  public static final class UserProperties extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.UserProperties)
      UserPropertiesOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use UserProperties.newBuilder() to construct.
    private UserProperties(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private UserProperties() {
      properties_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new UserProperties();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserProperties_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserProperties_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.UserProperties.class, org.apache.drill.exec.proto.UserProtos.UserProperties.Builder.class);
    }

    public static final int PROPERTIES_FIELD_NUMBER = 1;
    private java.util.List<org.apache.drill.exec.proto.UserProtos.Property> properties_;
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.Property> getPropertiesList() {
      return properties_;
    }
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder> 
        getPropertiesOrBuilderList() {
      return properties_;
    }
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    @java.lang.Override
    public int getPropertiesCount() {
      return properties_.size();
    }
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.Property getProperties(int index) {
      return properties_.get(index);
    }
    /**
     * <code>repeated .exec.user.Property properties = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder getPropertiesOrBuilder(
        int index) {
      return properties_.get(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getPropertiesCount(); i++) {
        if (!getProperties(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      for (int i = 0; i < properties_.size(); i++) {
        output.writeMessage(1, properties_.get(i));
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < properties_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, properties_.get(i));
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.UserProperties)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.UserProperties other = (org.apache.drill.exec.proto.UserProtos.UserProperties) obj;

      if (!getPropertiesList()
          .equals(other.getPropertiesList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (getPropertiesCount() > 0) {
        hash = (37 * hash) + PROPERTIES_FIELD_NUMBER;
        hash = (53 * hash) + getPropertiesList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties 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.drill.exec.proto.UserProtos.UserProperties parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserProperties parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.UserProperties prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.UserProperties}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.UserProperties)
        org.apache.drill.exec.proto.UserProtos.UserPropertiesOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserProperties_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserProperties_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.UserProperties.class, org.apache.drill.exec.proto.UserProtos.UserProperties.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.UserProperties.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (propertiesBuilder_ == null) {
          properties_ = java.util.Collections.emptyList();
        } else {
          properties_ = null;
          propertiesBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserProperties_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.UserProperties getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.UserProperties.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.UserProperties build() {
        org.apache.drill.exec.proto.UserProtos.UserProperties result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.UserProperties buildPartial() {
        org.apache.drill.exec.proto.UserProtos.UserProperties result = new org.apache.drill.exec.proto.UserProtos.UserProperties(this);
        int from_bitField0_ = bitField0_;
        if (propertiesBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            properties_ = java.util.Collections.unmodifiableList(properties_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.properties_ = properties_;
        } else {
          result.properties_ = propertiesBuilder_.build();
        }
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.UserProperties) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.UserProperties)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.UserProperties other) {
        if (other == org.apache.drill.exec.proto.UserProtos.UserProperties.getDefaultInstance()) return this;
        if (propertiesBuilder_ == null) {
          if (!other.properties_.isEmpty()) {
            if (properties_.isEmpty()) {
              properties_ = other.properties_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensurePropertiesIsMutable();
              properties_.addAll(other.properties_);
            }
            onChanged();
          }
        } else {
          if (!other.properties_.isEmpty()) {
            if (propertiesBuilder_.isEmpty()) {
              propertiesBuilder_.dispose();
              propertiesBuilder_ = null;
              properties_ = other.properties_;
              bitField0_ = (bitField0_ & ~0x00000001);
              propertiesBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getPropertiesFieldBuilder() : null;
            } else {
              propertiesBuilder_.addAllMessages(other.properties_);
            }
          }
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        for (int i = 0; i < getPropertiesCount(); i++) {
          if (!getProperties(i).isInitialized()) {
            return false;
          }
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                org.apache.drill.exec.proto.UserProtos.Property m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserProtos.Property.PARSER,
                        extensionRegistry);
                if (propertiesBuilder_ == null) {
                  ensurePropertiesIsMutable();
                  properties_.add(m);
                } else {
                  propertiesBuilder_.addMessage(m);
                }
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<org.apache.drill.exec.proto.UserProtos.Property> properties_ =
        java.util.Collections.emptyList();
      private void ensurePropertiesIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          properties_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserProtos.Property>(properties_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.Property, org.apache.drill.exec.proto.UserProtos.Property.Builder, org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder> propertiesBuilder_;

      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.Property> getPropertiesList() {
        if (propertiesBuilder_ == null) {
          return java.util.Collections.unmodifiableList(properties_);
        } else {
          return propertiesBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public int getPropertiesCount() {
        if (propertiesBuilder_ == null) {
          return properties_.size();
        } else {
          return propertiesBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.Property getProperties(int index) {
        if (propertiesBuilder_ == null) {
          return properties_.get(index);
        } else {
          return propertiesBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder setProperties(
          int index, org.apache.drill.exec.proto.UserProtos.Property value) {
        if (propertiesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensurePropertiesIsMutable();
          properties_.set(index, value);
          onChanged();
        } else {
          propertiesBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder setProperties(
          int index, org.apache.drill.exec.proto.UserProtos.Property.Builder builderForValue) {
        if (propertiesBuilder_ == null) {
          ensurePropertiesIsMutable();
          properties_.set(index, builderForValue.build());
          onChanged();
        } else {
          propertiesBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder addProperties(org.apache.drill.exec.proto.UserProtos.Property value) {
        if (propertiesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensurePropertiesIsMutable();
          properties_.add(value);
          onChanged();
        } else {
          propertiesBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder addProperties(
          int index, org.apache.drill.exec.proto.UserProtos.Property value) {
        if (propertiesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensurePropertiesIsMutable();
          properties_.add(index, value);
          onChanged();
        } else {
          propertiesBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder addProperties(
          org.apache.drill.exec.proto.UserProtos.Property.Builder builderForValue) {
        if (propertiesBuilder_ == null) {
          ensurePropertiesIsMutable();
          properties_.add(builderForValue.build());
          onChanged();
        } else {
          propertiesBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder addProperties(
          int index, org.apache.drill.exec.proto.UserProtos.Property.Builder builderForValue) {
        if (propertiesBuilder_ == null) {
          ensurePropertiesIsMutable();
          properties_.add(index, builderForValue.build());
          onChanged();
        } else {
          propertiesBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder addAllProperties(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.Property> values) {
        if (propertiesBuilder_ == null) {
          ensurePropertiesIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, properties_);
          onChanged();
        } else {
          propertiesBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder clearProperties() {
        if (propertiesBuilder_ == null) {
          properties_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          propertiesBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public Builder removeProperties(int index) {
        if (propertiesBuilder_ == null) {
          ensurePropertiesIsMutable();
          properties_.remove(index);
          onChanged();
        } else {
          propertiesBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.Property.Builder getPropertiesBuilder(
          int index) {
        return getPropertiesFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder getPropertiesOrBuilder(
          int index) {
        if (propertiesBuilder_ == null) {
          return properties_.get(index);  } else {
          return propertiesBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder> 
           getPropertiesOrBuilderList() {
        if (propertiesBuilder_ != null) {
          return propertiesBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(properties_);
        }
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.Property.Builder addPropertiesBuilder() {
        return getPropertiesFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserProtos.Property.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.Property.Builder addPropertiesBuilder(
          int index) {
        return getPropertiesFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserProtos.Property.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.Property properties = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.Property.Builder> 
           getPropertiesBuilderList() {
        return getPropertiesFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.Property, org.apache.drill.exec.proto.UserProtos.Property.Builder, org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder> 
          getPropertiesFieldBuilder() {
        if (propertiesBuilder_ == null) {
          propertiesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.Property, org.apache.drill.exec.proto.UserProtos.Property.Builder, org.apache.drill.exec.proto.UserProtos.PropertyOrBuilder>(
                  properties_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          properties_ = null;
        }
        return propertiesBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.UserProperties)
    }

    // @@protoc_insertion_point(class_scope:exec.user.UserProperties)
    private static final org.apache.drill.exec.proto.UserProtos.UserProperties DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.UserProperties();
    }

    public static org.apache.drill.exec.proto.UserProtos.UserProperties getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<UserProperties>
        PARSER = new com.google.protobuf.AbstractParser<UserProperties>() {
      @java.lang.Override
      public UserProperties parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<UserProperties> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<UserProperties> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.UserProperties getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface RpcEndpointInfosOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.RpcEndpointInfos)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * example: Apache Drill Server, Apache Drill C++ client
     * </pre>
     *
     * <code>optional string name = 1;</code>
     * @return Whether the name field is set.
     */
    boolean hasName();
    /**
     * <pre>
     * example: Apache Drill Server, Apache Drill C++ client
     * </pre>
     *
     * <code>optional string name = 1;</code>
     * @return The name.
     */
    java.lang.String getName();
    /**
     * <pre>
     * example: Apache Drill Server, Apache Drill C++ client
     * </pre>
     *
     * <code>optional string name = 1;</code>
     * @return The bytes for name.
     */
    com.google.protobuf.ByteString
        getNameBytes();

    /**
     * <pre>
     * example: 1.9.0
     * </pre>
     *
     * <code>optional string version = 2;</code>
     * @return Whether the version field is set.
     */
    boolean hasVersion();
    /**
     * <pre>
     * example: 1.9.0
     * </pre>
     *
     * <code>optional string version = 2;</code>
     * @return The version.
     */
    java.lang.String getVersion();
    /**
     * <pre>
     * example: 1.9.0
     * </pre>
     *
     * <code>optional string version = 2;</code>
     * @return The bytes for version.
     */
    com.google.protobuf.ByteString
        getVersionBytes();

    /**
     * <pre>
     * example: 1
     * </pre>
     *
     * <code>optional uint32 majorVersion = 3;</code>
     * @return Whether the majorVersion field is set.
     */
    boolean hasMajorVersion();
    /**
     * <pre>
     * example: 1
     * </pre>
     *
     * <code>optional uint32 majorVersion = 3;</code>
     * @return The majorVersion.
     */
    int getMajorVersion();

    /**
     * <pre>
     * example: 9
     * </pre>
     *
     * <code>optional uint32 minorVersion = 4;</code>
     * @return Whether the minorVersion field is set.
     */
    boolean hasMinorVersion();
    /**
     * <pre>
     * example: 9
     * </pre>
     *
     * <code>optional uint32 minorVersion = 4;</code>
     * @return The minorVersion.
     */
    int getMinorVersion();

    /**
     * <pre>
     * example: 0
     * </pre>
     *
     * <code>optional uint32 patchVersion = 5;</code>
     * @return Whether the patchVersion field is set.
     */
    boolean hasPatchVersion();
    /**
     * <pre>
     * example: 0
     * </pre>
     *
     * <code>optional uint32 patchVersion = 5;</code>
     * @return The patchVersion.
     */
    int getPatchVersion();

    /**
     * <pre>
     * example: Tableau 9.3
     * </pre>
     *
     * <code>optional string application = 6;</code>
     * @return Whether the application field is set.
     */
    boolean hasApplication();
    /**
     * <pre>
     * example: Tableau 9.3
     * </pre>
     *
     * <code>optional string application = 6;</code>
     * @return The application.
     */
    java.lang.String getApplication();
    /**
     * <pre>
     * example: Tableau 9.3
     * </pre>
     *
     * <code>optional string application = 6;</code>
     * @return The bytes for application.
     */
    com.google.protobuf.ByteString
        getApplicationBytes();

    /**
     * <pre>
     * example: 32
     * </pre>
     *
     * <code>optional uint32 buildNumber = 7;</code>
     * @return Whether the buildNumber field is set.
     */
    boolean hasBuildNumber();
    /**
     * <pre>
     * example: 32
     * </pre>
     *
     * <code>optional uint32 buildNumber = 7;</code>
     * @return The buildNumber.
     */
    int getBuildNumber();

    /**
     * <pre>
     * example: SNAPSHOT
     * </pre>
     *
     * <code>optional string versionQualifier = 8;</code>
     * @return Whether the versionQualifier field is set.
     */
    boolean hasVersionQualifier();
    /**
     * <pre>
     * example: SNAPSHOT
     * </pre>
     *
     * <code>optional string versionQualifier = 8;</code>
     * @return The versionQualifier.
     */
    java.lang.String getVersionQualifier();
    /**
     * <pre>
     * example: SNAPSHOT
     * </pre>
     *
     * <code>optional string versionQualifier = 8;</code>
     * @return The bytes for versionQualifier.
     */
    com.google.protobuf.ByteString
        getVersionQualifierBytes();
  }
  /**
   * Protobuf type {@code exec.user.RpcEndpointInfos}
   */
  public static final class RpcEndpointInfos extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.RpcEndpointInfos)
      RpcEndpointInfosOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use RpcEndpointInfos.newBuilder() to construct.
    private RpcEndpointInfos(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private RpcEndpointInfos() {
      name_ = "";
      version_ = "";
      application_ = "";
      versionQualifier_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new RpcEndpointInfos();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RpcEndpointInfos_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RpcEndpointInfos_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.class, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder.class);
    }

    private int bitField0_;
    public static final int NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object name_;
    /**
     * <pre>
     * example: Apache Drill Server, Apache Drill C++ client
     * </pre>
     *
     * <code>optional string name = 1;</code>
     * @return Whether the name field is set.
     */
    @java.lang.Override
    public boolean hasName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * example: Apache Drill Server, Apache Drill C++ client
     * </pre>
     *
     * <code>optional string name = 1;</code>
     * @return The name.
     */
    @java.lang.Override
    public java.lang.String getName() {
      java.lang.Object ref = name_;
      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()) {
          name_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * example: Apache Drill Server, Apache Drill C++ client
     * </pre>
     *
     * <code>optional string name = 1;</code>
     * @return The bytes for name.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getNameBytes() {
      java.lang.Object ref = name_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        name_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int VERSION_FIELD_NUMBER = 2;
    private volatile java.lang.Object version_;
    /**
     * <pre>
     * example: 1.9.0
     * </pre>
     *
     * <code>optional string version = 2;</code>
     * @return Whether the version field is set.
     */
    @java.lang.Override
    public boolean hasVersion() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <pre>
     * example: 1.9.0
     * </pre>
     *
     * <code>optional string version = 2;</code>
     * @return The version.
     */
    @java.lang.Override
    public java.lang.String getVersion() {
      java.lang.Object ref = version_;
      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()) {
          version_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * example: 1.9.0
     * </pre>
     *
     * <code>optional string version = 2;</code>
     * @return The bytes for version.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getVersionBytes() {
      java.lang.Object ref = version_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        version_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int MAJORVERSION_FIELD_NUMBER = 3;
    private int majorVersion_;
    /**
     * <pre>
     * example: 1
     * </pre>
     *
     * <code>optional uint32 majorVersion = 3;</code>
     * @return Whether the majorVersion field is set.
     */
    @java.lang.Override
    public boolean hasMajorVersion() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <pre>
     * example: 1
     * </pre>
     *
     * <code>optional uint32 majorVersion = 3;</code>
     * @return The majorVersion.
     */
    @java.lang.Override
    public int getMajorVersion() {
      return majorVersion_;
    }

    public static final int MINORVERSION_FIELD_NUMBER = 4;
    private int minorVersion_;
    /**
     * <pre>
     * example: 9
     * </pre>
     *
     * <code>optional uint32 minorVersion = 4;</code>
     * @return Whether the minorVersion field is set.
     */
    @java.lang.Override
    public boolean hasMinorVersion() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * example: 9
     * </pre>
     *
     * <code>optional uint32 minorVersion = 4;</code>
     * @return The minorVersion.
     */
    @java.lang.Override
    public int getMinorVersion() {
      return minorVersion_;
    }

    public static final int PATCHVERSION_FIELD_NUMBER = 5;
    private int patchVersion_;
    /**
     * <pre>
     * example: 0
     * </pre>
     *
     * <code>optional uint32 patchVersion = 5;</code>
     * @return Whether the patchVersion field is set.
     */
    @java.lang.Override
    public boolean hasPatchVersion() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <pre>
     * example: 0
     * </pre>
     *
     * <code>optional uint32 patchVersion = 5;</code>
     * @return The patchVersion.
     */
    @java.lang.Override
    public int getPatchVersion() {
      return patchVersion_;
    }

    public static final int APPLICATION_FIELD_NUMBER = 6;
    private volatile java.lang.Object application_;
    /**
     * <pre>
     * example: Tableau 9.3
     * </pre>
     *
     * <code>optional string application = 6;</code>
     * @return Whether the application field is set.
     */
    @java.lang.Override
    public boolean hasApplication() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <pre>
     * example: Tableau 9.3
     * </pre>
     *
     * <code>optional string application = 6;</code>
     * @return The application.
     */
    @java.lang.Override
    public java.lang.String getApplication() {
      java.lang.Object ref = application_;
      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()) {
          application_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * example: Tableau 9.3
     * </pre>
     *
     * <code>optional string application = 6;</code>
     * @return The bytes for application.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getApplicationBytes() {
      java.lang.Object ref = application_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        application_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int BUILDNUMBER_FIELD_NUMBER = 7;
    private int buildNumber_;
    /**
     * <pre>
     * example: 32
     * </pre>
     *
     * <code>optional uint32 buildNumber = 7;</code>
     * @return Whether the buildNumber field is set.
     */
    @java.lang.Override
    public boolean hasBuildNumber() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <pre>
     * example: 32
     * </pre>
     *
     * <code>optional uint32 buildNumber = 7;</code>
     * @return The buildNumber.
     */
    @java.lang.Override
    public int getBuildNumber() {
      return buildNumber_;
    }

    public static final int VERSIONQUALIFIER_FIELD_NUMBER = 8;
    private volatile java.lang.Object versionQualifier_;
    /**
     * <pre>
     * example: SNAPSHOT
     * </pre>
     *
     * <code>optional string versionQualifier = 8;</code>
     * @return Whether the versionQualifier field is set.
     */
    @java.lang.Override
    public boolean hasVersionQualifier() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <pre>
     * example: SNAPSHOT
     * </pre>
     *
     * <code>optional string versionQualifier = 8;</code>
     * @return The versionQualifier.
     */
    @java.lang.Override
    public java.lang.String getVersionQualifier() {
      java.lang.Object ref = versionQualifier_;
      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()) {
          versionQualifier_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * example: SNAPSHOT
     * </pre>
     *
     * <code>optional string versionQualifier = 8;</code>
     * @return The bytes for versionQualifier.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getVersionQualifierBytes() {
      java.lang.Object ref = versionQualifier_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        versionQualifier_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, name_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, version_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeUInt32(3, majorVersion_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeUInt32(4, minorVersion_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeUInt32(5, patchVersion_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, application_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeUInt32(7, buildNumber_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 8, versionQualifier_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, name_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, version_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(3, majorVersion_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(4, minorVersion_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(5, patchVersion_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, application_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(7, buildNumber_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, versionQualifier_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos other = (org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos) obj;

      if (hasName() != other.hasName()) return false;
      if (hasName()) {
        if (!getName()
            .equals(other.getName())) return false;
      }
      if (hasVersion() != other.hasVersion()) return false;
      if (hasVersion()) {
        if (!getVersion()
            .equals(other.getVersion())) return false;
      }
      if (hasMajorVersion() != other.hasMajorVersion()) return false;
      if (hasMajorVersion()) {
        if (getMajorVersion()
            != other.getMajorVersion()) return false;
      }
      if (hasMinorVersion() != other.hasMinorVersion()) return false;
      if (hasMinorVersion()) {
        if (getMinorVersion()
            != other.getMinorVersion()) return false;
      }
      if (hasPatchVersion() != other.hasPatchVersion()) return false;
      if (hasPatchVersion()) {
        if (getPatchVersion()
            != other.getPatchVersion()) return false;
      }
      if (hasApplication() != other.hasApplication()) return false;
      if (hasApplication()) {
        if (!getApplication()
            .equals(other.getApplication())) return false;
      }
      if (hasBuildNumber() != other.hasBuildNumber()) return false;
      if (hasBuildNumber()) {
        if (getBuildNumber()
            != other.getBuildNumber()) return false;
      }
      if (hasVersionQualifier() != other.hasVersionQualifier()) return false;
      if (hasVersionQualifier()) {
        if (!getVersionQualifier()
            .equals(other.getVersionQualifier())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasName()) {
        hash = (37 * hash) + NAME_FIELD_NUMBER;
        hash = (53 * hash) + getName().hashCode();
      }
      if (hasVersion()) {
        hash = (37 * hash) + VERSION_FIELD_NUMBER;
        hash = (53 * hash) + getVersion().hashCode();
      }
      if (hasMajorVersion()) {
        hash = (37 * hash) + MAJORVERSION_FIELD_NUMBER;
        hash = (53 * hash) + getMajorVersion();
      }
      if (hasMinorVersion()) {
        hash = (37 * hash) + MINORVERSION_FIELD_NUMBER;
        hash = (53 * hash) + getMinorVersion();
      }
      if (hasPatchVersion()) {
        hash = (37 * hash) + PATCHVERSION_FIELD_NUMBER;
        hash = (53 * hash) + getPatchVersion();
      }
      if (hasApplication()) {
        hash = (37 * hash) + APPLICATION_FIELD_NUMBER;
        hash = (53 * hash) + getApplication().hashCode();
      }
      if (hasBuildNumber()) {
        hash = (37 * hash) + BUILDNUMBER_FIELD_NUMBER;
        hash = (53 * hash) + getBuildNumber();
      }
      if (hasVersionQualifier()) {
        hash = (37 * hash) + VERSIONQUALIFIER_FIELD_NUMBER;
        hash = (53 * hash) + getVersionQualifier().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos 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.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.RpcEndpointInfos}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.RpcEndpointInfos)
        org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RpcEndpointInfos_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RpcEndpointInfos_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.class, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        name_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        version_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        majorVersion_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        minorVersion_ = 0;
        bitField0_ = (bitField0_ & ~0x00000008);
        patchVersion_ = 0;
        bitField0_ = (bitField0_ & ~0x00000010);
        application_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        buildNumber_ = 0;
        bitField0_ = (bitField0_ & ~0x00000040);
        versionQualifier_ = "";
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RpcEndpointInfos_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos build() {
        org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos buildPartial() {
        org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos result = new org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.name_ = name_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.version_ = version_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.majorVersion_ = majorVersion_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          result.minorVersion_ = minorVersion_;
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.patchVersion_ = patchVersion_;
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.application_ = application_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.buildNumber_ = buildNumber_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          to_bitField0_ |= 0x00000080;
        }
        result.versionQualifier_ = versionQualifier_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos other) {
        if (other == org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance()) return this;
        if (other.hasName()) {
          bitField0_ |= 0x00000001;
          name_ = other.name_;
          onChanged();
        }
        if (other.hasVersion()) {
          bitField0_ |= 0x00000002;
          version_ = other.version_;
          onChanged();
        }
        if (other.hasMajorVersion()) {
          setMajorVersion(other.getMajorVersion());
        }
        if (other.hasMinorVersion()) {
          setMinorVersion(other.getMinorVersion());
        }
        if (other.hasPatchVersion()) {
          setPatchVersion(other.getPatchVersion());
        }
        if (other.hasApplication()) {
          bitField0_ |= 0x00000020;
          application_ = other.application_;
          onChanged();
        }
        if (other.hasBuildNumber()) {
          setBuildNumber(other.getBuildNumber());
        }
        if (other.hasVersionQualifier()) {
          bitField0_ |= 0x00000080;
          versionQualifier_ = other.versionQualifier_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                name_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                version_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 24: {
                majorVersion_ = input.readUInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 32: {
                minorVersion_ = input.readUInt32();
                bitField0_ |= 0x00000008;
                break;
              } // case 32
              case 40: {
                patchVersion_ = input.readUInt32();
                bitField0_ |= 0x00000010;
                break;
              } // case 40
              case 50: {
                application_ = input.readBytes();
                bitField0_ |= 0x00000020;
                break;
              } // case 50
              case 56: {
                buildNumber_ = input.readUInt32();
                bitField0_ |= 0x00000040;
                break;
              } // case 56
              case 66: {
                versionQualifier_ = input.readBytes();
                bitField0_ |= 0x00000080;
                break;
              } // case 66
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object name_ = "";
      /**
       * <pre>
       * example: Apache Drill Server, Apache Drill C++ client
       * </pre>
       *
       * <code>optional string name = 1;</code>
       * @return Whether the name field is set.
       */
      public boolean hasName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * example: Apache Drill Server, Apache Drill C++ client
       * </pre>
       *
       * <code>optional string name = 1;</code>
       * @return The name.
       */
      public java.lang.String getName() {
        java.lang.Object ref = name_;
        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()) {
            name_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * example: Apache Drill Server, Apache Drill C++ client
       * </pre>
       *
       * <code>optional string name = 1;</code>
       * @return The bytes for name.
       */
      public com.google.protobuf.ByteString
          getNameBytes() {
        java.lang.Object ref = name_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          name_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * example: Apache Drill Server, Apache Drill C++ client
       * </pre>
       *
       * <code>optional string name = 1;</code>
       * @param value The name to set.
       * @return This builder for chaining.
       */
      public Builder setName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: Apache Drill Server, Apache Drill C++ client
       * </pre>
       *
       * <code>optional string name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        name_ = getDefaultInstance().getName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: Apache Drill Server, Apache Drill C++ client
       * </pre>
       *
       * <code>optional string name = 1;</code>
       * @param value The bytes for name to set.
       * @return This builder for chaining.
       */
      public Builder setNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        name_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object version_ = "";
      /**
       * <pre>
       * example: 1.9.0
       * </pre>
       *
       * <code>optional string version = 2;</code>
       * @return Whether the version field is set.
       */
      public boolean hasVersion() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * example: 1.9.0
       * </pre>
       *
       * <code>optional string version = 2;</code>
       * @return The version.
       */
      public java.lang.String getVersion() {
        java.lang.Object ref = version_;
        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()) {
            version_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * example: 1.9.0
       * </pre>
       *
       * <code>optional string version = 2;</code>
       * @return The bytes for version.
       */
      public com.google.protobuf.ByteString
          getVersionBytes() {
        java.lang.Object ref = version_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          version_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * example: 1.9.0
       * </pre>
       *
       * <code>optional string version = 2;</code>
       * @param value The version to set.
       * @return This builder for chaining.
       */
      public Builder setVersion(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        version_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: 1.9.0
       * </pre>
       *
       * <code>optional string version = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearVersion() {
        bitField0_ = (bitField0_ & ~0x00000002);
        version_ = getDefaultInstance().getVersion();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: 1.9.0
       * </pre>
       *
       * <code>optional string version = 2;</code>
       * @param value The bytes for version to set.
       * @return This builder for chaining.
       */
      public Builder setVersionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        version_ = value;
        onChanged();
        return this;
      }

      private int majorVersion_ ;
      /**
       * <pre>
       * example: 1
       * </pre>
       *
       * <code>optional uint32 majorVersion = 3;</code>
       * @return Whether the majorVersion field is set.
       */
      @java.lang.Override
      public boolean hasMajorVersion() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * example: 1
       * </pre>
       *
       * <code>optional uint32 majorVersion = 3;</code>
       * @return The majorVersion.
       */
      @java.lang.Override
      public int getMajorVersion() {
        return majorVersion_;
      }
      /**
       * <pre>
       * example: 1
       * </pre>
       *
       * <code>optional uint32 majorVersion = 3;</code>
       * @param value The majorVersion to set.
       * @return This builder for chaining.
       */
      public Builder setMajorVersion(int value) {
        bitField0_ |= 0x00000004;
        majorVersion_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: 1
       * </pre>
       *
       * <code>optional uint32 majorVersion = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearMajorVersion() {
        bitField0_ = (bitField0_ & ~0x00000004);
        majorVersion_ = 0;
        onChanged();
        return this;
      }

      private int minorVersion_ ;
      /**
       * <pre>
       * example: 9
       * </pre>
       *
       * <code>optional uint32 minorVersion = 4;</code>
       * @return Whether the minorVersion field is set.
       */
      @java.lang.Override
      public boolean hasMinorVersion() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * example: 9
       * </pre>
       *
       * <code>optional uint32 minorVersion = 4;</code>
       * @return The minorVersion.
       */
      @java.lang.Override
      public int getMinorVersion() {
        return minorVersion_;
      }
      /**
       * <pre>
       * example: 9
       * </pre>
       *
       * <code>optional uint32 minorVersion = 4;</code>
       * @param value The minorVersion to set.
       * @return This builder for chaining.
       */
      public Builder setMinorVersion(int value) {
        bitField0_ |= 0x00000008;
        minorVersion_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: 9
       * </pre>
       *
       * <code>optional uint32 minorVersion = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearMinorVersion() {
        bitField0_ = (bitField0_ & ~0x00000008);
        minorVersion_ = 0;
        onChanged();
        return this;
      }

      private int patchVersion_ ;
      /**
       * <pre>
       * example: 0
       * </pre>
       *
       * <code>optional uint32 patchVersion = 5;</code>
       * @return Whether the patchVersion field is set.
       */
      @java.lang.Override
      public boolean hasPatchVersion() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <pre>
       * example: 0
       * </pre>
       *
       * <code>optional uint32 patchVersion = 5;</code>
       * @return The patchVersion.
       */
      @java.lang.Override
      public int getPatchVersion() {
        return patchVersion_;
      }
      /**
       * <pre>
       * example: 0
       * </pre>
       *
       * <code>optional uint32 patchVersion = 5;</code>
       * @param value The patchVersion to set.
       * @return This builder for chaining.
       */
      public Builder setPatchVersion(int value) {
        bitField0_ |= 0x00000010;
        patchVersion_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: 0
       * </pre>
       *
       * <code>optional uint32 patchVersion = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearPatchVersion() {
        bitField0_ = (bitField0_ & ~0x00000010);
        patchVersion_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object application_ = "";
      /**
       * <pre>
       * example: Tableau 9.3
       * </pre>
       *
       * <code>optional string application = 6;</code>
       * @return Whether the application field is set.
       */
      public boolean hasApplication() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <pre>
       * example: Tableau 9.3
       * </pre>
       *
       * <code>optional string application = 6;</code>
       * @return The application.
       */
      public java.lang.String getApplication() {
        java.lang.Object ref = application_;
        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()) {
            application_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * example: Tableau 9.3
       * </pre>
       *
       * <code>optional string application = 6;</code>
       * @return The bytes for application.
       */
      public com.google.protobuf.ByteString
          getApplicationBytes() {
        java.lang.Object ref = application_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          application_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * example: Tableau 9.3
       * </pre>
       *
       * <code>optional string application = 6;</code>
       * @param value The application to set.
       * @return This builder for chaining.
       */
      public Builder setApplication(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        application_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: Tableau 9.3
       * </pre>
       *
       * <code>optional string application = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearApplication() {
        bitField0_ = (bitField0_ & ~0x00000020);
        application_ = getDefaultInstance().getApplication();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: Tableau 9.3
       * </pre>
       *
       * <code>optional string application = 6;</code>
       * @param value The bytes for application to set.
       * @return This builder for chaining.
       */
      public Builder setApplicationBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        application_ = value;
        onChanged();
        return this;
      }

      private int buildNumber_ ;
      /**
       * <pre>
       * example: 32
       * </pre>
       *
       * <code>optional uint32 buildNumber = 7;</code>
       * @return Whether the buildNumber field is set.
       */
      @java.lang.Override
      public boolean hasBuildNumber() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <pre>
       * example: 32
       * </pre>
       *
       * <code>optional uint32 buildNumber = 7;</code>
       * @return The buildNumber.
       */
      @java.lang.Override
      public int getBuildNumber() {
        return buildNumber_;
      }
      /**
       * <pre>
       * example: 32
       * </pre>
       *
       * <code>optional uint32 buildNumber = 7;</code>
       * @param value The buildNumber to set.
       * @return This builder for chaining.
       */
      public Builder setBuildNumber(int value) {
        bitField0_ |= 0x00000040;
        buildNumber_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: 32
       * </pre>
       *
       * <code>optional uint32 buildNumber = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearBuildNumber() {
        bitField0_ = (bitField0_ & ~0x00000040);
        buildNumber_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object versionQualifier_ = "";
      /**
       * <pre>
       * example: SNAPSHOT
       * </pre>
       *
       * <code>optional string versionQualifier = 8;</code>
       * @return Whether the versionQualifier field is set.
       */
      public boolean hasVersionQualifier() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <pre>
       * example: SNAPSHOT
       * </pre>
       *
       * <code>optional string versionQualifier = 8;</code>
       * @return The versionQualifier.
       */
      public java.lang.String getVersionQualifier() {
        java.lang.Object ref = versionQualifier_;
        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()) {
            versionQualifier_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * example: SNAPSHOT
       * </pre>
       *
       * <code>optional string versionQualifier = 8;</code>
       * @return The bytes for versionQualifier.
       */
      public com.google.protobuf.ByteString
          getVersionQualifierBytes() {
        java.lang.Object ref = versionQualifier_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          versionQualifier_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * example: SNAPSHOT
       * </pre>
       *
       * <code>optional string versionQualifier = 8;</code>
       * @param value The versionQualifier to set.
       * @return This builder for chaining.
       */
      public Builder setVersionQualifier(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
        versionQualifier_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: SNAPSHOT
       * </pre>
       *
       * <code>optional string versionQualifier = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearVersionQualifier() {
        bitField0_ = (bitField0_ & ~0x00000080);
        versionQualifier_ = getDefaultInstance().getVersionQualifier();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * example: SNAPSHOT
       * </pre>
       *
       * <code>optional string versionQualifier = 8;</code>
       * @param value The bytes for versionQualifier to set.
       * @return This builder for chaining.
       */
      public Builder setVersionQualifierBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
        versionQualifier_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.RpcEndpointInfos)
    }

    // @@protoc_insertion_point(class_scope:exec.user.RpcEndpointInfos)
    private static final org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos();
    }

    public static org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<RpcEndpointInfos>
        PARSER = new com.google.protobuf.AbstractParser<RpcEndpointInfos>() {
      @java.lang.Override
      public RpcEndpointInfos parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<RpcEndpointInfos> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<RpcEndpointInfos> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface UserToBitHandshakeOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.UserToBitHandshake)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
     * @return Whether the channel field is set.
     */
    boolean hasChannel();
    /**
     * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
     * @return The channel.
     */
    org.apache.drill.exec.proto.UserBitShared.RpcChannel getChannel();

    /**
     * <code>optional bool support_listening = 2;</code>
     * @return Whether the supportListening field is set.
     */
    boolean hasSupportListening();
    /**
     * <code>optional bool support_listening = 2;</code>
     * @return The supportListening.
     */
    boolean getSupportListening();

    /**
     * <code>optional int32 rpc_version = 3;</code>
     * @return Whether the rpcVersion field is set.
     */
    boolean hasRpcVersion();
    /**
     * <code>optional int32 rpc_version = 3;</code>
     * @return The rpcVersion.
     */
    int getRpcVersion();

    /**
     * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
     * @return Whether the credentials field is set.
     */
    boolean hasCredentials();
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
     * @return The credentials.
     */
    org.apache.drill.exec.proto.UserBitShared.UserCredentials getCredentials();
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder getCredentialsOrBuilder();

    /**
     * <code>optional .exec.user.UserProperties properties = 5;</code>
     * @return Whether the properties field is set.
     */
    boolean hasProperties();
    /**
     * <code>optional .exec.user.UserProperties properties = 5;</code>
     * @return The properties.
     */
    org.apache.drill.exec.proto.UserProtos.UserProperties getProperties();
    /**
     * <code>optional .exec.user.UserProperties properties = 5;</code>
     */
    org.apache.drill.exec.proto.UserProtos.UserPropertiesOrBuilder getPropertiesOrBuilder();

    /**
     * <code>optional bool support_complex_types = 6 [default = false];</code>
     * @return Whether the supportComplexTypes field is set.
     */
    boolean hasSupportComplexTypes();
    /**
     * <code>optional bool support_complex_types = 6 [default = false];</code>
     * @return The supportComplexTypes.
     */
    boolean getSupportComplexTypes();

    /**
     * <code>optional bool support_timeout = 7 [default = false];</code>
     * @return Whether the supportTimeout field is set.
     */
    boolean hasSupportTimeout();
    /**
     * <code>optional bool support_timeout = 7 [default = false];</code>
     * @return The supportTimeout.
     */
    boolean getSupportTimeout();

    /**
     * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
     * @return Whether the clientInfos field is set.
     */
    boolean hasClientInfos();
    /**
     * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
     * @return The clientInfos.
     */
    org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getClientInfos();
    /**
     * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
     */
    org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder getClientInfosOrBuilder();

    /**
     * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
     * @return Whether the saslSupport field is set.
     */
    boolean hasSaslSupport();
    /**
     * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
     * @return The saslSupport.
     */
    org.apache.drill.exec.proto.UserProtos.SaslSupport getSaslSupport();
  }
  /**
   * Protobuf type {@code exec.user.UserToBitHandshake}
   */
  public static final class UserToBitHandshake extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.UserToBitHandshake)
      UserToBitHandshakeOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use UserToBitHandshake.newBuilder() to construct.
    private UserToBitHandshake(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private UserToBitHandshake() {
      channel_ = 2;
      saslSupport_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new UserToBitHandshake();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserToBitHandshake_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserToBitHandshake_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.UserToBitHandshake.class, org.apache.drill.exec.proto.UserProtos.UserToBitHandshake.Builder.class);
    }

    private int bitField0_;
    public static final int CHANNEL_FIELD_NUMBER = 1;
    private int channel_;
    /**
     * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
     * @return Whether the channel field is set.
     */
    @java.lang.Override public boolean hasChannel() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
     * @return The channel.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.RpcChannel getChannel() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.RpcChannel result = org.apache.drill.exec.proto.UserBitShared.RpcChannel.valueOf(channel_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.RpcChannel.USER : result;
    }

    public static final int SUPPORT_LISTENING_FIELD_NUMBER = 2;
    private boolean supportListening_;
    /**
     * <code>optional bool support_listening = 2;</code>
     * @return Whether the supportListening field is set.
     */
    @java.lang.Override
    public boolean hasSupportListening() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional bool support_listening = 2;</code>
     * @return The supportListening.
     */
    @java.lang.Override
    public boolean getSupportListening() {
      return supportListening_;
    }

    public static final int RPC_VERSION_FIELD_NUMBER = 3;
    private int rpcVersion_;
    /**
     * <code>optional int32 rpc_version = 3;</code>
     * @return Whether the rpcVersion field is set.
     */
    @java.lang.Override
    public boolean hasRpcVersion() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional int32 rpc_version = 3;</code>
     * @return The rpcVersion.
     */
    @java.lang.Override
    public int getRpcVersion() {
      return rpcVersion_;
    }

    public static final int CREDENTIALS_FIELD_NUMBER = 4;
    private org.apache.drill.exec.proto.UserBitShared.UserCredentials credentials_;
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
     * @return Whether the credentials field is set.
     */
    @java.lang.Override
    public boolean hasCredentials() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
     * @return The credentials.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.UserCredentials getCredentials() {
      return credentials_ == null ? org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
    }
    /**
     * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder getCredentialsOrBuilder() {
      return credentials_ == null ? org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
    }

    public static final int PROPERTIES_FIELD_NUMBER = 5;
    private org.apache.drill.exec.proto.UserProtos.UserProperties properties_;
    /**
     * <code>optional .exec.user.UserProperties properties = 5;</code>
     * @return Whether the properties field is set.
     */
    @java.lang.Override
    public boolean hasProperties() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional .exec.user.UserProperties properties = 5;</code>
     * @return The properties.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.UserProperties getProperties() {
      return properties_ == null ? org.apache.drill.exec.proto.UserProtos.UserProperties.getDefaultInstance() : properties_;
    }
    /**
     * <code>optional .exec.user.UserProperties properties = 5;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.UserPropertiesOrBuilder getPropertiesOrBuilder() {
      return properties_ == null ? org.apache.drill.exec.proto.UserProtos.UserProperties.getDefaultInstance() : properties_;
    }

    public static final int SUPPORT_COMPLEX_TYPES_FIELD_NUMBER = 6;
    private boolean supportComplexTypes_;
    /**
     * <code>optional bool support_complex_types = 6 [default = false];</code>
     * @return Whether the supportComplexTypes field is set.
     */
    @java.lang.Override
    public boolean hasSupportComplexTypes() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional bool support_complex_types = 6 [default = false];</code>
     * @return The supportComplexTypes.
     */
    @java.lang.Override
    public boolean getSupportComplexTypes() {
      return supportComplexTypes_;
    }

    public static final int SUPPORT_TIMEOUT_FIELD_NUMBER = 7;
    private boolean supportTimeout_;
    /**
     * <code>optional bool support_timeout = 7 [default = false];</code>
     * @return Whether the supportTimeout field is set.
     */
    @java.lang.Override
    public boolean hasSupportTimeout() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional bool support_timeout = 7 [default = false];</code>
     * @return The supportTimeout.
     */
    @java.lang.Override
    public boolean getSupportTimeout() {
      return supportTimeout_;
    }

    public static final int CLIENT_INFOS_FIELD_NUMBER = 8;
    private org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos clientInfos_;
    /**
     * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
     * @return Whether the clientInfos field is set.
     */
    @java.lang.Override
    public boolean hasClientInfos() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
     * @return The clientInfos.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getClientInfos() {
      return clientInfos_ == null ? org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : clientInfos_;
    }
    /**
     * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder getClientInfosOrBuilder() {
      return clientInfos_ == null ? org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : clientInfos_;
    }

    public static final int SASL_SUPPORT_FIELD_NUMBER = 9;
    private int saslSupport_;
    /**
     * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
     * @return Whether the saslSupport field is set.
     */
    @java.lang.Override public boolean hasSaslSupport() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
     * @return The saslSupport.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.SaslSupport getSaslSupport() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.SaslSupport result = org.apache.drill.exec.proto.UserProtos.SaslSupport.valueOf(saslSupport_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.SaslSupport.UNKNOWN_SASL_SUPPORT : result;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (hasProperties()) {
        if (!getProperties().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, channel_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBool(2, supportListening_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeInt32(3, rpcVersion_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeMessage(4, getCredentials());
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeMessage(5, getProperties());
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeBool(6, supportComplexTypes_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeBool(7, supportTimeout_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeMessage(8, getClientInfos());
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeEnum(9, saslSupport_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, channel_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(2, supportListening_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(3, rpcVersion_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getCredentials());
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getProperties());
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(6, supportComplexTypes_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(7, supportTimeout_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, getClientInfos());
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(9, saslSupport_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.UserToBitHandshake)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.UserToBitHandshake other = (org.apache.drill.exec.proto.UserProtos.UserToBitHandshake) obj;

      if (hasChannel() != other.hasChannel()) return false;
      if (hasChannel()) {
        if (channel_ != other.channel_) return false;
      }
      if (hasSupportListening() != other.hasSupportListening()) return false;
      if (hasSupportListening()) {
        if (getSupportListening()
            != other.getSupportListening()) return false;
      }
      if (hasRpcVersion() != other.hasRpcVersion()) return false;
      if (hasRpcVersion()) {
        if (getRpcVersion()
            != other.getRpcVersion()) return false;
      }
      if (hasCredentials() != other.hasCredentials()) return false;
      if (hasCredentials()) {
        if (!getCredentials()
            .equals(other.getCredentials())) return false;
      }
      if (hasProperties() != other.hasProperties()) return false;
      if (hasProperties()) {
        if (!getProperties()
            .equals(other.getProperties())) return false;
      }
      if (hasSupportComplexTypes() != other.hasSupportComplexTypes()) return false;
      if (hasSupportComplexTypes()) {
        if (getSupportComplexTypes()
            != other.getSupportComplexTypes()) return false;
      }
      if (hasSupportTimeout() != other.hasSupportTimeout()) return false;
      if (hasSupportTimeout()) {
        if (getSupportTimeout()
            != other.getSupportTimeout()) return false;
      }
      if (hasClientInfos() != other.hasClientInfos()) return false;
      if (hasClientInfos()) {
        if (!getClientInfos()
            .equals(other.getClientInfos())) return false;
      }
      if (hasSaslSupport() != other.hasSaslSupport()) return false;
      if (hasSaslSupport()) {
        if (saslSupport_ != other.saslSupport_) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasChannel()) {
        hash = (37 * hash) + CHANNEL_FIELD_NUMBER;
        hash = (53 * hash) + channel_;
      }
      if (hasSupportListening()) {
        hash = (37 * hash) + SUPPORT_LISTENING_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSupportListening());
      }
      if (hasRpcVersion()) {
        hash = (37 * hash) + RPC_VERSION_FIELD_NUMBER;
        hash = (53 * hash) + getRpcVersion();
      }
      if (hasCredentials()) {
        hash = (37 * hash) + CREDENTIALS_FIELD_NUMBER;
        hash = (53 * hash) + getCredentials().hashCode();
      }
      if (hasProperties()) {
        hash = (37 * hash) + PROPERTIES_FIELD_NUMBER;
        hash = (53 * hash) + getProperties().hashCode();
      }
      if (hasSupportComplexTypes()) {
        hash = (37 * hash) + SUPPORT_COMPLEX_TYPES_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSupportComplexTypes());
      }
      if (hasSupportTimeout()) {
        hash = (37 * hash) + SUPPORT_TIMEOUT_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSupportTimeout());
      }
      if (hasClientInfos()) {
        hash = (37 * hash) + CLIENT_INFOS_FIELD_NUMBER;
        hash = (53 * hash) + getClientInfos().hashCode();
      }
      if (hasSaslSupport()) {
        hash = (37 * hash) + SASL_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + saslSupport_;
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake 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.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.UserToBitHandshake prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.UserToBitHandshake}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.UserToBitHandshake)
        org.apache.drill.exec.proto.UserProtos.UserToBitHandshakeOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserToBitHandshake_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserToBitHandshake_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.UserToBitHandshake.class, org.apache.drill.exec.proto.UserProtos.UserToBitHandshake.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.UserToBitHandshake.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getCredentialsFieldBuilder();
          getPropertiesFieldBuilder();
          getClientInfosFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        channel_ = 2;
        bitField0_ = (bitField0_ & ~0x00000001);
        supportListening_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        rpcVersion_ = 0;
        bitField0_ = (bitField0_ & ~0x00000004);
        if (credentialsBuilder_ == null) {
          credentials_ = null;
        } else {
          credentialsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        if (propertiesBuilder_ == null) {
          properties_ = null;
        } else {
          propertiesBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        supportComplexTypes_ = false;
        bitField0_ = (bitField0_ & ~0x00000020);
        supportTimeout_ = false;
        bitField0_ = (bitField0_ & ~0x00000040);
        if (clientInfosBuilder_ == null) {
          clientInfos_ = null;
        } else {
          clientInfosBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        saslSupport_ = 0;
        bitField0_ = (bitField0_ & ~0x00000100);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_UserToBitHandshake_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.UserToBitHandshake getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.UserToBitHandshake.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.UserToBitHandshake build() {
        org.apache.drill.exec.proto.UserProtos.UserToBitHandshake result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.UserToBitHandshake buildPartial() {
        org.apache.drill.exec.proto.UserProtos.UserToBitHandshake result = new org.apache.drill.exec.proto.UserProtos.UserToBitHandshake(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.channel_ = channel_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.supportListening_ = supportListening_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.rpcVersion_ = rpcVersion_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          if (credentialsBuilder_ == null) {
            result.credentials_ = credentials_;
          } else {
            result.credentials_ = credentialsBuilder_.build();
          }
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          if (propertiesBuilder_ == null) {
            result.properties_ = properties_;
          } else {
            result.properties_ = propertiesBuilder_.build();
          }
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.supportComplexTypes_ = supportComplexTypes_;
          to_bitField0_ |= 0x00000020;
        }
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.supportTimeout_ = supportTimeout_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          if (clientInfosBuilder_ == null) {
            result.clientInfos_ = clientInfos_;
          } else {
            result.clientInfos_ = clientInfosBuilder_.build();
          }
          to_bitField0_ |= 0x00000080;
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          to_bitField0_ |= 0x00000100;
        }
        result.saslSupport_ = saslSupport_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.UserToBitHandshake) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.UserToBitHandshake)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.UserToBitHandshake other) {
        if (other == org.apache.drill.exec.proto.UserProtos.UserToBitHandshake.getDefaultInstance()) return this;
        if (other.hasChannel()) {
          setChannel(other.getChannel());
        }
        if (other.hasSupportListening()) {
          setSupportListening(other.getSupportListening());
        }
        if (other.hasRpcVersion()) {
          setRpcVersion(other.getRpcVersion());
        }
        if (other.hasCredentials()) {
          mergeCredentials(other.getCredentials());
        }
        if (other.hasProperties()) {
          mergeProperties(other.getProperties());
        }
        if (other.hasSupportComplexTypes()) {
          setSupportComplexTypes(other.getSupportComplexTypes());
        }
        if (other.hasSupportTimeout()) {
          setSupportTimeout(other.getSupportTimeout());
        }
        if (other.hasClientInfos()) {
          mergeClientInfos(other.getClientInfos());
        }
        if (other.hasSaslSupport()) {
          setSaslSupport(other.getSaslSupport());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        if (hasProperties()) {
          if (!getProperties().isInitialized()) {
            return false;
          }
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.RpcChannel tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.RpcChannel.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  channel_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 16: {
                supportListening_ = input.readBool();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 24: {
                rpcVersion_ = input.readInt32();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 34: {
                input.readMessage(
                    getCredentialsFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 42: {
                input.readMessage(
                    getPropertiesFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 48: {
                supportComplexTypes_ = input.readBool();
                bitField0_ |= 0x00000020;
                break;
              } // case 48
              case 56: {
                supportTimeout_ = input.readBool();
                bitField0_ |= 0x00000040;
                break;
              } // case 56
              case 66: {
                input.readMessage(
                    getClientInfosFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000080;
                break;
              } // case 66
              case 72: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.SaslSupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.SaslSupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(9, tmpRaw);
                } else {
                  saslSupport_ = tmpRaw;
                  bitField0_ |= 0x00000100;
                }
                break;
              } // case 72
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int channel_ = 2;
      /**
       * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
       * @return Whether the channel field is set.
       */
      @java.lang.Override public boolean hasChannel() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
       * @return The channel.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.RpcChannel getChannel() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.RpcChannel result = org.apache.drill.exec.proto.UserBitShared.RpcChannel.valueOf(channel_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.RpcChannel.USER : result;
      }
      /**
       * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
       * @param value The channel to set.
       * @return This builder for chaining.
       */
      public Builder setChannel(org.apache.drill.exec.proto.UserBitShared.RpcChannel value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        channel_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.RpcChannel channel = 1 [default = USER];</code>
       * @return This builder for chaining.
       */
      public Builder clearChannel() {
        bitField0_ = (bitField0_ & ~0x00000001);
        channel_ = 2;
        onChanged();
        return this;
      }

      private boolean supportListening_ ;
      /**
       * <code>optional bool support_listening = 2;</code>
       * @return Whether the supportListening field is set.
       */
      @java.lang.Override
      public boolean hasSupportListening() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional bool support_listening = 2;</code>
       * @return The supportListening.
       */
      @java.lang.Override
      public boolean getSupportListening() {
        return supportListening_;
      }
      /**
       * <code>optional bool support_listening = 2;</code>
       * @param value The supportListening to set.
       * @return This builder for chaining.
       */
      public Builder setSupportListening(boolean value) {
        bitField0_ |= 0x00000002;
        supportListening_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool support_listening = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearSupportListening() {
        bitField0_ = (bitField0_ & ~0x00000002);
        supportListening_ = false;
        onChanged();
        return this;
      }

      private int rpcVersion_ ;
      /**
       * <code>optional int32 rpc_version = 3;</code>
       * @return Whether the rpcVersion field is set.
       */
      @java.lang.Override
      public boolean hasRpcVersion() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional int32 rpc_version = 3;</code>
       * @return The rpcVersion.
       */
      @java.lang.Override
      public int getRpcVersion() {
        return rpcVersion_;
      }
      /**
       * <code>optional int32 rpc_version = 3;</code>
       * @param value The rpcVersion to set.
       * @return This builder for chaining.
       */
      public Builder setRpcVersion(int value) {
        bitField0_ |= 0x00000004;
        rpcVersion_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 rpc_version = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearRpcVersion() {
        bitField0_ = (bitField0_ & ~0x00000004);
        rpcVersion_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.UserCredentials credentials_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.UserCredentials, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder, org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder> credentialsBuilder_;
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       * @return Whether the credentials field is set.
       */
      public boolean hasCredentials() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       * @return The credentials.
       */
      public org.apache.drill.exec.proto.UserBitShared.UserCredentials getCredentials() {
        if (credentialsBuilder_ == null) {
          return credentials_ == null ? org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
        } else {
          return credentialsBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       */
      public Builder setCredentials(org.apache.drill.exec.proto.UserBitShared.UserCredentials value) {
        if (credentialsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          credentials_ = value;
          onChanged();
        } else {
          credentialsBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       */
      public Builder setCredentials(
          org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder builderForValue) {
        if (credentialsBuilder_ == null) {
          credentials_ = builderForValue.build();
          onChanged();
        } else {
          credentialsBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       */
      public Builder mergeCredentials(org.apache.drill.exec.proto.UserBitShared.UserCredentials value) {
        if (credentialsBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0) &&
              credentials_ != null &&
              credentials_ != org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance()) {
            credentials_ =
              org.apache.drill.exec.proto.UserBitShared.UserCredentials.newBuilder(credentials_).mergeFrom(value).buildPartial();
          } else {
            credentials_ = value;
          }
          onChanged();
        } else {
          credentialsBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       */
      public Builder clearCredentials() {
        if (credentialsBuilder_ == null) {
          credentials_ = null;
          onChanged();
        } else {
          credentialsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder getCredentialsBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getCredentialsFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder getCredentialsOrBuilder() {
        if (credentialsBuilder_ != null) {
          return credentialsBuilder_.getMessageOrBuilder();
        } else {
          return credentials_ == null ?
              org.apache.drill.exec.proto.UserBitShared.UserCredentials.getDefaultInstance() : credentials_;
        }
      }
      /**
       * <code>optional .exec.shared.UserCredentials credentials = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.UserCredentials, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder, org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder> 
          getCredentialsFieldBuilder() {
        if (credentialsBuilder_ == null) {
          credentialsBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.UserCredentials, org.apache.drill.exec.proto.UserBitShared.UserCredentials.Builder, org.apache.drill.exec.proto.UserBitShared.UserCredentialsOrBuilder>(
                  getCredentials(),
                  getParentForChildren(),
                  isClean());
          credentials_ = null;
        }
        return credentialsBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.UserProperties properties_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.UserProperties, org.apache.drill.exec.proto.UserProtos.UserProperties.Builder, org.apache.drill.exec.proto.UserProtos.UserPropertiesOrBuilder> propertiesBuilder_;
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       * @return Whether the properties field is set.
       */
      public boolean hasProperties() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       * @return The properties.
       */
      public org.apache.drill.exec.proto.UserProtos.UserProperties getProperties() {
        if (propertiesBuilder_ == null) {
          return properties_ == null ? org.apache.drill.exec.proto.UserProtos.UserProperties.getDefaultInstance() : properties_;
        } else {
          return propertiesBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       */
      public Builder setProperties(org.apache.drill.exec.proto.UserProtos.UserProperties value) {
        if (propertiesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          properties_ = value;
          onChanged();
        } else {
          propertiesBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       */
      public Builder setProperties(
          org.apache.drill.exec.proto.UserProtos.UserProperties.Builder builderForValue) {
        if (propertiesBuilder_ == null) {
          properties_ = builderForValue.build();
          onChanged();
        } else {
          propertiesBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       */
      public Builder mergeProperties(org.apache.drill.exec.proto.UserProtos.UserProperties value) {
        if (propertiesBuilder_ == null) {
          if (((bitField0_ & 0x00000010) != 0) &&
              properties_ != null &&
              properties_ != org.apache.drill.exec.proto.UserProtos.UserProperties.getDefaultInstance()) {
            properties_ =
              org.apache.drill.exec.proto.UserProtos.UserProperties.newBuilder(properties_).mergeFrom(value).buildPartial();
          } else {
            properties_ = value;
          }
          onChanged();
        } else {
          propertiesBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       */
      public Builder clearProperties() {
        if (propertiesBuilder_ == null) {
          properties_ = null;
          onChanged();
        } else {
          propertiesBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.UserProperties.Builder getPropertiesBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getPropertiesFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.UserPropertiesOrBuilder getPropertiesOrBuilder() {
        if (propertiesBuilder_ != null) {
          return propertiesBuilder_.getMessageOrBuilder();
        } else {
          return properties_ == null ?
              org.apache.drill.exec.proto.UserProtos.UserProperties.getDefaultInstance() : properties_;
        }
      }
      /**
       * <code>optional .exec.user.UserProperties properties = 5;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.UserProperties, org.apache.drill.exec.proto.UserProtos.UserProperties.Builder, org.apache.drill.exec.proto.UserProtos.UserPropertiesOrBuilder> 
          getPropertiesFieldBuilder() {
        if (propertiesBuilder_ == null) {
          propertiesBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.UserProperties, org.apache.drill.exec.proto.UserProtos.UserProperties.Builder, org.apache.drill.exec.proto.UserProtos.UserPropertiesOrBuilder>(
                  getProperties(),
                  getParentForChildren(),
                  isClean());
          properties_ = null;
        }
        return propertiesBuilder_;
      }

      private boolean supportComplexTypes_ ;
      /**
       * <code>optional bool support_complex_types = 6 [default = false];</code>
       * @return Whether the supportComplexTypes field is set.
       */
      @java.lang.Override
      public boolean hasSupportComplexTypes() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional bool support_complex_types = 6 [default = false];</code>
       * @return The supportComplexTypes.
       */
      @java.lang.Override
      public boolean getSupportComplexTypes() {
        return supportComplexTypes_;
      }
      /**
       * <code>optional bool support_complex_types = 6 [default = false];</code>
       * @param value The supportComplexTypes to set.
       * @return This builder for chaining.
       */
      public Builder setSupportComplexTypes(boolean value) {
        bitField0_ |= 0x00000020;
        supportComplexTypes_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool support_complex_types = 6 [default = false];</code>
       * @return This builder for chaining.
       */
      public Builder clearSupportComplexTypes() {
        bitField0_ = (bitField0_ & ~0x00000020);
        supportComplexTypes_ = false;
        onChanged();
        return this;
      }

      private boolean supportTimeout_ ;
      /**
       * <code>optional bool support_timeout = 7 [default = false];</code>
       * @return Whether the supportTimeout field is set.
       */
      @java.lang.Override
      public boolean hasSupportTimeout() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional bool support_timeout = 7 [default = false];</code>
       * @return The supportTimeout.
       */
      @java.lang.Override
      public boolean getSupportTimeout() {
        return supportTimeout_;
      }
      /**
       * <code>optional bool support_timeout = 7 [default = false];</code>
       * @param value The supportTimeout to set.
       * @return This builder for chaining.
       */
      public Builder setSupportTimeout(boolean value) {
        bitField0_ |= 0x00000040;
        supportTimeout_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool support_timeout = 7 [default = false];</code>
       * @return This builder for chaining.
       */
      public Builder clearSupportTimeout() {
        bitField0_ = (bitField0_ & ~0x00000040);
        supportTimeout_ = false;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos clientInfos_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder> clientInfosBuilder_;
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       * @return Whether the clientInfos field is set.
       */
      public boolean hasClientInfos() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       * @return The clientInfos.
       */
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getClientInfos() {
        if (clientInfosBuilder_ == null) {
          return clientInfos_ == null ? org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : clientInfos_;
        } else {
          return clientInfosBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       */
      public Builder setClientInfos(org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos value) {
        if (clientInfosBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          clientInfos_ = value;
          onChanged();
        } else {
          clientInfosBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       */
      public Builder setClientInfos(
          org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder builderForValue) {
        if (clientInfosBuilder_ == null) {
          clientInfos_ = builderForValue.build();
          onChanged();
        } else {
          clientInfosBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       */
      public Builder mergeClientInfos(org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos value) {
        if (clientInfosBuilder_ == null) {
          if (((bitField0_ & 0x00000080) != 0) &&
              clientInfos_ != null &&
              clientInfos_ != org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance()) {
            clientInfos_ =
              org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.newBuilder(clientInfos_).mergeFrom(value).buildPartial();
          } else {
            clientInfos_ = value;
          }
          onChanged();
        } else {
          clientInfosBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000080;
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       */
      public Builder clearClientInfos() {
        if (clientInfosBuilder_ == null) {
          clientInfos_ = null;
          onChanged();
        } else {
          clientInfosBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder getClientInfosBuilder() {
        bitField0_ |= 0x00000080;
        onChanged();
        return getClientInfosFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder getClientInfosOrBuilder() {
        if (clientInfosBuilder_ != null) {
          return clientInfosBuilder_.getMessageOrBuilder();
        } else {
          return clientInfos_ == null ?
              org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : clientInfos_;
        }
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos client_infos = 8;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder> 
          getClientInfosFieldBuilder() {
        if (clientInfosBuilder_ == null) {
          clientInfosBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder>(
                  getClientInfos(),
                  getParentForChildren(),
                  isClean());
          clientInfos_ = null;
        }
        return clientInfosBuilder_;
      }

      private int saslSupport_ = 0;
      /**
       * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
       * @return Whether the saslSupport field is set.
       */
      @java.lang.Override public boolean hasSaslSupport() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
       * @return The saslSupport.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.SaslSupport getSaslSupport() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.SaslSupport result = org.apache.drill.exec.proto.UserProtos.SaslSupport.valueOf(saslSupport_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.SaslSupport.UNKNOWN_SASL_SUPPORT : result;
      }
      /**
       * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
       * @param value The saslSupport to set.
       * @return This builder for chaining.
       */
      public Builder setSaslSupport(org.apache.drill.exec.proto.UserProtos.SaslSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000100;
        saslSupport_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.SaslSupport sasl_support = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearSaslSupport() {
        bitField0_ = (bitField0_ & ~0x00000100);
        saslSupport_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.UserToBitHandshake)
    }

    // @@protoc_insertion_point(class_scope:exec.user.UserToBitHandshake)
    private static final org.apache.drill.exec.proto.UserProtos.UserToBitHandshake DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.UserToBitHandshake();
    }

    public static org.apache.drill.exec.proto.UserProtos.UserToBitHandshake getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<UserToBitHandshake>
        PARSER = new com.google.protobuf.AbstractParser<UserToBitHandshake>() {
      @java.lang.Override
      public UserToBitHandshake parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<UserToBitHandshake> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<UserToBitHandshake> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.UserToBitHandshake getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface RequestResultsOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.RequestResults)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return Whether the queryId field is set.
     */
    boolean hasQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return The queryId.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder();

    /**
     * <code>optional int32 maximum_responses = 2;</code>
     * @return Whether the maximumResponses field is set.
     */
    boolean hasMaximumResponses();
    /**
     * <code>optional int32 maximum_responses = 2;</code>
     * @return The maximumResponses.
     */
    int getMaximumResponses();
  }
  /**
   * Protobuf type {@code exec.user.RequestResults}
   */
  public static final class RequestResults extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.RequestResults)
      RequestResultsOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use RequestResults.newBuilder() to construct.
    private RequestResults(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private RequestResults() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new RequestResults();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RequestResults_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RequestResults_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.RequestResults.class, org.apache.drill.exec.proto.UserProtos.RequestResults.Builder.class);
    }

    private int bitField0_;
    public static final int QUERY_ID_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return Whether the queryId field is set.
     */
    @java.lang.Override
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     * @return The queryId.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }

    public static final int MAXIMUM_RESPONSES_FIELD_NUMBER = 2;
    private int maximumResponses_;
    /**
     * <code>optional int32 maximum_responses = 2;</code>
     * @return Whether the maximumResponses field is set.
     */
    @java.lang.Override
    public boolean hasMaximumResponses() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional int32 maximum_responses = 2;</code>
     * @return The maximumResponses.
     */
    @java.lang.Override
    public int getMaximumResponses() {
      return maximumResponses_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeInt32(2, maximumResponses_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getQueryId());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, maximumResponses_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.RequestResults)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.RequestResults other = (org.apache.drill.exec.proto.UserProtos.RequestResults) obj;

      if (hasQueryId() != other.hasQueryId()) return false;
      if (hasQueryId()) {
        if (!getQueryId()
            .equals(other.getQueryId())) return false;
      }
      if (hasMaximumResponses() != other.hasMaximumResponses()) return false;
      if (hasMaximumResponses()) {
        if (getMaximumResponses()
            != other.getMaximumResponses()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasQueryId()) {
        hash = (37 * hash) + QUERY_ID_FIELD_NUMBER;
        hash = (53 * hash) + getQueryId().hashCode();
      }
      if (hasMaximumResponses()) {
        hash = (37 * hash) + MAXIMUM_RESPONSES_FIELD_NUMBER;
        hash = (53 * hash) + getMaximumResponses();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults 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.drill.exec.proto.UserProtos.RequestResults parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RequestResults parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.RequestResults prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.RequestResults}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.RequestResults)
        org.apache.drill.exec.proto.UserProtos.RequestResultsOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RequestResults_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RequestResults_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.RequestResults.class, org.apache.drill.exec.proto.UserProtos.RequestResults.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.RequestResults.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getQueryIdFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (queryIdBuilder_ == null) {
          queryId_ = null;
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        maximumResponses_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RequestResults_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestResults getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.RequestResults.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestResults build() {
        org.apache.drill.exec.proto.UserProtos.RequestResults result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestResults buildPartial() {
        org.apache.drill.exec.proto.UserProtos.RequestResults result = new org.apache.drill.exec.proto.UserProtos.RequestResults(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (queryIdBuilder_ == null) {
            result.queryId_ = queryId_;
          } else {
            result.queryId_ = queryIdBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.maximumResponses_ = maximumResponses_;
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.RequestResults) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.RequestResults)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.RequestResults other) {
        if (other == org.apache.drill.exec.proto.UserProtos.RequestResults.getDefaultInstance()) return this;
        if (other.hasQueryId()) {
          mergeQueryId(other.getQueryId());
        }
        if (other.hasMaximumResponses()) {
          setMaximumResponses(other.getMaximumResponses());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getQueryIdFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                maximumResponses_ = input.readInt32();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> queryIdBuilder_;
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       * @return Whether the queryId field is set.
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       * @return The queryId.
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
        if (queryIdBuilder_ == null) {
          return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        } else {
          return queryIdBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder setQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          queryId_ = value;
          onChanged();
        } else {
          queryIdBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder setQueryId(
          org.apache.drill.exec.proto.UserBitShared.QueryId.Builder builderForValue) {
        if (queryIdBuilder_ == null) {
          queryId_ = builderForValue.build();
          onChanged();
        } else {
          queryIdBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder mergeQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              queryId_ != null &&
              queryId_ != org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) {
            queryId_ =
              org.apache.drill.exec.proto.UserBitShared.QueryId.newBuilder(queryId_).mergeFrom(value).buildPartial();
          } else {
            queryId_ = value;
          }
          onChanged();
        } else {
          queryIdBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public Builder clearQueryId() {
        if (queryIdBuilder_ == null) {
          queryId_ = null;
          onChanged();
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId.Builder getQueryIdBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getQueryIdFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
        if (queryIdBuilder_ != null) {
          return queryIdBuilder_.getMessageOrBuilder();
        } else {
          return queryId_ == null ?
              org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> 
          getQueryIdFieldBuilder() {
        if (queryIdBuilder_ == null) {
          queryIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder>(
                  getQueryId(),
                  getParentForChildren(),
                  isClean());
          queryId_ = null;
        }
        return queryIdBuilder_;
      }

      private int maximumResponses_ ;
      /**
       * <code>optional int32 maximum_responses = 2;</code>
       * @return Whether the maximumResponses field is set.
       */
      @java.lang.Override
      public boolean hasMaximumResponses() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional int32 maximum_responses = 2;</code>
       * @return The maximumResponses.
       */
      @java.lang.Override
      public int getMaximumResponses() {
        return maximumResponses_;
      }
      /**
       * <code>optional int32 maximum_responses = 2;</code>
       * @param value The maximumResponses to set.
       * @return This builder for chaining.
       */
      public Builder setMaximumResponses(int value) {
        bitField0_ |= 0x00000002;
        maximumResponses_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 maximum_responses = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaximumResponses() {
        bitField0_ = (bitField0_ & ~0x00000002);
        maximumResponses_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.RequestResults)
    }

    // @@protoc_insertion_point(class_scope:exec.user.RequestResults)
    private static final org.apache.drill.exec.proto.UserProtos.RequestResults DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.RequestResults();
    }

    public static org.apache.drill.exec.proto.UserProtos.RequestResults getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<RequestResults>
        PARSER = new com.google.protobuf.AbstractParser<RequestResults>() {
      @java.lang.Override
      public RequestResults parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<RequestResults> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<RequestResults> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RequestResults getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetQueryPlanFragmentsOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetQueryPlanFragments)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>required string query = 1;</code>
     * @return Whether the query field is set.
     */
    boolean hasQuery();
    /**
     * <code>required string query = 1;</code>
     * @return The query.
     */
    java.lang.String getQuery();
    /**
     * <code>required string query = 1;</code>
     * @return The bytes for query.
     */
    com.google.protobuf.ByteString
        getQueryBytes();

    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return The type.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryType getType();

    /**
     * <code>optional bool split_plan = 3 [default = false];</code>
     * @return Whether the splitPlan field is set.
     */
    boolean hasSplitPlan();
    /**
     * <code>optional bool split_plan = 3 [default = false];</code>
     * @return The splitPlan.
     */
    boolean getSplitPlan();
  }
  /**
   * Protobuf type {@code exec.user.GetQueryPlanFragments}
   */
  public static final class GetQueryPlanFragments extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetQueryPlanFragments)
      GetQueryPlanFragmentsOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetQueryPlanFragments.newBuilder() to construct.
    private GetQueryPlanFragments(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetQueryPlanFragments() {
      query_ = "";
      type_ = 1;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetQueryPlanFragments();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetQueryPlanFragments_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetQueryPlanFragments_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments.class, org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments.Builder.class);
    }

    private int bitField0_;
    public static final int QUERY_FIELD_NUMBER = 1;
    private volatile java.lang.Object query_;
    /**
     * <code>required string query = 1;</code>
     * @return Whether the query field is set.
     */
    @java.lang.Override
    public boolean hasQuery() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>required string query = 1;</code>
     * @return The query.
     */
    @java.lang.Override
    public java.lang.String getQuery() {
      java.lang.Object ref = query_;
      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()) {
          query_ = s;
        }
        return s;
      }
    }
    /**
     * <code>required string query = 1;</code>
     * @return The bytes for query.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getQueryBytes() {
      java.lang.Object ref = query_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        query_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TYPE_FIELD_NUMBER = 2;
    private int type_;
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return Whether the type field is set.
     */
    @java.lang.Override public boolean hasType() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return The type.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.QueryType getType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryType result = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(type_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryType.SQL : result;
    }

    public static final int SPLIT_PLAN_FIELD_NUMBER = 3;
    private boolean splitPlan_;
    /**
     * <code>optional bool split_plan = 3 [default = false];</code>
     * @return Whether the splitPlan field is set.
     */
    @java.lang.Override
    public boolean hasSplitPlan() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional bool split_plan = 3 [default = false];</code>
     * @return The splitPlan.
     */
    @java.lang.Override
    public boolean getSplitPlan() {
      return splitPlan_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasQuery()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, query_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeEnum(2, type_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeBool(3, splitPlan_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, query_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, type_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, splitPlan_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments other = (org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments) obj;

      if (hasQuery() != other.hasQuery()) return false;
      if (hasQuery()) {
        if (!getQuery()
            .equals(other.getQuery())) return false;
      }
      if (hasType() != other.hasType()) return false;
      if (hasType()) {
        if (type_ != other.type_) return false;
      }
      if (hasSplitPlan() != other.hasSplitPlan()) return false;
      if (hasSplitPlan()) {
        if (getSplitPlan()
            != other.getSplitPlan()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasQuery()) {
        hash = (37 * hash) + QUERY_FIELD_NUMBER;
        hash = (53 * hash) + getQuery().hashCode();
      }
      if (hasType()) {
        hash = (37 * hash) + TYPE_FIELD_NUMBER;
        hash = (53 * hash) + type_;
      }
      if (hasSplitPlan()) {
        hash = (37 * hash) + SPLIT_PLAN_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSplitPlan());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments 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.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.GetQueryPlanFragments}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetQueryPlanFragments)
        org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragmentsOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetQueryPlanFragments_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetQueryPlanFragments_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments.class, org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        query_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = 1;
        bitField0_ = (bitField0_ & ~0x00000002);
        splitPlan_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetQueryPlanFragments_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments build() {
        org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments result = new org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.query_ = query_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.splitPlan_ = splitPlan_;
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments.getDefaultInstance()) return this;
        if (other.hasQuery()) {
          bitField0_ |= 0x00000001;
          query_ = other.query_;
          onChanged();
        }
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasSplitPlan()) {
          setSplitPlan(other.getSplitPlan());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        if (!hasQuery()) {
          return false;
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                query_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 16: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.QueryType tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.QueryType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(2, tmpRaw);
                } else {
                  type_ = tmpRaw;
                  bitField0_ |= 0x00000002;
                }
                break;
              } // case 16
              case 24: {
                splitPlan_ = input.readBool();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object query_ = "";
      /**
       * <code>required string query = 1;</code>
       * @return Whether the query field is set.
       */
      public boolean hasQuery() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>required string query = 1;</code>
       * @return The query.
       */
      public java.lang.String getQuery() {
        java.lang.Object ref = query_;
        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()) {
            query_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>required string query = 1;</code>
       * @return The bytes for query.
       */
      public com.google.protobuf.ByteString
          getQueryBytes() {
        java.lang.Object ref = query_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          query_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>required string query = 1;</code>
       * @param value The query to set.
       * @return This builder for chaining.
       */
      public Builder setQuery(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>required string query = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearQuery() {
        bitField0_ = (bitField0_ & ~0x00000001);
        query_ = getDefaultInstance().getQuery();
        onChanged();
        return this;
      }
      /**
       * <code>required string query = 1;</code>
       * @param value The bytes for query to set.
       * @return This builder for chaining.
       */
      public Builder setQueryBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        query_ = value;
        onChanged();
        return this;
      }

      private int type_ = 1;
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return Whether the type field is set.
       */
      @java.lang.Override public boolean hasType() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return The type.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryType getType() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryType result = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(type_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryType.SQL : result;
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(org.apache.drill.exec.proto.UserBitShared.QueryType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        type_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000002);
        type_ = 1;
        onChanged();
        return this;
      }

      private boolean splitPlan_ ;
      /**
       * <code>optional bool split_plan = 3 [default = false];</code>
       * @return Whether the splitPlan field is set.
       */
      @java.lang.Override
      public boolean hasSplitPlan() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional bool split_plan = 3 [default = false];</code>
       * @return The splitPlan.
       */
      @java.lang.Override
      public boolean getSplitPlan() {
        return splitPlan_;
      }
      /**
       * <code>optional bool split_plan = 3 [default = false];</code>
       * @param value The splitPlan to set.
       * @return This builder for chaining.
       */
      public Builder setSplitPlan(boolean value) {
        bitField0_ |= 0x00000004;
        splitPlan_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool split_plan = 3 [default = false];</code>
       * @return This builder for chaining.
       */
      public Builder clearSplitPlan() {
        bitField0_ = (bitField0_ & ~0x00000004);
        splitPlan_ = false;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetQueryPlanFragments)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetQueryPlanFragments)
    private static final org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetQueryPlanFragments>
        PARSER = new com.google.protobuf.AbstractParser<GetQueryPlanFragments>() {
      @java.lang.Override
      public GetQueryPlanFragments parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetQueryPlanFragments> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetQueryPlanFragments> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetQueryPlanFragments getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface QueryPlanFragmentsOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.QueryPlanFragments)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getStatus();

    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return Whether the queryId field is set.
     */
    boolean hasQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return The queryId.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId();
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder();

    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> 
        getFragmentsList();
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    org.apache.drill.exec.proto.BitControl.PlanFragment getFragments(int index);
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    int getFragmentsCount();
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
        getFragmentsOrBuilderList();
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentsOrBuilder(
        int index);

    /**
     * <code>optional .exec.shared.DrillPBError error = 4;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 4;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 4;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();
  }
  /**
   * Protobuf type {@code exec.user.QueryPlanFragments}
   */
  public static final class QueryPlanFragments extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.QueryPlanFragments)
      QueryPlanFragmentsOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use QueryPlanFragments.newBuilder() to construct.
    private QueryPlanFragments(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private QueryPlanFragments() {
      status_ = 0;
      fragments_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new QueryPlanFragments();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_QueryPlanFragments_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_QueryPlanFragments_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.QueryPlanFragments.class, org.apache.drill.exec.proto.UserProtos.QueryPlanFragments.Builder.class);
    }

    private int bitField0_;
    public static final int STATUS_FIELD_NUMBER = 1;
    private int status_;
    /**
     * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
    }

    public static final int QUERY_ID_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return Whether the queryId field is set.
     */
    @java.lang.Override
    public boolean hasQueryId() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     * @return The queryId.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }
    /**
     * <code>optional .exec.shared.QueryId query_id = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
      return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
    }

    public static final int FRAGMENTS_FIELD_NUMBER = 3;
    private java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> fragments_;
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> getFragmentsList() {
      return fragments_;
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
        getFragmentsOrBuilderList() {
      return fragments_;
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    @java.lang.Override
    public int getFragmentsCount() {
      return fragments_.size();
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.PlanFragment getFragments(int index) {
      return fragments_.get(index);
    }
    /**
     * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentsOrBuilder(
        int index) {
      return fragments_.get(index);
    }

    public static final int ERROR_FIELD_NUMBER = 4;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 4;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 4;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasStatus()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, status_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getQueryId());
      }
      for (int i = 0; i < fragments_.size(); i++) {
        output.writeMessage(3, fragments_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(4, getError());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, status_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getQueryId());
      }
      for (int i = 0; i < fragments_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, fragments_.get(i));
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getError());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.QueryPlanFragments)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.QueryPlanFragments other = (org.apache.drill.exec.proto.UserProtos.QueryPlanFragments) obj;

      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (hasQueryId() != other.hasQueryId()) return false;
      if (hasQueryId()) {
        if (!getQueryId()
            .equals(other.getQueryId())) return false;
      }
      if (!getFragmentsList()
          .equals(other.getFragmentsList())) return false;
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (hasQueryId()) {
        hash = (37 * hash) + QUERY_ID_FIELD_NUMBER;
        hash = (53 * hash) + getQueryId().hashCode();
      }
      if (getFragmentsCount() > 0) {
        hash = (37 * hash) + FRAGMENTS_FIELD_NUMBER;
        hash = (53 * hash) + getFragmentsList().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments 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.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.QueryPlanFragments prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.QueryPlanFragments}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.QueryPlanFragments)
        org.apache.drill.exec.proto.UserProtos.QueryPlanFragmentsOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_QueryPlanFragments_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_QueryPlanFragments_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.QueryPlanFragments.class, org.apache.drill.exec.proto.UserProtos.QueryPlanFragments.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.QueryPlanFragments.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getQueryIdFieldBuilder();
          getFragmentsFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (queryIdBuilder_ == null) {
          queryId_ = null;
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (fragmentsBuilder_ == null) {
          fragments_ = java.util.Collections.emptyList();
        } else {
          fragments_ = null;
          fragmentsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_QueryPlanFragments_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.QueryPlanFragments getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.QueryPlanFragments.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.QueryPlanFragments build() {
        org.apache.drill.exec.proto.UserProtos.QueryPlanFragments result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.QueryPlanFragments buildPartial() {
        org.apache.drill.exec.proto.UserProtos.QueryPlanFragments result = new org.apache.drill.exec.proto.UserProtos.QueryPlanFragments(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.status_ = status_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (queryIdBuilder_ == null) {
            result.queryId_ = queryId_;
          } else {
            result.queryId_ = queryIdBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (fragmentsBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0)) {
            fragments_ = java.util.Collections.unmodifiableList(fragments_);
            bitField0_ = (bitField0_ & ~0x00000004);
          }
          result.fragments_ = fragments_;
        } else {
          result.fragments_ = fragmentsBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.QueryPlanFragments) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.QueryPlanFragments)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.QueryPlanFragments other) {
        if (other == org.apache.drill.exec.proto.UserProtos.QueryPlanFragments.getDefaultInstance()) return this;
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (other.hasQueryId()) {
          mergeQueryId(other.getQueryId());
        }
        if (fragmentsBuilder_ == null) {
          if (!other.fragments_.isEmpty()) {
            if (fragments_.isEmpty()) {
              fragments_ = other.fragments_;
              bitField0_ = (bitField0_ & ~0x00000004);
            } else {
              ensureFragmentsIsMutable();
              fragments_.addAll(other.fragments_);
            }
            onChanged();
          }
        } else {
          if (!other.fragments_.isEmpty()) {
            if (fragmentsBuilder_.isEmpty()) {
              fragmentsBuilder_.dispose();
              fragmentsBuilder_ = null;
              fragments_ = other.fragments_;
              bitField0_ = (bitField0_ & ~0x00000004);
              fragmentsBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFragmentsFieldBuilder() : null;
            } else {
              fragmentsBuilder_.addAllMessages(other.fragments_);
            }
          }
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        if (!hasStatus()) {
          return false;
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                input.readMessage(
                    getQueryIdFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                org.apache.drill.exec.proto.BitControl.PlanFragment m =
                    input.readMessage(
                        org.apache.drill.exec.proto.BitControl.PlanFragment.PARSER,
                        extensionRegistry);
                if (fragmentsBuilder_ == null) {
                  ensureFragmentsIsMutable();
                  fragments_.add(m);
                } else {
                  fragmentsBuilder_.addMessage(m);
                }
                break;
              } // case 26
              case 34: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int status_ = 0;
      /**
       * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState result = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.STARTING : result;
      }
      /**
       * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>required .exec.shared.QueryResult.QueryState status = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserBitShared.QueryId queryId_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> queryIdBuilder_;
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       * @return Whether the queryId field is set.
       */
      public boolean hasQueryId() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       * @return The queryId.
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId getQueryId() {
        if (queryIdBuilder_ == null) {
          return queryId_ == null ? org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        } else {
          return queryIdBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder setQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          queryId_ = value;
          onChanged();
        } else {
          queryIdBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder setQueryId(
          org.apache.drill.exec.proto.UserBitShared.QueryId.Builder builderForValue) {
        if (queryIdBuilder_ == null) {
          queryId_ = builderForValue.build();
          onChanged();
        } else {
          queryIdBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder mergeQueryId(org.apache.drill.exec.proto.UserBitShared.QueryId value) {
        if (queryIdBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              queryId_ != null &&
              queryId_ != org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance()) {
            queryId_ =
              org.apache.drill.exec.proto.UserBitShared.QueryId.newBuilder(queryId_).mergeFrom(value).buildPartial();
          } else {
            queryId_ = value;
          }
          onChanged();
        } else {
          queryIdBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public Builder clearQueryId() {
        if (queryIdBuilder_ == null) {
          queryId_ = null;
          onChanged();
        } else {
          queryIdBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryId.Builder getQueryIdBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getQueryIdFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder getQueryIdOrBuilder() {
        if (queryIdBuilder_ != null) {
          return queryIdBuilder_.getMessageOrBuilder();
        } else {
          return queryId_ == null ?
              org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance() : queryId_;
        }
      }
      /**
       * <code>optional .exec.shared.QueryId query_id = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder> 
          getQueryIdFieldBuilder() {
        if (queryIdBuilder_ == null) {
          queryIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.QueryId, org.apache.drill.exec.proto.UserBitShared.QueryId.Builder, org.apache.drill.exec.proto.UserBitShared.QueryIdOrBuilder>(
                  getQueryId(),
                  getParentForChildren(),
                  isClean());
          queryId_ = null;
        }
        return queryIdBuilder_;
      }

      private java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> fragments_ =
        java.util.Collections.emptyList();
      private void ensureFragmentsIsMutable() {
        if (!((bitField0_ & 0x00000004) != 0)) {
          fragments_ = new java.util.ArrayList<org.apache.drill.exec.proto.BitControl.PlanFragment>(fragments_);
          bitField0_ |= 0x00000004;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> fragmentsBuilder_;

      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> getFragmentsList() {
        if (fragmentsBuilder_ == null) {
          return java.util.Collections.unmodifiableList(fragments_);
        } else {
          return fragmentsBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public int getFragmentsCount() {
        if (fragmentsBuilder_ == null) {
          return fragments_.size();
        } else {
          return fragmentsBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment getFragments(int index) {
        if (fragmentsBuilder_ == null) {
          return fragments_.get(index);
        } else {
          return fragmentsBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder setFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentsIsMutable();
          fragments_.set(index, value);
          onChanged();
        } else {
          fragmentsBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder setFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.set(index, builderForValue.build());
          onChanged();
        } else {
          fragmentsBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder addFragments(org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentsIsMutable();
          fragments_.add(value);
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder addFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentsIsMutable();
          fragments_.add(index, value);
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder addFragments(
          org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.add(builderForValue.build());
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder addFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.add(index, builderForValue.build());
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder addAllFragments(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.BitControl.PlanFragment> values) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, fragments_);
          onChanged();
        } else {
          fragmentsBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder clearFragments() {
        if (fragmentsBuilder_ == null) {
          fragments_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000004);
          onChanged();
        } else {
          fragmentsBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public Builder removeFragments(int index) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.remove(index);
          onChanged();
        } else {
          fragmentsBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder getFragmentsBuilder(
          int index) {
        return getFragmentsFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentsOrBuilder(
          int index) {
        if (fragmentsBuilder_ == null) {
          return fragments_.get(index);  } else {
          return fragmentsBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
           getFragmentsOrBuilderList() {
        if (fragmentsBuilder_ != null) {
          return fragmentsBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(fragments_);
        }
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder addFragmentsBuilder() {
        return getFragmentsFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.BitControl.PlanFragment.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder addFragmentsBuilder(
          int index) {
        return getFragmentsFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.BitControl.PlanFragment.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.bit.control.PlanFragment fragments = 3;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment.Builder> 
           getFragmentsBuilderList() {
        return getFragmentsFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
          getFragmentsFieldBuilder() {
        if (fragmentsBuilder_ == null) {
          fragmentsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder>(
                  fragments_,
                  ((bitField0_ & 0x00000004) != 0),
                  getParentForChildren(),
                  isClean());
          fragments_ = null;
        }
        return fragmentsBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.QueryPlanFragments)
    }

    // @@protoc_insertion_point(class_scope:exec.user.QueryPlanFragments)
    private static final org.apache.drill.exec.proto.UserProtos.QueryPlanFragments DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.QueryPlanFragments();
    }

    public static org.apache.drill.exec.proto.UserProtos.QueryPlanFragments getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<QueryPlanFragments>
        PARSER = new com.google.protobuf.AbstractParser<QueryPlanFragments>() {
      @java.lang.Override
      public QueryPlanFragments parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<QueryPlanFragments> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<QueryPlanFragments> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.QueryPlanFragments getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface BitToUserHandshakeOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.BitToUserHandshake)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional int32 rpc_version = 2;</code>
     * @return Whether the rpcVersion field is set.
     */
    boolean hasRpcVersion();
    /**
     * <code>optional int32 rpc_version = 2;</code>
     * @return The rpcVersion.
     */
    int getRpcVersion();

    /**
     * <code>optional .exec.user.HandshakeStatus status = 3;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.user.HandshakeStatus status = 3;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserProtos.HandshakeStatus getStatus();

    /**
     * <code>optional string errorId = 4;</code>
     * @return Whether the errorId field is set.
     */
    boolean hasErrorId();
    /**
     * <code>optional string errorId = 4;</code>
     * @return The errorId.
     */
    java.lang.String getErrorId();
    /**
     * <code>optional string errorId = 4;</code>
     * @return The bytes for errorId.
     */
    com.google.protobuf.ByteString
        getErrorIdBytes();

    /**
     * <code>optional string errorMessage = 5;</code>
     * @return Whether the errorMessage field is set.
     */
    boolean hasErrorMessage();
    /**
     * <code>optional string errorMessage = 5;</code>
     * @return The errorMessage.
     */
    java.lang.String getErrorMessage();
    /**
     * <code>optional string errorMessage = 5;</code>
     * @return The bytes for errorMessage.
     */
    com.google.protobuf.ByteString
        getErrorMessageBytes();

    /**
     * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
     * @return Whether the serverInfos field is set.
     */
    boolean hasServerInfos();
    /**
     * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
     * @return The serverInfos.
     */
    org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getServerInfos();
    /**
     * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
     */
    org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder getServerInfosOrBuilder();

    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @return A list containing the authenticationMechanisms.
     */
    java.util.List<java.lang.String>
        getAuthenticationMechanismsList();
    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @return The count of authenticationMechanisms.
     */
    int getAuthenticationMechanismsCount();
    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @param index The index of the element to return.
     * @return The authenticationMechanisms at the given index.
     */
    java.lang.String getAuthenticationMechanisms(int index);
    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @param index The index of the value to return.
     * @return The bytes of the authenticationMechanisms at the given index.
     */
    com.google.protobuf.ByteString
        getAuthenticationMechanismsBytes(int index);

    /**
     * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
     * @return A list containing the supportedMethods.
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.RpcType> getSupportedMethodsList();
    /**
     * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
     * @return The count of supportedMethods.
     */
    int getSupportedMethodsCount();
    /**
     * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
     * @param index The index of the element to return.
     * @return The supportedMethods at the given index.
     */
    org.apache.drill.exec.proto.UserProtos.RpcType getSupportedMethods(int index);

    /**
     * <code>optional bool encrypted = 9;</code>
     * @return Whether the encrypted field is set.
     */
    boolean hasEncrypted();
    /**
     * <code>optional bool encrypted = 9;</code>
     * @return The encrypted.
     */
    boolean getEncrypted();

    /**
     * <code>optional int32 maxWrappedSize = 10;</code>
     * @return Whether the maxWrappedSize field is set.
     */
    boolean hasMaxWrappedSize();
    /**
     * <code>optional int32 maxWrappedSize = 10;</code>
     * @return The maxWrappedSize.
     */
    int getMaxWrappedSize();
  }
  /**
   * Protobuf type {@code exec.user.BitToUserHandshake}
   */
  public static final class BitToUserHandshake extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.BitToUserHandshake)
      BitToUserHandshakeOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use BitToUserHandshake.newBuilder() to construct.
    private BitToUserHandshake(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private BitToUserHandshake() {
      status_ = 1;
      errorId_ = "";
      errorMessage_ = "";
      authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      supportedMethods_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new BitToUserHandshake();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_BitToUserHandshake_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_BitToUserHandshake_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.BitToUserHandshake.class, org.apache.drill.exec.proto.UserProtos.BitToUserHandshake.Builder.class);
    }

    private int bitField0_;
    public static final int RPC_VERSION_FIELD_NUMBER = 2;
    private int rpcVersion_;
    /**
     * <code>optional int32 rpc_version = 2;</code>
     * @return Whether the rpcVersion field is set.
     */
    @java.lang.Override
    public boolean hasRpcVersion() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional int32 rpc_version = 2;</code>
     * @return The rpcVersion.
     */
    @java.lang.Override
    public int getRpcVersion() {
      return rpcVersion_;
    }

    public static final int STATUS_FIELD_NUMBER = 3;
    private int status_;
    /**
     * <code>optional .exec.user.HandshakeStatus status = 3;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.user.HandshakeStatus status = 3;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.HandshakeStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.HandshakeStatus result = org.apache.drill.exec.proto.UserProtos.HandshakeStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.HandshakeStatus.SUCCESS : result;
    }

    public static final int ERRORID_FIELD_NUMBER = 4;
    private volatile java.lang.Object errorId_;
    /**
     * <code>optional string errorId = 4;</code>
     * @return Whether the errorId field is set.
     */
    @java.lang.Override
    public boolean hasErrorId() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional string errorId = 4;</code>
     * @return The errorId.
     */
    @java.lang.Override
    public java.lang.String getErrorId() {
      java.lang.Object ref = errorId_;
      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()) {
          errorId_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string errorId = 4;</code>
     * @return The bytes for errorId.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getErrorIdBytes() {
      java.lang.Object ref = errorId_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        errorId_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ERRORMESSAGE_FIELD_NUMBER = 5;
    private volatile java.lang.Object errorMessage_;
    /**
     * <code>optional string errorMessage = 5;</code>
     * @return Whether the errorMessage field is set.
     */
    @java.lang.Override
    public boolean hasErrorMessage() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional string errorMessage = 5;</code>
     * @return The errorMessage.
     */
    @java.lang.Override
    public java.lang.String getErrorMessage() {
      java.lang.Object ref = errorMessage_;
      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()) {
          errorMessage_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string errorMessage = 5;</code>
     * @return The bytes for errorMessage.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getErrorMessageBytes() {
      java.lang.Object ref = errorMessage_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        errorMessage_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SERVER_INFOS_FIELD_NUMBER = 6;
    private org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos serverInfos_;
    /**
     * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
     * @return Whether the serverInfos field is set.
     */
    @java.lang.Override
    public boolean hasServerInfos() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
     * @return The serverInfos.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getServerInfos() {
      return serverInfos_ == null ? org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : serverInfos_;
    }
    /**
     * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder getServerInfosOrBuilder() {
      return serverInfos_ == null ? org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : serverInfos_;
    }

    public static final int AUTHENTICATIONMECHANISMS_FIELD_NUMBER = 7;
    private com.google.protobuf.LazyStringList authenticationMechanisms_;
    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @return A list containing the authenticationMechanisms.
     */
    public com.google.protobuf.ProtocolStringList
        getAuthenticationMechanismsList() {
      return authenticationMechanisms_;
    }
    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @return The count of authenticationMechanisms.
     */
    public int getAuthenticationMechanismsCount() {
      return authenticationMechanisms_.size();
    }
    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @param index The index of the element to return.
     * @return The authenticationMechanisms at the given index.
     */
    public java.lang.String getAuthenticationMechanisms(int index) {
      return authenticationMechanisms_.get(index);
    }
    /**
     * <code>repeated string authenticationMechanisms = 7;</code>
     * @param index The index of the value to return.
     * @return The bytes of the authenticationMechanisms at the given index.
     */
    public com.google.protobuf.ByteString
        getAuthenticationMechanismsBytes(int index) {
      return authenticationMechanisms_.getByteString(index);
    }

    public static final int SUPPORTED_METHODS_FIELD_NUMBER = 8;
    private java.util.List<java.lang.Integer> supportedMethods_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.exec.proto.UserProtos.RpcType> supportedMethods_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.exec.proto.UserProtos.RpcType>() {
              public org.apache.drill.exec.proto.UserProtos.RpcType convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.exec.proto.UserProtos.RpcType result = org.apache.drill.exec.proto.UserProtos.RpcType.valueOf(from);
                return result == null ? org.apache.drill.exec.proto.UserProtos.RpcType.HANDSHAKE : result;
              }
            };
    /**
     * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
     * @return A list containing the supportedMethods.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.RpcType> getSupportedMethodsList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.exec.proto.UserProtos.RpcType>(supportedMethods_, supportedMethods_converter_);
    }
    /**
     * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
     * @return The count of supportedMethods.
     */
    @java.lang.Override
    public int getSupportedMethodsCount() {
      return supportedMethods_.size();
    }
    /**
     * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
     * @param index The index of the element to return.
     * @return The supportedMethods at the given index.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RpcType getSupportedMethods(int index) {
      return supportedMethods_converter_.convert(supportedMethods_.get(index));
    }

    public static final int ENCRYPTED_FIELD_NUMBER = 9;
    private boolean encrypted_;
    /**
     * <code>optional bool encrypted = 9;</code>
     * @return Whether the encrypted field is set.
     */
    @java.lang.Override
    public boolean hasEncrypted() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional bool encrypted = 9;</code>
     * @return The encrypted.
     */
    @java.lang.Override
    public boolean getEncrypted() {
      return encrypted_;
    }

    public static final int MAXWRAPPEDSIZE_FIELD_NUMBER = 10;
    private int maxWrappedSize_;
    /**
     * <code>optional int32 maxWrappedSize = 10;</code>
     * @return Whether the maxWrappedSize field is set.
     */
    @java.lang.Override
    public boolean hasMaxWrappedSize() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional int32 maxWrappedSize = 10;</code>
     * @return The maxWrappedSize.
     */
    @java.lang.Override
    public int getMaxWrappedSize() {
      return maxWrappedSize_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeInt32(2, rpcVersion_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeEnum(3, status_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, errorId_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, errorMessage_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeMessage(6, getServerInfos());
      }
      for (int i = 0; i < authenticationMechanisms_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 7, authenticationMechanisms_.getRaw(i));
      }
      for (int i = 0; i < supportedMethods_.size(); i++) {
        output.writeEnum(8, supportedMethods_.get(i));
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeBool(9, encrypted_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeInt32(10, maxWrappedSize_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(2, rpcVersion_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(3, status_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, errorId_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, errorMessage_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(6, getServerInfos());
      }
      {
        int dataSize = 0;
        for (int i = 0; i < authenticationMechanisms_.size(); i++) {
          dataSize += computeStringSizeNoTag(authenticationMechanisms_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getAuthenticationMechanismsList().size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < supportedMethods_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(supportedMethods_.get(i));
        }
        size += dataSize;
        size += 1 * supportedMethods_.size();
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(9, encrypted_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(10, maxWrappedSize_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.BitToUserHandshake)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.BitToUserHandshake other = (org.apache.drill.exec.proto.UserProtos.BitToUserHandshake) obj;

      if (hasRpcVersion() != other.hasRpcVersion()) return false;
      if (hasRpcVersion()) {
        if (getRpcVersion()
            != other.getRpcVersion()) return false;
      }
      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (hasErrorId() != other.hasErrorId()) return false;
      if (hasErrorId()) {
        if (!getErrorId()
            .equals(other.getErrorId())) return false;
      }
      if (hasErrorMessage() != other.hasErrorMessage()) return false;
      if (hasErrorMessage()) {
        if (!getErrorMessage()
            .equals(other.getErrorMessage())) return false;
      }
      if (hasServerInfos() != other.hasServerInfos()) return false;
      if (hasServerInfos()) {
        if (!getServerInfos()
            .equals(other.getServerInfos())) return false;
      }
      if (!getAuthenticationMechanismsList()
          .equals(other.getAuthenticationMechanismsList())) return false;
      if (!supportedMethods_.equals(other.supportedMethods_)) return false;
      if (hasEncrypted() != other.hasEncrypted()) return false;
      if (hasEncrypted()) {
        if (getEncrypted()
            != other.getEncrypted()) return false;
      }
      if (hasMaxWrappedSize() != other.hasMaxWrappedSize()) return false;
      if (hasMaxWrappedSize()) {
        if (getMaxWrappedSize()
            != other.getMaxWrappedSize()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasRpcVersion()) {
        hash = (37 * hash) + RPC_VERSION_FIELD_NUMBER;
        hash = (53 * hash) + getRpcVersion();
      }
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (hasErrorId()) {
        hash = (37 * hash) + ERRORID_FIELD_NUMBER;
        hash = (53 * hash) + getErrorId().hashCode();
      }
      if (hasErrorMessage()) {
        hash = (37 * hash) + ERRORMESSAGE_FIELD_NUMBER;
        hash = (53 * hash) + getErrorMessage().hashCode();
      }
      if (hasServerInfos()) {
        hash = (37 * hash) + SERVER_INFOS_FIELD_NUMBER;
        hash = (53 * hash) + getServerInfos().hashCode();
      }
      if (getAuthenticationMechanismsCount() > 0) {
        hash = (37 * hash) + AUTHENTICATIONMECHANISMS_FIELD_NUMBER;
        hash = (53 * hash) + getAuthenticationMechanismsList().hashCode();
      }
      if (getSupportedMethodsCount() > 0) {
        hash = (37 * hash) + SUPPORTED_METHODS_FIELD_NUMBER;
        hash = (53 * hash) + supportedMethods_.hashCode();
      }
      if (hasEncrypted()) {
        hash = (37 * hash) + ENCRYPTED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getEncrypted());
      }
      if (hasMaxWrappedSize()) {
        hash = (37 * hash) + MAXWRAPPEDSIZE_FIELD_NUMBER;
        hash = (53 * hash) + getMaxWrappedSize();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake 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.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.BitToUserHandshake prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.BitToUserHandshake}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.BitToUserHandshake)
        org.apache.drill.exec.proto.UserProtos.BitToUserHandshakeOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_BitToUserHandshake_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_BitToUserHandshake_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.BitToUserHandshake.class, org.apache.drill.exec.proto.UserProtos.BitToUserHandshake.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.BitToUserHandshake.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getServerInfosFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        rpcVersion_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 1;
        bitField0_ = (bitField0_ & ~0x00000002);
        errorId_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        errorMessage_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        if (serverInfosBuilder_ == null) {
          serverInfos_ = null;
        } else {
          serverInfosBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000020);
        supportedMethods_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000040);
        encrypted_ = false;
        bitField0_ = (bitField0_ & ~0x00000080);
        maxWrappedSize_ = 0;
        bitField0_ = (bitField0_ & ~0x00000100);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_BitToUserHandshake_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.BitToUserHandshake getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.BitToUserHandshake.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.BitToUserHandshake build() {
        org.apache.drill.exec.proto.UserProtos.BitToUserHandshake result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.BitToUserHandshake buildPartial() {
        org.apache.drill.exec.proto.UserProtos.BitToUserHandshake result = new org.apache.drill.exec.proto.UserProtos.BitToUserHandshake(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.rpcVersion_ = rpcVersion_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.status_ = status_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.errorId_ = errorId_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.errorMessage_ = errorMessage_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          if (serverInfosBuilder_ == null) {
            result.serverInfos_ = serverInfos_;
          } else {
            result.serverInfos_ = serverInfosBuilder_.build();
          }
          to_bitField0_ |= 0x00000010;
        }
        if (((bitField0_ & 0x00000020) != 0)) {
          authenticationMechanisms_ = authenticationMechanisms_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000020);
        }
        result.authenticationMechanisms_ = authenticationMechanisms_;
        if (((bitField0_ & 0x00000040) != 0)) {
          supportedMethods_ = java.util.Collections.unmodifiableList(supportedMethods_);
          bitField0_ = (bitField0_ & ~0x00000040);
        }
        result.supportedMethods_ = supportedMethods_;
        if (((from_bitField0_ & 0x00000080) != 0)) {
          result.encrypted_ = encrypted_;
          to_bitField0_ |= 0x00000020;
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          result.maxWrappedSize_ = maxWrappedSize_;
          to_bitField0_ |= 0x00000040;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.BitToUserHandshake) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.BitToUserHandshake)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.BitToUserHandshake other) {
        if (other == org.apache.drill.exec.proto.UserProtos.BitToUserHandshake.getDefaultInstance()) return this;
        if (other.hasRpcVersion()) {
          setRpcVersion(other.getRpcVersion());
        }
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (other.hasErrorId()) {
          bitField0_ |= 0x00000004;
          errorId_ = other.errorId_;
          onChanged();
        }
        if (other.hasErrorMessage()) {
          bitField0_ |= 0x00000008;
          errorMessage_ = other.errorMessage_;
          onChanged();
        }
        if (other.hasServerInfos()) {
          mergeServerInfos(other.getServerInfos());
        }
        if (!other.authenticationMechanisms_.isEmpty()) {
          if (authenticationMechanisms_.isEmpty()) {
            authenticationMechanisms_ = other.authenticationMechanisms_;
            bitField0_ = (bitField0_ & ~0x00000020);
          } else {
            ensureAuthenticationMechanismsIsMutable();
            authenticationMechanisms_.addAll(other.authenticationMechanisms_);
          }
          onChanged();
        }
        if (!other.supportedMethods_.isEmpty()) {
          if (supportedMethods_.isEmpty()) {
            supportedMethods_ = other.supportedMethods_;
            bitField0_ = (bitField0_ & ~0x00000040);
          } else {
            ensureSupportedMethodsIsMutable();
            supportedMethods_.addAll(other.supportedMethods_);
          }
          onChanged();
        }
        if (other.hasEncrypted()) {
          setEncrypted(other.getEncrypted());
        }
        if (other.hasMaxWrappedSize()) {
          setMaxWrappedSize(other.getMaxWrappedSize());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 16: {
                rpcVersion_ = input.readInt32();
                bitField0_ |= 0x00000001;
                break;
              } // case 16
              case 24: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.HandshakeStatus tmpValue =
                    org.apache.drill.exec.proto.UserProtos.HandshakeStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(3, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000002;
                }
                break;
              } // case 24
              case 34: {
                errorId_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 34
              case 42: {
                errorMessage_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 42
              case 50: {
                input.readMessage(
                    getServerInfosFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000010;
                break;
              } // case 50
              case 58: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureAuthenticationMechanismsIsMutable();
                authenticationMechanisms_.add(bs);
                break;
              } // case 58
              case 64: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.RpcType tmpValue =
                    org.apache.drill.exec.proto.UserProtos.RpcType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(8, tmpRaw);
                } else {
                  ensureSupportedMethodsIsMutable();
                  supportedMethods_.add(tmpRaw);
                }
                break;
              } // case 64
              case 66: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.exec.proto.UserProtos.RpcType tmpValue =
                      org.apache.drill.exec.proto.UserProtos.RpcType.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(8, tmpRaw);
                  } else {
                    ensureSupportedMethodsIsMutable();
                    supportedMethods_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 66
              case 72: {
                encrypted_ = input.readBool();
                bitField0_ |= 0x00000080;
                break;
              } // case 72
              case 80: {
                maxWrappedSize_ = input.readInt32();
                bitField0_ |= 0x00000100;
                break;
              } // case 80
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int rpcVersion_ ;
      /**
       * <code>optional int32 rpc_version = 2;</code>
       * @return Whether the rpcVersion field is set.
       */
      @java.lang.Override
      public boolean hasRpcVersion() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional int32 rpc_version = 2;</code>
       * @return The rpcVersion.
       */
      @java.lang.Override
      public int getRpcVersion() {
        return rpcVersion_;
      }
      /**
       * <code>optional int32 rpc_version = 2;</code>
       * @param value The rpcVersion to set.
       * @return This builder for chaining.
       */
      public Builder setRpcVersion(int value) {
        bitField0_ |= 0x00000001;
        rpcVersion_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 rpc_version = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearRpcVersion() {
        bitField0_ = (bitField0_ & ~0x00000001);
        rpcVersion_ = 0;
        onChanged();
        return this;
      }

      private int status_ = 1;
      /**
       * <code>optional .exec.user.HandshakeStatus status = 3;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.user.HandshakeStatus status = 3;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.HandshakeStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.HandshakeStatus result = org.apache.drill.exec.proto.UserProtos.HandshakeStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.HandshakeStatus.SUCCESS : result;
      }
      /**
       * <code>optional .exec.user.HandshakeStatus status = 3;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserProtos.HandshakeStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.HandshakeStatus status = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000002);
        status_ = 1;
        onChanged();
        return this;
      }

      private java.lang.Object errorId_ = "";
      /**
       * <code>optional string errorId = 4;</code>
       * @return Whether the errorId field is set.
       */
      public boolean hasErrorId() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional string errorId = 4;</code>
       * @return The errorId.
       */
      public java.lang.String getErrorId() {
        java.lang.Object ref = errorId_;
        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()) {
            errorId_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string errorId = 4;</code>
       * @return The bytes for errorId.
       */
      public com.google.protobuf.ByteString
          getErrorIdBytes() {
        java.lang.Object ref = errorId_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          errorId_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string errorId = 4;</code>
       * @param value The errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorId(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        errorId_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string errorId = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearErrorId() {
        bitField0_ = (bitField0_ & ~0x00000004);
        errorId_ = getDefaultInstance().getErrorId();
        onChanged();
        return this;
      }
      /**
       * <code>optional string errorId = 4;</code>
       * @param value The bytes for errorId to set.
       * @return This builder for chaining.
       */
      public Builder setErrorIdBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        errorId_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object errorMessage_ = "";
      /**
       * <code>optional string errorMessage = 5;</code>
       * @return Whether the errorMessage field is set.
       */
      public boolean hasErrorMessage() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional string errorMessage = 5;</code>
       * @return The errorMessage.
       */
      public java.lang.String getErrorMessage() {
        java.lang.Object ref = errorMessage_;
        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()) {
            errorMessage_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string errorMessage = 5;</code>
       * @return The bytes for errorMessage.
       */
      public com.google.protobuf.ByteString
          getErrorMessageBytes() {
        java.lang.Object ref = errorMessage_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          errorMessage_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string errorMessage = 5;</code>
       * @param value The errorMessage to set.
       * @return This builder for chaining.
       */
      public Builder setErrorMessage(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        errorMessage_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string errorMessage = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearErrorMessage() {
        bitField0_ = (bitField0_ & ~0x00000008);
        errorMessage_ = getDefaultInstance().getErrorMessage();
        onChanged();
        return this;
      }
      /**
       * <code>optional string errorMessage = 5;</code>
       * @param value The bytes for errorMessage to set.
       * @return This builder for chaining.
       */
      public Builder setErrorMessageBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        errorMessage_ = value;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos serverInfos_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder> serverInfosBuilder_;
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       * @return Whether the serverInfos field is set.
       */
      public boolean hasServerInfos() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       * @return The serverInfos.
       */
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos getServerInfos() {
        if (serverInfosBuilder_ == null) {
          return serverInfos_ == null ? org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : serverInfos_;
        } else {
          return serverInfosBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       */
      public Builder setServerInfos(org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos value) {
        if (serverInfosBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          serverInfos_ = value;
          onChanged();
        } else {
          serverInfosBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       */
      public Builder setServerInfos(
          org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder builderForValue) {
        if (serverInfosBuilder_ == null) {
          serverInfos_ = builderForValue.build();
          onChanged();
        } else {
          serverInfosBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       */
      public Builder mergeServerInfos(org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos value) {
        if (serverInfosBuilder_ == null) {
          if (((bitField0_ & 0x00000010) != 0) &&
              serverInfos_ != null &&
              serverInfos_ != org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance()) {
            serverInfos_ =
              org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.newBuilder(serverInfos_).mergeFrom(value).buildPartial();
          } else {
            serverInfos_ = value;
          }
          onChanged();
        } else {
          serverInfosBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       */
      public Builder clearServerInfos() {
        if (serverInfosBuilder_ == null) {
          serverInfos_ = null;
          onChanged();
        } else {
          serverInfosBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder getServerInfosBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getServerInfosFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder getServerInfosOrBuilder() {
        if (serverInfosBuilder_ != null) {
          return serverInfosBuilder_.getMessageOrBuilder();
        } else {
          return serverInfos_ == null ?
              org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.getDefaultInstance() : serverInfos_;
        }
      }
      /**
       * <code>optional .exec.user.RpcEndpointInfos server_infos = 6;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder> 
          getServerInfosFieldBuilder() {
        if (serverInfosBuilder_ == null) {
          serverInfosBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfos.Builder, org.apache.drill.exec.proto.UserProtos.RpcEndpointInfosOrBuilder>(
                  getServerInfos(),
                  getParentForChildren(),
                  isClean());
          serverInfos_ = null;
        }
        return serverInfosBuilder_;
      }

      private com.google.protobuf.LazyStringList authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureAuthenticationMechanismsIsMutable() {
        if (!((bitField0_ & 0x00000020) != 0)) {
          authenticationMechanisms_ = new com.google.protobuf.LazyStringArrayList(authenticationMechanisms_);
          bitField0_ |= 0x00000020;
         }
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @return A list containing the authenticationMechanisms.
       */
      public com.google.protobuf.ProtocolStringList
          getAuthenticationMechanismsList() {
        return authenticationMechanisms_.getUnmodifiableView();
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @return The count of authenticationMechanisms.
       */
      public int getAuthenticationMechanismsCount() {
        return authenticationMechanisms_.size();
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @param index The index of the element to return.
       * @return The authenticationMechanisms at the given index.
       */
      public java.lang.String getAuthenticationMechanisms(int index) {
        return authenticationMechanisms_.get(index);
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @param index The index of the value to return.
       * @return The bytes of the authenticationMechanisms at the given index.
       */
      public com.google.protobuf.ByteString
          getAuthenticationMechanismsBytes(int index) {
        return authenticationMechanisms_.getByteString(index);
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @param index The index to set the value at.
       * @param value The authenticationMechanisms to set.
       * @return This builder for chaining.
       */
      public Builder setAuthenticationMechanisms(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureAuthenticationMechanismsIsMutable();
        authenticationMechanisms_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @param value The authenticationMechanisms to add.
       * @return This builder for chaining.
       */
      public Builder addAuthenticationMechanisms(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureAuthenticationMechanismsIsMutable();
        authenticationMechanisms_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @param values The authenticationMechanisms to add.
       * @return This builder for chaining.
       */
      public Builder addAllAuthenticationMechanisms(
          java.lang.Iterable<java.lang.String> values) {
        ensureAuthenticationMechanismsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, authenticationMechanisms_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearAuthenticationMechanisms() {
        authenticationMechanisms_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000020);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string authenticationMechanisms = 7;</code>
       * @param value The bytes of the authenticationMechanisms to add.
       * @return This builder for chaining.
       */
      public Builder addAuthenticationMechanismsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureAuthenticationMechanismsIsMutable();
        authenticationMechanisms_.add(value);
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> supportedMethods_ =
        java.util.Collections.emptyList();
      private void ensureSupportedMethodsIsMutable() {
        if (!((bitField0_ & 0x00000040) != 0)) {
          supportedMethods_ = new java.util.ArrayList<java.lang.Integer>(supportedMethods_);
          bitField0_ |= 0x00000040;
        }
      }
      /**
       * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
       * @return A list containing the supportedMethods.
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.RpcType> getSupportedMethodsList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.exec.proto.UserProtos.RpcType>(supportedMethods_, supportedMethods_converter_);
      }
      /**
       * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
       * @return The count of supportedMethods.
       */
      public int getSupportedMethodsCount() {
        return supportedMethods_.size();
      }
      /**
       * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
       * @param index The index of the element to return.
       * @return The supportedMethods at the given index.
       */
      public org.apache.drill.exec.proto.UserProtos.RpcType getSupportedMethods(int index) {
        return supportedMethods_converter_.convert(supportedMethods_.get(index));
      }
      /**
       * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
       * @param index The index to set the value at.
       * @param value The supportedMethods to set.
       * @return This builder for chaining.
       */
      public Builder setSupportedMethods(
          int index, org.apache.drill.exec.proto.UserProtos.RpcType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSupportedMethodsIsMutable();
        supportedMethods_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
       * @param value The supportedMethods to add.
       * @return This builder for chaining.
       */
      public Builder addSupportedMethods(org.apache.drill.exec.proto.UserProtos.RpcType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSupportedMethodsIsMutable();
        supportedMethods_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
       * @param values The supportedMethods to add.
       * @return This builder for chaining.
       */
      public Builder addAllSupportedMethods(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.RpcType> values) {
        ensureSupportedMethodsIsMutable();
        for (org.apache.drill.exec.proto.UserProtos.RpcType value : values) {
          supportedMethods_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <code>repeated .exec.user.RpcType supported_methods = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearSupportedMethods() {
        supportedMethods_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000040);
        onChanged();
        return this;
      }

      private boolean encrypted_ ;
      /**
       * <code>optional bool encrypted = 9;</code>
       * @return Whether the encrypted field is set.
       */
      @java.lang.Override
      public boolean hasEncrypted() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional bool encrypted = 9;</code>
       * @return The encrypted.
       */
      @java.lang.Override
      public boolean getEncrypted() {
        return encrypted_;
      }
      /**
       * <code>optional bool encrypted = 9;</code>
       * @param value The encrypted to set.
       * @return This builder for chaining.
       */
      public Builder setEncrypted(boolean value) {
        bitField0_ |= 0x00000080;
        encrypted_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool encrypted = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearEncrypted() {
        bitField0_ = (bitField0_ & ~0x00000080);
        encrypted_ = false;
        onChanged();
        return this;
      }

      private int maxWrappedSize_ ;
      /**
       * <code>optional int32 maxWrappedSize = 10;</code>
       * @return Whether the maxWrappedSize field is set.
       */
      @java.lang.Override
      public boolean hasMaxWrappedSize() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional int32 maxWrappedSize = 10;</code>
       * @return The maxWrappedSize.
       */
      @java.lang.Override
      public int getMaxWrappedSize() {
        return maxWrappedSize_;
      }
      /**
       * <code>optional int32 maxWrappedSize = 10;</code>
       * @param value The maxWrappedSize to set.
       * @return This builder for chaining.
       */
      public Builder setMaxWrappedSize(int value) {
        bitField0_ |= 0x00000100;
        maxWrappedSize_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 maxWrappedSize = 10;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxWrappedSize() {
        bitField0_ = (bitField0_ & ~0x00000100);
        maxWrappedSize_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.BitToUserHandshake)
    }

    // @@protoc_insertion_point(class_scope:exec.user.BitToUserHandshake)
    private static final org.apache.drill.exec.proto.UserProtos.BitToUserHandshake DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.BitToUserHandshake();
    }

    public static org.apache.drill.exec.proto.UserProtos.BitToUserHandshake getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<BitToUserHandshake>
        PARSER = new com.google.protobuf.AbstractParser<BitToUserHandshake>() {
      @java.lang.Override
      public BitToUserHandshake parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<BitToUserHandshake> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<BitToUserHandshake> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.BitToUserHandshake getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface LikeFilterOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.LikeFilter)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * pattern to match
     * </pre>
     *
     * <code>optional string pattern = 1;</code>
     * @return Whether the pattern field is set.
     */
    boolean hasPattern();
    /**
     * <pre>
     * pattern to match
     * </pre>
     *
     * <code>optional string pattern = 1;</code>
     * @return The pattern.
     */
    java.lang.String getPattern();
    /**
     * <pre>
     * pattern to match
     * </pre>
     *
     * <code>optional string pattern = 1;</code>
     * @return The bytes for pattern.
     */
    com.google.protobuf.ByteString
        getPatternBytes();

    /**
     * <pre>
     * escape character (if any) present in the pattern
     * </pre>
     *
     * <code>optional string escape = 2;</code>
     * @return Whether the escape field is set.
     */
    boolean hasEscape();
    /**
     * <pre>
     * escape character (if any) present in the pattern
     * </pre>
     *
     * <code>optional string escape = 2;</code>
     * @return The escape.
     */
    java.lang.String getEscape();
    /**
     * <pre>
     * escape character (if any) present in the pattern
     * </pre>
     *
     * <code>optional string escape = 2;</code>
     * @return The bytes for escape.
     */
    com.google.protobuf.ByteString
        getEscapeBytes();
  }
  /**
   * <pre>
   * Simple filter which encapsulates the SQL LIKE ... ESCAPE function
   * </pre>
   *
   * Protobuf type {@code exec.user.LikeFilter}
   */
  public static final class LikeFilter extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.LikeFilter)
      LikeFilterOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use LikeFilter.newBuilder() to construct.
    private LikeFilter(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private LikeFilter() {
      pattern_ = "";
      escape_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new LikeFilter();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_LikeFilter_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_LikeFilter_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.LikeFilter.class, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder.class);
    }

    private int bitField0_;
    public static final int PATTERN_FIELD_NUMBER = 1;
    private volatile java.lang.Object pattern_;
    /**
     * <pre>
     * pattern to match
     * </pre>
     *
     * <code>optional string pattern = 1;</code>
     * @return Whether the pattern field is set.
     */
    @java.lang.Override
    public boolean hasPattern() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * pattern to match
     * </pre>
     *
     * <code>optional string pattern = 1;</code>
     * @return The pattern.
     */
    @java.lang.Override
    public java.lang.String getPattern() {
      java.lang.Object ref = pattern_;
      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()) {
          pattern_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * pattern to match
     * </pre>
     *
     * <code>optional string pattern = 1;</code>
     * @return The bytes for pattern.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getPatternBytes() {
      java.lang.Object ref = pattern_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        pattern_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ESCAPE_FIELD_NUMBER = 2;
    private volatile java.lang.Object escape_;
    /**
     * <pre>
     * escape character (if any) present in the pattern
     * </pre>
     *
     * <code>optional string escape = 2;</code>
     * @return Whether the escape field is set.
     */
    @java.lang.Override
    public boolean hasEscape() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <pre>
     * escape character (if any) present in the pattern
     * </pre>
     *
     * <code>optional string escape = 2;</code>
     * @return The escape.
     */
    @java.lang.Override
    public java.lang.String getEscape() {
      java.lang.Object ref = escape_;
      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()) {
          escape_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * escape character (if any) present in the pattern
     * </pre>
     *
     * <code>optional string escape = 2;</code>
     * @return The bytes for escape.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getEscapeBytes() {
      java.lang.Object ref = escape_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        escape_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, pattern_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, escape_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, pattern_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, escape_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.LikeFilter)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.LikeFilter other = (org.apache.drill.exec.proto.UserProtos.LikeFilter) obj;

      if (hasPattern() != other.hasPattern()) return false;
      if (hasPattern()) {
        if (!getPattern()
            .equals(other.getPattern())) return false;
      }
      if (hasEscape() != other.hasEscape()) return false;
      if (hasEscape()) {
        if (!getEscape()
            .equals(other.getEscape())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasPattern()) {
        hash = (37 * hash) + PATTERN_FIELD_NUMBER;
        hash = (53 * hash) + getPattern().hashCode();
      }
      if (hasEscape()) {
        hash = (37 * hash) + ESCAPE_FIELD_NUMBER;
        hash = (53 * hash) + getEscape().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter 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.drill.exec.proto.UserProtos.LikeFilter parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.LikeFilter parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.LikeFilter prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Simple filter which encapsulates the SQL LIKE ... ESCAPE function
     * </pre>
     *
     * Protobuf type {@code exec.user.LikeFilter}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.LikeFilter)
        org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_LikeFilter_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_LikeFilter_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.LikeFilter.class, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        pattern_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        escape_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_LikeFilter_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.LikeFilter build() {
        org.apache.drill.exec.proto.UserProtos.LikeFilter result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.LikeFilter buildPartial() {
        org.apache.drill.exec.proto.UserProtos.LikeFilter result = new org.apache.drill.exec.proto.UserProtos.LikeFilter(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.pattern_ = pattern_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.escape_ = escape_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.LikeFilter) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.LikeFilter)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.LikeFilter other) {
        if (other == org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) return this;
        if (other.hasPattern()) {
          bitField0_ |= 0x00000001;
          pattern_ = other.pattern_;
          onChanged();
        }
        if (other.hasEscape()) {
          bitField0_ |= 0x00000002;
          escape_ = other.escape_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                pattern_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                escape_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object pattern_ = "";
      /**
       * <pre>
       * pattern to match
       * </pre>
       *
       * <code>optional string pattern = 1;</code>
       * @return Whether the pattern field is set.
       */
      public boolean hasPattern() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * pattern to match
       * </pre>
       *
       * <code>optional string pattern = 1;</code>
       * @return The pattern.
       */
      public java.lang.String getPattern() {
        java.lang.Object ref = pattern_;
        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()) {
            pattern_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * pattern to match
       * </pre>
       *
       * <code>optional string pattern = 1;</code>
       * @return The bytes for pattern.
       */
      public com.google.protobuf.ByteString
          getPatternBytes() {
        java.lang.Object ref = pattern_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          pattern_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * pattern to match
       * </pre>
       *
       * <code>optional string pattern = 1;</code>
       * @param value The pattern to set.
       * @return This builder for chaining.
       */
      public Builder setPattern(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        pattern_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * pattern to match
       * </pre>
       *
       * <code>optional string pattern = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearPattern() {
        bitField0_ = (bitField0_ & ~0x00000001);
        pattern_ = getDefaultInstance().getPattern();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * pattern to match
       * </pre>
       *
       * <code>optional string pattern = 1;</code>
       * @param value The bytes for pattern to set.
       * @return This builder for chaining.
       */
      public Builder setPatternBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        pattern_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object escape_ = "";
      /**
       * <pre>
       * escape character (if any) present in the pattern
       * </pre>
       *
       * <code>optional string escape = 2;</code>
       * @return Whether the escape field is set.
       */
      public boolean hasEscape() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * escape character (if any) present in the pattern
       * </pre>
       *
       * <code>optional string escape = 2;</code>
       * @return The escape.
       */
      public java.lang.String getEscape() {
        java.lang.Object ref = escape_;
        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()) {
            escape_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * escape character (if any) present in the pattern
       * </pre>
       *
       * <code>optional string escape = 2;</code>
       * @return The bytes for escape.
       */
      public com.google.protobuf.ByteString
          getEscapeBytes() {
        java.lang.Object ref = escape_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          escape_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * escape character (if any) present in the pattern
       * </pre>
       *
       * <code>optional string escape = 2;</code>
       * @param value The escape to set.
       * @return This builder for chaining.
       */
      public Builder setEscape(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        escape_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * escape character (if any) present in the pattern
       * </pre>
       *
       * <code>optional string escape = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearEscape() {
        bitField0_ = (bitField0_ & ~0x00000002);
        escape_ = getDefaultInstance().getEscape();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * escape character (if any) present in the pattern
       * </pre>
       *
       * <code>optional string escape = 2;</code>
       * @param value The bytes for escape to set.
       * @return This builder for chaining.
       */
      public Builder setEscapeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        escape_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.LikeFilter)
    }

    // @@protoc_insertion_point(class_scope:exec.user.LikeFilter)
    private static final org.apache.drill.exec.proto.UserProtos.LikeFilter DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.LikeFilter();
    }

    public static org.apache.drill.exec.proto.UserProtos.LikeFilter getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<LikeFilter>
        PARSER = new com.google.protobuf.AbstractParser<LikeFilter>() {
      @java.lang.Override
      public LikeFilter parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<LikeFilter> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<LikeFilter> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetCatalogsReqOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetCatalogsReq)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    boolean hasCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder();
  }
  /**
   * <pre>
   * Request message for getting the metadata for catalogs satisfying the given optional filter.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetCatalogsReq}
   */
  public static final class GetCatalogsReq extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetCatalogsReq)
      GetCatalogsReqOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetCatalogsReq.newBuilder() to construct.
    private GetCatalogsReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetCatalogsReq() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetCatalogsReq();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsReq_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsReq_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetCatalogsReq.class, org.apache.drill.exec.proto.UserProtos.GetCatalogsReq.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FILTER_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasCatalogNameFilter() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getCatalogNameFilter());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getCatalogNameFilter());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetCatalogsReq)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetCatalogsReq other = (org.apache.drill.exec.proto.UserProtos.GetCatalogsReq) obj;

      if (hasCatalogNameFilter() != other.hasCatalogNameFilter()) return false;
      if (hasCatalogNameFilter()) {
        if (!getCatalogNameFilter()
            .equals(other.getCatalogNameFilter())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogNameFilter()) {
        hash = (37 * hash) + CATALOG_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogNameFilter().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq 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.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetCatalogsReq prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Request message for getting the metadata for catalogs satisfying the given optional filter.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetCatalogsReq}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetCatalogsReq)
        org.apache.drill.exec.proto.UserProtos.GetCatalogsReqOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsReq_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsReq_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetCatalogsReq.class, org.apache.drill.exec.proto.UserProtos.GetCatalogsReq.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetCatalogsReq.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getCatalogNameFilterFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsReq_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetCatalogsReq getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetCatalogsReq.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetCatalogsReq build() {
        org.apache.drill.exec.proto.UserProtos.GetCatalogsReq result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetCatalogsReq buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetCatalogsReq result = new org.apache.drill.exec.proto.UserProtos.GetCatalogsReq(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (catalogNameFilterBuilder_ == null) {
            result.catalogNameFilter_ = catalogNameFilter_;
          } else {
            result.catalogNameFilter_ = catalogNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetCatalogsReq) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetCatalogsReq)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetCatalogsReq other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetCatalogsReq.getDefaultInstance()) return this;
        if (other.hasCatalogNameFilter()) {
          mergeCatalogNameFilter(other.getCatalogNameFilter());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getCatalogNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> catalogNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return Whether the catalogNameFilter field is set.
       */
      public boolean hasCatalogNameFilter() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return The catalogNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        } else {
          return catalogNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          catalogNameFilter_ = value;
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder mergeCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              catalogNameFilter_ != null &&
              catalogNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            catalogNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(catalogNameFilter_).mergeFrom(value).buildPartial();
          } else {
            catalogNameFilter_ = value;
          }
          onChanged();
        } else {
          catalogNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder clearCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
          onChanged();
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getCatalogNameFilterBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getCatalogNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
        if (catalogNameFilterBuilder_ != null) {
          return catalogNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return catalogNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getCatalogNameFilterFieldBuilder() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getCatalogNameFilter(),
                  getParentForChildren(),
                  isClean());
          catalogNameFilter_ = null;
        }
        return catalogNameFilterBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetCatalogsReq)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetCatalogsReq)
    private static final org.apache.drill.exec.proto.UserProtos.GetCatalogsReq DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetCatalogsReq();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsReq getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetCatalogsReq>
        PARSER = new com.google.protobuf.AbstractParser<GetCatalogsReq>() {
      @java.lang.Override
      public GetCatalogsReq parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetCatalogsReq> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetCatalogsReq> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetCatalogsReq getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface CatalogMetadataOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.CatalogMetadata)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    boolean hasCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    java.lang.String getCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    com.google.protobuf.ByteString
        getCatalogNameBytes();

    /**
     * <code>optional string description = 2;</code>
     * @return Whether the description field is set.
     */
    boolean hasDescription();
    /**
     * <code>optional string description = 2;</code>
     * @return The description.
     */
    java.lang.String getDescription();
    /**
     * <code>optional string description = 2;</code>
     * @return The bytes for description.
     */
    com.google.protobuf.ByteString
        getDescriptionBytes();

    /**
     * <code>optional string connect = 3;</code>
     * @return Whether the connect field is set.
     */
    boolean hasConnect();
    /**
     * <code>optional string connect = 3;</code>
     * @return The connect.
     */
    java.lang.String getConnect();
    /**
     * <code>optional string connect = 3;</code>
     * @return The bytes for connect.
     */
    com.google.protobuf.ByteString
        getConnectBytes();
  }
  /**
   * <pre>
   * Message encapsulating metadata for a Catalog.
   * </pre>
   *
   * Protobuf type {@code exec.user.CatalogMetadata}
   */
  public static final class CatalogMetadata extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.CatalogMetadata)
      CatalogMetadataOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use CatalogMetadata.newBuilder() to construct.
    private CatalogMetadata(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private CatalogMetadata() {
      catalogName_ = "";
      description_ = "";
      connect_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new CatalogMetadata();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CatalogMetadata_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CatalogMetadata_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.CatalogMetadata.class, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object catalogName_;
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    @java.lang.Override
    public boolean hasCatalogName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    @java.lang.Override
    public java.lang.String getCatalogName() {
      java.lang.Object ref = catalogName_;
      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()) {
          catalogName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCatalogNameBytes() {
      java.lang.Object ref = catalogName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        catalogName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int DESCRIPTION_FIELD_NUMBER = 2;
    private volatile java.lang.Object description_;
    /**
     * <code>optional string description = 2;</code>
     * @return Whether the description field is set.
     */
    @java.lang.Override
    public boolean hasDescription() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string description = 2;</code>
     * @return The description.
     */
    @java.lang.Override
    public java.lang.String getDescription() {
      java.lang.Object ref = description_;
      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()) {
          description_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string description = 2;</code>
     * @return The bytes for description.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getDescriptionBytes() {
      java.lang.Object ref = description_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        description_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int CONNECT_FIELD_NUMBER = 3;
    private volatile java.lang.Object connect_;
    /**
     * <code>optional string connect = 3;</code>
     * @return Whether the connect field is set.
     */
    @java.lang.Override
    public boolean hasConnect() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional string connect = 3;</code>
     * @return The connect.
     */
    @java.lang.Override
    public java.lang.String getConnect() {
      java.lang.Object ref = connect_;
      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()) {
          connect_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string connect = 3;</code>
     * @return The bytes for connect.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getConnectBytes() {
      java.lang.Object ref = connect_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        connect_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, description_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, connect_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, description_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, connect_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.CatalogMetadata)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.CatalogMetadata other = (org.apache.drill.exec.proto.UserProtos.CatalogMetadata) obj;

      if (hasCatalogName() != other.hasCatalogName()) return false;
      if (hasCatalogName()) {
        if (!getCatalogName()
            .equals(other.getCatalogName())) return false;
      }
      if (hasDescription() != other.hasDescription()) return false;
      if (hasDescription()) {
        if (!getDescription()
            .equals(other.getDescription())) return false;
      }
      if (hasConnect() != other.hasConnect()) return false;
      if (hasConnect()) {
        if (!getConnect()
            .equals(other.getConnect())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogName()) {
        hash = (37 * hash) + CATALOG_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogName().hashCode();
      }
      if (hasDescription()) {
        hash = (37 * hash) + DESCRIPTION_FIELD_NUMBER;
        hash = (53 * hash) + getDescription().hashCode();
      }
      if (hasConnect()) {
        hash = (37 * hash) + CONNECT_FIELD_NUMBER;
        hash = (53 * hash) + getConnect().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata 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.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.CatalogMetadata prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Message encapsulating metadata for a Catalog.
     * </pre>
     *
     * Protobuf type {@code exec.user.CatalogMetadata}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.CatalogMetadata)
        org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CatalogMetadata_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CatalogMetadata_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.CatalogMetadata.class, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.CatalogMetadata.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        catalogName_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        description_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        connect_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CatalogMetadata_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadata getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.CatalogMetadata.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadata build() {
        org.apache.drill.exec.proto.UserProtos.CatalogMetadata result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadata buildPartial() {
        org.apache.drill.exec.proto.UserProtos.CatalogMetadata result = new org.apache.drill.exec.proto.UserProtos.CatalogMetadata(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.catalogName_ = catalogName_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.description_ = description_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.connect_ = connect_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.CatalogMetadata) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.CatalogMetadata)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.CatalogMetadata other) {
        if (other == org.apache.drill.exec.proto.UserProtos.CatalogMetadata.getDefaultInstance()) return this;
        if (other.hasCatalogName()) {
          bitField0_ |= 0x00000001;
          catalogName_ = other.catalogName_;
          onChanged();
        }
        if (other.hasDescription()) {
          bitField0_ |= 0x00000002;
          description_ = other.description_;
          onChanged();
        }
        if (other.hasConnect()) {
          bitField0_ |= 0x00000004;
          connect_ = other.connect_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                catalogName_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                description_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                connect_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object catalogName_ = "";
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return Whether the catalogName field is set.
       */
      public boolean hasCatalogName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The catalogName.
       */
      public java.lang.String getCatalogName() {
        java.lang.Object ref = catalogName_;
        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()) {
            catalogName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The bytes for catalogName.
       */
      public com.google.protobuf.ByteString
          getCatalogNameBytes() {
        java.lang.Object ref = catalogName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          catalogName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        catalogName_ = getDefaultInstance().getCatalogName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The bytes for catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object description_ = "";
      /**
       * <code>optional string description = 2;</code>
       * @return Whether the description field is set.
       */
      public boolean hasDescription() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional string description = 2;</code>
       * @return The description.
       */
      public java.lang.String getDescription() {
        java.lang.Object ref = description_;
        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()) {
            description_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string description = 2;</code>
       * @return The bytes for description.
       */
      public com.google.protobuf.ByteString
          getDescriptionBytes() {
        java.lang.Object ref = description_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          description_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string description = 2;</code>
       * @param value The description to set.
       * @return This builder for chaining.
       */
      public Builder setDescription(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        description_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string description = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearDescription() {
        bitField0_ = (bitField0_ & ~0x00000002);
        description_ = getDefaultInstance().getDescription();
        onChanged();
        return this;
      }
      /**
       * <code>optional string description = 2;</code>
       * @param value The bytes for description to set.
       * @return This builder for chaining.
       */
      public Builder setDescriptionBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        description_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object connect_ = "";
      /**
       * <code>optional string connect = 3;</code>
       * @return Whether the connect field is set.
       */
      public boolean hasConnect() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional string connect = 3;</code>
       * @return The connect.
       */
      public java.lang.String getConnect() {
        java.lang.Object ref = connect_;
        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()) {
            connect_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string connect = 3;</code>
       * @return The bytes for connect.
       */
      public com.google.protobuf.ByteString
          getConnectBytes() {
        java.lang.Object ref = connect_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          connect_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string connect = 3;</code>
       * @param value The connect to set.
       * @return This builder for chaining.
       */
      public Builder setConnect(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        connect_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string connect = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearConnect() {
        bitField0_ = (bitField0_ & ~0x00000004);
        connect_ = getDefaultInstance().getConnect();
        onChanged();
        return this;
      }
      /**
       * <code>optional string connect = 3;</code>
       * @param value The bytes for connect to set.
       * @return This builder for chaining.
       */
      public Builder setConnectBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        connect_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.CatalogMetadata)
    }

    // @@protoc_insertion_point(class_scope:exec.user.CatalogMetadata)
    private static final org.apache.drill.exec.proto.UserProtos.CatalogMetadata DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.CatalogMetadata();
    }

    public static org.apache.drill.exec.proto.UserProtos.CatalogMetadata getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<CatalogMetadata>
        PARSER = new com.google.protobuf.AbstractParser<CatalogMetadata>() {
      @java.lang.Override
      public CatalogMetadata parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<CatalogMetadata> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<CatalogMetadata> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.CatalogMetadata getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetCatalogsRespOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetCatalogsResp)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus();

    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.CatalogMetadata> 
        getCatalogsList();
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.CatalogMetadata getCatalogs(int index);
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    int getCatalogsCount();
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder> 
        getCatalogsOrBuilderList();
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder getCatalogsOrBuilder(
        int index);

    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();
  }
  /**
   * <pre>
   * Response message for GetCatalogReq.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetCatalogsResp}
   */
  public static final class GetCatalogsResp extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetCatalogsResp)
      GetCatalogsRespOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetCatalogsResp.newBuilder() to construct.
    private GetCatalogsResp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetCatalogsResp() {
      status_ = 0;
      catalogs_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetCatalogsResp();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsResp_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsResp_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetCatalogsResp.class, org.apache.drill.exec.proto.UserProtos.GetCatalogsResp.Builder.class);
    }

    private int bitField0_;
    public static final int STATUS_FIELD_NUMBER = 1;
    private int status_;
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
    }

    public static final int CATALOGS_FIELD_NUMBER = 2;
    private java.util.List<org.apache.drill.exec.proto.UserProtos.CatalogMetadata> catalogs_;
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.CatalogMetadata> getCatalogsList() {
      return catalogs_;
    }
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder> 
        getCatalogsOrBuilderList() {
      return catalogs_;
    }
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    @java.lang.Override
    public int getCatalogsCount() {
      return catalogs_.size();
    }
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.CatalogMetadata getCatalogs(int index) {
      return catalogs_.get(index);
    }
    /**
     * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder getCatalogsOrBuilder(
        int index) {
      return catalogs_.get(index);
    }

    public static final int ERROR_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, status_);
      }
      for (int i = 0; i < catalogs_.size(); i++) {
        output.writeMessage(2, catalogs_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(3, getError());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, status_);
      }
      for (int i = 0; i < catalogs_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, catalogs_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getError());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetCatalogsResp)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetCatalogsResp other = (org.apache.drill.exec.proto.UserProtos.GetCatalogsResp) obj;

      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (!getCatalogsList()
          .equals(other.getCatalogsList())) return false;
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (getCatalogsCount() > 0) {
        hash = (37 * hash) + CATALOGS_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogsList().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp 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.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetCatalogsResp prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Response message for GetCatalogReq.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetCatalogsResp}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetCatalogsResp)
        org.apache.drill.exec.proto.UserProtos.GetCatalogsRespOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsResp_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsResp_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetCatalogsResp.class, org.apache.drill.exec.proto.UserProtos.GetCatalogsResp.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetCatalogsResp.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getCatalogsFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (catalogsBuilder_ == null) {
          catalogs_ = java.util.Collections.emptyList();
        } else {
          catalogs_ = null;
          catalogsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetCatalogsResp_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetCatalogsResp getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetCatalogsResp.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetCatalogsResp build() {
        org.apache.drill.exec.proto.UserProtos.GetCatalogsResp result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetCatalogsResp buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetCatalogsResp result = new org.apache.drill.exec.proto.UserProtos.GetCatalogsResp(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.status_ = status_;
        if (catalogsBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            catalogs_ = java.util.Collections.unmodifiableList(catalogs_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.catalogs_ = catalogs_;
        } else {
          result.catalogs_ = catalogsBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetCatalogsResp) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetCatalogsResp)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetCatalogsResp other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetCatalogsResp.getDefaultInstance()) return this;
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (catalogsBuilder_ == null) {
          if (!other.catalogs_.isEmpty()) {
            if (catalogs_.isEmpty()) {
              catalogs_ = other.catalogs_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureCatalogsIsMutable();
              catalogs_.addAll(other.catalogs_);
            }
            onChanged();
          }
        } else {
          if (!other.catalogs_.isEmpty()) {
            if (catalogsBuilder_.isEmpty()) {
              catalogsBuilder_.dispose();
              catalogsBuilder_ = null;
              catalogs_ = other.catalogs_;
              bitField0_ = (bitField0_ & ~0x00000002);
              catalogsBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getCatalogsFieldBuilder() : null;
            } else {
              catalogsBuilder_.addAllMessages(other.catalogs_);
            }
          }
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.RequestStatus tmpValue =
                    org.apache.drill.exec.proto.UserProtos.RequestStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                org.apache.drill.exec.proto.UserProtos.CatalogMetadata m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserProtos.CatalogMetadata.PARSER,
                        extensionRegistry);
                if (catalogsBuilder_ == null) {
                  ensureCatalogsIsMutable();
                  catalogs_.add(m);
                } else {
                  catalogsBuilder_.addMessage(m);
                }
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int status_ = 0;
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserProtos.RequestStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserProtos.CatalogMetadata> catalogs_ =
        java.util.Collections.emptyList();
      private void ensureCatalogsIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          catalogs_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserProtos.CatalogMetadata>(catalogs_);
          bitField0_ |= 0x00000002;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.CatalogMetadata, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder, org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder> catalogsBuilder_;

      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.CatalogMetadata> getCatalogsList() {
        if (catalogsBuilder_ == null) {
          return java.util.Collections.unmodifiableList(catalogs_);
        } else {
          return catalogsBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public int getCatalogsCount() {
        if (catalogsBuilder_ == null) {
          return catalogs_.size();
        } else {
          return catalogsBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadata getCatalogs(int index) {
        if (catalogsBuilder_ == null) {
          return catalogs_.get(index);
        } else {
          return catalogsBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder setCatalogs(
          int index, org.apache.drill.exec.proto.UserProtos.CatalogMetadata value) {
        if (catalogsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureCatalogsIsMutable();
          catalogs_.set(index, value);
          onChanged();
        } else {
          catalogsBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder setCatalogs(
          int index, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder builderForValue) {
        if (catalogsBuilder_ == null) {
          ensureCatalogsIsMutable();
          catalogs_.set(index, builderForValue.build());
          onChanged();
        } else {
          catalogsBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder addCatalogs(org.apache.drill.exec.proto.UserProtos.CatalogMetadata value) {
        if (catalogsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureCatalogsIsMutable();
          catalogs_.add(value);
          onChanged();
        } else {
          catalogsBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder addCatalogs(
          int index, org.apache.drill.exec.proto.UserProtos.CatalogMetadata value) {
        if (catalogsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureCatalogsIsMutable();
          catalogs_.add(index, value);
          onChanged();
        } else {
          catalogsBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder addCatalogs(
          org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder builderForValue) {
        if (catalogsBuilder_ == null) {
          ensureCatalogsIsMutable();
          catalogs_.add(builderForValue.build());
          onChanged();
        } else {
          catalogsBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder addCatalogs(
          int index, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder builderForValue) {
        if (catalogsBuilder_ == null) {
          ensureCatalogsIsMutable();
          catalogs_.add(index, builderForValue.build());
          onChanged();
        } else {
          catalogsBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder addAllCatalogs(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.CatalogMetadata> values) {
        if (catalogsBuilder_ == null) {
          ensureCatalogsIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, catalogs_);
          onChanged();
        } else {
          catalogsBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder clearCatalogs() {
        if (catalogsBuilder_ == null) {
          catalogs_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          catalogsBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public Builder removeCatalogs(int index) {
        if (catalogsBuilder_ == null) {
          ensureCatalogsIsMutable();
          catalogs_.remove(index);
          onChanged();
        } else {
          catalogsBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder getCatalogsBuilder(
          int index) {
        return getCatalogsFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder getCatalogsOrBuilder(
          int index) {
        if (catalogsBuilder_ == null) {
          return catalogs_.get(index);  } else {
          return catalogsBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder> 
           getCatalogsOrBuilderList() {
        if (catalogsBuilder_ != null) {
          return catalogsBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(catalogs_);
        }
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder addCatalogsBuilder() {
        return getCatalogsFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserProtos.CatalogMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder addCatalogsBuilder(
          int index) {
        return getCatalogsFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.CatalogMetadata catalogs = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder> 
           getCatalogsBuilderList() {
        return getCatalogsFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.CatalogMetadata, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder, org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder> 
          getCatalogsFieldBuilder() {
        if (catalogsBuilder_ == null) {
          catalogsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.CatalogMetadata, org.apache.drill.exec.proto.UserProtos.CatalogMetadata.Builder, org.apache.drill.exec.proto.UserProtos.CatalogMetadataOrBuilder>(
                  catalogs_,
                  ((bitField0_ & 0x00000002) != 0),
                  getParentForChildren(),
                  isClean());
          catalogs_ = null;
        }
        return catalogsBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetCatalogsResp)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetCatalogsResp)
    private static final org.apache.drill.exec.proto.UserProtos.GetCatalogsResp DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetCatalogsResp();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetCatalogsResp getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetCatalogsResp>
        PARSER = new com.google.protobuf.AbstractParser<GetCatalogsResp>() {
      @java.lang.Override
      public GetCatalogsResp parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetCatalogsResp> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetCatalogsResp> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetCatalogsResp getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetSchemasReqOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetSchemasReq)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    boolean hasCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder();

    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return Whether the schemaNameFilter field is set.
     */
    boolean hasSchemaNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return The schemaNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder();
  }
  /**
   * <pre>
   * Request message for getting the metadata for schemas satisfying the given optional filters.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetSchemasReq}
   */
  public static final class GetSchemasReq extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetSchemasReq)
      GetSchemasReqOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetSchemasReq.newBuilder() to construct.
    private GetSchemasReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetSchemasReq() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetSchemasReq();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasReq_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasReq_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetSchemasReq.class, org.apache.drill.exec.proto.UserProtos.GetSchemasReq.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FILTER_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasCatalogNameFilter() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }

    public static final int SCHEMA_NAME_FILTER_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter schemaNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return Whether the schemaNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasSchemaNameFilter() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return The schemaNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter() {
      return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder() {
      return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getCatalogNameFilter());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getSchemaNameFilter());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getCatalogNameFilter());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getSchemaNameFilter());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetSchemasReq)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetSchemasReq other = (org.apache.drill.exec.proto.UserProtos.GetSchemasReq) obj;

      if (hasCatalogNameFilter() != other.hasCatalogNameFilter()) return false;
      if (hasCatalogNameFilter()) {
        if (!getCatalogNameFilter()
            .equals(other.getCatalogNameFilter())) return false;
      }
      if (hasSchemaNameFilter() != other.hasSchemaNameFilter()) return false;
      if (hasSchemaNameFilter()) {
        if (!getSchemaNameFilter()
            .equals(other.getSchemaNameFilter())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogNameFilter()) {
        hash = (37 * hash) + CATALOG_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogNameFilter().hashCode();
      }
      if (hasSchemaNameFilter()) {
        hash = (37 * hash) + SCHEMA_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaNameFilter().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq 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.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetSchemasReq prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Request message for getting the metadata for schemas satisfying the given optional filters.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetSchemasReq}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetSchemasReq)
        org.apache.drill.exec.proto.UserProtos.GetSchemasReqOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasReq_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasReq_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetSchemasReq.class, org.apache.drill.exec.proto.UserProtos.GetSchemasReq.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetSchemasReq.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getCatalogNameFilterFieldBuilder();
          getSchemaNameFilterFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = null;
        } else {
          schemaNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasReq_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetSchemasReq getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetSchemasReq.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetSchemasReq build() {
        org.apache.drill.exec.proto.UserProtos.GetSchemasReq result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetSchemasReq buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetSchemasReq result = new org.apache.drill.exec.proto.UserProtos.GetSchemasReq(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (catalogNameFilterBuilder_ == null) {
            result.catalogNameFilter_ = catalogNameFilter_;
          } else {
            result.catalogNameFilter_ = catalogNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (schemaNameFilterBuilder_ == null) {
            result.schemaNameFilter_ = schemaNameFilter_;
          } else {
            result.schemaNameFilter_ = schemaNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetSchemasReq) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetSchemasReq)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetSchemasReq other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetSchemasReq.getDefaultInstance()) return this;
        if (other.hasCatalogNameFilter()) {
          mergeCatalogNameFilter(other.getCatalogNameFilter());
        }
        if (other.hasSchemaNameFilter()) {
          mergeSchemaNameFilter(other.getSchemaNameFilter());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getCatalogNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getSchemaNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> catalogNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return Whether the catalogNameFilter field is set.
       */
      public boolean hasCatalogNameFilter() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return The catalogNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        } else {
          return catalogNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          catalogNameFilter_ = value;
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder mergeCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              catalogNameFilter_ != null &&
              catalogNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            catalogNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(catalogNameFilter_).mergeFrom(value).buildPartial();
          } else {
            catalogNameFilter_ = value;
          }
          onChanged();
        } else {
          catalogNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder clearCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
          onChanged();
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getCatalogNameFilterBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getCatalogNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
        if (catalogNameFilterBuilder_ != null) {
          return catalogNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return catalogNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getCatalogNameFilterFieldBuilder() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getCatalogNameFilter(),
                  getParentForChildren(),
                  isClean());
          catalogNameFilter_ = null;
        }
        return catalogNameFilterBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.LikeFilter schemaNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> schemaNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       * @return Whether the schemaNameFilter field is set.
       */
      public boolean hasSchemaNameFilter() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       * @return The schemaNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter() {
        if (schemaNameFilterBuilder_ == null) {
          return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
        } else {
          return schemaNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder setSchemaNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (schemaNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          schemaNameFilter_ = value;
          onChanged();
        } else {
          schemaNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder setSchemaNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          schemaNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder mergeSchemaNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (schemaNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              schemaNameFilter_ != null &&
              schemaNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            schemaNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(schemaNameFilter_).mergeFrom(value).buildPartial();
          } else {
            schemaNameFilter_ = value;
          }
          onChanged();
        } else {
          schemaNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder clearSchemaNameFilter() {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = null;
          onChanged();
        } else {
          schemaNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getSchemaNameFilterBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getSchemaNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder() {
        if (schemaNameFilterBuilder_ != null) {
          return schemaNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return schemaNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getSchemaNameFilterFieldBuilder() {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getSchemaNameFilter(),
                  getParentForChildren(),
                  isClean());
          schemaNameFilter_ = null;
        }
        return schemaNameFilterBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetSchemasReq)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetSchemasReq)
    private static final org.apache.drill.exec.proto.UserProtos.GetSchemasReq DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetSchemasReq();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetSchemasReq getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetSchemasReq>
        PARSER = new com.google.protobuf.AbstractParser<GetSchemasReq>() {
      @java.lang.Override
      public GetSchemasReq parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetSchemasReq> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetSchemasReq> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetSchemasReq getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface SchemaMetadataOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.SchemaMetadata)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    boolean hasCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    java.lang.String getCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    com.google.protobuf.ByteString
        getCatalogNameBytes();

    /**
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    boolean hasSchemaName();
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    java.lang.String getSchemaName();
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    com.google.protobuf.ByteString
        getSchemaNameBytes();

    /**
     * <code>optional string owner = 3;</code>
     * @return Whether the owner field is set.
     */
    boolean hasOwner();
    /**
     * <code>optional string owner = 3;</code>
     * @return The owner.
     */
    java.lang.String getOwner();
    /**
     * <code>optional string owner = 3;</code>
     * @return The bytes for owner.
     */
    com.google.protobuf.ByteString
        getOwnerBytes();

    /**
     * <pre>
     * Type. Ex. "file", "mongodb", "hive" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <pre>
     * Type. Ex. "file", "mongodb", "hive" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The type.
     */
    java.lang.String getType();
    /**
     * <pre>
     * Type. Ex. "file", "mongodb", "hive" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The bytes for type.
     */
    com.google.protobuf.ByteString
        getTypeBytes();

    /**
     * <code>optional string mutable = 5;</code>
     * @return Whether the mutable field is set.
     */
    boolean hasMutable();
    /**
     * <code>optional string mutable = 5;</code>
     * @return The mutable.
     */
    java.lang.String getMutable();
    /**
     * <code>optional string mutable = 5;</code>
     * @return The bytes for mutable.
     */
    com.google.protobuf.ByteString
        getMutableBytes();
  }
  /**
   * <pre>
   * Message encapsulating metadata for a Schema.
   * </pre>
   *
   * Protobuf type {@code exec.user.SchemaMetadata}
   */
  public static final class SchemaMetadata extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.SchemaMetadata)
      SchemaMetadataOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use SchemaMetadata.newBuilder() to construct.
    private SchemaMetadata(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private SchemaMetadata() {
      catalogName_ = "";
      schemaName_ = "";
      owner_ = "";
      type_ = "";
      mutable_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new SchemaMetadata();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_SchemaMetadata_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_SchemaMetadata_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.SchemaMetadata.class, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object catalogName_;
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    @java.lang.Override
    public boolean hasCatalogName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    @java.lang.Override
    public java.lang.String getCatalogName() {
      java.lang.Object ref = catalogName_;
      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()) {
          catalogName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCatalogNameBytes() {
      java.lang.Object ref = catalogName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        catalogName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SCHEMA_NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object schemaName_;
    /**
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    @java.lang.Override
    public boolean hasSchemaName() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    @java.lang.Override
    public java.lang.String getSchemaName() {
      java.lang.Object ref = schemaName_;
      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()) {
          schemaName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSchemaNameBytes() {
      java.lang.Object ref = schemaName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        schemaName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int OWNER_FIELD_NUMBER = 3;
    private volatile java.lang.Object owner_;
    /**
     * <code>optional string owner = 3;</code>
     * @return Whether the owner field is set.
     */
    @java.lang.Override
    public boolean hasOwner() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional string owner = 3;</code>
     * @return The owner.
     */
    @java.lang.Override
    public java.lang.String getOwner() {
      java.lang.Object ref = owner_;
      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()) {
          owner_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string owner = 3;</code>
     * @return The bytes for owner.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getOwnerBytes() {
      java.lang.Object ref = owner_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        owner_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TYPE_FIELD_NUMBER = 4;
    private volatile java.lang.Object type_;
    /**
     * <pre>
     * Type. Ex. "file", "mongodb", "hive" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return Whether the type field is set.
     */
    @java.lang.Override
    public boolean hasType() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * Type. Ex. "file", "mongodb", "hive" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The type.
     */
    @java.lang.Override
    public java.lang.String getType() {
      java.lang.Object ref = type_;
      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()) {
          type_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Type. Ex. "file", "mongodb", "hive" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The bytes for type.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getTypeBytes() {
      java.lang.Object ref = type_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        type_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int MUTABLE_FIELD_NUMBER = 5;
    private volatile java.lang.Object mutable_;
    /**
     * <code>optional string mutable = 5;</code>
     * @return Whether the mutable field is set.
     */
    @java.lang.Override
    public boolean hasMutable() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional string mutable = 5;</code>
     * @return The mutable.
     */
    @java.lang.Override
    public java.lang.String getMutable() {
      java.lang.Object ref = mutable_;
      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()) {
          mutable_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string mutable = 5;</code>
     * @return The bytes for mutable.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getMutableBytes() {
      java.lang.Object ref = mutable_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        mutable_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, owner_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, type_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, mutable_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, owner_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, type_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, mutable_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.SchemaMetadata)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.SchemaMetadata other = (org.apache.drill.exec.proto.UserProtos.SchemaMetadata) obj;

      if (hasCatalogName() != other.hasCatalogName()) return false;
      if (hasCatalogName()) {
        if (!getCatalogName()
            .equals(other.getCatalogName())) return false;
      }
      if (hasSchemaName() != other.hasSchemaName()) return false;
      if (hasSchemaName()) {
        if (!getSchemaName()
            .equals(other.getSchemaName())) return false;
      }
      if (hasOwner() != other.hasOwner()) return false;
      if (hasOwner()) {
        if (!getOwner()
            .equals(other.getOwner())) return false;
      }
      if (hasType() != other.hasType()) return false;
      if (hasType()) {
        if (!getType()
            .equals(other.getType())) return false;
      }
      if (hasMutable() != other.hasMutable()) return false;
      if (hasMutable()) {
        if (!getMutable()
            .equals(other.getMutable())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogName()) {
        hash = (37 * hash) + CATALOG_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogName().hashCode();
      }
      if (hasSchemaName()) {
        hash = (37 * hash) + SCHEMA_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaName().hashCode();
      }
      if (hasOwner()) {
        hash = (37 * hash) + OWNER_FIELD_NUMBER;
        hash = (53 * hash) + getOwner().hashCode();
      }
      if (hasType()) {
        hash = (37 * hash) + TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getType().hashCode();
      }
      if (hasMutable()) {
        hash = (37 * hash) + MUTABLE_FIELD_NUMBER;
        hash = (53 * hash) + getMutable().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata 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.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.SchemaMetadata prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Message encapsulating metadata for a Schema.
     * </pre>
     *
     * Protobuf type {@code exec.user.SchemaMetadata}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.SchemaMetadata)
        org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_SchemaMetadata_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_SchemaMetadata_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.SchemaMetadata.class, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.SchemaMetadata.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        catalogName_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        schemaName_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        owner_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        type_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        mutable_ = "";
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_SchemaMetadata_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadata getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.SchemaMetadata.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadata build() {
        org.apache.drill.exec.proto.UserProtos.SchemaMetadata result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadata buildPartial() {
        org.apache.drill.exec.proto.UserProtos.SchemaMetadata result = new org.apache.drill.exec.proto.UserProtos.SchemaMetadata(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.catalogName_ = catalogName_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.schemaName_ = schemaName_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.owner_ = owner_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          to_bitField0_ |= 0x00000010;
        }
        result.mutable_ = mutable_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.SchemaMetadata) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.SchemaMetadata)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.SchemaMetadata other) {
        if (other == org.apache.drill.exec.proto.UserProtos.SchemaMetadata.getDefaultInstance()) return this;
        if (other.hasCatalogName()) {
          bitField0_ |= 0x00000001;
          catalogName_ = other.catalogName_;
          onChanged();
        }
        if (other.hasSchemaName()) {
          bitField0_ |= 0x00000002;
          schemaName_ = other.schemaName_;
          onChanged();
        }
        if (other.hasOwner()) {
          bitField0_ |= 0x00000004;
          owner_ = other.owner_;
          onChanged();
        }
        if (other.hasType()) {
          bitField0_ |= 0x00000008;
          type_ = other.type_;
          onChanged();
        }
        if (other.hasMutable()) {
          bitField0_ |= 0x00000010;
          mutable_ = other.mutable_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                catalogName_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                schemaName_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                owner_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                type_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 42: {
                mutable_ = input.readBytes();
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object catalogName_ = "";
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return Whether the catalogName field is set.
       */
      public boolean hasCatalogName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The catalogName.
       */
      public java.lang.String getCatalogName() {
        java.lang.Object ref = catalogName_;
        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()) {
            catalogName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The bytes for catalogName.
       */
      public com.google.protobuf.ByteString
          getCatalogNameBytes() {
        java.lang.Object ref = catalogName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          catalogName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        catalogName_ = getDefaultInstance().getCatalogName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The bytes for catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object schemaName_ = "";
      /**
       * <code>optional string schema_name = 2;</code>
       * @return Whether the schemaName field is set.
       */
      public boolean hasSchemaName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return The schemaName.
       */
      public java.lang.String getSchemaName() {
        java.lang.Object ref = schemaName_;
        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()) {
            schemaName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return The bytes for schemaName.
       */
      public com.google.protobuf.ByteString
          getSchemaNameBytes() {
        java.lang.Object ref = schemaName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          schemaName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @param value The schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearSchemaName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        schemaName_ = getDefaultInstance().getSchemaName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @param value The bytes for schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object owner_ = "";
      /**
       * <code>optional string owner = 3;</code>
       * @return Whether the owner field is set.
       */
      public boolean hasOwner() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional string owner = 3;</code>
       * @return The owner.
       */
      public java.lang.String getOwner() {
        java.lang.Object ref = owner_;
        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()) {
            owner_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string owner = 3;</code>
       * @return The bytes for owner.
       */
      public com.google.protobuf.ByteString
          getOwnerBytes() {
        java.lang.Object ref = owner_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          owner_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string owner = 3;</code>
       * @param value The owner to set.
       * @return This builder for chaining.
       */
      public Builder setOwner(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        owner_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string owner = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearOwner() {
        bitField0_ = (bitField0_ & ~0x00000004);
        owner_ = getDefaultInstance().getOwner();
        onChanged();
        return this;
      }
      /**
       * <code>optional string owner = 3;</code>
       * @param value The bytes for owner to set.
       * @return This builder for chaining.
       */
      public Builder setOwnerBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        owner_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object type_ = "";
      /**
       * <pre>
       * Type. Ex. "file", "mongodb", "hive" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return Whether the type field is set.
       */
      public boolean hasType() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * Type. Ex. "file", "mongodb", "hive" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return The type.
       */
      public java.lang.String getType() {
        java.lang.Object ref = type_;
        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()) {
            type_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Type. Ex. "file", "mongodb", "hive" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return The bytes for type.
       */
      public com.google.protobuf.ByteString
          getTypeBytes() {
        java.lang.Object ref = type_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          type_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Type. Ex. "file", "mongodb", "hive" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        type_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Type. Ex. "file", "mongodb", "hive" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000008);
        type_ = getDefaultInstance().getType();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Type. Ex. "file", "mongodb", "hive" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @param value The bytes for type to set.
       * @return This builder for chaining.
       */
      public Builder setTypeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        type_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object mutable_ = "";
      /**
       * <code>optional string mutable = 5;</code>
       * @return Whether the mutable field is set.
       */
      public boolean hasMutable() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional string mutable = 5;</code>
       * @return The mutable.
       */
      public java.lang.String getMutable() {
        java.lang.Object ref = mutable_;
        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()) {
            mutable_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string mutable = 5;</code>
       * @return The bytes for mutable.
       */
      public com.google.protobuf.ByteString
          getMutableBytes() {
        java.lang.Object ref = mutable_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          mutable_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string mutable = 5;</code>
       * @param value The mutable to set.
       * @return This builder for chaining.
       */
      public Builder setMutable(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        mutable_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string mutable = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearMutable() {
        bitField0_ = (bitField0_ & ~0x00000010);
        mutable_ = getDefaultInstance().getMutable();
        onChanged();
        return this;
      }
      /**
       * <code>optional string mutable = 5;</code>
       * @param value The bytes for mutable to set.
       * @return This builder for chaining.
       */
      public Builder setMutableBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        mutable_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.SchemaMetadata)
    }

    // @@protoc_insertion_point(class_scope:exec.user.SchemaMetadata)
    private static final org.apache.drill.exec.proto.UserProtos.SchemaMetadata DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.SchemaMetadata();
    }

    public static org.apache.drill.exec.proto.UserProtos.SchemaMetadata getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<SchemaMetadata>
        PARSER = new com.google.protobuf.AbstractParser<SchemaMetadata>() {
      @java.lang.Override
      public SchemaMetadata parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<SchemaMetadata> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<SchemaMetadata> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.SchemaMetadata getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetSchemasRespOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetSchemasResp)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus();

    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.SchemaMetadata> 
        getSchemasList();
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.SchemaMetadata getSchemas(int index);
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    int getSchemasCount();
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder> 
        getSchemasOrBuilderList();
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder getSchemasOrBuilder(
        int index);

    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();
  }
  /**
   * <pre>
   * Response message for GetSchemasReq.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetSchemasResp}
   */
  public static final class GetSchemasResp extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetSchemasResp)
      GetSchemasRespOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetSchemasResp.newBuilder() to construct.
    private GetSchemasResp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetSchemasResp() {
      status_ = 0;
      schemas_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetSchemasResp();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasResp_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasResp_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetSchemasResp.class, org.apache.drill.exec.proto.UserProtos.GetSchemasResp.Builder.class);
    }

    private int bitField0_;
    public static final int STATUS_FIELD_NUMBER = 1;
    private int status_;
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
    }

    public static final int SCHEMAS_FIELD_NUMBER = 2;
    private java.util.List<org.apache.drill.exec.proto.UserProtos.SchemaMetadata> schemas_;
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.SchemaMetadata> getSchemasList() {
      return schemas_;
    }
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder> 
        getSchemasOrBuilderList() {
      return schemas_;
    }
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    @java.lang.Override
    public int getSchemasCount() {
      return schemas_.size();
    }
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.SchemaMetadata getSchemas(int index) {
      return schemas_.get(index);
    }
    /**
     * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder getSchemasOrBuilder(
        int index) {
      return schemas_.get(index);
    }

    public static final int ERROR_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, status_);
      }
      for (int i = 0; i < schemas_.size(); i++) {
        output.writeMessage(2, schemas_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(3, getError());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, status_);
      }
      for (int i = 0; i < schemas_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, schemas_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getError());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetSchemasResp)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetSchemasResp other = (org.apache.drill.exec.proto.UserProtos.GetSchemasResp) obj;

      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (!getSchemasList()
          .equals(other.getSchemasList())) return false;
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (getSchemasCount() > 0) {
        hash = (37 * hash) + SCHEMAS_FIELD_NUMBER;
        hash = (53 * hash) + getSchemasList().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp 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.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetSchemasResp prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Response message for GetSchemasReq.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetSchemasResp}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetSchemasResp)
        org.apache.drill.exec.proto.UserProtos.GetSchemasRespOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasResp_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasResp_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetSchemasResp.class, org.apache.drill.exec.proto.UserProtos.GetSchemasResp.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetSchemasResp.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getSchemasFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (schemasBuilder_ == null) {
          schemas_ = java.util.Collections.emptyList();
        } else {
          schemas_ = null;
          schemasBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetSchemasResp_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetSchemasResp getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetSchemasResp.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetSchemasResp build() {
        org.apache.drill.exec.proto.UserProtos.GetSchemasResp result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetSchemasResp buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetSchemasResp result = new org.apache.drill.exec.proto.UserProtos.GetSchemasResp(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.status_ = status_;
        if (schemasBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            schemas_ = java.util.Collections.unmodifiableList(schemas_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.schemas_ = schemas_;
        } else {
          result.schemas_ = schemasBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetSchemasResp) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetSchemasResp)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetSchemasResp other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetSchemasResp.getDefaultInstance()) return this;
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (schemasBuilder_ == null) {
          if (!other.schemas_.isEmpty()) {
            if (schemas_.isEmpty()) {
              schemas_ = other.schemas_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureSchemasIsMutable();
              schemas_.addAll(other.schemas_);
            }
            onChanged();
          }
        } else {
          if (!other.schemas_.isEmpty()) {
            if (schemasBuilder_.isEmpty()) {
              schemasBuilder_.dispose();
              schemasBuilder_ = null;
              schemas_ = other.schemas_;
              bitField0_ = (bitField0_ & ~0x00000002);
              schemasBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getSchemasFieldBuilder() : null;
            } else {
              schemasBuilder_.addAllMessages(other.schemas_);
            }
          }
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.RequestStatus tmpValue =
                    org.apache.drill.exec.proto.UserProtos.RequestStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                org.apache.drill.exec.proto.UserProtos.SchemaMetadata m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserProtos.SchemaMetadata.PARSER,
                        extensionRegistry);
                if (schemasBuilder_ == null) {
                  ensureSchemasIsMutable();
                  schemas_.add(m);
                } else {
                  schemasBuilder_.addMessage(m);
                }
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int status_ = 0;
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserProtos.RequestStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserProtos.SchemaMetadata> schemas_ =
        java.util.Collections.emptyList();
      private void ensureSchemasIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          schemas_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserProtos.SchemaMetadata>(schemas_);
          bitField0_ |= 0x00000002;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.SchemaMetadata, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder, org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder> schemasBuilder_;

      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.SchemaMetadata> getSchemasList() {
        if (schemasBuilder_ == null) {
          return java.util.Collections.unmodifiableList(schemas_);
        } else {
          return schemasBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public int getSchemasCount() {
        if (schemasBuilder_ == null) {
          return schemas_.size();
        } else {
          return schemasBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadata getSchemas(int index) {
        if (schemasBuilder_ == null) {
          return schemas_.get(index);
        } else {
          return schemasBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder setSchemas(
          int index, org.apache.drill.exec.proto.UserProtos.SchemaMetadata value) {
        if (schemasBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureSchemasIsMutable();
          schemas_.set(index, value);
          onChanged();
        } else {
          schemasBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder setSchemas(
          int index, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder builderForValue) {
        if (schemasBuilder_ == null) {
          ensureSchemasIsMutable();
          schemas_.set(index, builderForValue.build());
          onChanged();
        } else {
          schemasBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder addSchemas(org.apache.drill.exec.proto.UserProtos.SchemaMetadata value) {
        if (schemasBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureSchemasIsMutable();
          schemas_.add(value);
          onChanged();
        } else {
          schemasBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder addSchemas(
          int index, org.apache.drill.exec.proto.UserProtos.SchemaMetadata value) {
        if (schemasBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureSchemasIsMutable();
          schemas_.add(index, value);
          onChanged();
        } else {
          schemasBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder addSchemas(
          org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder builderForValue) {
        if (schemasBuilder_ == null) {
          ensureSchemasIsMutable();
          schemas_.add(builderForValue.build());
          onChanged();
        } else {
          schemasBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder addSchemas(
          int index, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder builderForValue) {
        if (schemasBuilder_ == null) {
          ensureSchemasIsMutable();
          schemas_.add(index, builderForValue.build());
          onChanged();
        } else {
          schemasBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder addAllSchemas(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.SchemaMetadata> values) {
        if (schemasBuilder_ == null) {
          ensureSchemasIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, schemas_);
          onChanged();
        } else {
          schemasBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder clearSchemas() {
        if (schemasBuilder_ == null) {
          schemas_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          schemasBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public Builder removeSchemas(int index) {
        if (schemasBuilder_ == null) {
          ensureSchemasIsMutable();
          schemas_.remove(index);
          onChanged();
        } else {
          schemasBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder getSchemasBuilder(
          int index) {
        return getSchemasFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder getSchemasOrBuilder(
          int index) {
        if (schemasBuilder_ == null) {
          return schemas_.get(index);  } else {
          return schemasBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder> 
           getSchemasOrBuilderList() {
        if (schemasBuilder_ != null) {
          return schemasBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(schemas_);
        }
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder addSchemasBuilder() {
        return getSchemasFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserProtos.SchemaMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder addSchemasBuilder(
          int index) {
        return getSchemasFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.SchemaMetadata schemas = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder> 
           getSchemasBuilderList() {
        return getSchemasFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.SchemaMetadata, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder, org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder> 
          getSchemasFieldBuilder() {
        if (schemasBuilder_ == null) {
          schemasBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.SchemaMetadata, org.apache.drill.exec.proto.UserProtos.SchemaMetadata.Builder, org.apache.drill.exec.proto.UserProtos.SchemaMetadataOrBuilder>(
                  schemas_,
                  ((bitField0_ & 0x00000002) != 0),
                  getParentForChildren(),
                  isClean());
          schemas_ = null;
        }
        return schemasBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetSchemasResp)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetSchemasResp)
    private static final org.apache.drill.exec.proto.UserProtos.GetSchemasResp DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetSchemasResp();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetSchemasResp getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetSchemasResp>
        PARSER = new com.google.protobuf.AbstractParser<GetSchemasResp>() {
      @java.lang.Override
      public GetSchemasResp parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetSchemasResp> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetSchemasResp> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetSchemasResp getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetTablesReqOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetTablesReq)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    boolean hasCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder();

    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return Whether the schemaNameFilter field is set.
     */
    boolean hasSchemaNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return The schemaNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder();

    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return Whether the tableNameFilter field is set.
     */
    boolean hasTableNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return The tableNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getTableNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getTableNameFilterOrBuilder();

    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @return A list containing the tableTypeFilter.
     */
    java.util.List<java.lang.String>
        getTableTypeFilterList();
    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @return The count of tableTypeFilter.
     */
    int getTableTypeFilterCount();
    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @param index The index of the element to return.
     * @return The tableTypeFilter at the given index.
     */
    java.lang.String getTableTypeFilter(int index);
    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @param index The index of the value to return.
     * @return The bytes of the tableTypeFilter at the given index.
     */
    com.google.protobuf.ByteString
        getTableTypeFilterBytes(int index);
  }
  /**
   * <pre>
   * Request message for getting the metadata for tables satisfying the given optional filters.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetTablesReq}
   */
  public static final class GetTablesReq extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetTablesReq)
      GetTablesReqOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetTablesReq.newBuilder() to construct.
    private GetTablesReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetTablesReq() {
      tableTypeFilter_ = com.google.protobuf.LazyStringArrayList.EMPTY;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetTablesReq();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesReq_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesReq_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetTablesReq.class, org.apache.drill.exec.proto.UserProtos.GetTablesReq.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FILTER_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasCatalogNameFilter() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }

    public static final int SCHEMA_NAME_FILTER_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter schemaNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return Whether the schemaNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasSchemaNameFilter() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return The schemaNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter() {
      return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder() {
      return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
    }

    public static final int TABLE_NAME_FILTER_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter tableNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return Whether the tableNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasTableNameFilter() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return The tableNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getTableNameFilter() {
      return tableNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getTableNameFilterOrBuilder() {
      return tableNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
    }

    public static final int TABLE_TYPE_FILTER_FIELD_NUMBER = 4;
    private com.google.protobuf.LazyStringList tableTypeFilter_;
    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @return A list containing the tableTypeFilter.
     */
    public com.google.protobuf.ProtocolStringList
        getTableTypeFilterList() {
      return tableTypeFilter_;
    }
    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @return The count of tableTypeFilter.
     */
    public int getTableTypeFilterCount() {
      return tableTypeFilter_.size();
    }
    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @param index The index of the element to return.
     * @return The tableTypeFilter at the given index.
     */
    public java.lang.String getTableTypeFilter(int index) {
      return tableTypeFilter_.get(index);
    }
    /**
     * <code>repeated string table_type_filter = 4;</code>
     * @param index The index of the value to return.
     * @return The bytes of the tableTypeFilter at the given index.
     */
    public com.google.protobuf.ByteString
        getTableTypeFilterBytes(int index) {
      return tableTypeFilter_.getByteString(index);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getCatalogNameFilter());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getSchemaNameFilter());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getTableNameFilter());
      }
      for (int i = 0; i < tableTypeFilter_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, tableTypeFilter_.getRaw(i));
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getCatalogNameFilter());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getSchemaNameFilter());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getTableNameFilter());
      }
      {
        int dataSize = 0;
        for (int i = 0; i < tableTypeFilter_.size(); i++) {
          dataSize += computeStringSizeNoTag(tableTypeFilter_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getTableTypeFilterList().size();
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetTablesReq)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetTablesReq other = (org.apache.drill.exec.proto.UserProtos.GetTablesReq) obj;

      if (hasCatalogNameFilter() != other.hasCatalogNameFilter()) return false;
      if (hasCatalogNameFilter()) {
        if (!getCatalogNameFilter()
            .equals(other.getCatalogNameFilter())) return false;
      }
      if (hasSchemaNameFilter() != other.hasSchemaNameFilter()) return false;
      if (hasSchemaNameFilter()) {
        if (!getSchemaNameFilter()
            .equals(other.getSchemaNameFilter())) return false;
      }
      if (hasTableNameFilter() != other.hasTableNameFilter()) return false;
      if (hasTableNameFilter()) {
        if (!getTableNameFilter()
            .equals(other.getTableNameFilter())) return false;
      }
      if (!getTableTypeFilterList()
          .equals(other.getTableTypeFilterList())) return false;
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogNameFilter()) {
        hash = (37 * hash) + CATALOG_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogNameFilter().hashCode();
      }
      if (hasSchemaNameFilter()) {
        hash = (37 * hash) + SCHEMA_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaNameFilter().hashCode();
      }
      if (hasTableNameFilter()) {
        hash = (37 * hash) + TABLE_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getTableNameFilter().hashCode();
      }
      if (getTableTypeFilterCount() > 0) {
        hash = (37 * hash) + TABLE_TYPE_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getTableTypeFilterList().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq 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.drill.exec.proto.UserProtos.GetTablesReq parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetTablesReq prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Request message for getting the metadata for tables satisfying the given optional filters.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetTablesReq}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetTablesReq)
        org.apache.drill.exec.proto.UserProtos.GetTablesReqOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesReq_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesReq_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetTablesReq.class, org.apache.drill.exec.proto.UserProtos.GetTablesReq.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetTablesReq.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getCatalogNameFilterFieldBuilder();
          getSchemaNameFilterFieldBuilder();
          getTableNameFilterFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = null;
        } else {
          schemaNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (tableNameFilterBuilder_ == null) {
          tableNameFilter_ = null;
        } else {
          tableNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        tableTypeFilter_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesReq_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetTablesReq getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetTablesReq.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetTablesReq build() {
        org.apache.drill.exec.proto.UserProtos.GetTablesReq result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetTablesReq buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetTablesReq result = new org.apache.drill.exec.proto.UserProtos.GetTablesReq(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (catalogNameFilterBuilder_ == null) {
            result.catalogNameFilter_ = catalogNameFilter_;
          } else {
            result.catalogNameFilter_ = catalogNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (schemaNameFilterBuilder_ == null) {
            result.schemaNameFilter_ = schemaNameFilter_;
          } else {
            result.schemaNameFilter_ = schemaNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (tableNameFilterBuilder_ == null) {
            result.tableNameFilter_ = tableNameFilter_;
          } else {
            result.tableNameFilter_ = tableNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        if (((bitField0_ & 0x00000008) != 0)) {
          tableTypeFilter_ = tableTypeFilter_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000008);
        }
        result.tableTypeFilter_ = tableTypeFilter_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetTablesReq) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetTablesReq)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetTablesReq other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetTablesReq.getDefaultInstance()) return this;
        if (other.hasCatalogNameFilter()) {
          mergeCatalogNameFilter(other.getCatalogNameFilter());
        }
        if (other.hasSchemaNameFilter()) {
          mergeSchemaNameFilter(other.getSchemaNameFilter());
        }
        if (other.hasTableNameFilter()) {
          mergeTableNameFilter(other.getTableNameFilter());
        }
        if (!other.tableTypeFilter_.isEmpty()) {
          if (tableTypeFilter_.isEmpty()) {
            tableTypeFilter_ = other.tableTypeFilter_;
            bitField0_ = (bitField0_ & ~0x00000008);
          } else {
            ensureTableTypeFilterIsMutable();
            tableTypeFilter_.addAll(other.tableTypeFilter_);
          }
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getCatalogNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getSchemaNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getTableNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureTableTypeFilterIsMutable();
                tableTypeFilter_.add(bs);
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> catalogNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return Whether the catalogNameFilter field is set.
       */
      public boolean hasCatalogNameFilter() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return The catalogNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        } else {
          return catalogNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          catalogNameFilter_ = value;
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder mergeCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              catalogNameFilter_ != null &&
              catalogNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            catalogNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(catalogNameFilter_).mergeFrom(value).buildPartial();
          } else {
            catalogNameFilter_ = value;
          }
          onChanged();
        } else {
          catalogNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder clearCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
          onChanged();
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getCatalogNameFilterBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getCatalogNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
        if (catalogNameFilterBuilder_ != null) {
          return catalogNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return catalogNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getCatalogNameFilterFieldBuilder() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getCatalogNameFilter(),
                  getParentForChildren(),
                  isClean());
          catalogNameFilter_ = null;
        }
        return catalogNameFilterBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.LikeFilter schemaNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> schemaNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       * @return Whether the schemaNameFilter field is set.
       */
      public boolean hasSchemaNameFilter() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       * @return The schemaNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter() {
        if (schemaNameFilterBuilder_ == null) {
          return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
        } else {
          return schemaNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder setSchemaNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (schemaNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          schemaNameFilter_ = value;
          onChanged();
        } else {
          schemaNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder setSchemaNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          schemaNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder mergeSchemaNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (schemaNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              schemaNameFilter_ != null &&
              schemaNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            schemaNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(schemaNameFilter_).mergeFrom(value).buildPartial();
          } else {
            schemaNameFilter_ = value;
          }
          onChanged();
        } else {
          schemaNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder clearSchemaNameFilter() {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = null;
          onChanged();
        } else {
          schemaNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getSchemaNameFilterBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getSchemaNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder() {
        if (schemaNameFilterBuilder_ != null) {
          return schemaNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return schemaNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getSchemaNameFilterFieldBuilder() {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getSchemaNameFilter(),
                  getParentForChildren(),
                  isClean());
          schemaNameFilter_ = null;
        }
        return schemaNameFilterBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.LikeFilter tableNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> tableNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       * @return Whether the tableNameFilter field is set.
       */
      public boolean hasTableNameFilter() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       * @return The tableNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getTableNameFilter() {
        if (tableNameFilterBuilder_ == null) {
          return tableNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
        } else {
          return tableNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder setTableNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (tableNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          tableNameFilter_ = value;
          onChanged();
        } else {
          tableNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder setTableNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (tableNameFilterBuilder_ == null) {
          tableNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          tableNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder mergeTableNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (tableNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              tableNameFilter_ != null &&
              tableNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            tableNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(tableNameFilter_).mergeFrom(value).buildPartial();
          } else {
            tableNameFilter_ = value;
          }
          onChanged();
        } else {
          tableNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder clearTableNameFilter() {
        if (tableNameFilterBuilder_ == null) {
          tableNameFilter_ = null;
          onChanged();
        } else {
          tableNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getTableNameFilterBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getTableNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getTableNameFilterOrBuilder() {
        if (tableNameFilterBuilder_ != null) {
          return tableNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return tableNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getTableNameFilterFieldBuilder() {
        if (tableNameFilterBuilder_ == null) {
          tableNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getTableNameFilter(),
                  getParentForChildren(),
                  isClean());
          tableNameFilter_ = null;
        }
        return tableNameFilterBuilder_;
      }

      private com.google.protobuf.LazyStringList tableTypeFilter_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureTableTypeFilterIsMutable() {
        if (!((bitField0_ & 0x00000008) != 0)) {
          tableTypeFilter_ = new com.google.protobuf.LazyStringArrayList(tableTypeFilter_);
          bitField0_ |= 0x00000008;
         }
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @return A list containing the tableTypeFilter.
       */
      public com.google.protobuf.ProtocolStringList
          getTableTypeFilterList() {
        return tableTypeFilter_.getUnmodifiableView();
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @return The count of tableTypeFilter.
       */
      public int getTableTypeFilterCount() {
        return tableTypeFilter_.size();
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @param index The index of the element to return.
       * @return The tableTypeFilter at the given index.
       */
      public java.lang.String getTableTypeFilter(int index) {
        return tableTypeFilter_.get(index);
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @param index The index of the value to return.
       * @return The bytes of the tableTypeFilter at the given index.
       */
      public com.google.protobuf.ByteString
          getTableTypeFilterBytes(int index) {
        return tableTypeFilter_.getByteString(index);
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @param index The index to set the value at.
       * @param value The tableTypeFilter to set.
       * @return This builder for chaining.
       */
      public Builder setTableTypeFilter(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureTableTypeFilterIsMutable();
        tableTypeFilter_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @param value The tableTypeFilter to add.
       * @return This builder for chaining.
       */
      public Builder addTableTypeFilter(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureTableTypeFilterIsMutable();
        tableTypeFilter_.add(value);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @param values The tableTypeFilter to add.
       * @return This builder for chaining.
       */
      public Builder addAllTableTypeFilter(
          java.lang.Iterable<java.lang.String> values) {
        ensureTableTypeFilterIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, tableTypeFilter_);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearTableTypeFilter() {
        tableTypeFilter_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000008);
        onChanged();
        return this;
      }
      /**
       * <code>repeated string table_type_filter = 4;</code>
       * @param value The bytes of the tableTypeFilter to add.
       * @return This builder for chaining.
       */
      public Builder addTableTypeFilterBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureTableTypeFilterIsMutable();
        tableTypeFilter_.add(value);
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetTablesReq)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetTablesReq)
    private static final org.apache.drill.exec.proto.UserProtos.GetTablesReq DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetTablesReq();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetTablesReq getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetTablesReq>
        PARSER = new com.google.protobuf.AbstractParser<GetTablesReq>() {
      @java.lang.Override
      public GetTablesReq parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetTablesReq> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetTablesReq> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetTablesReq getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface TableMetadataOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.TableMetadata)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    boolean hasCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    java.lang.String getCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    com.google.protobuf.ByteString
        getCatalogNameBytes();

    /**
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    boolean hasSchemaName();
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    java.lang.String getSchemaName();
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    com.google.protobuf.ByteString
        getSchemaNameBytes();

    /**
     * <code>optional string table_name = 3;</code>
     * @return Whether the tableName field is set.
     */
    boolean hasTableName();
    /**
     * <code>optional string table_name = 3;</code>
     * @return The tableName.
     */
    java.lang.String getTableName();
    /**
     * <code>optional string table_name = 3;</code>
     * @return The bytes for tableName.
     */
    com.google.protobuf.ByteString
        getTableNameBytes();

    /**
     * <pre>
     * Type. Ex. "TABLE", "VIEW" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <pre>
     * Type. Ex. "TABLE", "VIEW" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The type.
     */
    java.lang.String getType();
    /**
     * <pre>
     * Type. Ex. "TABLE", "VIEW" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The bytes for type.
     */
    com.google.protobuf.ByteString
        getTypeBytes();
  }
  /**
   * <pre>
   * Message encapsulating metadata for a Table.
   * </pre>
   *
   * Protobuf type {@code exec.user.TableMetadata}
   */
  public static final class TableMetadata extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.TableMetadata)
      TableMetadataOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use TableMetadata.newBuilder() to construct.
    private TableMetadata(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private TableMetadata() {
      catalogName_ = "";
      schemaName_ = "";
      tableName_ = "";
      type_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new TableMetadata();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_TableMetadata_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_TableMetadata_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.TableMetadata.class, org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object catalogName_;
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    @java.lang.Override
    public boolean hasCatalogName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    @java.lang.Override
    public java.lang.String getCatalogName() {
      java.lang.Object ref = catalogName_;
      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()) {
          catalogName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCatalogNameBytes() {
      java.lang.Object ref = catalogName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        catalogName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SCHEMA_NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object schemaName_;
    /**
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    @java.lang.Override
    public boolean hasSchemaName() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    @java.lang.Override
    public java.lang.String getSchemaName() {
      java.lang.Object ref = schemaName_;
      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()) {
          schemaName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSchemaNameBytes() {
      java.lang.Object ref = schemaName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        schemaName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TABLE_NAME_FIELD_NUMBER = 3;
    private volatile java.lang.Object tableName_;
    /**
     * <code>optional string table_name = 3;</code>
     * @return Whether the tableName field is set.
     */
    @java.lang.Override
    public boolean hasTableName() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional string table_name = 3;</code>
     * @return The tableName.
     */
    @java.lang.Override
    public java.lang.String getTableName() {
      java.lang.Object ref = tableName_;
      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()) {
          tableName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string table_name = 3;</code>
     * @return The bytes for tableName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getTableNameBytes() {
      java.lang.Object ref = tableName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        tableName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TYPE_FIELD_NUMBER = 4;
    private volatile java.lang.Object type_;
    /**
     * <pre>
     * Type. Ex. "TABLE", "VIEW" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return Whether the type field is set.
     */
    @java.lang.Override
    public boolean hasType() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * Type. Ex. "TABLE", "VIEW" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The type.
     */
    @java.lang.Override
    public java.lang.String getType() {
      java.lang.Object ref = type_;
      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()) {
          type_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Type. Ex. "TABLE", "VIEW" etc.
     * </pre>
     *
     * <code>optional string type = 4;</code>
     * @return The bytes for type.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getTypeBytes() {
      java.lang.Object ref = type_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        type_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, tableName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, type_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, tableName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, type_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.TableMetadata)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.TableMetadata other = (org.apache.drill.exec.proto.UserProtos.TableMetadata) obj;

      if (hasCatalogName() != other.hasCatalogName()) return false;
      if (hasCatalogName()) {
        if (!getCatalogName()
            .equals(other.getCatalogName())) return false;
      }
      if (hasSchemaName() != other.hasSchemaName()) return false;
      if (hasSchemaName()) {
        if (!getSchemaName()
            .equals(other.getSchemaName())) return false;
      }
      if (hasTableName() != other.hasTableName()) return false;
      if (hasTableName()) {
        if (!getTableName()
            .equals(other.getTableName())) return false;
      }
      if (hasType() != other.hasType()) return false;
      if (hasType()) {
        if (!getType()
            .equals(other.getType())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogName()) {
        hash = (37 * hash) + CATALOG_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogName().hashCode();
      }
      if (hasSchemaName()) {
        hash = (37 * hash) + SCHEMA_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaName().hashCode();
      }
      if (hasTableName()) {
        hash = (37 * hash) + TABLE_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getTableName().hashCode();
      }
      if (hasType()) {
        hash = (37 * hash) + TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getType().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata 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.drill.exec.proto.UserProtos.TableMetadata parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.TableMetadata parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.TableMetadata prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Message encapsulating metadata for a Table.
     * </pre>
     *
     * Protobuf type {@code exec.user.TableMetadata}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.TableMetadata)
        org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_TableMetadata_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_TableMetadata_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.TableMetadata.class, org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.TableMetadata.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        catalogName_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        schemaName_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        tableName_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        type_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_TableMetadata_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.TableMetadata getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.TableMetadata.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.TableMetadata build() {
        org.apache.drill.exec.proto.UserProtos.TableMetadata result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.TableMetadata buildPartial() {
        org.apache.drill.exec.proto.UserProtos.TableMetadata result = new org.apache.drill.exec.proto.UserProtos.TableMetadata(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.catalogName_ = catalogName_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.schemaName_ = schemaName_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.tableName_ = tableName_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.type_ = type_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.TableMetadata) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.TableMetadata)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.TableMetadata other) {
        if (other == org.apache.drill.exec.proto.UserProtos.TableMetadata.getDefaultInstance()) return this;
        if (other.hasCatalogName()) {
          bitField0_ |= 0x00000001;
          catalogName_ = other.catalogName_;
          onChanged();
        }
        if (other.hasSchemaName()) {
          bitField0_ |= 0x00000002;
          schemaName_ = other.schemaName_;
          onChanged();
        }
        if (other.hasTableName()) {
          bitField0_ |= 0x00000004;
          tableName_ = other.tableName_;
          onChanged();
        }
        if (other.hasType()) {
          bitField0_ |= 0x00000008;
          type_ = other.type_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                catalogName_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                schemaName_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                tableName_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                type_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object catalogName_ = "";
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return Whether the catalogName field is set.
       */
      public boolean hasCatalogName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The catalogName.
       */
      public java.lang.String getCatalogName() {
        java.lang.Object ref = catalogName_;
        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()) {
            catalogName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The bytes for catalogName.
       */
      public com.google.protobuf.ByteString
          getCatalogNameBytes() {
        java.lang.Object ref = catalogName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          catalogName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        catalogName_ = getDefaultInstance().getCatalogName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The bytes for catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object schemaName_ = "";
      /**
       * <code>optional string schema_name = 2;</code>
       * @return Whether the schemaName field is set.
       */
      public boolean hasSchemaName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return The schemaName.
       */
      public java.lang.String getSchemaName() {
        java.lang.Object ref = schemaName_;
        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()) {
            schemaName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return The bytes for schemaName.
       */
      public com.google.protobuf.ByteString
          getSchemaNameBytes() {
        java.lang.Object ref = schemaName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          schemaName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @param value The schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearSchemaName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        schemaName_ = getDefaultInstance().getSchemaName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @param value The bytes for schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object tableName_ = "";
      /**
       * <code>optional string table_name = 3;</code>
       * @return Whether the tableName field is set.
       */
      public boolean hasTableName() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @return The tableName.
       */
      public java.lang.String getTableName() {
        java.lang.Object ref = tableName_;
        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()) {
            tableName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @return The bytes for tableName.
       */
      public com.google.protobuf.ByteString
          getTableNameBytes() {
        java.lang.Object ref = tableName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          tableName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @param value The tableName to set.
       * @return This builder for chaining.
       */
      public Builder setTableName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tableName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearTableName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        tableName_ = getDefaultInstance().getTableName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @param value The bytes for tableName to set.
       * @return This builder for chaining.
       */
      public Builder setTableNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tableName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object type_ = "";
      /**
       * <pre>
       * Type. Ex. "TABLE", "VIEW" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return Whether the type field is set.
       */
      public boolean hasType() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * Type. Ex. "TABLE", "VIEW" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return The type.
       */
      public java.lang.String getType() {
        java.lang.Object ref = type_;
        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()) {
            type_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Type. Ex. "TABLE", "VIEW" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return The bytes for type.
       */
      public com.google.protobuf.ByteString
          getTypeBytes() {
        java.lang.Object ref = type_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          type_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Type. Ex. "TABLE", "VIEW" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        type_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Type. Ex. "TABLE", "VIEW" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000008);
        type_ = getDefaultInstance().getType();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Type. Ex. "TABLE", "VIEW" etc.
       * </pre>
       *
       * <code>optional string type = 4;</code>
       * @param value The bytes for type to set.
       * @return This builder for chaining.
       */
      public Builder setTypeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        type_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.TableMetadata)
    }

    // @@protoc_insertion_point(class_scope:exec.user.TableMetadata)
    private static final org.apache.drill.exec.proto.UserProtos.TableMetadata DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.TableMetadata();
    }

    public static org.apache.drill.exec.proto.UserProtos.TableMetadata getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<TableMetadata>
        PARSER = new com.google.protobuf.AbstractParser<TableMetadata>() {
      @java.lang.Override
      public TableMetadata parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<TableMetadata> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<TableMetadata> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.TableMetadata getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetTablesRespOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetTablesResp)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus();

    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.TableMetadata> 
        getTablesList();
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.TableMetadata getTables(int index);
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    int getTablesCount();
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder> 
        getTablesOrBuilderList();
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder getTablesOrBuilder(
        int index);

    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();
  }
  /**
   * <pre>
   * Response message for GetTablesReq.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetTablesResp}
   */
  public static final class GetTablesResp extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetTablesResp)
      GetTablesRespOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetTablesResp.newBuilder() to construct.
    private GetTablesResp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetTablesResp() {
      status_ = 0;
      tables_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetTablesResp();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesResp_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesResp_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetTablesResp.class, org.apache.drill.exec.proto.UserProtos.GetTablesResp.Builder.class);
    }

    private int bitField0_;
    public static final int STATUS_FIELD_NUMBER = 1;
    private int status_;
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
    }

    public static final int TABLES_FIELD_NUMBER = 2;
    private java.util.List<org.apache.drill.exec.proto.UserProtos.TableMetadata> tables_;
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.TableMetadata> getTablesList() {
      return tables_;
    }
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder> 
        getTablesOrBuilderList() {
      return tables_;
    }
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    @java.lang.Override
    public int getTablesCount() {
      return tables_.size();
    }
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.TableMetadata getTables(int index) {
      return tables_.get(index);
    }
    /**
     * <code>repeated .exec.user.TableMetadata tables = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder getTablesOrBuilder(
        int index) {
      return tables_.get(index);
    }

    public static final int ERROR_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, status_);
      }
      for (int i = 0; i < tables_.size(); i++) {
        output.writeMessage(2, tables_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(3, getError());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, status_);
      }
      for (int i = 0; i < tables_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, tables_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getError());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetTablesResp)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetTablesResp other = (org.apache.drill.exec.proto.UserProtos.GetTablesResp) obj;

      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (!getTablesList()
          .equals(other.getTablesList())) return false;
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (getTablesCount() > 0) {
        hash = (37 * hash) + TABLES_FIELD_NUMBER;
        hash = (53 * hash) + getTablesList().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp 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.drill.exec.proto.UserProtos.GetTablesResp parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetTablesResp prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Response message for GetTablesReq.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetTablesResp}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetTablesResp)
        org.apache.drill.exec.proto.UserProtos.GetTablesRespOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesResp_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesResp_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetTablesResp.class, org.apache.drill.exec.proto.UserProtos.GetTablesResp.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetTablesResp.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getTablesFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (tablesBuilder_ == null) {
          tables_ = java.util.Collections.emptyList();
        } else {
          tables_ = null;
          tablesBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetTablesResp_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetTablesResp getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetTablesResp.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetTablesResp build() {
        org.apache.drill.exec.proto.UserProtos.GetTablesResp result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetTablesResp buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetTablesResp result = new org.apache.drill.exec.proto.UserProtos.GetTablesResp(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.status_ = status_;
        if (tablesBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            tables_ = java.util.Collections.unmodifiableList(tables_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.tables_ = tables_;
        } else {
          result.tables_ = tablesBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetTablesResp) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetTablesResp)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetTablesResp other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetTablesResp.getDefaultInstance()) return this;
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (tablesBuilder_ == null) {
          if (!other.tables_.isEmpty()) {
            if (tables_.isEmpty()) {
              tables_ = other.tables_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureTablesIsMutable();
              tables_.addAll(other.tables_);
            }
            onChanged();
          }
        } else {
          if (!other.tables_.isEmpty()) {
            if (tablesBuilder_.isEmpty()) {
              tablesBuilder_.dispose();
              tablesBuilder_ = null;
              tables_ = other.tables_;
              bitField0_ = (bitField0_ & ~0x00000002);
              tablesBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getTablesFieldBuilder() : null;
            } else {
              tablesBuilder_.addAllMessages(other.tables_);
            }
          }
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.RequestStatus tmpValue =
                    org.apache.drill.exec.proto.UserProtos.RequestStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                org.apache.drill.exec.proto.UserProtos.TableMetadata m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserProtos.TableMetadata.PARSER,
                        extensionRegistry);
                if (tablesBuilder_ == null) {
                  ensureTablesIsMutable();
                  tables_.add(m);
                } else {
                  tablesBuilder_.addMessage(m);
                }
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int status_ = 0;
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserProtos.RequestStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserProtos.TableMetadata> tables_ =
        java.util.Collections.emptyList();
      private void ensureTablesIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          tables_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserProtos.TableMetadata>(tables_);
          bitField0_ |= 0x00000002;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.TableMetadata, org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder, org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder> tablesBuilder_;

      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.TableMetadata> getTablesList() {
        if (tablesBuilder_ == null) {
          return java.util.Collections.unmodifiableList(tables_);
        } else {
          return tablesBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public int getTablesCount() {
        if (tablesBuilder_ == null) {
          return tables_.size();
        } else {
          return tablesBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.TableMetadata getTables(int index) {
        if (tablesBuilder_ == null) {
          return tables_.get(index);
        } else {
          return tablesBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder setTables(
          int index, org.apache.drill.exec.proto.UserProtos.TableMetadata value) {
        if (tablesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTablesIsMutable();
          tables_.set(index, value);
          onChanged();
        } else {
          tablesBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder setTables(
          int index, org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder builderForValue) {
        if (tablesBuilder_ == null) {
          ensureTablesIsMutable();
          tables_.set(index, builderForValue.build());
          onChanged();
        } else {
          tablesBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder addTables(org.apache.drill.exec.proto.UserProtos.TableMetadata value) {
        if (tablesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTablesIsMutable();
          tables_.add(value);
          onChanged();
        } else {
          tablesBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder addTables(
          int index, org.apache.drill.exec.proto.UserProtos.TableMetadata value) {
        if (tablesBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureTablesIsMutable();
          tables_.add(index, value);
          onChanged();
        } else {
          tablesBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder addTables(
          org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder builderForValue) {
        if (tablesBuilder_ == null) {
          ensureTablesIsMutable();
          tables_.add(builderForValue.build());
          onChanged();
        } else {
          tablesBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder addTables(
          int index, org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder builderForValue) {
        if (tablesBuilder_ == null) {
          ensureTablesIsMutable();
          tables_.add(index, builderForValue.build());
          onChanged();
        } else {
          tablesBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder addAllTables(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.TableMetadata> values) {
        if (tablesBuilder_ == null) {
          ensureTablesIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, tables_);
          onChanged();
        } else {
          tablesBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder clearTables() {
        if (tablesBuilder_ == null) {
          tables_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          tablesBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public Builder removeTables(int index) {
        if (tablesBuilder_ == null) {
          ensureTablesIsMutable();
          tables_.remove(index);
          onChanged();
        } else {
          tablesBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder getTablesBuilder(
          int index) {
        return getTablesFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder getTablesOrBuilder(
          int index) {
        if (tablesBuilder_ == null) {
          return tables_.get(index);  } else {
          return tablesBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder> 
           getTablesOrBuilderList() {
        if (tablesBuilder_ != null) {
          return tablesBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(tables_);
        }
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder addTablesBuilder() {
        return getTablesFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserProtos.TableMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder addTablesBuilder(
          int index) {
        return getTablesFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserProtos.TableMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.TableMetadata tables = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder> 
           getTablesBuilderList() {
        return getTablesFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.TableMetadata, org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder, org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder> 
          getTablesFieldBuilder() {
        if (tablesBuilder_ == null) {
          tablesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.TableMetadata, org.apache.drill.exec.proto.UserProtos.TableMetadata.Builder, org.apache.drill.exec.proto.UserProtos.TableMetadataOrBuilder>(
                  tables_,
                  ((bitField0_ & 0x00000002) != 0),
                  getParentForChildren(),
                  isClean());
          tables_ = null;
        }
        return tablesBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetTablesResp)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetTablesResp)
    private static final org.apache.drill.exec.proto.UserProtos.GetTablesResp DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetTablesResp();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetTablesResp getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetTablesResp>
        PARSER = new com.google.protobuf.AbstractParser<GetTablesResp>() {
      @java.lang.Override
      public GetTablesResp parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetTablesResp> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetTablesResp> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetTablesResp getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetColumnsReqOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetColumnsReq)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    boolean hasCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder();

    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return Whether the schemaNameFilter field is set.
     */
    boolean hasSchemaNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return The schemaNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder();

    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return Whether the tableNameFilter field is set.
     */
    boolean hasTableNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return The tableNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getTableNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getTableNameFilterOrBuilder();

    /**
     * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
     * @return Whether the columnNameFilter field is set.
     */
    boolean hasColumnNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
     * @return The columnNameFilter.
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilter getColumnNameFilter();
    /**
     * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
     */
    org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getColumnNameFilterOrBuilder();
  }
  /**
   * <pre>
   * Request message for getting the metadata for columns satisfying the given optional filters.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetColumnsReq}
   */
  public static final class GetColumnsReq extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetColumnsReq)
      GetColumnsReqOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetColumnsReq.newBuilder() to construct.
    private GetColumnsReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetColumnsReq() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetColumnsReq();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsReq_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsReq_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetColumnsReq.class, org.apache.drill.exec.proto.UserProtos.GetColumnsReq.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FILTER_FIELD_NUMBER = 1;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return Whether the catalogNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasCatalogNameFilter() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     * @return The catalogNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
      return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
    }

    public static final int SCHEMA_NAME_FILTER_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter schemaNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return Whether the schemaNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasSchemaNameFilter() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     * @return The schemaNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter() {
      return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder() {
      return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
    }

    public static final int TABLE_NAME_FILTER_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter tableNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return Whether the tableNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasTableNameFilter() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     * @return The tableNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getTableNameFilter() {
      return tableNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getTableNameFilterOrBuilder() {
      return tableNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
    }

    public static final int COLUMN_NAME_FILTER_FIELD_NUMBER = 4;
    private org.apache.drill.exec.proto.UserProtos.LikeFilter columnNameFilter_;
    /**
     * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
     * @return Whether the columnNameFilter field is set.
     */
    @java.lang.Override
    public boolean hasColumnNameFilter() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
     * @return The columnNameFilter.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilter getColumnNameFilter() {
      return columnNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : columnNameFilter_;
    }
    /**
     * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getColumnNameFilterOrBuilder() {
      return columnNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : columnNameFilter_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(1, getCatalogNameFilter());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getSchemaNameFilter());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getTableNameFilter());
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeMessage(4, getColumnNameFilter());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, getCatalogNameFilter());
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getSchemaNameFilter());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getTableNameFilter());
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, getColumnNameFilter());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetColumnsReq)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetColumnsReq other = (org.apache.drill.exec.proto.UserProtos.GetColumnsReq) obj;

      if (hasCatalogNameFilter() != other.hasCatalogNameFilter()) return false;
      if (hasCatalogNameFilter()) {
        if (!getCatalogNameFilter()
            .equals(other.getCatalogNameFilter())) return false;
      }
      if (hasSchemaNameFilter() != other.hasSchemaNameFilter()) return false;
      if (hasSchemaNameFilter()) {
        if (!getSchemaNameFilter()
            .equals(other.getSchemaNameFilter())) return false;
      }
      if (hasTableNameFilter() != other.hasTableNameFilter()) return false;
      if (hasTableNameFilter()) {
        if (!getTableNameFilter()
            .equals(other.getTableNameFilter())) return false;
      }
      if (hasColumnNameFilter() != other.hasColumnNameFilter()) return false;
      if (hasColumnNameFilter()) {
        if (!getColumnNameFilter()
            .equals(other.getColumnNameFilter())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogNameFilter()) {
        hash = (37 * hash) + CATALOG_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogNameFilter().hashCode();
      }
      if (hasSchemaNameFilter()) {
        hash = (37 * hash) + SCHEMA_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaNameFilter().hashCode();
      }
      if (hasTableNameFilter()) {
        hash = (37 * hash) + TABLE_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getTableNameFilter().hashCode();
      }
      if (hasColumnNameFilter()) {
        hash = (37 * hash) + COLUMN_NAME_FILTER_FIELD_NUMBER;
        hash = (53 * hash) + getColumnNameFilter().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq 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.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetColumnsReq prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Request message for getting the metadata for columns satisfying the given optional filters.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetColumnsReq}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetColumnsReq)
        org.apache.drill.exec.proto.UserProtos.GetColumnsReqOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsReq_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsReq_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetColumnsReq.class, org.apache.drill.exec.proto.UserProtos.GetColumnsReq.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetColumnsReq.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getCatalogNameFilterFieldBuilder();
          getSchemaNameFilterFieldBuilder();
          getTableNameFilterFieldBuilder();
          getColumnNameFilterFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = null;
        } else {
          schemaNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (tableNameFilterBuilder_ == null) {
          tableNameFilter_ = null;
        } else {
          tableNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        if (columnNameFilterBuilder_ == null) {
          columnNameFilter_ = null;
        } else {
          columnNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsReq_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetColumnsReq getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetColumnsReq.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetColumnsReq build() {
        org.apache.drill.exec.proto.UserProtos.GetColumnsReq result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetColumnsReq buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetColumnsReq result = new org.apache.drill.exec.proto.UserProtos.GetColumnsReq(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          if (catalogNameFilterBuilder_ == null) {
            result.catalogNameFilter_ = catalogNameFilter_;
          } else {
            result.catalogNameFilter_ = catalogNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (schemaNameFilterBuilder_ == null) {
            result.schemaNameFilter_ = schemaNameFilter_;
          } else {
            result.schemaNameFilter_ = schemaNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (tableNameFilterBuilder_ == null) {
            result.tableNameFilter_ = tableNameFilter_;
          } else {
            result.tableNameFilter_ = tableNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          if (columnNameFilterBuilder_ == null) {
            result.columnNameFilter_ = columnNameFilter_;
          } else {
            result.columnNameFilter_ = columnNameFilterBuilder_.build();
          }
          to_bitField0_ |= 0x00000008;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetColumnsReq) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetColumnsReq)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetColumnsReq other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetColumnsReq.getDefaultInstance()) return this;
        if (other.hasCatalogNameFilter()) {
          mergeCatalogNameFilter(other.getCatalogNameFilter());
        }
        if (other.hasSchemaNameFilter()) {
          mergeSchemaNameFilter(other.getSchemaNameFilter());
        }
        if (other.hasTableNameFilter()) {
          mergeTableNameFilter(other.getTableNameFilter());
        }
        if (other.hasColumnNameFilter()) {
          mergeColumnNameFilter(other.getColumnNameFilter());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                input.readMessage(
                    getCatalogNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getSchemaNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getTableNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                input.readMessage(
                    getColumnNameFilterFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private org.apache.drill.exec.proto.UserProtos.LikeFilter catalogNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> catalogNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return Whether the catalogNameFilter field is set.
       */
      public boolean hasCatalogNameFilter() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       * @return The catalogNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          return catalogNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        } else {
          return catalogNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          catalogNameFilter_ = value;
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder setCatalogNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          catalogNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder mergeCatalogNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (catalogNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0) &&
              catalogNameFilter_ != null &&
              catalogNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            catalogNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(catalogNameFilter_).mergeFrom(value).buildPartial();
          } else {
            catalogNameFilter_ = value;
          }
          onChanged();
        } else {
          catalogNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000001;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public Builder clearCatalogNameFilter() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilter_ = null;
          onChanged();
        } else {
          catalogNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getCatalogNameFilterBuilder() {
        bitField0_ |= 0x00000001;
        onChanged();
        return getCatalogNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getCatalogNameFilterOrBuilder() {
        if (catalogNameFilterBuilder_ != null) {
          return catalogNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return catalogNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : catalogNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter catalog_name_filter = 1;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getCatalogNameFilterFieldBuilder() {
        if (catalogNameFilterBuilder_ == null) {
          catalogNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getCatalogNameFilter(),
                  getParentForChildren(),
                  isClean());
          catalogNameFilter_ = null;
        }
        return catalogNameFilterBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.LikeFilter schemaNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> schemaNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       * @return Whether the schemaNameFilter field is set.
       */
      public boolean hasSchemaNameFilter() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       * @return The schemaNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getSchemaNameFilter() {
        if (schemaNameFilterBuilder_ == null) {
          return schemaNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
        } else {
          return schemaNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder setSchemaNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (schemaNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          schemaNameFilter_ = value;
          onChanged();
        } else {
          schemaNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder setSchemaNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          schemaNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder mergeSchemaNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (schemaNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              schemaNameFilter_ != null &&
              schemaNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            schemaNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(schemaNameFilter_).mergeFrom(value).buildPartial();
          } else {
            schemaNameFilter_ = value;
          }
          onChanged();
        } else {
          schemaNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public Builder clearSchemaNameFilter() {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilter_ = null;
          onChanged();
        } else {
          schemaNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getSchemaNameFilterBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getSchemaNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getSchemaNameFilterOrBuilder() {
        if (schemaNameFilterBuilder_ != null) {
          return schemaNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return schemaNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : schemaNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter schema_name_filter = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getSchemaNameFilterFieldBuilder() {
        if (schemaNameFilterBuilder_ == null) {
          schemaNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getSchemaNameFilter(),
                  getParentForChildren(),
                  isClean());
          schemaNameFilter_ = null;
        }
        return schemaNameFilterBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.LikeFilter tableNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> tableNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       * @return Whether the tableNameFilter field is set.
       */
      public boolean hasTableNameFilter() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       * @return The tableNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getTableNameFilter() {
        if (tableNameFilterBuilder_ == null) {
          return tableNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
        } else {
          return tableNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder setTableNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (tableNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          tableNameFilter_ = value;
          onChanged();
        } else {
          tableNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder setTableNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (tableNameFilterBuilder_ == null) {
          tableNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          tableNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder mergeTableNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (tableNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              tableNameFilter_ != null &&
              tableNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            tableNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(tableNameFilter_).mergeFrom(value).buildPartial();
          } else {
            tableNameFilter_ = value;
          }
          onChanged();
        } else {
          tableNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public Builder clearTableNameFilter() {
        if (tableNameFilterBuilder_ == null) {
          tableNameFilter_ = null;
          onChanged();
        } else {
          tableNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getTableNameFilterBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getTableNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getTableNameFilterOrBuilder() {
        if (tableNameFilterBuilder_ != null) {
          return tableNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return tableNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : tableNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter table_name_filter = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getTableNameFilterFieldBuilder() {
        if (tableNameFilterBuilder_ == null) {
          tableNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getTableNameFilter(),
                  getParentForChildren(),
                  isClean());
          tableNameFilter_ = null;
        }
        return tableNameFilterBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.LikeFilter columnNameFilter_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> columnNameFilterBuilder_;
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       * @return Whether the columnNameFilter field is set.
       */
      public boolean hasColumnNameFilter() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       * @return The columnNameFilter.
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter getColumnNameFilter() {
        if (columnNameFilterBuilder_ == null) {
          return columnNameFilter_ == null ? org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : columnNameFilter_;
        } else {
          return columnNameFilterBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       */
      public Builder setColumnNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (columnNameFilterBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          columnNameFilter_ = value;
          onChanged();
        } else {
          columnNameFilterBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       */
      public Builder setColumnNameFilter(
          org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder builderForValue) {
        if (columnNameFilterBuilder_ == null) {
          columnNameFilter_ = builderForValue.build();
          onChanged();
        } else {
          columnNameFilterBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       */
      public Builder mergeColumnNameFilter(org.apache.drill.exec.proto.UserProtos.LikeFilter value) {
        if (columnNameFilterBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0) &&
              columnNameFilter_ != null &&
              columnNameFilter_ != org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance()) {
            columnNameFilter_ =
              org.apache.drill.exec.proto.UserProtos.LikeFilter.newBuilder(columnNameFilter_).mergeFrom(value).buildPartial();
          } else {
            columnNameFilter_ = value;
          }
          onChanged();
        } else {
          columnNameFilterBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000008;
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       */
      public Builder clearColumnNameFilter() {
        if (columnNameFilterBuilder_ == null) {
          columnNameFilter_ = null;
          onChanged();
        } else {
          columnNameFilterBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        return this;
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder getColumnNameFilterBuilder() {
        bitField0_ |= 0x00000008;
        onChanged();
        return getColumnNameFilterFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder getColumnNameFilterOrBuilder() {
        if (columnNameFilterBuilder_ != null) {
          return columnNameFilterBuilder_.getMessageOrBuilder();
        } else {
          return columnNameFilter_ == null ?
              org.apache.drill.exec.proto.UserProtos.LikeFilter.getDefaultInstance() : columnNameFilter_;
        }
      }
      /**
       * <code>optional .exec.user.LikeFilter column_name_filter = 4;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder> 
          getColumnNameFilterFieldBuilder() {
        if (columnNameFilterBuilder_ == null) {
          columnNameFilterBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.LikeFilter, org.apache.drill.exec.proto.UserProtos.LikeFilter.Builder, org.apache.drill.exec.proto.UserProtos.LikeFilterOrBuilder>(
                  getColumnNameFilter(),
                  getParentForChildren(),
                  isClean());
          columnNameFilter_ = null;
        }
        return columnNameFilterBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetColumnsReq)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetColumnsReq)
    private static final org.apache.drill.exec.proto.UserProtos.GetColumnsReq DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetColumnsReq();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetColumnsReq getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetColumnsReq>
        PARSER = new com.google.protobuf.AbstractParser<GetColumnsReq>() {
      @java.lang.Override
      public GetColumnsReq parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetColumnsReq> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetColumnsReq> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetColumnsReq getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ColumnMetadataOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.ColumnMetadata)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    boolean hasCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    java.lang.String getCatalogName();
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    com.google.protobuf.ByteString
        getCatalogNameBytes();

    /**
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    boolean hasSchemaName();
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    java.lang.String getSchemaName();
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    com.google.protobuf.ByteString
        getSchemaNameBytes();

    /**
     * <code>optional string table_name = 3;</code>
     * @return Whether the tableName field is set.
     */
    boolean hasTableName();
    /**
     * <code>optional string table_name = 3;</code>
     * @return The tableName.
     */
    java.lang.String getTableName();
    /**
     * <code>optional string table_name = 3;</code>
     * @return The bytes for tableName.
     */
    com.google.protobuf.ByteString
        getTableNameBytes();

    /**
     * <code>optional string column_name = 4;</code>
     * @return Whether the columnName field is set.
     */
    boolean hasColumnName();
    /**
     * <code>optional string column_name = 4;</code>
     * @return The columnName.
     */
    java.lang.String getColumnName();
    /**
     * <code>optional string column_name = 4;</code>
     * @return The bytes for columnName.
     */
    com.google.protobuf.ByteString
        getColumnNameBytes();

    /**
     * <code>optional int32 ordinal_position = 5;</code>
     * @return Whether the ordinalPosition field is set.
     */
    boolean hasOrdinalPosition();
    /**
     * <code>optional int32 ordinal_position = 5;</code>
     * @return The ordinalPosition.
     */
    int getOrdinalPosition();

    /**
     * <code>optional string default_value = 6;</code>
     * @return Whether the defaultValue field is set.
     */
    boolean hasDefaultValue();
    /**
     * <code>optional string default_value = 6;</code>
     * @return The defaultValue.
     */
    java.lang.String getDefaultValue();
    /**
     * <code>optional string default_value = 6;</code>
     * @return The bytes for defaultValue.
     */
    com.google.protobuf.ByteString
        getDefaultValueBytes();

    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return Whether the isNullable field is set.
     */
    boolean hasIsNullable();
    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return The isNullable.
     */
    boolean getIsNullable();

    /**
     * <code>optional string data_type = 8;</code>
     * @return Whether the dataType field is set.
     */
    boolean hasDataType();
    /**
     * <code>optional string data_type = 8;</code>
     * @return The dataType.
     */
    java.lang.String getDataType();
    /**
     * <code>optional string data_type = 8;</code>
     * @return The bytes for dataType.
     */
    com.google.protobuf.ByteString
        getDataTypeBytes();

    /**
     * <code>optional int32 char_max_length = 9;</code>
     * @return Whether the charMaxLength field is set.
     */
    boolean hasCharMaxLength();
    /**
     * <code>optional int32 char_max_length = 9;</code>
     * @return The charMaxLength.
     */
    int getCharMaxLength();

    /**
     * <code>optional int32 char_octet_length = 10;</code>
     * @return Whether the charOctetLength field is set.
     */
    boolean hasCharOctetLength();
    /**
     * <code>optional int32 char_octet_length = 10;</code>
     * @return The charOctetLength.
     */
    int getCharOctetLength();

    /**
     * <code>optional int32 numeric_precision = 11;</code>
     * @return Whether the numericPrecision field is set.
     */
    boolean hasNumericPrecision();
    /**
     * <code>optional int32 numeric_precision = 11;</code>
     * @return The numericPrecision.
     */
    int getNumericPrecision();

    /**
     * <code>optional int32 numeric_precision_radix = 12;</code>
     * @return Whether the numericPrecisionRadix field is set.
     */
    boolean hasNumericPrecisionRadix();
    /**
     * <code>optional int32 numeric_precision_radix = 12;</code>
     * @return The numericPrecisionRadix.
     */
    int getNumericPrecisionRadix();

    /**
     * <code>optional int32 numeric_scale = 13;</code>
     * @return Whether the numericScale field is set.
     */
    boolean hasNumericScale();
    /**
     * <code>optional int32 numeric_scale = 13;</code>
     * @return The numericScale.
     */
    int getNumericScale();

    /**
     * <code>optional int32 date_time_precision = 14;</code>
     * @return Whether the dateTimePrecision field is set.
     */
    boolean hasDateTimePrecision();
    /**
     * <code>optional int32 date_time_precision = 14;</code>
     * @return The dateTimePrecision.
     */
    int getDateTimePrecision();

    /**
     * <code>optional string interval_type = 15;</code>
     * @return Whether the intervalType field is set.
     */
    boolean hasIntervalType();
    /**
     * <code>optional string interval_type = 15;</code>
     * @return The intervalType.
     */
    java.lang.String getIntervalType();
    /**
     * <code>optional string interval_type = 15;</code>
     * @return The bytes for intervalType.
     */
    com.google.protobuf.ByteString
        getIntervalTypeBytes();

    /**
     * <code>optional int32 interval_precision = 16;</code>
     * @return Whether the intervalPrecision field is set.
     */
    boolean hasIntervalPrecision();
    /**
     * <code>optional int32 interval_precision = 16;</code>
     * @return The intervalPrecision.
     */
    int getIntervalPrecision();

    /**
     * <code>optional int32 column_size = 17;</code>
     * @return Whether the columnSize field is set.
     */
    boolean hasColumnSize();
    /**
     * <code>optional int32 column_size = 17;</code>
     * @return The columnSize.
     */
    int getColumnSize();
  }
  /**
   * <pre>
   * Message encapsulating metadata for a Column.
   * </pre>
   *
   * Protobuf type {@code exec.user.ColumnMetadata}
   */
  public static final class ColumnMetadata extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.ColumnMetadata)
      ColumnMetadataOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ColumnMetadata.newBuilder() to construct.
    private ColumnMetadata(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ColumnMetadata() {
      catalogName_ = "";
      schemaName_ = "";
      tableName_ = "";
      columnName_ = "";
      defaultValue_ = "";
      dataType_ = "";
      intervalType_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new ColumnMetadata();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ColumnMetadata_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ColumnMetadata_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.ColumnMetadata.class, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object catalogName_;
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    @java.lang.Override
    public boolean hasCatalogName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    @java.lang.Override
    public java.lang.String getCatalogName() {
      java.lang.Object ref = catalogName_;
      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()) {
          catalogName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCatalogNameBytes() {
      java.lang.Object ref = catalogName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        catalogName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SCHEMA_NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object schemaName_;
    /**
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    @java.lang.Override
    public boolean hasSchemaName() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    @java.lang.Override
    public java.lang.String getSchemaName() {
      java.lang.Object ref = schemaName_;
      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()) {
          schemaName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSchemaNameBytes() {
      java.lang.Object ref = schemaName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        schemaName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TABLE_NAME_FIELD_NUMBER = 3;
    private volatile java.lang.Object tableName_;
    /**
     * <code>optional string table_name = 3;</code>
     * @return Whether the tableName field is set.
     */
    @java.lang.Override
    public boolean hasTableName() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional string table_name = 3;</code>
     * @return The tableName.
     */
    @java.lang.Override
    public java.lang.String getTableName() {
      java.lang.Object ref = tableName_;
      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()) {
          tableName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string table_name = 3;</code>
     * @return The bytes for tableName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getTableNameBytes() {
      java.lang.Object ref = tableName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        tableName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int COLUMN_NAME_FIELD_NUMBER = 4;
    private volatile java.lang.Object columnName_;
    /**
     * <code>optional string column_name = 4;</code>
     * @return Whether the columnName field is set.
     */
    @java.lang.Override
    public boolean hasColumnName() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <code>optional string column_name = 4;</code>
     * @return The columnName.
     */
    @java.lang.Override
    public java.lang.String getColumnName() {
      java.lang.Object ref = columnName_;
      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()) {
          columnName_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string column_name = 4;</code>
     * @return The bytes for columnName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getColumnNameBytes() {
      java.lang.Object ref = columnName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        columnName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int ORDINAL_POSITION_FIELD_NUMBER = 5;
    private int ordinalPosition_;
    /**
     * <code>optional int32 ordinal_position = 5;</code>
     * @return Whether the ordinalPosition field is set.
     */
    @java.lang.Override
    public boolean hasOrdinalPosition() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <code>optional int32 ordinal_position = 5;</code>
     * @return The ordinalPosition.
     */
    @java.lang.Override
    public int getOrdinalPosition() {
      return ordinalPosition_;
    }

    public static final int DEFAULT_VALUE_FIELD_NUMBER = 6;
    private volatile java.lang.Object defaultValue_;
    /**
     * <code>optional string default_value = 6;</code>
     * @return Whether the defaultValue field is set.
     */
    @java.lang.Override
    public boolean hasDefaultValue() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <code>optional string default_value = 6;</code>
     * @return The defaultValue.
     */
    @java.lang.Override
    public java.lang.String getDefaultValue() {
      java.lang.Object ref = defaultValue_;
      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()) {
          defaultValue_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string default_value = 6;</code>
     * @return The bytes for defaultValue.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getDefaultValueBytes() {
      java.lang.Object ref = defaultValue_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        defaultValue_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int IS_NULLABLE_FIELD_NUMBER = 7;
    private boolean isNullable_;
    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return Whether the isNullable field is set.
     */
    @java.lang.Override
    public boolean hasIsNullable() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return The isNullable.
     */
    @java.lang.Override
    public boolean getIsNullable() {
      return isNullable_;
    }

    public static final int DATA_TYPE_FIELD_NUMBER = 8;
    private volatile java.lang.Object dataType_;
    /**
     * <code>optional string data_type = 8;</code>
     * @return Whether the dataType field is set.
     */
    @java.lang.Override
    public boolean hasDataType() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <code>optional string data_type = 8;</code>
     * @return The dataType.
     */
    @java.lang.Override
    public java.lang.String getDataType() {
      java.lang.Object ref = dataType_;
      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()) {
          dataType_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string data_type = 8;</code>
     * @return The bytes for dataType.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getDataTypeBytes() {
      java.lang.Object ref = dataType_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        dataType_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int CHAR_MAX_LENGTH_FIELD_NUMBER = 9;
    private int charMaxLength_;
    /**
     * <code>optional int32 char_max_length = 9;</code>
     * @return Whether the charMaxLength field is set.
     */
    @java.lang.Override
    public boolean hasCharMaxLength() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <code>optional int32 char_max_length = 9;</code>
     * @return The charMaxLength.
     */
    @java.lang.Override
    public int getCharMaxLength() {
      return charMaxLength_;
    }

    public static final int CHAR_OCTET_LENGTH_FIELD_NUMBER = 10;
    private int charOctetLength_;
    /**
     * <code>optional int32 char_octet_length = 10;</code>
     * @return Whether the charOctetLength field is set.
     */
    @java.lang.Override
    public boolean hasCharOctetLength() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <code>optional int32 char_octet_length = 10;</code>
     * @return The charOctetLength.
     */
    @java.lang.Override
    public int getCharOctetLength() {
      return charOctetLength_;
    }

    public static final int NUMERIC_PRECISION_FIELD_NUMBER = 11;
    private int numericPrecision_;
    /**
     * <code>optional int32 numeric_precision = 11;</code>
     * @return Whether the numericPrecision field is set.
     */
    @java.lang.Override
    public boolean hasNumericPrecision() {
      return ((bitField0_ & 0x00000400) != 0);
    }
    /**
     * <code>optional int32 numeric_precision = 11;</code>
     * @return The numericPrecision.
     */
    @java.lang.Override
    public int getNumericPrecision() {
      return numericPrecision_;
    }

    public static final int NUMERIC_PRECISION_RADIX_FIELD_NUMBER = 12;
    private int numericPrecisionRadix_;
    /**
     * <code>optional int32 numeric_precision_radix = 12;</code>
     * @return Whether the numericPrecisionRadix field is set.
     */
    @java.lang.Override
    public boolean hasNumericPrecisionRadix() {
      return ((bitField0_ & 0x00000800) != 0);
    }
    /**
     * <code>optional int32 numeric_precision_radix = 12;</code>
     * @return The numericPrecisionRadix.
     */
    @java.lang.Override
    public int getNumericPrecisionRadix() {
      return numericPrecisionRadix_;
    }

    public static final int NUMERIC_SCALE_FIELD_NUMBER = 13;
    private int numericScale_;
    /**
     * <code>optional int32 numeric_scale = 13;</code>
     * @return Whether the numericScale field is set.
     */
    @java.lang.Override
    public boolean hasNumericScale() {
      return ((bitField0_ & 0x00001000) != 0);
    }
    /**
     * <code>optional int32 numeric_scale = 13;</code>
     * @return The numericScale.
     */
    @java.lang.Override
    public int getNumericScale() {
      return numericScale_;
    }

    public static final int DATE_TIME_PRECISION_FIELD_NUMBER = 14;
    private int dateTimePrecision_;
    /**
     * <code>optional int32 date_time_precision = 14;</code>
     * @return Whether the dateTimePrecision field is set.
     */
    @java.lang.Override
    public boolean hasDateTimePrecision() {
      return ((bitField0_ & 0x00002000) != 0);
    }
    /**
     * <code>optional int32 date_time_precision = 14;</code>
     * @return The dateTimePrecision.
     */
    @java.lang.Override
    public int getDateTimePrecision() {
      return dateTimePrecision_;
    }

    public static final int INTERVAL_TYPE_FIELD_NUMBER = 15;
    private volatile java.lang.Object intervalType_;
    /**
     * <code>optional string interval_type = 15;</code>
     * @return Whether the intervalType field is set.
     */
    @java.lang.Override
    public boolean hasIntervalType() {
      return ((bitField0_ & 0x00004000) != 0);
    }
    /**
     * <code>optional string interval_type = 15;</code>
     * @return The intervalType.
     */
    @java.lang.Override
    public java.lang.String getIntervalType() {
      java.lang.Object ref = intervalType_;
      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()) {
          intervalType_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string interval_type = 15;</code>
     * @return The bytes for intervalType.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getIntervalTypeBytes() {
      java.lang.Object ref = intervalType_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        intervalType_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int INTERVAL_PRECISION_FIELD_NUMBER = 16;
    private int intervalPrecision_;
    /**
     * <code>optional int32 interval_precision = 16;</code>
     * @return Whether the intervalPrecision field is set.
     */
    @java.lang.Override
    public boolean hasIntervalPrecision() {
      return ((bitField0_ & 0x00008000) != 0);
    }
    /**
     * <code>optional int32 interval_precision = 16;</code>
     * @return The intervalPrecision.
     */
    @java.lang.Override
    public int getIntervalPrecision() {
      return intervalPrecision_;
    }

    public static final int COLUMN_SIZE_FIELD_NUMBER = 17;
    private int columnSize_;
    /**
     * <code>optional int32 column_size = 17;</code>
     * @return Whether the columnSize field is set.
     */
    @java.lang.Override
    public boolean hasColumnSize() {
      return ((bitField0_ & 0x00010000) != 0);
    }
    /**
     * <code>optional int32 column_size = 17;</code>
     * @return The columnSize.
     */
    @java.lang.Override
    public int getColumnSize() {
      return columnSize_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, tableName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, columnName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt32(5, ordinalPosition_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, defaultValue_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeBool(7, isNullable_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 8, dataType_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeInt32(9, charMaxLength_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        output.writeInt32(10, charOctetLength_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        output.writeInt32(11, numericPrecision_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        output.writeInt32(12, numericPrecisionRadix_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        output.writeInt32(13, numericScale_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        output.writeInt32(14, dateTimePrecision_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 15, intervalType_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        output.writeInt32(16, intervalPrecision_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        output.writeInt32(17, columnSize_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, tableName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, columnName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(5, ordinalPosition_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, defaultValue_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(7, isNullable_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, dataType_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(9, charMaxLength_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(10, charOctetLength_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(11, numericPrecision_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(12, numericPrecisionRadix_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(13, numericScale_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(14, dateTimePrecision_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(15, intervalType_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(16, intervalPrecision_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(17, columnSize_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.ColumnMetadata)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.ColumnMetadata other = (org.apache.drill.exec.proto.UserProtos.ColumnMetadata) obj;

      if (hasCatalogName() != other.hasCatalogName()) return false;
      if (hasCatalogName()) {
        if (!getCatalogName()
            .equals(other.getCatalogName())) return false;
      }
      if (hasSchemaName() != other.hasSchemaName()) return false;
      if (hasSchemaName()) {
        if (!getSchemaName()
            .equals(other.getSchemaName())) return false;
      }
      if (hasTableName() != other.hasTableName()) return false;
      if (hasTableName()) {
        if (!getTableName()
            .equals(other.getTableName())) return false;
      }
      if (hasColumnName() != other.hasColumnName()) return false;
      if (hasColumnName()) {
        if (!getColumnName()
            .equals(other.getColumnName())) return false;
      }
      if (hasOrdinalPosition() != other.hasOrdinalPosition()) return false;
      if (hasOrdinalPosition()) {
        if (getOrdinalPosition()
            != other.getOrdinalPosition()) return false;
      }
      if (hasDefaultValue() != other.hasDefaultValue()) return false;
      if (hasDefaultValue()) {
        if (!getDefaultValue()
            .equals(other.getDefaultValue())) return false;
      }
      if (hasIsNullable() != other.hasIsNullable()) return false;
      if (hasIsNullable()) {
        if (getIsNullable()
            != other.getIsNullable()) return false;
      }
      if (hasDataType() != other.hasDataType()) return false;
      if (hasDataType()) {
        if (!getDataType()
            .equals(other.getDataType())) return false;
      }
      if (hasCharMaxLength() != other.hasCharMaxLength()) return false;
      if (hasCharMaxLength()) {
        if (getCharMaxLength()
            != other.getCharMaxLength()) return false;
      }
      if (hasCharOctetLength() != other.hasCharOctetLength()) return false;
      if (hasCharOctetLength()) {
        if (getCharOctetLength()
            != other.getCharOctetLength()) return false;
      }
      if (hasNumericPrecision() != other.hasNumericPrecision()) return false;
      if (hasNumericPrecision()) {
        if (getNumericPrecision()
            != other.getNumericPrecision()) return false;
      }
      if (hasNumericPrecisionRadix() != other.hasNumericPrecisionRadix()) return false;
      if (hasNumericPrecisionRadix()) {
        if (getNumericPrecisionRadix()
            != other.getNumericPrecisionRadix()) return false;
      }
      if (hasNumericScale() != other.hasNumericScale()) return false;
      if (hasNumericScale()) {
        if (getNumericScale()
            != other.getNumericScale()) return false;
      }
      if (hasDateTimePrecision() != other.hasDateTimePrecision()) return false;
      if (hasDateTimePrecision()) {
        if (getDateTimePrecision()
            != other.getDateTimePrecision()) return false;
      }
      if (hasIntervalType() != other.hasIntervalType()) return false;
      if (hasIntervalType()) {
        if (!getIntervalType()
            .equals(other.getIntervalType())) return false;
      }
      if (hasIntervalPrecision() != other.hasIntervalPrecision()) return false;
      if (hasIntervalPrecision()) {
        if (getIntervalPrecision()
            != other.getIntervalPrecision()) return false;
      }
      if (hasColumnSize() != other.hasColumnSize()) return false;
      if (hasColumnSize()) {
        if (getColumnSize()
            != other.getColumnSize()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogName()) {
        hash = (37 * hash) + CATALOG_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogName().hashCode();
      }
      if (hasSchemaName()) {
        hash = (37 * hash) + SCHEMA_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaName().hashCode();
      }
      if (hasTableName()) {
        hash = (37 * hash) + TABLE_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getTableName().hashCode();
      }
      if (hasColumnName()) {
        hash = (37 * hash) + COLUMN_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getColumnName().hashCode();
      }
      if (hasOrdinalPosition()) {
        hash = (37 * hash) + ORDINAL_POSITION_FIELD_NUMBER;
        hash = (53 * hash) + getOrdinalPosition();
      }
      if (hasDefaultValue()) {
        hash = (37 * hash) + DEFAULT_VALUE_FIELD_NUMBER;
        hash = (53 * hash) + getDefaultValue().hashCode();
      }
      if (hasIsNullable()) {
        hash = (37 * hash) + IS_NULLABLE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getIsNullable());
      }
      if (hasDataType()) {
        hash = (37 * hash) + DATA_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getDataType().hashCode();
      }
      if (hasCharMaxLength()) {
        hash = (37 * hash) + CHAR_MAX_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getCharMaxLength();
      }
      if (hasCharOctetLength()) {
        hash = (37 * hash) + CHAR_OCTET_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getCharOctetLength();
      }
      if (hasNumericPrecision()) {
        hash = (37 * hash) + NUMERIC_PRECISION_FIELD_NUMBER;
        hash = (53 * hash) + getNumericPrecision();
      }
      if (hasNumericPrecisionRadix()) {
        hash = (37 * hash) + NUMERIC_PRECISION_RADIX_FIELD_NUMBER;
        hash = (53 * hash) + getNumericPrecisionRadix();
      }
      if (hasNumericScale()) {
        hash = (37 * hash) + NUMERIC_SCALE_FIELD_NUMBER;
        hash = (53 * hash) + getNumericScale();
      }
      if (hasDateTimePrecision()) {
        hash = (37 * hash) + DATE_TIME_PRECISION_FIELD_NUMBER;
        hash = (53 * hash) + getDateTimePrecision();
      }
      if (hasIntervalType()) {
        hash = (37 * hash) + INTERVAL_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getIntervalType().hashCode();
      }
      if (hasIntervalPrecision()) {
        hash = (37 * hash) + INTERVAL_PRECISION_FIELD_NUMBER;
        hash = (53 * hash) + getIntervalPrecision();
      }
      if (hasColumnSize()) {
        hash = (37 * hash) + COLUMN_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getColumnSize();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata 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.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.ColumnMetadata prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Message encapsulating metadata for a Column.
     * </pre>
     *
     * Protobuf type {@code exec.user.ColumnMetadata}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.ColumnMetadata)
        org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ColumnMetadata_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ColumnMetadata_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.ColumnMetadata.class, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.ColumnMetadata.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        catalogName_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        schemaName_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        tableName_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        columnName_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        ordinalPosition_ = 0;
        bitField0_ = (bitField0_ & ~0x00000010);
        defaultValue_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        isNullable_ = false;
        bitField0_ = (bitField0_ & ~0x00000040);
        dataType_ = "";
        bitField0_ = (bitField0_ & ~0x00000080);
        charMaxLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00000100);
        charOctetLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00000200);
        numericPrecision_ = 0;
        bitField0_ = (bitField0_ & ~0x00000400);
        numericPrecisionRadix_ = 0;
        bitField0_ = (bitField0_ & ~0x00000800);
        numericScale_ = 0;
        bitField0_ = (bitField0_ & ~0x00001000);
        dateTimePrecision_ = 0;
        bitField0_ = (bitField0_ & ~0x00002000);
        intervalType_ = "";
        bitField0_ = (bitField0_ & ~0x00004000);
        intervalPrecision_ = 0;
        bitField0_ = (bitField0_ & ~0x00008000);
        columnSize_ = 0;
        bitField0_ = (bitField0_ & ~0x00010000);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ColumnMetadata_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadata getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.ColumnMetadata.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadata build() {
        org.apache.drill.exec.proto.UserProtos.ColumnMetadata result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadata buildPartial() {
        org.apache.drill.exec.proto.UserProtos.ColumnMetadata result = new org.apache.drill.exec.proto.UserProtos.ColumnMetadata(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.catalogName_ = catalogName_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.schemaName_ = schemaName_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.tableName_ = tableName_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.columnName_ = columnName_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          result.ordinalPosition_ = ordinalPosition_;
          to_bitField0_ |= 0x00000010;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.defaultValue_ = defaultValue_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.isNullable_ = isNullable_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          to_bitField0_ |= 0x00000080;
        }
        result.dataType_ = dataType_;
        if (((from_bitField0_ & 0x00000100) != 0)) {
          result.charMaxLength_ = charMaxLength_;
          to_bitField0_ |= 0x00000100;
        }
        if (((from_bitField0_ & 0x00000200) != 0)) {
          result.charOctetLength_ = charOctetLength_;
          to_bitField0_ |= 0x00000200;
        }
        if (((from_bitField0_ & 0x00000400) != 0)) {
          result.numericPrecision_ = numericPrecision_;
          to_bitField0_ |= 0x00000400;
        }
        if (((from_bitField0_ & 0x00000800) != 0)) {
          result.numericPrecisionRadix_ = numericPrecisionRadix_;
          to_bitField0_ |= 0x00000800;
        }
        if (((from_bitField0_ & 0x00001000) != 0)) {
          result.numericScale_ = numericScale_;
          to_bitField0_ |= 0x00001000;
        }
        if (((from_bitField0_ & 0x00002000) != 0)) {
          result.dateTimePrecision_ = dateTimePrecision_;
          to_bitField0_ |= 0x00002000;
        }
        if (((from_bitField0_ & 0x00004000) != 0)) {
          to_bitField0_ |= 0x00004000;
        }
        result.intervalType_ = intervalType_;
        if (((from_bitField0_ & 0x00008000) != 0)) {
          result.intervalPrecision_ = intervalPrecision_;
          to_bitField0_ |= 0x00008000;
        }
        if (((from_bitField0_ & 0x00010000) != 0)) {
          result.columnSize_ = columnSize_;
          to_bitField0_ |= 0x00010000;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.ColumnMetadata) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.ColumnMetadata)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.ColumnMetadata other) {
        if (other == org.apache.drill.exec.proto.UserProtos.ColumnMetadata.getDefaultInstance()) return this;
        if (other.hasCatalogName()) {
          bitField0_ |= 0x00000001;
          catalogName_ = other.catalogName_;
          onChanged();
        }
        if (other.hasSchemaName()) {
          bitField0_ |= 0x00000002;
          schemaName_ = other.schemaName_;
          onChanged();
        }
        if (other.hasTableName()) {
          bitField0_ |= 0x00000004;
          tableName_ = other.tableName_;
          onChanged();
        }
        if (other.hasColumnName()) {
          bitField0_ |= 0x00000008;
          columnName_ = other.columnName_;
          onChanged();
        }
        if (other.hasOrdinalPosition()) {
          setOrdinalPosition(other.getOrdinalPosition());
        }
        if (other.hasDefaultValue()) {
          bitField0_ |= 0x00000020;
          defaultValue_ = other.defaultValue_;
          onChanged();
        }
        if (other.hasIsNullable()) {
          setIsNullable(other.getIsNullable());
        }
        if (other.hasDataType()) {
          bitField0_ |= 0x00000080;
          dataType_ = other.dataType_;
          onChanged();
        }
        if (other.hasCharMaxLength()) {
          setCharMaxLength(other.getCharMaxLength());
        }
        if (other.hasCharOctetLength()) {
          setCharOctetLength(other.getCharOctetLength());
        }
        if (other.hasNumericPrecision()) {
          setNumericPrecision(other.getNumericPrecision());
        }
        if (other.hasNumericPrecisionRadix()) {
          setNumericPrecisionRadix(other.getNumericPrecisionRadix());
        }
        if (other.hasNumericScale()) {
          setNumericScale(other.getNumericScale());
        }
        if (other.hasDateTimePrecision()) {
          setDateTimePrecision(other.getDateTimePrecision());
        }
        if (other.hasIntervalType()) {
          bitField0_ |= 0x00004000;
          intervalType_ = other.intervalType_;
          onChanged();
        }
        if (other.hasIntervalPrecision()) {
          setIntervalPrecision(other.getIntervalPrecision());
        }
        if (other.hasColumnSize()) {
          setColumnSize(other.getColumnSize());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                catalogName_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                schemaName_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                tableName_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                columnName_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 40: {
                ordinalPosition_ = input.readInt32();
                bitField0_ |= 0x00000010;
                break;
              } // case 40
              case 50: {
                defaultValue_ = input.readBytes();
                bitField0_ |= 0x00000020;
                break;
              } // case 50
              case 56: {
                isNullable_ = input.readBool();
                bitField0_ |= 0x00000040;
                break;
              } // case 56
              case 66: {
                dataType_ = input.readBytes();
                bitField0_ |= 0x00000080;
                break;
              } // case 66
              case 72: {
                charMaxLength_ = input.readInt32();
                bitField0_ |= 0x00000100;
                break;
              } // case 72
              case 80: {
                charOctetLength_ = input.readInt32();
                bitField0_ |= 0x00000200;
                break;
              } // case 80
              case 88: {
                numericPrecision_ = input.readInt32();
                bitField0_ |= 0x00000400;
                break;
              } // case 88
              case 96: {
                numericPrecisionRadix_ = input.readInt32();
                bitField0_ |= 0x00000800;
                break;
              } // case 96
              case 104: {
                numericScale_ = input.readInt32();
                bitField0_ |= 0x00001000;
                break;
              } // case 104
              case 112: {
                dateTimePrecision_ = input.readInt32();
                bitField0_ |= 0x00002000;
                break;
              } // case 112
              case 122: {
                intervalType_ = input.readBytes();
                bitField0_ |= 0x00004000;
                break;
              } // case 122
              case 128: {
                intervalPrecision_ = input.readInt32();
                bitField0_ |= 0x00008000;
                break;
              } // case 128
              case 136: {
                columnSize_ = input.readInt32();
                bitField0_ |= 0x00010000;
                break;
              } // case 136
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object catalogName_ = "";
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return Whether the catalogName field is set.
       */
      public boolean hasCatalogName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The catalogName.
       */
      public java.lang.String getCatalogName() {
        java.lang.Object ref = catalogName_;
        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()) {
            catalogName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return The bytes for catalogName.
       */
      public com.google.protobuf.ByteString
          getCatalogNameBytes() {
        java.lang.Object ref = catalogName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          catalogName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        catalogName_ = getDefaultInstance().getCatalogName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string catalog_name = 1;</code>
       * @param value The bytes for catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object schemaName_ = "";
      /**
       * <code>optional string schema_name = 2;</code>
       * @return Whether the schemaName field is set.
       */
      public boolean hasSchemaName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return The schemaName.
       */
      public java.lang.String getSchemaName() {
        java.lang.Object ref = schemaName_;
        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()) {
            schemaName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return The bytes for schemaName.
       */
      public com.google.protobuf.ByteString
          getSchemaNameBytes() {
        java.lang.Object ref = schemaName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          schemaName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @param value The schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearSchemaName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        schemaName_ = getDefaultInstance().getSchemaName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string schema_name = 2;</code>
       * @param value The bytes for schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object tableName_ = "";
      /**
       * <code>optional string table_name = 3;</code>
       * @return Whether the tableName field is set.
       */
      public boolean hasTableName() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @return The tableName.
       */
      public java.lang.String getTableName() {
        java.lang.Object ref = tableName_;
        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()) {
            tableName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @return The bytes for tableName.
       */
      public com.google.protobuf.ByteString
          getTableNameBytes() {
        java.lang.Object ref = tableName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          tableName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @param value The tableName to set.
       * @return This builder for chaining.
       */
      public Builder setTableName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tableName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearTableName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        tableName_ = getDefaultInstance().getTableName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string table_name = 3;</code>
       * @param value The bytes for tableName to set.
       * @return This builder for chaining.
       */
      public Builder setTableNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tableName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object columnName_ = "";
      /**
       * <code>optional string column_name = 4;</code>
       * @return Whether the columnName field is set.
       */
      public boolean hasColumnName() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <code>optional string column_name = 4;</code>
       * @return The columnName.
       */
      public java.lang.String getColumnName() {
        java.lang.Object ref = columnName_;
        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()) {
            columnName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string column_name = 4;</code>
       * @return The bytes for columnName.
       */
      public com.google.protobuf.ByteString
          getColumnNameBytes() {
        java.lang.Object ref = columnName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          columnName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string column_name = 4;</code>
       * @param value The columnName to set.
       * @return This builder for chaining.
       */
      public Builder setColumnName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        columnName_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string column_name = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearColumnName() {
        bitField0_ = (bitField0_ & ~0x00000008);
        columnName_ = getDefaultInstance().getColumnName();
        onChanged();
        return this;
      }
      /**
       * <code>optional string column_name = 4;</code>
       * @param value The bytes for columnName to set.
       * @return This builder for chaining.
       */
      public Builder setColumnNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        columnName_ = value;
        onChanged();
        return this;
      }

      private int ordinalPosition_ ;
      /**
       * <code>optional int32 ordinal_position = 5;</code>
       * @return Whether the ordinalPosition field is set.
       */
      @java.lang.Override
      public boolean hasOrdinalPosition() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <code>optional int32 ordinal_position = 5;</code>
       * @return The ordinalPosition.
       */
      @java.lang.Override
      public int getOrdinalPosition() {
        return ordinalPosition_;
      }
      /**
       * <code>optional int32 ordinal_position = 5;</code>
       * @param value The ordinalPosition to set.
       * @return This builder for chaining.
       */
      public Builder setOrdinalPosition(int value) {
        bitField0_ |= 0x00000010;
        ordinalPosition_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 ordinal_position = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearOrdinalPosition() {
        bitField0_ = (bitField0_ & ~0x00000010);
        ordinalPosition_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object defaultValue_ = "";
      /**
       * <code>optional string default_value = 6;</code>
       * @return Whether the defaultValue field is set.
       */
      public boolean hasDefaultValue() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <code>optional string default_value = 6;</code>
       * @return The defaultValue.
       */
      public java.lang.String getDefaultValue() {
        java.lang.Object ref = defaultValue_;
        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()) {
            defaultValue_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string default_value = 6;</code>
       * @return The bytes for defaultValue.
       */
      public com.google.protobuf.ByteString
          getDefaultValueBytes() {
        java.lang.Object ref = defaultValue_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          defaultValue_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string default_value = 6;</code>
       * @param value The defaultValue to set.
       * @return This builder for chaining.
       */
      public Builder setDefaultValue(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        defaultValue_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string default_value = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearDefaultValue() {
        bitField0_ = (bitField0_ & ~0x00000020);
        defaultValue_ = getDefaultInstance().getDefaultValue();
        onChanged();
        return this;
      }
      /**
       * <code>optional string default_value = 6;</code>
       * @param value The bytes for defaultValue to set.
       * @return This builder for chaining.
       */
      public Builder setDefaultValueBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        defaultValue_ = value;
        onChanged();
        return this;
      }

      private boolean isNullable_ ;
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @return Whether the isNullable field is set.
       */
      @java.lang.Override
      public boolean hasIsNullable() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @return The isNullable.
       */
      @java.lang.Override
      public boolean getIsNullable() {
        return isNullable_;
      }
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @param value The isNullable to set.
       * @return This builder for chaining.
       */
      public Builder setIsNullable(boolean value) {
        bitField0_ |= 0x00000040;
        isNullable_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsNullable() {
        bitField0_ = (bitField0_ & ~0x00000040);
        isNullable_ = false;
        onChanged();
        return this;
      }

      private java.lang.Object dataType_ = "";
      /**
       * <code>optional string data_type = 8;</code>
       * @return Whether the dataType field is set.
       */
      public boolean hasDataType() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <code>optional string data_type = 8;</code>
       * @return The dataType.
       */
      public java.lang.String getDataType() {
        java.lang.Object ref = dataType_;
        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()) {
            dataType_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string data_type = 8;</code>
       * @return The bytes for dataType.
       */
      public com.google.protobuf.ByteString
          getDataTypeBytes() {
        java.lang.Object ref = dataType_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          dataType_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string data_type = 8;</code>
       * @param value The dataType to set.
       * @return This builder for chaining.
       */
      public Builder setDataType(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
        dataType_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string data_type = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearDataType() {
        bitField0_ = (bitField0_ & ~0x00000080);
        dataType_ = getDefaultInstance().getDataType();
        onChanged();
        return this;
      }
      /**
       * <code>optional string data_type = 8;</code>
       * @param value The bytes for dataType to set.
       * @return This builder for chaining.
       */
      public Builder setDataTypeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000080;
        dataType_ = value;
        onChanged();
        return this;
      }

      private int charMaxLength_ ;
      /**
       * <code>optional int32 char_max_length = 9;</code>
       * @return Whether the charMaxLength field is set.
       */
      @java.lang.Override
      public boolean hasCharMaxLength() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <code>optional int32 char_max_length = 9;</code>
       * @return The charMaxLength.
       */
      @java.lang.Override
      public int getCharMaxLength() {
        return charMaxLength_;
      }
      /**
       * <code>optional int32 char_max_length = 9;</code>
       * @param value The charMaxLength to set.
       * @return This builder for chaining.
       */
      public Builder setCharMaxLength(int value) {
        bitField0_ |= 0x00000100;
        charMaxLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 char_max_length = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearCharMaxLength() {
        bitField0_ = (bitField0_ & ~0x00000100);
        charMaxLength_ = 0;
        onChanged();
        return this;
      }

      private int charOctetLength_ ;
      /**
       * <code>optional int32 char_octet_length = 10;</code>
       * @return Whether the charOctetLength field is set.
       */
      @java.lang.Override
      public boolean hasCharOctetLength() {
        return ((bitField0_ & 0x00000200) != 0);
      }
      /**
       * <code>optional int32 char_octet_length = 10;</code>
       * @return The charOctetLength.
       */
      @java.lang.Override
      public int getCharOctetLength() {
        return charOctetLength_;
      }
      /**
       * <code>optional int32 char_octet_length = 10;</code>
       * @param value The charOctetLength to set.
       * @return This builder for chaining.
       */
      public Builder setCharOctetLength(int value) {
        bitField0_ |= 0x00000200;
        charOctetLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 char_octet_length = 10;</code>
       * @return This builder for chaining.
       */
      public Builder clearCharOctetLength() {
        bitField0_ = (bitField0_ & ~0x00000200);
        charOctetLength_ = 0;
        onChanged();
        return this;
      }

      private int numericPrecision_ ;
      /**
       * <code>optional int32 numeric_precision = 11;</code>
       * @return Whether the numericPrecision field is set.
       */
      @java.lang.Override
      public boolean hasNumericPrecision() {
        return ((bitField0_ & 0x00000400) != 0);
      }
      /**
       * <code>optional int32 numeric_precision = 11;</code>
       * @return The numericPrecision.
       */
      @java.lang.Override
      public int getNumericPrecision() {
        return numericPrecision_;
      }
      /**
       * <code>optional int32 numeric_precision = 11;</code>
       * @param value The numericPrecision to set.
       * @return This builder for chaining.
       */
      public Builder setNumericPrecision(int value) {
        bitField0_ |= 0x00000400;
        numericPrecision_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 numeric_precision = 11;</code>
       * @return This builder for chaining.
       */
      public Builder clearNumericPrecision() {
        bitField0_ = (bitField0_ & ~0x00000400);
        numericPrecision_ = 0;
        onChanged();
        return this;
      }

      private int numericPrecisionRadix_ ;
      /**
       * <code>optional int32 numeric_precision_radix = 12;</code>
       * @return Whether the numericPrecisionRadix field is set.
       */
      @java.lang.Override
      public boolean hasNumericPrecisionRadix() {
        return ((bitField0_ & 0x00000800) != 0);
      }
      /**
       * <code>optional int32 numeric_precision_radix = 12;</code>
       * @return The numericPrecisionRadix.
       */
      @java.lang.Override
      public int getNumericPrecisionRadix() {
        return numericPrecisionRadix_;
      }
      /**
       * <code>optional int32 numeric_precision_radix = 12;</code>
       * @param value The numericPrecisionRadix to set.
       * @return This builder for chaining.
       */
      public Builder setNumericPrecisionRadix(int value) {
        bitField0_ |= 0x00000800;
        numericPrecisionRadix_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 numeric_precision_radix = 12;</code>
       * @return This builder for chaining.
       */
      public Builder clearNumericPrecisionRadix() {
        bitField0_ = (bitField0_ & ~0x00000800);
        numericPrecisionRadix_ = 0;
        onChanged();
        return this;
      }

      private int numericScale_ ;
      /**
       * <code>optional int32 numeric_scale = 13;</code>
       * @return Whether the numericScale field is set.
       */
      @java.lang.Override
      public boolean hasNumericScale() {
        return ((bitField0_ & 0x00001000) != 0);
      }
      /**
       * <code>optional int32 numeric_scale = 13;</code>
       * @return The numericScale.
       */
      @java.lang.Override
      public int getNumericScale() {
        return numericScale_;
      }
      /**
       * <code>optional int32 numeric_scale = 13;</code>
       * @param value The numericScale to set.
       * @return This builder for chaining.
       */
      public Builder setNumericScale(int value) {
        bitField0_ |= 0x00001000;
        numericScale_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 numeric_scale = 13;</code>
       * @return This builder for chaining.
       */
      public Builder clearNumericScale() {
        bitField0_ = (bitField0_ & ~0x00001000);
        numericScale_ = 0;
        onChanged();
        return this;
      }

      private int dateTimePrecision_ ;
      /**
       * <code>optional int32 date_time_precision = 14;</code>
       * @return Whether the dateTimePrecision field is set.
       */
      @java.lang.Override
      public boolean hasDateTimePrecision() {
        return ((bitField0_ & 0x00002000) != 0);
      }
      /**
       * <code>optional int32 date_time_precision = 14;</code>
       * @return The dateTimePrecision.
       */
      @java.lang.Override
      public int getDateTimePrecision() {
        return dateTimePrecision_;
      }
      /**
       * <code>optional int32 date_time_precision = 14;</code>
       * @param value The dateTimePrecision to set.
       * @return This builder for chaining.
       */
      public Builder setDateTimePrecision(int value) {
        bitField0_ |= 0x00002000;
        dateTimePrecision_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 date_time_precision = 14;</code>
       * @return This builder for chaining.
       */
      public Builder clearDateTimePrecision() {
        bitField0_ = (bitField0_ & ~0x00002000);
        dateTimePrecision_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object intervalType_ = "";
      /**
       * <code>optional string interval_type = 15;</code>
       * @return Whether the intervalType field is set.
       */
      public boolean hasIntervalType() {
        return ((bitField0_ & 0x00004000) != 0);
      }
      /**
       * <code>optional string interval_type = 15;</code>
       * @return The intervalType.
       */
      public java.lang.String getIntervalType() {
        java.lang.Object ref = intervalType_;
        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()) {
            intervalType_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string interval_type = 15;</code>
       * @return The bytes for intervalType.
       */
      public com.google.protobuf.ByteString
          getIntervalTypeBytes() {
        java.lang.Object ref = intervalType_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          intervalType_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string interval_type = 15;</code>
       * @param value The intervalType to set.
       * @return This builder for chaining.
       */
      public Builder setIntervalType(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00004000;
        intervalType_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string interval_type = 15;</code>
       * @return This builder for chaining.
       */
      public Builder clearIntervalType() {
        bitField0_ = (bitField0_ & ~0x00004000);
        intervalType_ = getDefaultInstance().getIntervalType();
        onChanged();
        return this;
      }
      /**
       * <code>optional string interval_type = 15;</code>
       * @param value The bytes for intervalType to set.
       * @return This builder for chaining.
       */
      public Builder setIntervalTypeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00004000;
        intervalType_ = value;
        onChanged();
        return this;
      }

      private int intervalPrecision_ ;
      /**
       * <code>optional int32 interval_precision = 16;</code>
       * @return Whether the intervalPrecision field is set.
       */
      @java.lang.Override
      public boolean hasIntervalPrecision() {
        return ((bitField0_ & 0x00008000) != 0);
      }
      /**
       * <code>optional int32 interval_precision = 16;</code>
       * @return The intervalPrecision.
       */
      @java.lang.Override
      public int getIntervalPrecision() {
        return intervalPrecision_;
      }
      /**
       * <code>optional int32 interval_precision = 16;</code>
       * @param value The intervalPrecision to set.
       * @return This builder for chaining.
       */
      public Builder setIntervalPrecision(int value) {
        bitField0_ |= 0x00008000;
        intervalPrecision_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 interval_precision = 16;</code>
       * @return This builder for chaining.
       */
      public Builder clearIntervalPrecision() {
        bitField0_ = (bitField0_ & ~0x00008000);
        intervalPrecision_ = 0;
        onChanged();
        return this;
      }

      private int columnSize_ ;
      /**
       * <code>optional int32 column_size = 17;</code>
       * @return Whether the columnSize field is set.
       */
      @java.lang.Override
      public boolean hasColumnSize() {
        return ((bitField0_ & 0x00010000) != 0);
      }
      /**
       * <code>optional int32 column_size = 17;</code>
       * @return The columnSize.
       */
      @java.lang.Override
      public int getColumnSize() {
        return columnSize_;
      }
      /**
       * <code>optional int32 column_size = 17;</code>
       * @param value The columnSize to set.
       * @return This builder for chaining.
       */
      public Builder setColumnSize(int value) {
        bitField0_ |= 0x00010000;
        columnSize_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional int32 column_size = 17;</code>
       * @return This builder for chaining.
       */
      public Builder clearColumnSize() {
        bitField0_ = (bitField0_ & ~0x00010000);
        columnSize_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.ColumnMetadata)
    }

    // @@protoc_insertion_point(class_scope:exec.user.ColumnMetadata)
    private static final org.apache.drill.exec.proto.UserProtos.ColumnMetadata DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.ColumnMetadata();
    }

    public static org.apache.drill.exec.proto.UserProtos.ColumnMetadata getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ColumnMetadata>
        PARSER = new com.google.protobuf.AbstractParser<ColumnMetadata>() {
      @java.lang.Override
      public ColumnMetadata parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<ColumnMetadata> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<ColumnMetadata> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ColumnMetadata getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetColumnsRespOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetColumnsResp)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus();

    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.ColumnMetadata> 
        getColumnsList();
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.ColumnMetadata getColumns(int index);
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    int getColumnsCount();
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder> 
        getColumnsOrBuilderList();
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder getColumnsOrBuilder(
        int index);

    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();
  }
  /**
   * <pre>
   * Response message for GetColumnsReq.
   * </pre>
   *
   * Protobuf type {@code exec.user.GetColumnsResp}
   */
  public static final class GetColumnsResp extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetColumnsResp)
      GetColumnsRespOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetColumnsResp.newBuilder() to construct.
    private GetColumnsResp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetColumnsResp() {
      status_ = 0;
      columns_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetColumnsResp();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsResp_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsResp_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetColumnsResp.class, org.apache.drill.exec.proto.UserProtos.GetColumnsResp.Builder.class);
    }

    private int bitField0_;
    public static final int STATUS_FIELD_NUMBER = 1;
    private int status_;
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
    }

    public static final int COLUMNS_FIELD_NUMBER = 2;
    private java.util.List<org.apache.drill.exec.proto.UserProtos.ColumnMetadata> columns_;
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.ColumnMetadata> getColumnsList() {
      return columns_;
    }
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder> 
        getColumnsOrBuilderList() {
      return columns_;
    }
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    @java.lang.Override
    public int getColumnsCount() {
      return columns_.size();
    }
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ColumnMetadata getColumns(int index) {
      return columns_.get(index);
    }
    /**
     * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder getColumnsOrBuilder(
        int index) {
      return columns_.get(index);
    }

    public static final int ERROR_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, status_);
      }
      for (int i = 0; i < columns_.size(); i++) {
        output.writeMessage(2, columns_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(3, getError());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, status_);
      }
      for (int i = 0; i < columns_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, columns_.get(i));
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getError());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetColumnsResp)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetColumnsResp other = (org.apache.drill.exec.proto.UserProtos.GetColumnsResp) obj;

      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (!getColumnsList()
          .equals(other.getColumnsList())) return false;
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (getColumnsCount() > 0) {
        hash = (37 * hash) + COLUMNS_FIELD_NUMBER;
        hash = (53 * hash) + getColumnsList().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp 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.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetColumnsResp prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Response message for GetColumnsReq.
     * </pre>
     *
     * Protobuf type {@code exec.user.GetColumnsResp}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetColumnsResp)
        org.apache.drill.exec.proto.UserProtos.GetColumnsRespOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsResp_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsResp_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetColumnsResp.class, org.apache.drill.exec.proto.UserProtos.GetColumnsResp.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetColumnsResp.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getColumnsFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (columnsBuilder_ == null) {
          columns_ = java.util.Collections.emptyList();
        } else {
          columns_ = null;
          columnsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetColumnsResp_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetColumnsResp getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetColumnsResp.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetColumnsResp build() {
        org.apache.drill.exec.proto.UserProtos.GetColumnsResp result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetColumnsResp buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetColumnsResp result = new org.apache.drill.exec.proto.UserProtos.GetColumnsResp(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.status_ = status_;
        if (columnsBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0)) {
            columns_ = java.util.Collections.unmodifiableList(columns_);
            bitField0_ = (bitField0_ & ~0x00000002);
          }
          result.columns_ = columns_;
        } else {
          result.columns_ = columnsBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetColumnsResp) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetColumnsResp)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetColumnsResp other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetColumnsResp.getDefaultInstance()) return this;
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (columnsBuilder_ == null) {
          if (!other.columns_.isEmpty()) {
            if (columns_.isEmpty()) {
              columns_ = other.columns_;
              bitField0_ = (bitField0_ & ~0x00000002);
            } else {
              ensureColumnsIsMutable();
              columns_.addAll(other.columns_);
            }
            onChanged();
          }
        } else {
          if (!other.columns_.isEmpty()) {
            if (columnsBuilder_.isEmpty()) {
              columnsBuilder_.dispose();
              columnsBuilder_ = null;
              columns_ = other.columns_;
              bitField0_ = (bitField0_ & ~0x00000002);
              columnsBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getColumnsFieldBuilder() : null;
            } else {
              columnsBuilder_.addAllMessages(other.columns_);
            }
          }
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.RequestStatus tmpValue =
                    org.apache.drill.exec.proto.UserProtos.RequestStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                org.apache.drill.exec.proto.UserProtos.ColumnMetadata m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserProtos.ColumnMetadata.PARSER,
                        extensionRegistry);
                if (columnsBuilder_ == null) {
                  ensureColumnsIsMutable();
                  columns_.add(m);
                } else {
                  columnsBuilder_.addMessage(m);
                }
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int status_ = 0;
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserProtos.RequestStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 0;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserProtos.ColumnMetadata> columns_ =
        java.util.Collections.emptyList();
      private void ensureColumnsIsMutable() {
        if (!((bitField0_ & 0x00000002) != 0)) {
          columns_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserProtos.ColumnMetadata>(columns_);
          bitField0_ |= 0x00000002;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ColumnMetadata, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder, org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder> columnsBuilder_;

      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.ColumnMetadata> getColumnsList() {
        if (columnsBuilder_ == null) {
          return java.util.Collections.unmodifiableList(columns_);
        } else {
          return columnsBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public int getColumnsCount() {
        if (columnsBuilder_ == null) {
          return columns_.size();
        } else {
          return columnsBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadata getColumns(int index) {
        if (columnsBuilder_ == null) {
          return columns_.get(index);
        } else {
          return columnsBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder setColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ColumnMetadata value) {
        if (columnsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureColumnsIsMutable();
          columns_.set(index, value);
          onChanged();
        } else {
          columnsBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder setColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder builderForValue) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.set(index, builderForValue.build());
          onChanged();
        } else {
          columnsBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder addColumns(org.apache.drill.exec.proto.UserProtos.ColumnMetadata value) {
        if (columnsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureColumnsIsMutable();
          columns_.add(value);
          onChanged();
        } else {
          columnsBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder addColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ColumnMetadata value) {
        if (columnsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureColumnsIsMutable();
          columns_.add(index, value);
          onChanged();
        } else {
          columnsBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder addColumns(
          org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder builderForValue) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.add(builderForValue.build());
          onChanged();
        } else {
          columnsBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder addColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder builderForValue) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.add(index, builderForValue.build());
          onChanged();
        } else {
          columnsBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder addAllColumns(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.ColumnMetadata> values) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, columns_);
          onChanged();
        } else {
          columnsBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder clearColumns() {
        if (columnsBuilder_ == null) {
          columns_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000002);
          onChanged();
        } else {
          columnsBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public Builder removeColumns(int index) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.remove(index);
          onChanged();
        } else {
          columnsBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder getColumnsBuilder(
          int index) {
        return getColumnsFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder getColumnsOrBuilder(
          int index) {
        if (columnsBuilder_ == null) {
          return columns_.get(index);  } else {
          return columnsBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder> 
           getColumnsOrBuilderList() {
        if (columnsBuilder_ != null) {
          return columnsBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(columns_);
        }
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder addColumnsBuilder() {
        return getColumnsFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserProtos.ColumnMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder addColumnsBuilder(
          int index) {
        return getColumnsFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.ColumnMetadata columns = 2;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder> 
           getColumnsBuilderList() {
        return getColumnsFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ColumnMetadata, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder, org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder> 
          getColumnsFieldBuilder() {
        if (columnsBuilder_ == null) {
          columnsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.ColumnMetadata, org.apache.drill.exec.proto.UserProtos.ColumnMetadata.Builder, org.apache.drill.exec.proto.UserProtos.ColumnMetadataOrBuilder>(
                  columns_,
                  ((bitField0_ & 0x00000002) != 0),
                  getParentForChildren(),
                  isClean());
          columns_ = null;
        }
        return columnsBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetColumnsResp)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetColumnsResp)
    private static final org.apache.drill.exec.proto.UserProtos.GetColumnsResp DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetColumnsResp();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetColumnsResp getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetColumnsResp>
        PARSER = new com.google.protobuf.AbstractParser<GetColumnsResp>() {
      @java.lang.Override
      public GetColumnsResp parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetColumnsResp> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetColumnsResp> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetColumnsResp getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface CreatePreparedStatementReqOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.CreatePreparedStatementReq)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional string sql_query = 1;</code>
     * @return Whether the sqlQuery field is set.
     */
    boolean hasSqlQuery();
    /**
     * <code>optional string sql_query = 1;</code>
     * @return The sqlQuery.
     */
    java.lang.String getSqlQuery();
    /**
     * <code>optional string sql_query = 1;</code>
     * @return The bytes for sqlQuery.
     */
    com.google.protobuf.ByteString
        getSqlQueryBytes();
  }
  /**
   * <pre>
   * Request message to create a prepared statement. Currently prepared
   * statement only accepts a SQL query. Query parameter support is not
   * included in current implementation.
   * </pre>
   *
   * Protobuf type {@code exec.user.CreatePreparedStatementReq}
   */
  public static final class CreatePreparedStatementReq extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.CreatePreparedStatementReq)
      CreatePreparedStatementReqOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use CreatePreparedStatementReq.newBuilder() to construct.
    private CreatePreparedStatementReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private CreatePreparedStatementReq() {
      sqlQuery_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new CreatePreparedStatementReq();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementReq_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementReq_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq.class, org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq.Builder.class);
    }

    private int bitField0_;
    public static final int SQL_QUERY_FIELD_NUMBER = 1;
    private volatile java.lang.Object sqlQuery_;
    /**
     * <code>optional string sql_query = 1;</code>
     * @return Whether the sqlQuery field is set.
     */
    @java.lang.Override
    public boolean hasSqlQuery() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional string sql_query = 1;</code>
     * @return The sqlQuery.
     */
    @java.lang.Override
    public java.lang.String getSqlQuery() {
      java.lang.Object ref = sqlQuery_;
      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()) {
          sqlQuery_ = s;
        }
        return s;
      }
    }
    /**
     * <code>optional string sql_query = 1;</code>
     * @return The bytes for sqlQuery.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSqlQueryBytes() {
      java.lang.Object ref = sqlQuery_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        sqlQuery_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, sqlQuery_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, sqlQuery_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq other = (org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq) obj;

      if (hasSqlQuery() != other.hasSqlQuery()) return false;
      if (hasSqlQuery()) {
        if (!getSqlQuery()
            .equals(other.getSqlQuery())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasSqlQuery()) {
        hash = (37 * hash) + SQL_QUERY_FIELD_NUMBER;
        hash = (53 * hash) + getSqlQuery().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq 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.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Request message to create a prepared statement. Currently prepared
     * statement only accepts a SQL query. Query parameter support is not
     * included in current implementation.
     * </pre>
     *
     * Protobuf type {@code exec.user.CreatePreparedStatementReq}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.CreatePreparedStatementReq)
        org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReqOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementReq_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementReq_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq.class, org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        sqlQuery_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementReq_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq build() {
        org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq buildPartial() {
        org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq result = new org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.sqlQuery_ = sqlQuery_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq other) {
        if (other == org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq.getDefaultInstance()) return this;
        if (other.hasSqlQuery()) {
          bitField0_ |= 0x00000001;
          sqlQuery_ = other.sqlQuery_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                sqlQuery_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object sqlQuery_ = "";
      /**
       * <code>optional string sql_query = 1;</code>
       * @return Whether the sqlQuery field is set.
       */
      public boolean hasSqlQuery() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional string sql_query = 1;</code>
       * @return The sqlQuery.
       */
      public java.lang.String getSqlQuery() {
        java.lang.Object ref = sqlQuery_;
        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()) {
            sqlQuery_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <code>optional string sql_query = 1;</code>
       * @return The bytes for sqlQuery.
       */
      public com.google.protobuf.ByteString
          getSqlQueryBytes() {
        java.lang.Object ref = sqlQuery_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          sqlQuery_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <code>optional string sql_query = 1;</code>
       * @param value The sqlQuery to set.
       * @return This builder for chaining.
       */
      public Builder setSqlQuery(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        sqlQuery_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional string sql_query = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearSqlQuery() {
        bitField0_ = (bitField0_ & ~0x00000001);
        sqlQuery_ = getDefaultInstance().getSqlQuery();
        onChanged();
        return this;
      }
      /**
       * <code>optional string sql_query = 1;</code>
       * @param value The bytes for sqlQuery to set.
       * @return This builder for chaining.
       */
      public Builder setSqlQueryBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        sqlQuery_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.CreatePreparedStatementReq)
    }

    // @@protoc_insertion_point(class_scope:exec.user.CreatePreparedStatementReq)
    private static final org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq();
    }

    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<CreatePreparedStatementReq>
        PARSER = new com.google.protobuf.AbstractParser<CreatePreparedStatementReq>() {
      @java.lang.Override
      public CreatePreparedStatementReq parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<CreatePreparedStatementReq> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<CreatePreparedStatementReq> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementReq getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ResultColumnMetadataOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.ResultColumnMetadata)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * Designated column's catalog name. Empty string if not applicable.
     * Defaults to "DRILL" as drill has only one catalog.
     * </pre>
     *
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    boolean hasCatalogName();
    /**
     * <pre>
     * Designated column's catalog name. Empty string if not applicable.
     * Defaults to "DRILL" as drill has only one catalog.
     * </pre>
     *
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    java.lang.String getCatalogName();
    /**
     * <pre>
     * Designated column's catalog name. Empty string if not applicable.
     * Defaults to "DRILL" as drill has only one catalog.
     * </pre>
     *
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    com.google.protobuf.ByteString
        getCatalogNameBytes();

    /**
     * <pre>
     * Designated column's schema name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
     * is lost. If we derive the schema from plan, we may get the right value.
     * </pre>
     *
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    boolean hasSchemaName();
    /**
     * <pre>
     * Designated column's schema name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
     * is lost. If we derive the schema from plan, we may get the right value.
     * </pre>
     *
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    java.lang.String getSchemaName();
    /**
     * <pre>
     * Designated column's schema name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
     * is lost. If we derive the schema from plan, we may get the right value.
     * </pre>
     *
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    com.google.protobuf.ByteString
        getSchemaNameBytes();

    /**
     * <pre>
     * Designated column's table name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and table info
     * is lost. If we derive the schema from query plan, we may get the right value.
     * </pre>
     *
     * <code>optional string table_name = 3;</code>
     * @return Whether the tableName field is set.
     */
    boolean hasTableName();
    /**
     * <pre>
     * Designated column's table name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and table info
     * is lost. If we derive the schema from query plan, we may get the right value.
     * </pre>
     *
     * <code>optional string table_name = 3;</code>
     * @return The tableName.
     */
    java.lang.String getTableName();
    /**
     * <pre>
     * Designated column's table name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and table info
     * is lost. If we derive the schema from query plan, we may get the right value.
     * </pre>
     *
     * <code>optional string table_name = 3;</code>
     * @return The bytes for tableName.
     */
    com.google.protobuf.ByteString
        getTableNameBytes();

    /**
     * <pre>
     * column name
     * </pre>
     *
     * <code>optional string column_name = 4;</code>
     * @return Whether the columnName field is set.
     */
    boolean hasColumnName();
    /**
     * <pre>
     * column name
     * </pre>
     *
     * <code>optional string column_name = 4;</code>
     * @return The columnName.
     */
    java.lang.String getColumnName();
    /**
     * <pre>
     * column name
     * </pre>
     *
     * <code>optional string column_name = 4;</code>
     * @return The bytes for columnName.
     */
    com.google.protobuf.ByteString
        getColumnNameBytes();

    /**
     * <pre>
     * Column label name for display or print purposes.
     * Ex. a column named "empName" might be labeled as "Employee Name".
     * </pre>
     *
     * <code>optional string label = 5;</code>
     * @return Whether the label field is set.
     */
    boolean hasLabel();
    /**
     * <pre>
     * Column label name for display or print purposes.
     * Ex. a column named "empName" might be labeled as "Employee Name".
     * </pre>
     *
     * <code>optional string label = 5;</code>
     * @return The label.
     */
    java.lang.String getLabel();
    /**
     * <pre>
     * Column label name for display or print purposes.
     * Ex. a column named "empName" might be labeled as "Employee Name".
     * </pre>
     *
     * <code>optional string label = 5;</code>
     * @return The bytes for label.
     */
    com.google.protobuf.ByteString
        getLabelBytes();

    /**
     * <pre>
     * Data type in string format. Value is SQL standard type.
     * </pre>
     *
     * <code>optional string data_type = 6;</code>
     * @return Whether the dataType field is set.
     */
    boolean hasDataType();
    /**
     * <pre>
     * Data type in string format. Value is SQL standard type.
     * </pre>
     *
     * <code>optional string data_type = 6;</code>
     * @return The dataType.
     */
    java.lang.String getDataType();
    /**
     * <pre>
     * Data type in string format. Value is SQL standard type.
     * </pre>
     *
     * <code>optional string data_type = 6;</code>
     * @return The bytes for dataType.
     */
    com.google.protobuf.ByteString
        getDataTypeBytes();

    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return Whether the isNullable field is set.
     */
    boolean hasIsNullable();
    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return The isNullable.
     */
    boolean getIsNullable();

    /**
     * <pre>
     * For numeric data, this is the maximum precision.
     * For character data, this is the length in characters.
     * For datetime datatypes, this is the length in characters of the String representation
     *    (assuming the maximum allowed precision of the fractional seconds component).
     * For binary data, this is the length in bytes.
     * For all other types 0 is returned where the column size is not applicable.
     * </pre>
     *
     * <code>optional int32 precision = 8;</code>
     * @return Whether the precision field is set.
     */
    boolean hasPrecision();
    /**
     * <pre>
     * For numeric data, this is the maximum precision.
     * For character data, this is the length in characters.
     * For datetime datatypes, this is the length in characters of the String representation
     *    (assuming the maximum allowed precision of the fractional seconds component).
     * For binary data, this is the length in bytes.
     * For all other types 0 is returned where the column size is not applicable.
     * </pre>
     *
     * <code>optional int32 precision = 8;</code>
     * @return The precision.
     */
    int getPrecision();

    /**
     * <pre>
     * Column's number of digits to right of the decimal point.
     * 0 is returned for types where the scale is not applicable
     * </pre>
     *
     * <code>optional int32 scale = 9;</code>
     * @return Whether the scale field is set.
     */
    boolean hasScale();
    /**
     * <pre>
     * Column's number of digits to right of the decimal point.
     * 0 is returned for types where the scale is not applicable
     * </pre>
     *
     * <code>optional int32 scale = 9;</code>
     * @return The scale.
     */
    int getScale();

    /**
     * <pre>
     * Indicates whether values in the designated column are signed numbers.
     * </pre>
     *
     * <code>optional bool signed = 10;</code>
     * @return Whether the signed field is set.
     */
    boolean hasSigned();
    /**
     * <pre>
     * Indicates whether values in the designated column are signed numbers.
     * </pre>
     *
     * <code>optional bool signed = 10;</code>
     * @return The signed.
     */
    boolean getSigned();

    /**
     * <pre>
     * Maximum number of characters required to display data from the column.
     * </pre>
     *
     * <code>optional int32 display_size = 11;</code>
     * @return Whether the displaySize field is set.
     */
    boolean hasDisplaySize();
    /**
     * <pre>
     * Maximum number of characters required to display data from the column.
     * </pre>
     *
     * <code>optional int32 display_size = 11;</code>
     * @return The displaySize.
     */
    int getDisplaySize();

    /**
     * <pre>
     * Is the column an aliased column. Initial implementation defaults to
     * true as we derive schema from LIMIT 0 query and not the query plan.
     * </pre>
     *
     * <code>optional bool is_aliased = 12;</code>
     * @return Whether the isAliased field is set.
     */
    boolean hasIsAliased();
    /**
     * <pre>
     * Is the column an aliased column. Initial implementation defaults to
     * true as we derive schema from LIMIT 0 query and not the query plan.
     * </pre>
     *
     * <code>optional bool is_aliased = 12;</code>
     * @return The isAliased.
     */
    boolean getIsAliased();

    /**
     * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
     * @return Whether the searchability field is set.
     */
    boolean hasSearchability();
    /**
     * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
     * @return The searchability.
     */
    org.apache.drill.exec.proto.UserProtos.ColumnSearchability getSearchability();

    /**
     * <pre>
     * Defaults to READ_ONLY
     * </pre>
     *
     * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
     * @return Whether the updatability field is set.
     */
    boolean hasUpdatability();
    /**
     * <pre>
     * Defaults to READ_ONLY
     * </pre>
     *
     * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
     * @return The updatability.
     */
    org.apache.drill.exec.proto.UserProtos.ColumnUpdatability getUpdatability();

    /**
     * <pre>
     * whether the designated column is automatically incremented.
     * </pre>
     *
     * <code>optional bool auto_increment = 15;</code>
     * @return Whether the autoIncrement field is set.
     */
    boolean hasAutoIncrement();
    /**
     * <pre>
     * whether the designated column is automatically incremented.
     * </pre>
     *
     * <code>optional bool auto_increment = 15;</code>
     * @return The autoIncrement.
     */
    boolean getAutoIncrement();

    /**
     * <pre>
     * Whether column's case matters for collations and comparisons. Defaults to true.
     * </pre>
     *
     * <code>optional bool case_sensitivity = 16;</code>
     * @return Whether the caseSensitivity field is set.
     */
    boolean hasCaseSensitivity();
    /**
     * <pre>
     * Whether column's case matters for collations and comparisons. Defaults to true.
     * </pre>
     *
     * <code>optional bool case_sensitivity = 16;</code>
     * @return The caseSensitivity.
     */
    boolean getCaseSensitivity();

    /**
     * <pre>
     * whether the column can be used in ORDER BY clause
     * </pre>
     *
     * <code>optional bool sortable = 17;</code>
     * @return Whether the sortable field is set.
     */
    boolean hasSortable();
    /**
     * <pre>
     * whether the column can be used in ORDER BY clause
     * </pre>
     *
     * <code>optional bool sortable = 17;</code>
     * @return The sortable.
     */
    boolean getSortable();

    /**
     * <pre>
     * A fully-qualified name of the Java class whose instances are created
     * if the method ResultSet.getObject is called to retrieve
     * a value from the column. Applicable only to JDBC clients.
     * </pre>
     *
     * <code>optional string class_name = 18;</code>
     * @return Whether the className field is set.
     */
    boolean hasClassName();
    /**
     * <pre>
     * A fully-qualified name of the Java class whose instances are created
     * if the method ResultSet.getObject is called to retrieve
     * a value from the column. Applicable only to JDBC clients.
     * </pre>
     *
     * <code>optional string class_name = 18;</code>
     * @return The className.
     */
    java.lang.String getClassName();
    /**
     * <pre>
     * A fully-qualified name of the Java class whose instances are created
     * if the method ResultSet.getObject is called to retrieve
     * a value from the column. Applicable only to JDBC clients.
     * </pre>
     *
     * <code>optional string class_name = 18;</code>
     * @return The bytes for className.
     */
    com.google.protobuf.ByteString
        getClassNameBytes();

    /**
     * <pre>
     * Is the data type a currency type? For JDBC only.
     * </pre>
     *
     * <code>optional bool is_currency = 20;</code>
     * @return Whether the isCurrency field is set.
     */
    boolean hasIsCurrency();
    /**
     * <pre>
     * Is the data type a currency type? For JDBC only.
     * </pre>
     *
     * <code>optional bool is_currency = 20;</code>
     * @return The isCurrency.
     */
    boolean getIsCurrency();
  }
  /**
   * <pre>
   * Metadata of a column in query result set
   * </pre>
   *
   * Protobuf type {@code exec.user.ResultColumnMetadata}
   */
  public static final class ResultColumnMetadata extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.ResultColumnMetadata)
      ResultColumnMetadataOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ResultColumnMetadata.newBuilder() to construct.
    private ResultColumnMetadata(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ResultColumnMetadata() {
      catalogName_ = "";
      schemaName_ = "";
      tableName_ = "";
      columnName_ = "";
      label_ = "";
      dataType_ = "";
      searchability_ = 0;
      updatability_ = 0;
      className_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new ResultColumnMetadata();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ResultColumnMetadata_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ResultColumnMetadata_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.class, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder.class);
    }

    private int bitField0_;
    public static final int CATALOG_NAME_FIELD_NUMBER = 1;
    private volatile java.lang.Object catalogName_;
    /**
     * <pre>
     * Designated column's catalog name. Empty string if not applicable.
     * Defaults to "DRILL" as drill has only one catalog.
     * </pre>
     *
     * <code>optional string catalog_name = 1;</code>
     * @return Whether the catalogName field is set.
     */
    @java.lang.Override
    public boolean hasCatalogName() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * Designated column's catalog name. Empty string if not applicable.
     * Defaults to "DRILL" as drill has only one catalog.
     * </pre>
     *
     * <code>optional string catalog_name = 1;</code>
     * @return The catalogName.
     */
    @java.lang.Override
    public java.lang.String getCatalogName() {
      java.lang.Object ref = catalogName_;
      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()) {
          catalogName_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Designated column's catalog name. Empty string if not applicable.
     * Defaults to "DRILL" as drill has only one catalog.
     * </pre>
     *
     * <code>optional string catalog_name = 1;</code>
     * @return The bytes for catalogName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCatalogNameBytes() {
      java.lang.Object ref = catalogName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        catalogName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SCHEMA_NAME_FIELD_NUMBER = 2;
    private volatile java.lang.Object schemaName_;
    /**
     * <pre>
     * Designated column's schema name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
     * is lost. If we derive the schema from plan, we may get the right value.
     * </pre>
     *
     * <code>optional string schema_name = 2;</code>
     * @return Whether the schemaName field is set.
     */
    @java.lang.Override
    public boolean hasSchemaName() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <pre>
     * Designated column's schema name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
     * is lost. If we derive the schema from plan, we may get the right value.
     * </pre>
     *
     * <code>optional string schema_name = 2;</code>
     * @return The schemaName.
     */
    @java.lang.Override
    public java.lang.String getSchemaName() {
      java.lang.Object ref = schemaName_;
      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()) {
          schemaName_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Designated column's schema name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
     * is lost. If we derive the schema from plan, we may get the right value.
     * </pre>
     *
     * <code>optional string schema_name = 2;</code>
     * @return The bytes for schemaName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSchemaNameBytes() {
      java.lang.Object ref = schemaName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        schemaName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TABLE_NAME_FIELD_NUMBER = 3;
    private volatile java.lang.Object tableName_;
    /**
     * <pre>
     * Designated column's table name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and table info
     * is lost. If we derive the schema from query plan, we may get the right value.
     * </pre>
     *
     * <code>optional string table_name = 3;</code>
     * @return Whether the tableName field is set.
     */
    @java.lang.Override
    public boolean hasTableName() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <pre>
     * Designated column's table name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and table info
     * is lost. If we derive the schema from query plan, we may get the right value.
     * </pre>
     *
     * <code>optional string table_name = 3;</code>
     * @return The tableName.
     */
    @java.lang.Override
    public java.lang.String getTableName() {
      java.lang.Object ref = tableName_;
      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()) {
          tableName_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Designated column's table name. Not set if not applicable. Initial implementation
     * defaults to no value as we use LIMIT 0 queries to get the schema and table info
     * is lost. If we derive the schema from query plan, we may get the right value.
     * </pre>
     *
     * <code>optional string table_name = 3;</code>
     * @return The bytes for tableName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getTableNameBytes() {
      java.lang.Object ref = tableName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        tableName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int COLUMN_NAME_FIELD_NUMBER = 4;
    private volatile java.lang.Object columnName_;
    /**
     * <pre>
     * column name
     * </pre>
     *
     * <code>optional string column_name = 4;</code>
     * @return Whether the columnName field is set.
     */
    @java.lang.Override
    public boolean hasColumnName() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * column name
     * </pre>
     *
     * <code>optional string column_name = 4;</code>
     * @return The columnName.
     */
    @java.lang.Override
    public java.lang.String getColumnName() {
      java.lang.Object ref = columnName_;
      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()) {
          columnName_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * column name
     * </pre>
     *
     * <code>optional string column_name = 4;</code>
     * @return The bytes for columnName.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getColumnNameBytes() {
      java.lang.Object ref = columnName_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        columnName_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int LABEL_FIELD_NUMBER = 5;
    private volatile java.lang.Object label_;
    /**
     * <pre>
     * Column label name for display or print purposes.
     * Ex. a column named "empName" might be labeled as "Employee Name".
     * </pre>
     *
     * <code>optional string label = 5;</code>
     * @return Whether the label field is set.
     */
    @java.lang.Override
    public boolean hasLabel() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <pre>
     * Column label name for display or print purposes.
     * Ex. a column named "empName" might be labeled as "Employee Name".
     * </pre>
     *
     * <code>optional string label = 5;</code>
     * @return The label.
     */
    @java.lang.Override
    public java.lang.String getLabel() {
      java.lang.Object ref = label_;
      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()) {
          label_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Column label name for display or print purposes.
     * Ex. a column named "empName" might be labeled as "Employee Name".
     * </pre>
     *
     * <code>optional string label = 5;</code>
     * @return The bytes for label.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getLabelBytes() {
      java.lang.Object ref = label_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        label_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int DATA_TYPE_FIELD_NUMBER = 6;
    private volatile java.lang.Object dataType_;
    /**
     * <pre>
     * Data type in string format. Value is SQL standard type.
     * </pre>
     *
     * <code>optional string data_type = 6;</code>
     * @return Whether the dataType field is set.
     */
    @java.lang.Override
    public boolean hasDataType() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <pre>
     * Data type in string format. Value is SQL standard type.
     * </pre>
     *
     * <code>optional string data_type = 6;</code>
     * @return The dataType.
     */
    @java.lang.Override
    public java.lang.String getDataType() {
      java.lang.Object ref = dataType_;
      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()) {
          dataType_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Data type in string format. Value is SQL standard type.
     * </pre>
     *
     * <code>optional string data_type = 6;</code>
     * @return The bytes for dataType.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getDataTypeBytes() {
      java.lang.Object ref = dataType_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        dataType_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int IS_NULLABLE_FIELD_NUMBER = 7;
    private boolean isNullable_;
    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return Whether the isNullable field is set.
     */
    @java.lang.Override
    public boolean hasIsNullable() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <code>optional bool is_nullable = 7;</code>
     * @return The isNullable.
     */
    @java.lang.Override
    public boolean getIsNullable() {
      return isNullable_;
    }

    public static final int PRECISION_FIELD_NUMBER = 8;
    private int precision_;
    /**
     * <pre>
     * For numeric data, this is the maximum precision.
     * For character data, this is the length in characters.
     * For datetime datatypes, this is the length in characters of the String representation
     *    (assuming the maximum allowed precision of the fractional seconds component).
     * For binary data, this is the length in bytes.
     * For all other types 0 is returned where the column size is not applicable.
     * </pre>
     *
     * <code>optional int32 precision = 8;</code>
     * @return Whether the precision field is set.
     */
    @java.lang.Override
    public boolean hasPrecision() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <pre>
     * For numeric data, this is the maximum precision.
     * For character data, this is the length in characters.
     * For datetime datatypes, this is the length in characters of the String representation
     *    (assuming the maximum allowed precision of the fractional seconds component).
     * For binary data, this is the length in bytes.
     * For all other types 0 is returned where the column size is not applicable.
     * </pre>
     *
     * <code>optional int32 precision = 8;</code>
     * @return The precision.
     */
    @java.lang.Override
    public int getPrecision() {
      return precision_;
    }

    public static final int SCALE_FIELD_NUMBER = 9;
    private int scale_;
    /**
     * <pre>
     * Column's number of digits to right of the decimal point.
     * 0 is returned for types where the scale is not applicable
     * </pre>
     *
     * <code>optional int32 scale = 9;</code>
     * @return Whether the scale field is set.
     */
    @java.lang.Override
    public boolean hasScale() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <pre>
     * Column's number of digits to right of the decimal point.
     * 0 is returned for types where the scale is not applicable
     * </pre>
     *
     * <code>optional int32 scale = 9;</code>
     * @return The scale.
     */
    @java.lang.Override
    public int getScale() {
      return scale_;
    }

    public static final int SIGNED_FIELD_NUMBER = 10;
    private boolean signed_;
    /**
     * <pre>
     * Indicates whether values in the designated column are signed numbers.
     * </pre>
     *
     * <code>optional bool signed = 10;</code>
     * @return Whether the signed field is set.
     */
    @java.lang.Override
    public boolean hasSigned() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <pre>
     * Indicates whether values in the designated column are signed numbers.
     * </pre>
     *
     * <code>optional bool signed = 10;</code>
     * @return The signed.
     */
    @java.lang.Override
    public boolean getSigned() {
      return signed_;
    }

    public static final int DISPLAY_SIZE_FIELD_NUMBER = 11;
    private int displaySize_;
    /**
     * <pre>
     * Maximum number of characters required to display data from the column.
     * </pre>
     *
     * <code>optional int32 display_size = 11;</code>
     * @return Whether the displaySize field is set.
     */
    @java.lang.Override
    public boolean hasDisplaySize() {
      return ((bitField0_ & 0x00000400) != 0);
    }
    /**
     * <pre>
     * Maximum number of characters required to display data from the column.
     * </pre>
     *
     * <code>optional int32 display_size = 11;</code>
     * @return The displaySize.
     */
    @java.lang.Override
    public int getDisplaySize() {
      return displaySize_;
    }

    public static final int IS_ALIASED_FIELD_NUMBER = 12;
    private boolean isAliased_;
    /**
     * <pre>
     * Is the column an aliased column. Initial implementation defaults to
     * true as we derive schema from LIMIT 0 query and not the query plan.
     * </pre>
     *
     * <code>optional bool is_aliased = 12;</code>
     * @return Whether the isAliased field is set.
     */
    @java.lang.Override
    public boolean hasIsAliased() {
      return ((bitField0_ & 0x00000800) != 0);
    }
    /**
     * <pre>
     * Is the column an aliased column. Initial implementation defaults to
     * true as we derive schema from LIMIT 0 query and not the query plan.
     * </pre>
     *
     * <code>optional bool is_aliased = 12;</code>
     * @return The isAliased.
     */
    @java.lang.Override
    public boolean getIsAliased() {
      return isAliased_;
    }

    public static final int SEARCHABILITY_FIELD_NUMBER = 13;
    private int searchability_;
    /**
     * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
     * @return Whether the searchability field is set.
     */
    @java.lang.Override public boolean hasSearchability() {
      return ((bitField0_ & 0x00001000) != 0);
    }
    /**
     * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
     * @return The searchability.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.ColumnSearchability getSearchability() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.ColumnSearchability result = org.apache.drill.exec.proto.UserProtos.ColumnSearchability.valueOf(searchability_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.ColumnSearchability.UNKNOWN_SEARCHABILITY : result;
    }

    public static final int UPDATABILITY_FIELD_NUMBER = 14;
    private int updatability_;
    /**
     * <pre>
     * Defaults to READ_ONLY
     * </pre>
     *
     * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
     * @return Whether the updatability field is set.
     */
    @java.lang.Override public boolean hasUpdatability() {
      return ((bitField0_ & 0x00002000) != 0);
    }
    /**
     * <pre>
     * Defaults to READ_ONLY
     * </pre>
     *
     * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
     * @return The updatability.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.ColumnUpdatability getUpdatability() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.ColumnUpdatability result = org.apache.drill.exec.proto.UserProtos.ColumnUpdatability.valueOf(updatability_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.ColumnUpdatability.UNKNOWN_UPDATABILITY : result;
    }

    public static final int AUTO_INCREMENT_FIELD_NUMBER = 15;
    private boolean autoIncrement_;
    /**
     * <pre>
     * whether the designated column is automatically incremented.
     * </pre>
     *
     * <code>optional bool auto_increment = 15;</code>
     * @return Whether the autoIncrement field is set.
     */
    @java.lang.Override
    public boolean hasAutoIncrement() {
      return ((bitField0_ & 0x00004000) != 0);
    }
    /**
     * <pre>
     * whether the designated column is automatically incremented.
     * </pre>
     *
     * <code>optional bool auto_increment = 15;</code>
     * @return The autoIncrement.
     */
    @java.lang.Override
    public boolean getAutoIncrement() {
      return autoIncrement_;
    }

    public static final int CASE_SENSITIVITY_FIELD_NUMBER = 16;
    private boolean caseSensitivity_;
    /**
     * <pre>
     * Whether column's case matters for collations and comparisons. Defaults to true.
     * </pre>
     *
     * <code>optional bool case_sensitivity = 16;</code>
     * @return Whether the caseSensitivity field is set.
     */
    @java.lang.Override
    public boolean hasCaseSensitivity() {
      return ((bitField0_ & 0x00008000) != 0);
    }
    /**
     * <pre>
     * Whether column's case matters for collations and comparisons. Defaults to true.
     * </pre>
     *
     * <code>optional bool case_sensitivity = 16;</code>
     * @return The caseSensitivity.
     */
    @java.lang.Override
    public boolean getCaseSensitivity() {
      return caseSensitivity_;
    }

    public static final int SORTABLE_FIELD_NUMBER = 17;
    private boolean sortable_;
    /**
     * <pre>
     * whether the column can be used in ORDER BY clause
     * </pre>
     *
     * <code>optional bool sortable = 17;</code>
     * @return Whether the sortable field is set.
     */
    @java.lang.Override
    public boolean hasSortable() {
      return ((bitField0_ & 0x00010000) != 0);
    }
    /**
     * <pre>
     * whether the column can be used in ORDER BY clause
     * </pre>
     *
     * <code>optional bool sortable = 17;</code>
     * @return The sortable.
     */
    @java.lang.Override
    public boolean getSortable() {
      return sortable_;
    }

    public static final int CLASS_NAME_FIELD_NUMBER = 18;
    private volatile java.lang.Object className_;
    /**
     * <pre>
     * A fully-qualified name of the Java class whose instances are created
     * if the method ResultSet.getObject is called to retrieve
     * a value from the column. Applicable only to JDBC clients.
     * </pre>
     *
     * <code>optional string class_name = 18;</code>
     * @return Whether the className field is set.
     */
    @java.lang.Override
    public boolean hasClassName() {
      return ((bitField0_ & 0x00020000) != 0);
    }
    /**
     * <pre>
     * A fully-qualified name of the Java class whose instances are created
     * if the method ResultSet.getObject is called to retrieve
     * a value from the column. Applicable only to JDBC clients.
     * </pre>
     *
     * <code>optional string class_name = 18;</code>
     * @return The className.
     */
    @java.lang.Override
    public java.lang.String getClassName() {
      java.lang.Object ref = className_;
      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()) {
          className_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * A fully-qualified name of the Java class whose instances are created
     * if the method ResultSet.getObject is called to retrieve
     * a value from the column. Applicable only to JDBC clients.
     * </pre>
     *
     * <code>optional string class_name = 18;</code>
     * @return The bytes for className.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getClassNameBytes() {
      java.lang.Object ref = className_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        className_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int IS_CURRENCY_FIELD_NUMBER = 20;
    private boolean isCurrency_;
    /**
     * <pre>
     * Is the data type a currency type? For JDBC only.
     * </pre>
     *
     * <code>optional bool is_currency = 20;</code>
     * @return Whether the isCurrency field is set.
     */
    @java.lang.Override
    public boolean hasIsCurrency() {
      return ((bitField0_ & 0x00040000) != 0);
    }
    /**
     * <pre>
     * Is the data type a currency type? For JDBC only.
     * </pre>
     *
     * <code>optional bool is_currency = 20;</code>
     * @return The isCurrency.
     */
    @java.lang.Override
    public boolean getIsCurrency() {
      return isCurrency_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, tableName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, columnName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, label_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 6, dataType_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeBool(7, isNullable_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeInt32(8, precision_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeInt32(9, scale_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        output.writeBool(10, signed_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        output.writeInt32(11, displaySize_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        output.writeBool(12, isAliased_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        output.writeEnum(13, searchability_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        output.writeEnum(14, updatability_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        output.writeBool(15, autoIncrement_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        output.writeBool(16, caseSensitivity_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        output.writeBool(17, sortable_);
      }
      if (((bitField0_ & 0x00020000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 18, className_);
      }
      if (((bitField0_ & 0x00040000) != 0)) {
        output.writeBool(20, isCurrency_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, catalogName_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, schemaName_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, tableName_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, columnName_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, label_);
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, dataType_);
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(7, isNullable_);
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(8, precision_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(9, scale_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(10, signed_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(11, displaySize_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(12, isAliased_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(13, searchability_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(14, updatability_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(15, autoIncrement_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(16, caseSensitivity_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(17, sortable_);
      }
      if (((bitField0_ & 0x00020000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(18, className_);
      }
      if (((bitField0_ & 0x00040000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(20, isCurrency_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata other = (org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata) obj;

      if (hasCatalogName() != other.hasCatalogName()) return false;
      if (hasCatalogName()) {
        if (!getCatalogName()
            .equals(other.getCatalogName())) return false;
      }
      if (hasSchemaName() != other.hasSchemaName()) return false;
      if (hasSchemaName()) {
        if (!getSchemaName()
            .equals(other.getSchemaName())) return false;
      }
      if (hasTableName() != other.hasTableName()) return false;
      if (hasTableName()) {
        if (!getTableName()
            .equals(other.getTableName())) return false;
      }
      if (hasColumnName() != other.hasColumnName()) return false;
      if (hasColumnName()) {
        if (!getColumnName()
            .equals(other.getColumnName())) return false;
      }
      if (hasLabel() != other.hasLabel()) return false;
      if (hasLabel()) {
        if (!getLabel()
            .equals(other.getLabel())) return false;
      }
      if (hasDataType() != other.hasDataType()) return false;
      if (hasDataType()) {
        if (!getDataType()
            .equals(other.getDataType())) return false;
      }
      if (hasIsNullable() != other.hasIsNullable()) return false;
      if (hasIsNullable()) {
        if (getIsNullable()
            != other.getIsNullable()) return false;
      }
      if (hasPrecision() != other.hasPrecision()) return false;
      if (hasPrecision()) {
        if (getPrecision()
            != other.getPrecision()) return false;
      }
      if (hasScale() != other.hasScale()) return false;
      if (hasScale()) {
        if (getScale()
            != other.getScale()) return false;
      }
      if (hasSigned() != other.hasSigned()) return false;
      if (hasSigned()) {
        if (getSigned()
            != other.getSigned()) return false;
      }
      if (hasDisplaySize() != other.hasDisplaySize()) return false;
      if (hasDisplaySize()) {
        if (getDisplaySize()
            != other.getDisplaySize()) return false;
      }
      if (hasIsAliased() != other.hasIsAliased()) return false;
      if (hasIsAliased()) {
        if (getIsAliased()
            != other.getIsAliased()) return false;
      }
      if (hasSearchability() != other.hasSearchability()) return false;
      if (hasSearchability()) {
        if (searchability_ != other.searchability_) return false;
      }
      if (hasUpdatability() != other.hasUpdatability()) return false;
      if (hasUpdatability()) {
        if (updatability_ != other.updatability_) return false;
      }
      if (hasAutoIncrement() != other.hasAutoIncrement()) return false;
      if (hasAutoIncrement()) {
        if (getAutoIncrement()
            != other.getAutoIncrement()) return false;
      }
      if (hasCaseSensitivity() != other.hasCaseSensitivity()) return false;
      if (hasCaseSensitivity()) {
        if (getCaseSensitivity()
            != other.getCaseSensitivity()) return false;
      }
      if (hasSortable() != other.hasSortable()) return false;
      if (hasSortable()) {
        if (getSortable()
            != other.getSortable()) return false;
      }
      if (hasClassName() != other.hasClassName()) return false;
      if (hasClassName()) {
        if (!getClassName()
            .equals(other.getClassName())) return false;
      }
      if (hasIsCurrency() != other.hasIsCurrency()) return false;
      if (hasIsCurrency()) {
        if (getIsCurrency()
            != other.getIsCurrency()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasCatalogName()) {
        hash = (37 * hash) + CATALOG_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogName().hashCode();
      }
      if (hasSchemaName()) {
        hash = (37 * hash) + SCHEMA_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaName().hashCode();
      }
      if (hasTableName()) {
        hash = (37 * hash) + TABLE_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getTableName().hashCode();
      }
      if (hasColumnName()) {
        hash = (37 * hash) + COLUMN_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getColumnName().hashCode();
      }
      if (hasLabel()) {
        hash = (37 * hash) + LABEL_FIELD_NUMBER;
        hash = (53 * hash) + getLabel().hashCode();
      }
      if (hasDataType()) {
        hash = (37 * hash) + DATA_TYPE_FIELD_NUMBER;
        hash = (53 * hash) + getDataType().hashCode();
      }
      if (hasIsNullable()) {
        hash = (37 * hash) + IS_NULLABLE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getIsNullable());
      }
      if (hasPrecision()) {
        hash = (37 * hash) + PRECISION_FIELD_NUMBER;
        hash = (53 * hash) + getPrecision();
      }
      if (hasScale()) {
        hash = (37 * hash) + SCALE_FIELD_NUMBER;
        hash = (53 * hash) + getScale();
      }
      if (hasSigned()) {
        hash = (37 * hash) + SIGNED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSigned());
      }
      if (hasDisplaySize()) {
        hash = (37 * hash) + DISPLAY_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getDisplaySize();
      }
      if (hasIsAliased()) {
        hash = (37 * hash) + IS_ALIASED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getIsAliased());
      }
      if (hasSearchability()) {
        hash = (37 * hash) + SEARCHABILITY_FIELD_NUMBER;
        hash = (53 * hash) + searchability_;
      }
      if (hasUpdatability()) {
        hash = (37 * hash) + UPDATABILITY_FIELD_NUMBER;
        hash = (53 * hash) + updatability_;
      }
      if (hasAutoIncrement()) {
        hash = (37 * hash) + AUTO_INCREMENT_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getAutoIncrement());
      }
      if (hasCaseSensitivity()) {
        hash = (37 * hash) + CASE_SENSITIVITY_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getCaseSensitivity());
      }
      if (hasSortable()) {
        hash = (37 * hash) + SORTABLE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSortable());
      }
      if (hasClassName()) {
        hash = (37 * hash) + CLASS_NAME_FIELD_NUMBER;
        hash = (53 * hash) + getClassName().hashCode();
      }
      if (hasIsCurrency()) {
        hash = (37 * hash) + IS_CURRENCY_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getIsCurrency());
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata 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.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Metadata of a column in query result set
     * </pre>
     *
     * Protobuf type {@code exec.user.ResultColumnMetadata}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.ResultColumnMetadata)
        org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ResultColumnMetadata_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ResultColumnMetadata_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.class, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        catalogName_ = "";
        bitField0_ = (bitField0_ & ~0x00000001);
        schemaName_ = "";
        bitField0_ = (bitField0_ & ~0x00000002);
        tableName_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        columnName_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        label_ = "";
        bitField0_ = (bitField0_ & ~0x00000010);
        dataType_ = "";
        bitField0_ = (bitField0_ & ~0x00000020);
        isNullable_ = false;
        bitField0_ = (bitField0_ & ~0x00000040);
        precision_ = 0;
        bitField0_ = (bitField0_ & ~0x00000080);
        scale_ = 0;
        bitField0_ = (bitField0_ & ~0x00000100);
        signed_ = false;
        bitField0_ = (bitField0_ & ~0x00000200);
        displaySize_ = 0;
        bitField0_ = (bitField0_ & ~0x00000400);
        isAliased_ = false;
        bitField0_ = (bitField0_ & ~0x00000800);
        searchability_ = 0;
        bitField0_ = (bitField0_ & ~0x00001000);
        updatability_ = 0;
        bitField0_ = (bitField0_ & ~0x00002000);
        autoIncrement_ = false;
        bitField0_ = (bitField0_ & ~0x00004000);
        caseSensitivity_ = false;
        bitField0_ = (bitField0_ & ~0x00008000);
        sortable_ = false;
        bitField0_ = (bitField0_ & ~0x00010000);
        className_ = "";
        bitField0_ = (bitField0_ & ~0x00020000);
        isCurrency_ = false;
        bitField0_ = (bitField0_ & ~0x00040000);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ResultColumnMetadata_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata build() {
        org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata buildPartial() {
        org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata result = new org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.catalogName_ = catalogName_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.schemaName_ = schemaName_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.tableName_ = tableName_;
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.columnName_ = columnName_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          to_bitField0_ |= 0x00000010;
        }
        result.label_ = label_;
        if (((from_bitField0_ & 0x00000020) != 0)) {
          to_bitField0_ |= 0x00000020;
        }
        result.dataType_ = dataType_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.isNullable_ = isNullable_;
          to_bitField0_ |= 0x00000040;
        }
        if (((from_bitField0_ & 0x00000080) != 0)) {
          result.precision_ = precision_;
          to_bitField0_ |= 0x00000080;
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          result.scale_ = scale_;
          to_bitField0_ |= 0x00000100;
        }
        if (((from_bitField0_ & 0x00000200) != 0)) {
          result.signed_ = signed_;
          to_bitField0_ |= 0x00000200;
        }
        if (((from_bitField0_ & 0x00000400) != 0)) {
          result.displaySize_ = displaySize_;
          to_bitField0_ |= 0x00000400;
        }
        if (((from_bitField0_ & 0x00000800) != 0)) {
          result.isAliased_ = isAliased_;
          to_bitField0_ |= 0x00000800;
        }
        if (((from_bitField0_ & 0x00001000) != 0)) {
          to_bitField0_ |= 0x00001000;
        }
        result.searchability_ = searchability_;
        if (((from_bitField0_ & 0x00002000) != 0)) {
          to_bitField0_ |= 0x00002000;
        }
        result.updatability_ = updatability_;
        if (((from_bitField0_ & 0x00004000) != 0)) {
          result.autoIncrement_ = autoIncrement_;
          to_bitField0_ |= 0x00004000;
        }
        if (((from_bitField0_ & 0x00008000) != 0)) {
          result.caseSensitivity_ = caseSensitivity_;
          to_bitField0_ |= 0x00008000;
        }
        if (((from_bitField0_ & 0x00010000) != 0)) {
          result.sortable_ = sortable_;
          to_bitField0_ |= 0x00010000;
        }
        if (((from_bitField0_ & 0x00020000) != 0)) {
          to_bitField0_ |= 0x00020000;
        }
        result.className_ = className_;
        if (((from_bitField0_ & 0x00040000) != 0)) {
          result.isCurrency_ = isCurrency_;
          to_bitField0_ |= 0x00040000;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata other) {
        if (other == org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.getDefaultInstance()) return this;
        if (other.hasCatalogName()) {
          bitField0_ |= 0x00000001;
          catalogName_ = other.catalogName_;
          onChanged();
        }
        if (other.hasSchemaName()) {
          bitField0_ |= 0x00000002;
          schemaName_ = other.schemaName_;
          onChanged();
        }
        if (other.hasTableName()) {
          bitField0_ |= 0x00000004;
          tableName_ = other.tableName_;
          onChanged();
        }
        if (other.hasColumnName()) {
          bitField0_ |= 0x00000008;
          columnName_ = other.columnName_;
          onChanged();
        }
        if (other.hasLabel()) {
          bitField0_ |= 0x00000010;
          label_ = other.label_;
          onChanged();
        }
        if (other.hasDataType()) {
          bitField0_ |= 0x00000020;
          dataType_ = other.dataType_;
          onChanged();
        }
        if (other.hasIsNullable()) {
          setIsNullable(other.getIsNullable());
        }
        if (other.hasPrecision()) {
          setPrecision(other.getPrecision());
        }
        if (other.hasScale()) {
          setScale(other.getScale());
        }
        if (other.hasSigned()) {
          setSigned(other.getSigned());
        }
        if (other.hasDisplaySize()) {
          setDisplaySize(other.getDisplaySize());
        }
        if (other.hasIsAliased()) {
          setIsAliased(other.getIsAliased());
        }
        if (other.hasSearchability()) {
          setSearchability(other.getSearchability());
        }
        if (other.hasUpdatability()) {
          setUpdatability(other.getUpdatability());
        }
        if (other.hasAutoIncrement()) {
          setAutoIncrement(other.getAutoIncrement());
        }
        if (other.hasCaseSensitivity()) {
          setCaseSensitivity(other.getCaseSensitivity());
        }
        if (other.hasSortable()) {
          setSortable(other.getSortable());
        }
        if (other.hasClassName()) {
          bitField0_ |= 0x00020000;
          className_ = other.className_;
          onChanged();
        }
        if (other.hasIsCurrency()) {
          setIsCurrency(other.getIsCurrency());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                catalogName_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              case 18: {
                schemaName_ = input.readBytes();
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                tableName_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                columnName_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 42: {
                label_ = input.readBytes();
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 50: {
                dataType_ = input.readBytes();
                bitField0_ |= 0x00000020;
                break;
              } // case 50
              case 56: {
                isNullable_ = input.readBool();
                bitField0_ |= 0x00000040;
                break;
              } // case 56
              case 64: {
                precision_ = input.readInt32();
                bitField0_ |= 0x00000080;
                break;
              } // case 64
              case 72: {
                scale_ = input.readInt32();
                bitField0_ |= 0x00000100;
                break;
              } // case 72
              case 80: {
                signed_ = input.readBool();
                bitField0_ |= 0x00000200;
                break;
              } // case 80
              case 88: {
                displaySize_ = input.readInt32();
                bitField0_ |= 0x00000400;
                break;
              } // case 88
              case 96: {
                isAliased_ = input.readBool();
                bitField0_ |= 0x00000800;
                break;
              } // case 96
              case 104: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.ColumnSearchability tmpValue =
                    org.apache.drill.exec.proto.UserProtos.ColumnSearchability.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(13, tmpRaw);
                } else {
                  searchability_ = tmpRaw;
                  bitField0_ |= 0x00001000;
                }
                break;
              } // case 104
              case 112: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.ColumnUpdatability tmpValue =
                    org.apache.drill.exec.proto.UserProtos.ColumnUpdatability.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(14, tmpRaw);
                } else {
                  updatability_ = tmpRaw;
                  bitField0_ |= 0x00002000;
                }
                break;
              } // case 112
              case 120: {
                autoIncrement_ = input.readBool();
                bitField0_ |= 0x00004000;
                break;
              } // case 120
              case 128: {
                caseSensitivity_ = input.readBool();
                bitField0_ |= 0x00008000;
                break;
              } // case 128
              case 136: {
                sortable_ = input.readBool();
                bitField0_ |= 0x00010000;
                break;
              } // case 136
              case 146: {
                className_ = input.readBytes();
                bitField0_ |= 0x00020000;
                break;
              } // case 146
              case 160: {
                isCurrency_ = input.readBool();
                bitField0_ |= 0x00040000;
                break;
              } // case 160
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.lang.Object catalogName_ = "";
      /**
       * <pre>
       * Designated column's catalog name. Empty string if not applicable.
       * Defaults to "DRILL" as drill has only one catalog.
       * </pre>
       *
       * <code>optional string catalog_name = 1;</code>
       * @return Whether the catalogName field is set.
       */
      public boolean hasCatalogName() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * Designated column's catalog name. Empty string if not applicable.
       * Defaults to "DRILL" as drill has only one catalog.
       * </pre>
       *
       * <code>optional string catalog_name = 1;</code>
       * @return The catalogName.
       */
      public java.lang.String getCatalogName() {
        java.lang.Object ref = catalogName_;
        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()) {
            catalogName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Designated column's catalog name. Empty string if not applicable.
       * Defaults to "DRILL" as drill has only one catalog.
       * </pre>
       *
       * <code>optional string catalog_name = 1;</code>
       * @return The bytes for catalogName.
       */
      public com.google.protobuf.ByteString
          getCatalogNameBytes() {
        java.lang.Object ref = catalogName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          catalogName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Designated column's catalog name. Empty string if not applicable.
       * Defaults to "DRILL" as drill has only one catalog.
       * </pre>
       *
       * <code>optional string catalog_name = 1;</code>
       * @param value The catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Designated column's catalog name. Empty string if not applicable.
       * Defaults to "DRILL" as drill has only one catalog.
       * </pre>
       *
       * <code>optional string catalog_name = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogName() {
        bitField0_ = (bitField0_ & ~0x00000001);
        catalogName_ = getDefaultInstance().getCatalogName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Designated column's catalog name. Empty string if not applicable.
       * Defaults to "DRILL" as drill has only one catalog.
       * </pre>
       *
       * <code>optional string catalog_name = 1;</code>
       * @param value The bytes for catalogName to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        catalogName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object schemaName_ = "";
      /**
       * <pre>
       * Designated column's schema name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
       * is lost. If we derive the schema from plan, we may get the right value.
       * </pre>
       *
       * <code>optional string schema_name = 2;</code>
       * @return Whether the schemaName field is set.
       */
      public boolean hasSchemaName() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * Designated column's schema name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
       * is lost. If we derive the schema from plan, we may get the right value.
       * </pre>
       *
       * <code>optional string schema_name = 2;</code>
       * @return The schemaName.
       */
      public java.lang.String getSchemaName() {
        java.lang.Object ref = schemaName_;
        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()) {
            schemaName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Designated column's schema name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
       * is lost. If we derive the schema from plan, we may get the right value.
       * </pre>
       *
       * <code>optional string schema_name = 2;</code>
       * @return The bytes for schemaName.
       */
      public com.google.protobuf.ByteString
          getSchemaNameBytes() {
        java.lang.Object ref = schemaName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          schemaName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Designated column's schema name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
       * is lost. If we derive the schema from plan, we may get the right value.
       * </pre>
       *
       * <code>optional string schema_name = 2;</code>
       * @param value The schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Designated column's schema name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
       * is lost. If we derive the schema from plan, we may get the right value.
       * </pre>
       *
       * <code>optional string schema_name = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearSchemaName() {
        bitField0_ = (bitField0_ & ~0x00000002);
        schemaName_ = getDefaultInstance().getSchemaName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Designated column's schema name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and schema info
       * is lost. If we derive the schema from plan, we may get the right value.
       * </pre>
       *
       * <code>optional string schema_name = 2;</code>
       * @param value The bytes for schemaName to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000002;
        schemaName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object tableName_ = "";
      /**
       * <pre>
       * Designated column's table name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and table info
       * is lost. If we derive the schema from query plan, we may get the right value.
       * </pre>
       *
       * <code>optional string table_name = 3;</code>
       * @return Whether the tableName field is set.
       */
      public boolean hasTableName() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * Designated column's table name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and table info
       * is lost. If we derive the schema from query plan, we may get the right value.
       * </pre>
       *
       * <code>optional string table_name = 3;</code>
       * @return The tableName.
       */
      public java.lang.String getTableName() {
        java.lang.Object ref = tableName_;
        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()) {
            tableName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Designated column's table name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and table info
       * is lost. If we derive the schema from query plan, we may get the right value.
       * </pre>
       *
       * <code>optional string table_name = 3;</code>
       * @return The bytes for tableName.
       */
      public com.google.protobuf.ByteString
          getTableNameBytes() {
        java.lang.Object ref = tableName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          tableName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Designated column's table name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and table info
       * is lost. If we derive the schema from query plan, we may get the right value.
       * </pre>
       *
       * <code>optional string table_name = 3;</code>
       * @param value The tableName to set.
       * @return This builder for chaining.
       */
      public Builder setTableName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tableName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Designated column's table name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and table info
       * is lost. If we derive the schema from query plan, we may get the right value.
       * </pre>
       *
       * <code>optional string table_name = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearTableName() {
        bitField0_ = (bitField0_ & ~0x00000004);
        tableName_ = getDefaultInstance().getTableName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Designated column's table name. Not set if not applicable. Initial implementation
       * defaults to no value as we use LIMIT 0 queries to get the schema and table info
       * is lost. If we derive the schema from query plan, we may get the right value.
       * </pre>
       *
       * <code>optional string table_name = 3;</code>
       * @param value The bytes for tableName to set.
       * @return This builder for chaining.
       */
      public Builder setTableNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        tableName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object columnName_ = "";
      /**
       * <pre>
       * column name
       * </pre>
       *
       * <code>optional string column_name = 4;</code>
       * @return Whether the columnName field is set.
       */
      public boolean hasColumnName() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * column name
       * </pre>
       *
       * <code>optional string column_name = 4;</code>
       * @return The columnName.
       */
      public java.lang.String getColumnName() {
        java.lang.Object ref = columnName_;
        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()) {
            columnName_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * column name
       * </pre>
       *
       * <code>optional string column_name = 4;</code>
       * @return The bytes for columnName.
       */
      public com.google.protobuf.ByteString
          getColumnNameBytes() {
        java.lang.Object ref = columnName_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          columnName_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * column name
       * </pre>
       *
       * <code>optional string column_name = 4;</code>
       * @param value The columnName to set.
       * @return This builder for chaining.
       */
      public Builder setColumnName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        columnName_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * column name
       * </pre>
       *
       * <code>optional string column_name = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearColumnName() {
        bitField0_ = (bitField0_ & ~0x00000008);
        columnName_ = getDefaultInstance().getColumnName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * column name
       * </pre>
       *
       * <code>optional string column_name = 4;</code>
       * @param value The bytes for columnName to set.
       * @return This builder for chaining.
       */
      public Builder setColumnNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        columnName_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object label_ = "";
      /**
       * <pre>
       * Column label name for display or print purposes.
       * Ex. a column named "empName" might be labeled as "Employee Name".
       * </pre>
       *
       * <code>optional string label = 5;</code>
       * @return Whether the label field is set.
       */
      public boolean hasLabel() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <pre>
       * Column label name for display or print purposes.
       * Ex. a column named "empName" might be labeled as "Employee Name".
       * </pre>
       *
       * <code>optional string label = 5;</code>
       * @return The label.
       */
      public java.lang.String getLabel() {
        java.lang.Object ref = label_;
        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()) {
            label_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Column label name for display or print purposes.
       * Ex. a column named "empName" might be labeled as "Employee Name".
       * </pre>
       *
       * <code>optional string label = 5;</code>
       * @return The bytes for label.
       */
      public com.google.protobuf.ByteString
          getLabelBytes() {
        java.lang.Object ref = label_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          label_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Column label name for display or print purposes.
       * Ex. a column named "empName" might be labeled as "Employee Name".
       * </pre>
       *
       * <code>optional string label = 5;</code>
       * @param value The label to set.
       * @return This builder for chaining.
       */
      public Builder setLabel(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        label_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Column label name for display or print purposes.
       * Ex. a column named "empName" might be labeled as "Employee Name".
       * </pre>
       *
       * <code>optional string label = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearLabel() {
        bitField0_ = (bitField0_ & ~0x00000010);
        label_ = getDefaultInstance().getLabel();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Column label name for display or print purposes.
       * Ex. a column named "empName" might be labeled as "Employee Name".
       * </pre>
       *
       * <code>optional string label = 5;</code>
       * @param value The bytes for label to set.
       * @return This builder for chaining.
       */
      public Builder setLabelBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        label_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object dataType_ = "";
      /**
       * <pre>
       * Data type in string format. Value is SQL standard type.
       * </pre>
       *
       * <code>optional string data_type = 6;</code>
       * @return Whether the dataType field is set.
       */
      public boolean hasDataType() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <pre>
       * Data type in string format. Value is SQL standard type.
       * </pre>
       *
       * <code>optional string data_type = 6;</code>
       * @return The dataType.
       */
      public java.lang.String getDataType() {
        java.lang.Object ref = dataType_;
        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()) {
            dataType_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Data type in string format. Value is SQL standard type.
       * </pre>
       *
       * <code>optional string data_type = 6;</code>
       * @return The bytes for dataType.
       */
      public com.google.protobuf.ByteString
          getDataTypeBytes() {
        java.lang.Object ref = dataType_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          dataType_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Data type in string format. Value is SQL standard type.
       * </pre>
       *
       * <code>optional string data_type = 6;</code>
       * @param value The dataType to set.
       * @return This builder for chaining.
       */
      public Builder setDataType(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        dataType_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Data type in string format. Value is SQL standard type.
       * </pre>
       *
       * <code>optional string data_type = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearDataType() {
        bitField0_ = (bitField0_ & ~0x00000020);
        dataType_ = getDefaultInstance().getDataType();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Data type in string format. Value is SQL standard type.
       * </pre>
       *
       * <code>optional string data_type = 6;</code>
       * @param value The bytes for dataType to set.
       * @return This builder for chaining.
       */
      public Builder setDataTypeBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000020;
        dataType_ = value;
        onChanged();
        return this;
      }

      private boolean isNullable_ ;
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @return Whether the isNullable field is set.
       */
      @java.lang.Override
      public boolean hasIsNullable() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @return The isNullable.
       */
      @java.lang.Override
      public boolean getIsNullable() {
        return isNullable_;
      }
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @param value The isNullable to set.
       * @return This builder for chaining.
       */
      public Builder setIsNullable(boolean value) {
        bitField0_ |= 0x00000040;
        isNullable_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bool is_nullable = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsNullable() {
        bitField0_ = (bitField0_ & ~0x00000040);
        isNullable_ = false;
        onChanged();
        return this;
      }

      private int precision_ ;
      /**
       * <pre>
       * For numeric data, this is the maximum precision.
       * For character data, this is the length in characters.
       * For datetime datatypes, this is the length in characters of the String representation
       *    (assuming the maximum allowed precision of the fractional seconds component).
       * For binary data, this is the length in bytes.
       * For all other types 0 is returned where the column size is not applicable.
       * </pre>
       *
       * <code>optional int32 precision = 8;</code>
       * @return Whether the precision field is set.
       */
      @java.lang.Override
      public boolean hasPrecision() {
        return ((bitField0_ & 0x00000080) != 0);
      }
      /**
       * <pre>
       * For numeric data, this is the maximum precision.
       * For character data, this is the length in characters.
       * For datetime datatypes, this is the length in characters of the String representation
       *    (assuming the maximum allowed precision of the fractional seconds component).
       * For binary data, this is the length in bytes.
       * For all other types 0 is returned where the column size is not applicable.
       * </pre>
       *
       * <code>optional int32 precision = 8;</code>
       * @return The precision.
       */
      @java.lang.Override
      public int getPrecision() {
        return precision_;
      }
      /**
       * <pre>
       * For numeric data, this is the maximum precision.
       * For character data, this is the length in characters.
       * For datetime datatypes, this is the length in characters of the String representation
       *    (assuming the maximum allowed precision of the fractional seconds component).
       * For binary data, this is the length in bytes.
       * For all other types 0 is returned where the column size is not applicable.
       * </pre>
       *
       * <code>optional int32 precision = 8;</code>
       * @param value The precision to set.
       * @return This builder for chaining.
       */
      public Builder setPrecision(int value) {
        bitField0_ |= 0x00000080;
        precision_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * For numeric data, this is the maximum precision.
       * For character data, this is the length in characters.
       * For datetime datatypes, this is the length in characters of the String representation
       *    (assuming the maximum allowed precision of the fractional seconds component).
       * For binary data, this is the length in bytes.
       * For all other types 0 is returned where the column size is not applicable.
       * </pre>
       *
       * <code>optional int32 precision = 8;</code>
       * @return This builder for chaining.
       */
      public Builder clearPrecision() {
        bitField0_ = (bitField0_ & ~0x00000080);
        precision_ = 0;
        onChanged();
        return this;
      }

      private int scale_ ;
      /**
       * <pre>
       * Column's number of digits to right of the decimal point.
       * 0 is returned for types where the scale is not applicable
       * </pre>
       *
       * <code>optional int32 scale = 9;</code>
       * @return Whether the scale field is set.
       */
      @java.lang.Override
      public boolean hasScale() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <pre>
       * Column's number of digits to right of the decimal point.
       * 0 is returned for types where the scale is not applicable
       * </pre>
       *
       * <code>optional int32 scale = 9;</code>
       * @return The scale.
       */
      @java.lang.Override
      public int getScale() {
        return scale_;
      }
      /**
       * <pre>
       * Column's number of digits to right of the decimal point.
       * 0 is returned for types where the scale is not applicable
       * </pre>
       *
       * <code>optional int32 scale = 9;</code>
       * @param value The scale to set.
       * @return This builder for chaining.
       */
      public Builder setScale(int value) {
        bitField0_ |= 0x00000100;
        scale_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Column's number of digits to right of the decimal point.
       * 0 is returned for types where the scale is not applicable
       * </pre>
       *
       * <code>optional int32 scale = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearScale() {
        bitField0_ = (bitField0_ & ~0x00000100);
        scale_ = 0;
        onChanged();
        return this;
      }

      private boolean signed_ ;
      /**
       * <pre>
       * Indicates whether values in the designated column are signed numbers.
       * </pre>
       *
       * <code>optional bool signed = 10;</code>
       * @return Whether the signed field is set.
       */
      @java.lang.Override
      public boolean hasSigned() {
        return ((bitField0_ & 0x00000200) != 0);
      }
      /**
       * <pre>
       * Indicates whether values in the designated column are signed numbers.
       * </pre>
       *
       * <code>optional bool signed = 10;</code>
       * @return The signed.
       */
      @java.lang.Override
      public boolean getSigned() {
        return signed_;
      }
      /**
       * <pre>
       * Indicates whether values in the designated column are signed numbers.
       * </pre>
       *
       * <code>optional bool signed = 10;</code>
       * @param value The signed to set.
       * @return This builder for chaining.
       */
      public Builder setSigned(boolean value) {
        bitField0_ |= 0x00000200;
        signed_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Indicates whether values in the designated column are signed numbers.
       * </pre>
       *
       * <code>optional bool signed = 10;</code>
       * @return This builder for chaining.
       */
      public Builder clearSigned() {
        bitField0_ = (bitField0_ & ~0x00000200);
        signed_ = false;
        onChanged();
        return this;
      }

      private int displaySize_ ;
      /**
       * <pre>
       * Maximum number of characters required to display data from the column.
       * </pre>
       *
       * <code>optional int32 display_size = 11;</code>
       * @return Whether the displaySize field is set.
       */
      @java.lang.Override
      public boolean hasDisplaySize() {
        return ((bitField0_ & 0x00000400) != 0);
      }
      /**
       * <pre>
       * Maximum number of characters required to display data from the column.
       * </pre>
       *
       * <code>optional int32 display_size = 11;</code>
       * @return The displaySize.
       */
      @java.lang.Override
      public int getDisplaySize() {
        return displaySize_;
      }
      /**
       * <pre>
       * Maximum number of characters required to display data from the column.
       * </pre>
       *
       * <code>optional int32 display_size = 11;</code>
       * @param value The displaySize to set.
       * @return This builder for chaining.
       */
      public Builder setDisplaySize(int value) {
        bitField0_ |= 0x00000400;
        displaySize_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of characters required to display data from the column.
       * </pre>
       *
       * <code>optional int32 display_size = 11;</code>
       * @return This builder for chaining.
       */
      public Builder clearDisplaySize() {
        bitField0_ = (bitField0_ & ~0x00000400);
        displaySize_ = 0;
        onChanged();
        return this;
      }

      private boolean isAliased_ ;
      /**
       * <pre>
       * Is the column an aliased column. Initial implementation defaults to
       * true as we derive schema from LIMIT 0 query and not the query plan.
       * </pre>
       *
       * <code>optional bool is_aliased = 12;</code>
       * @return Whether the isAliased field is set.
       */
      @java.lang.Override
      public boolean hasIsAliased() {
        return ((bitField0_ & 0x00000800) != 0);
      }
      /**
       * <pre>
       * Is the column an aliased column. Initial implementation defaults to
       * true as we derive schema from LIMIT 0 query and not the query plan.
       * </pre>
       *
       * <code>optional bool is_aliased = 12;</code>
       * @return The isAliased.
       */
      @java.lang.Override
      public boolean getIsAliased() {
        return isAliased_;
      }
      /**
       * <pre>
       * Is the column an aliased column. Initial implementation defaults to
       * true as we derive schema from LIMIT 0 query and not the query plan.
       * </pre>
       *
       * <code>optional bool is_aliased = 12;</code>
       * @param value The isAliased to set.
       * @return This builder for chaining.
       */
      public Builder setIsAliased(boolean value) {
        bitField0_ |= 0x00000800;
        isAliased_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Is the column an aliased column. Initial implementation defaults to
       * true as we derive schema from LIMIT 0 query and not the query plan.
       * </pre>
       *
       * <code>optional bool is_aliased = 12;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsAliased() {
        bitField0_ = (bitField0_ & ~0x00000800);
        isAliased_ = false;
        onChanged();
        return this;
      }

      private int searchability_ = 0;
      /**
       * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
       * @return Whether the searchability field is set.
       */
      @java.lang.Override public boolean hasSearchability() {
        return ((bitField0_ & 0x00001000) != 0);
      }
      /**
       * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
       * @return The searchability.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ColumnSearchability getSearchability() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.ColumnSearchability result = org.apache.drill.exec.proto.UserProtos.ColumnSearchability.valueOf(searchability_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.ColumnSearchability.UNKNOWN_SEARCHABILITY : result;
      }
      /**
       * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
       * @param value The searchability to set.
       * @return This builder for chaining.
       */
      public Builder setSearchability(org.apache.drill.exec.proto.UserProtos.ColumnSearchability value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00001000;
        searchability_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.ColumnSearchability searchability = 13;</code>
       * @return This builder for chaining.
       */
      public Builder clearSearchability() {
        bitField0_ = (bitField0_ & ~0x00001000);
        searchability_ = 0;
        onChanged();
        return this;
      }

      private int updatability_ = 0;
      /**
       * <pre>
       * Defaults to READ_ONLY
       * </pre>
       *
       * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
       * @return Whether the updatability field is set.
       */
      @java.lang.Override public boolean hasUpdatability() {
        return ((bitField0_ & 0x00002000) != 0);
      }
      /**
       * <pre>
       * Defaults to READ_ONLY
       * </pre>
       *
       * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
       * @return The updatability.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ColumnUpdatability getUpdatability() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.ColumnUpdatability result = org.apache.drill.exec.proto.UserProtos.ColumnUpdatability.valueOf(updatability_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.ColumnUpdatability.UNKNOWN_UPDATABILITY : result;
      }
      /**
       * <pre>
       * Defaults to READ_ONLY
       * </pre>
       *
       * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
       * @param value The updatability to set.
       * @return This builder for chaining.
       */
      public Builder setUpdatability(org.apache.drill.exec.proto.UserProtos.ColumnUpdatability value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00002000;
        updatability_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Defaults to READ_ONLY
       * </pre>
       *
       * <code>optional .exec.user.ColumnUpdatability updatability = 14;</code>
       * @return This builder for chaining.
       */
      public Builder clearUpdatability() {
        bitField0_ = (bitField0_ & ~0x00002000);
        updatability_ = 0;
        onChanged();
        return this;
      }

      private boolean autoIncrement_ ;
      /**
       * <pre>
       * whether the designated column is automatically incremented.
       * </pre>
       *
       * <code>optional bool auto_increment = 15;</code>
       * @return Whether the autoIncrement field is set.
       */
      @java.lang.Override
      public boolean hasAutoIncrement() {
        return ((bitField0_ & 0x00004000) != 0);
      }
      /**
       * <pre>
       * whether the designated column is automatically incremented.
       * </pre>
       *
       * <code>optional bool auto_increment = 15;</code>
       * @return The autoIncrement.
       */
      @java.lang.Override
      public boolean getAutoIncrement() {
        return autoIncrement_;
      }
      /**
       * <pre>
       * whether the designated column is automatically incremented.
       * </pre>
       *
       * <code>optional bool auto_increment = 15;</code>
       * @param value The autoIncrement to set.
       * @return This builder for chaining.
       */
      public Builder setAutoIncrement(boolean value) {
        bitField0_ |= 0x00004000;
        autoIncrement_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * whether the designated column is automatically incremented.
       * </pre>
       *
       * <code>optional bool auto_increment = 15;</code>
       * @return This builder for chaining.
       */
      public Builder clearAutoIncrement() {
        bitField0_ = (bitField0_ & ~0x00004000);
        autoIncrement_ = false;
        onChanged();
        return this;
      }

      private boolean caseSensitivity_ ;
      /**
       * <pre>
       * Whether column's case matters for collations and comparisons. Defaults to true.
       * </pre>
       *
       * <code>optional bool case_sensitivity = 16;</code>
       * @return Whether the caseSensitivity field is set.
       */
      @java.lang.Override
      public boolean hasCaseSensitivity() {
        return ((bitField0_ & 0x00008000) != 0);
      }
      /**
       * <pre>
       * Whether column's case matters for collations and comparisons. Defaults to true.
       * </pre>
       *
       * <code>optional bool case_sensitivity = 16;</code>
       * @return The caseSensitivity.
       */
      @java.lang.Override
      public boolean getCaseSensitivity() {
        return caseSensitivity_;
      }
      /**
       * <pre>
       * Whether column's case matters for collations and comparisons. Defaults to true.
       * </pre>
       *
       * <code>optional bool case_sensitivity = 16;</code>
       * @param value The caseSensitivity to set.
       * @return This builder for chaining.
       */
      public Builder setCaseSensitivity(boolean value) {
        bitField0_ |= 0x00008000;
        caseSensitivity_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Whether column's case matters for collations and comparisons. Defaults to true.
       * </pre>
       *
       * <code>optional bool case_sensitivity = 16;</code>
       * @return This builder for chaining.
       */
      public Builder clearCaseSensitivity() {
        bitField0_ = (bitField0_ & ~0x00008000);
        caseSensitivity_ = false;
        onChanged();
        return this;
      }

      private boolean sortable_ ;
      /**
       * <pre>
       * whether the column can be used in ORDER BY clause
       * </pre>
       *
       * <code>optional bool sortable = 17;</code>
       * @return Whether the sortable field is set.
       */
      @java.lang.Override
      public boolean hasSortable() {
        return ((bitField0_ & 0x00010000) != 0);
      }
      /**
       * <pre>
       * whether the column can be used in ORDER BY clause
       * </pre>
       *
       * <code>optional bool sortable = 17;</code>
       * @return The sortable.
       */
      @java.lang.Override
      public boolean getSortable() {
        return sortable_;
      }
      /**
       * <pre>
       * whether the column can be used in ORDER BY clause
       * </pre>
       *
       * <code>optional bool sortable = 17;</code>
       * @param value The sortable to set.
       * @return This builder for chaining.
       */
      public Builder setSortable(boolean value) {
        bitField0_ |= 0x00010000;
        sortable_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * whether the column can be used in ORDER BY clause
       * </pre>
       *
       * <code>optional bool sortable = 17;</code>
       * @return This builder for chaining.
       */
      public Builder clearSortable() {
        bitField0_ = (bitField0_ & ~0x00010000);
        sortable_ = false;
        onChanged();
        return this;
      }

      private java.lang.Object className_ = "";
      /**
       * <pre>
       * A fully-qualified name of the Java class whose instances are created
       * if the method ResultSet.getObject is called to retrieve
       * a value from the column. Applicable only to JDBC clients.
       * </pre>
       *
       * <code>optional string class_name = 18;</code>
       * @return Whether the className field is set.
       */
      public boolean hasClassName() {
        return ((bitField0_ & 0x00020000) != 0);
      }
      /**
       * <pre>
       * A fully-qualified name of the Java class whose instances are created
       * if the method ResultSet.getObject is called to retrieve
       * a value from the column. Applicable only to JDBC clients.
       * </pre>
       *
       * <code>optional string class_name = 18;</code>
       * @return The className.
       */
      public java.lang.String getClassName() {
        java.lang.Object ref = className_;
        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()) {
            className_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * A fully-qualified name of the Java class whose instances are created
       * if the method ResultSet.getObject is called to retrieve
       * a value from the column. Applicable only to JDBC clients.
       * </pre>
       *
       * <code>optional string class_name = 18;</code>
       * @return The bytes for className.
       */
      public com.google.protobuf.ByteString
          getClassNameBytes() {
        java.lang.Object ref = className_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          className_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * A fully-qualified name of the Java class whose instances are created
       * if the method ResultSet.getObject is called to retrieve
       * a value from the column. Applicable only to JDBC clients.
       * </pre>
       *
       * <code>optional string class_name = 18;</code>
       * @param value The className to set.
       * @return This builder for chaining.
       */
      public Builder setClassName(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00020000;
        className_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A fully-qualified name of the Java class whose instances are created
       * if the method ResultSet.getObject is called to retrieve
       * a value from the column. Applicable only to JDBC clients.
       * </pre>
       *
       * <code>optional string class_name = 18;</code>
       * @return This builder for chaining.
       */
      public Builder clearClassName() {
        bitField0_ = (bitField0_ & ~0x00020000);
        className_ = getDefaultInstance().getClassName();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * A fully-qualified name of the Java class whose instances are created
       * if the method ResultSet.getObject is called to retrieve
       * a value from the column. Applicable only to JDBC clients.
       * </pre>
       *
       * <code>optional string class_name = 18;</code>
       * @param value The bytes for className to set.
       * @return This builder for chaining.
       */
      public Builder setClassNameBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00020000;
        className_ = value;
        onChanged();
        return this;
      }

      private boolean isCurrency_ ;
      /**
       * <pre>
       * Is the data type a currency type? For JDBC only.
       * </pre>
       *
       * <code>optional bool is_currency = 20;</code>
       * @return Whether the isCurrency field is set.
       */
      @java.lang.Override
      public boolean hasIsCurrency() {
        return ((bitField0_ & 0x00040000) != 0);
      }
      /**
       * <pre>
       * Is the data type a currency type? For JDBC only.
       * </pre>
       *
       * <code>optional bool is_currency = 20;</code>
       * @return The isCurrency.
       */
      @java.lang.Override
      public boolean getIsCurrency() {
        return isCurrency_;
      }
      /**
       * <pre>
       * Is the data type a currency type? For JDBC only.
       * </pre>
       *
       * <code>optional bool is_currency = 20;</code>
       * @param value The isCurrency to set.
       * @return This builder for chaining.
       */
      public Builder setIsCurrency(boolean value) {
        bitField0_ |= 0x00040000;
        isCurrency_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Is the data type a currency type? For JDBC only.
       * </pre>
       *
       * <code>optional bool is_currency = 20;</code>
       * @return This builder for chaining.
       */
      public Builder clearIsCurrency() {
        bitField0_ = (bitField0_ & ~0x00040000);
        isCurrency_ = false;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.ResultColumnMetadata)
    }

    // @@protoc_insertion_point(class_scope:exec.user.ResultColumnMetadata)
    private static final org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata();
    }

    public static org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ResultColumnMetadata>
        PARSER = new com.google.protobuf.AbstractParser<ResultColumnMetadata>() {
      @java.lang.Override
      public ResultColumnMetadata parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<ResultColumnMetadata> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<ResultColumnMetadata> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface PreparedStatementHandleOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.PreparedStatementHandle)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional bytes server_info = 1;</code>
     * @return Whether the serverInfo field is set.
     */
    boolean hasServerInfo();
    /**
     * <code>optional bytes server_info = 1;</code>
     * @return The serverInfo.
     */
    com.google.protobuf.ByteString getServerInfo();
  }
  /**
   * <pre>
   * Server state of prepared statement. Contents are opaque to
   * client. Client just need to submit this object in RunQuery to
   * the prepared statement.
   * </pre>
   *
   * Protobuf type {@code exec.user.PreparedStatementHandle}
   */
  public static final class PreparedStatementHandle extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.PreparedStatementHandle)
      PreparedStatementHandleOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use PreparedStatementHandle.newBuilder() to construct.
    private PreparedStatementHandle(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private PreparedStatementHandle() {
      serverInfo_ = com.google.protobuf.ByteString.EMPTY;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new PreparedStatementHandle();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatementHandle_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatementHandle_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.class, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder.class);
    }

    private int bitField0_;
    public static final int SERVER_INFO_FIELD_NUMBER = 1;
    private com.google.protobuf.ByteString serverInfo_;
    /**
     * <code>optional bytes server_info = 1;</code>
     * @return Whether the serverInfo field is set.
     */
    @java.lang.Override
    public boolean hasServerInfo() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional bytes server_info = 1;</code>
     * @return The serverInfo.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString getServerInfo() {
      return serverInfo_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeBytes(1, serverInfo_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBytesSize(1, serverInfo_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle other = (org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle) obj;

      if (hasServerInfo() != other.hasServerInfo()) return false;
      if (hasServerInfo()) {
        if (!getServerInfo()
            .equals(other.getServerInfo())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasServerInfo()) {
        hash = (37 * hash) + SERVER_INFO_FIELD_NUMBER;
        hash = (53 * hash) + getServerInfo().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle 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.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Server state of prepared statement. Contents are opaque to
     * client. Client just need to submit this object in RunQuery to
     * the prepared statement.
     * </pre>
     *
     * Protobuf type {@code exec.user.PreparedStatementHandle}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.PreparedStatementHandle)
        org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatementHandle_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatementHandle_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.class, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        serverInfo_ = com.google.protobuf.ByteString.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000001);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatementHandle_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle build() {
        org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle buildPartial() {
        org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle result = new org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.serverInfo_ = serverInfo_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle other) {
        if (other == org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance()) return this;
        if (other.hasServerInfo()) {
          setServerInfo(other.getServerInfo());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                serverInfo_ = input.readBytes();
                bitField0_ |= 0x00000001;
                break;
              } // case 10
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private com.google.protobuf.ByteString serverInfo_ = com.google.protobuf.ByteString.EMPTY;
      /**
       * <code>optional bytes server_info = 1;</code>
       * @return Whether the serverInfo field is set.
       */
      @java.lang.Override
      public boolean hasServerInfo() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional bytes server_info = 1;</code>
       * @return The serverInfo.
       */
      @java.lang.Override
      public com.google.protobuf.ByteString getServerInfo() {
        return serverInfo_;
      }
      /**
       * <code>optional bytes server_info = 1;</code>
       * @param value The serverInfo to set.
       * @return This builder for chaining.
       */
      public Builder setServerInfo(com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000001;
        serverInfo_ = value;
        onChanged();
        return this;
      }
      /**
       * <code>optional bytes server_info = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearServerInfo() {
        bitField0_ = (bitField0_ & ~0x00000001);
        serverInfo_ = getDefaultInstance().getServerInfo();
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.PreparedStatementHandle)
    }

    // @@protoc_insertion_point(class_scope:exec.user.PreparedStatementHandle)
    private static final org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle();
    }

    public static org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<PreparedStatementHandle>
        PARSER = new com.google.protobuf.AbstractParser<PreparedStatementHandle>() {
      @java.lang.Override
      public PreparedStatementHandle parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<PreparedStatementHandle> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<PreparedStatementHandle> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface PreparedStatementOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.PreparedStatement)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata> 
        getColumnsList();
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata getColumns(int index);
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    int getColumnsCount();
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder> 
        getColumnsOrBuilderList();
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder getColumnsOrBuilder(
        int index);

    /**
     * <pre>
     * In order to execute the prepared statement,
     * clients need to submit this object in RunQuery message.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
     * @return Whether the serverHandle field is set.
     */
    boolean hasServerHandle();
    /**
     * <pre>
     * In order to execute the prepared statement,
     * clients need to submit this object in RunQuery message.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
     * @return The serverHandle.
     */
    org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getServerHandle();
    /**
     * <pre>
     * In order to execute the prepared statement,
     * clients need to submit this object in RunQuery message.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder getServerHandleOrBuilder();
  }
  /**
   * <pre>
   * Prepared statement. It contains the query metadata and handle to prepared
   * statement state on server.
   * </pre>
   *
   * Protobuf type {@code exec.user.PreparedStatement}
   */
  public static final class PreparedStatement extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.PreparedStatement)
      PreparedStatementOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use PreparedStatement.newBuilder() to construct.
    private PreparedStatement(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private PreparedStatement() {
      columns_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new PreparedStatement();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatement_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatement_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.PreparedStatement.class, org.apache.drill.exec.proto.UserProtos.PreparedStatement.Builder.class);
    }

    private int bitField0_;
    public static final int COLUMNS_FIELD_NUMBER = 1;
    private java.util.List<org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata> columns_;
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata> getColumnsList() {
      return columns_;
    }
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder> 
        getColumnsOrBuilderList() {
      return columns_;
    }
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    @java.lang.Override
    public int getColumnsCount() {
      return columns_.size();
    }
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata getColumns(int index) {
      return columns_.get(index);
    }
    /**
     * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder getColumnsOrBuilder(
        int index) {
      return columns_.get(index);
    }

    public static final int SERVER_HANDLE_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle serverHandle_;
    /**
     * <pre>
     * In order to execute the prepared statement,
     * clients need to submit this object in RunQuery message.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
     * @return Whether the serverHandle field is set.
     */
    @java.lang.Override
    public boolean hasServerHandle() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * In order to execute the prepared statement,
     * clients need to submit this object in RunQuery message.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
     * @return The serverHandle.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getServerHandle() {
      return serverHandle_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : serverHandle_;
    }
    /**
     * <pre>
     * In order to execute the prepared statement,
     * clients need to submit this object in RunQuery message.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder getServerHandleOrBuilder() {
      return serverHandle_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : serverHandle_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      for (int i = 0; i < columns_.size(); i++) {
        output.writeMessage(1, columns_.get(i));
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeMessage(2, getServerHandle());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      for (int i = 0; i < columns_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(1, columns_.get(i));
      }
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getServerHandle());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.PreparedStatement)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.PreparedStatement other = (org.apache.drill.exec.proto.UserProtos.PreparedStatement) obj;

      if (!getColumnsList()
          .equals(other.getColumnsList())) return false;
      if (hasServerHandle() != other.hasServerHandle()) return false;
      if (hasServerHandle()) {
        if (!getServerHandle()
            .equals(other.getServerHandle())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (getColumnsCount() > 0) {
        hash = (37 * hash) + COLUMNS_FIELD_NUMBER;
        hash = (53 * hash) + getColumnsList().hashCode();
      }
      if (hasServerHandle()) {
        hash = (37 * hash) + SERVER_HANDLE_FIELD_NUMBER;
        hash = (53 * hash) + getServerHandle().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement 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.drill.exec.proto.UserProtos.PreparedStatement parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.PreparedStatement prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Prepared statement. It contains the query metadata and handle to prepared
     * statement state on server.
     * </pre>
     *
     * Protobuf type {@code exec.user.PreparedStatement}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.PreparedStatement)
        org.apache.drill.exec.proto.UserProtos.PreparedStatementOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatement_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatement_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.PreparedStatement.class, org.apache.drill.exec.proto.UserProtos.PreparedStatement.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.PreparedStatement.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getColumnsFieldBuilder();
          getServerHandleFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        if (columnsBuilder_ == null) {
          columns_ = java.util.Collections.emptyList();
        } else {
          columns_ = null;
          columnsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000001);
        if (serverHandleBuilder_ == null) {
          serverHandle_ = null;
        } else {
          serverHandleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_PreparedStatement_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.PreparedStatement getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.PreparedStatement.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.PreparedStatement build() {
        org.apache.drill.exec.proto.UserProtos.PreparedStatement result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.PreparedStatement buildPartial() {
        org.apache.drill.exec.proto.UserProtos.PreparedStatement result = new org.apache.drill.exec.proto.UserProtos.PreparedStatement(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (columnsBuilder_ == null) {
          if (((bitField0_ & 0x00000001) != 0)) {
            columns_ = java.util.Collections.unmodifiableList(columns_);
            bitField0_ = (bitField0_ & ~0x00000001);
          }
          result.columns_ = columns_;
        } else {
          result.columns_ = columnsBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (serverHandleBuilder_ == null) {
            result.serverHandle_ = serverHandle_;
          } else {
            result.serverHandle_ = serverHandleBuilder_.build();
          }
          to_bitField0_ |= 0x00000001;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.PreparedStatement) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.PreparedStatement)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.PreparedStatement other) {
        if (other == org.apache.drill.exec.proto.UserProtos.PreparedStatement.getDefaultInstance()) return this;
        if (columnsBuilder_ == null) {
          if (!other.columns_.isEmpty()) {
            if (columns_.isEmpty()) {
              columns_ = other.columns_;
              bitField0_ = (bitField0_ & ~0x00000001);
            } else {
              ensureColumnsIsMutable();
              columns_.addAll(other.columns_);
            }
            onChanged();
          }
        } else {
          if (!other.columns_.isEmpty()) {
            if (columnsBuilder_.isEmpty()) {
              columnsBuilder_.dispose();
              columnsBuilder_ = null;
              columns_ = other.columns_;
              bitField0_ = (bitField0_ & ~0x00000001);
              columnsBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getColumnsFieldBuilder() : null;
            } else {
              columnsBuilder_.addAllMessages(other.columns_);
            }
          }
        }
        if (other.hasServerHandle()) {
          mergeServerHandle(other.getServerHandle());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 10: {
                org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.PARSER,
                        extensionRegistry);
                if (columnsBuilder_ == null) {
                  ensureColumnsIsMutable();
                  columns_.add(m);
                } else {
                  columnsBuilder_.addMessage(m);
                }
                break;
              } // case 10
              case 18: {
                input.readMessage(
                    getServerHandleFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private java.util.List<org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata> columns_ =
        java.util.Collections.emptyList();
      private void ensureColumnsIsMutable() {
        if (!((bitField0_ & 0x00000001) != 0)) {
          columns_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata>(columns_);
          bitField0_ |= 0x00000001;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder> columnsBuilder_;

      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata> getColumnsList() {
        if (columnsBuilder_ == null) {
          return java.util.Collections.unmodifiableList(columns_);
        } else {
          return columnsBuilder_.getMessageList();
        }
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public int getColumnsCount() {
        if (columnsBuilder_ == null) {
          return columns_.size();
        } else {
          return columnsBuilder_.getCount();
        }
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata getColumns(int index) {
        if (columnsBuilder_ == null) {
          return columns_.get(index);
        } else {
          return columnsBuilder_.getMessage(index);
        }
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder setColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata value) {
        if (columnsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureColumnsIsMutable();
          columns_.set(index, value);
          onChanged();
        } else {
          columnsBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder setColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder builderForValue) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.set(index, builderForValue.build());
          onChanged();
        } else {
          columnsBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder addColumns(org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata value) {
        if (columnsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureColumnsIsMutable();
          columns_.add(value);
          onChanged();
        } else {
          columnsBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder addColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata value) {
        if (columnsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureColumnsIsMutable();
          columns_.add(index, value);
          onChanged();
        } else {
          columnsBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder addColumns(
          org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder builderForValue) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.add(builderForValue.build());
          onChanged();
        } else {
          columnsBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder addColumns(
          int index, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder builderForValue) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.add(index, builderForValue.build());
          onChanged();
        } else {
          columnsBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder addAllColumns(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata> values) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, columns_);
          onChanged();
        } else {
          columnsBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder clearColumns() {
        if (columnsBuilder_ == null) {
          columns_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000001);
          onChanged();
        } else {
          columnsBuilder_.clear();
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public Builder removeColumns(int index) {
        if (columnsBuilder_ == null) {
          ensureColumnsIsMutable();
          columns_.remove(index);
          onChanged();
        } else {
          columnsBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder getColumnsBuilder(
          int index) {
        return getColumnsFieldBuilder().getBuilder(index);
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder getColumnsOrBuilder(
          int index) {
        if (columnsBuilder_ == null) {
          return columns_.get(index);  } else {
          return columnsBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder> 
           getColumnsOrBuilderList() {
        if (columnsBuilder_ != null) {
          return columnsBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(columns_);
        }
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder addColumnsBuilder() {
        return getColumnsFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder addColumnsBuilder(
          int index) {
        return getColumnsFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.getDefaultInstance());
      }
      /**
       * <code>repeated .exec.user.ResultColumnMetadata columns = 1;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder> 
           getColumnsBuilderList() {
        return getColumnsFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder> 
          getColumnsFieldBuilder() {
        if (columnsBuilder_ == null) {
          columnsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadata.Builder, org.apache.drill.exec.proto.UserProtos.ResultColumnMetadataOrBuilder>(
                  columns_,
                  ((bitField0_ & 0x00000001) != 0),
                  getParentForChildren(),
                  isClean());
          columns_ = null;
        }
        return columnsBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle serverHandle_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder> serverHandleBuilder_;
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       * @return Whether the serverHandle field is set.
       */
      public boolean hasServerHandle() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       * @return The serverHandle.
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getServerHandle() {
        if (serverHandleBuilder_ == null) {
          return serverHandle_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : serverHandle_;
        } else {
          return serverHandleBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       */
      public Builder setServerHandle(org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle value) {
        if (serverHandleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          serverHandle_ = value;
          onChanged();
        } else {
          serverHandleBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       */
      public Builder setServerHandle(
          org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder builderForValue) {
        if (serverHandleBuilder_ == null) {
          serverHandle_ = builderForValue.build();
          onChanged();
        } else {
          serverHandleBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       */
      public Builder mergeServerHandle(org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle value) {
        if (serverHandleBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              serverHandle_ != null &&
              serverHandle_ != org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance()) {
            serverHandle_ =
              org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.newBuilder(serverHandle_).mergeFrom(value).buildPartial();
          } else {
            serverHandle_ = value;
          }
          onChanged();
        } else {
          serverHandleBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       */
      public Builder clearServerHandle() {
        if (serverHandleBuilder_ == null) {
          serverHandle_ = null;
          onChanged();
        } else {
          serverHandleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder getServerHandleBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getServerHandleFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder getServerHandleOrBuilder() {
        if (serverHandleBuilder_ != null) {
          return serverHandleBuilder_.getMessageOrBuilder();
        } else {
          return serverHandle_ == null ?
              org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : serverHandle_;
        }
      }
      /**
       * <pre>
       * In order to execute the prepared statement,
       * clients need to submit this object in RunQuery message.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle server_handle = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder> 
          getServerHandleFieldBuilder() {
        if (serverHandleBuilder_ == null) {
          serverHandleBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder>(
                  getServerHandle(),
                  getParentForChildren(),
                  isClean());
          serverHandle_ = null;
        }
        return serverHandleBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.PreparedStatement)
    }

    // @@protoc_insertion_point(class_scope:exec.user.PreparedStatement)
    private static final org.apache.drill.exec.proto.UserProtos.PreparedStatement DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.PreparedStatement();
    }

    public static org.apache.drill.exec.proto.UserProtos.PreparedStatement getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<PreparedStatement>
        PARSER = new com.google.protobuf.AbstractParser<PreparedStatement>() {
      @java.lang.Override
      public PreparedStatement parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<PreparedStatement> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<PreparedStatement> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatement getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface CreatePreparedStatementRespOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.CreatePreparedStatementResp)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus();

    /**
     * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
     * @return Whether the preparedStatement field is set.
     */
    boolean hasPreparedStatement();
    /**
     * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
     * @return The preparedStatement.
     */
    org.apache.drill.exec.proto.UserProtos.PreparedStatement getPreparedStatement();
    /**
     * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.PreparedStatementOrBuilder getPreparedStatementOrBuilder();

    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();
  }
  /**
   * <pre>
   * Response message for CreatePreparedStatementReq.
   * </pre>
   *
   * Protobuf type {@code exec.user.CreatePreparedStatementResp}
   */
  public static final class CreatePreparedStatementResp extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.CreatePreparedStatementResp)
      CreatePreparedStatementRespOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use CreatePreparedStatementResp.newBuilder() to construct.
    private CreatePreparedStatementResp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private CreatePreparedStatementResp() {
      status_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new CreatePreparedStatementResp();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementResp_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementResp_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp.class, org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp.Builder.class);
    }

    private int bitField0_;
    public static final int STATUS_FIELD_NUMBER = 1;
    private int status_;
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
    }

    public static final int PREPARED_STATEMENT_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserProtos.PreparedStatement preparedStatement_;
    /**
     * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
     * @return Whether the preparedStatement field is set.
     */
    @java.lang.Override
    public boolean hasPreparedStatement() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
     * @return The preparedStatement.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatement getPreparedStatement() {
      return preparedStatement_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatement.getDefaultInstance() : preparedStatement_;
    }
    /**
     * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatementOrBuilder getPreparedStatementOrBuilder() {
      return preparedStatement_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatement.getDefaultInstance() : preparedStatement_;
    }

    public static final int ERROR_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, status_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getPreparedStatement());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getError());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, status_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getPreparedStatement());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getError());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp other = (org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp) obj;

      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (hasPreparedStatement() != other.hasPreparedStatement()) return false;
      if (hasPreparedStatement()) {
        if (!getPreparedStatement()
            .equals(other.getPreparedStatement())) return false;
      }
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (hasPreparedStatement()) {
        hash = (37 * hash) + PREPARED_STATEMENT_FIELD_NUMBER;
        hash = (53 * hash) + getPreparedStatement().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp 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.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Response message for CreatePreparedStatementReq.
     * </pre>
     *
     * Protobuf type {@code exec.user.CreatePreparedStatementResp}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.CreatePreparedStatementResp)
        org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementRespOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementResp_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementResp_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp.class, org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getPreparedStatementFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (preparedStatementBuilder_ == null) {
          preparedStatement_ = null;
        } else {
          preparedStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_CreatePreparedStatementResp_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp build() {
        org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp buildPartial() {
        org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp result = new org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.status_ = status_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (preparedStatementBuilder_ == null) {
            result.preparedStatement_ = preparedStatement_;
          } else {
            result.preparedStatement_ = preparedStatementBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp other) {
        if (other == org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp.getDefaultInstance()) return this;
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (other.hasPreparedStatement()) {
          mergePreparedStatement(other.getPreparedStatement());
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.RequestStatus tmpValue =
                    org.apache.drill.exec.proto.UserProtos.RequestStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                input.readMessage(
                    getPreparedStatementFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int status_ = 0;
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserProtos.RequestStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserProtos.PreparedStatement preparedStatement_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.PreparedStatement, org.apache.drill.exec.proto.UserProtos.PreparedStatement.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementOrBuilder> preparedStatementBuilder_;
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       * @return Whether the preparedStatement field is set.
       */
      public boolean hasPreparedStatement() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       * @return The preparedStatement.
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatement getPreparedStatement() {
        if (preparedStatementBuilder_ == null) {
          return preparedStatement_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatement.getDefaultInstance() : preparedStatement_;
        } else {
          return preparedStatementBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       */
      public Builder setPreparedStatement(org.apache.drill.exec.proto.UserProtos.PreparedStatement value) {
        if (preparedStatementBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          preparedStatement_ = value;
          onChanged();
        } else {
          preparedStatementBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       */
      public Builder setPreparedStatement(
          org.apache.drill.exec.proto.UserProtos.PreparedStatement.Builder builderForValue) {
        if (preparedStatementBuilder_ == null) {
          preparedStatement_ = builderForValue.build();
          onChanged();
        } else {
          preparedStatementBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       */
      public Builder mergePreparedStatement(org.apache.drill.exec.proto.UserProtos.PreparedStatement value) {
        if (preparedStatementBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              preparedStatement_ != null &&
              preparedStatement_ != org.apache.drill.exec.proto.UserProtos.PreparedStatement.getDefaultInstance()) {
            preparedStatement_ =
              org.apache.drill.exec.proto.UserProtos.PreparedStatement.newBuilder(preparedStatement_).mergeFrom(value).buildPartial();
          } else {
            preparedStatement_ = value;
          }
          onChanged();
        } else {
          preparedStatementBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       */
      public Builder clearPreparedStatement() {
        if (preparedStatementBuilder_ == null) {
          preparedStatement_ = null;
          onChanged();
        } else {
          preparedStatementBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatement.Builder getPreparedStatementBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getPreparedStatementFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementOrBuilder getPreparedStatementOrBuilder() {
        if (preparedStatementBuilder_ != null) {
          return preparedStatementBuilder_.getMessageOrBuilder();
        } else {
          return preparedStatement_ == null ?
              org.apache.drill.exec.proto.UserProtos.PreparedStatement.getDefaultInstance() : preparedStatement_;
        }
      }
      /**
       * <code>optional .exec.user.PreparedStatement prepared_statement = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.PreparedStatement, org.apache.drill.exec.proto.UserProtos.PreparedStatement.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementOrBuilder> 
          getPreparedStatementFieldBuilder() {
        if (preparedStatementBuilder_ == null) {
          preparedStatementBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.PreparedStatement, org.apache.drill.exec.proto.UserProtos.PreparedStatement.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementOrBuilder>(
                  getPreparedStatement(),
                  getParentForChildren(),
                  isClean());
          preparedStatement_ = null;
        }
        return preparedStatementBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.CreatePreparedStatementResp)
    }

    // @@protoc_insertion_point(class_scope:exec.user.CreatePreparedStatementResp)
    private static final org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp();
    }

    public static org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<CreatePreparedStatementResp>
        PARSER = new com.google.protobuf.AbstractParser<CreatePreparedStatementResp>() {
      @java.lang.Override
      public CreatePreparedStatementResp parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<CreatePreparedStatementResp> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<CreatePreparedStatementResp> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.CreatePreparedStatementResp getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetServerMetaReqOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetServerMetaReq)
      com.google.protobuf.MessageOrBuilder {
  }
  /**
   * <pre>
   * Request message for getting server metadata
   * </pre>
   *
   * Protobuf type {@code exec.user.GetServerMetaReq}
   */
  public static final class GetServerMetaReq extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetServerMetaReq)
      GetServerMetaReqOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetServerMetaReq.newBuilder() to construct.
    private GetServerMetaReq(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetServerMetaReq() {
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetServerMetaReq();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaReq_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaReq_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetServerMetaReq.class, org.apache.drill.exec.proto.UserProtos.GetServerMetaReq.Builder.class);
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetServerMetaReq)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetServerMetaReq other = (org.apache.drill.exec.proto.UserProtos.GetServerMetaReq) obj;

      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq 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.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetServerMetaReq prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Request message for getting server metadata
     * </pre>
     *
     * Protobuf type {@code exec.user.GetServerMetaReq}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetServerMetaReq)
        org.apache.drill.exec.proto.UserProtos.GetServerMetaReqOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaReq_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaReq_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetServerMetaReq.class, org.apache.drill.exec.proto.UserProtos.GetServerMetaReq.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetServerMetaReq.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaReq_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetServerMetaReq getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetServerMetaReq.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetServerMetaReq build() {
        org.apache.drill.exec.proto.UserProtos.GetServerMetaReq result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetServerMetaReq buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetServerMetaReq result = new org.apache.drill.exec.proto.UserProtos.GetServerMetaReq(this);
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetServerMetaReq) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetServerMetaReq)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetServerMetaReq other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetServerMetaReq.getDefaultInstance()) return this;
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetServerMetaReq)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetServerMetaReq)
    private static final org.apache.drill.exec.proto.UserProtos.GetServerMetaReq DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetServerMetaReq();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaReq getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetServerMetaReq>
        PARSER = new com.google.protobuf.AbstractParser<GetServerMetaReq>() {
      @java.lang.Override
      public GetServerMetaReq parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetServerMetaReq> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetServerMetaReq> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetServerMetaReq getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ConvertSupportOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.ConvertSupport)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>required .common.MinorType from = 1;</code>
     * @return Whether the from field is set.
     */
    boolean hasFrom();
    /**
     * <code>required .common.MinorType from = 1;</code>
     * @return The from.
     */
    org.apache.drill.common.types.TypeProtos.MinorType getFrom();

    /**
     * <code>required .common.MinorType to = 2;</code>
     * @return Whether the to field is set.
     */
    boolean hasTo();
    /**
     * <code>required .common.MinorType to = 2;</code>
     * @return The to.
     */
    org.apache.drill.common.types.TypeProtos.MinorType getTo();
  }
  /**
   * Protobuf type {@code exec.user.ConvertSupport}
   */
  public static final class ConvertSupport extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.ConvertSupport)
      ConvertSupportOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ConvertSupport.newBuilder() to construct.
    private ConvertSupport(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ConvertSupport() {
      from_ = 0;
      to_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new ConvertSupport();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ConvertSupport_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ConvertSupport_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.ConvertSupport.class, org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder.class);
    }

    private int bitField0_;
    public static final int FROM_FIELD_NUMBER = 1;
    private int from_;
    /**
     * <code>required .common.MinorType from = 1;</code>
     * @return Whether the from field is set.
     */
    @java.lang.Override public boolean hasFrom() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>required .common.MinorType from = 1;</code>
     * @return The from.
     */
    @java.lang.Override public org.apache.drill.common.types.TypeProtos.MinorType getFrom() {
      @SuppressWarnings("deprecation")
      org.apache.drill.common.types.TypeProtos.MinorType result = org.apache.drill.common.types.TypeProtos.MinorType.valueOf(from_);
      return result == null ? org.apache.drill.common.types.TypeProtos.MinorType.LATE : result;
    }

    public static final int TO_FIELD_NUMBER = 2;
    private int to_;
    /**
     * <code>required .common.MinorType to = 2;</code>
     * @return Whether the to field is set.
     */
    @java.lang.Override public boolean hasTo() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>required .common.MinorType to = 2;</code>
     * @return The to.
     */
    @java.lang.Override public org.apache.drill.common.types.TypeProtos.MinorType getTo() {
      @SuppressWarnings("deprecation")
      org.apache.drill.common.types.TypeProtos.MinorType result = org.apache.drill.common.types.TypeProtos.MinorType.valueOf(to_);
      return result == null ? org.apache.drill.common.types.TypeProtos.MinorType.LATE : result;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (!hasFrom()) {
        memoizedIsInitialized = 0;
        return false;
      }
      if (!hasTo()) {
        memoizedIsInitialized = 0;
        return false;
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, from_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeEnum(2, to_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, from_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, to_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.ConvertSupport)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.ConvertSupport other = (org.apache.drill.exec.proto.UserProtos.ConvertSupport) obj;

      if (hasFrom() != other.hasFrom()) return false;
      if (hasFrom()) {
        if (from_ != other.from_) return false;
      }
      if (hasTo() != other.hasTo()) return false;
      if (hasTo()) {
        if (to_ != other.to_) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasFrom()) {
        hash = (37 * hash) + FROM_FIELD_NUMBER;
        hash = (53 * hash) + from_;
      }
      if (hasTo()) {
        hash = (37 * hash) + TO_FIELD_NUMBER;
        hash = (53 * hash) + to_;
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport 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.drill.exec.proto.UserProtos.ConvertSupport parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.ConvertSupport prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.ConvertSupport}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.ConvertSupport)
        org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ConvertSupport_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ConvertSupport_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.ConvertSupport.class, org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.ConvertSupport.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        from_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        to_ = 0;
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ConvertSupport_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ConvertSupport getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.ConvertSupport.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ConvertSupport build() {
        org.apache.drill.exec.proto.UserProtos.ConvertSupport result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ConvertSupport buildPartial() {
        org.apache.drill.exec.proto.UserProtos.ConvertSupport result = new org.apache.drill.exec.proto.UserProtos.ConvertSupport(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.from_ = from_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.to_ = to_;
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.ConvertSupport) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.ConvertSupport)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.ConvertSupport other) {
        if (other == org.apache.drill.exec.proto.UserProtos.ConvertSupport.getDefaultInstance()) return this;
        if (other.hasFrom()) {
          setFrom(other.getFrom());
        }
        if (other.hasTo()) {
          setTo(other.getTo());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        if (!hasFrom()) {
          return false;
        }
        if (!hasTo()) {
          return false;
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.common.types.TypeProtos.MinorType tmpValue =
                    org.apache.drill.common.types.TypeProtos.MinorType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  from_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 16: {
                int tmpRaw = input.readEnum();
                org.apache.drill.common.types.TypeProtos.MinorType tmpValue =
                    org.apache.drill.common.types.TypeProtos.MinorType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(2, tmpRaw);
                } else {
                  to_ = tmpRaw;
                  bitField0_ |= 0x00000002;
                }
                break;
              } // case 16
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int from_ = 0;
      /**
       * <code>required .common.MinorType from = 1;</code>
       * @return Whether the from field is set.
       */
      @java.lang.Override public boolean hasFrom() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>required .common.MinorType from = 1;</code>
       * @return The from.
       */
      @java.lang.Override
      public org.apache.drill.common.types.TypeProtos.MinorType getFrom() {
        @SuppressWarnings("deprecation")
        org.apache.drill.common.types.TypeProtos.MinorType result = org.apache.drill.common.types.TypeProtos.MinorType.valueOf(from_);
        return result == null ? org.apache.drill.common.types.TypeProtos.MinorType.LATE : result;
      }
      /**
       * <code>required .common.MinorType from = 1;</code>
       * @param value The from to set.
       * @return This builder for chaining.
       */
      public Builder setFrom(org.apache.drill.common.types.TypeProtos.MinorType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        from_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>required .common.MinorType from = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearFrom() {
        bitField0_ = (bitField0_ & ~0x00000001);
        from_ = 0;
        onChanged();
        return this;
      }

      private int to_ = 0;
      /**
       * <code>required .common.MinorType to = 2;</code>
       * @return Whether the to field is set.
       */
      @java.lang.Override public boolean hasTo() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>required .common.MinorType to = 2;</code>
       * @return The to.
       */
      @java.lang.Override
      public org.apache.drill.common.types.TypeProtos.MinorType getTo() {
        @SuppressWarnings("deprecation")
        org.apache.drill.common.types.TypeProtos.MinorType result = org.apache.drill.common.types.TypeProtos.MinorType.valueOf(to_);
        return result == null ? org.apache.drill.common.types.TypeProtos.MinorType.LATE : result;
      }
      /**
       * <code>required .common.MinorType to = 2;</code>
       * @param value The to to set.
       * @return This builder for chaining.
       */
      public Builder setTo(org.apache.drill.common.types.TypeProtos.MinorType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        to_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>required .common.MinorType to = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearTo() {
        bitField0_ = (bitField0_ & ~0x00000002);
        to_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.ConvertSupport)
    }

    // @@protoc_insertion_point(class_scope:exec.user.ConvertSupport)
    private static final org.apache.drill.exec.proto.UserProtos.ConvertSupport DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.ConvertSupport();
    }

    public static org.apache.drill.exec.proto.UserProtos.ConvertSupport getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ConvertSupport>
        PARSER = new com.google.protobuf.AbstractParser<ConvertSupport>() {
      @java.lang.Override
      public ConvertSupport parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<ConvertSupport> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<ConvertSupport> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ConvertSupport getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface GetServerMetaRespOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.GetServerMetaResp)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    boolean hasStatus();
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus();

    /**
     * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
     * @return Whether the serverMeta field is set.
     */
    boolean hasServerMeta();
    /**
     * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
     * @return The serverMeta.
     */
    org.apache.drill.exec.proto.UserProtos.ServerMeta getServerMeta();
    /**
     * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
     */
    org.apache.drill.exec.proto.UserProtos.ServerMetaOrBuilder getServerMetaOrBuilder();

    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    boolean hasError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBError getError();
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder();
  }
  /**
   * <pre>
   * Response message for GetServerMetaReq
   * </pre>
   *
   * Protobuf type {@code exec.user.GetServerMetaResp}
   */
  public static final class GetServerMetaResp extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.GetServerMetaResp)
      GetServerMetaRespOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use GetServerMetaResp.newBuilder() to construct.
    private GetServerMetaResp(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private GetServerMetaResp() {
      status_ = 0;
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new GetServerMetaResp();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaResp_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaResp_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.GetServerMetaResp.class, org.apache.drill.exec.proto.UserProtos.GetServerMetaResp.Builder.class);
    }

    private int bitField0_;
    public static final int STATUS_FIELD_NUMBER = 1;
    private int status_;
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return Whether the status field is set.
     */
    @java.lang.Override public boolean hasStatus() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.RequestStatus status = 1;</code>
     * @return The status.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
    }

    public static final int SERVER_META_FIELD_NUMBER = 2;
    private org.apache.drill.exec.proto.UserProtos.ServerMeta serverMeta_;
    /**
     * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
     * @return Whether the serverMeta field is set.
     */
    @java.lang.Override
    public boolean hasServerMeta() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
     * @return The serverMeta.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ServerMeta getServerMeta() {
      return serverMeta_ == null ? org.apache.drill.exec.proto.UserProtos.ServerMeta.getDefaultInstance() : serverMeta_;
    }
    /**
     * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ServerMetaOrBuilder getServerMetaOrBuilder() {
      return serverMeta_ == null ? org.apache.drill.exec.proto.UserProtos.ServerMeta.getDefaultInstance() : serverMeta_;
    }

    public static final int ERROR_FIELD_NUMBER = 3;
    private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return Whether the error field is set.
     */
    @java.lang.Override
    public boolean hasError() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     * @return The error.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }
    /**
     * <code>optional .exec.shared.DrillPBError error = 3;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
      return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      if (hasServerMeta()) {
        if (!getServerMeta().isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, status_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeMessage(2, getServerMeta());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeMessage(3, getError());
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, status_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(2, getServerMeta());
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(3, getError());
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.GetServerMetaResp)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.GetServerMetaResp other = (org.apache.drill.exec.proto.UserProtos.GetServerMetaResp) obj;

      if (hasStatus() != other.hasStatus()) return false;
      if (hasStatus()) {
        if (status_ != other.status_) return false;
      }
      if (hasServerMeta() != other.hasServerMeta()) return false;
      if (hasServerMeta()) {
        if (!getServerMeta()
            .equals(other.getServerMeta())) return false;
      }
      if (hasError() != other.hasError()) return false;
      if (hasError()) {
        if (!getError()
            .equals(other.getError())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasStatus()) {
        hash = (37 * hash) + STATUS_FIELD_NUMBER;
        hash = (53 * hash) + status_;
      }
      if (hasServerMeta()) {
        hash = (37 * hash) + SERVER_META_FIELD_NUMBER;
        hash = (53 * hash) + getServerMeta().hashCode();
      }
      if (hasError()) {
        hash = (37 * hash) + ERROR_FIELD_NUMBER;
        hash = (53 * hash) + getError().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp 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.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.GetServerMetaResp prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Response message for GetServerMetaReq
     * </pre>
     *
     * Protobuf type {@code exec.user.GetServerMetaResp}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.GetServerMetaResp)
        org.apache.drill.exec.proto.UserProtos.GetServerMetaRespOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaResp_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaResp_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.GetServerMetaResp.class, org.apache.drill.exec.proto.UserProtos.GetServerMetaResp.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.GetServerMetaResp.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getServerMetaFieldBuilder();
          getErrorFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        status_ = 0;
        bitField0_ = (bitField0_ & ~0x00000001);
        if (serverMetaBuilder_ == null) {
          serverMeta_ = null;
        } else {
          serverMetaBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        if (errorBuilder_ == null) {
          error_ = null;
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_GetServerMetaResp_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetServerMetaResp getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.GetServerMetaResp.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetServerMetaResp build() {
        org.apache.drill.exec.proto.UserProtos.GetServerMetaResp result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GetServerMetaResp buildPartial() {
        org.apache.drill.exec.proto.UserProtos.GetServerMetaResp result = new org.apache.drill.exec.proto.UserProtos.GetServerMetaResp(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.status_ = status_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          if (serverMetaBuilder_ == null) {
            result.serverMeta_ = serverMeta_;
          } else {
            result.serverMeta_ = serverMetaBuilder_.build();
          }
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          if (errorBuilder_ == null) {
            result.error_ = error_;
          } else {
            result.error_ = errorBuilder_.build();
          }
          to_bitField0_ |= 0x00000004;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.GetServerMetaResp) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.GetServerMetaResp)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.GetServerMetaResp other) {
        if (other == org.apache.drill.exec.proto.UserProtos.GetServerMetaResp.getDefaultInstance()) return this;
        if (other.hasStatus()) {
          setStatus(other.getStatus());
        }
        if (other.hasServerMeta()) {
          mergeServerMeta(other.getServerMeta());
        }
        if (other.hasError()) {
          mergeError(other.getError());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        if (hasServerMeta()) {
          if (!getServerMeta().isInitialized()) {
            return false;
          }
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.RequestStatus tmpValue =
                    org.apache.drill.exec.proto.UserProtos.RequestStatus.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  status_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 18: {
                input.readMessage(
                    getServerMetaFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000002;
                break;
              } // case 18
              case 26: {
                input.readMessage(
                    getErrorFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int status_ = 0;
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return Whether the status field is set.
       */
      @java.lang.Override public boolean hasStatus() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return The status.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RequestStatus getStatus() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.RequestStatus result = org.apache.drill.exec.proto.UserProtos.RequestStatus.valueOf(status_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.RequestStatus.UNKNOWN_STATUS : result;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @param value The status to set.
       * @return This builder for chaining.
       */
      public Builder setStatus(org.apache.drill.exec.proto.UserProtos.RequestStatus value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        status_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.RequestStatus status = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearStatus() {
        bitField0_ = (bitField0_ & ~0x00000001);
        status_ = 0;
        onChanged();
        return this;
      }

      private org.apache.drill.exec.proto.UserProtos.ServerMeta serverMeta_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ServerMeta, org.apache.drill.exec.proto.UserProtos.ServerMeta.Builder, org.apache.drill.exec.proto.UserProtos.ServerMetaOrBuilder> serverMetaBuilder_;
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       * @return Whether the serverMeta field is set.
       */
      public boolean hasServerMeta() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       * @return The serverMeta.
       */
      public org.apache.drill.exec.proto.UserProtos.ServerMeta getServerMeta() {
        if (serverMetaBuilder_ == null) {
          return serverMeta_ == null ? org.apache.drill.exec.proto.UserProtos.ServerMeta.getDefaultInstance() : serverMeta_;
        } else {
          return serverMetaBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       */
      public Builder setServerMeta(org.apache.drill.exec.proto.UserProtos.ServerMeta value) {
        if (serverMetaBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          serverMeta_ = value;
          onChanged();
        } else {
          serverMetaBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       */
      public Builder setServerMeta(
          org.apache.drill.exec.proto.UserProtos.ServerMeta.Builder builderForValue) {
        if (serverMetaBuilder_ == null) {
          serverMeta_ = builderForValue.build();
          onChanged();
        } else {
          serverMetaBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       */
      public Builder mergeServerMeta(org.apache.drill.exec.proto.UserProtos.ServerMeta value) {
        if (serverMetaBuilder_ == null) {
          if (((bitField0_ & 0x00000002) != 0) &&
              serverMeta_ != null &&
              serverMeta_ != org.apache.drill.exec.proto.UserProtos.ServerMeta.getDefaultInstance()) {
            serverMeta_ =
              org.apache.drill.exec.proto.UserProtos.ServerMeta.newBuilder(serverMeta_).mergeFrom(value).buildPartial();
          } else {
            serverMeta_ = value;
          }
          onChanged();
        } else {
          serverMetaBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000002;
        return this;
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       */
      public Builder clearServerMeta() {
        if (serverMetaBuilder_ == null) {
          serverMeta_ = null;
          onChanged();
        } else {
          serverMetaBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000002);
        return this;
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ServerMeta.Builder getServerMetaBuilder() {
        bitField0_ |= 0x00000002;
        onChanged();
        return getServerMetaFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ServerMetaOrBuilder getServerMetaOrBuilder() {
        if (serverMetaBuilder_ != null) {
          return serverMetaBuilder_.getMessageOrBuilder();
        } else {
          return serverMeta_ == null ?
              org.apache.drill.exec.proto.UserProtos.ServerMeta.getDefaultInstance() : serverMeta_;
        }
      }
      /**
       * <code>optional .exec.user.ServerMeta server_meta = 2;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ServerMeta, org.apache.drill.exec.proto.UserProtos.ServerMeta.Builder, org.apache.drill.exec.proto.UserProtos.ServerMetaOrBuilder> 
          getServerMetaFieldBuilder() {
        if (serverMetaBuilder_ == null) {
          serverMetaBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.ServerMeta, org.apache.drill.exec.proto.UserProtos.ServerMeta.Builder, org.apache.drill.exec.proto.UserProtos.ServerMetaOrBuilder>(
                  getServerMeta(),
                  getParentForChildren(),
                  isClean());
          serverMeta_ = null;
        }
        return serverMetaBuilder_;
      }

      private org.apache.drill.exec.proto.UserBitShared.DrillPBError error_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> errorBuilder_;
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return Whether the error field is set.
       */
      public boolean hasError() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       * @return The error.
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError getError() {
        if (errorBuilder_ == null) {
          return error_ == null ? org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        } else {
          return errorBuilder_.getMessage();
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          error_ = value;
          onChanged();
        } else {
          errorBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder setError(
          org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder builderForValue) {
        if (errorBuilder_ == null) {
          error_ = builderForValue.build();
          onChanged();
        } else {
          errorBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder mergeError(org.apache.drill.exec.proto.UserBitShared.DrillPBError value) {
        if (errorBuilder_ == null) {
          if (((bitField0_ & 0x00000004) != 0) &&
              error_ != null &&
              error_ != org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance()) {
            error_ =
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.newBuilder(error_).mergeFrom(value).buildPartial();
          } else {
            error_ = value;
          }
          onChanged();
        } else {
          errorBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000004;
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public Builder clearError() {
        if (errorBuilder_ == null) {
          error_ = null;
          onChanged();
        } else {
          errorBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000004);
        return this;
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder getErrorBuilder() {
        bitField0_ |= 0x00000004;
        onChanged();
        return getErrorFieldBuilder().getBuilder();
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      public org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder getErrorOrBuilder() {
        if (errorBuilder_ != null) {
          return errorBuilder_.getMessageOrBuilder();
        } else {
          return error_ == null ?
              org.apache.drill.exec.proto.UserBitShared.DrillPBError.getDefaultInstance() : error_;
        }
      }
      /**
       * <code>optional .exec.shared.DrillPBError error = 3;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder> 
          getErrorFieldBuilder() {
        if (errorBuilder_ == null) {
          errorBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserBitShared.DrillPBError, org.apache.drill.exec.proto.UserBitShared.DrillPBError.Builder, org.apache.drill.exec.proto.UserBitShared.DrillPBErrorOrBuilder>(
                  getError(),
                  getParentForChildren(),
                  isClean());
          error_ = null;
        }
        return errorBuilder_;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.GetServerMetaResp)
    }

    // @@protoc_insertion_point(class_scope:exec.user.GetServerMetaResp)
    private static final org.apache.drill.exec.proto.UserProtos.GetServerMetaResp DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.GetServerMetaResp();
    }

    public static org.apache.drill.exec.proto.UserProtos.GetServerMetaResp getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<GetServerMetaResp>
        PARSER = new com.google.protobuf.AbstractParser<GetServerMetaResp>() {
      @java.lang.Override
      public GetServerMetaResp parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<GetServerMetaResp> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<GetServerMetaResp> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.GetServerMetaResp getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface ServerMetaOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.ServerMeta)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <pre>
     * True if current user can use all tables returned by GetTables
     * </pre>
     *
     * <code>optional bool all_tables_selectable = 1;</code>
     * @return Whether the allTablesSelectable field is set.
     */
    boolean hasAllTablesSelectable();
    /**
     * <pre>
     * True if current user can use all tables returned by GetTables
     * </pre>
     *
     * <code>optional bool all_tables_selectable = 1;</code>
     * @return The allTablesSelectable.
     */
    boolean getAllTablesSelectable();

    /**
     * <pre>
     * True if BLOB are included into the max row size
     * </pre>
     *
     * <code>optional bool blob_included_in_max_row_size = 2;</code>
     * @return Whether the blobIncludedInMaxRowSize field is set.
     */
    boolean hasBlobIncludedInMaxRowSize();
    /**
     * <pre>
     * True if BLOB are included into the max row size
     * </pre>
     *
     * <code>optional bool blob_included_in_max_row_size = 2;</code>
     * @return The blobIncludedInMaxRowSize.
     */
    boolean getBlobIncludedInMaxRowSize();

    /**
     * <pre>
     * True if catalog name is at the start of a fully qualified table
     * </pre>
     *
     * <code>optional bool catalog_at_start = 3;</code>
     * @return Whether the catalogAtStart field is set.
     */
    boolean hasCatalogAtStart();
    /**
     * <pre>
     * True if catalog name is at the start of a fully qualified table
     * </pre>
     *
     * <code>optional bool catalog_at_start = 3;</code>
     * @return The catalogAtStart.
     */
    boolean getCatalogAtStart();

    /**
     * <pre>
     * The catalog separator
     * </pre>
     *
     * <code>optional string catalog_separator = 4;</code>
     * @return Whether the catalogSeparator field is set.
     */
    boolean hasCatalogSeparator();
    /**
     * <pre>
     * The catalog separator
     * </pre>
     *
     * <code>optional string catalog_separator = 4;</code>
     * @return The catalogSeparator.
     */
    java.lang.String getCatalogSeparator();
    /**
     * <pre>
     * The catalog separator
     * </pre>
     *
     * <code>optional string catalog_separator = 4;</code>
     * @return The bytes for catalogSeparator.
     */
    com.google.protobuf.ByteString
        getCatalogSeparatorBytes();

    /**
     * <pre>
     * The term used to designate catalogs
     * </pre>
     *
     * <code>optional string catalog_term = 5;</code>
     * @return Whether the catalogTerm field is set.
     */
    boolean hasCatalogTerm();
    /**
     * <pre>
     * The term used to designate catalogs
     * </pre>
     *
     * <code>optional string catalog_term = 5;</code>
     * @return The catalogTerm.
     */
    java.lang.String getCatalogTerm();
    /**
     * <pre>
     * The term used to designate catalogs
     * </pre>
     *
     * <code>optional string catalog_term = 5;</code>
     * @return The bytes for catalogTerm.
     */
    com.google.protobuf.ByteString
        getCatalogTermBytes();

    /**
     * <pre>
     * COLLATE support
     * </pre>
     *
     * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
     * @return A list containing the collateSupport.
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.CollateSupport> getCollateSupportList();
    /**
     * <pre>
     * COLLATE support
     * </pre>
     *
     * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
     * @return The count of collateSupport.
     */
    int getCollateSupportCount();
    /**
     * <pre>
     * COLLATE support
     * </pre>
     *
     * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
     * @param index The index of the element to return.
     * @return The collateSupport at the given index.
     */
    org.apache.drill.exec.proto.UserProtos.CollateSupport getCollateSupport(int index);

    /**
     * <pre>
     * True if column aliasing is supported
     * </pre>
     *
     * <code>optional bool column_aliasing_supported = 7;</code>
     * @return Whether the columnAliasingSupported field is set.
     */
    boolean hasColumnAliasingSupported();
    /**
     * <pre>
     * True if column aliasing is supported
     * </pre>
     *
     * <code>optional bool column_aliasing_supported = 7;</code>
     * @return The columnAliasingSupported.
     */
    boolean getColumnAliasingSupported();

    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.ConvertSupport> 
        getConvertSupportList();
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    org.apache.drill.exec.proto.UserProtos.ConvertSupport getConvertSupport(int index);
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    int getConvertSupportCount();
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder> 
        getConvertSupportOrBuilderList();
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder getConvertSupportOrBuilder(
        int index);

    /**
     * <pre>
     * Correlation names support
     * </pre>
     *
     * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
     * @return Whether the correlationNamesSupport field is set.
     */
    boolean hasCorrelationNamesSupport();
    /**
     * <pre>
     * Correlation names support
     * </pre>
     *
     * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
     * @return The correlationNamesSupport.
     */
    org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport getCorrelationNamesSupport();

    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @return A list containing the dateTimeFunctions.
     */
    java.util.List<java.lang.String>
        getDateTimeFunctionsList();
    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @return The count of dateTimeFunctions.
     */
    int getDateTimeFunctionsCount();
    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @param index The index of the element to return.
     * @return The dateTimeFunctions at the given index.
     */
    java.lang.String getDateTimeFunctions(int index);
    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @param index The index of the value to return.
     * @return The bytes of the dateTimeFunctions at the given index.
     */
    com.google.protobuf.ByteString
        getDateTimeFunctionsBytes(int index);

    /**
     * <pre>
     * Supported Date Time literals
     * </pre>
     *
     * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
     * @return A list containing the dateTimeLiteralsSupport.
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport> getDateTimeLiteralsSupportList();
    /**
     * <pre>
     * Supported Date Time literals
     * </pre>
     *
     * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
     * @return The count of dateTimeLiteralsSupport.
     */
    int getDateTimeLiteralsSupportCount();
    /**
     * <pre>
     * Supported Date Time literals
     * </pre>
     *
     * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
     * @param index The index of the element to return.
     * @return The dateTimeLiteralsSupport at the given index.
     */
    org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport getDateTimeLiteralsSupport(int index);

    /**
     * <pre>
     * Group By support
     * </pre>
     *
     * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
     * @return Whether the groupBySupport field is set.
     */
    boolean hasGroupBySupport();
    /**
     * <pre>
     * Group By support
     * </pre>
     *
     * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
     * @return The groupBySupport.
     */
    org.apache.drill.exec.proto.UserProtos.GroupBySupport getGroupBySupport();

    /**
     * <pre>
     * Unquoted Identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
     * @return Whether the identifierCasing field is set.
     */
    boolean hasIdentifierCasing();
    /**
     * <pre>
     * Unquoted Identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
     * @return The identifierCasing.
     */
    org.apache.drill.exec.proto.UserProtos.IdentifierCasing getIdentifierCasing();

    /**
     * <pre>
     * Quote string for identifiers
     * </pre>
     *
     * <code>optional string identifier_quote_string = 14;</code>
     * @return Whether the identifierQuoteString field is set.
     */
    boolean hasIdentifierQuoteString();
    /**
     * <pre>
     * Quote string for identifiers
     * </pre>
     *
     * <code>optional string identifier_quote_string = 14;</code>
     * @return The identifierQuoteString.
     */
    java.lang.String getIdentifierQuoteString();
    /**
     * <pre>
     * Quote string for identifiers
     * </pre>
     *
     * <code>optional string identifier_quote_string = 14;</code>
     * @return The bytes for identifierQuoteString.
     */
    com.google.protobuf.ByteString
        getIdentifierQuoteStringBytes();

    /**
     * <pre>
     * True if LIKE supports an ESCAPE clause
     * </pre>
     *
     * <code>optional bool like_escape_clause_supported = 15;</code>
     * @return Whether the likeEscapeClauseSupported field is set.
     */
    boolean hasLikeEscapeClauseSupported();
    /**
     * <pre>
     * True if LIKE supports an ESCAPE clause
     * </pre>
     *
     * <code>optional bool like_escape_clause_supported = 15;</code>
     * @return The likeEscapeClauseSupported.
     */
    boolean getLikeEscapeClauseSupported();

    /**
     * <pre>
     * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_binary_literal_length = 16;</code>
     * @return Whether the maxBinaryLiteralLength field is set.
     */
    boolean hasMaxBinaryLiteralLength();
    /**
     * <pre>
     * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_binary_literal_length = 16;</code>
     * @return The maxBinaryLiteralLength.
     */
    int getMaxBinaryLiteralLength();

    /**
     * <pre>
     * Maximum length of catalog names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_catalog_name_length = 17;</code>
     * @return Whether the maxCatalogNameLength field is set.
     */
    boolean hasMaxCatalogNameLength();
    /**
     * <pre>
     * Maximum length of catalog names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_catalog_name_length = 17;</code>
     * @return The maxCatalogNameLength.
     */
    int getMaxCatalogNameLength();

    /**
     * <pre>
     * Maximum number of characters for string literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_char_literal_length = 18;</code>
     * @return Whether the maxCharLiteralLength field is set.
     */
    boolean hasMaxCharLiteralLength();
    /**
     * <pre>
     * Maximum number of characters for string literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_char_literal_length = 18;</code>
     * @return The maxCharLiteralLength.
     */
    int getMaxCharLiteralLength();

    /**
     * <pre>
     * Maximum length of column names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_column_name_length = 19;</code>
     * @return Whether the maxColumnNameLength field is set.
     */
    boolean hasMaxColumnNameLength();
    /**
     * <pre>
     * Maximum length of column names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_column_name_length = 19;</code>
     * @return The maxColumnNameLength.
     */
    int getMaxColumnNameLength();

    /**
     * <pre>
     * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_group_by = 20;</code>
     * @return Whether the maxColumnsInGroupBy field is set.
     */
    boolean hasMaxColumnsInGroupBy();
    /**
     * <pre>
     * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_group_by = 20;</code>
     * @return The maxColumnsInGroupBy.
     */
    int getMaxColumnsInGroupBy();

    /**
     * <pre>
     * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_order_by = 21;</code>
     * @return Whether the maxColumnsInOrderBy field is set.
     */
    boolean hasMaxColumnsInOrderBy();
    /**
     * <pre>
     * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_order_by = 21;</code>
     * @return The maxColumnsInOrderBy.
     */
    int getMaxColumnsInOrderBy();

    /**
     * <pre>
     * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_select = 22;</code>
     * @return Whether the maxColumnsInSelect field is set.
     */
    boolean hasMaxColumnsInSelect();
    /**
     * <pre>
     * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_select = 22;</code>
     * @return The maxColumnsInSelect.
     */
    int getMaxColumnsInSelect();

    /**
     * <pre>
     * Maximum length of cursor names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_cursor_name_length = 23;</code>
     * @return Whether the maxCursorNameLength field is set.
     */
    boolean hasMaxCursorNameLength();
    /**
     * <pre>
     * Maximum length of cursor names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_cursor_name_length = 23;</code>
     * @return The maxCursorNameLength.
     */
    int getMaxCursorNameLength();

    /**
     * <pre>
     * Maximum logical size for LOB types (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_logical_lob_size = 24;</code>
     * @return Whether the maxLogicalLobSize field is set.
     */
    boolean hasMaxLogicalLobSize();
    /**
     * <pre>
     * Maximum logical size for LOB types (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_logical_lob_size = 24;</code>
     * @return The maxLogicalLobSize.
     */
    int getMaxLogicalLobSize();

    /**
     * <pre>
     * Maximum number of bytes for a single row (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_row_size = 25;</code>
     * @return Whether the maxRowSize field is set.
     */
    boolean hasMaxRowSize();
    /**
     * <pre>
     * Maximum number of bytes for a single row (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_row_size = 25;</code>
     * @return The maxRowSize.
     */
    int getMaxRowSize();

    /**
     * <pre>
     * Maximum length of schema names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_schema_name_length = 26;</code>
     * @return Whether the maxSchemaNameLength field is set.
     */
    boolean hasMaxSchemaNameLength();
    /**
     * <pre>
     * Maximum length of schema names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_schema_name_length = 26;</code>
     * @return The maxSchemaNameLength.
     */
    int getMaxSchemaNameLength();

    /**
     * <pre>
     * Maximum length for statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statement_length = 27;</code>
     * @return Whether the maxStatementLength field is set.
     */
    boolean hasMaxStatementLength();
    /**
     * <pre>
     * Maximum length for statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statement_length = 27;</code>
     * @return The maxStatementLength.
     */
    int getMaxStatementLength();

    /**
     * <pre>
     * Maximum number of statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statements = 28;</code>
     * @return Whether the maxStatements field is set.
     */
    boolean hasMaxStatements();
    /**
     * <pre>
     * Maximum number of statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statements = 28;</code>
     * @return The maxStatements.
     */
    int getMaxStatements();

    /**
     * <pre>
     * Maximum length of table names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_table_name_length = 29;</code>
     * @return Whether the maxTableNameLength field is set.
     */
    boolean hasMaxTableNameLength();
    /**
     * <pre>
     * Maximum length of table names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_table_name_length = 29;</code>
     * @return The maxTableNameLength.
     */
    int getMaxTableNameLength();

    /**
     * <pre>
     * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_tables_in_select = 30;</code>
     * @return Whether the maxTablesInSelect field is set.
     */
    boolean hasMaxTablesInSelect();
    /**
     * <pre>
     * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_tables_in_select = 30;</code>
     * @return The maxTablesInSelect.
     */
    int getMaxTablesInSelect();

    /**
     * <pre>
     * Maximum length of user names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_user_name_length = 31;</code>
     * @return Whether the maxUserNameLength field is set.
     */
    boolean hasMaxUserNameLength();
    /**
     * <pre>
     * Maximum length of user names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_user_name_length = 31;</code>
     * @return The maxUserNameLength.
     */
    int getMaxUserNameLength();

    /**
     * <pre>
     * How NULL are sorted
     * </pre>
     *
     * <code>optional .exec.user.NullCollation null_collation = 32;</code>
     * @return Whether the nullCollation field is set.
     */
    boolean hasNullCollation();
    /**
     * <pre>
     * How NULL are sorted
     * </pre>
     *
     * <code>optional .exec.user.NullCollation null_collation = 32;</code>
     * @return The nullCollation.
     */
    org.apache.drill.exec.proto.UserProtos.NullCollation getNullCollation();

    /**
     * <pre>
     * True if NULL + non NULL is NULL
     * </pre>
     *
     * <code>optional bool null_plus_non_null_equals_null = 33;</code>
     * @return Whether the nullPlusNonNullEqualsNull field is set.
     */
    boolean hasNullPlusNonNullEqualsNull();
    /**
     * <pre>
     * True if NULL + non NULL is NULL
     * </pre>
     *
     * <code>optional bool null_plus_non_null_equals_null = 33;</code>
     * @return The nullPlusNonNullEqualsNull.
     */
    boolean getNullPlusNonNullEqualsNull();

    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @return A list containing the numericFunctions.
     */
    java.util.List<java.lang.String>
        getNumericFunctionsList();
    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @return The count of numericFunctions.
     */
    int getNumericFunctionsCount();
    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @param index The index of the element to return.
     * @return The numericFunctions at the given index.
     */
    java.lang.String getNumericFunctions(int index);
    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @param index The index of the value to return.
     * @return The bytes of the numericFunctions at the given index.
     */
    com.google.protobuf.ByteString
        getNumericFunctionsBytes(int index);

    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
     * @return A list containing the orderBySupport.
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.OrderBySupport> getOrderBySupportList();
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
     * @return The count of orderBySupport.
     */
    int getOrderBySupportCount();
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
     * @param index The index of the element to return.
     * @return The orderBySupport at the given index.
     */
    org.apache.drill.exec.proto.UserProtos.OrderBySupport getOrderBySupport(int index);

    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
     * @return A list containing the outerJoinSupport.
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.OuterJoinSupport> getOuterJoinSupportList();
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
     * @return The count of outerJoinSupport.
     */
    int getOuterJoinSupportCount();
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
     * @param index The index of the element to return.
     * @return The outerJoinSupport at the given index.
     */
    org.apache.drill.exec.proto.UserProtos.OuterJoinSupport getOuterJoinSupport(int index);

    /**
     * <pre>
     * Quoted identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
     * @return Whether the quotedIdentifierCasing field is set.
     */
    boolean hasQuotedIdentifierCasing();
    /**
     * <pre>
     * Quoted identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
     * @return The quotedIdentifierCasing.
     */
    org.apache.drill.exec.proto.UserProtos.IdentifierCasing getQuotedIdentifierCasing();

    /**
     * <pre>
     * True if connection access is read only
     * </pre>
     *
     * <code>optional bool read_only = 38;</code>
     * @return Whether the readOnly field is set.
     */
    boolean hasReadOnly();
    /**
     * <pre>
     * True if connection access is read only
     * </pre>
     *
     * <code>optional bool read_only = 38;</code>
     * @return The readOnly.
     */
    boolean getReadOnly();

    /**
     * <pre>
     * The term used to designate a schema
     * </pre>
     *
     * <code>optional string schema_term = 39;</code>
     * @return Whether the schemaTerm field is set.
     */
    boolean hasSchemaTerm();
    /**
     * <pre>
     * The term used to designate a schema
     * </pre>
     *
     * <code>optional string schema_term = 39;</code>
     * @return The schemaTerm.
     */
    java.lang.String getSchemaTerm();
    /**
     * <pre>
     * The term used to designate a schema
     * </pre>
     *
     * <code>optional string schema_term = 39;</code>
     * @return The bytes for schemaTerm.
     */
    com.google.protobuf.ByteString
        getSchemaTermBytes();

    /**
     * <pre>
     * Characters used for escaping (empty if not suported)
     * </pre>
     *
     * <code>optional string search_escape_string = 40;</code>
     * @return Whether the searchEscapeString field is set.
     */
    boolean hasSearchEscapeString();
    /**
     * <pre>
     * Characters used for escaping (empty if not suported)
     * </pre>
     *
     * <code>optional string search_escape_string = 40;</code>
     * @return The searchEscapeString.
     */
    java.lang.String getSearchEscapeString();
    /**
     * <pre>
     * Characters used for escaping (empty if not suported)
     * </pre>
     *
     * <code>optional string search_escape_string = 40;</code>
     * @return The bytes for searchEscapeString.
     */
    com.google.protobuf.ByteString
        getSearchEscapeStringBytes();

    /**
     * <pre>
     * True if SELECT FOR UPDATE is supported
     * </pre>
     *
     * <code>optional bool select_for_update_supported = 41;</code>
     * @return Whether the selectForUpdateSupported field is set.
     */
    boolean hasSelectForUpdateSupported();
    /**
     * <pre>
     * True if SELECT FOR UPDATE is supported
     * </pre>
     *
     * <code>optional bool select_for_update_supported = 41;</code>
     * @return The selectForUpdateSupported.
     */
    boolean getSelectForUpdateSupported();

    /**
     * <pre>
     * List of extra characters that can be used in identifier names
     * </pre>
     *
     * <code>optional string special_characters = 42;</code>
     * @return Whether the specialCharacters field is set.
     */
    boolean hasSpecialCharacters();
    /**
     * <pre>
     * List of extra characters that can be used in identifier names
     * </pre>
     *
     * <code>optional string special_characters = 42;</code>
     * @return The specialCharacters.
     */
    java.lang.String getSpecialCharacters();
    /**
     * <pre>
     * List of extra characters that can be used in identifier names
     * </pre>
     *
     * <code>optional string special_characters = 42;</code>
     * @return The bytes for specialCharacters.
     */
    com.google.protobuf.ByteString
        getSpecialCharactersBytes();

    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @return A list containing the sqlKeywords.
     */
    java.util.List<java.lang.String>
        getSqlKeywordsList();
    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @return The count of sqlKeywords.
     */
    int getSqlKeywordsCount();
    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @param index The index of the element to return.
     * @return The sqlKeywords at the given index.
     */
    java.lang.String getSqlKeywords(int index);
    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @param index The index of the value to return.
     * @return The bytes of the sqlKeywords at the given index.
     */
    com.google.protobuf.ByteString
        getSqlKeywordsBytes(int index);

    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @return A list containing the stringFunctions.
     */
    java.util.List<java.lang.String>
        getStringFunctionsList();
    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @return The count of stringFunctions.
     */
    int getStringFunctionsCount();
    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @param index The index of the element to return.
     * @return The stringFunctions at the given index.
     */
    java.lang.String getStringFunctions(int index);
    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @param index The index of the value to return.
     * @return The bytes of the stringFunctions at the given index.
     */
    com.google.protobuf.ByteString
        getStringFunctionsBytes(int index);

    /**
     * <pre>
     * Subquery support
     * </pre>
     *
     * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
     * @return A list containing the subquerySupport.
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.SubQuerySupport> getSubquerySupportList();
    /**
     * <pre>
     * Subquery support
     * </pre>
     *
     * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
     * @return The count of subquerySupport.
     */
    int getSubquerySupportCount();
    /**
     * <pre>
     * Subquery support
     * </pre>
     *
     * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
     * @param index The index of the element to return.
     * @return The subquerySupport at the given index.
     */
    org.apache.drill.exec.proto.UserProtos.SubQuerySupport getSubquerySupport(int index);

    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @return A list containing the systemFunctions.
     */
    java.util.List<java.lang.String>
        getSystemFunctionsList();
    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @return The count of systemFunctions.
     */
    int getSystemFunctionsCount();
    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @param index The index of the element to return.
     * @return The systemFunctions at the given index.
     */
    java.lang.String getSystemFunctions(int index);
    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @param index The index of the value to return.
     * @return The bytes of the systemFunctions at the given index.
     */
    com.google.protobuf.ByteString
        getSystemFunctionsBytes(int index);

    /**
     * <pre>
     * The term used to designate a table
     * </pre>
     *
     * <code>optional string table_term = 47;</code>
     * @return Whether the tableTerm field is set.
     */
    boolean hasTableTerm();
    /**
     * <pre>
     * The term used to designate a table
     * </pre>
     *
     * <code>optional string table_term = 47;</code>
     * @return The tableTerm.
     */
    java.lang.String getTableTerm();
    /**
     * <pre>
     * The term used to designate a table
     * </pre>
     *
     * <code>optional string table_term = 47;</code>
     * @return The bytes for tableTerm.
     */
    com.google.protobuf.ByteString
        getTableTermBytes();

    /**
     * <pre>
     * True if transaction is supported
     * </pre>
     *
     * <code>optional bool transaction_supported = 48;</code>
     * @return Whether the transactionSupported field is set.
     */
    boolean hasTransactionSupported();
    /**
     * <pre>
     * True if transaction is supported
     * </pre>
     *
     * <code>optional bool transaction_supported = 48;</code>
     * @return The transactionSupported.
     */
    boolean getTransactionSupported();

    /**
     * <pre>
     * UNION support
     * </pre>
     *
     * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
     * @return A list containing the unionSupport.
     */
    java.util.List<org.apache.drill.exec.proto.UserProtos.UnionSupport> getUnionSupportList();
    /**
     * <pre>
     * UNION support
     * </pre>
     *
     * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
     * @return The count of unionSupport.
     */
    int getUnionSupportCount();
    /**
     * <pre>
     * UNION support
     * </pre>
     *
     * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
     * @param index The index of the element to return.
     * @return The unionSupport at the given index.
     */
    org.apache.drill.exec.proto.UserProtos.UnionSupport getUnionSupport(int index);

    /**
     * <pre>
     * current schema
     * </pre>
     *
     * <code>optional string current_schema = 50;</code>
     * @return Whether the currentSchema field is set.
     */
    boolean hasCurrentSchema();
    /**
     * <pre>
     * current schema
     * </pre>
     *
     * <code>optional string current_schema = 50;</code>
     * @return The currentSchema.
     */
    java.lang.String getCurrentSchema();
    /**
     * <pre>
     * current schema
     * </pre>
     *
     * <code>optional string current_schema = 50;</code>
     * @return The bytes for currentSchema.
     */
    com.google.protobuf.ByteString
        getCurrentSchemaBytes();
  }
  /**
   * Protobuf type {@code exec.user.ServerMeta}
   */
  public static final class ServerMeta extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.ServerMeta)
      ServerMetaOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use ServerMeta.newBuilder() to construct.
    private ServerMeta(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private ServerMeta() {
      catalogSeparator_ = "";
      catalogTerm_ = "";
      collateSupport_ = java.util.Collections.emptyList();
      convertSupport_ = java.util.Collections.emptyList();
      correlationNamesSupport_ = 1;
      dateTimeFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      dateTimeLiteralsSupport_ = java.util.Collections.emptyList();
      groupBySupport_ = 1;
      identifierCasing_ = 0;
      identifierQuoteString_ = "";
      nullCollation_ = 0;
      numericFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      orderBySupport_ = java.util.Collections.emptyList();
      outerJoinSupport_ = java.util.Collections.emptyList();
      quotedIdentifierCasing_ = 0;
      schemaTerm_ = "";
      searchEscapeString_ = "";
      specialCharacters_ = "";
      sqlKeywords_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      stringFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      subquerySupport_ = java.util.Collections.emptyList();
      systemFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      tableTerm_ = "";
      unionSupport_ = java.util.Collections.emptyList();
      currentSchema_ = "";
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new ServerMeta();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ServerMeta_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ServerMeta_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.ServerMeta.class, org.apache.drill.exec.proto.UserProtos.ServerMeta.Builder.class);
    }

    private int bitField0_;
    private int bitField1_;
    public static final int ALL_TABLES_SELECTABLE_FIELD_NUMBER = 1;
    private boolean allTablesSelectable_;
    /**
     * <pre>
     * True if current user can use all tables returned by GetTables
     * </pre>
     *
     * <code>optional bool all_tables_selectable = 1;</code>
     * @return Whether the allTablesSelectable field is set.
     */
    @java.lang.Override
    public boolean hasAllTablesSelectable() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * True if current user can use all tables returned by GetTables
     * </pre>
     *
     * <code>optional bool all_tables_selectable = 1;</code>
     * @return The allTablesSelectable.
     */
    @java.lang.Override
    public boolean getAllTablesSelectable() {
      return allTablesSelectable_;
    }

    public static final int BLOB_INCLUDED_IN_MAX_ROW_SIZE_FIELD_NUMBER = 2;
    private boolean blobIncludedInMaxRowSize_;
    /**
     * <pre>
     * True if BLOB are included into the max row size
     * </pre>
     *
     * <code>optional bool blob_included_in_max_row_size = 2;</code>
     * @return Whether the blobIncludedInMaxRowSize field is set.
     */
    @java.lang.Override
    public boolean hasBlobIncludedInMaxRowSize() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <pre>
     * True if BLOB are included into the max row size
     * </pre>
     *
     * <code>optional bool blob_included_in_max_row_size = 2;</code>
     * @return The blobIncludedInMaxRowSize.
     */
    @java.lang.Override
    public boolean getBlobIncludedInMaxRowSize() {
      return blobIncludedInMaxRowSize_;
    }

    public static final int CATALOG_AT_START_FIELD_NUMBER = 3;
    private boolean catalogAtStart_;
    /**
     * <pre>
     * True if catalog name is at the start of a fully qualified table
     * </pre>
     *
     * <code>optional bool catalog_at_start = 3;</code>
     * @return Whether the catalogAtStart field is set.
     */
    @java.lang.Override
    public boolean hasCatalogAtStart() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <pre>
     * True if catalog name is at the start of a fully qualified table
     * </pre>
     *
     * <code>optional bool catalog_at_start = 3;</code>
     * @return The catalogAtStart.
     */
    @java.lang.Override
    public boolean getCatalogAtStart() {
      return catalogAtStart_;
    }

    public static final int CATALOG_SEPARATOR_FIELD_NUMBER = 4;
    private volatile java.lang.Object catalogSeparator_;
    /**
     * <pre>
     * The catalog separator
     * </pre>
     *
     * <code>optional string catalog_separator = 4;</code>
     * @return Whether the catalogSeparator field is set.
     */
    @java.lang.Override
    public boolean hasCatalogSeparator() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * The catalog separator
     * </pre>
     *
     * <code>optional string catalog_separator = 4;</code>
     * @return The catalogSeparator.
     */
    @java.lang.Override
    public java.lang.String getCatalogSeparator() {
      java.lang.Object ref = catalogSeparator_;
      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()) {
          catalogSeparator_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * The catalog separator
     * </pre>
     *
     * <code>optional string catalog_separator = 4;</code>
     * @return The bytes for catalogSeparator.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCatalogSeparatorBytes() {
      java.lang.Object ref = catalogSeparator_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        catalogSeparator_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int CATALOG_TERM_FIELD_NUMBER = 5;
    private volatile java.lang.Object catalogTerm_;
    /**
     * <pre>
     * The term used to designate catalogs
     * </pre>
     *
     * <code>optional string catalog_term = 5;</code>
     * @return Whether the catalogTerm field is set.
     */
    @java.lang.Override
    public boolean hasCatalogTerm() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <pre>
     * The term used to designate catalogs
     * </pre>
     *
     * <code>optional string catalog_term = 5;</code>
     * @return The catalogTerm.
     */
    @java.lang.Override
    public java.lang.String getCatalogTerm() {
      java.lang.Object ref = catalogTerm_;
      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()) {
          catalogTerm_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * The term used to designate catalogs
     * </pre>
     *
     * <code>optional string catalog_term = 5;</code>
     * @return The bytes for catalogTerm.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCatalogTermBytes() {
      java.lang.Object ref = catalogTerm_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        catalogTerm_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int COLLATE_SUPPORT_FIELD_NUMBER = 6;
    private java.util.List<java.lang.Integer> collateSupport_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.exec.proto.UserProtos.CollateSupport> collateSupport_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.exec.proto.UserProtos.CollateSupport>() {
              public org.apache.drill.exec.proto.UserProtos.CollateSupport convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.exec.proto.UserProtos.CollateSupport result = org.apache.drill.exec.proto.UserProtos.CollateSupport.valueOf(from);
                return result == null ? org.apache.drill.exec.proto.UserProtos.CollateSupport.CS_UNKNOWN : result;
              }
            };
    /**
     * <pre>
     * COLLATE support
     * </pre>
     *
     * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
     * @return A list containing the collateSupport.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.CollateSupport> getCollateSupportList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.exec.proto.UserProtos.CollateSupport>(collateSupport_, collateSupport_converter_);
    }
    /**
     * <pre>
     * COLLATE support
     * </pre>
     *
     * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
     * @return The count of collateSupport.
     */
    @java.lang.Override
    public int getCollateSupportCount() {
      return collateSupport_.size();
    }
    /**
     * <pre>
     * COLLATE support
     * </pre>
     *
     * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
     * @param index The index of the element to return.
     * @return The collateSupport at the given index.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.CollateSupport getCollateSupport(int index) {
      return collateSupport_converter_.convert(collateSupport_.get(index));
    }

    public static final int COLUMN_ALIASING_SUPPORTED_FIELD_NUMBER = 7;
    private boolean columnAliasingSupported_;
    /**
     * <pre>
     * True if column aliasing is supported
     * </pre>
     *
     * <code>optional bool column_aliasing_supported = 7;</code>
     * @return Whether the columnAliasingSupported field is set.
     */
    @java.lang.Override
    public boolean hasColumnAliasingSupported() {
      return ((bitField0_ & 0x00000020) != 0);
    }
    /**
     * <pre>
     * True if column aliasing is supported
     * </pre>
     *
     * <code>optional bool column_aliasing_supported = 7;</code>
     * @return The columnAliasingSupported.
     */
    @java.lang.Override
    public boolean getColumnAliasingSupported() {
      return columnAliasingSupported_;
    }

    public static final int CONVERT_SUPPORT_FIELD_NUMBER = 8;
    private java.util.List<org.apache.drill.exec.proto.UserProtos.ConvertSupport> convertSupport_;
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.ConvertSupport> getConvertSupportList() {
      return convertSupport_;
    }
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder> 
        getConvertSupportOrBuilderList() {
      return convertSupport_;
    }
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    @java.lang.Override
    public int getConvertSupportCount() {
      return convertSupport_.size();
    }
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ConvertSupport getConvertSupport(int index) {
      return convertSupport_.get(index);
    }
    /**
     * <pre>
     * CONVERT support
     * </pre>
     *
     * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder getConvertSupportOrBuilder(
        int index) {
      return convertSupport_.get(index);
    }

    public static final int CORRELATION_NAMES_SUPPORT_FIELD_NUMBER = 9;
    private int correlationNamesSupport_;
    /**
     * <pre>
     * Correlation names support
     * </pre>
     *
     * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
     * @return Whether the correlationNamesSupport field is set.
     */
    @java.lang.Override public boolean hasCorrelationNamesSupport() {
      return ((bitField0_ & 0x00000040) != 0);
    }
    /**
     * <pre>
     * Correlation names support
     * </pre>
     *
     * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
     * @return The correlationNamesSupport.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport getCorrelationNamesSupport() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport result = org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport.valueOf(correlationNamesSupport_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport.CN_NONE : result;
    }

    public static final int DATE_TIME_FUNCTIONS_FIELD_NUMBER = 10;
    private com.google.protobuf.LazyStringList dateTimeFunctions_;
    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @return A list containing the dateTimeFunctions.
     */
    public com.google.protobuf.ProtocolStringList
        getDateTimeFunctionsList() {
      return dateTimeFunctions_;
    }
    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @return The count of dateTimeFunctions.
     */
    public int getDateTimeFunctionsCount() {
      return dateTimeFunctions_.size();
    }
    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @param index The index of the element to return.
     * @return The dateTimeFunctions at the given index.
     */
    public java.lang.String getDateTimeFunctions(int index) {
      return dateTimeFunctions_.get(index);
    }
    /**
     * <pre>
     * Supported ODBC/JDBC Date Time scalar functions
     * </pre>
     *
     * <code>repeated string date_time_functions = 10;</code>
     * @param index The index of the value to return.
     * @return The bytes of the dateTimeFunctions at the given index.
     */
    public com.google.protobuf.ByteString
        getDateTimeFunctionsBytes(int index) {
      return dateTimeFunctions_.getByteString(index);
    }

    public static final int DATE_TIME_LITERALS_SUPPORT_FIELD_NUMBER = 11;
    private java.util.List<java.lang.Integer> dateTimeLiteralsSupport_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport> dateTimeLiteralsSupport_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport>() {
              public org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport result = org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport.valueOf(from);
                return result == null ? org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport.DL_UNKNOWN : result;
              }
            };
    /**
     * <pre>
     * Supported Date Time literals
     * </pre>
     *
     * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
     * @return A list containing the dateTimeLiteralsSupport.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport> getDateTimeLiteralsSupportList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport>(dateTimeLiteralsSupport_, dateTimeLiteralsSupport_converter_);
    }
    /**
     * <pre>
     * Supported Date Time literals
     * </pre>
     *
     * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
     * @return The count of dateTimeLiteralsSupport.
     */
    @java.lang.Override
    public int getDateTimeLiteralsSupportCount() {
      return dateTimeLiteralsSupport_.size();
    }
    /**
     * <pre>
     * Supported Date Time literals
     * </pre>
     *
     * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
     * @param index The index of the element to return.
     * @return The dateTimeLiteralsSupport at the given index.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport getDateTimeLiteralsSupport(int index) {
      return dateTimeLiteralsSupport_converter_.convert(dateTimeLiteralsSupport_.get(index));
    }

    public static final int GROUP_BY_SUPPORT_FIELD_NUMBER = 12;
    private int groupBySupport_;
    /**
     * <pre>
     * Group By support
     * </pre>
     *
     * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
     * @return Whether the groupBySupport field is set.
     */
    @java.lang.Override public boolean hasGroupBySupport() {
      return ((bitField0_ & 0x00000080) != 0);
    }
    /**
     * <pre>
     * Group By support
     * </pre>
     *
     * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
     * @return The groupBySupport.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.GroupBySupport getGroupBySupport() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.GroupBySupport result = org.apache.drill.exec.proto.UserProtos.GroupBySupport.valueOf(groupBySupport_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.GroupBySupport.GB_NONE : result;
    }

    public static final int IDENTIFIER_CASING_FIELD_NUMBER = 13;
    private int identifierCasing_;
    /**
     * <pre>
     * Unquoted Identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
     * @return Whether the identifierCasing field is set.
     */
    @java.lang.Override public boolean hasIdentifierCasing() {
      return ((bitField0_ & 0x00000100) != 0);
    }
    /**
     * <pre>
     * Unquoted Identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
     * @return The identifierCasing.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.IdentifierCasing getIdentifierCasing() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.IdentifierCasing result = org.apache.drill.exec.proto.UserProtos.IdentifierCasing.valueOf(identifierCasing_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.IdentifierCasing.IC_UNKNOWN : result;
    }

    public static final int IDENTIFIER_QUOTE_STRING_FIELD_NUMBER = 14;
    private volatile java.lang.Object identifierQuoteString_;
    /**
     * <pre>
     * Quote string for identifiers
     * </pre>
     *
     * <code>optional string identifier_quote_string = 14;</code>
     * @return Whether the identifierQuoteString field is set.
     */
    @java.lang.Override
    public boolean hasIdentifierQuoteString() {
      return ((bitField0_ & 0x00000200) != 0);
    }
    /**
     * <pre>
     * Quote string for identifiers
     * </pre>
     *
     * <code>optional string identifier_quote_string = 14;</code>
     * @return The identifierQuoteString.
     */
    @java.lang.Override
    public java.lang.String getIdentifierQuoteString() {
      java.lang.Object ref = identifierQuoteString_;
      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()) {
          identifierQuoteString_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Quote string for identifiers
     * </pre>
     *
     * <code>optional string identifier_quote_string = 14;</code>
     * @return The bytes for identifierQuoteString.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getIdentifierQuoteStringBytes() {
      java.lang.Object ref = identifierQuoteString_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        identifierQuoteString_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int LIKE_ESCAPE_CLAUSE_SUPPORTED_FIELD_NUMBER = 15;
    private boolean likeEscapeClauseSupported_;
    /**
     * <pre>
     * True if LIKE supports an ESCAPE clause
     * </pre>
     *
     * <code>optional bool like_escape_clause_supported = 15;</code>
     * @return Whether the likeEscapeClauseSupported field is set.
     */
    @java.lang.Override
    public boolean hasLikeEscapeClauseSupported() {
      return ((bitField0_ & 0x00000400) != 0);
    }
    /**
     * <pre>
     * True if LIKE supports an ESCAPE clause
     * </pre>
     *
     * <code>optional bool like_escape_clause_supported = 15;</code>
     * @return The likeEscapeClauseSupported.
     */
    @java.lang.Override
    public boolean getLikeEscapeClauseSupported() {
      return likeEscapeClauseSupported_;
    }

    public static final int MAX_BINARY_LITERAL_LENGTH_FIELD_NUMBER = 16;
    private int maxBinaryLiteralLength_;
    /**
     * <pre>
     * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_binary_literal_length = 16;</code>
     * @return Whether the maxBinaryLiteralLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxBinaryLiteralLength() {
      return ((bitField0_ & 0x00000800) != 0);
    }
    /**
     * <pre>
     * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_binary_literal_length = 16;</code>
     * @return The maxBinaryLiteralLength.
     */
    @java.lang.Override
    public int getMaxBinaryLiteralLength() {
      return maxBinaryLiteralLength_;
    }

    public static final int MAX_CATALOG_NAME_LENGTH_FIELD_NUMBER = 17;
    private int maxCatalogNameLength_;
    /**
     * <pre>
     * Maximum length of catalog names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_catalog_name_length = 17;</code>
     * @return Whether the maxCatalogNameLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxCatalogNameLength() {
      return ((bitField0_ & 0x00001000) != 0);
    }
    /**
     * <pre>
     * Maximum length of catalog names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_catalog_name_length = 17;</code>
     * @return The maxCatalogNameLength.
     */
    @java.lang.Override
    public int getMaxCatalogNameLength() {
      return maxCatalogNameLength_;
    }

    public static final int MAX_CHAR_LITERAL_LENGTH_FIELD_NUMBER = 18;
    private int maxCharLiteralLength_;
    /**
     * <pre>
     * Maximum number of characters for string literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_char_literal_length = 18;</code>
     * @return Whether the maxCharLiteralLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxCharLiteralLength() {
      return ((bitField0_ & 0x00002000) != 0);
    }
    /**
     * <pre>
     * Maximum number of characters for string literals (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_char_literal_length = 18;</code>
     * @return The maxCharLiteralLength.
     */
    @java.lang.Override
    public int getMaxCharLiteralLength() {
      return maxCharLiteralLength_;
    }

    public static final int MAX_COLUMN_NAME_LENGTH_FIELD_NUMBER = 19;
    private int maxColumnNameLength_;
    /**
     * <pre>
     * Maximum length of column names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_column_name_length = 19;</code>
     * @return Whether the maxColumnNameLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxColumnNameLength() {
      return ((bitField0_ & 0x00004000) != 0);
    }
    /**
     * <pre>
     * Maximum length of column names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_column_name_length = 19;</code>
     * @return The maxColumnNameLength.
     */
    @java.lang.Override
    public int getMaxColumnNameLength() {
      return maxColumnNameLength_;
    }

    public static final int MAX_COLUMNS_IN_GROUP_BY_FIELD_NUMBER = 20;
    private int maxColumnsInGroupBy_;
    /**
     * <pre>
     * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_group_by = 20;</code>
     * @return Whether the maxColumnsInGroupBy field is set.
     */
    @java.lang.Override
    public boolean hasMaxColumnsInGroupBy() {
      return ((bitField0_ & 0x00008000) != 0);
    }
    /**
     * <pre>
     * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_group_by = 20;</code>
     * @return The maxColumnsInGroupBy.
     */
    @java.lang.Override
    public int getMaxColumnsInGroupBy() {
      return maxColumnsInGroupBy_;
    }

    public static final int MAX_COLUMNS_IN_ORDER_BY_FIELD_NUMBER = 21;
    private int maxColumnsInOrderBy_;
    /**
     * <pre>
     * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_order_by = 21;</code>
     * @return Whether the maxColumnsInOrderBy field is set.
     */
    @java.lang.Override
    public boolean hasMaxColumnsInOrderBy() {
      return ((bitField0_ & 0x00010000) != 0);
    }
    /**
     * <pre>
     * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_order_by = 21;</code>
     * @return The maxColumnsInOrderBy.
     */
    @java.lang.Override
    public int getMaxColumnsInOrderBy() {
      return maxColumnsInOrderBy_;
    }

    public static final int MAX_COLUMNS_IN_SELECT_FIELD_NUMBER = 22;
    private int maxColumnsInSelect_;
    /**
     * <pre>
     * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_select = 22;</code>
     * @return Whether the maxColumnsInSelect field is set.
     */
    @java.lang.Override
    public boolean hasMaxColumnsInSelect() {
      return ((bitField0_ & 0x00020000) != 0);
    }
    /**
     * <pre>
     * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_columns_in_select = 22;</code>
     * @return The maxColumnsInSelect.
     */
    @java.lang.Override
    public int getMaxColumnsInSelect() {
      return maxColumnsInSelect_;
    }

    public static final int MAX_CURSOR_NAME_LENGTH_FIELD_NUMBER = 23;
    private int maxCursorNameLength_;
    /**
     * <pre>
     * Maximum length of cursor names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_cursor_name_length = 23;</code>
     * @return Whether the maxCursorNameLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxCursorNameLength() {
      return ((bitField0_ & 0x00040000) != 0);
    }
    /**
     * <pre>
     * Maximum length of cursor names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_cursor_name_length = 23;</code>
     * @return The maxCursorNameLength.
     */
    @java.lang.Override
    public int getMaxCursorNameLength() {
      return maxCursorNameLength_;
    }

    public static final int MAX_LOGICAL_LOB_SIZE_FIELD_NUMBER = 24;
    private int maxLogicalLobSize_;
    /**
     * <pre>
     * Maximum logical size for LOB types (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_logical_lob_size = 24;</code>
     * @return Whether the maxLogicalLobSize field is set.
     */
    @java.lang.Override
    public boolean hasMaxLogicalLobSize() {
      return ((bitField0_ & 0x00080000) != 0);
    }
    /**
     * <pre>
     * Maximum logical size for LOB types (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_logical_lob_size = 24;</code>
     * @return The maxLogicalLobSize.
     */
    @java.lang.Override
    public int getMaxLogicalLobSize() {
      return maxLogicalLobSize_;
    }

    public static final int MAX_ROW_SIZE_FIELD_NUMBER = 25;
    private int maxRowSize_;
    /**
     * <pre>
     * Maximum number of bytes for a single row (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_row_size = 25;</code>
     * @return Whether the maxRowSize field is set.
     */
    @java.lang.Override
    public boolean hasMaxRowSize() {
      return ((bitField0_ & 0x00100000) != 0);
    }
    /**
     * <pre>
     * Maximum number of bytes for a single row (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_row_size = 25;</code>
     * @return The maxRowSize.
     */
    @java.lang.Override
    public int getMaxRowSize() {
      return maxRowSize_;
    }

    public static final int MAX_SCHEMA_NAME_LENGTH_FIELD_NUMBER = 26;
    private int maxSchemaNameLength_;
    /**
     * <pre>
     * Maximum length of schema names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_schema_name_length = 26;</code>
     * @return Whether the maxSchemaNameLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxSchemaNameLength() {
      return ((bitField0_ & 0x00200000) != 0);
    }
    /**
     * <pre>
     * Maximum length of schema names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_schema_name_length = 26;</code>
     * @return The maxSchemaNameLength.
     */
    @java.lang.Override
    public int getMaxSchemaNameLength() {
      return maxSchemaNameLength_;
    }

    public static final int MAX_STATEMENT_LENGTH_FIELD_NUMBER = 27;
    private int maxStatementLength_;
    /**
     * <pre>
     * Maximum length for statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statement_length = 27;</code>
     * @return Whether the maxStatementLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxStatementLength() {
      return ((bitField0_ & 0x00400000) != 0);
    }
    /**
     * <pre>
     * Maximum length for statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statement_length = 27;</code>
     * @return The maxStatementLength.
     */
    @java.lang.Override
    public int getMaxStatementLength() {
      return maxStatementLength_;
    }

    public static final int MAX_STATEMENTS_FIELD_NUMBER = 28;
    private int maxStatements_;
    /**
     * <pre>
     * Maximum number of statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statements = 28;</code>
     * @return Whether the maxStatements field is set.
     */
    @java.lang.Override
    public boolean hasMaxStatements() {
      return ((bitField0_ & 0x00800000) != 0);
    }
    /**
     * <pre>
     * Maximum number of statements (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_statements = 28;</code>
     * @return The maxStatements.
     */
    @java.lang.Override
    public int getMaxStatements() {
      return maxStatements_;
    }

    public static final int MAX_TABLE_NAME_LENGTH_FIELD_NUMBER = 29;
    private int maxTableNameLength_;
    /**
     * <pre>
     * Maximum length of table names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_table_name_length = 29;</code>
     * @return Whether the maxTableNameLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxTableNameLength() {
      return ((bitField0_ & 0x01000000) != 0);
    }
    /**
     * <pre>
     * Maximum length of table names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_table_name_length = 29;</code>
     * @return The maxTableNameLength.
     */
    @java.lang.Override
    public int getMaxTableNameLength() {
      return maxTableNameLength_;
    }

    public static final int MAX_TABLES_IN_SELECT_FIELD_NUMBER = 30;
    private int maxTablesInSelect_;
    /**
     * <pre>
     * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_tables_in_select = 30;</code>
     * @return Whether the maxTablesInSelect field is set.
     */
    @java.lang.Override
    public boolean hasMaxTablesInSelect() {
      return ((bitField0_ & 0x02000000) != 0);
    }
    /**
     * <pre>
     * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_tables_in_select = 30;</code>
     * @return The maxTablesInSelect.
     */
    @java.lang.Override
    public int getMaxTablesInSelect() {
      return maxTablesInSelect_;
    }

    public static final int MAX_USER_NAME_LENGTH_FIELD_NUMBER = 31;
    private int maxUserNameLength_;
    /**
     * <pre>
     * Maximum length of user names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_user_name_length = 31;</code>
     * @return Whether the maxUserNameLength field is set.
     */
    @java.lang.Override
    public boolean hasMaxUserNameLength() {
      return ((bitField0_ & 0x04000000) != 0);
    }
    /**
     * <pre>
     * Maximum length of user names (0 if unlimited or unknown)
     * </pre>
     *
     * <code>optional uint32 max_user_name_length = 31;</code>
     * @return The maxUserNameLength.
     */
    @java.lang.Override
    public int getMaxUserNameLength() {
      return maxUserNameLength_;
    }

    public static final int NULL_COLLATION_FIELD_NUMBER = 32;
    private int nullCollation_;
    /**
     * <pre>
     * How NULL are sorted
     * </pre>
     *
     * <code>optional .exec.user.NullCollation null_collation = 32;</code>
     * @return Whether the nullCollation field is set.
     */
    @java.lang.Override public boolean hasNullCollation() {
      return ((bitField0_ & 0x08000000) != 0);
    }
    /**
     * <pre>
     * How NULL are sorted
     * </pre>
     *
     * <code>optional .exec.user.NullCollation null_collation = 32;</code>
     * @return The nullCollation.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.NullCollation getNullCollation() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.NullCollation result = org.apache.drill.exec.proto.UserProtos.NullCollation.valueOf(nullCollation_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.NullCollation.NC_UNKNOWN : result;
    }

    public static final int NULL_PLUS_NON_NULL_EQUALS_NULL_FIELD_NUMBER = 33;
    private boolean nullPlusNonNullEqualsNull_;
    /**
     * <pre>
     * True if NULL + non NULL is NULL
     * </pre>
     *
     * <code>optional bool null_plus_non_null_equals_null = 33;</code>
     * @return Whether the nullPlusNonNullEqualsNull field is set.
     */
    @java.lang.Override
    public boolean hasNullPlusNonNullEqualsNull() {
      return ((bitField0_ & 0x10000000) != 0);
    }
    /**
     * <pre>
     * True if NULL + non NULL is NULL
     * </pre>
     *
     * <code>optional bool null_plus_non_null_equals_null = 33;</code>
     * @return The nullPlusNonNullEqualsNull.
     */
    @java.lang.Override
    public boolean getNullPlusNonNullEqualsNull() {
      return nullPlusNonNullEqualsNull_;
    }

    public static final int NUMERIC_FUNCTIONS_FIELD_NUMBER = 34;
    private com.google.protobuf.LazyStringList numericFunctions_;
    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @return A list containing the numericFunctions.
     */
    public com.google.protobuf.ProtocolStringList
        getNumericFunctionsList() {
      return numericFunctions_;
    }
    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @return The count of numericFunctions.
     */
    public int getNumericFunctionsCount() {
      return numericFunctions_.size();
    }
    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @param index The index of the element to return.
     * @return The numericFunctions at the given index.
     */
    public java.lang.String getNumericFunctions(int index) {
      return numericFunctions_.get(index);
    }
    /**
     * <pre>
     * Supported ODBC/JDBC numeric scalar functions
     * </pre>
     *
     * <code>repeated string numeric_functions = 34;</code>
     * @param index The index of the value to return.
     * @return The bytes of the numericFunctions at the given index.
     */
    public com.google.protobuf.ByteString
        getNumericFunctionsBytes(int index) {
      return numericFunctions_.getByteString(index);
    }

    public static final int ORDER_BY_SUPPORT_FIELD_NUMBER = 35;
    private java.util.List<java.lang.Integer> orderBySupport_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OrderBySupport> orderBySupport_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OrderBySupport>() {
              public org.apache.drill.exec.proto.UserProtos.OrderBySupport convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.exec.proto.UserProtos.OrderBySupport result = org.apache.drill.exec.proto.UserProtos.OrderBySupport.valueOf(from);
                return result == null ? org.apache.drill.exec.proto.UserProtos.OrderBySupport.OB_UNKNOWN : result;
              }
            };
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
     * @return A list containing the orderBySupport.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.OrderBySupport> getOrderBySupportList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OrderBySupport>(orderBySupport_, orderBySupport_converter_);
    }
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
     * @return The count of orderBySupport.
     */
    @java.lang.Override
    public int getOrderBySupportCount() {
      return orderBySupport_.size();
    }
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
     * @param index The index of the element to return.
     * @return The orderBySupport at the given index.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.OrderBySupport getOrderBySupport(int index) {
      return orderBySupport_converter_.convert(orderBySupport_.get(index));
    }

    public static final int OUTER_JOIN_SUPPORT_FIELD_NUMBER = 36;
    private java.util.List<java.lang.Integer> outerJoinSupport_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OuterJoinSupport> outerJoinSupport_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OuterJoinSupport>() {
              public org.apache.drill.exec.proto.UserProtos.OuterJoinSupport convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.exec.proto.UserProtos.OuterJoinSupport result = org.apache.drill.exec.proto.UserProtos.OuterJoinSupport.valueOf(from);
                return result == null ? org.apache.drill.exec.proto.UserProtos.OuterJoinSupport.OJ_UNKNOWN : result;
              }
            };
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
     * @return A list containing the outerJoinSupport.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.OuterJoinSupport> getOuterJoinSupportList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OuterJoinSupport>(outerJoinSupport_, outerJoinSupport_converter_);
    }
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
     * @return The count of outerJoinSupport.
     */
    @java.lang.Override
    public int getOuterJoinSupportCount() {
      return outerJoinSupport_.size();
    }
    /**
     * <pre>
     * Outer join suport
     * </pre>
     *
     * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
     * @param index The index of the element to return.
     * @return The outerJoinSupport at the given index.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.OuterJoinSupport getOuterJoinSupport(int index) {
      return outerJoinSupport_converter_.convert(outerJoinSupport_.get(index));
    }

    public static final int QUOTED_IDENTIFIER_CASING_FIELD_NUMBER = 37;
    private int quotedIdentifierCasing_;
    /**
     * <pre>
     * Quoted identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
     * @return Whether the quotedIdentifierCasing field is set.
     */
    @java.lang.Override public boolean hasQuotedIdentifierCasing() {
      return ((bitField0_ & 0x20000000) != 0);
    }
    /**
     * <pre>
     * Quoted identifier casing
     * </pre>
     *
     * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
     * @return The quotedIdentifierCasing.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.IdentifierCasing getQuotedIdentifierCasing() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.IdentifierCasing result = org.apache.drill.exec.proto.UserProtos.IdentifierCasing.valueOf(quotedIdentifierCasing_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.IdentifierCasing.IC_UNKNOWN : result;
    }

    public static final int READ_ONLY_FIELD_NUMBER = 38;
    private boolean readOnly_;
    /**
     * <pre>
     * True if connection access is read only
     * </pre>
     *
     * <code>optional bool read_only = 38;</code>
     * @return Whether the readOnly field is set.
     */
    @java.lang.Override
    public boolean hasReadOnly() {
      return ((bitField0_ & 0x40000000) != 0);
    }
    /**
     * <pre>
     * True if connection access is read only
     * </pre>
     *
     * <code>optional bool read_only = 38;</code>
     * @return The readOnly.
     */
    @java.lang.Override
    public boolean getReadOnly() {
      return readOnly_;
    }

    public static final int SCHEMA_TERM_FIELD_NUMBER = 39;
    private volatile java.lang.Object schemaTerm_;
    /**
     * <pre>
     * The term used to designate a schema
     * </pre>
     *
     * <code>optional string schema_term = 39;</code>
     * @return Whether the schemaTerm field is set.
     */
    @java.lang.Override
    public boolean hasSchemaTerm() {
      return ((bitField0_ & 0x80000000) != 0);
    }
    /**
     * <pre>
     * The term used to designate a schema
     * </pre>
     *
     * <code>optional string schema_term = 39;</code>
     * @return The schemaTerm.
     */
    @java.lang.Override
    public java.lang.String getSchemaTerm() {
      java.lang.Object ref = schemaTerm_;
      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()) {
          schemaTerm_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * The term used to designate a schema
     * </pre>
     *
     * <code>optional string schema_term = 39;</code>
     * @return The bytes for schemaTerm.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSchemaTermBytes() {
      java.lang.Object ref = schemaTerm_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        schemaTerm_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SEARCH_ESCAPE_STRING_FIELD_NUMBER = 40;
    private volatile java.lang.Object searchEscapeString_;
    /**
     * <pre>
     * Characters used for escaping (empty if not suported)
     * </pre>
     *
     * <code>optional string search_escape_string = 40;</code>
     * @return Whether the searchEscapeString field is set.
     */
    @java.lang.Override
    public boolean hasSearchEscapeString() {
      return ((bitField1_ & 0x00000001) != 0);
    }
    /**
     * <pre>
     * Characters used for escaping (empty if not suported)
     * </pre>
     *
     * <code>optional string search_escape_string = 40;</code>
     * @return The searchEscapeString.
     */
    @java.lang.Override
    public java.lang.String getSearchEscapeString() {
      java.lang.Object ref = searchEscapeString_;
      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()) {
          searchEscapeString_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Characters used for escaping (empty if not suported)
     * </pre>
     *
     * <code>optional string search_escape_string = 40;</code>
     * @return The bytes for searchEscapeString.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSearchEscapeStringBytes() {
      java.lang.Object ref = searchEscapeString_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        searchEscapeString_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SELECT_FOR_UPDATE_SUPPORTED_FIELD_NUMBER = 41;
    private boolean selectForUpdateSupported_;
    /**
     * <pre>
     * True if SELECT FOR UPDATE is supported
     * </pre>
     *
     * <code>optional bool select_for_update_supported = 41;</code>
     * @return Whether the selectForUpdateSupported field is set.
     */
    @java.lang.Override
    public boolean hasSelectForUpdateSupported() {
      return ((bitField1_ & 0x00000002) != 0);
    }
    /**
     * <pre>
     * True if SELECT FOR UPDATE is supported
     * </pre>
     *
     * <code>optional bool select_for_update_supported = 41;</code>
     * @return The selectForUpdateSupported.
     */
    @java.lang.Override
    public boolean getSelectForUpdateSupported() {
      return selectForUpdateSupported_;
    }

    public static final int SPECIAL_CHARACTERS_FIELD_NUMBER = 42;
    private volatile java.lang.Object specialCharacters_;
    /**
     * <pre>
     * List of extra characters that can be used in identifier names
     * </pre>
     *
     * <code>optional string special_characters = 42;</code>
     * @return Whether the specialCharacters field is set.
     */
    @java.lang.Override
    public boolean hasSpecialCharacters() {
      return ((bitField1_ & 0x00000004) != 0);
    }
    /**
     * <pre>
     * List of extra characters that can be used in identifier names
     * </pre>
     *
     * <code>optional string special_characters = 42;</code>
     * @return The specialCharacters.
     */
    @java.lang.Override
    public java.lang.String getSpecialCharacters() {
      java.lang.Object ref = specialCharacters_;
      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()) {
          specialCharacters_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * List of extra characters that can be used in identifier names
     * </pre>
     *
     * <code>optional string special_characters = 42;</code>
     * @return The bytes for specialCharacters.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getSpecialCharactersBytes() {
      java.lang.Object ref = specialCharacters_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        specialCharacters_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int SQL_KEYWORDS_FIELD_NUMBER = 43;
    private com.google.protobuf.LazyStringList sqlKeywords_;
    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @return A list containing the sqlKeywords.
     */
    public com.google.protobuf.ProtocolStringList
        getSqlKeywordsList() {
      return sqlKeywords_;
    }
    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @return The count of sqlKeywords.
     */
    public int getSqlKeywordsCount() {
      return sqlKeywords_.size();
    }
    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @param index The index of the element to return.
     * @return The sqlKeywords at the given index.
     */
    public java.lang.String getSqlKeywords(int index) {
      return sqlKeywords_.get(index);
    }
    /**
     * <pre>
     * list of SQL keywords
     * </pre>
     *
     * <code>repeated string sql_keywords = 43;</code>
     * @param index The index of the value to return.
     * @return The bytes of the sqlKeywords at the given index.
     */
    public com.google.protobuf.ByteString
        getSqlKeywordsBytes(int index) {
      return sqlKeywords_.getByteString(index);
    }

    public static final int STRING_FUNCTIONS_FIELD_NUMBER = 44;
    private com.google.protobuf.LazyStringList stringFunctions_;
    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @return A list containing the stringFunctions.
     */
    public com.google.protobuf.ProtocolStringList
        getStringFunctionsList() {
      return stringFunctions_;
    }
    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @return The count of stringFunctions.
     */
    public int getStringFunctionsCount() {
      return stringFunctions_.size();
    }
    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @param index The index of the element to return.
     * @return The stringFunctions at the given index.
     */
    public java.lang.String getStringFunctions(int index) {
      return stringFunctions_.get(index);
    }
    /**
     * <pre>
     * Supported ODBC/JDBC string scalar functions
     * </pre>
     *
     * <code>repeated string string_functions = 44;</code>
     * @param index The index of the value to return.
     * @return The bytes of the stringFunctions at the given index.
     */
    public com.google.protobuf.ByteString
        getStringFunctionsBytes(int index) {
      return stringFunctions_.getByteString(index);
    }

    public static final int SUBQUERY_SUPPORT_FIELD_NUMBER = 45;
    private java.util.List<java.lang.Integer> subquerySupport_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.exec.proto.UserProtos.SubQuerySupport> subquerySupport_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.exec.proto.UserProtos.SubQuerySupport>() {
              public org.apache.drill.exec.proto.UserProtos.SubQuerySupport convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.exec.proto.UserProtos.SubQuerySupport result = org.apache.drill.exec.proto.UserProtos.SubQuerySupport.valueOf(from);
                return result == null ? org.apache.drill.exec.proto.UserProtos.SubQuerySupport.SQ_UNKNOWN : result;
              }
            };
    /**
     * <pre>
     * Subquery support
     * </pre>
     *
     * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
     * @return A list containing the subquerySupport.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.SubQuerySupport> getSubquerySupportList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.exec.proto.UserProtos.SubQuerySupport>(subquerySupport_, subquerySupport_converter_);
    }
    /**
     * <pre>
     * Subquery support
     * </pre>
     *
     * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
     * @return The count of subquerySupport.
     */
    @java.lang.Override
    public int getSubquerySupportCount() {
      return subquerySupport_.size();
    }
    /**
     * <pre>
     * Subquery support
     * </pre>
     *
     * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
     * @param index The index of the element to return.
     * @return The subquerySupport at the given index.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.SubQuerySupport getSubquerySupport(int index) {
      return subquerySupport_converter_.convert(subquerySupport_.get(index));
    }

    public static final int SYSTEM_FUNCTIONS_FIELD_NUMBER = 46;
    private com.google.protobuf.LazyStringList systemFunctions_;
    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @return A list containing the systemFunctions.
     */
    public com.google.protobuf.ProtocolStringList
        getSystemFunctionsList() {
      return systemFunctions_;
    }
    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @return The count of systemFunctions.
     */
    public int getSystemFunctionsCount() {
      return systemFunctions_.size();
    }
    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @param index The index of the element to return.
     * @return The systemFunctions at the given index.
     */
    public java.lang.String getSystemFunctions(int index) {
      return systemFunctions_.get(index);
    }
    /**
     * <pre>
     * Supported ODBC/JDBC systen scalar functions
     * </pre>
     *
     * <code>repeated string system_functions = 46;</code>
     * @param index The index of the value to return.
     * @return The bytes of the systemFunctions at the given index.
     */
    public com.google.protobuf.ByteString
        getSystemFunctionsBytes(int index) {
      return systemFunctions_.getByteString(index);
    }

    public static final int TABLE_TERM_FIELD_NUMBER = 47;
    private volatile java.lang.Object tableTerm_;
    /**
     * <pre>
     * The term used to designate a table
     * </pre>
     *
     * <code>optional string table_term = 47;</code>
     * @return Whether the tableTerm field is set.
     */
    @java.lang.Override
    public boolean hasTableTerm() {
      return ((bitField1_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * The term used to designate a table
     * </pre>
     *
     * <code>optional string table_term = 47;</code>
     * @return The tableTerm.
     */
    @java.lang.Override
    public java.lang.String getTableTerm() {
      java.lang.Object ref = tableTerm_;
      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()) {
          tableTerm_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * The term used to designate a table
     * </pre>
     *
     * <code>optional string table_term = 47;</code>
     * @return The bytes for tableTerm.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getTableTermBytes() {
      java.lang.Object ref = tableTerm_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        tableTerm_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int TRANSACTION_SUPPORTED_FIELD_NUMBER = 48;
    private boolean transactionSupported_;
    /**
     * <pre>
     * True if transaction is supported
     * </pre>
     *
     * <code>optional bool transaction_supported = 48;</code>
     * @return Whether the transactionSupported field is set.
     */
    @java.lang.Override
    public boolean hasTransactionSupported() {
      return ((bitField1_ & 0x00000010) != 0);
    }
    /**
     * <pre>
     * True if transaction is supported
     * </pre>
     *
     * <code>optional bool transaction_supported = 48;</code>
     * @return The transactionSupported.
     */
    @java.lang.Override
    public boolean getTransactionSupported() {
      return transactionSupported_;
    }

    public static final int UNION_SUPPORT_FIELD_NUMBER = 49;
    private java.util.List<java.lang.Integer> unionSupport_;
    private static final com.google.protobuf.Internal.ListAdapter.Converter<
        java.lang.Integer, org.apache.drill.exec.proto.UserProtos.UnionSupport> unionSupport_converter_ =
            new com.google.protobuf.Internal.ListAdapter.Converter<
                java.lang.Integer, org.apache.drill.exec.proto.UserProtos.UnionSupport>() {
              public org.apache.drill.exec.proto.UserProtos.UnionSupport convert(java.lang.Integer from) {
                @SuppressWarnings("deprecation")
                org.apache.drill.exec.proto.UserProtos.UnionSupport result = org.apache.drill.exec.proto.UserProtos.UnionSupport.valueOf(from);
                return result == null ? org.apache.drill.exec.proto.UserProtos.UnionSupport.U_UNKNOWN : result;
              }
            };
    /**
     * <pre>
     * UNION support
     * </pre>
     *
     * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
     * @return A list containing the unionSupport.
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.UserProtos.UnionSupport> getUnionSupportList() {
      return new com.google.protobuf.Internal.ListAdapter<
          java.lang.Integer, org.apache.drill.exec.proto.UserProtos.UnionSupport>(unionSupport_, unionSupport_converter_);
    }
    /**
     * <pre>
     * UNION support
     * </pre>
     *
     * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
     * @return The count of unionSupport.
     */
    @java.lang.Override
    public int getUnionSupportCount() {
      return unionSupport_.size();
    }
    /**
     * <pre>
     * UNION support
     * </pre>
     *
     * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
     * @param index The index of the element to return.
     * @return The unionSupport at the given index.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.UnionSupport getUnionSupport(int index) {
      return unionSupport_converter_.convert(unionSupport_.get(index));
    }

    public static final int CURRENT_SCHEMA_FIELD_NUMBER = 50;
    private volatile java.lang.Object currentSchema_;
    /**
     * <pre>
     * current schema
     * </pre>
     *
     * <code>optional string current_schema = 50;</code>
     * @return Whether the currentSchema field is set.
     */
    @java.lang.Override
    public boolean hasCurrentSchema() {
      return ((bitField1_ & 0x00000020) != 0);
    }
    /**
     * <pre>
     * current schema
     * </pre>
     *
     * <code>optional string current_schema = 50;</code>
     * @return The currentSchema.
     */
    @java.lang.Override
    public java.lang.String getCurrentSchema() {
      java.lang.Object ref = currentSchema_;
      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()) {
          currentSchema_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * current schema
     * </pre>
     *
     * <code>optional string current_schema = 50;</code>
     * @return The bytes for currentSchema.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getCurrentSchemaBytes() {
      java.lang.Object ref = currentSchema_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        currentSchema_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      for (int i = 0; i < getConvertSupportCount(); i++) {
        if (!getConvertSupport(i).isInitialized()) {
          memoizedIsInitialized = 0;
          return false;
        }
      }
      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeBool(1, allTablesSelectable_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeBool(2, blobIncludedInMaxRowSize_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        output.writeBool(3, catalogAtStart_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 4, catalogSeparator_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 5, catalogTerm_);
      }
      for (int i = 0; i < collateSupport_.size(); i++) {
        output.writeEnum(6, collateSupport_.get(i));
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        output.writeBool(7, columnAliasingSupported_);
      }
      for (int i = 0; i < convertSupport_.size(); i++) {
        output.writeMessage(8, convertSupport_.get(i));
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        output.writeEnum(9, correlationNamesSupport_);
      }
      for (int i = 0; i < dateTimeFunctions_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 10, dateTimeFunctions_.getRaw(i));
      }
      for (int i = 0; i < dateTimeLiteralsSupport_.size(); i++) {
        output.writeEnum(11, dateTimeLiteralsSupport_.get(i));
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        output.writeEnum(12, groupBySupport_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        output.writeEnum(13, identifierCasing_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 14, identifierQuoteString_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        output.writeBool(15, likeEscapeClauseSupported_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        output.writeUInt32(16, maxBinaryLiteralLength_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        output.writeUInt32(17, maxCatalogNameLength_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        output.writeUInt32(18, maxCharLiteralLength_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        output.writeUInt32(19, maxColumnNameLength_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        output.writeUInt32(20, maxColumnsInGroupBy_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        output.writeUInt32(21, maxColumnsInOrderBy_);
      }
      if (((bitField0_ & 0x00020000) != 0)) {
        output.writeUInt32(22, maxColumnsInSelect_);
      }
      if (((bitField0_ & 0x00040000) != 0)) {
        output.writeUInt32(23, maxCursorNameLength_);
      }
      if (((bitField0_ & 0x00080000) != 0)) {
        output.writeUInt32(24, maxLogicalLobSize_);
      }
      if (((bitField0_ & 0x00100000) != 0)) {
        output.writeUInt32(25, maxRowSize_);
      }
      if (((bitField0_ & 0x00200000) != 0)) {
        output.writeUInt32(26, maxSchemaNameLength_);
      }
      if (((bitField0_ & 0x00400000) != 0)) {
        output.writeUInt32(27, maxStatementLength_);
      }
      if (((bitField0_ & 0x00800000) != 0)) {
        output.writeUInt32(28, maxStatements_);
      }
      if (((bitField0_ & 0x01000000) != 0)) {
        output.writeUInt32(29, maxTableNameLength_);
      }
      if (((bitField0_ & 0x02000000) != 0)) {
        output.writeUInt32(30, maxTablesInSelect_);
      }
      if (((bitField0_ & 0x04000000) != 0)) {
        output.writeUInt32(31, maxUserNameLength_);
      }
      if (((bitField0_ & 0x08000000) != 0)) {
        output.writeEnum(32, nullCollation_);
      }
      if (((bitField0_ & 0x10000000) != 0)) {
        output.writeBool(33, nullPlusNonNullEqualsNull_);
      }
      for (int i = 0; i < numericFunctions_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 34, numericFunctions_.getRaw(i));
      }
      for (int i = 0; i < orderBySupport_.size(); i++) {
        output.writeEnum(35, orderBySupport_.get(i));
      }
      for (int i = 0; i < outerJoinSupport_.size(); i++) {
        output.writeEnum(36, outerJoinSupport_.get(i));
      }
      if (((bitField0_ & 0x20000000) != 0)) {
        output.writeEnum(37, quotedIdentifierCasing_);
      }
      if (((bitField0_ & 0x40000000) != 0)) {
        output.writeBool(38, readOnly_);
      }
      if (((bitField0_ & 0x80000000) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 39, schemaTerm_);
      }
      if (((bitField1_ & 0x00000001) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 40, searchEscapeString_);
      }
      if (((bitField1_ & 0x00000002) != 0)) {
        output.writeBool(41, selectForUpdateSupported_);
      }
      if (((bitField1_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 42, specialCharacters_);
      }
      for (int i = 0; i < sqlKeywords_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 43, sqlKeywords_.getRaw(i));
      }
      for (int i = 0; i < stringFunctions_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 44, stringFunctions_.getRaw(i));
      }
      for (int i = 0; i < subquerySupport_.size(); i++) {
        output.writeEnum(45, subquerySupport_.get(i));
      }
      for (int i = 0; i < systemFunctions_.size(); i++) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 46, systemFunctions_.getRaw(i));
      }
      if (((bitField1_ & 0x00000008) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 47, tableTerm_);
      }
      if (((bitField1_ & 0x00000010) != 0)) {
        output.writeBool(48, transactionSupported_);
      }
      for (int i = 0; i < unionSupport_.size(); i++) {
        output.writeEnum(49, unionSupport_.get(i));
      }
      if (((bitField1_ & 0x00000020) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 50, currentSchema_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(1, allTablesSelectable_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(2, blobIncludedInMaxRowSize_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(3, catalogAtStart_);
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, catalogSeparator_);
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, catalogTerm_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < collateSupport_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(collateSupport_.get(i));
        }
        size += dataSize;
        size += 1 * collateSupport_.size();
      }
      if (((bitField0_ & 0x00000020) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(7, columnAliasingSupported_);
      }
      for (int i = 0; i < convertSupport_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(8, convertSupport_.get(i));
      }
      if (((bitField0_ & 0x00000040) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(9, correlationNamesSupport_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < dateTimeFunctions_.size(); i++) {
          dataSize += computeStringSizeNoTag(dateTimeFunctions_.getRaw(i));
        }
        size += dataSize;
        size += 1 * getDateTimeFunctionsList().size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < dateTimeLiteralsSupport_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(dateTimeLiteralsSupport_.get(i));
        }
        size += dataSize;
        size += 1 * dateTimeLiteralsSupport_.size();
      }
      if (((bitField0_ & 0x00000080) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(12, groupBySupport_);
      }
      if (((bitField0_ & 0x00000100) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(13, identifierCasing_);
      }
      if (((bitField0_ & 0x00000200) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(14, identifierQuoteString_);
      }
      if (((bitField0_ & 0x00000400) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(15, likeEscapeClauseSupported_);
      }
      if (((bitField0_ & 0x00000800) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(16, maxBinaryLiteralLength_);
      }
      if (((bitField0_ & 0x00001000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(17, maxCatalogNameLength_);
      }
      if (((bitField0_ & 0x00002000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(18, maxCharLiteralLength_);
      }
      if (((bitField0_ & 0x00004000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(19, maxColumnNameLength_);
      }
      if (((bitField0_ & 0x00008000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(20, maxColumnsInGroupBy_);
      }
      if (((bitField0_ & 0x00010000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(21, maxColumnsInOrderBy_);
      }
      if (((bitField0_ & 0x00020000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(22, maxColumnsInSelect_);
      }
      if (((bitField0_ & 0x00040000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(23, maxCursorNameLength_);
      }
      if (((bitField0_ & 0x00080000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(24, maxLogicalLobSize_);
      }
      if (((bitField0_ & 0x00100000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(25, maxRowSize_);
      }
      if (((bitField0_ & 0x00200000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(26, maxSchemaNameLength_);
      }
      if (((bitField0_ & 0x00400000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(27, maxStatementLength_);
      }
      if (((bitField0_ & 0x00800000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(28, maxStatements_);
      }
      if (((bitField0_ & 0x01000000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(29, maxTableNameLength_);
      }
      if (((bitField0_ & 0x02000000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(30, maxTablesInSelect_);
      }
      if (((bitField0_ & 0x04000000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeUInt32Size(31, maxUserNameLength_);
      }
      if (((bitField0_ & 0x08000000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(32, nullCollation_);
      }
      if (((bitField0_ & 0x10000000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(33, nullPlusNonNullEqualsNull_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < numericFunctions_.size(); i++) {
          dataSize += computeStringSizeNoTag(numericFunctions_.getRaw(i));
        }
        size += dataSize;
        size += 2 * getNumericFunctionsList().size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < orderBySupport_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(orderBySupport_.get(i));
        }
        size += dataSize;
        size += 2 * orderBySupport_.size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < outerJoinSupport_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(outerJoinSupport_.get(i));
        }
        size += dataSize;
        size += 2 * outerJoinSupport_.size();
      }
      if (((bitField0_ & 0x20000000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(37, quotedIdentifierCasing_);
      }
      if (((bitField0_ & 0x40000000) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(38, readOnly_);
      }
      if (((bitField0_ & 0x80000000) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(39, schemaTerm_);
      }
      if (((bitField1_ & 0x00000001) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(40, searchEscapeString_);
      }
      if (((bitField1_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(41, selectForUpdateSupported_);
      }
      if (((bitField1_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(42, specialCharacters_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < sqlKeywords_.size(); i++) {
          dataSize += computeStringSizeNoTag(sqlKeywords_.getRaw(i));
        }
        size += dataSize;
        size += 2 * getSqlKeywordsList().size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < stringFunctions_.size(); i++) {
          dataSize += computeStringSizeNoTag(stringFunctions_.getRaw(i));
        }
        size += dataSize;
        size += 2 * getStringFunctionsList().size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < subquerySupport_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(subquerySupport_.get(i));
        }
        size += dataSize;
        size += 2 * subquerySupport_.size();
      }
      {
        int dataSize = 0;
        for (int i = 0; i < systemFunctions_.size(); i++) {
          dataSize += computeStringSizeNoTag(systemFunctions_.getRaw(i));
        }
        size += dataSize;
        size += 2 * getSystemFunctionsList().size();
      }
      if (((bitField1_ & 0x00000008) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(47, tableTerm_);
      }
      if (((bitField1_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeBoolSize(48, transactionSupported_);
      }
      {
        int dataSize = 0;
        for (int i = 0; i < unionSupport_.size(); i++) {
          dataSize += com.google.protobuf.CodedOutputStream
            .computeEnumSizeNoTag(unionSupport_.get(i));
        }
        size += dataSize;
        size += 2 * unionSupport_.size();
      }
      if (((bitField1_ & 0x00000020) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(50, currentSchema_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.ServerMeta)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.ServerMeta other = (org.apache.drill.exec.proto.UserProtos.ServerMeta) obj;

      if (hasAllTablesSelectable() != other.hasAllTablesSelectable()) return false;
      if (hasAllTablesSelectable()) {
        if (getAllTablesSelectable()
            != other.getAllTablesSelectable()) return false;
      }
      if (hasBlobIncludedInMaxRowSize() != other.hasBlobIncludedInMaxRowSize()) return false;
      if (hasBlobIncludedInMaxRowSize()) {
        if (getBlobIncludedInMaxRowSize()
            != other.getBlobIncludedInMaxRowSize()) return false;
      }
      if (hasCatalogAtStart() != other.hasCatalogAtStart()) return false;
      if (hasCatalogAtStart()) {
        if (getCatalogAtStart()
            != other.getCatalogAtStart()) return false;
      }
      if (hasCatalogSeparator() != other.hasCatalogSeparator()) return false;
      if (hasCatalogSeparator()) {
        if (!getCatalogSeparator()
            .equals(other.getCatalogSeparator())) return false;
      }
      if (hasCatalogTerm() != other.hasCatalogTerm()) return false;
      if (hasCatalogTerm()) {
        if (!getCatalogTerm()
            .equals(other.getCatalogTerm())) return false;
      }
      if (!collateSupport_.equals(other.collateSupport_)) return false;
      if (hasColumnAliasingSupported() != other.hasColumnAliasingSupported()) return false;
      if (hasColumnAliasingSupported()) {
        if (getColumnAliasingSupported()
            != other.getColumnAliasingSupported()) return false;
      }
      if (!getConvertSupportList()
          .equals(other.getConvertSupportList())) return false;
      if (hasCorrelationNamesSupport() != other.hasCorrelationNamesSupport()) return false;
      if (hasCorrelationNamesSupport()) {
        if (correlationNamesSupport_ != other.correlationNamesSupport_) return false;
      }
      if (!getDateTimeFunctionsList()
          .equals(other.getDateTimeFunctionsList())) return false;
      if (!dateTimeLiteralsSupport_.equals(other.dateTimeLiteralsSupport_)) return false;
      if (hasGroupBySupport() != other.hasGroupBySupport()) return false;
      if (hasGroupBySupport()) {
        if (groupBySupport_ != other.groupBySupport_) return false;
      }
      if (hasIdentifierCasing() != other.hasIdentifierCasing()) return false;
      if (hasIdentifierCasing()) {
        if (identifierCasing_ != other.identifierCasing_) return false;
      }
      if (hasIdentifierQuoteString() != other.hasIdentifierQuoteString()) return false;
      if (hasIdentifierQuoteString()) {
        if (!getIdentifierQuoteString()
            .equals(other.getIdentifierQuoteString())) return false;
      }
      if (hasLikeEscapeClauseSupported() != other.hasLikeEscapeClauseSupported()) return false;
      if (hasLikeEscapeClauseSupported()) {
        if (getLikeEscapeClauseSupported()
            != other.getLikeEscapeClauseSupported()) return false;
      }
      if (hasMaxBinaryLiteralLength() != other.hasMaxBinaryLiteralLength()) return false;
      if (hasMaxBinaryLiteralLength()) {
        if (getMaxBinaryLiteralLength()
            != other.getMaxBinaryLiteralLength()) return false;
      }
      if (hasMaxCatalogNameLength() != other.hasMaxCatalogNameLength()) return false;
      if (hasMaxCatalogNameLength()) {
        if (getMaxCatalogNameLength()
            != other.getMaxCatalogNameLength()) return false;
      }
      if (hasMaxCharLiteralLength() != other.hasMaxCharLiteralLength()) return false;
      if (hasMaxCharLiteralLength()) {
        if (getMaxCharLiteralLength()
            != other.getMaxCharLiteralLength()) return false;
      }
      if (hasMaxColumnNameLength() != other.hasMaxColumnNameLength()) return false;
      if (hasMaxColumnNameLength()) {
        if (getMaxColumnNameLength()
            != other.getMaxColumnNameLength()) return false;
      }
      if (hasMaxColumnsInGroupBy() != other.hasMaxColumnsInGroupBy()) return false;
      if (hasMaxColumnsInGroupBy()) {
        if (getMaxColumnsInGroupBy()
            != other.getMaxColumnsInGroupBy()) return false;
      }
      if (hasMaxColumnsInOrderBy() != other.hasMaxColumnsInOrderBy()) return false;
      if (hasMaxColumnsInOrderBy()) {
        if (getMaxColumnsInOrderBy()
            != other.getMaxColumnsInOrderBy()) return false;
      }
      if (hasMaxColumnsInSelect() != other.hasMaxColumnsInSelect()) return false;
      if (hasMaxColumnsInSelect()) {
        if (getMaxColumnsInSelect()
            != other.getMaxColumnsInSelect()) return false;
      }
      if (hasMaxCursorNameLength() != other.hasMaxCursorNameLength()) return false;
      if (hasMaxCursorNameLength()) {
        if (getMaxCursorNameLength()
            != other.getMaxCursorNameLength()) return false;
      }
      if (hasMaxLogicalLobSize() != other.hasMaxLogicalLobSize()) return false;
      if (hasMaxLogicalLobSize()) {
        if (getMaxLogicalLobSize()
            != other.getMaxLogicalLobSize()) return false;
      }
      if (hasMaxRowSize() != other.hasMaxRowSize()) return false;
      if (hasMaxRowSize()) {
        if (getMaxRowSize()
            != other.getMaxRowSize()) return false;
      }
      if (hasMaxSchemaNameLength() != other.hasMaxSchemaNameLength()) return false;
      if (hasMaxSchemaNameLength()) {
        if (getMaxSchemaNameLength()
            != other.getMaxSchemaNameLength()) return false;
      }
      if (hasMaxStatementLength() != other.hasMaxStatementLength()) return false;
      if (hasMaxStatementLength()) {
        if (getMaxStatementLength()
            != other.getMaxStatementLength()) return false;
      }
      if (hasMaxStatements() != other.hasMaxStatements()) return false;
      if (hasMaxStatements()) {
        if (getMaxStatements()
            != other.getMaxStatements()) return false;
      }
      if (hasMaxTableNameLength() != other.hasMaxTableNameLength()) return false;
      if (hasMaxTableNameLength()) {
        if (getMaxTableNameLength()
            != other.getMaxTableNameLength()) return false;
      }
      if (hasMaxTablesInSelect() != other.hasMaxTablesInSelect()) return false;
      if (hasMaxTablesInSelect()) {
        if (getMaxTablesInSelect()
            != other.getMaxTablesInSelect()) return false;
      }
      if (hasMaxUserNameLength() != other.hasMaxUserNameLength()) return false;
      if (hasMaxUserNameLength()) {
        if (getMaxUserNameLength()
            != other.getMaxUserNameLength()) return false;
      }
      if (hasNullCollation() != other.hasNullCollation()) return false;
      if (hasNullCollation()) {
        if (nullCollation_ != other.nullCollation_) return false;
      }
      if (hasNullPlusNonNullEqualsNull() != other.hasNullPlusNonNullEqualsNull()) return false;
      if (hasNullPlusNonNullEqualsNull()) {
        if (getNullPlusNonNullEqualsNull()
            != other.getNullPlusNonNullEqualsNull()) return false;
      }
      if (!getNumericFunctionsList()
          .equals(other.getNumericFunctionsList())) return false;
      if (!orderBySupport_.equals(other.orderBySupport_)) return false;
      if (!outerJoinSupport_.equals(other.outerJoinSupport_)) return false;
      if (hasQuotedIdentifierCasing() != other.hasQuotedIdentifierCasing()) return false;
      if (hasQuotedIdentifierCasing()) {
        if (quotedIdentifierCasing_ != other.quotedIdentifierCasing_) return false;
      }
      if (hasReadOnly() != other.hasReadOnly()) return false;
      if (hasReadOnly()) {
        if (getReadOnly()
            != other.getReadOnly()) return false;
      }
      if (hasSchemaTerm() != other.hasSchemaTerm()) return false;
      if (hasSchemaTerm()) {
        if (!getSchemaTerm()
            .equals(other.getSchemaTerm())) return false;
      }
      if (hasSearchEscapeString() != other.hasSearchEscapeString()) return false;
      if (hasSearchEscapeString()) {
        if (!getSearchEscapeString()
            .equals(other.getSearchEscapeString())) return false;
      }
      if (hasSelectForUpdateSupported() != other.hasSelectForUpdateSupported()) return false;
      if (hasSelectForUpdateSupported()) {
        if (getSelectForUpdateSupported()
            != other.getSelectForUpdateSupported()) return false;
      }
      if (hasSpecialCharacters() != other.hasSpecialCharacters()) return false;
      if (hasSpecialCharacters()) {
        if (!getSpecialCharacters()
            .equals(other.getSpecialCharacters())) return false;
      }
      if (!getSqlKeywordsList()
          .equals(other.getSqlKeywordsList())) return false;
      if (!getStringFunctionsList()
          .equals(other.getStringFunctionsList())) return false;
      if (!subquerySupport_.equals(other.subquerySupport_)) return false;
      if (!getSystemFunctionsList()
          .equals(other.getSystemFunctionsList())) return false;
      if (hasTableTerm() != other.hasTableTerm()) return false;
      if (hasTableTerm()) {
        if (!getTableTerm()
            .equals(other.getTableTerm())) return false;
      }
      if (hasTransactionSupported() != other.hasTransactionSupported()) return false;
      if (hasTransactionSupported()) {
        if (getTransactionSupported()
            != other.getTransactionSupported()) return false;
      }
      if (!unionSupport_.equals(other.unionSupport_)) return false;
      if (hasCurrentSchema() != other.hasCurrentSchema()) return false;
      if (hasCurrentSchema()) {
        if (!getCurrentSchema()
            .equals(other.getCurrentSchema())) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasAllTablesSelectable()) {
        hash = (37 * hash) + ALL_TABLES_SELECTABLE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getAllTablesSelectable());
      }
      if (hasBlobIncludedInMaxRowSize()) {
        hash = (37 * hash) + BLOB_INCLUDED_IN_MAX_ROW_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getBlobIncludedInMaxRowSize());
      }
      if (hasCatalogAtStart()) {
        hash = (37 * hash) + CATALOG_AT_START_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getCatalogAtStart());
      }
      if (hasCatalogSeparator()) {
        hash = (37 * hash) + CATALOG_SEPARATOR_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogSeparator().hashCode();
      }
      if (hasCatalogTerm()) {
        hash = (37 * hash) + CATALOG_TERM_FIELD_NUMBER;
        hash = (53 * hash) + getCatalogTerm().hashCode();
      }
      if (getCollateSupportCount() > 0) {
        hash = (37 * hash) + COLLATE_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + collateSupport_.hashCode();
      }
      if (hasColumnAliasingSupported()) {
        hash = (37 * hash) + COLUMN_ALIASING_SUPPORTED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getColumnAliasingSupported());
      }
      if (getConvertSupportCount() > 0) {
        hash = (37 * hash) + CONVERT_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + getConvertSupportList().hashCode();
      }
      if (hasCorrelationNamesSupport()) {
        hash = (37 * hash) + CORRELATION_NAMES_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + correlationNamesSupport_;
      }
      if (getDateTimeFunctionsCount() > 0) {
        hash = (37 * hash) + DATE_TIME_FUNCTIONS_FIELD_NUMBER;
        hash = (53 * hash) + getDateTimeFunctionsList().hashCode();
      }
      if (getDateTimeLiteralsSupportCount() > 0) {
        hash = (37 * hash) + DATE_TIME_LITERALS_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + dateTimeLiteralsSupport_.hashCode();
      }
      if (hasGroupBySupport()) {
        hash = (37 * hash) + GROUP_BY_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + groupBySupport_;
      }
      if (hasIdentifierCasing()) {
        hash = (37 * hash) + IDENTIFIER_CASING_FIELD_NUMBER;
        hash = (53 * hash) + identifierCasing_;
      }
      if (hasIdentifierQuoteString()) {
        hash = (37 * hash) + IDENTIFIER_QUOTE_STRING_FIELD_NUMBER;
        hash = (53 * hash) + getIdentifierQuoteString().hashCode();
      }
      if (hasLikeEscapeClauseSupported()) {
        hash = (37 * hash) + LIKE_ESCAPE_CLAUSE_SUPPORTED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getLikeEscapeClauseSupported());
      }
      if (hasMaxBinaryLiteralLength()) {
        hash = (37 * hash) + MAX_BINARY_LITERAL_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxBinaryLiteralLength();
      }
      if (hasMaxCatalogNameLength()) {
        hash = (37 * hash) + MAX_CATALOG_NAME_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxCatalogNameLength();
      }
      if (hasMaxCharLiteralLength()) {
        hash = (37 * hash) + MAX_CHAR_LITERAL_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxCharLiteralLength();
      }
      if (hasMaxColumnNameLength()) {
        hash = (37 * hash) + MAX_COLUMN_NAME_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxColumnNameLength();
      }
      if (hasMaxColumnsInGroupBy()) {
        hash = (37 * hash) + MAX_COLUMNS_IN_GROUP_BY_FIELD_NUMBER;
        hash = (53 * hash) + getMaxColumnsInGroupBy();
      }
      if (hasMaxColumnsInOrderBy()) {
        hash = (37 * hash) + MAX_COLUMNS_IN_ORDER_BY_FIELD_NUMBER;
        hash = (53 * hash) + getMaxColumnsInOrderBy();
      }
      if (hasMaxColumnsInSelect()) {
        hash = (37 * hash) + MAX_COLUMNS_IN_SELECT_FIELD_NUMBER;
        hash = (53 * hash) + getMaxColumnsInSelect();
      }
      if (hasMaxCursorNameLength()) {
        hash = (37 * hash) + MAX_CURSOR_NAME_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxCursorNameLength();
      }
      if (hasMaxLogicalLobSize()) {
        hash = (37 * hash) + MAX_LOGICAL_LOB_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getMaxLogicalLobSize();
      }
      if (hasMaxRowSize()) {
        hash = (37 * hash) + MAX_ROW_SIZE_FIELD_NUMBER;
        hash = (53 * hash) + getMaxRowSize();
      }
      if (hasMaxSchemaNameLength()) {
        hash = (37 * hash) + MAX_SCHEMA_NAME_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxSchemaNameLength();
      }
      if (hasMaxStatementLength()) {
        hash = (37 * hash) + MAX_STATEMENT_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxStatementLength();
      }
      if (hasMaxStatements()) {
        hash = (37 * hash) + MAX_STATEMENTS_FIELD_NUMBER;
        hash = (53 * hash) + getMaxStatements();
      }
      if (hasMaxTableNameLength()) {
        hash = (37 * hash) + MAX_TABLE_NAME_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxTableNameLength();
      }
      if (hasMaxTablesInSelect()) {
        hash = (37 * hash) + MAX_TABLES_IN_SELECT_FIELD_NUMBER;
        hash = (53 * hash) + getMaxTablesInSelect();
      }
      if (hasMaxUserNameLength()) {
        hash = (37 * hash) + MAX_USER_NAME_LENGTH_FIELD_NUMBER;
        hash = (53 * hash) + getMaxUserNameLength();
      }
      if (hasNullCollation()) {
        hash = (37 * hash) + NULL_COLLATION_FIELD_NUMBER;
        hash = (53 * hash) + nullCollation_;
      }
      if (hasNullPlusNonNullEqualsNull()) {
        hash = (37 * hash) + NULL_PLUS_NON_NULL_EQUALS_NULL_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getNullPlusNonNullEqualsNull());
      }
      if (getNumericFunctionsCount() > 0) {
        hash = (37 * hash) + NUMERIC_FUNCTIONS_FIELD_NUMBER;
        hash = (53 * hash) + getNumericFunctionsList().hashCode();
      }
      if (getOrderBySupportCount() > 0) {
        hash = (37 * hash) + ORDER_BY_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + orderBySupport_.hashCode();
      }
      if (getOuterJoinSupportCount() > 0) {
        hash = (37 * hash) + OUTER_JOIN_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + outerJoinSupport_.hashCode();
      }
      if (hasQuotedIdentifierCasing()) {
        hash = (37 * hash) + QUOTED_IDENTIFIER_CASING_FIELD_NUMBER;
        hash = (53 * hash) + quotedIdentifierCasing_;
      }
      if (hasReadOnly()) {
        hash = (37 * hash) + READ_ONLY_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getReadOnly());
      }
      if (hasSchemaTerm()) {
        hash = (37 * hash) + SCHEMA_TERM_FIELD_NUMBER;
        hash = (53 * hash) + getSchemaTerm().hashCode();
      }
      if (hasSearchEscapeString()) {
        hash = (37 * hash) + SEARCH_ESCAPE_STRING_FIELD_NUMBER;
        hash = (53 * hash) + getSearchEscapeString().hashCode();
      }
      if (hasSelectForUpdateSupported()) {
        hash = (37 * hash) + SELECT_FOR_UPDATE_SUPPORTED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getSelectForUpdateSupported());
      }
      if (hasSpecialCharacters()) {
        hash = (37 * hash) + SPECIAL_CHARACTERS_FIELD_NUMBER;
        hash = (53 * hash) + getSpecialCharacters().hashCode();
      }
      if (getSqlKeywordsCount() > 0) {
        hash = (37 * hash) + SQL_KEYWORDS_FIELD_NUMBER;
        hash = (53 * hash) + getSqlKeywordsList().hashCode();
      }
      if (getStringFunctionsCount() > 0) {
        hash = (37 * hash) + STRING_FUNCTIONS_FIELD_NUMBER;
        hash = (53 * hash) + getStringFunctionsList().hashCode();
      }
      if (getSubquerySupportCount() > 0) {
        hash = (37 * hash) + SUBQUERY_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + subquerySupport_.hashCode();
      }
      if (getSystemFunctionsCount() > 0) {
        hash = (37 * hash) + SYSTEM_FUNCTIONS_FIELD_NUMBER;
        hash = (53 * hash) + getSystemFunctionsList().hashCode();
      }
      if (hasTableTerm()) {
        hash = (37 * hash) + TABLE_TERM_FIELD_NUMBER;
        hash = (53 * hash) + getTableTerm().hashCode();
      }
      if (hasTransactionSupported()) {
        hash = (37 * hash) + TRANSACTION_SUPPORTED_FIELD_NUMBER;
        hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
            getTransactionSupported());
      }
      if (getUnionSupportCount() > 0) {
        hash = (37 * hash) + UNION_SUPPORT_FIELD_NUMBER;
        hash = (53 * hash) + unionSupport_.hashCode();
      }
      if (hasCurrentSchema()) {
        hash = (37 * hash) + CURRENT_SCHEMA_FIELD_NUMBER;
        hash = (53 * hash) + getCurrentSchema().hashCode();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta 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.drill.exec.proto.UserProtos.ServerMeta parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.ServerMeta parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.ServerMeta prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * Protobuf type {@code exec.user.ServerMeta}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.ServerMeta)
        org.apache.drill.exec.proto.UserProtos.ServerMetaOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ServerMeta_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ServerMeta_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.ServerMeta.class, org.apache.drill.exec.proto.UserProtos.ServerMeta.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.ServerMeta.newBuilder()
      private Builder() {

      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);

      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        allTablesSelectable_ = false;
        bitField0_ = (bitField0_ & ~0x00000001);
        blobIncludedInMaxRowSize_ = false;
        bitField0_ = (bitField0_ & ~0x00000002);
        catalogAtStart_ = false;
        bitField0_ = (bitField0_ & ~0x00000004);
        catalogSeparator_ = "";
        bitField0_ = (bitField0_ & ~0x00000008);
        catalogTerm_ = "";
        bitField0_ = (bitField0_ & ~0x00000010);
        collateSupport_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000020);
        columnAliasingSupported_ = false;
        bitField0_ = (bitField0_ & ~0x00000040);
        if (convertSupportBuilder_ == null) {
          convertSupport_ = java.util.Collections.emptyList();
        } else {
          convertSupport_ = null;
          convertSupportBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000080);
        correlationNamesSupport_ = 1;
        bitField0_ = (bitField0_ & ~0x00000100);
        dateTimeFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000200);
        dateTimeLiteralsSupport_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000400);
        groupBySupport_ = 1;
        bitField0_ = (bitField0_ & ~0x00000800);
        identifierCasing_ = 0;
        bitField0_ = (bitField0_ & ~0x00001000);
        identifierQuoteString_ = "";
        bitField0_ = (bitField0_ & ~0x00002000);
        likeEscapeClauseSupported_ = false;
        bitField0_ = (bitField0_ & ~0x00004000);
        maxBinaryLiteralLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00008000);
        maxCatalogNameLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00010000);
        maxCharLiteralLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00020000);
        maxColumnNameLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00040000);
        maxColumnsInGroupBy_ = 0;
        bitField0_ = (bitField0_ & ~0x00080000);
        maxColumnsInOrderBy_ = 0;
        bitField0_ = (bitField0_ & ~0x00100000);
        maxColumnsInSelect_ = 0;
        bitField0_ = (bitField0_ & ~0x00200000);
        maxCursorNameLength_ = 0;
        bitField0_ = (bitField0_ & ~0x00400000);
        maxLogicalLobSize_ = 0;
        bitField0_ = (bitField0_ & ~0x00800000);
        maxRowSize_ = 0;
        bitField0_ = (bitField0_ & ~0x01000000);
        maxSchemaNameLength_ = 0;
        bitField0_ = (bitField0_ & ~0x02000000);
        maxStatementLength_ = 0;
        bitField0_ = (bitField0_ & ~0x04000000);
        maxStatements_ = 0;
        bitField0_ = (bitField0_ & ~0x08000000);
        maxTableNameLength_ = 0;
        bitField0_ = (bitField0_ & ~0x10000000);
        maxTablesInSelect_ = 0;
        bitField0_ = (bitField0_ & ~0x20000000);
        maxUserNameLength_ = 0;
        bitField0_ = (bitField0_ & ~0x40000000);
        nullCollation_ = 0;
        bitField0_ = (bitField0_ & ~0x80000000);
        nullPlusNonNullEqualsNull_ = false;
        bitField1_ = (bitField1_ & ~0x00000001);
        numericFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00000002);
        orderBySupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00000004);
        outerJoinSupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00000008);
        quotedIdentifierCasing_ = 0;
        bitField1_ = (bitField1_ & ~0x00000010);
        readOnly_ = false;
        bitField1_ = (bitField1_ & ~0x00000020);
        schemaTerm_ = "";
        bitField1_ = (bitField1_ & ~0x00000040);
        searchEscapeString_ = "";
        bitField1_ = (bitField1_ & ~0x00000080);
        selectForUpdateSupported_ = false;
        bitField1_ = (bitField1_ & ~0x00000100);
        specialCharacters_ = "";
        bitField1_ = (bitField1_ & ~0x00000200);
        sqlKeywords_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00000400);
        stringFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00000800);
        subquerySupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00001000);
        systemFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00002000);
        tableTerm_ = "";
        bitField1_ = (bitField1_ & ~0x00004000);
        transactionSupported_ = false;
        bitField1_ = (bitField1_ & ~0x00008000);
        unionSupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00010000);
        currentSchema_ = "";
        bitField1_ = (bitField1_ & ~0x00020000);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_ServerMeta_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ServerMeta getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.ServerMeta.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ServerMeta build() {
        org.apache.drill.exec.proto.UserProtos.ServerMeta result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.ServerMeta buildPartial() {
        org.apache.drill.exec.proto.UserProtos.ServerMeta result = new org.apache.drill.exec.proto.UserProtos.ServerMeta(this);
        int from_bitField0_ = bitField0_;
        int from_bitField1_ = bitField1_;
        int to_bitField0_ = 0;
        int to_bitField1_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          result.allTablesSelectable_ = allTablesSelectable_;
          to_bitField0_ |= 0x00000001;
        }
        if (((from_bitField0_ & 0x00000002) != 0)) {
          result.blobIncludedInMaxRowSize_ = blobIncludedInMaxRowSize_;
          to_bitField0_ |= 0x00000002;
        }
        if (((from_bitField0_ & 0x00000004) != 0)) {
          result.catalogAtStart_ = catalogAtStart_;
          to_bitField0_ |= 0x00000004;
        }
        if (((from_bitField0_ & 0x00000008) != 0)) {
          to_bitField0_ |= 0x00000008;
        }
        result.catalogSeparator_ = catalogSeparator_;
        if (((from_bitField0_ & 0x00000010) != 0)) {
          to_bitField0_ |= 0x00000010;
        }
        result.catalogTerm_ = catalogTerm_;
        if (((bitField0_ & 0x00000020) != 0)) {
          collateSupport_ = java.util.Collections.unmodifiableList(collateSupport_);
          bitField0_ = (bitField0_ & ~0x00000020);
        }
        result.collateSupport_ = collateSupport_;
        if (((from_bitField0_ & 0x00000040) != 0)) {
          result.columnAliasingSupported_ = columnAliasingSupported_;
          to_bitField0_ |= 0x00000020;
        }
        if (convertSupportBuilder_ == null) {
          if (((bitField0_ & 0x00000080) != 0)) {
            convertSupport_ = java.util.Collections.unmodifiableList(convertSupport_);
            bitField0_ = (bitField0_ & ~0x00000080);
          }
          result.convertSupport_ = convertSupport_;
        } else {
          result.convertSupport_ = convertSupportBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000100) != 0)) {
          to_bitField0_ |= 0x00000040;
        }
        result.correlationNamesSupport_ = correlationNamesSupport_;
        if (((bitField0_ & 0x00000200) != 0)) {
          dateTimeFunctions_ = dateTimeFunctions_.getUnmodifiableView();
          bitField0_ = (bitField0_ & ~0x00000200);
        }
        result.dateTimeFunctions_ = dateTimeFunctions_;
        if (((bitField0_ & 0x00000400) != 0)) {
          dateTimeLiteralsSupport_ = java.util.Collections.unmodifiableList(dateTimeLiteralsSupport_);
          bitField0_ = (bitField0_ & ~0x00000400);
        }
        result.dateTimeLiteralsSupport_ = dateTimeLiteralsSupport_;
        if (((from_bitField0_ & 0x00000800) != 0)) {
          to_bitField0_ |= 0x00000080;
        }
        result.groupBySupport_ = groupBySupport_;
        if (((from_bitField0_ & 0x00001000) != 0)) {
          to_bitField0_ |= 0x00000100;
        }
        result.identifierCasing_ = identifierCasing_;
        if (((from_bitField0_ & 0x00002000) != 0)) {
          to_bitField0_ |= 0x00000200;
        }
        result.identifierQuoteString_ = identifierQuoteString_;
        if (((from_bitField0_ & 0x00004000) != 0)) {
          result.likeEscapeClauseSupported_ = likeEscapeClauseSupported_;
          to_bitField0_ |= 0x00000400;
        }
        if (((from_bitField0_ & 0x00008000) != 0)) {
          result.maxBinaryLiteralLength_ = maxBinaryLiteralLength_;
          to_bitField0_ |= 0x00000800;
        }
        if (((from_bitField0_ & 0x00010000) != 0)) {
          result.maxCatalogNameLength_ = maxCatalogNameLength_;
          to_bitField0_ |= 0x00001000;
        }
        if (((from_bitField0_ & 0x00020000) != 0)) {
          result.maxCharLiteralLength_ = maxCharLiteralLength_;
          to_bitField0_ |= 0x00002000;
        }
        if (((from_bitField0_ & 0x00040000) != 0)) {
          result.maxColumnNameLength_ = maxColumnNameLength_;
          to_bitField0_ |= 0x00004000;
        }
        if (((from_bitField0_ & 0x00080000) != 0)) {
          result.maxColumnsInGroupBy_ = maxColumnsInGroupBy_;
          to_bitField0_ |= 0x00008000;
        }
        if (((from_bitField0_ & 0x00100000) != 0)) {
          result.maxColumnsInOrderBy_ = maxColumnsInOrderBy_;
          to_bitField0_ |= 0x00010000;
        }
        if (((from_bitField0_ & 0x00200000) != 0)) {
          result.maxColumnsInSelect_ = maxColumnsInSelect_;
          to_bitField0_ |= 0x00020000;
        }
        if (((from_bitField0_ & 0x00400000) != 0)) {
          result.maxCursorNameLength_ = maxCursorNameLength_;
          to_bitField0_ |= 0x00040000;
        }
        if (((from_bitField0_ & 0x00800000) != 0)) {
          result.maxLogicalLobSize_ = maxLogicalLobSize_;
          to_bitField0_ |= 0x00080000;
        }
        if (((from_bitField0_ & 0x01000000) != 0)) {
          result.maxRowSize_ = maxRowSize_;
          to_bitField0_ |= 0x00100000;
        }
        if (((from_bitField0_ & 0x02000000) != 0)) {
          result.maxSchemaNameLength_ = maxSchemaNameLength_;
          to_bitField0_ |= 0x00200000;
        }
        if (((from_bitField0_ & 0x04000000) != 0)) {
          result.maxStatementLength_ = maxStatementLength_;
          to_bitField0_ |= 0x00400000;
        }
        if (((from_bitField0_ & 0x08000000) != 0)) {
          result.maxStatements_ = maxStatements_;
          to_bitField0_ |= 0x00800000;
        }
        if (((from_bitField0_ & 0x10000000) != 0)) {
          result.maxTableNameLength_ = maxTableNameLength_;
          to_bitField0_ |= 0x01000000;
        }
        if (((from_bitField0_ & 0x20000000) != 0)) {
          result.maxTablesInSelect_ = maxTablesInSelect_;
          to_bitField0_ |= 0x02000000;
        }
        if (((from_bitField0_ & 0x40000000) != 0)) {
          result.maxUserNameLength_ = maxUserNameLength_;
          to_bitField0_ |= 0x04000000;
        }
        if (((from_bitField0_ & 0x80000000) != 0)) {
          to_bitField0_ |= 0x08000000;
        }
        result.nullCollation_ = nullCollation_;
        if (((from_bitField1_ & 0x00000001) != 0)) {
          result.nullPlusNonNullEqualsNull_ = nullPlusNonNullEqualsNull_;
          to_bitField0_ |= 0x10000000;
        }
        if (((bitField1_ & 0x00000002) != 0)) {
          numericFunctions_ = numericFunctions_.getUnmodifiableView();
          bitField1_ = (bitField1_ & ~0x00000002);
        }
        result.numericFunctions_ = numericFunctions_;
        if (((bitField1_ & 0x00000004) != 0)) {
          orderBySupport_ = java.util.Collections.unmodifiableList(orderBySupport_);
          bitField1_ = (bitField1_ & ~0x00000004);
        }
        result.orderBySupport_ = orderBySupport_;
        if (((bitField1_ & 0x00000008) != 0)) {
          outerJoinSupport_ = java.util.Collections.unmodifiableList(outerJoinSupport_);
          bitField1_ = (bitField1_ & ~0x00000008);
        }
        result.outerJoinSupport_ = outerJoinSupport_;
        if (((from_bitField1_ & 0x00000010) != 0)) {
          to_bitField0_ |= 0x20000000;
        }
        result.quotedIdentifierCasing_ = quotedIdentifierCasing_;
        if (((from_bitField1_ & 0x00000020) != 0)) {
          result.readOnly_ = readOnly_;
          to_bitField0_ |= 0x40000000;
        }
        if (((from_bitField1_ & 0x00000040) != 0)) {
          to_bitField0_ |= 0x80000000;
        }
        result.schemaTerm_ = schemaTerm_;
        if (((from_bitField1_ & 0x00000080) != 0)) {
          to_bitField1_ |= 0x00000001;
        }
        result.searchEscapeString_ = searchEscapeString_;
        if (((from_bitField1_ & 0x00000100) != 0)) {
          result.selectForUpdateSupported_ = selectForUpdateSupported_;
          to_bitField1_ |= 0x00000002;
        }
        if (((from_bitField1_ & 0x00000200) != 0)) {
          to_bitField1_ |= 0x00000004;
        }
        result.specialCharacters_ = specialCharacters_;
        if (((bitField1_ & 0x00000400) != 0)) {
          sqlKeywords_ = sqlKeywords_.getUnmodifiableView();
          bitField1_ = (bitField1_ & ~0x00000400);
        }
        result.sqlKeywords_ = sqlKeywords_;
        if (((bitField1_ & 0x00000800) != 0)) {
          stringFunctions_ = stringFunctions_.getUnmodifiableView();
          bitField1_ = (bitField1_ & ~0x00000800);
        }
        result.stringFunctions_ = stringFunctions_;
        if (((bitField1_ & 0x00001000) != 0)) {
          subquerySupport_ = java.util.Collections.unmodifiableList(subquerySupport_);
          bitField1_ = (bitField1_ & ~0x00001000);
        }
        result.subquerySupport_ = subquerySupport_;
        if (((bitField1_ & 0x00002000) != 0)) {
          systemFunctions_ = systemFunctions_.getUnmodifiableView();
          bitField1_ = (bitField1_ & ~0x00002000);
        }
        result.systemFunctions_ = systemFunctions_;
        if (((from_bitField1_ & 0x00004000) != 0)) {
          to_bitField1_ |= 0x00000008;
        }
        result.tableTerm_ = tableTerm_;
        if (((from_bitField1_ & 0x00008000) != 0)) {
          result.transactionSupported_ = transactionSupported_;
          to_bitField1_ |= 0x00000010;
        }
        if (((bitField1_ & 0x00010000) != 0)) {
          unionSupport_ = java.util.Collections.unmodifiableList(unionSupport_);
          bitField1_ = (bitField1_ & ~0x00010000);
        }
        result.unionSupport_ = unionSupport_;
        if (((from_bitField1_ & 0x00020000) != 0)) {
          to_bitField1_ |= 0x00000020;
        }
        result.currentSchema_ = currentSchema_;
        result.bitField0_ = to_bitField0_;
        result.bitField1_ = to_bitField1_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.ServerMeta) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.ServerMeta)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.ServerMeta other) {
        if (other == org.apache.drill.exec.proto.UserProtos.ServerMeta.getDefaultInstance()) return this;
        if (other.hasAllTablesSelectable()) {
          setAllTablesSelectable(other.getAllTablesSelectable());
        }
        if (other.hasBlobIncludedInMaxRowSize()) {
          setBlobIncludedInMaxRowSize(other.getBlobIncludedInMaxRowSize());
        }
        if (other.hasCatalogAtStart()) {
          setCatalogAtStart(other.getCatalogAtStart());
        }
        if (other.hasCatalogSeparator()) {
          bitField0_ |= 0x00000008;
          catalogSeparator_ = other.catalogSeparator_;
          onChanged();
        }
        if (other.hasCatalogTerm()) {
          bitField0_ |= 0x00000010;
          catalogTerm_ = other.catalogTerm_;
          onChanged();
        }
        if (!other.collateSupport_.isEmpty()) {
          if (collateSupport_.isEmpty()) {
            collateSupport_ = other.collateSupport_;
            bitField0_ = (bitField0_ & ~0x00000020);
          } else {
            ensureCollateSupportIsMutable();
            collateSupport_.addAll(other.collateSupport_);
          }
          onChanged();
        }
        if (other.hasColumnAliasingSupported()) {
          setColumnAliasingSupported(other.getColumnAliasingSupported());
        }
        if (convertSupportBuilder_ == null) {
          if (!other.convertSupport_.isEmpty()) {
            if (convertSupport_.isEmpty()) {
              convertSupport_ = other.convertSupport_;
              bitField0_ = (bitField0_ & ~0x00000080);
            } else {
              ensureConvertSupportIsMutable();
              convertSupport_.addAll(other.convertSupport_);
            }
            onChanged();
          }
        } else {
          if (!other.convertSupport_.isEmpty()) {
            if (convertSupportBuilder_.isEmpty()) {
              convertSupportBuilder_.dispose();
              convertSupportBuilder_ = null;
              convertSupport_ = other.convertSupport_;
              bitField0_ = (bitField0_ & ~0x00000080);
              convertSupportBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getConvertSupportFieldBuilder() : null;
            } else {
              convertSupportBuilder_.addAllMessages(other.convertSupport_);
            }
          }
        }
        if (other.hasCorrelationNamesSupport()) {
          setCorrelationNamesSupport(other.getCorrelationNamesSupport());
        }
        if (!other.dateTimeFunctions_.isEmpty()) {
          if (dateTimeFunctions_.isEmpty()) {
            dateTimeFunctions_ = other.dateTimeFunctions_;
            bitField0_ = (bitField0_ & ~0x00000200);
          } else {
            ensureDateTimeFunctionsIsMutable();
            dateTimeFunctions_.addAll(other.dateTimeFunctions_);
          }
          onChanged();
        }
        if (!other.dateTimeLiteralsSupport_.isEmpty()) {
          if (dateTimeLiteralsSupport_.isEmpty()) {
            dateTimeLiteralsSupport_ = other.dateTimeLiteralsSupport_;
            bitField0_ = (bitField0_ & ~0x00000400);
          } else {
            ensureDateTimeLiteralsSupportIsMutable();
            dateTimeLiteralsSupport_.addAll(other.dateTimeLiteralsSupport_);
          }
          onChanged();
        }
        if (other.hasGroupBySupport()) {
          setGroupBySupport(other.getGroupBySupport());
        }
        if (other.hasIdentifierCasing()) {
          setIdentifierCasing(other.getIdentifierCasing());
        }
        if (other.hasIdentifierQuoteString()) {
          bitField0_ |= 0x00002000;
          identifierQuoteString_ = other.identifierQuoteString_;
          onChanged();
        }
        if (other.hasLikeEscapeClauseSupported()) {
          setLikeEscapeClauseSupported(other.getLikeEscapeClauseSupported());
        }
        if (other.hasMaxBinaryLiteralLength()) {
          setMaxBinaryLiteralLength(other.getMaxBinaryLiteralLength());
        }
        if (other.hasMaxCatalogNameLength()) {
          setMaxCatalogNameLength(other.getMaxCatalogNameLength());
        }
        if (other.hasMaxCharLiteralLength()) {
          setMaxCharLiteralLength(other.getMaxCharLiteralLength());
        }
        if (other.hasMaxColumnNameLength()) {
          setMaxColumnNameLength(other.getMaxColumnNameLength());
        }
        if (other.hasMaxColumnsInGroupBy()) {
          setMaxColumnsInGroupBy(other.getMaxColumnsInGroupBy());
        }
        if (other.hasMaxColumnsInOrderBy()) {
          setMaxColumnsInOrderBy(other.getMaxColumnsInOrderBy());
        }
        if (other.hasMaxColumnsInSelect()) {
          setMaxColumnsInSelect(other.getMaxColumnsInSelect());
        }
        if (other.hasMaxCursorNameLength()) {
          setMaxCursorNameLength(other.getMaxCursorNameLength());
        }
        if (other.hasMaxLogicalLobSize()) {
          setMaxLogicalLobSize(other.getMaxLogicalLobSize());
        }
        if (other.hasMaxRowSize()) {
          setMaxRowSize(other.getMaxRowSize());
        }
        if (other.hasMaxSchemaNameLength()) {
          setMaxSchemaNameLength(other.getMaxSchemaNameLength());
        }
        if (other.hasMaxStatementLength()) {
          setMaxStatementLength(other.getMaxStatementLength());
        }
        if (other.hasMaxStatements()) {
          setMaxStatements(other.getMaxStatements());
        }
        if (other.hasMaxTableNameLength()) {
          setMaxTableNameLength(other.getMaxTableNameLength());
        }
        if (other.hasMaxTablesInSelect()) {
          setMaxTablesInSelect(other.getMaxTablesInSelect());
        }
        if (other.hasMaxUserNameLength()) {
          setMaxUserNameLength(other.getMaxUserNameLength());
        }
        if (other.hasNullCollation()) {
          setNullCollation(other.getNullCollation());
        }
        if (other.hasNullPlusNonNullEqualsNull()) {
          setNullPlusNonNullEqualsNull(other.getNullPlusNonNullEqualsNull());
        }
        if (!other.numericFunctions_.isEmpty()) {
          if (numericFunctions_.isEmpty()) {
            numericFunctions_ = other.numericFunctions_;
            bitField1_ = (bitField1_ & ~0x00000002);
          } else {
            ensureNumericFunctionsIsMutable();
            numericFunctions_.addAll(other.numericFunctions_);
          }
          onChanged();
        }
        if (!other.orderBySupport_.isEmpty()) {
          if (orderBySupport_.isEmpty()) {
            orderBySupport_ = other.orderBySupport_;
            bitField1_ = (bitField1_ & ~0x00000004);
          } else {
            ensureOrderBySupportIsMutable();
            orderBySupport_.addAll(other.orderBySupport_);
          }
          onChanged();
        }
        if (!other.outerJoinSupport_.isEmpty()) {
          if (outerJoinSupport_.isEmpty()) {
            outerJoinSupport_ = other.outerJoinSupport_;
            bitField1_ = (bitField1_ & ~0x00000008);
          } else {
            ensureOuterJoinSupportIsMutable();
            outerJoinSupport_.addAll(other.outerJoinSupport_);
          }
          onChanged();
        }
        if (other.hasQuotedIdentifierCasing()) {
          setQuotedIdentifierCasing(other.getQuotedIdentifierCasing());
        }
        if (other.hasReadOnly()) {
          setReadOnly(other.getReadOnly());
        }
        if (other.hasSchemaTerm()) {
          bitField1_ |= 0x00000040;
          schemaTerm_ = other.schemaTerm_;
          onChanged();
        }
        if (other.hasSearchEscapeString()) {
          bitField1_ |= 0x00000080;
          searchEscapeString_ = other.searchEscapeString_;
          onChanged();
        }
        if (other.hasSelectForUpdateSupported()) {
          setSelectForUpdateSupported(other.getSelectForUpdateSupported());
        }
        if (other.hasSpecialCharacters()) {
          bitField1_ |= 0x00000200;
          specialCharacters_ = other.specialCharacters_;
          onChanged();
        }
        if (!other.sqlKeywords_.isEmpty()) {
          if (sqlKeywords_.isEmpty()) {
            sqlKeywords_ = other.sqlKeywords_;
            bitField1_ = (bitField1_ & ~0x00000400);
          } else {
            ensureSqlKeywordsIsMutable();
            sqlKeywords_.addAll(other.sqlKeywords_);
          }
          onChanged();
        }
        if (!other.stringFunctions_.isEmpty()) {
          if (stringFunctions_.isEmpty()) {
            stringFunctions_ = other.stringFunctions_;
            bitField1_ = (bitField1_ & ~0x00000800);
          } else {
            ensureStringFunctionsIsMutable();
            stringFunctions_.addAll(other.stringFunctions_);
          }
          onChanged();
        }
        if (!other.subquerySupport_.isEmpty()) {
          if (subquerySupport_.isEmpty()) {
            subquerySupport_ = other.subquerySupport_;
            bitField1_ = (bitField1_ & ~0x00001000);
          } else {
            ensureSubquerySupportIsMutable();
            subquerySupport_.addAll(other.subquerySupport_);
          }
          onChanged();
        }
        if (!other.systemFunctions_.isEmpty()) {
          if (systemFunctions_.isEmpty()) {
            systemFunctions_ = other.systemFunctions_;
            bitField1_ = (bitField1_ & ~0x00002000);
          } else {
            ensureSystemFunctionsIsMutable();
            systemFunctions_.addAll(other.systemFunctions_);
          }
          onChanged();
        }
        if (other.hasTableTerm()) {
          bitField1_ |= 0x00004000;
          tableTerm_ = other.tableTerm_;
          onChanged();
        }
        if (other.hasTransactionSupported()) {
          setTransactionSupported(other.getTransactionSupported());
        }
        if (!other.unionSupport_.isEmpty()) {
          if (unionSupport_.isEmpty()) {
            unionSupport_ = other.unionSupport_;
            bitField1_ = (bitField1_ & ~0x00010000);
          } else {
            ensureUnionSupportIsMutable();
            unionSupport_.addAll(other.unionSupport_);
          }
          onChanged();
        }
        if (other.hasCurrentSchema()) {
          bitField1_ |= 0x00020000;
          currentSchema_ = other.currentSchema_;
          onChanged();
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        for (int i = 0; i < getConvertSupportCount(); i++) {
          if (!getConvertSupport(i).isInitialized()) {
            return false;
          }
        }
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                allTablesSelectable_ = input.readBool();
                bitField0_ |= 0x00000001;
                break;
              } // case 8
              case 16: {
                blobIncludedInMaxRowSize_ = input.readBool();
                bitField0_ |= 0x00000002;
                break;
              } // case 16
              case 24: {
                catalogAtStart_ = input.readBool();
                bitField0_ |= 0x00000004;
                break;
              } // case 24
              case 34: {
                catalogSeparator_ = input.readBytes();
                bitField0_ |= 0x00000008;
                break;
              } // case 34
              case 42: {
                catalogTerm_ = input.readBytes();
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 48: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.CollateSupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.CollateSupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(6, tmpRaw);
                } else {
                  ensureCollateSupportIsMutable();
                  collateSupport_.add(tmpRaw);
                }
                break;
              } // case 48
              case 50: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.exec.proto.UserProtos.CollateSupport tmpValue =
                      org.apache.drill.exec.proto.UserProtos.CollateSupport.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(6, tmpRaw);
                  } else {
                    ensureCollateSupportIsMutable();
                    collateSupport_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 50
              case 56: {
                columnAliasingSupported_ = input.readBool();
                bitField0_ |= 0x00000040;
                break;
              } // case 56
              case 66: {
                org.apache.drill.exec.proto.UserProtos.ConvertSupport m =
                    input.readMessage(
                        org.apache.drill.exec.proto.UserProtos.ConvertSupport.PARSER,
                        extensionRegistry);
                if (convertSupportBuilder_ == null) {
                  ensureConvertSupportIsMutable();
                  convertSupport_.add(m);
                } else {
                  convertSupportBuilder_.addMessage(m);
                }
                break;
              } // case 66
              case 72: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(9, tmpRaw);
                } else {
                  correlationNamesSupport_ = tmpRaw;
                  bitField0_ |= 0x00000100;
                }
                break;
              } // case 72
              case 82: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureDateTimeFunctionsIsMutable();
                dateTimeFunctions_.add(bs);
                break;
              } // case 82
              case 88: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(11, tmpRaw);
                } else {
                  ensureDateTimeLiteralsSupportIsMutable();
                  dateTimeLiteralsSupport_.add(tmpRaw);
                }
                break;
              } // case 88
              case 90: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport tmpValue =
                      org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(11, tmpRaw);
                  } else {
                    ensureDateTimeLiteralsSupportIsMutable();
                    dateTimeLiteralsSupport_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 90
              case 96: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.GroupBySupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.GroupBySupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(12, tmpRaw);
                } else {
                  groupBySupport_ = tmpRaw;
                  bitField0_ |= 0x00000800;
                }
                break;
              } // case 96
              case 104: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.IdentifierCasing tmpValue =
                    org.apache.drill.exec.proto.UserProtos.IdentifierCasing.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(13, tmpRaw);
                } else {
                  identifierCasing_ = tmpRaw;
                  bitField0_ |= 0x00001000;
                }
                break;
              } // case 104
              case 114: {
                identifierQuoteString_ = input.readBytes();
                bitField0_ |= 0x00002000;
                break;
              } // case 114
              case 120: {
                likeEscapeClauseSupported_ = input.readBool();
                bitField0_ |= 0x00004000;
                break;
              } // case 120
              case 128: {
                maxBinaryLiteralLength_ = input.readUInt32();
                bitField0_ |= 0x00008000;
                break;
              } // case 128
              case 136: {
                maxCatalogNameLength_ = input.readUInt32();
                bitField0_ |= 0x00010000;
                break;
              } // case 136
              case 144: {
                maxCharLiteralLength_ = input.readUInt32();
                bitField0_ |= 0x00020000;
                break;
              } // case 144
              case 152: {
                maxColumnNameLength_ = input.readUInt32();
                bitField0_ |= 0x00040000;
                break;
              } // case 152
              case 160: {
                maxColumnsInGroupBy_ = input.readUInt32();
                bitField0_ |= 0x00080000;
                break;
              } // case 160
              case 168: {
                maxColumnsInOrderBy_ = input.readUInt32();
                bitField0_ |= 0x00100000;
                break;
              } // case 168
              case 176: {
                maxColumnsInSelect_ = input.readUInt32();
                bitField0_ |= 0x00200000;
                break;
              } // case 176
              case 184: {
                maxCursorNameLength_ = input.readUInt32();
                bitField0_ |= 0x00400000;
                break;
              } // case 184
              case 192: {
                maxLogicalLobSize_ = input.readUInt32();
                bitField0_ |= 0x00800000;
                break;
              } // case 192
              case 200: {
                maxRowSize_ = input.readUInt32();
                bitField0_ |= 0x01000000;
                break;
              } // case 200
              case 208: {
                maxSchemaNameLength_ = input.readUInt32();
                bitField0_ |= 0x02000000;
                break;
              } // case 208
              case 216: {
                maxStatementLength_ = input.readUInt32();
                bitField0_ |= 0x04000000;
                break;
              } // case 216
              case 224: {
                maxStatements_ = input.readUInt32();
                bitField0_ |= 0x08000000;
                break;
              } // case 224
              case 232: {
                maxTableNameLength_ = input.readUInt32();
                bitField0_ |= 0x10000000;
                break;
              } // case 232
              case 240: {
                maxTablesInSelect_ = input.readUInt32();
                bitField0_ |= 0x20000000;
                break;
              } // case 240
              case 248: {
                maxUserNameLength_ = input.readUInt32();
                bitField0_ |= 0x40000000;
                break;
              } // case 248
              case 256: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.NullCollation tmpValue =
                    org.apache.drill.exec.proto.UserProtos.NullCollation.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(32, tmpRaw);
                } else {
                  nullCollation_ = tmpRaw;
                  bitField0_ |= 0x80000000;
                }
                break;
              } // case 256
              case 264: {
                nullPlusNonNullEqualsNull_ = input.readBool();
                bitField1_ |= 0x00000001;
                break;
              } // case 264
              case 274: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureNumericFunctionsIsMutable();
                numericFunctions_.add(bs);
                break;
              } // case 274
              case 280: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.OrderBySupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.OrderBySupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(35, tmpRaw);
                } else {
                  ensureOrderBySupportIsMutable();
                  orderBySupport_.add(tmpRaw);
                }
                break;
              } // case 280
              case 282: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.exec.proto.UserProtos.OrderBySupport tmpValue =
                      org.apache.drill.exec.proto.UserProtos.OrderBySupport.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(35, tmpRaw);
                  } else {
                    ensureOrderBySupportIsMutable();
                    orderBySupport_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 282
              case 288: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.OuterJoinSupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.OuterJoinSupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(36, tmpRaw);
                } else {
                  ensureOuterJoinSupportIsMutable();
                  outerJoinSupport_.add(tmpRaw);
                }
                break;
              } // case 288
              case 290: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.exec.proto.UserProtos.OuterJoinSupport tmpValue =
                      org.apache.drill.exec.proto.UserProtos.OuterJoinSupport.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(36, tmpRaw);
                  } else {
                    ensureOuterJoinSupportIsMutable();
                    outerJoinSupport_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 290
              case 296: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.IdentifierCasing tmpValue =
                    org.apache.drill.exec.proto.UserProtos.IdentifierCasing.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(37, tmpRaw);
                } else {
                  quotedIdentifierCasing_ = tmpRaw;
                  bitField1_ |= 0x00000010;
                }
                break;
              } // case 296
              case 304: {
                readOnly_ = input.readBool();
                bitField1_ |= 0x00000020;
                break;
              } // case 304
              case 314: {
                schemaTerm_ = input.readBytes();
                bitField1_ |= 0x00000040;
                break;
              } // case 314
              case 322: {
                searchEscapeString_ = input.readBytes();
                bitField1_ |= 0x00000080;
                break;
              } // case 322
              case 328: {
                selectForUpdateSupported_ = input.readBool();
                bitField1_ |= 0x00000100;
                break;
              } // case 328
              case 338: {
                specialCharacters_ = input.readBytes();
                bitField1_ |= 0x00000200;
                break;
              } // case 338
              case 346: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureSqlKeywordsIsMutable();
                sqlKeywords_.add(bs);
                break;
              } // case 346
              case 354: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureStringFunctionsIsMutable();
                stringFunctions_.add(bs);
                break;
              } // case 354
              case 360: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.SubQuerySupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.SubQuerySupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(45, tmpRaw);
                } else {
                  ensureSubquerySupportIsMutable();
                  subquerySupport_.add(tmpRaw);
                }
                break;
              } // case 360
              case 362: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.exec.proto.UserProtos.SubQuerySupport tmpValue =
                      org.apache.drill.exec.proto.UserProtos.SubQuerySupport.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(45, tmpRaw);
                  } else {
                    ensureSubquerySupportIsMutable();
                    subquerySupport_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 362
              case 370: {
                com.google.protobuf.ByteString bs = input.readBytes();
                ensureSystemFunctionsIsMutable();
                systemFunctions_.add(bs);
                break;
              } // case 370
              case 378: {
                tableTerm_ = input.readBytes();
                bitField1_ |= 0x00004000;
                break;
              } // case 378
              case 384: {
                transactionSupported_ = input.readBool();
                bitField1_ |= 0x00008000;
                break;
              } // case 384
              case 392: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.UnionSupport tmpValue =
                    org.apache.drill.exec.proto.UserProtos.UnionSupport.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(49, tmpRaw);
                } else {
                  ensureUnionSupportIsMutable();
                  unionSupport_.add(tmpRaw);
                }
                break;
              } // case 392
              case 394: {
                int length = input.readRawVarint32();
                int oldLimit = input.pushLimit(length);
                while(input.getBytesUntilLimit() > 0) {
                  int tmpRaw = input.readEnum();
                  org.apache.drill.exec.proto.UserProtos.UnionSupport tmpValue =
                      org.apache.drill.exec.proto.UserProtos.UnionSupport.forNumber(tmpRaw);
                  if (tmpValue == null) {
                    mergeUnknownVarintField(49, tmpRaw);
                  } else {
                    ensureUnionSupportIsMutable();
                    unionSupport_.add(tmpRaw);
                  }
                }
                input.popLimit(oldLimit);
                break;
              } // case 394
              case 402: {
                currentSchema_ = input.readBytes();
                bitField1_ |= 0x00020000;
                break;
              } // case 402
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;
      private int bitField1_;

      private boolean allTablesSelectable_ ;
      /**
       * <pre>
       * True if current user can use all tables returned by GetTables
       * </pre>
       *
       * <code>optional bool all_tables_selectable = 1;</code>
       * @return Whether the allTablesSelectable field is set.
       */
      @java.lang.Override
      public boolean hasAllTablesSelectable() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * True if current user can use all tables returned by GetTables
       * </pre>
       *
       * <code>optional bool all_tables_selectable = 1;</code>
       * @return The allTablesSelectable.
       */
      @java.lang.Override
      public boolean getAllTablesSelectable() {
        return allTablesSelectable_;
      }
      /**
       * <pre>
       * True if current user can use all tables returned by GetTables
       * </pre>
       *
       * <code>optional bool all_tables_selectable = 1;</code>
       * @param value The allTablesSelectable to set.
       * @return This builder for chaining.
       */
      public Builder setAllTablesSelectable(boolean value) {
        bitField0_ |= 0x00000001;
        allTablesSelectable_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if current user can use all tables returned by GetTables
       * </pre>
       *
       * <code>optional bool all_tables_selectable = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearAllTablesSelectable() {
        bitField0_ = (bitField0_ & ~0x00000001);
        allTablesSelectable_ = false;
        onChanged();
        return this;
      }

      private boolean blobIncludedInMaxRowSize_ ;
      /**
       * <pre>
       * True if BLOB are included into the max row size
       * </pre>
       *
       * <code>optional bool blob_included_in_max_row_size = 2;</code>
       * @return Whether the blobIncludedInMaxRowSize field is set.
       */
      @java.lang.Override
      public boolean hasBlobIncludedInMaxRowSize() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <pre>
       * True if BLOB are included into the max row size
       * </pre>
       *
       * <code>optional bool blob_included_in_max_row_size = 2;</code>
       * @return The blobIncludedInMaxRowSize.
       */
      @java.lang.Override
      public boolean getBlobIncludedInMaxRowSize() {
        return blobIncludedInMaxRowSize_;
      }
      /**
       * <pre>
       * True if BLOB are included into the max row size
       * </pre>
       *
       * <code>optional bool blob_included_in_max_row_size = 2;</code>
       * @param value The blobIncludedInMaxRowSize to set.
       * @return This builder for chaining.
       */
      public Builder setBlobIncludedInMaxRowSize(boolean value) {
        bitField0_ |= 0x00000002;
        blobIncludedInMaxRowSize_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if BLOB are included into the max row size
       * </pre>
       *
       * <code>optional bool blob_included_in_max_row_size = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearBlobIncludedInMaxRowSize() {
        bitField0_ = (bitField0_ & ~0x00000002);
        blobIncludedInMaxRowSize_ = false;
        onChanged();
        return this;
      }

      private boolean catalogAtStart_ ;
      /**
       * <pre>
       * True if catalog name is at the start of a fully qualified table
       * </pre>
       *
       * <code>optional bool catalog_at_start = 3;</code>
       * @return Whether the catalogAtStart field is set.
       */
      @java.lang.Override
      public boolean hasCatalogAtStart() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * True if catalog name is at the start of a fully qualified table
       * </pre>
       *
       * <code>optional bool catalog_at_start = 3;</code>
       * @return The catalogAtStart.
       */
      @java.lang.Override
      public boolean getCatalogAtStart() {
        return catalogAtStart_;
      }
      /**
       * <pre>
       * True if catalog name is at the start of a fully qualified table
       * </pre>
       *
       * <code>optional bool catalog_at_start = 3;</code>
       * @param value The catalogAtStart to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogAtStart(boolean value) {
        bitField0_ |= 0x00000004;
        catalogAtStart_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if catalog name is at the start of a fully qualified table
       * </pre>
       *
       * <code>optional bool catalog_at_start = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogAtStart() {
        bitField0_ = (bitField0_ & ~0x00000004);
        catalogAtStart_ = false;
        onChanged();
        return this;
      }

      private java.lang.Object catalogSeparator_ = "";
      /**
       * <pre>
       * The catalog separator
       * </pre>
       *
       * <code>optional string catalog_separator = 4;</code>
       * @return Whether the catalogSeparator field is set.
       */
      public boolean hasCatalogSeparator() {
        return ((bitField0_ & 0x00000008) != 0);
      }
      /**
       * <pre>
       * The catalog separator
       * </pre>
       *
       * <code>optional string catalog_separator = 4;</code>
       * @return The catalogSeparator.
       */
      public java.lang.String getCatalogSeparator() {
        java.lang.Object ref = catalogSeparator_;
        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()) {
            catalogSeparator_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The catalog separator
       * </pre>
       *
       * <code>optional string catalog_separator = 4;</code>
       * @return The bytes for catalogSeparator.
       */
      public com.google.protobuf.ByteString
          getCatalogSeparatorBytes() {
        java.lang.Object ref = catalogSeparator_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          catalogSeparator_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The catalog separator
       * </pre>
       *
       * <code>optional string catalog_separator = 4;</code>
       * @param value The catalogSeparator to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogSeparator(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        catalogSeparator_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The catalog separator
       * </pre>
       *
       * <code>optional string catalog_separator = 4;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogSeparator() {
        bitField0_ = (bitField0_ & ~0x00000008);
        catalogSeparator_ = getDefaultInstance().getCatalogSeparator();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The catalog separator
       * </pre>
       *
       * <code>optional string catalog_separator = 4;</code>
       * @param value The bytes for catalogSeparator to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogSeparatorBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000008;
        catalogSeparator_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object catalogTerm_ = "";
      /**
       * <pre>
       * The term used to designate catalogs
       * </pre>
       *
       * <code>optional string catalog_term = 5;</code>
       * @return Whether the catalogTerm field is set.
       */
      public boolean hasCatalogTerm() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <pre>
       * The term used to designate catalogs
       * </pre>
       *
       * <code>optional string catalog_term = 5;</code>
       * @return The catalogTerm.
       */
      public java.lang.String getCatalogTerm() {
        java.lang.Object ref = catalogTerm_;
        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()) {
            catalogTerm_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The term used to designate catalogs
       * </pre>
       *
       * <code>optional string catalog_term = 5;</code>
       * @return The bytes for catalogTerm.
       */
      public com.google.protobuf.ByteString
          getCatalogTermBytes() {
        java.lang.Object ref = catalogTerm_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          catalogTerm_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The term used to designate catalogs
       * </pre>
       *
       * <code>optional string catalog_term = 5;</code>
       * @param value The catalogTerm to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogTerm(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        catalogTerm_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The term used to designate catalogs
       * </pre>
       *
       * <code>optional string catalog_term = 5;</code>
       * @return This builder for chaining.
       */
      public Builder clearCatalogTerm() {
        bitField0_ = (bitField0_ & ~0x00000010);
        catalogTerm_ = getDefaultInstance().getCatalogTerm();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The term used to designate catalogs
       * </pre>
       *
       * <code>optional string catalog_term = 5;</code>
       * @param value The bytes for catalogTerm to set.
       * @return This builder for chaining.
       */
      public Builder setCatalogTermBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000010;
        catalogTerm_ = value;
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> collateSupport_ =
        java.util.Collections.emptyList();
      private void ensureCollateSupportIsMutable() {
        if (!((bitField0_ & 0x00000020) != 0)) {
          collateSupport_ = new java.util.ArrayList<java.lang.Integer>(collateSupport_);
          bitField0_ |= 0x00000020;
        }
      }
      /**
       * <pre>
       * COLLATE support
       * </pre>
       *
       * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
       * @return A list containing the collateSupport.
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.CollateSupport> getCollateSupportList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.exec.proto.UserProtos.CollateSupport>(collateSupport_, collateSupport_converter_);
      }
      /**
       * <pre>
       * COLLATE support
       * </pre>
       *
       * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
       * @return The count of collateSupport.
       */
      public int getCollateSupportCount() {
        return collateSupport_.size();
      }
      /**
       * <pre>
       * COLLATE support
       * </pre>
       *
       * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
       * @param index The index of the element to return.
       * @return The collateSupport at the given index.
       */
      public org.apache.drill.exec.proto.UserProtos.CollateSupport getCollateSupport(int index) {
        return collateSupport_converter_.convert(collateSupport_.get(index));
      }
      /**
       * <pre>
       * COLLATE support
       * </pre>
       *
       * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
       * @param index The index to set the value at.
       * @param value The collateSupport to set.
       * @return This builder for chaining.
       */
      public Builder setCollateSupport(
          int index, org.apache.drill.exec.proto.UserProtos.CollateSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureCollateSupportIsMutable();
        collateSupport_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * COLLATE support
       * </pre>
       *
       * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
       * @param value The collateSupport to add.
       * @return This builder for chaining.
       */
      public Builder addCollateSupport(org.apache.drill.exec.proto.UserProtos.CollateSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureCollateSupportIsMutable();
        collateSupport_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * COLLATE support
       * </pre>
       *
       * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
       * @param values The collateSupport to add.
       * @return This builder for chaining.
       */
      public Builder addAllCollateSupport(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.CollateSupport> values) {
        ensureCollateSupportIsMutable();
        for (org.apache.drill.exec.proto.UserProtos.CollateSupport value : values) {
          collateSupport_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * COLLATE support
       * </pre>
       *
       * <code>repeated .exec.user.CollateSupport collate_support = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearCollateSupport() {
        collateSupport_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000020);
        onChanged();
        return this;
      }

      private boolean columnAliasingSupported_ ;
      /**
       * <pre>
       * True if column aliasing is supported
       * </pre>
       *
       * <code>optional bool column_aliasing_supported = 7;</code>
       * @return Whether the columnAliasingSupported field is set.
       */
      @java.lang.Override
      public boolean hasColumnAliasingSupported() {
        return ((bitField0_ & 0x00000040) != 0);
      }
      /**
       * <pre>
       * True if column aliasing is supported
       * </pre>
       *
       * <code>optional bool column_aliasing_supported = 7;</code>
       * @return The columnAliasingSupported.
       */
      @java.lang.Override
      public boolean getColumnAliasingSupported() {
        return columnAliasingSupported_;
      }
      /**
       * <pre>
       * True if column aliasing is supported
       * </pre>
       *
       * <code>optional bool column_aliasing_supported = 7;</code>
       * @param value The columnAliasingSupported to set.
       * @return This builder for chaining.
       */
      public Builder setColumnAliasingSupported(boolean value) {
        bitField0_ |= 0x00000040;
        columnAliasingSupported_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if column aliasing is supported
       * </pre>
       *
       * <code>optional bool column_aliasing_supported = 7;</code>
       * @return This builder for chaining.
       */
      public Builder clearColumnAliasingSupported() {
        bitField0_ = (bitField0_ & ~0x00000040);
        columnAliasingSupported_ = false;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.UserProtos.ConvertSupport> convertSupport_ =
        java.util.Collections.emptyList();
      private void ensureConvertSupportIsMutable() {
        if (!((bitField0_ & 0x00000080) != 0)) {
          convertSupport_ = new java.util.ArrayList<org.apache.drill.exec.proto.UserProtos.ConvertSupport>(convertSupport_);
          bitField0_ |= 0x00000080;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ConvertSupport, org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder, org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder> convertSupportBuilder_;

      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.ConvertSupport> getConvertSupportList() {
        if (convertSupportBuilder_ == null) {
          return java.util.Collections.unmodifiableList(convertSupport_);
        } else {
          return convertSupportBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public int getConvertSupportCount() {
        if (convertSupportBuilder_ == null) {
          return convertSupport_.size();
        } else {
          return convertSupportBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ConvertSupport getConvertSupport(int index) {
        if (convertSupportBuilder_ == null) {
          return convertSupport_.get(index);
        } else {
          return convertSupportBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder setConvertSupport(
          int index, org.apache.drill.exec.proto.UserProtos.ConvertSupport value) {
        if (convertSupportBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureConvertSupportIsMutable();
          convertSupport_.set(index, value);
          onChanged();
        } else {
          convertSupportBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder setConvertSupport(
          int index, org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder builderForValue) {
        if (convertSupportBuilder_ == null) {
          ensureConvertSupportIsMutable();
          convertSupport_.set(index, builderForValue.build());
          onChanged();
        } else {
          convertSupportBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder addConvertSupport(org.apache.drill.exec.proto.UserProtos.ConvertSupport value) {
        if (convertSupportBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureConvertSupportIsMutable();
          convertSupport_.add(value);
          onChanged();
        } else {
          convertSupportBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder addConvertSupport(
          int index, org.apache.drill.exec.proto.UserProtos.ConvertSupport value) {
        if (convertSupportBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureConvertSupportIsMutable();
          convertSupport_.add(index, value);
          onChanged();
        } else {
          convertSupportBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder addConvertSupport(
          org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder builderForValue) {
        if (convertSupportBuilder_ == null) {
          ensureConvertSupportIsMutable();
          convertSupport_.add(builderForValue.build());
          onChanged();
        } else {
          convertSupportBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder addConvertSupport(
          int index, org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder builderForValue) {
        if (convertSupportBuilder_ == null) {
          ensureConvertSupportIsMutable();
          convertSupport_.add(index, builderForValue.build());
          onChanged();
        } else {
          convertSupportBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder addAllConvertSupport(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.ConvertSupport> values) {
        if (convertSupportBuilder_ == null) {
          ensureConvertSupportIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, convertSupport_);
          onChanged();
        } else {
          convertSupportBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder clearConvertSupport() {
        if (convertSupportBuilder_ == null) {
          convertSupport_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000080);
          onChanged();
        } else {
          convertSupportBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public Builder removeConvertSupport(int index) {
        if (convertSupportBuilder_ == null) {
          ensureConvertSupportIsMutable();
          convertSupport_.remove(index);
          onChanged();
        } else {
          convertSupportBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder getConvertSupportBuilder(
          int index) {
        return getConvertSupportFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder getConvertSupportOrBuilder(
          int index) {
        if (convertSupportBuilder_ == null) {
          return convertSupport_.get(index);  } else {
          return convertSupportBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder> 
           getConvertSupportOrBuilderList() {
        if (convertSupportBuilder_ != null) {
          return convertSupportBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(convertSupport_);
        }
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder addConvertSupportBuilder() {
        return getConvertSupportFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.UserProtos.ConvertSupport.getDefaultInstance());
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder addConvertSupportBuilder(
          int index) {
        return getConvertSupportFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.UserProtos.ConvertSupport.getDefaultInstance());
      }
      /**
       * <pre>
       * CONVERT support
       * </pre>
       *
       * <code>repeated .exec.user.ConvertSupport convert_support = 8;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder> 
           getConvertSupportBuilderList() {
        return getConvertSupportFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.ConvertSupport, org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder, org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder> 
          getConvertSupportFieldBuilder() {
        if (convertSupportBuilder_ == null) {
          convertSupportBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.ConvertSupport, org.apache.drill.exec.proto.UserProtos.ConvertSupport.Builder, org.apache.drill.exec.proto.UserProtos.ConvertSupportOrBuilder>(
                  convertSupport_,
                  ((bitField0_ & 0x00000080) != 0),
                  getParentForChildren(),
                  isClean());
          convertSupport_ = null;
        }
        return convertSupportBuilder_;
      }

      private int correlationNamesSupport_ = 1;
      /**
       * <pre>
       * Correlation names support
       * </pre>
       *
       * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
       * @return Whether the correlationNamesSupport field is set.
       */
      @java.lang.Override public boolean hasCorrelationNamesSupport() {
        return ((bitField0_ & 0x00000100) != 0);
      }
      /**
       * <pre>
       * Correlation names support
       * </pre>
       *
       * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
       * @return The correlationNamesSupport.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport getCorrelationNamesSupport() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport result = org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport.valueOf(correlationNamesSupport_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport.CN_NONE : result;
      }
      /**
       * <pre>
       * Correlation names support
       * </pre>
       *
       * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
       * @param value The correlationNamesSupport to set.
       * @return This builder for chaining.
       */
      public Builder setCorrelationNamesSupport(org.apache.drill.exec.proto.UserProtos.CorrelationNamesSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000100;
        correlationNamesSupport_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Correlation names support
       * </pre>
       *
       * <code>optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;</code>
       * @return This builder for chaining.
       */
      public Builder clearCorrelationNamesSupport() {
        bitField0_ = (bitField0_ & ~0x00000100);
        correlationNamesSupport_ = 1;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList dateTimeFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureDateTimeFunctionsIsMutable() {
        if (!((bitField0_ & 0x00000200) != 0)) {
          dateTimeFunctions_ = new com.google.protobuf.LazyStringArrayList(dateTimeFunctions_);
          bitField0_ |= 0x00000200;
         }
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @return A list containing the dateTimeFunctions.
       */
      public com.google.protobuf.ProtocolStringList
          getDateTimeFunctionsList() {
        return dateTimeFunctions_.getUnmodifiableView();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @return The count of dateTimeFunctions.
       */
      public int getDateTimeFunctionsCount() {
        return dateTimeFunctions_.size();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @param index The index of the element to return.
       * @return The dateTimeFunctions at the given index.
       */
      public java.lang.String getDateTimeFunctions(int index) {
        return dateTimeFunctions_.get(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @param index The index of the value to return.
       * @return The bytes of the dateTimeFunctions at the given index.
       */
      public com.google.protobuf.ByteString
          getDateTimeFunctionsBytes(int index) {
        return dateTimeFunctions_.getByteString(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @param index The index to set the value at.
       * @param value The dateTimeFunctions to set.
       * @return This builder for chaining.
       */
      public Builder setDateTimeFunctions(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureDateTimeFunctionsIsMutable();
        dateTimeFunctions_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @param value The dateTimeFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addDateTimeFunctions(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureDateTimeFunctionsIsMutable();
        dateTimeFunctions_.add(value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @param values The dateTimeFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addAllDateTimeFunctions(
          java.lang.Iterable<java.lang.String> values) {
        ensureDateTimeFunctionsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, dateTimeFunctions_);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @return This builder for chaining.
       */
      public Builder clearDateTimeFunctions() {
        dateTimeFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField0_ = (bitField0_ & ~0x00000200);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC Date Time scalar functions
       * </pre>
       *
       * <code>repeated string date_time_functions = 10;</code>
       * @param value The bytes of the dateTimeFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addDateTimeFunctionsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureDateTimeFunctionsIsMutable();
        dateTimeFunctions_.add(value);
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> dateTimeLiteralsSupport_ =
        java.util.Collections.emptyList();
      private void ensureDateTimeLiteralsSupportIsMutable() {
        if (!((bitField0_ & 0x00000400) != 0)) {
          dateTimeLiteralsSupport_ = new java.util.ArrayList<java.lang.Integer>(dateTimeLiteralsSupport_);
          bitField0_ |= 0x00000400;
        }
      }
      /**
       * <pre>
       * Supported Date Time literals
       * </pre>
       *
       * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
       * @return A list containing the dateTimeLiteralsSupport.
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport> getDateTimeLiteralsSupportList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport>(dateTimeLiteralsSupport_, dateTimeLiteralsSupport_converter_);
      }
      /**
       * <pre>
       * Supported Date Time literals
       * </pre>
       *
       * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
       * @return The count of dateTimeLiteralsSupport.
       */
      public int getDateTimeLiteralsSupportCount() {
        return dateTimeLiteralsSupport_.size();
      }
      /**
       * <pre>
       * Supported Date Time literals
       * </pre>
       *
       * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
       * @param index The index of the element to return.
       * @return The dateTimeLiteralsSupport at the given index.
       */
      public org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport getDateTimeLiteralsSupport(int index) {
        return dateTimeLiteralsSupport_converter_.convert(dateTimeLiteralsSupport_.get(index));
      }
      /**
       * <pre>
       * Supported Date Time literals
       * </pre>
       *
       * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
       * @param index The index to set the value at.
       * @param value The dateTimeLiteralsSupport to set.
       * @return This builder for chaining.
       */
      public Builder setDateTimeLiteralsSupport(
          int index, org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureDateTimeLiteralsSupportIsMutable();
        dateTimeLiteralsSupport_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported Date Time literals
       * </pre>
       *
       * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
       * @param value The dateTimeLiteralsSupport to add.
       * @return This builder for chaining.
       */
      public Builder addDateTimeLiteralsSupport(org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureDateTimeLiteralsSupportIsMutable();
        dateTimeLiteralsSupport_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported Date Time literals
       * </pre>
       *
       * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
       * @param values The dateTimeLiteralsSupport to add.
       * @return This builder for chaining.
       */
      public Builder addAllDateTimeLiteralsSupport(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport> values) {
        ensureDateTimeLiteralsSupportIsMutable();
        for (org.apache.drill.exec.proto.UserProtos.DateTimeLiteralsSupport value : values) {
          dateTimeLiteralsSupport_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported Date Time literals
       * </pre>
       *
       * <code>repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;</code>
       * @return This builder for chaining.
       */
      public Builder clearDateTimeLiteralsSupport() {
        dateTimeLiteralsSupport_ = java.util.Collections.emptyList();
        bitField0_ = (bitField0_ & ~0x00000400);
        onChanged();
        return this;
      }

      private int groupBySupport_ = 1;
      /**
       * <pre>
       * Group By support
       * </pre>
       *
       * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
       * @return Whether the groupBySupport field is set.
       */
      @java.lang.Override public boolean hasGroupBySupport() {
        return ((bitField0_ & 0x00000800) != 0);
      }
      /**
       * <pre>
       * Group By support
       * </pre>
       *
       * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
       * @return The groupBySupport.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.GroupBySupport getGroupBySupport() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.GroupBySupport result = org.apache.drill.exec.proto.UserProtos.GroupBySupport.valueOf(groupBySupport_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.GroupBySupport.GB_NONE : result;
      }
      /**
       * <pre>
       * Group By support
       * </pre>
       *
       * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
       * @param value The groupBySupport to set.
       * @return This builder for chaining.
       */
      public Builder setGroupBySupport(org.apache.drill.exec.proto.UserProtos.GroupBySupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000800;
        groupBySupport_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Group By support
       * </pre>
       *
       * <code>optional .exec.user.GroupBySupport group_by_support = 12;</code>
       * @return This builder for chaining.
       */
      public Builder clearGroupBySupport() {
        bitField0_ = (bitField0_ & ~0x00000800);
        groupBySupport_ = 1;
        onChanged();
        return this;
      }

      private int identifierCasing_ = 0;
      /**
       * <pre>
       * Unquoted Identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
       * @return Whether the identifierCasing field is set.
       */
      @java.lang.Override public boolean hasIdentifierCasing() {
        return ((bitField0_ & 0x00001000) != 0);
      }
      /**
       * <pre>
       * Unquoted Identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
       * @return The identifierCasing.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.IdentifierCasing getIdentifierCasing() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.IdentifierCasing result = org.apache.drill.exec.proto.UserProtos.IdentifierCasing.valueOf(identifierCasing_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.IdentifierCasing.IC_UNKNOWN : result;
      }
      /**
       * <pre>
       * Unquoted Identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
       * @param value The identifierCasing to set.
       * @return This builder for chaining.
       */
      public Builder setIdentifierCasing(org.apache.drill.exec.proto.UserProtos.IdentifierCasing value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00001000;
        identifierCasing_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Unquoted Identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing identifier_casing = 13;</code>
       * @return This builder for chaining.
       */
      public Builder clearIdentifierCasing() {
        bitField0_ = (bitField0_ & ~0x00001000);
        identifierCasing_ = 0;
        onChanged();
        return this;
      }

      private java.lang.Object identifierQuoteString_ = "";
      /**
       * <pre>
       * Quote string for identifiers
       * </pre>
       *
       * <code>optional string identifier_quote_string = 14;</code>
       * @return Whether the identifierQuoteString field is set.
       */
      public boolean hasIdentifierQuoteString() {
        return ((bitField0_ & 0x00002000) != 0);
      }
      /**
       * <pre>
       * Quote string for identifiers
       * </pre>
       *
       * <code>optional string identifier_quote_string = 14;</code>
       * @return The identifierQuoteString.
       */
      public java.lang.String getIdentifierQuoteString() {
        java.lang.Object ref = identifierQuoteString_;
        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()) {
            identifierQuoteString_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Quote string for identifiers
       * </pre>
       *
       * <code>optional string identifier_quote_string = 14;</code>
       * @return The bytes for identifierQuoteString.
       */
      public com.google.protobuf.ByteString
          getIdentifierQuoteStringBytes() {
        java.lang.Object ref = identifierQuoteString_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          identifierQuoteString_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Quote string for identifiers
       * </pre>
       *
       * <code>optional string identifier_quote_string = 14;</code>
       * @param value The identifierQuoteString to set.
       * @return This builder for chaining.
       */
      public Builder setIdentifierQuoteString(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00002000;
        identifierQuoteString_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Quote string for identifiers
       * </pre>
       *
       * <code>optional string identifier_quote_string = 14;</code>
       * @return This builder for chaining.
       */
      public Builder clearIdentifierQuoteString() {
        bitField0_ = (bitField0_ & ~0x00002000);
        identifierQuoteString_ = getDefaultInstance().getIdentifierQuoteString();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Quote string for identifiers
       * </pre>
       *
       * <code>optional string identifier_quote_string = 14;</code>
       * @param value The bytes for identifierQuoteString to set.
       * @return This builder for chaining.
       */
      public Builder setIdentifierQuoteStringBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00002000;
        identifierQuoteString_ = value;
        onChanged();
        return this;
      }

      private boolean likeEscapeClauseSupported_ ;
      /**
       * <pre>
       * True if LIKE supports an ESCAPE clause
       * </pre>
       *
       * <code>optional bool like_escape_clause_supported = 15;</code>
       * @return Whether the likeEscapeClauseSupported field is set.
       */
      @java.lang.Override
      public boolean hasLikeEscapeClauseSupported() {
        return ((bitField0_ & 0x00004000) != 0);
      }
      /**
       * <pre>
       * True if LIKE supports an ESCAPE clause
       * </pre>
       *
       * <code>optional bool like_escape_clause_supported = 15;</code>
       * @return The likeEscapeClauseSupported.
       */
      @java.lang.Override
      public boolean getLikeEscapeClauseSupported() {
        return likeEscapeClauseSupported_;
      }
      /**
       * <pre>
       * True if LIKE supports an ESCAPE clause
       * </pre>
       *
       * <code>optional bool like_escape_clause_supported = 15;</code>
       * @param value The likeEscapeClauseSupported to set.
       * @return This builder for chaining.
       */
      public Builder setLikeEscapeClauseSupported(boolean value) {
        bitField0_ |= 0x00004000;
        likeEscapeClauseSupported_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if LIKE supports an ESCAPE clause
       * </pre>
       *
       * <code>optional bool like_escape_clause_supported = 15;</code>
       * @return This builder for chaining.
       */
      public Builder clearLikeEscapeClauseSupported() {
        bitField0_ = (bitField0_ & ~0x00004000);
        likeEscapeClauseSupported_ = false;
        onChanged();
        return this;
      }

      private int maxBinaryLiteralLength_ ;
      /**
       * <pre>
       * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_binary_literal_length = 16;</code>
       * @return Whether the maxBinaryLiteralLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxBinaryLiteralLength() {
        return ((bitField0_ & 0x00008000) != 0);
      }
      /**
       * <pre>
       * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_binary_literal_length = 16;</code>
       * @return The maxBinaryLiteralLength.
       */
      @java.lang.Override
      public int getMaxBinaryLiteralLength() {
        return maxBinaryLiteralLength_;
      }
      /**
       * <pre>
       * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_binary_literal_length = 16;</code>
       * @param value The maxBinaryLiteralLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxBinaryLiteralLength(int value) {
        bitField0_ |= 0x00008000;
        maxBinaryLiteralLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of hexa characters for binary literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_binary_literal_length = 16;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxBinaryLiteralLength() {
        bitField0_ = (bitField0_ & ~0x00008000);
        maxBinaryLiteralLength_ = 0;
        onChanged();
        return this;
      }

      private int maxCatalogNameLength_ ;
      /**
       * <pre>
       * Maximum length of catalog names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_catalog_name_length = 17;</code>
       * @return Whether the maxCatalogNameLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxCatalogNameLength() {
        return ((bitField0_ & 0x00010000) != 0);
      }
      /**
       * <pre>
       * Maximum length of catalog names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_catalog_name_length = 17;</code>
       * @return The maxCatalogNameLength.
       */
      @java.lang.Override
      public int getMaxCatalogNameLength() {
        return maxCatalogNameLength_;
      }
      /**
       * <pre>
       * Maximum length of catalog names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_catalog_name_length = 17;</code>
       * @param value The maxCatalogNameLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxCatalogNameLength(int value) {
        bitField0_ |= 0x00010000;
        maxCatalogNameLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum length of catalog names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_catalog_name_length = 17;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxCatalogNameLength() {
        bitField0_ = (bitField0_ & ~0x00010000);
        maxCatalogNameLength_ = 0;
        onChanged();
        return this;
      }

      private int maxCharLiteralLength_ ;
      /**
       * <pre>
       * Maximum number of characters for string literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_char_literal_length = 18;</code>
       * @return Whether the maxCharLiteralLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxCharLiteralLength() {
        return ((bitField0_ & 0x00020000) != 0);
      }
      /**
       * <pre>
       * Maximum number of characters for string literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_char_literal_length = 18;</code>
       * @return The maxCharLiteralLength.
       */
      @java.lang.Override
      public int getMaxCharLiteralLength() {
        return maxCharLiteralLength_;
      }
      /**
       * <pre>
       * Maximum number of characters for string literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_char_literal_length = 18;</code>
       * @param value The maxCharLiteralLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxCharLiteralLength(int value) {
        bitField0_ |= 0x00020000;
        maxCharLiteralLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of characters for string literals (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_char_literal_length = 18;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxCharLiteralLength() {
        bitField0_ = (bitField0_ & ~0x00020000);
        maxCharLiteralLength_ = 0;
        onChanged();
        return this;
      }

      private int maxColumnNameLength_ ;
      /**
       * <pre>
       * Maximum length of column names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_column_name_length = 19;</code>
       * @return Whether the maxColumnNameLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxColumnNameLength() {
        return ((bitField0_ & 0x00040000) != 0);
      }
      /**
       * <pre>
       * Maximum length of column names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_column_name_length = 19;</code>
       * @return The maxColumnNameLength.
       */
      @java.lang.Override
      public int getMaxColumnNameLength() {
        return maxColumnNameLength_;
      }
      /**
       * <pre>
       * Maximum length of column names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_column_name_length = 19;</code>
       * @param value The maxColumnNameLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxColumnNameLength(int value) {
        bitField0_ |= 0x00040000;
        maxColumnNameLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum length of column names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_column_name_length = 19;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxColumnNameLength() {
        bitField0_ = (bitField0_ & ~0x00040000);
        maxColumnNameLength_ = 0;
        onChanged();
        return this;
      }

      private int maxColumnsInGroupBy_ ;
      /**
       * <pre>
       * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_group_by = 20;</code>
       * @return Whether the maxColumnsInGroupBy field is set.
       */
      @java.lang.Override
      public boolean hasMaxColumnsInGroupBy() {
        return ((bitField0_ & 0x00080000) != 0);
      }
      /**
       * <pre>
       * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_group_by = 20;</code>
       * @return The maxColumnsInGroupBy.
       */
      @java.lang.Override
      public int getMaxColumnsInGroupBy() {
        return maxColumnsInGroupBy_;
      }
      /**
       * <pre>
       * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_group_by = 20;</code>
       * @param value The maxColumnsInGroupBy to set.
       * @return This builder for chaining.
       */
      public Builder setMaxColumnsInGroupBy(int value) {
        bitField0_ |= 0x00080000;
        maxColumnsInGroupBy_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of columns in GROUP BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_group_by = 20;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxColumnsInGroupBy() {
        bitField0_ = (bitField0_ & ~0x00080000);
        maxColumnsInGroupBy_ = 0;
        onChanged();
        return this;
      }

      private int maxColumnsInOrderBy_ ;
      /**
       * <pre>
       * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_order_by = 21;</code>
       * @return Whether the maxColumnsInOrderBy field is set.
       */
      @java.lang.Override
      public boolean hasMaxColumnsInOrderBy() {
        return ((bitField0_ & 0x00100000) != 0);
      }
      /**
       * <pre>
       * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_order_by = 21;</code>
       * @return The maxColumnsInOrderBy.
       */
      @java.lang.Override
      public int getMaxColumnsInOrderBy() {
        return maxColumnsInOrderBy_;
      }
      /**
       * <pre>
       * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_order_by = 21;</code>
       * @param value The maxColumnsInOrderBy to set.
       * @return This builder for chaining.
       */
      public Builder setMaxColumnsInOrderBy(int value) {
        bitField0_ |= 0x00100000;
        maxColumnsInOrderBy_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of columns in ORDER BY expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_order_by = 21;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxColumnsInOrderBy() {
        bitField0_ = (bitField0_ & ~0x00100000);
        maxColumnsInOrderBy_ = 0;
        onChanged();
        return this;
      }

      private int maxColumnsInSelect_ ;
      /**
       * <pre>
       * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_select = 22;</code>
       * @return Whether the maxColumnsInSelect field is set.
       */
      @java.lang.Override
      public boolean hasMaxColumnsInSelect() {
        return ((bitField0_ & 0x00200000) != 0);
      }
      /**
       * <pre>
       * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_select = 22;</code>
       * @return The maxColumnsInSelect.
       */
      @java.lang.Override
      public int getMaxColumnsInSelect() {
        return maxColumnsInSelect_;
      }
      /**
       * <pre>
       * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_select = 22;</code>
       * @param value The maxColumnsInSelect to set.
       * @return This builder for chaining.
       */
      public Builder setMaxColumnsInSelect(int value) {
        bitField0_ |= 0x00200000;
        maxColumnsInSelect_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of columns in SELECT expressions (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_columns_in_select = 22;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxColumnsInSelect() {
        bitField0_ = (bitField0_ & ~0x00200000);
        maxColumnsInSelect_ = 0;
        onChanged();
        return this;
      }

      private int maxCursorNameLength_ ;
      /**
       * <pre>
       * Maximum length of cursor names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_cursor_name_length = 23;</code>
       * @return Whether the maxCursorNameLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxCursorNameLength() {
        return ((bitField0_ & 0x00400000) != 0);
      }
      /**
       * <pre>
       * Maximum length of cursor names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_cursor_name_length = 23;</code>
       * @return The maxCursorNameLength.
       */
      @java.lang.Override
      public int getMaxCursorNameLength() {
        return maxCursorNameLength_;
      }
      /**
       * <pre>
       * Maximum length of cursor names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_cursor_name_length = 23;</code>
       * @param value The maxCursorNameLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxCursorNameLength(int value) {
        bitField0_ |= 0x00400000;
        maxCursorNameLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum length of cursor names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_cursor_name_length = 23;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxCursorNameLength() {
        bitField0_ = (bitField0_ & ~0x00400000);
        maxCursorNameLength_ = 0;
        onChanged();
        return this;
      }

      private int maxLogicalLobSize_ ;
      /**
       * <pre>
       * Maximum logical size for LOB types (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_logical_lob_size = 24;</code>
       * @return Whether the maxLogicalLobSize field is set.
       */
      @java.lang.Override
      public boolean hasMaxLogicalLobSize() {
        return ((bitField0_ & 0x00800000) != 0);
      }
      /**
       * <pre>
       * Maximum logical size for LOB types (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_logical_lob_size = 24;</code>
       * @return The maxLogicalLobSize.
       */
      @java.lang.Override
      public int getMaxLogicalLobSize() {
        return maxLogicalLobSize_;
      }
      /**
       * <pre>
       * Maximum logical size for LOB types (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_logical_lob_size = 24;</code>
       * @param value The maxLogicalLobSize to set.
       * @return This builder for chaining.
       */
      public Builder setMaxLogicalLobSize(int value) {
        bitField0_ |= 0x00800000;
        maxLogicalLobSize_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum logical size for LOB types (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_logical_lob_size = 24;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxLogicalLobSize() {
        bitField0_ = (bitField0_ & ~0x00800000);
        maxLogicalLobSize_ = 0;
        onChanged();
        return this;
      }

      private int maxRowSize_ ;
      /**
       * <pre>
       * Maximum number of bytes for a single row (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_row_size = 25;</code>
       * @return Whether the maxRowSize field is set.
       */
      @java.lang.Override
      public boolean hasMaxRowSize() {
        return ((bitField0_ & 0x01000000) != 0);
      }
      /**
       * <pre>
       * Maximum number of bytes for a single row (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_row_size = 25;</code>
       * @return The maxRowSize.
       */
      @java.lang.Override
      public int getMaxRowSize() {
        return maxRowSize_;
      }
      /**
       * <pre>
       * Maximum number of bytes for a single row (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_row_size = 25;</code>
       * @param value The maxRowSize to set.
       * @return This builder for chaining.
       */
      public Builder setMaxRowSize(int value) {
        bitField0_ |= 0x01000000;
        maxRowSize_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of bytes for a single row (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_row_size = 25;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxRowSize() {
        bitField0_ = (bitField0_ & ~0x01000000);
        maxRowSize_ = 0;
        onChanged();
        return this;
      }

      private int maxSchemaNameLength_ ;
      /**
       * <pre>
       * Maximum length of schema names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_schema_name_length = 26;</code>
       * @return Whether the maxSchemaNameLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxSchemaNameLength() {
        return ((bitField0_ & 0x02000000) != 0);
      }
      /**
       * <pre>
       * Maximum length of schema names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_schema_name_length = 26;</code>
       * @return The maxSchemaNameLength.
       */
      @java.lang.Override
      public int getMaxSchemaNameLength() {
        return maxSchemaNameLength_;
      }
      /**
       * <pre>
       * Maximum length of schema names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_schema_name_length = 26;</code>
       * @param value The maxSchemaNameLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxSchemaNameLength(int value) {
        bitField0_ |= 0x02000000;
        maxSchemaNameLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum length of schema names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_schema_name_length = 26;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxSchemaNameLength() {
        bitField0_ = (bitField0_ & ~0x02000000);
        maxSchemaNameLength_ = 0;
        onChanged();
        return this;
      }

      private int maxStatementLength_ ;
      /**
       * <pre>
       * Maximum length for statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statement_length = 27;</code>
       * @return Whether the maxStatementLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxStatementLength() {
        return ((bitField0_ & 0x04000000) != 0);
      }
      /**
       * <pre>
       * Maximum length for statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statement_length = 27;</code>
       * @return The maxStatementLength.
       */
      @java.lang.Override
      public int getMaxStatementLength() {
        return maxStatementLength_;
      }
      /**
       * <pre>
       * Maximum length for statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statement_length = 27;</code>
       * @param value The maxStatementLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxStatementLength(int value) {
        bitField0_ |= 0x04000000;
        maxStatementLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum length for statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statement_length = 27;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxStatementLength() {
        bitField0_ = (bitField0_ & ~0x04000000);
        maxStatementLength_ = 0;
        onChanged();
        return this;
      }

      private int maxStatements_ ;
      /**
       * <pre>
       * Maximum number of statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statements = 28;</code>
       * @return Whether the maxStatements field is set.
       */
      @java.lang.Override
      public boolean hasMaxStatements() {
        return ((bitField0_ & 0x08000000) != 0);
      }
      /**
       * <pre>
       * Maximum number of statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statements = 28;</code>
       * @return The maxStatements.
       */
      @java.lang.Override
      public int getMaxStatements() {
        return maxStatements_;
      }
      /**
       * <pre>
       * Maximum number of statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statements = 28;</code>
       * @param value The maxStatements to set.
       * @return This builder for chaining.
       */
      public Builder setMaxStatements(int value) {
        bitField0_ |= 0x08000000;
        maxStatements_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of statements (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_statements = 28;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxStatements() {
        bitField0_ = (bitField0_ & ~0x08000000);
        maxStatements_ = 0;
        onChanged();
        return this;
      }

      private int maxTableNameLength_ ;
      /**
       * <pre>
       * Maximum length of table names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_table_name_length = 29;</code>
       * @return Whether the maxTableNameLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxTableNameLength() {
        return ((bitField0_ & 0x10000000) != 0);
      }
      /**
       * <pre>
       * Maximum length of table names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_table_name_length = 29;</code>
       * @return The maxTableNameLength.
       */
      @java.lang.Override
      public int getMaxTableNameLength() {
        return maxTableNameLength_;
      }
      /**
       * <pre>
       * Maximum length of table names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_table_name_length = 29;</code>
       * @param value The maxTableNameLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxTableNameLength(int value) {
        bitField0_ |= 0x10000000;
        maxTableNameLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum length of table names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_table_name_length = 29;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxTableNameLength() {
        bitField0_ = (bitField0_ & ~0x10000000);
        maxTableNameLength_ = 0;
        onChanged();
        return this;
      }

      private int maxTablesInSelect_ ;
      /**
       * <pre>
       * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_tables_in_select = 30;</code>
       * @return Whether the maxTablesInSelect field is set.
       */
      @java.lang.Override
      public boolean hasMaxTablesInSelect() {
        return ((bitField0_ & 0x20000000) != 0);
      }
      /**
       * <pre>
       * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_tables_in_select = 30;</code>
       * @return The maxTablesInSelect.
       */
      @java.lang.Override
      public int getMaxTablesInSelect() {
        return maxTablesInSelect_;
      }
      /**
       * <pre>
       * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_tables_in_select = 30;</code>
       * @param value The maxTablesInSelect to set.
       * @return This builder for chaining.
       */
      public Builder setMaxTablesInSelect(int value) {
        bitField0_ |= 0x20000000;
        maxTablesInSelect_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum number of tables in a SELECT expression (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_tables_in_select = 30;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxTablesInSelect() {
        bitField0_ = (bitField0_ & ~0x20000000);
        maxTablesInSelect_ = 0;
        onChanged();
        return this;
      }

      private int maxUserNameLength_ ;
      /**
       * <pre>
       * Maximum length of user names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_user_name_length = 31;</code>
       * @return Whether the maxUserNameLength field is set.
       */
      @java.lang.Override
      public boolean hasMaxUserNameLength() {
        return ((bitField0_ & 0x40000000) != 0);
      }
      /**
       * <pre>
       * Maximum length of user names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_user_name_length = 31;</code>
       * @return The maxUserNameLength.
       */
      @java.lang.Override
      public int getMaxUserNameLength() {
        return maxUserNameLength_;
      }
      /**
       * <pre>
       * Maximum length of user names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_user_name_length = 31;</code>
       * @param value The maxUserNameLength to set.
       * @return This builder for chaining.
       */
      public Builder setMaxUserNameLength(int value) {
        bitField0_ |= 0x40000000;
        maxUserNameLength_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Maximum length of user names (0 if unlimited or unknown)
       * </pre>
       *
       * <code>optional uint32 max_user_name_length = 31;</code>
       * @return This builder for chaining.
       */
      public Builder clearMaxUserNameLength() {
        bitField0_ = (bitField0_ & ~0x40000000);
        maxUserNameLength_ = 0;
        onChanged();
        return this;
      }

      private int nullCollation_ = 0;
      /**
       * <pre>
       * How NULL are sorted
       * </pre>
       *
       * <code>optional .exec.user.NullCollation null_collation = 32;</code>
       * @return Whether the nullCollation field is set.
       */
      @java.lang.Override public boolean hasNullCollation() {
        return ((bitField0_ & 0x80000000) != 0);
      }
      /**
       * <pre>
       * How NULL are sorted
       * </pre>
       *
       * <code>optional .exec.user.NullCollation null_collation = 32;</code>
       * @return The nullCollation.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.NullCollation getNullCollation() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.NullCollation result = org.apache.drill.exec.proto.UserProtos.NullCollation.valueOf(nullCollation_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.NullCollation.NC_UNKNOWN : result;
      }
      /**
       * <pre>
       * How NULL are sorted
       * </pre>
       *
       * <code>optional .exec.user.NullCollation null_collation = 32;</code>
       * @param value The nullCollation to set.
       * @return This builder for chaining.
       */
      public Builder setNullCollation(org.apache.drill.exec.proto.UserProtos.NullCollation value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x80000000;
        nullCollation_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * How NULL are sorted
       * </pre>
       *
       * <code>optional .exec.user.NullCollation null_collation = 32;</code>
       * @return This builder for chaining.
       */
      public Builder clearNullCollation() {
        bitField0_ = (bitField0_ & ~0x80000000);
        nullCollation_ = 0;
        onChanged();
        return this;
      }

      private boolean nullPlusNonNullEqualsNull_ ;
      /**
       * <pre>
       * True if NULL + non NULL is NULL
       * </pre>
       *
       * <code>optional bool null_plus_non_null_equals_null = 33;</code>
       * @return Whether the nullPlusNonNullEqualsNull field is set.
       */
      @java.lang.Override
      public boolean hasNullPlusNonNullEqualsNull() {
        return ((bitField1_ & 0x00000001) != 0);
      }
      /**
       * <pre>
       * True if NULL + non NULL is NULL
       * </pre>
       *
       * <code>optional bool null_plus_non_null_equals_null = 33;</code>
       * @return The nullPlusNonNullEqualsNull.
       */
      @java.lang.Override
      public boolean getNullPlusNonNullEqualsNull() {
        return nullPlusNonNullEqualsNull_;
      }
      /**
       * <pre>
       * True if NULL + non NULL is NULL
       * </pre>
       *
       * <code>optional bool null_plus_non_null_equals_null = 33;</code>
       * @param value The nullPlusNonNullEqualsNull to set.
       * @return This builder for chaining.
       */
      public Builder setNullPlusNonNullEqualsNull(boolean value) {
        bitField1_ |= 0x00000001;
        nullPlusNonNullEqualsNull_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if NULL + non NULL is NULL
       * </pre>
       *
       * <code>optional bool null_plus_non_null_equals_null = 33;</code>
       * @return This builder for chaining.
       */
      public Builder clearNullPlusNonNullEqualsNull() {
        bitField1_ = (bitField1_ & ~0x00000001);
        nullPlusNonNullEqualsNull_ = false;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList numericFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureNumericFunctionsIsMutable() {
        if (!((bitField1_ & 0x00000002) != 0)) {
          numericFunctions_ = new com.google.protobuf.LazyStringArrayList(numericFunctions_);
          bitField1_ |= 0x00000002;
         }
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @return A list containing the numericFunctions.
       */
      public com.google.protobuf.ProtocolStringList
          getNumericFunctionsList() {
        return numericFunctions_.getUnmodifiableView();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @return The count of numericFunctions.
       */
      public int getNumericFunctionsCount() {
        return numericFunctions_.size();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @param index The index of the element to return.
       * @return The numericFunctions at the given index.
       */
      public java.lang.String getNumericFunctions(int index) {
        return numericFunctions_.get(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @param index The index of the value to return.
       * @return The bytes of the numericFunctions at the given index.
       */
      public com.google.protobuf.ByteString
          getNumericFunctionsBytes(int index) {
        return numericFunctions_.getByteString(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @param index The index to set the value at.
       * @param value The numericFunctions to set.
       * @return This builder for chaining.
       */
      public Builder setNumericFunctions(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureNumericFunctionsIsMutable();
        numericFunctions_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @param value The numericFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addNumericFunctions(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureNumericFunctionsIsMutable();
        numericFunctions_.add(value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @param values The numericFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addAllNumericFunctions(
          java.lang.Iterable<java.lang.String> values) {
        ensureNumericFunctionsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, numericFunctions_);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @return This builder for chaining.
       */
      public Builder clearNumericFunctions() {
        numericFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00000002);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC numeric scalar functions
       * </pre>
       *
       * <code>repeated string numeric_functions = 34;</code>
       * @param value The bytes of the numericFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addNumericFunctionsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureNumericFunctionsIsMutable();
        numericFunctions_.add(value);
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> orderBySupport_ =
        java.util.Collections.emptyList();
      private void ensureOrderBySupportIsMutable() {
        if (!((bitField1_ & 0x00000004) != 0)) {
          orderBySupport_ = new java.util.ArrayList<java.lang.Integer>(orderBySupport_);
          bitField1_ |= 0x00000004;
        }
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
       * @return A list containing the orderBySupport.
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.OrderBySupport> getOrderBySupportList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OrderBySupport>(orderBySupport_, orderBySupport_converter_);
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
       * @return The count of orderBySupport.
       */
      public int getOrderBySupportCount() {
        return orderBySupport_.size();
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
       * @param index The index of the element to return.
       * @return The orderBySupport at the given index.
       */
      public org.apache.drill.exec.proto.UserProtos.OrderBySupport getOrderBySupport(int index) {
        return orderBySupport_converter_.convert(orderBySupport_.get(index));
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
       * @param index The index to set the value at.
       * @param value The orderBySupport to set.
       * @return This builder for chaining.
       */
      public Builder setOrderBySupport(
          int index, org.apache.drill.exec.proto.UserProtos.OrderBySupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureOrderBySupportIsMutable();
        orderBySupport_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
       * @param value The orderBySupport to add.
       * @return This builder for chaining.
       */
      public Builder addOrderBySupport(org.apache.drill.exec.proto.UserProtos.OrderBySupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureOrderBySupportIsMutable();
        orderBySupport_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
       * @param values The orderBySupport to add.
       * @return This builder for chaining.
       */
      public Builder addAllOrderBySupport(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.OrderBySupport> values) {
        ensureOrderBySupportIsMutable();
        for (org.apache.drill.exec.proto.UserProtos.OrderBySupport value : values) {
          orderBySupport_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OrderBySupport order_by_support = 35;</code>
       * @return This builder for chaining.
       */
      public Builder clearOrderBySupport() {
        orderBySupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00000004);
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> outerJoinSupport_ =
        java.util.Collections.emptyList();
      private void ensureOuterJoinSupportIsMutable() {
        if (!((bitField1_ & 0x00000008) != 0)) {
          outerJoinSupport_ = new java.util.ArrayList<java.lang.Integer>(outerJoinSupport_);
          bitField1_ |= 0x00000008;
        }
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
       * @return A list containing the outerJoinSupport.
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.OuterJoinSupport> getOuterJoinSupportList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.exec.proto.UserProtos.OuterJoinSupport>(outerJoinSupport_, outerJoinSupport_converter_);
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
       * @return The count of outerJoinSupport.
       */
      public int getOuterJoinSupportCount() {
        return outerJoinSupport_.size();
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
       * @param index The index of the element to return.
       * @return The outerJoinSupport at the given index.
       */
      public org.apache.drill.exec.proto.UserProtos.OuterJoinSupport getOuterJoinSupport(int index) {
        return outerJoinSupport_converter_.convert(outerJoinSupport_.get(index));
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
       * @param index The index to set the value at.
       * @param value The outerJoinSupport to set.
       * @return This builder for chaining.
       */
      public Builder setOuterJoinSupport(
          int index, org.apache.drill.exec.proto.UserProtos.OuterJoinSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureOuterJoinSupportIsMutable();
        outerJoinSupport_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
       * @param value The outerJoinSupport to add.
       * @return This builder for chaining.
       */
      public Builder addOuterJoinSupport(org.apache.drill.exec.proto.UserProtos.OuterJoinSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureOuterJoinSupportIsMutable();
        outerJoinSupport_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
       * @param values The outerJoinSupport to add.
       * @return This builder for chaining.
       */
      public Builder addAllOuterJoinSupport(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.OuterJoinSupport> values) {
        ensureOuterJoinSupportIsMutable();
        for (org.apache.drill.exec.proto.UserProtos.OuterJoinSupport value : values) {
          outerJoinSupport_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Outer join suport
       * </pre>
       *
       * <code>repeated .exec.user.OuterJoinSupport outer_join_support = 36;</code>
       * @return This builder for chaining.
       */
      public Builder clearOuterJoinSupport() {
        outerJoinSupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00000008);
        onChanged();
        return this;
      }

      private int quotedIdentifierCasing_ = 0;
      /**
       * <pre>
       * Quoted identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
       * @return Whether the quotedIdentifierCasing field is set.
       */
      @java.lang.Override public boolean hasQuotedIdentifierCasing() {
        return ((bitField1_ & 0x00000010) != 0);
      }
      /**
       * <pre>
       * Quoted identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
       * @return The quotedIdentifierCasing.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.IdentifierCasing getQuotedIdentifierCasing() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.IdentifierCasing result = org.apache.drill.exec.proto.UserProtos.IdentifierCasing.valueOf(quotedIdentifierCasing_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.IdentifierCasing.IC_UNKNOWN : result;
      }
      /**
       * <pre>
       * Quoted identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
       * @param value The quotedIdentifierCasing to set.
       * @return This builder for chaining.
       */
      public Builder setQuotedIdentifierCasing(org.apache.drill.exec.proto.UserProtos.IdentifierCasing value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField1_ |= 0x00000010;
        quotedIdentifierCasing_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Quoted identifier casing
       * </pre>
       *
       * <code>optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;</code>
       * @return This builder for chaining.
       */
      public Builder clearQuotedIdentifierCasing() {
        bitField1_ = (bitField1_ & ~0x00000010);
        quotedIdentifierCasing_ = 0;
        onChanged();
        return this;
      }

      private boolean readOnly_ ;
      /**
       * <pre>
       * True if connection access is read only
       * </pre>
       *
       * <code>optional bool read_only = 38;</code>
       * @return Whether the readOnly field is set.
       */
      @java.lang.Override
      public boolean hasReadOnly() {
        return ((bitField1_ & 0x00000020) != 0);
      }
      /**
       * <pre>
       * True if connection access is read only
       * </pre>
       *
       * <code>optional bool read_only = 38;</code>
       * @return The readOnly.
       */
      @java.lang.Override
      public boolean getReadOnly() {
        return readOnly_;
      }
      /**
       * <pre>
       * True if connection access is read only
       * </pre>
       *
       * <code>optional bool read_only = 38;</code>
       * @param value The readOnly to set.
       * @return This builder for chaining.
       */
      public Builder setReadOnly(boolean value) {
        bitField1_ |= 0x00000020;
        readOnly_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if connection access is read only
       * </pre>
       *
       * <code>optional bool read_only = 38;</code>
       * @return This builder for chaining.
       */
      public Builder clearReadOnly() {
        bitField1_ = (bitField1_ & ~0x00000020);
        readOnly_ = false;
        onChanged();
        return this;
      }

      private java.lang.Object schemaTerm_ = "";
      /**
       * <pre>
       * The term used to designate a schema
       * </pre>
       *
       * <code>optional string schema_term = 39;</code>
       * @return Whether the schemaTerm field is set.
       */
      public boolean hasSchemaTerm() {
        return ((bitField1_ & 0x00000040) != 0);
      }
      /**
       * <pre>
       * The term used to designate a schema
       * </pre>
       *
       * <code>optional string schema_term = 39;</code>
       * @return The schemaTerm.
       */
      public java.lang.String getSchemaTerm() {
        java.lang.Object ref = schemaTerm_;
        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()) {
            schemaTerm_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The term used to designate a schema
       * </pre>
       *
       * <code>optional string schema_term = 39;</code>
       * @return The bytes for schemaTerm.
       */
      public com.google.protobuf.ByteString
          getSchemaTermBytes() {
        java.lang.Object ref = schemaTerm_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          schemaTerm_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The term used to designate a schema
       * </pre>
       *
       * <code>optional string schema_term = 39;</code>
       * @param value The schemaTerm to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaTerm(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00000040;
        schemaTerm_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The term used to designate a schema
       * </pre>
       *
       * <code>optional string schema_term = 39;</code>
       * @return This builder for chaining.
       */
      public Builder clearSchemaTerm() {
        bitField1_ = (bitField1_ & ~0x00000040);
        schemaTerm_ = getDefaultInstance().getSchemaTerm();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The term used to designate a schema
       * </pre>
       *
       * <code>optional string schema_term = 39;</code>
       * @param value The bytes for schemaTerm to set.
       * @return This builder for chaining.
       */
      public Builder setSchemaTermBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00000040;
        schemaTerm_ = value;
        onChanged();
        return this;
      }

      private java.lang.Object searchEscapeString_ = "";
      /**
       * <pre>
       * Characters used for escaping (empty if not suported)
       * </pre>
       *
       * <code>optional string search_escape_string = 40;</code>
       * @return Whether the searchEscapeString field is set.
       */
      public boolean hasSearchEscapeString() {
        return ((bitField1_ & 0x00000080) != 0);
      }
      /**
       * <pre>
       * Characters used for escaping (empty if not suported)
       * </pre>
       *
       * <code>optional string search_escape_string = 40;</code>
       * @return The searchEscapeString.
       */
      public java.lang.String getSearchEscapeString() {
        java.lang.Object ref = searchEscapeString_;
        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()) {
            searchEscapeString_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Characters used for escaping (empty if not suported)
       * </pre>
       *
       * <code>optional string search_escape_string = 40;</code>
       * @return The bytes for searchEscapeString.
       */
      public com.google.protobuf.ByteString
          getSearchEscapeStringBytes() {
        java.lang.Object ref = searchEscapeString_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          searchEscapeString_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Characters used for escaping (empty if not suported)
       * </pre>
       *
       * <code>optional string search_escape_string = 40;</code>
       * @param value The searchEscapeString to set.
       * @return This builder for chaining.
       */
      public Builder setSearchEscapeString(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00000080;
        searchEscapeString_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Characters used for escaping (empty if not suported)
       * </pre>
       *
       * <code>optional string search_escape_string = 40;</code>
       * @return This builder for chaining.
       */
      public Builder clearSearchEscapeString() {
        bitField1_ = (bitField1_ & ~0x00000080);
        searchEscapeString_ = getDefaultInstance().getSearchEscapeString();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Characters used for escaping (empty if not suported)
       * </pre>
       *
       * <code>optional string search_escape_string = 40;</code>
       * @param value The bytes for searchEscapeString to set.
       * @return This builder for chaining.
       */
      public Builder setSearchEscapeStringBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00000080;
        searchEscapeString_ = value;
        onChanged();
        return this;
      }

      private boolean selectForUpdateSupported_ ;
      /**
       * <pre>
       * True if SELECT FOR UPDATE is supported
       * </pre>
       *
       * <code>optional bool select_for_update_supported = 41;</code>
       * @return Whether the selectForUpdateSupported field is set.
       */
      @java.lang.Override
      public boolean hasSelectForUpdateSupported() {
        return ((bitField1_ & 0x00000100) != 0);
      }
      /**
       * <pre>
       * True if SELECT FOR UPDATE is supported
       * </pre>
       *
       * <code>optional bool select_for_update_supported = 41;</code>
       * @return The selectForUpdateSupported.
       */
      @java.lang.Override
      public boolean getSelectForUpdateSupported() {
        return selectForUpdateSupported_;
      }
      /**
       * <pre>
       * True if SELECT FOR UPDATE is supported
       * </pre>
       *
       * <code>optional bool select_for_update_supported = 41;</code>
       * @param value The selectForUpdateSupported to set.
       * @return This builder for chaining.
       */
      public Builder setSelectForUpdateSupported(boolean value) {
        bitField1_ |= 0x00000100;
        selectForUpdateSupported_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if SELECT FOR UPDATE is supported
       * </pre>
       *
       * <code>optional bool select_for_update_supported = 41;</code>
       * @return This builder for chaining.
       */
      public Builder clearSelectForUpdateSupported() {
        bitField1_ = (bitField1_ & ~0x00000100);
        selectForUpdateSupported_ = false;
        onChanged();
        return this;
      }

      private java.lang.Object specialCharacters_ = "";
      /**
       * <pre>
       * List of extra characters that can be used in identifier names
       * </pre>
       *
       * <code>optional string special_characters = 42;</code>
       * @return Whether the specialCharacters field is set.
       */
      public boolean hasSpecialCharacters() {
        return ((bitField1_ & 0x00000200) != 0);
      }
      /**
       * <pre>
       * List of extra characters that can be used in identifier names
       * </pre>
       *
       * <code>optional string special_characters = 42;</code>
       * @return The specialCharacters.
       */
      public java.lang.String getSpecialCharacters() {
        java.lang.Object ref = specialCharacters_;
        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()) {
            specialCharacters_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * List of extra characters that can be used in identifier names
       * </pre>
       *
       * <code>optional string special_characters = 42;</code>
       * @return The bytes for specialCharacters.
       */
      public com.google.protobuf.ByteString
          getSpecialCharactersBytes() {
        java.lang.Object ref = specialCharacters_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          specialCharacters_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * List of extra characters that can be used in identifier names
       * </pre>
       *
       * <code>optional string special_characters = 42;</code>
       * @param value The specialCharacters to set.
       * @return This builder for chaining.
       */
      public Builder setSpecialCharacters(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00000200;
        specialCharacters_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * List of extra characters that can be used in identifier names
       * </pre>
       *
       * <code>optional string special_characters = 42;</code>
       * @return This builder for chaining.
       */
      public Builder clearSpecialCharacters() {
        bitField1_ = (bitField1_ & ~0x00000200);
        specialCharacters_ = getDefaultInstance().getSpecialCharacters();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * List of extra characters that can be used in identifier names
       * </pre>
       *
       * <code>optional string special_characters = 42;</code>
       * @param value The bytes for specialCharacters to set.
       * @return This builder for chaining.
       */
      public Builder setSpecialCharactersBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00000200;
        specialCharacters_ = value;
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList sqlKeywords_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureSqlKeywordsIsMutable() {
        if (!((bitField1_ & 0x00000400) != 0)) {
          sqlKeywords_ = new com.google.protobuf.LazyStringArrayList(sqlKeywords_);
          bitField1_ |= 0x00000400;
         }
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @return A list containing the sqlKeywords.
       */
      public com.google.protobuf.ProtocolStringList
          getSqlKeywordsList() {
        return sqlKeywords_.getUnmodifiableView();
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @return The count of sqlKeywords.
       */
      public int getSqlKeywordsCount() {
        return sqlKeywords_.size();
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @param index The index of the element to return.
       * @return The sqlKeywords at the given index.
       */
      public java.lang.String getSqlKeywords(int index) {
        return sqlKeywords_.get(index);
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @param index The index of the value to return.
       * @return The bytes of the sqlKeywords at the given index.
       */
      public com.google.protobuf.ByteString
          getSqlKeywordsBytes(int index) {
        return sqlKeywords_.getByteString(index);
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @param index The index to set the value at.
       * @param value The sqlKeywords to set.
       * @return This builder for chaining.
       */
      public Builder setSqlKeywords(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureSqlKeywordsIsMutable();
        sqlKeywords_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @param value The sqlKeywords to add.
       * @return This builder for chaining.
       */
      public Builder addSqlKeywords(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureSqlKeywordsIsMutable();
        sqlKeywords_.add(value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @param values The sqlKeywords to add.
       * @return This builder for chaining.
       */
      public Builder addAllSqlKeywords(
          java.lang.Iterable<java.lang.String> values) {
        ensureSqlKeywordsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, sqlKeywords_);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @return This builder for chaining.
       */
      public Builder clearSqlKeywords() {
        sqlKeywords_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00000400);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * list of SQL keywords
       * </pre>
       *
       * <code>repeated string sql_keywords = 43;</code>
       * @param value The bytes of the sqlKeywords to add.
       * @return This builder for chaining.
       */
      public Builder addSqlKeywordsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureSqlKeywordsIsMutable();
        sqlKeywords_.add(value);
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList stringFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureStringFunctionsIsMutable() {
        if (!((bitField1_ & 0x00000800) != 0)) {
          stringFunctions_ = new com.google.protobuf.LazyStringArrayList(stringFunctions_);
          bitField1_ |= 0x00000800;
         }
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @return A list containing the stringFunctions.
       */
      public com.google.protobuf.ProtocolStringList
          getStringFunctionsList() {
        return stringFunctions_.getUnmodifiableView();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @return The count of stringFunctions.
       */
      public int getStringFunctionsCount() {
        return stringFunctions_.size();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @param index The index of the element to return.
       * @return The stringFunctions at the given index.
       */
      public java.lang.String getStringFunctions(int index) {
        return stringFunctions_.get(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @param index The index of the value to return.
       * @return The bytes of the stringFunctions at the given index.
       */
      public com.google.protobuf.ByteString
          getStringFunctionsBytes(int index) {
        return stringFunctions_.getByteString(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @param index The index to set the value at.
       * @param value The stringFunctions to set.
       * @return This builder for chaining.
       */
      public Builder setStringFunctions(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureStringFunctionsIsMutable();
        stringFunctions_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @param value The stringFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addStringFunctions(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureStringFunctionsIsMutable();
        stringFunctions_.add(value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @param values The stringFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addAllStringFunctions(
          java.lang.Iterable<java.lang.String> values) {
        ensureStringFunctionsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, stringFunctions_);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @return This builder for chaining.
       */
      public Builder clearStringFunctions() {
        stringFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00000800);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC string scalar functions
       * </pre>
       *
       * <code>repeated string string_functions = 44;</code>
       * @param value The bytes of the stringFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addStringFunctionsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureStringFunctionsIsMutable();
        stringFunctions_.add(value);
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> subquerySupport_ =
        java.util.Collections.emptyList();
      private void ensureSubquerySupportIsMutable() {
        if (!((bitField1_ & 0x00001000) != 0)) {
          subquerySupport_ = new java.util.ArrayList<java.lang.Integer>(subquerySupport_);
          bitField1_ |= 0x00001000;
        }
      }
      /**
       * <pre>
       * Subquery support
       * </pre>
       *
       * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
       * @return A list containing the subquerySupport.
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.SubQuerySupport> getSubquerySupportList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.exec.proto.UserProtos.SubQuerySupport>(subquerySupport_, subquerySupport_converter_);
      }
      /**
       * <pre>
       * Subquery support
       * </pre>
       *
       * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
       * @return The count of subquerySupport.
       */
      public int getSubquerySupportCount() {
        return subquerySupport_.size();
      }
      /**
       * <pre>
       * Subquery support
       * </pre>
       *
       * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
       * @param index The index of the element to return.
       * @return The subquerySupport at the given index.
       */
      public org.apache.drill.exec.proto.UserProtos.SubQuerySupport getSubquerySupport(int index) {
        return subquerySupport_converter_.convert(subquerySupport_.get(index));
      }
      /**
       * <pre>
       * Subquery support
       * </pre>
       *
       * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
       * @param index The index to set the value at.
       * @param value The subquerySupport to set.
       * @return This builder for chaining.
       */
      public Builder setSubquerySupport(
          int index, org.apache.drill.exec.proto.UserProtos.SubQuerySupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSubquerySupportIsMutable();
        subquerySupport_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Subquery support
       * </pre>
       *
       * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
       * @param value The subquerySupport to add.
       * @return This builder for chaining.
       */
      public Builder addSubquerySupport(org.apache.drill.exec.proto.UserProtos.SubQuerySupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureSubquerySupportIsMutable();
        subquerySupport_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Subquery support
       * </pre>
       *
       * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
       * @param values The subquerySupport to add.
       * @return This builder for chaining.
       */
      public Builder addAllSubquerySupport(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.SubQuerySupport> values) {
        ensureSubquerySupportIsMutable();
        for (org.apache.drill.exec.proto.UserProtos.SubQuerySupport value : values) {
          subquerySupport_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Subquery support
       * </pre>
       *
       * <code>repeated .exec.user.SubQuerySupport subquery_support = 45;</code>
       * @return This builder for chaining.
       */
      public Builder clearSubquerySupport() {
        subquerySupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00001000);
        onChanged();
        return this;
      }

      private com.google.protobuf.LazyStringList systemFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
      private void ensureSystemFunctionsIsMutable() {
        if (!((bitField1_ & 0x00002000) != 0)) {
          systemFunctions_ = new com.google.protobuf.LazyStringArrayList(systemFunctions_);
          bitField1_ |= 0x00002000;
         }
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @return A list containing the systemFunctions.
       */
      public com.google.protobuf.ProtocolStringList
          getSystemFunctionsList() {
        return systemFunctions_.getUnmodifiableView();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @return The count of systemFunctions.
       */
      public int getSystemFunctionsCount() {
        return systemFunctions_.size();
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @param index The index of the element to return.
       * @return The systemFunctions at the given index.
       */
      public java.lang.String getSystemFunctions(int index) {
        return systemFunctions_.get(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @param index The index of the value to return.
       * @return The bytes of the systemFunctions at the given index.
       */
      public com.google.protobuf.ByteString
          getSystemFunctionsBytes(int index) {
        return systemFunctions_.getByteString(index);
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @param index The index to set the value at.
       * @param value The systemFunctions to set.
       * @return This builder for chaining.
       */
      public Builder setSystemFunctions(
          int index, java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureSystemFunctionsIsMutable();
        systemFunctions_.set(index, value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @param value The systemFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addSystemFunctions(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureSystemFunctionsIsMutable();
        systemFunctions_.add(value);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @param values The systemFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addAllSystemFunctions(
          java.lang.Iterable<java.lang.String> values) {
        ensureSystemFunctionsIsMutable();
        com.google.protobuf.AbstractMessageLite.Builder.addAll(
            values, systemFunctions_);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @return This builder for chaining.
       */
      public Builder clearSystemFunctions() {
        systemFunctions_ = com.google.protobuf.LazyStringArrayList.EMPTY;
        bitField1_ = (bitField1_ & ~0x00002000);
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Supported ODBC/JDBC systen scalar functions
       * </pre>
       *
       * <code>repeated string system_functions = 46;</code>
       * @param value The bytes of the systemFunctions to add.
       * @return This builder for chaining.
       */
      public Builder addSystemFunctionsBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  ensureSystemFunctionsIsMutable();
        systemFunctions_.add(value);
        onChanged();
        return this;
      }

      private java.lang.Object tableTerm_ = "";
      /**
       * <pre>
       * The term used to designate a table
       * </pre>
       *
       * <code>optional string table_term = 47;</code>
       * @return Whether the tableTerm field is set.
       */
      public boolean hasTableTerm() {
        return ((bitField1_ & 0x00004000) != 0);
      }
      /**
       * <pre>
       * The term used to designate a table
       * </pre>
       *
       * <code>optional string table_term = 47;</code>
       * @return The tableTerm.
       */
      public java.lang.String getTableTerm() {
        java.lang.Object ref = tableTerm_;
        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()) {
            tableTerm_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * The term used to designate a table
       * </pre>
       *
       * <code>optional string table_term = 47;</code>
       * @return The bytes for tableTerm.
       */
      public com.google.protobuf.ByteString
          getTableTermBytes() {
        java.lang.Object ref = tableTerm_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          tableTerm_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * The term used to designate a table
       * </pre>
       *
       * <code>optional string table_term = 47;</code>
       * @param value The tableTerm to set.
       * @return This builder for chaining.
       */
      public Builder setTableTerm(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00004000;
        tableTerm_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The term used to designate a table
       * </pre>
       *
       * <code>optional string table_term = 47;</code>
       * @return This builder for chaining.
       */
      public Builder clearTableTerm() {
        bitField1_ = (bitField1_ & ~0x00004000);
        tableTerm_ = getDefaultInstance().getTableTerm();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * The term used to designate a table
       * </pre>
       *
       * <code>optional string table_term = 47;</code>
       * @param value The bytes for tableTerm to set.
       * @return This builder for chaining.
       */
      public Builder setTableTermBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00004000;
        tableTerm_ = value;
        onChanged();
        return this;
      }

      private boolean transactionSupported_ ;
      /**
       * <pre>
       * True if transaction is supported
       * </pre>
       *
       * <code>optional bool transaction_supported = 48;</code>
       * @return Whether the transactionSupported field is set.
       */
      @java.lang.Override
      public boolean hasTransactionSupported() {
        return ((bitField1_ & 0x00008000) != 0);
      }
      /**
       * <pre>
       * True if transaction is supported
       * </pre>
       *
       * <code>optional bool transaction_supported = 48;</code>
       * @return The transactionSupported.
       */
      @java.lang.Override
      public boolean getTransactionSupported() {
        return transactionSupported_;
      }
      /**
       * <pre>
       * True if transaction is supported
       * </pre>
       *
       * <code>optional bool transaction_supported = 48;</code>
       * @param value The transactionSupported to set.
       * @return This builder for chaining.
       */
      public Builder setTransactionSupported(boolean value) {
        bitField1_ |= 0x00008000;
        transactionSupported_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * True if transaction is supported
       * </pre>
       *
       * <code>optional bool transaction_supported = 48;</code>
       * @return This builder for chaining.
       */
      public Builder clearTransactionSupported() {
        bitField1_ = (bitField1_ & ~0x00008000);
        transactionSupported_ = false;
        onChanged();
        return this;
      }

      private java.util.List<java.lang.Integer> unionSupport_ =
        java.util.Collections.emptyList();
      private void ensureUnionSupportIsMutable() {
        if (!((bitField1_ & 0x00010000) != 0)) {
          unionSupport_ = new java.util.ArrayList<java.lang.Integer>(unionSupport_);
          bitField1_ |= 0x00010000;
        }
      }
      /**
       * <pre>
       * UNION support
       * </pre>
       *
       * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
       * @return A list containing the unionSupport.
       */
      public java.util.List<org.apache.drill.exec.proto.UserProtos.UnionSupport> getUnionSupportList() {
        return new com.google.protobuf.Internal.ListAdapter<
            java.lang.Integer, org.apache.drill.exec.proto.UserProtos.UnionSupport>(unionSupport_, unionSupport_converter_);
      }
      /**
       * <pre>
       * UNION support
       * </pre>
       *
       * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
       * @return The count of unionSupport.
       */
      public int getUnionSupportCount() {
        return unionSupport_.size();
      }
      /**
       * <pre>
       * UNION support
       * </pre>
       *
       * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
       * @param index The index of the element to return.
       * @return The unionSupport at the given index.
       */
      public org.apache.drill.exec.proto.UserProtos.UnionSupport getUnionSupport(int index) {
        return unionSupport_converter_.convert(unionSupport_.get(index));
      }
      /**
       * <pre>
       * UNION support
       * </pre>
       *
       * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
       * @param index The index to set the value at.
       * @param value The unionSupport to set.
       * @return This builder for chaining.
       */
      public Builder setUnionSupport(
          int index, org.apache.drill.exec.proto.UserProtos.UnionSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureUnionSupportIsMutable();
        unionSupport_.set(index, value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * UNION support
       * </pre>
       *
       * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
       * @param value The unionSupport to add.
       * @return This builder for chaining.
       */
      public Builder addUnionSupport(org.apache.drill.exec.proto.UserProtos.UnionSupport value) {
        if (value == null) {
          throw new NullPointerException();
        }
        ensureUnionSupportIsMutable();
        unionSupport_.add(value.getNumber());
        onChanged();
        return this;
      }
      /**
       * <pre>
       * UNION support
       * </pre>
       *
       * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
       * @param values The unionSupport to add.
       * @return This builder for chaining.
       */
      public Builder addAllUnionSupport(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.UserProtos.UnionSupport> values) {
        ensureUnionSupportIsMutable();
        for (org.apache.drill.exec.proto.UserProtos.UnionSupport value : values) {
          unionSupport_.add(value.getNumber());
        }
        onChanged();
        return this;
      }
      /**
       * <pre>
       * UNION support
       * </pre>
       *
       * <code>repeated .exec.user.UnionSupport union_support = 49;</code>
       * @return This builder for chaining.
       */
      public Builder clearUnionSupport() {
        unionSupport_ = java.util.Collections.emptyList();
        bitField1_ = (bitField1_ & ~0x00010000);
        onChanged();
        return this;
      }

      private java.lang.Object currentSchema_ = "";
      /**
       * <pre>
       * current schema
       * </pre>
       *
       * <code>optional string current_schema = 50;</code>
       * @return Whether the currentSchema field is set.
       */
      public boolean hasCurrentSchema() {
        return ((bitField1_ & 0x00020000) != 0);
      }
      /**
       * <pre>
       * current schema
       * </pre>
       *
       * <code>optional string current_schema = 50;</code>
       * @return The currentSchema.
       */
      public java.lang.String getCurrentSchema() {
        java.lang.Object ref = currentSchema_;
        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()) {
            currentSchema_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * current schema
       * </pre>
       *
       * <code>optional string current_schema = 50;</code>
       * @return The bytes for currentSchema.
       */
      public com.google.protobuf.ByteString
          getCurrentSchemaBytes() {
        java.lang.Object ref = currentSchema_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          currentSchema_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * current schema
       * </pre>
       *
       * <code>optional string current_schema = 50;</code>
       * @param value The currentSchema to set.
       * @return This builder for chaining.
       */
      public Builder setCurrentSchema(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00020000;
        currentSchema_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * current schema
       * </pre>
       *
       * <code>optional string current_schema = 50;</code>
       * @return This builder for chaining.
       */
      public Builder clearCurrentSchema() {
        bitField1_ = (bitField1_ & ~0x00020000);
        currentSchema_ = getDefaultInstance().getCurrentSchema();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * current schema
       * </pre>
       *
       * <code>optional string current_schema = 50;</code>
       * @param value The bytes for currentSchema to set.
       * @return This builder for chaining.
       */
      public Builder setCurrentSchemaBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField1_ |= 0x00020000;
        currentSchema_ = value;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.ServerMeta)
    }

    // @@protoc_insertion_point(class_scope:exec.user.ServerMeta)
    private static final org.apache.drill.exec.proto.UserProtos.ServerMeta DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.ServerMeta();
    }

    public static org.apache.drill.exec.proto.UserProtos.ServerMeta getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<ServerMeta>
        PARSER = new com.google.protobuf.AbstractParser<ServerMeta>() {
      @java.lang.Override
      public ServerMeta parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<ServerMeta> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<ServerMeta> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.ServerMeta getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  public interface RunQueryOrBuilder extends
      // @@protoc_insertion_point(interface_extends:exec.user.RunQuery)
      com.google.protobuf.MessageOrBuilder {

    /**
     * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
     * @return Whether the resultsMode field is set.
     */
    boolean hasResultsMode();
    /**
     * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
     * @return The resultsMode.
     */
    org.apache.drill.exec.proto.UserProtos.QueryResultsMode getResultsMode();

    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return Whether the type field is set.
     */
    boolean hasType();
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return The type.
     */
    org.apache.drill.exec.proto.UserBitShared.QueryType getType();

    /**
     * <pre>
     * Input for query type LOGICAL, PHYSICAL or SQL.
     * </pre>
     *
     * <code>optional string plan = 3;</code>
     * @return Whether the plan field is set.
     */
    boolean hasPlan();
    /**
     * <pre>
     * Input for query type LOGICAL, PHYSICAL or SQL.
     * </pre>
     *
     * <code>optional string plan = 3;</code>
     * @return The plan.
     */
    java.lang.String getPlan();
    /**
     * <pre>
     * Input for query type LOGICAL, PHYSICAL or SQL.
     * </pre>
     *
     * <code>optional string plan = 3;</code>
     * @return The bytes for plan.
     */
    com.google.protobuf.ByteString
        getPlanBytes();

    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> 
        getFragmentsList();
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    org.apache.drill.exec.proto.BitControl.PlanFragment getFragments(int index);
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    int getFragmentsCount();
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
        getFragmentsOrBuilderList();
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentsOrBuilder(
        int index);

    /**
     * <pre>
     * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
     * to state on server side which is returned in response to CreatePreparedStatementReq.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
     * @return Whether the preparedStatementHandle field is set.
     */
    boolean hasPreparedStatementHandle();
    /**
     * <pre>
     * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
     * to state on server side which is returned in response to CreatePreparedStatementReq.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
     * @return The preparedStatementHandle.
     */
    org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getPreparedStatementHandle();
    /**
     * <pre>
     * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
     * to state on server side which is returned in response to CreatePreparedStatementReq.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
     */
    org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder getPreparedStatementHandleOrBuilder();

    /**
     * <pre>
     * Input for indicating the limit on a query's result set.
     * </pre>
     *
     * <code>optional int32 autolimit_rowcount = 6;</code>
     * @return Whether the autolimitRowcount field is set.
     */
    boolean hasAutolimitRowcount();
    /**
     * <pre>
     * Input for indicating the limit on a query's result set.
     * </pre>
     *
     * <code>optional int32 autolimit_rowcount = 6;</code>
     * @return The autolimitRowcount.
     */
    int getAutolimitRowcount();
  }
  /**
   * <pre>
   * Request message for running a query.
   * </pre>
   *
   * Protobuf type {@code exec.user.RunQuery}
   */
  public static final class RunQuery extends
      com.google.protobuf.GeneratedMessageV3 implements
      // @@protoc_insertion_point(message_implements:exec.user.RunQuery)
      RunQueryOrBuilder {
  private static final long serialVersionUID = 0L;
    // Use RunQuery.newBuilder() to construct.
    private RunQuery(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
      super(builder);
    }
    private RunQuery() {
      resultsMode_ = 1;
      type_ = 1;
      plan_ = "";
      fragments_ = java.util.Collections.emptyList();
    }

    @java.lang.Override
    @SuppressWarnings({"unused"})
    protected java.lang.Object newInstance(
        UnusedPrivateParameter unused) {
      return new RunQuery();
    }

    @java.lang.Override
    public final com.google.protobuf.UnknownFieldSet
    getUnknownFields() {
      return this.unknownFields;
    }
    public static final com.google.protobuf.Descriptors.Descriptor
        getDescriptor() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RunQuery_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RunQuery_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              org.apache.drill.exec.proto.UserProtos.RunQuery.class, org.apache.drill.exec.proto.UserProtos.RunQuery.Builder.class);
    }

    private int bitField0_;
    public static final int RESULTS_MODE_FIELD_NUMBER = 1;
    private int resultsMode_;
    /**
     * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
     * @return Whether the resultsMode field is set.
     */
    @java.lang.Override public boolean hasResultsMode() {
      return ((bitField0_ & 0x00000001) != 0);
    }
    /**
     * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
     * @return The resultsMode.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserProtos.QueryResultsMode getResultsMode() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserProtos.QueryResultsMode result = org.apache.drill.exec.proto.UserProtos.QueryResultsMode.valueOf(resultsMode_);
      return result == null ? org.apache.drill.exec.proto.UserProtos.QueryResultsMode.STREAM_FULL : result;
    }

    public static final int TYPE_FIELD_NUMBER = 2;
    private int type_;
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return Whether the type field is set.
     */
    @java.lang.Override public boolean hasType() {
      return ((bitField0_ & 0x00000002) != 0);
    }
    /**
     * <code>optional .exec.shared.QueryType type = 2;</code>
     * @return The type.
     */
    @java.lang.Override public org.apache.drill.exec.proto.UserBitShared.QueryType getType() {
      @SuppressWarnings("deprecation")
      org.apache.drill.exec.proto.UserBitShared.QueryType result = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(type_);
      return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryType.SQL : result;
    }

    public static final int PLAN_FIELD_NUMBER = 3;
    private volatile java.lang.Object plan_;
    /**
     * <pre>
     * Input for query type LOGICAL, PHYSICAL or SQL.
     * </pre>
     *
     * <code>optional string plan = 3;</code>
     * @return Whether the plan field is set.
     */
    @java.lang.Override
    public boolean hasPlan() {
      return ((bitField0_ & 0x00000004) != 0);
    }
    /**
     * <pre>
     * Input for query type LOGICAL, PHYSICAL or SQL.
     * </pre>
     *
     * <code>optional string plan = 3;</code>
     * @return The plan.
     */
    @java.lang.Override
    public java.lang.String getPlan() {
      java.lang.Object ref = plan_;
      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()) {
          plan_ = s;
        }
        return s;
      }
    }
    /**
     * <pre>
     * Input for query type LOGICAL, PHYSICAL or SQL.
     * </pre>
     *
     * <code>optional string plan = 3;</code>
     * @return The bytes for plan.
     */
    @java.lang.Override
    public com.google.protobuf.ByteString
        getPlanBytes() {
      java.lang.Object ref = plan_;
      if (ref instanceof java.lang.String) {
        com.google.protobuf.ByteString b = 
            com.google.protobuf.ByteString.copyFromUtf8(
                (java.lang.String) ref);
        plan_ = b;
        return b;
      } else {
        return (com.google.protobuf.ByteString) ref;
      }
    }

    public static final int FRAGMENTS_FIELD_NUMBER = 4;
    private java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> fragments_;
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    @java.lang.Override
    public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> getFragmentsList() {
      return fragments_;
    }
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    @java.lang.Override
    public java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
        getFragmentsOrBuilderList() {
      return fragments_;
    }
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    @java.lang.Override
    public int getFragmentsCount() {
      return fragments_.size();
    }
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.PlanFragment getFragments(int index) {
      return fragments_.get(index);
    }
    /**
     * <pre>
     * Input for query type EXECUTION. Input is a set of executable fragments.
     * </pre>
     *
     * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentsOrBuilder(
        int index) {
      return fragments_.get(index);
    }

    public static final int PREPARED_STATEMENT_HANDLE_FIELD_NUMBER = 5;
    private org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle preparedStatementHandle_;
    /**
     * <pre>
     * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
     * to state on server side which is returned in response to CreatePreparedStatementReq.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
     * @return Whether the preparedStatementHandle field is set.
     */
    @java.lang.Override
    public boolean hasPreparedStatementHandle() {
      return ((bitField0_ & 0x00000008) != 0);
    }
    /**
     * <pre>
     * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
     * to state on server side which is returned in response to CreatePreparedStatementReq.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
     * @return The preparedStatementHandle.
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getPreparedStatementHandle() {
      return preparedStatementHandle_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : preparedStatementHandle_;
    }
    /**
     * <pre>
     * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
     * to state on server side which is returned in response to CreatePreparedStatementReq.
     * </pre>
     *
     * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
     */
    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder getPreparedStatementHandleOrBuilder() {
      return preparedStatementHandle_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : preparedStatementHandle_;
    }

    public static final int AUTOLIMIT_ROWCOUNT_FIELD_NUMBER = 6;
    private int autolimitRowcount_;
    /**
     * <pre>
     * Input for indicating the limit on a query's result set.
     * </pre>
     *
     * <code>optional int32 autolimit_rowcount = 6;</code>
     * @return Whether the autolimitRowcount field is set.
     */
    @java.lang.Override
    public boolean hasAutolimitRowcount() {
      return ((bitField0_ & 0x00000010) != 0);
    }
    /**
     * <pre>
     * Input for indicating the limit on a query's result set.
     * </pre>
     *
     * <code>optional int32 autolimit_rowcount = 6;</code>
     * @return The autolimitRowcount.
     */
    @java.lang.Override
    public int getAutolimitRowcount() {
      return autolimitRowcount_;
    }

    private byte memoizedIsInitialized = -1;
    @java.lang.Override
    public final boolean isInitialized() {
      byte isInitialized = memoizedIsInitialized;
      if (isInitialized == 1) return true;
      if (isInitialized == 0) return false;

      memoizedIsInitialized = 1;
      return true;
    }

    @java.lang.Override
    public void writeTo(com.google.protobuf.CodedOutputStream output)
                        throws java.io.IOException {
      if (((bitField0_ & 0x00000001) != 0)) {
        output.writeEnum(1, resultsMode_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        output.writeEnum(2, type_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, plan_);
      }
      for (int i = 0; i < fragments_.size(); i++) {
        output.writeMessage(4, fragments_.get(i));
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        output.writeMessage(5, getPreparedStatementHandle());
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        output.writeInt32(6, autolimitRowcount_);
      }
      getUnknownFields().writeTo(output);
    }

    @java.lang.Override
    public int getSerializedSize() {
      int size = memoizedSize;
      if (size != -1) return size;

      size = 0;
      if (((bitField0_ & 0x00000001) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(1, resultsMode_);
      }
      if (((bitField0_ & 0x00000002) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeEnumSize(2, type_);
      }
      if (((bitField0_ & 0x00000004) != 0)) {
        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, plan_);
      }
      for (int i = 0; i < fragments_.size(); i++) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(4, fragments_.get(i));
      }
      if (((bitField0_ & 0x00000008) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeMessageSize(5, getPreparedStatementHandle());
      }
      if (((bitField0_ & 0x00000010) != 0)) {
        size += com.google.protobuf.CodedOutputStream
          .computeInt32Size(6, autolimitRowcount_);
      }
      size += getUnknownFields().getSerializedSize();
      memoizedSize = size;
      return size;
    }

    @java.lang.Override
    public boolean equals(final java.lang.Object obj) {
      if (obj == this) {
       return true;
      }
      if (!(obj instanceof org.apache.drill.exec.proto.UserProtos.RunQuery)) {
        return super.equals(obj);
      }
      org.apache.drill.exec.proto.UserProtos.RunQuery other = (org.apache.drill.exec.proto.UserProtos.RunQuery) obj;

      if (hasResultsMode() != other.hasResultsMode()) return false;
      if (hasResultsMode()) {
        if (resultsMode_ != other.resultsMode_) return false;
      }
      if (hasType() != other.hasType()) return false;
      if (hasType()) {
        if (type_ != other.type_) return false;
      }
      if (hasPlan() != other.hasPlan()) return false;
      if (hasPlan()) {
        if (!getPlan()
            .equals(other.getPlan())) return false;
      }
      if (!getFragmentsList()
          .equals(other.getFragmentsList())) return false;
      if (hasPreparedStatementHandle() != other.hasPreparedStatementHandle()) return false;
      if (hasPreparedStatementHandle()) {
        if (!getPreparedStatementHandle()
            .equals(other.getPreparedStatementHandle())) return false;
      }
      if (hasAutolimitRowcount() != other.hasAutolimitRowcount()) return false;
      if (hasAutolimitRowcount()) {
        if (getAutolimitRowcount()
            != other.getAutolimitRowcount()) return false;
      }
      if (!getUnknownFields().equals(other.getUnknownFields())) return false;
      return true;
    }

    @java.lang.Override
    public int hashCode() {
      if (memoizedHashCode != 0) {
        return memoizedHashCode;
      }
      int hash = 41;
      hash = (19 * hash) + getDescriptor().hashCode();
      if (hasResultsMode()) {
        hash = (37 * hash) + RESULTS_MODE_FIELD_NUMBER;
        hash = (53 * hash) + resultsMode_;
      }
      if (hasType()) {
        hash = (37 * hash) + TYPE_FIELD_NUMBER;
        hash = (53 * hash) + type_;
      }
      if (hasPlan()) {
        hash = (37 * hash) + PLAN_FIELD_NUMBER;
        hash = (53 * hash) + getPlan().hashCode();
      }
      if (getFragmentsCount() > 0) {
        hash = (37 * hash) + FRAGMENTS_FIELD_NUMBER;
        hash = (53 * hash) + getFragmentsList().hashCode();
      }
      if (hasPreparedStatementHandle()) {
        hash = (37 * hash) + PREPARED_STATEMENT_HANDLE_FIELD_NUMBER;
        hash = (53 * hash) + getPreparedStatementHandle().hashCode();
      }
      if (hasAutolimitRowcount()) {
        hash = (37 * hash) + AUTOLIMIT_ROWCOUNT_FIELD_NUMBER;
        hash = (53 * hash) + getAutolimitRowcount();
      }
      hash = (29 * hash) + getUnknownFields().hashCode();
      memoizedHashCode = hash;
      return hash;
    }

    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(
        java.nio.ByteBuffer data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(
        java.nio.ByteBuffer data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(
        com.google.protobuf.ByteString data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery 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.drill.exec.proto.UserProtos.RunQuery parseFrom(byte[] data)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(
        byte[] data,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws com.google.protobuf.InvalidProtocolBufferException {
      return PARSER.parseFrom(data, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseDelimitedFrom(java.io.InputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseDelimitedFrom(
        java.io.InputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(
        com.google.protobuf.CodedInputStream input)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input);
    }
    public static org.apache.drill.exec.proto.UserProtos.RunQuery parseFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      return com.google.protobuf.GeneratedMessageV3
          .parseWithIOException(PARSER, input, extensionRegistry);
    }

    @java.lang.Override
    public Builder newBuilderForType() { return newBuilder(); }
    public static Builder newBuilder() {
      return DEFAULT_INSTANCE.toBuilder();
    }
    public static Builder newBuilder(org.apache.drill.exec.proto.UserProtos.RunQuery prototype) {
      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
    }
    @java.lang.Override
    public Builder toBuilder() {
      return this == DEFAULT_INSTANCE
          ? new Builder() : new Builder().mergeFrom(this);
    }

    @java.lang.Override
    protected Builder newBuilderForType(
        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      Builder builder = new Builder(parent);
      return builder;
    }
    /**
     * <pre>
     * Request message for running a query.
     * </pre>
     *
     * Protobuf type {@code exec.user.RunQuery}
     */
    public static final class Builder extends
        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
        // @@protoc_insertion_point(builder_implements:exec.user.RunQuery)
        org.apache.drill.exec.proto.UserProtos.RunQueryOrBuilder {
      public static final com.google.protobuf.Descriptors.Descriptor
          getDescriptor() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RunQuery_descriptor;
      }

      @java.lang.Override
      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
          internalGetFieldAccessorTable() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RunQuery_fieldAccessorTable
            .ensureFieldAccessorsInitialized(
                org.apache.drill.exec.proto.UserProtos.RunQuery.class, org.apache.drill.exec.proto.UserProtos.RunQuery.Builder.class);
      }

      // Construct using org.apache.drill.exec.proto.UserProtos.RunQuery.newBuilder()
      private Builder() {
        maybeForceBuilderInitialization();
      }

      private Builder(
          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
        super(parent);
        maybeForceBuilderInitialization();
      }
      private void maybeForceBuilderInitialization() {
        if (com.google.protobuf.GeneratedMessageV3
                .alwaysUseFieldBuilders) {
          getFragmentsFieldBuilder();
          getPreparedStatementHandleFieldBuilder();
        }
      }
      @java.lang.Override
      public Builder clear() {
        super.clear();
        resultsMode_ = 1;
        bitField0_ = (bitField0_ & ~0x00000001);
        type_ = 1;
        bitField0_ = (bitField0_ & ~0x00000002);
        plan_ = "";
        bitField0_ = (bitField0_ & ~0x00000004);
        if (fragmentsBuilder_ == null) {
          fragments_ = java.util.Collections.emptyList();
        } else {
          fragments_ = null;
          fragmentsBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000008);
        if (preparedStatementHandleBuilder_ == null) {
          preparedStatementHandle_ = null;
        } else {
          preparedStatementHandleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        autolimitRowcount_ = 0;
        bitField0_ = (bitField0_ & ~0x00000020);
        return this;
      }

      @java.lang.Override
      public com.google.protobuf.Descriptors.Descriptor
          getDescriptorForType() {
        return org.apache.drill.exec.proto.UserProtos.internal_static_exec_user_RunQuery_descriptor;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RunQuery getDefaultInstanceForType() {
        return org.apache.drill.exec.proto.UserProtos.RunQuery.getDefaultInstance();
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RunQuery build() {
        org.apache.drill.exec.proto.UserProtos.RunQuery result = buildPartial();
        if (!result.isInitialized()) {
          throw newUninitializedMessageException(result);
        }
        return result;
      }

      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.RunQuery buildPartial() {
        org.apache.drill.exec.proto.UserProtos.RunQuery result = new org.apache.drill.exec.proto.UserProtos.RunQuery(this);
        int from_bitField0_ = bitField0_;
        int to_bitField0_ = 0;
        if (((from_bitField0_ & 0x00000001) != 0)) {
          to_bitField0_ |= 0x00000001;
        }
        result.resultsMode_ = resultsMode_;
        if (((from_bitField0_ & 0x00000002) != 0)) {
          to_bitField0_ |= 0x00000002;
        }
        result.type_ = type_;
        if (((from_bitField0_ & 0x00000004) != 0)) {
          to_bitField0_ |= 0x00000004;
        }
        result.plan_ = plan_;
        if (fragmentsBuilder_ == null) {
          if (((bitField0_ & 0x00000008) != 0)) {
            fragments_ = java.util.Collections.unmodifiableList(fragments_);
            bitField0_ = (bitField0_ & ~0x00000008);
          }
          result.fragments_ = fragments_;
        } else {
          result.fragments_ = fragmentsBuilder_.build();
        }
        if (((from_bitField0_ & 0x00000010) != 0)) {
          if (preparedStatementHandleBuilder_ == null) {
            result.preparedStatementHandle_ = preparedStatementHandle_;
          } else {
            result.preparedStatementHandle_ = preparedStatementHandleBuilder_.build();
          }
          to_bitField0_ |= 0x00000008;
        }
        if (((from_bitField0_ & 0x00000020) != 0)) {
          result.autolimitRowcount_ = autolimitRowcount_;
          to_bitField0_ |= 0x00000010;
        }
        result.bitField0_ = to_bitField0_;
        onBuilt();
        return result;
      }

      @java.lang.Override
      public Builder clone() {
        return super.clone();
      }
      @java.lang.Override
      public Builder setField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.setField(field, value);
      }
      @java.lang.Override
      public Builder clearField(
          com.google.protobuf.Descriptors.FieldDescriptor field) {
        return super.clearField(field);
      }
      @java.lang.Override
      public Builder clearOneof(
          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
        return super.clearOneof(oneof);
      }
      @java.lang.Override
      public Builder setRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          int index, java.lang.Object value) {
        return super.setRepeatedField(field, index, value);
      }
      @java.lang.Override
      public Builder addRepeatedField(
          com.google.protobuf.Descriptors.FieldDescriptor field,
          java.lang.Object value) {
        return super.addRepeatedField(field, value);
      }
      @java.lang.Override
      public Builder mergeFrom(com.google.protobuf.Message other) {
        if (other instanceof org.apache.drill.exec.proto.UserProtos.RunQuery) {
          return mergeFrom((org.apache.drill.exec.proto.UserProtos.RunQuery)other);
        } else {
          super.mergeFrom(other);
          return this;
        }
      }

      public Builder mergeFrom(org.apache.drill.exec.proto.UserProtos.RunQuery other) {
        if (other == org.apache.drill.exec.proto.UserProtos.RunQuery.getDefaultInstance()) return this;
        if (other.hasResultsMode()) {
          setResultsMode(other.getResultsMode());
        }
        if (other.hasType()) {
          setType(other.getType());
        }
        if (other.hasPlan()) {
          bitField0_ |= 0x00000004;
          plan_ = other.plan_;
          onChanged();
        }
        if (fragmentsBuilder_ == null) {
          if (!other.fragments_.isEmpty()) {
            if (fragments_.isEmpty()) {
              fragments_ = other.fragments_;
              bitField0_ = (bitField0_ & ~0x00000008);
            } else {
              ensureFragmentsIsMutable();
              fragments_.addAll(other.fragments_);
            }
            onChanged();
          }
        } else {
          if (!other.fragments_.isEmpty()) {
            if (fragmentsBuilder_.isEmpty()) {
              fragmentsBuilder_.dispose();
              fragmentsBuilder_ = null;
              fragments_ = other.fragments_;
              bitField0_ = (bitField0_ & ~0x00000008);
              fragmentsBuilder_ = 
                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                   getFragmentsFieldBuilder() : null;
            } else {
              fragmentsBuilder_.addAllMessages(other.fragments_);
            }
          }
        }
        if (other.hasPreparedStatementHandle()) {
          mergePreparedStatementHandle(other.getPreparedStatementHandle());
        }
        if (other.hasAutolimitRowcount()) {
          setAutolimitRowcount(other.getAutolimitRowcount());
        }
        this.mergeUnknownFields(other.getUnknownFields());
        onChanged();
        return this;
      }

      @java.lang.Override
      public final boolean isInitialized() {
        return true;
      }

      @java.lang.Override
      public Builder mergeFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws java.io.IOException {
        if (extensionRegistry == null) {
          throw new java.lang.NullPointerException();
        }
        try {
          boolean done = false;
          while (!done) {
            int tag = input.readTag();
            switch (tag) {
              case 0:
                done = true;
                break;
              case 8: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserProtos.QueryResultsMode tmpValue =
                    org.apache.drill.exec.proto.UserProtos.QueryResultsMode.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(1, tmpRaw);
                } else {
                  resultsMode_ = tmpRaw;
                  bitField0_ |= 0x00000001;
                }
                break;
              } // case 8
              case 16: {
                int tmpRaw = input.readEnum();
                org.apache.drill.exec.proto.UserBitShared.QueryType tmpValue =
                    org.apache.drill.exec.proto.UserBitShared.QueryType.forNumber(tmpRaw);
                if (tmpValue == null) {
                  mergeUnknownVarintField(2, tmpRaw);
                } else {
                  type_ = tmpRaw;
                  bitField0_ |= 0x00000002;
                }
                break;
              } // case 16
              case 26: {
                plan_ = input.readBytes();
                bitField0_ |= 0x00000004;
                break;
              } // case 26
              case 34: {
                org.apache.drill.exec.proto.BitControl.PlanFragment m =
                    input.readMessage(
                        org.apache.drill.exec.proto.BitControl.PlanFragment.PARSER,
                        extensionRegistry);
                if (fragmentsBuilder_ == null) {
                  ensureFragmentsIsMutable();
                  fragments_.add(m);
                } else {
                  fragmentsBuilder_.addMessage(m);
                }
                break;
              } // case 34
              case 42: {
                input.readMessage(
                    getPreparedStatementHandleFieldBuilder().getBuilder(),
                    extensionRegistry);
                bitField0_ |= 0x00000010;
                break;
              } // case 42
              case 48: {
                autolimitRowcount_ = input.readInt32();
                bitField0_ |= 0x00000020;
                break;
              } // case 48
              default: {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
            } // switch (tag)
          } // while (!done)
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.unwrapIOException();
        } finally {
          onChanged();
        } // finally
        return this;
      }
      private int bitField0_;

      private int resultsMode_ = 1;
      /**
       * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
       * @return Whether the resultsMode field is set.
       */
      @java.lang.Override public boolean hasResultsMode() {
        return ((bitField0_ & 0x00000001) != 0);
      }
      /**
       * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
       * @return The resultsMode.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserProtos.QueryResultsMode getResultsMode() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserProtos.QueryResultsMode result = org.apache.drill.exec.proto.UserProtos.QueryResultsMode.valueOf(resultsMode_);
        return result == null ? org.apache.drill.exec.proto.UserProtos.QueryResultsMode.STREAM_FULL : result;
      }
      /**
       * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
       * @param value The resultsMode to set.
       * @return This builder for chaining.
       */
      public Builder setResultsMode(org.apache.drill.exec.proto.UserProtos.QueryResultsMode value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000001;
        resultsMode_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.user.QueryResultsMode results_mode = 1;</code>
       * @return This builder for chaining.
       */
      public Builder clearResultsMode() {
        bitField0_ = (bitField0_ & ~0x00000001);
        resultsMode_ = 1;
        onChanged();
        return this;
      }

      private int type_ = 1;
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return Whether the type field is set.
       */
      @java.lang.Override public boolean hasType() {
        return ((bitField0_ & 0x00000002) != 0);
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return The type.
       */
      @java.lang.Override
      public org.apache.drill.exec.proto.UserBitShared.QueryType getType() {
        @SuppressWarnings("deprecation")
        org.apache.drill.exec.proto.UserBitShared.QueryType result = org.apache.drill.exec.proto.UserBitShared.QueryType.valueOf(type_);
        return result == null ? org.apache.drill.exec.proto.UserBitShared.QueryType.SQL : result;
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @param value The type to set.
       * @return This builder for chaining.
       */
      public Builder setType(org.apache.drill.exec.proto.UserBitShared.QueryType value) {
        if (value == null) {
          throw new NullPointerException();
        }
        bitField0_ |= 0x00000002;
        type_ = value.getNumber();
        onChanged();
        return this;
      }
      /**
       * <code>optional .exec.shared.QueryType type = 2;</code>
       * @return This builder for chaining.
       */
      public Builder clearType() {
        bitField0_ = (bitField0_ & ~0x00000002);
        type_ = 1;
        onChanged();
        return this;
      }

      private java.lang.Object plan_ = "";
      /**
       * <pre>
       * Input for query type LOGICAL, PHYSICAL or SQL.
       * </pre>
       *
       * <code>optional string plan = 3;</code>
       * @return Whether the plan field is set.
       */
      public boolean hasPlan() {
        return ((bitField0_ & 0x00000004) != 0);
      }
      /**
       * <pre>
       * Input for query type LOGICAL, PHYSICAL or SQL.
       * </pre>
       *
       * <code>optional string plan = 3;</code>
       * @return The plan.
       */
      public java.lang.String getPlan() {
        java.lang.Object ref = plan_;
        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()) {
            plan_ = s;
          }
          return s;
        } else {
          return (java.lang.String) ref;
        }
      }
      /**
       * <pre>
       * Input for query type LOGICAL, PHYSICAL or SQL.
       * </pre>
       *
       * <code>optional string plan = 3;</code>
       * @return The bytes for plan.
       */
      public com.google.protobuf.ByteString
          getPlanBytes() {
        java.lang.Object ref = plan_;
        if (ref instanceof String) {
          com.google.protobuf.ByteString b = 
              com.google.protobuf.ByteString.copyFromUtf8(
                  (java.lang.String) ref);
          plan_ = b;
          return b;
        } else {
          return (com.google.protobuf.ByteString) ref;
        }
      }
      /**
       * <pre>
       * Input for query type LOGICAL, PHYSICAL or SQL.
       * </pre>
       *
       * <code>optional string plan = 3;</code>
       * @param value The plan to set.
       * @return This builder for chaining.
       */
      public Builder setPlan(
          java.lang.String value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        plan_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Input for query type LOGICAL, PHYSICAL or SQL.
       * </pre>
       *
       * <code>optional string plan = 3;</code>
       * @return This builder for chaining.
       */
      public Builder clearPlan() {
        bitField0_ = (bitField0_ & ~0x00000004);
        plan_ = getDefaultInstance().getPlan();
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Input for query type LOGICAL, PHYSICAL or SQL.
       * </pre>
       *
       * <code>optional string plan = 3;</code>
       * @param value The bytes for plan to set.
       * @return This builder for chaining.
       */
      public Builder setPlanBytes(
          com.google.protobuf.ByteString value) {
        if (value == null) {
    throw new NullPointerException();
  }
  bitField0_ |= 0x00000004;
        plan_ = value;
        onChanged();
        return this;
      }

      private java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> fragments_ =
        java.util.Collections.emptyList();
      private void ensureFragmentsIsMutable() {
        if (!((bitField0_ & 0x00000008) != 0)) {
          fragments_ = new java.util.ArrayList<org.apache.drill.exec.proto.BitControl.PlanFragment>(fragments_);
          bitField0_ |= 0x00000008;
         }
      }

      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> fragmentsBuilder_;

      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment> getFragmentsList() {
        if (fragmentsBuilder_ == null) {
          return java.util.Collections.unmodifiableList(fragments_);
        } else {
          return fragmentsBuilder_.getMessageList();
        }
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public int getFragmentsCount() {
        if (fragmentsBuilder_ == null) {
          return fragments_.size();
        } else {
          return fragmentsBuilder_.getCount();
        }
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment getFragments(int index) {
        if (fragmentsBuilder_ == null) {
          return fragments_.get(index);
        } else {
          return fragmentsBuilder_.getMessage(index);
        }
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder setFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentsIsMutable();
          fragments_.set(index, value);
          onChanged();
        } else {
          fragmentsBuilder_.setMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder setFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.set(index, builderForValue.build());
          onChanged();
        } else {
          fragmentsBuilder_.setMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder addFragments(org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentsIsMutable();
          fragments_.add(value);
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(value);
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder addFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment value) {
        if (fragmentsBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          ensureFragmentsIsMutable();
          fragments_.add(index, value);
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(index, value);
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder addFragments(
          org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.add(builderForValue.build());
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder addFragments(
          int index, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder builderForValue) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.add(index, builderForValue.build());
          onChanged();
        } else {
          fragmentsBuilder_.addMessage(index, builderForValue.build());
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder addAllFragments(
          java.lang.Iterable<? extends org.apache.drill.exec.proto.BitControl.PlanFragment> values) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          com.google.protobuf.AbstractMessageLite.Builder.addAll(
              values, fragments_);
          onChanged();
        } else {
          fragmentsBuilder_.addAllMessages(values);
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder clearFragments() {
        if (fragmentsBuilder_ == null) {
          fragments_ = java.util.Collections.emptyList();
          bitField0_ = (bitField0_ & ~0x00000008);
          onChanged();
        } else {
          fragmentsBuilder_.clear();
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public Builder removeFragments(int index) {
        if (fragmentsBuilder_ == null) {
          ensureFragmentsIsMutable();
          fragments_.remove(index);
          onChanged();
        } else {
          fragmentsBuilder_.remove(index);
        }
        return this;
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder getFragmentsBuilder(
          int index) {
        return getFragmentsFieldBuilder().getBuilder(index);
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder getFragmentsOrBuilder(
          int index) {
        if (fragmentsBuilder_ == null) {
          return fragments_.get(index);  } else {
          return fragmentsBuilder_.getMessageOrBuilder(index);
        }
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public java.util.List<? extends org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
           getFragmentsOrBuilderList() {
        if (fragmentsBuilder_ != null) {
          return fragmentsBuilder_.getMessageOrBuilderList();
        } else {
          return java.util.Collections.unmodifiableList(fragments_);
        }
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder addFragmentsBuilder() {
        return getFragmentsFieldBuilder().addBuilder(
            org.apache.drill.exec.proto.BitControl.PlanFragment.getDefaultInstance());
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public org.apache.drill.exec.proto.BitControl.PlanFragment.Builder addFragmentsBuilder(
          int index) {
        return getFragmentsFieldBuilder().addBuilder(
            index, org.apache.drill.exec.proto.BitControl.PlanFragment.getDefaultInstance());
      }
      /**
       * <pre>
       * Input for query type EXECUTION. Input is a set of executable fragments.
       * </pre>
       *
       * <code>repeated .exec.bit.control.PlanFragment fragments = 4;</code>
       */
      public java.util.List<org.apache.drill.exec.proto.BitControl.PlanFragment.Builder> 
           getFragmentsBuilderList() {
        return getFragmentsFieldBuilder().getBuilderList();
      }
      private com.google.protobuf.RepeatedFieldBuilderV3<
          org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder> 
          getFragmentsFieldBuilder() {
        if (fragmentsBuilder_ == null) {
          fragmentsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
              org.apache.drill.exec.proto.BitControl.PlanFragment, org.apache.drill.exec.proto.BitControl.PlanFragment.Builder, org.apache.drill.exec.proto.BitControl.PlanFragmentOrBuilder>(
                  fragments_,
                  ((bitField0_ & 0x00000008) != 0),
                  getParentForChildren(),
                  isClean());
          fragments_ = null;
        }
        return fragmentsBuilder_;
      }

      private org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle preparedStatementHandle_;
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder> preparedStatementHandleBuilder_;
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       * @return Whether the preparedStatementHandle field is set.
       */
      public boolean hasPreparedStatementHandle() {
        return ((bitField0_ & 0x00000010) != 0);
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       * @return The preparedStatementHandle.
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle getPreparedStatementHandle() {
        if (preparedStatementHandleBuilder_ == null) {
          return preparedStatementHandle_ == null ? org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : preparedStatementHandle_;
        } else {
          return preparedStatementHandleBuilder_.getMessage();
        }
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       */
      public Builder setPreparedStatementHandle(org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle value) {
        if (preparedStatementHandleBuilder_ == null) {
          if (value == null) {
            throw new NullPointerException();
          }
          preparedStatementHandle_ = value;
          onChanged();
        } else {
          preparedStatementHandleBuilder_.setMessage(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       */
      public Builder setPreparedStatementHandle(
          org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder builderForValue) {
        if (preparedStatementHandleBuilder_ == null) {
          preparedStatementHandle_ = builderForValue.build();
          onChanged();
        } else {
          preparedStatementHandleBuilder_.setMessage(builderForValue.build());
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       */
      public Builder mergePreparedStatementHandle(org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle value) {
        if (preparedStatementHandleBuilder_ == null) {
          if (((bitField0_ & 0x00000010) != 0) &&
              preparedStatementHandle_ != null &&
              preparedStatementHandle_ != org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance()) {
            preparedStatementHandle_ =
              org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.newBuilder(preparedStatementHandle_).mergeFrom(value).buildPartial();
          } else {
            preparedStatementHandle_ = value;
          }
          onChanged();
        } else {
          preparedStatementHandleBuilder_.mergeFrom(value);
        }
        bitField0_ |= 0x00000010;
        return this;
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       */
      public Builder clearPreparedStatementHandle() {
        if (preparedStatementHandleBuilder_ == null) {
          preparedStatementHandle_ = null;
          onChanged();
        } else {
          preparedStatementHandleBuilder_.clear();
        }
        bitField0_ = (bitField0_ & ~0x00000010);
        return this;
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder getPreparedStatementHandleBuilder() {
        bitField0_ |= 0x00000010;
        onChanged();
        return getPreparedStatementHandleFieldBuilder().getBuilder();
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       */
      public org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder getPreparedStatementHandleOrBuilder() {
        if (preparedStatementHandleBuilder_ != null) {
          return preparedStatementHandleBuilder_.getMessageOrBuilder();
        } else {
          return preparedStatementHandle_ == null ?
              org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.getDefaultInstance() : preparedStatementHandle_;
        }
      }
      /**
       * <pre>
       * Input for query type PREPARED_STATEMENT. Input is a prepared statement handle
       * to state on server side which is returned in response to CreatePreparedStatementReq.
       * </pre>
       *
       * <code>optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;</code>
       */
      private com.google.protobuf.SingleFieldBuilderV3<
          org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder> 
          getPreparedStatementHandleFieldBuilder() {
        if (preparedStatementHandleBuilder_ == null) {
          preparedStatementHandleBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
              org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandle.Builder, org.apache.drill.exec.proto.UserProtos.PreparedStatementHandleOrBuilder>(
                  getPreparedStatementHandle(),
                  getParentForChildren(),
                  isClean());
          preparedStatementHandle_ = null;
        }
        return preparedStatementHandleBuilder_;
      }

      private int autolimitRowcount_ ;
      /**
       * <pre>
       * Input for indicating the limit on a query's result set.
       * </pre>
       *
       * <code>optional int32 autolimit_rowcount = 6;</code>
       * @return Whether the autolimitRowcount field is set.
       */
      @java.lang.Override
      public boolean hasAutolimitRowcount() {
        return ((bitField0_ & 0x00000020) != 0);
      }
      /**
       * <pre>
       * Input for indicating the limit on a query's result set.
       * </pre>
       *
       * <code>optional int32 autolimit_rowcount = 6;</code>
       * @return The autolimitRowcount.
       */
      @java.lang.Override
      public int getAutolimitRowcount() {
        return autolimitRowcount_;
      }
      /**
       * <pre>
       * Input for indicating the limit on a query's result set.
       * </pre>
       *
       * <code>optional int32 autolimit_rowcount = 6;</code>
       * @param value The autolimitRowcount to set.
       * @return This builder for chaining.
       */
      public Builder setAutolimitRowcount(int value) {
        bitField0_ |= 0x00000020;
        autolimitRowcount_ = value;
        onChanged();
        return this;
      }
      /**
       * <pre>
       * Input for indicating the limit on a query's result set.
       * </pre>
       *
       * <code>optional int32 autolimit_rowcount = 6;</code>
       * @return This builder for chaining.
       */
      public Builder clearAutolimitRowcount() {
        bitField0_ = (bitField0_ & ~0x00000020);
        autolimitRowcount_ = 0;
        onChanged();
        return this;
      }
      @java.lang.Override
      public final Builder setUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.setUnknownFields(unknownFields);
      }

      @java.lang.Override
      public final Builder mergeUnknownFields(
          final com.google.protobuf.UnknownFieldSet unknownFields) {
        return super.mergeUnknownFields(unknownFields);
      }


      // @@protoc_insertion_point(builder_scope:exec.user.RunQuery)
    }

    // @@protoc_insertion_point(class_scope:exec.user.RunQuery)
    private static final org.apache.drill.exec.proto.UserProtos.RunQuery DEFAULT_INSTANCE;
    static {
      DEFAULT_INSTANCE = new org.apache.drill.exec.proto.UserProtos.RunQuery();
    }

    public static org.apache.drill.exec.proto.UserProtos.RunQuery getDefaultInstance() {
      return DEFAULT_INSTANCE;
    }

    @java.lang.Deprecated public static final com.google.protobuf.Parser<RunQuery>
        PARSER = new com.google.protobuf.AbstractParser<RunQuery>() {
      @java.lang.Override
      public RunQuery parsePartialFrom(
          com.google.protobuf.CodedInputStream input,
          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
          throws com.google.protobuf.InvalidProtocolBufferException {
        Builder builder = newBuilder();
        try {
          builder.mergeFrom(input, extensionRegistry);
        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
          throw e.setUnfinishedMessage(builder.buildPartial());
        } catch (com.google.protobuf.UninitializedMessageException e) {
          throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
        } catch (java.io.IOException e) {
          throw new com.google.protobuf.InvalidProtocolBufferException(e)
              .setUnfinishedMessage(builder.buildPartial());
        }
        return builder.buildPartial();
      }
    };

    public static com.google.protobuf.Parser<RunQuery> parser() {
      return PARSER;
    }

    @java.lang.Override
    public com.google.protobuf.Parser<RunQuery> getParserForType() {
      return PARSER;
    }

    @java.lang.Override
    public org.apache.drill.exec.proto.UserProtos.RunQuery getDefaultInstanceForType() {
      return DEFAULT_INSTANCE;
    }

  }

  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_Property_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_Property_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_UserProperties_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_UserProperties_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_RpcEndpointInfos_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_RpcEndpointInfos_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_UserToBitHandshake_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_UserToBitHandshake_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_RequestResults_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_RequestResults_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetQueryPlanFragments_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetQueryPlanFragments_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_QueryPlanFragments_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_QueryPlanFragments_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_BitToUserHandshake_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_BitToUserHandshake_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_LikeFilter_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_LikeFilter_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetCatalogsReq_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetCatalogsReq_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_CatalogMetadata_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_CatalogMetadata_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetCatalogsResp_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetCatalogsResp_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetSchemasReq_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetSchemasReq_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_SchemaMetadata_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_SchemaMetadata_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetSchemasResp_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetSchemasResp_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetTablesReq_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetTablesReq_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_TableMetadata_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_TableMetadata_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetTablesResp_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetTablesResp_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetColumnsReq_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetColumnsReq_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_ColumnMetadata_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_ColumnMetadata_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetColumnsResp_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetColumnsResp_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_CreatePreparedStatementReq_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_CreatePreparedStatementReq_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_ResultColumnMetadata_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_ResultColumnMetadata_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_PreparedStatementHandle_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_PreparedStatementHandle_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_PreparedStatement_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_PreparedStatement_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_CreatePreparedStatementResp_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_CreatePreparedStatementResp_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetServerMetaReq_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetServerMetaReq_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_ConvertSupport_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_ConvertSupport_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_GetServerMetaResp_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_GetServerMetaResp_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_ServerMeta_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_ServerMeta_fieldAccessorTable;
  private static final com.google.protobuf.Descriptors.Descriptor
    internal_static_exec_user_RunQuery_descriptor;
  private static final 
    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internal_static_exec_user_RunQuery_fieldAccessorTable;

  public static com.google.protobuf.Descriptors.FileDescriptor
      getDescriptor() {
    return descriptor;
  }
  private static  com.google.protobuf.Descriptors.FileDescriptor
      descriptor;
  static {
    java.lang.String[] descriptorData = {
      "\n\nUser.proto\022\texec.user\032\017SchemaDef.proto" +
      "\032\013Types.proto\032\023UserBitShared.proto\032\rBitD" +
      "ata.proto\032\020BitControl.proto\032\025ExecutionPr" +
      "otos.proto\"&\n\010Property\022\013\n\003key\030\001 \002(\t\022\r\n\005v" +
      "alue\030\002 \002(\t\"9\n\016UserProperties\022\'\n\nproperti" +
      "es\030\001 \003(\0132\023.exec.user.Property\"\267\001\n\020RpcEnd" +
      "pointInfos\022\014\n\004name\030\001 \001(\t\022\017\n\007version\030\002 \001(" +
      "\t\022\024\n\014majorVersion\030\003 \001(\r\022\024\n\014minorVersion\030" +
      "\004 \001(\r\022\024\n\014patchVersion\030\005 \001(\r\022\023\n\013applicati" +
      "on\030\006 \001(\t\022\023\n\013buildNumber\030\007 \001(\r\022\030\n\020version" +
      "Qualifier\030\010 \001(\t\"\375\002\n\022UserToBitHandshake\022." +
      "\n\007channel\030\001 \001(\0162\027.exec.shared.RpcChannel" +
      ":\004USER\022\031\n\021support_listening\030\002 \001(\010\022\023\n\013rpc" +
      "_version\030\003 \001(\005\0221\n\013credentials\030\004 \001(\0132\034.ex" +
      "ec.shared.UserCredentials\022-\n\nproperties\030" +
      "\005 \001(\0132\031.exec.user.UserProperties\022$\n\025supp" +
      "ort_complex_types\030\006 \001(\010:\005false\022\036\n\017suppor" +
      "t_timeout\030\007 \001(\010:\005false\0221\n\014client_infos\030\010" +
      " \001(\0132\033.exec.user.RpcEndpointInfos\022,\n\014sas" +
      "l_support\030\t \001(\0162\026.exec.user.SaslSupport\"" +
      "S\n\016RequestResults\022&\n\010query_id\030\001 \001(\0132\024.ex" +
      "ec.shared.QueryId\022\031\n\021maximum_responses\030\002" +
      " \001(\005\"g\n\025GetQueryPlanFragments\022\r\n\005query\030\001" +
      " \002(\t\022$\n\004type\030\002 \001(\0162\026.exec.shared.QueryTy" +
      "pe\022\031\n\nsplit_plan\030\003 \001(\010:\005false\"\316\001\n\022QueryP" +
      "lanFragments\0223\n\006status\030\001 \002(\0162#.exec.shar" +
      "ed.QueryResult.QueryState\022&\n\010query_id\030\002 " +
      "\001(\0132\024.exec.shared.QueryId\0221\n\tfragments\030\003" +
      " \003(\0132\036.exec.bit.control.PlanFragment\022(\n\005" +
      "error\030\004 \001(\0132\031.exec.shared.DrillPBError\"\253" +
      "\002\n\022BitToUserHandshake\022\023\n\013rpc_version\030\002 \001" +
      "(\005\022*\n\006status\030\003 \001(\0162\032.exec.user.Handshake" +
      "Status\022\017\n\007errorId\030\004 \001(\t\022\024\n\014errorMessage\030" +
      "\005 \001(\t\0221\n\014server_infos\030\006 \001(\0132\033.exec.user." +
      "RpcEndpointInfos\022 \n\030authenticationMechan" +
      "isms\030\007 \003(\t\022-\n\021supported_methods\030\010 \003(\0162\022." +
      "exec.user.RpcType\022\021\n\tencrypted\030\t \001(\010\022\026\n\016" +
      "maxWrappedSize\030\n \001(\005\"-\n\nLikeFilter\022\017\n\007pa" +
      "ttern\030\001 \001(\t\022\016\n\006escape\030\002 \001(\t\"D\n\016GetCatalo" +
      "gsReq\0222\n\023catalog_name_filter\030\001 \001(\0132\025.exe" +
      "c.user.LikeFilter\"M\n\017CatalogMetadata\022\024\n\014" +
      "catalog_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\006" +
      "status\030\001 \001(\0162\030.exec.user.RequestStatus\022," +
      "\n\010catalogs\030\002 \003(\0132\032.exec.user.CatalogMeta" +
      "data\022(\n\005error\030\003 \001(\0132\031.exec.shared.DrillP" +
      "BError\"v\n\rGetSchemasReq\0222\n\023catalog_name_" +
      "filter\030\001 \001(\0132\025.exec.user.LikeFilter\0221\n\022s" +
      "chema_name_filter\030\002 \001(\0132\025.exec.user.Like" +
      "Filter\"i\n\016SchemaMetadata\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\016Ge" +
      "tSchemasResp\022(\n\006status\030\001 \001(\0162\030.exec.user" +
      ".RequestStatus\022*\n\007schemas\030\002 \003(\0132\031.exec.u" +
      "ser.SchemaMetadata\022(\n\005error\030\003 \001(\0132\031.exec" +
      ".shared.DrillPBError\"\302\001\n\014GetTablesReq\0222\n" +
      "\023catalog_name_filter\030\001 \001(\0132\025.exec.user.L" +
      "ikeFilter\0221\n\022schema_name_filter\030\002 \001(\0132\025." +
      "exec.user.LikeFilter\0220\n\021table_name_filte" +
      "r\030\003 \001(\0132\025.exec.user.LikeFilter\022\031\n\021table_" +
      "type_filter\030\004 \003(\t\"\\\n\rTableMetadata\022\024\n\014ca" +
      "talog_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\rGetT" +
      "ablesResp\022(\n\006status\030\001 \001(\0162\030.exec.user.Re" +
      "questStatus\022(\n\006tables\030\002 \003(\0132\030.exec.user." +
      "TableMetadata\022(\n\005error\030\003 \001(\0132\031.exec.shar" +
      "ed.DrillPBError\"\333\001\n\rGetColumnsReq\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\0220\n\021table_name_filter\030\003 " +
      "\001(\0132\025.exec.user.LikeFilter\0221\n\022column_nam" +
      "e_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\rdefault_value\030\006 \001(\t\022\023\n\013is_null" +
      "able\030\007 \001(\010\022\021\n\tdata_type\030\010 \001(\t\022\027\n\017char_ma" +
      "x_length\030\t \001(\005\022\031\n\021char_octet_length\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\rnumeric_scale\030\r" +
      " \001(\005\022\033\n\023date_time_precision\030\016 \001(\005\022\025\n\rint" +
      "erval_type\030\017 \001(\t\022\032\n\022interval_precision\030\020" +
      " \001(\005\022\023\n\013column_size\030\021 \001(\005\"\220\001\n\016GetColumns" +
      "Resp\022(\n\006status\030\001 \001(\0162\030.exec.user.Request" +
      "Status\022*\n\007columns\030\002 \003(\0132\031.exec.user.Colu" +
      "mnMetadata\022(\n\005error\030\003 \001(\0132\031.exec.shared." +
      "DrillPBError\"/\n\032CreatePreparedStatementR" +
      "eq\022\021\n\tsql_query\030\001 \001(\t\"\326\003\n\024ResultColumnMe" +
      "tadata\022\024\n\014catalog_name\030\001 \001(\t\022\023\n\013schema_n" +
      "ame\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\tdata_type\030\006" +
      " \001(\t\022\023\n\013is_nullable\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\014d" +
      "isplay_size\030\013 \001(\005\022\022\n\nis_aliased\030\014 \001(\010\0225\n" +
      "\rsearchability\030\r \001(\0162\036.exec.user.ColumnS" +
      "earchability\0223\n\014updatability\030\016 \001(\0162\035.exe" +
      "c.user.ColumnUpdatability\022\026\n\016auto_increm" +
      "ent\030\017 \001(\010\022\030\n\020case_sensitivity\030\020 \001(\010\022\020\n\010s" +
      "ortable\030\021 \001(\010\022\022\n\nclass_name\030\022 \001(\t\022\023\n\013is_" +
      "currency\030\024 \001(\010\".\n\027PreparedStatementHandl" +
      "e\022\023\n\013server_info\030\001 \001(\014\"\200\001\n\021PreparedState" +
      "ment\0220\n\007columns\030\001 \003(\0132\037.exec.user.Result" +
      "ColumnMetadata\0229\n\rserver_handle\030\002 \001(\0132\"." +
      "exec.user.PreparedStatementHandle\"\253\001\n\033Cr" +
      "eatePreparedStatementResp\022(\n\006status\030\001 \001(" +
      "\0162\030.exec.user.RequestStatus\0228\n\022prepared_" +
      "statement\030\002 \001(\0132\034.exec.user.PreparedStat" +
      "ement\022(\n\005error\030\003 \001(\0132\031.exec.shared.Drill" +
      "PBError\"\022\n\020GetServerMetaReq\"P\n\016ConvertSu" +
      "pport\022\037\n\004from\030\001 \002(\0162\021.common.MinorType\022\035" +
      "\n\002to\030\002 \002(\0162\021.common.MinorType\"\223\001\n\021GetSer" +
      "verMetaResp\022(\n\006status\030\001 \001(\0162\030.exec.user." +
      "RequestStatus\022*\n\013server_meta\030\002 \001(\0132\025.exe" +
      "c.user.ServerMeta\022(\n\005error\030\003 \001(\0132\031.exec." +
      "shared.DrillPBError\"\227\016\n\nServerMeta\022\035\n\025al" +
      "l_tables_selectable\030\001 \001(\010\022%\n\035blob_includ" +
      "ed_in_max_row_size\030\002 \001(\010\022\030\n\020catalog_at_s" +
      "tart\030\003 \001(\010\022\031\n\021catalog_separator\030\004 \001(\t\022\024\n" +
      "\014catalog_term\030\005 \001(\t\0222\n\017collate_support\030\006" +
      " \003(\0162\031.exec.user.CollateSupport\022!\n\031colum" +
      "n_aliasing_supported\030\007 \001(\010\0222\n\017convert_su" +
      "pport\030\010 \003(\0132\031.exec.user.ConvertSupport\022E" +
      "\n\031correlation_names_support\030\t \001(\0162\".exec" +
      ".user.CorrelationNamesSupport\022\033\n\023date_ti" +
      "me_functions\030\n \003(\t\022F\n\032date_time_literals" +
      "_support\030\013 \003(\0162\".exec.user.DateTimeLiter" +
      "alsSupport\0223\n\020group_by_support\030\014 \001(\0162\031.e" +
      "xec.user.GroupBySupport\0226\n\021identifier_ca" +
      "sing\030\r \001(\0162\033.exec.user.IdentifierCasing\022" +
      "\037\n\027identifier_quote_string\030\016 \001(\t\022$\n\034like" +
      "_escape_clause_supported\030\017 \001(\010\022!\n\031max_bi" +
      "nary_literal_length\030\020 \001(\r\022\037\n\027max_catalog" +
      "_name_length\030\021 \001(\r\022\037\n\027max_char_literal_l" +
      "ength\030\022 \001(\r\022\036\n\026max_column_name_length\030\023 " +
      "\001(\r\022\037\n\027max_columns_in_group_by\030\024 \001(\r\022\037\n\027" +
      "max_columns_in_order_by\030\025 \001(\r\022\035\n\025max_col" +
      "umns_in_select\030\026 \001(\r\022\036\n\026max_cursor_name_" +
      "length\030\027 \001(\r\022\034\n\024max_logical_lob_size\030\030 \001" +
      "(\r\022\024\n\014max_row_size\030\031 \001(\r\022\036\n\026max_schema_n" +
      "ame_length\030\032 \001(\r\022\034\n\024max_statement_length" +
      "\030\033 \001(\r\022\026\n\016max_statements\030\034 \001(\r\022\035\n\025max_ta" +
      "ble_name_length\030\035 \001(\r\022\034\n\024max_tables_in_s" +
      "elect\030\036 \001(\r\022\034\n\024max_user_name_length\030\037 \001(" +
      "\r\0220\n\016null_collation\030  \001(\0162\030.exec.user.Nu" +
      "llCollation\022&\n\036null_plus_non_null_equals" +
      "_null\030! \001(\010\022\031\n\021numeric_functions\030\" \003(\t\0223" +
      "\n\020order_by_support\030# \003(\0162\031.exec.user.Ord" +
      "erBySupport\0227\n\022outer_join_support\030$ \003(\0162" +
      "\033.exec.user.OuterJoinSupport\022=\n\030quoted_i" +
      "dentifier_casing\030% \001(\0162\033.exec.user.Ident" +
      "ifierCasing\022\021\n\tread_only\030& \001(\010\022\023\n\013schema" +
      "_term\030\' \001(\t\022\034\n\024search_escape_string\030( \001(" +
      "\t\022#\n\033select_for_update_supported\030) \001(\010\022\032" +
      "\n\022special_characters\030* \001(\t\022\024\n\014sql_keywor" +
      "ds\030+ \003(\t\022\030\n\020string_functions\030, \003(\t\0224\n\020su" +
      "bquery_support\030- \003(\0162\032.exec.user.SubQuer" +
      "ySupport\022\030\n\020system_functions\030. \003(\t\022\022\n\nta" +
      "ble_term\030/ \001(\t\022\035\n\025transaction_supported\030" +
      "0 \001(\010\022.\n\runion_support\0301 \003(\0162\027.exec.user" +
      ".UnionSupport\022\026\n\016current_schema\0302 \001(\t\"\207\002" +
      "\n\010RunQuery\0221\n\014results_mode\030\001 \001(\0162\033.exec." +
      "user.QueryResultsMode\022$\n\004type\030\002 \001(\0162\026.ex" +
      "ec.shared.QueryType\022\014\n\004plan\030\003 \001(\t\0221\n\tfra" +
      "gments\030\004 \003(\0132\036.exec.bit.control.PlanFrag" +
      "ment\022E\n\031prepared_statement_handle\030\005 \001(\0132" +
      "\".exec.user.PreparedStatementHandle\022\032\n\022a" +
      "utolimit_rowcount\030\006 \001(\005*\320\003\n\007RpcType\022\r\n\tH" +
      "ANDSHAKE\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_RES" +
      "ULTS\020\005\022\027\n\023RESUME_PAUSED_QUERY\020\013\022\034\n\030GET_Q" +
      "UERY_PLAN_FRAGMENTS\020\014\022\020\n\014GET_CATALOGS\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_STATEMENT\020\026" +
      "\022\023\n\017GET_SERVER_META\020\010\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\017\n" +
      "\013SERVER_META\020\t\022\020\n\014QUERY_RESULT\020\n\022\020\n\014SASL" +
      "_MESSAGE\020\030*H\n\013SaslSupport\022\030\n\024UNKNOWN_SAS" +
      "L_SUPPORT\020\000\022\r\n\tSASL_AUTH\020\001\022\020\n\014SASL_PRIVA" +
      "CY\020\002*#\n\020QueryResultsMode\022\017\n\013STREAM_FULL\020" +
      "\001*q\n\017HandshakeStatus\022\013\n\007SUCCESS\020\001\022\030\n\024RPC" +
      "_VERSION_MISMATCH\020\002\022\017\n\013AUTH_FAILED\020\003\022\023\n\017" +
      "UNKNOWN_FAILURE\020\004\022\021\n\rAUTH_REQUIRED\020\005*D\n\r" +
      "RequestStatus\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\023ColumnSear" +
      "chability\022\031\n\025UNKNOWN_SEARCHABILITY\020\000\022\010\n\004" +
      "NONE\020\001\022\010\n\004CHAR\020\002\022\n\n\006NUMBER\020\003\022\007\n\003ALL\020\004*K\n" +
      "\022ColumnUpdatability\022\030\n\024UNKNOWN_UPDATABIL" +
      "ITY\020\000\022\r\n\tREAD_ONLY\020\001\022\014\n\010WRITABLE\020\002*1\n\016Co" +
      "llateSupport\022\016\n\nCS_UNKNOWN\020\000\022\017\n\013CS_GROUP" +
      "_BY\020\001*J\n\027CorrelationNamesSupport\022\013\n\007CN_N" +
      "ONE\020\001\022\026\n\022CN_DIFFERENT_NAMES\020\002\022\n\n\006CN_ANY\020" +
      "\003*\271\003\n\027DateTimeLiteralsSupport\022\016\n\nDL_UNKN" +
      "OWN\020\000\022\013\n\007DL_DATE\020\001\022\013\n\007DL_TIME\020\002\022\020\n\014DL_TI" +
      "MESTAMP\020\003\022\024\n\020DL_INTERVAL_YEAR\020\004\022\025\n\021DL_IN" +
      "TERVAL_MONTH\020\005\022\023\n\017DL_INTERVAL_DAY\020\006\022\024\n\020D" +
      "L_INTERVAL_HOUR\020\007\022\026\n\022DL_INTERVAL_MINUTE\020" +
      "\010\022\026\n\022DL_INTERVAL_SECOND\020\t\022\035\n\031DL_INTERVAL" +
      "_YEAR_TO_MONTH\020\n\022\033\n\027DL_INTERVAL_DAY_TO_H" +
      "OUR\020\013\022\035\n\031DL_INTERVAL_DAY_TO_MINUTE\020\014\022\035\n\031" +
      "DL_INTERVAL_DAY_TO_SECOND\020\r\022\036\n\032DL_INTERV" +
      "AL_HOUR_TO_MINUTE\020\016\022\036\n\032DL_INTERVAL_HOUR_" +
      "TO_SECOND\020\017\022 \n\034DL_INTERVAL_MINUTE_TO_SEC" +
      "OND\020\020*Y\n\016GroupBySupport\022\013\n\007GB_NONE\020\001\022\022\n\016" +
      "GB_SELECT_ONLY\020\002\022\024\n\020GB_BEYOND_SELECT\020\003\022\020" +
      "\n\014GB_UNRELATED\020\004*x\n\020IdentifierCasing\022\016\n\n" +
      "IC_UNKNOWN\020\000\022\023\n\017IC_STORES_LOWER\020\001\022\023\n\017IC_" +
      "STORES_MIXED\020\002\022\023\n\017IC_STORES_UPPER\020\003\022\025\n\021I" +
      "C_SUPPORTS_MIXED\020\004*X\n\rNullCollation\022\016\n\nN" +
      "C_UNKNOWN\020\000\022\017\n\013NC_AT_START\020\001\022\r\n\tNC_AT_EN" +
      "D\020\002\022\013\n\007NC_HIGH\020\003\022\n\n\006NC_LOW\020\004*E\n\016OrderByS" +
      "upport\022\016\n\nOB_UNKNOWN\020\000\022\020\n\014OB_UNRELATED\020\001" +
      "\022\021\n\rOB_EXPRESSION\020\002*\226\001\n\020OuterJoinSupport" +
      "\022\016\n\nOJ_UNKNOWN\020\000\022\013\n\007OJ_LEFT\020\001\022\014\n\010OJ_RIGH" +
      "T\020\002\022\013\n\007OJ_FULL\020\003\022\r\n\tOJ_NESTED\020\004\022\022\n\016OJ_NO" +
      "T_ORDERED\020\005\022\014\n\010OJ_INNER\020\006\022\031\n\025OJ_ALL_COMP" +
      "ARISON_OPS\020\007*\204\001\n\017SubQuerySupport\022\016\n\nSQ_U" +
      "NKNOWN\020\000\022\021\n\rSQ_CORRELATED\020\001\022\024\n\020SQ_IN_COM" +
      "PARISON\020\002\022\020\n\014SQ_IN_EXISTS\020\003\022\020\n\014SQ_IN_INS" +
      "ERT\020\004\022\024\n\020SQ_IN_QUANTIFIED\020\005*;\n\014UnionSupp" +
      "ort\022\r\n\tU_UNKNOWN\020\000\022\013\n\007U_UNION\020\001\022\017\n\013U_UNI" +
      "ON_ALL\020\002B+\n\033org.apache.drill.exec.protoB" +
      "\nUserProtosH\001"
    };
    descriptor = com.google.protobuf.Descriptors.FileDescriptor
      .internalBuildGeneratedFileFrom(descriptorData,
        new com.google.protobuf.Descriptors.FileDescriptor[] {
          org.apache.drill.exec.proto.SchemaDefProtos.getDescriptor(),
          org.apache.drill.common.types.TypeProtos.getDescriptor(),
          org.apache.drill.exec.proto.UserBitShared.getDescriptor(),
          org.apache.drill.exec.proto.BitData.getDescriptor(),
          org.apache.drill.exec.proto.BitControl.getDescriptor(),
          org.apache.drill.exec.proto.ExecProtos.getDescriptor(),
        });
    internal_static_exec_user_Property_descriptor =
      getDescriptor().getMessageTypes().get(0);
    internal_static_exec_user_Property_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_Property_descriptor,
        new java.lang.String[] { "Key", "Value", });
    internal_static_exec_user_UserProperties_descriptor =
      getDescriptor().getMessageTypes().get(1);
    internal_static_exec_user_UserProperties_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_UserProperties_descriptor,
        new java.lang.String[] { "Properties", });
    internal_static_exec_user_RpcEndpointInfos_descriptor =
      getDescriptor().getMessageTypes().get(2);
    internal_static_exec_user_RpcEndpointInfos_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_RpcEndpointInfos_descriptor,
        new java.lang.String[] { "Name", "Version", "MajorVersion", "MinorVersion", "PatchVersion", "Application", "BuildNumber", "VersionQualifier", });
    internal_static_exec_user_UserToBitHandshake_descriptor =
      getDescriptor().getMessageTypes().get(3);
    internal_static_exec_user_UserToBitHandshake_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_UserToBitHandshake_descriptor,
        new java.lang.String[] { "Channel", "SupportListening", "RpcVersion", "Credentials", "Properties", "SupportComplexTypes", "SupportTimeout", "ClientInfos", "SaslSupport", });
    internal_static_exec_user_RequestResults_descriptor =
      getDescriptor().getMessageTypes().get(4);
    internal_static_exec_user_RequestResults_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_RequestResults_descriptor,
        new java.lang.String[] { "QueryId", "MaximumResponses", });
    internal_static_exec_user_GetQueryPlanFragments_descriptor =
      getDescriptor().getMessageTypes().get(5);
    internal_static_exec_user_GetQueryPlanFragments_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetQueryPlanFragments_descriptor,
        new java.lang.String[] { "Query", "Type", "SplitPlan", });
    internal_static_exec_user_QueryPlanFragments_descriptor =
      getDescriptor().getMessageTypes().get(6);
    internal_static_exec_user_QueryPlanFragments_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_QueryPlanFragments_descriptor,
        new java.lang.String[] { "Status", "QueryId", "Fragments", "Error", });
    internal_static_exec_user_BitToUserHandshake_descriptor =
      getDescriptor().getMessageTypes().get(7);
    internal_static_exec_user_BitToUserHandshake_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_BitToUserHandshake_descriptor,
        new java.lang.String[] { "RpcVersion", "Status", "ErrorId", "ErrorMessage", "ServerInfos", "AuthenticationMechanisms", "SupportedMethods", "Encrypted", "MaxWrappedSize", });
    internal_static_exec_user_LikeFilter_descriptor =
      getDescriptor().getMessageTypes().get(8);
    internal_static_exec_user_LikeFilter_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_LikeFilter_descriptor,
        new java.lang.String[] { "Pattern", "Escape", });
    internal_static_exec_user_GetCatalogsReq_descriptor =
      getDescriptor().getMessageTypes().get(9);
    internal_static_exec_user_GetCatalogsReq_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetCatalogsReq_descriptor,
        new java.lang.String[] { "CatalogNameFilter", });
    internal_static_exec_user_CatalogMetadata_descriptor =
      getDescriptor().getMessageTypes().get(10);
    internal_static_exec_user_CatalogMetadata_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_CatalogMetadata_descriptor,
        new java.lang.String[] { "CatalogName", "Description", "Connect", });
    internal_static_exec_user_GetCatalogsResp_descriptor =
      getDescriptor().getMessageTypes().get(11);
    internal_static_exec_user_GetCatalogsResp_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetCatalogsResp_descriptor,
        new java.lang.String[] { "Status", "Catalogs", "Error", });
    internal_static_exec_user_GetSchemasReq_descriptor =
      getDescriptor().getMessageTypes().get(12);
    internal_static_exec_user_GetSchemasReq_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetSchemasReq_descriptor,
        new java.lang.String[] { "CatalogNameFilter", "SchemaNameFilter", });
    internal_static_exec_user_SchemaMetadata_descriptor =
      getDescriptor().getMessageTypes().get(13);
    internal_static_exec_user_SchemaMetadata_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_SchemaMetadata_descriptor,
        new java.lang.String[] { "CatalogName", "SchemaName", "Owner", "Type", "Mutable", });
    internal_static_exec_user_GetSchemasResp_descriptor =
      getDescriptor().getMessageTypes().get(14);
    internal_static_exec_user_GetSchemasResp_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetSchemasResp_descriptor,
        new java.lang.String[] { "Status", "Schemas", "Error", });
    internal_static_exec_user_GetTablesReq_descriptor =
      getDescriptor().getMessageTypes().get(15);
    internal_static_exec_user_GetTablesReq_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetTablesReq_descriptor,
        new java.lang.String[] { "CatalogNameFilter", "SchemaNameFilter", "TableNameFilter", "TableTypeFilter", });
    internal_static_exec_user_TableMetadata_descriptor =
      getDescriptor().getMessageTypes().get(16);
    internal_static_exec_user_TableMetadata_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_TableMetadata_descriptor,
        new java.lang.String[] { "CatalogName", "SchemaName", "TableName", "Type", });
    internal_static_exec_user_GetTablesResp_descriptor =
      getDescriptor().getMessageTypes().get(17);
    internal_static_exec_user_GetTablesResp_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetTablesResp_descriptor,
        new java.lang.String[] { "Status", "Tables", "Error", });
    internal_static_exec_user_GetColumnsReq_descriptor =
      getDescriptor().getMessageTypes().get(18);
    internal_static_exec_user_GetColumnsReq_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetColumnsReq_descriptor,
        new java.lang.String[] { "CatalogNameFilter", "SchemaNameFilter", "TableNameFilter", "ColumnNameFilter", });
    internal_static_exec_user_ColumnMetadata_descriptor =
      getDescriptor().getMessageTypes().get(19);
    internal_static_exec_user_ColumnMetadata_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_ColumnMetadata_descriptor,
        new java.lang.String[] { "CatalogName", "SchemaName", "TableName", "ColumnName", "OrdinalPosition", "DefaultValue", "IsNullable", "DataType", "CharMaxLength", "CharOctetLength", "NumericPrecision", "NumericPrecisionRadix", "NumericScale", "DateTimePrecision", "IntervalType", "IntervalPrecision", "ColumnSize", });
    internal_static_exec_user_GetColumnsResp_descriptor =
      getDescriptor().getMessageTypes().get(20);
    internal_static_exec_user_GetColumnsResp_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetColumnsResp_descriptor,
        new java.lang.String[] { "Status", "Columns", "Error", });
    internal_static_exec_user_CreatePreparedStatementReq_descriptor =
      getDescriptor().getMessageTypes().get(21);
    internal_static_exec_user_CreatePreparedStatementReq_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_CreatePreparedStatementReq_descriptor,
        new java.lang.String[] { "SqlQuery", });
    internal_static_exec_user_ResultColumnMetadata_descriptor =
      getDescriptor().getMessageTypes().get(22);
    internal_static_exec_user_ResultColumnMetadata_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_ResultColumnMetadata_descriptor,
        new java.lang.String[] { "CatalogName", "SchemaName", "TableName", "ColumnName", "Label", "DataType", "IsNullable", "Precision", "Scale", "Signed", "DisplaySize", "IsAliased", "Searchability", "Updatability", "AutoIncrement", "CaseSensitivity", "Sortable", "ClassName", "IsCurrency", });
    internal_static_exec_user_PreparedStatementHandle_descriptor =
      getDescriptor().getMessageTypes().get(23);
    internal_static_exec_user_PreparedStatementHandle_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_PreparedStatementHandle_descriptor,
        new java.lang.String[] { "ServerInfo", });
    internal_static_exec_user_PreparedStatement_descriptor =
      getDescriptor().getMessageTypes().get(24);
    internal_static_exec_user_PreparedStatement_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_PreparedStatement_descriptor,
        new java.lang.String[] { "Columns", "ServerHandle", });
    internal_static_exec_user_CreatePreparedStatementResp_descriptor =
      getDescriptor().getMessageTypes().get(25);
    internal_static_exec_user_CreatePreparedStatementResp_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_CreatePreparedStatementResp_descriptor,
        new java.lang.String[] { "Status", "PreparedStatement", "Error", });
    internal_static_exec_user_GetServerMetaReq_descriptor =
      getDescriptor().getMessageTypes().get(26);
    internal_static_exec_user_GetServerMetaReq_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetServerMetaReq_descriptor,
        new java.lang.String[] { });
    internal_static_exec_user_ConvertSupport_descriptor =
      getDescriptor().getMessageTypes().get(27);
    internal_static_exec_user_ConvertSupport_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_ConvertSupport_descriptor,
        new java.lang.String[] { "From", "To", });
    internal_static_exec_user_GetServerMetaResp_descriptor =
      getDescriptor().getMessageTypes().get(28);
    internal_static_exec_user_GetServerMetaResp_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_GetServerMetaResp_descriptor,
        new java.lang.String[] { "Status", "ServerMeta", "Error", });
    internal_static_exec_user_ServerMeta_descriptor =
      getDescriptor().getMessageTypes().get(29);
    internal_static_exec_user_ServerMeta_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_ServerMeta_descriptor,
        new java.lang.String[] { "AllTablesSelectable", "BlobIncludedInMaxRowSize", "CatalogAtStart", "CatalogSeparator", "CatalogTerm", "CollateSupport", "ColumnAliasingSupported", "ConvertSupport", "CorrelationNamesSupport", "DateTimeFunctions", "DateTimeLiteralsSupport", "GroupBySupport", "IdentifierCasing", "IdentifierQuoteString", "LikeEscapeClauseSupported", "MaxBinaryLiteralLength", "MaxCatalogNameLength", "MaxCharLiteralLength", "MaxColumnNameLength", "MaxColumnsInGroupBy", "MaxColumnsInOrderBy", "MaxColumnsInSelect", "MaxCursorNameLength", "MaxLogicalLobSize", "MaxRowSize", "MaxSchemaNameLength", "MaxStatementLength", "MaxStatements", "MaxTableNameLength", "MaxTablesInSelect", "MaxUserNameLength", "NullCollation", "NullPlusNonNullEqualsNull", "NumericFunctions", "OrderBySupport", "OuterJoinSupport", "QuotedIdentifierCasing", "ReadOnly", "SchemaTerm", "SearchEscapeString", "SelectForUpdateSupported", "SpecialCharacters", "SqlKeywords", "StringFunctions", "SubquerySupport", "SystemFunctions", "TableTerm", "TransactionSupported", "UnionSupport", "CurrentSchema", });
    internal_static_exec_user_RunQuery_descriptor =
      getDescriptor().getMessageTypes().get(30);
    internal_static_exec_user_RunQuery_fieldAccessorTable = new
      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
        internal_static_exec_user_RunQuery_descriptor,
        new java.lang.String[] { "ResultsMode", "Type", "Plan", "Fragments", "PreparedStatementHandle", "AutolimitRowcount", });
    org.apache.drill.exec.proto.SchemaDefProtos.getDescriptor();
    org.apache.drill.common.types.TypeProtos.getDescriptor();
    org.apache.drill.exec.proto.UserBitShared.getDescriptor();
    org.apache.drill.exec.proto.BitData.getDescriptor();
    org.apache.drill.exec.proto.BitControl.getDescriptor();
    org.apache.drill.exec.proto.ExecProtos.getDescriptor();
  }

  // @@protoc_insertion_point(outer_class_scope)
}
