// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: User.proto

#ifndef GOOGLE_PROTOBUF_INCLUDED_User_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_User_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3016000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3016003 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
#include "SchemaDef.pb.h"
#include "Types.pb.h"
#include "UserBitShared.pb.h"
#include "BitData.pb.h"
#include "BitControl.pb.h"
#include "ExecutionProtos.pb.h"
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_User_2eproto
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct TableStruct_User_2eproto {
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[31]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
  static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
  static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
};
extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_User_2eproto;
namespace exec {
namespace user {
class BitToUserHandshake;
struct BitToUserHandshakeDefaultTypeInternal;
extern BitToUserHandshakeDefaultTypeInternal _BitToUserHandshake_default_instance_;
class CatalogMetadata;
struct CatalogMetadataDefaultTypeInternal;
extern CatalogMetadataDefaultTypeInternal _CatalogMetadata_default_instance_;
class ColumnMetadata;
struct ColumnMetadataDefaultTypeInternal;
extern ColumnMetadataDefaultTypeInternal _ColumnMetadata_default_instance_;
class ConvertSupport;
struct ConvertSupportDefaultTypeInternal;
extern ConvertSupportDefaultTypeInternal _ConvertSupport_default_instance_;
class CreatePreparedStatementReq;
struct CreatePreparedStatementReqDefaultTypeInternal;
extern CreatePreparedStatementReqDefaultTypeInternal _CreatePreparedStatementReq_default_instance_;
class CreatePreparedStatementResp;
struct CreatePreparedStatementRespDefaultTypeInternal;
extern CreatePreparedStatementRespDefaultTypeInternal _CreatePreparedStatementResp_default_instance_;
class GetCatalogsReq;
struct GetCatalogsReqDefaultTypeInternal;
extern GetCatalogsReqDefaultTypeInternal _GetCatalogsReq_default_instance_;
class GetCatalogsResp;
struct GetCatalogsRespDefaultTypeInternal;
extern GetCatalogsRespDefaultTypeInternal _GetCatalogsResp_default_instance_;
class GetColumnsReq;
struct GetColumnsReqDefaultTypeInternal;
extern GetColumnsReqDefaultTypeInternal _GetColumnsReq_default_instance_;
class GetColumnsResp;
struct GetColumnsRespDefaultTypeInternal;
extern GetColumnsRespDefaultTypeInternal _GetColumnsResp_default_instance_;
class GetQueryPlanFragments;
struct GetQueryPlanFragmentsDefaultTypeInternal;
extern GetQueryPlanFragmentsDefaultTypeInternal _GetQueryPlanFragments_default_instance_;
class GetSchemasReq;
struct GetSchemasReqDefaultTypeInternal;
extern GetSchemasReqDefaultTypeInternal _GetSchemasReq_default_instance_;
class GetSchemasResp;
struct GetSchemasRespDefaultTypeInternal;
extern GetSchemasRespDefaultTypeInternal _GetSchemasResp_default_instance_;
class GetServerMetaReq;
struct GetServerMetaReqDefaultTypeInternal;
extern GetServerMetaReqDefaultTypeInternal _GetServerMetaReq_default_instance_;
class GetServerMetaResp;
struct GetServerMetaRespDefaultTypeInternal;
extern GetServerMetaRespDefaultTypeInternal _GetServerMetaResp_default_instance_;
class GetTablesReq;
struct GetTablesReqDefaultTypeInternal;
extern GetTablesReqDefaultTypeInternal _GetTablesReq_default_instance_;
class GetTablesResp;
struct GetTablesRespDefaultTypeInternal;
extern GetTablesRespDefaultTypeInternal _GetTablesResp_default_instance_;
class LikeFilter;
struct LikeFilterDefaultTypeInternal;
extern LikeFilterDefaultTypeInternal _LikeFilter_default_instance_;
class PreparedStatement;
struct PreparedStatementDefaultTypeInternal;
extern PreparedStatementDefaultTypeInternal _PreparedStatement_default_instance_;
class PreparedStatementHandle;
struct PreparedStatementHandleDefaultTypeInternal;
extern PreparedStatementHandleDefaultTypeInternal _PreparedStatementHandle_default_instance_;
class Property;
struct PropertyDefaultTypeInternal;
extern PropertyDefaultTypeInternal _Property_default_instance_;
class QueryPlanFragments;
struct QueryPlanFragmentsDefaultTypeInternal;
extern QueryPlanFragmentsDefaultTypeInternal _QueryPlanFragments_default_instance_;
class RequestResults;
struct RequestResultsDefaultTypeInternal;
extern RequestResultsDefaultTypeInternal _RequestResults_default_instance_;
class ResultColumnMetadata;
struct ResultColumnMetadataDefaultTypeInternal;
extern ResultColumnMetadataDefaultTypeInternal _ResultColumnMetadata_default_instance_;
class RpcEndpointInfos;
struct RpcEndpointInfosDefaultTypeInternal;
extern RpcEndpointInfosDefaultTypeInternal _RpcEndpointInfos_default_instance_;
class RunQuery;
struct RunQueryDefaultTypeInternal;
extern RunQueryDefaultTypeInternal _RunQuery_default_instance_;
class SchemaMetadata;
struct SchemaMetadataDefaultTypeInternal;
extern SchemaMetadataDefaultTypeInternal _SchemaMetadata_default_instance_;
class ServerMeta;
struct ServerMetaDefaultTypeInternal;
extern ServerMetaDefaultTypeInternal _ServerMeta_default_instance_;
class TableMetadata;
struct TableMetadataDefaultTypeInternal;
extern TableMetadataDefaultTypeInternal _TableMetadata_default_instance_;
class UserProperties;
struct UserPropertiesDefaultTypeInternal;
extern UserPropertiesDefaultTypeInternal _UserProperties_default_instance_;
class UserToBitHandshake;
struct UserToBitHandshakeDefaultTypeInternal;
extern UserToBitHandshakeDefaultTypeInternal _UserToBitHandshake_default_instance_;
}  // namespace user
}  // namespace exec
PROTOBUF_NAMESPACE_OPEN
template<> ::exec::user::BitToUserHandshake* Arena::CreateMaybeMessage<::exec::user::BitToUserHandshake>(Arena*);
template<> ::exec::user::CatalogMetadata* Arena::CreateMaybeMessage<::exec::user::CatalogMetadata>(Arena*);
template<> ::exec::user::ColumnMetadata* Arena::CreateMaybeMessage<::exec::user::ColumnMetadata>(Arena*);
template<> ::exec::user::ConvertSupport* Arena::CreateMaybeMessage<::exec::user::ConvertSupport>(Arena*);
template<> ::exec::user::CreatePreparedStatementReq* Arena::CreateMaybeMessage<::exec::user::CreatePreparedStatementReq>(Arena*);
template<> ::exec::user::CreatePreparedStatementResp* Arena::CreateMaybeMessage<::exec::user::CreatePreparedStatementResp>(Arena*);
template<> ::exec::user::GetCatalogsReq* Arena::CreateMaybeMessage<::exec::user::GetCatalogsReq>(Arena*);
template<> ::exec::user::GetCatalogsResp* Arena::CreateMaybeMessage<::exec::user::GetCatalogsResp>(Arena*);
template<> ::exec::user::GetColumnsReq* Arena::CreateMaybeMessage<::exec::user::GetColumnsReq>(Arena*);
template<> ::exec::user::GetColumnsResp* Arena::CreateMaybeMessage<::exec::user::GetColumnsResp>(Arena*);
template<> ::exec::user::GetQueryPlanFragments* Arena::CreateMaybeMessage<::exec::user::GetQueryPlanFragments>(Arena*);
template<> ::exec::user::GetSchemasReq* Arena::CreateMaybeMessage<::exec::user::GetSchemasReq>(Arena*);
template<> ::exec::user::GetSchemasResp* Arena::CreateMaybeMessage<::exec::user::GetSchemasResp>(Arena*);
template<> ::exec::user::GetServerMetaReq* Arena::CreateMaybeMessage<::exec::user::GetServerMetaReq>(Arena*);
template<> ::exec::user::GetServerMetaResp* Arena::CreateMaybeMessage<::exec::user::GetServerMetaResp>(Arena*);
template<> ::exec::user::GetTablesReq* Arena::CreateMaybeMessage<::exec::user::GetTablesReq>(Arena*);
template<> ::exec::user::GetTablesResp* Arena::CreateMaybeMessage<::exec::user::GetTablesResp>(Arena*);
template<> ::exec::user::LikeFilter* Arena::CreateMaybeMessage<::exec::user::LikeFilter>(Arena*);
template<> ::exec::user::PreparedStatement* Arena::CreateMaybeMessage<::exec::user::PreparedStatement>(Arena*);
template<> ::exec::user::PreparedStatementHandle* Arena::CreateMaybeMessage<::exec::user::PreparedStatementHandle>(Arena*);
template<> ::exec::user::Property* Arena::CreateMaybeMessage<::exec::user::Property>(Arena*);
template<> ::exec::user::QueryPlanFragments* Arena::CreateMaybeMessage<::exec::user::QueryPlanFragments>(Arena*);
template<> ::exec::user::RequestResults* Arena::CreateMaybeMessage<::exec::user::RequestResults>(Arena*);
template<> ::exec::user::ResultColumnMetadata* Arena::CreateMaybeMessage<::exec::user::ResultColumnMetadata>(Arena*);
template<> ::exec::user::RpcEndpointInfos* Arena::CreateMaybeMessage<::exec::user::RpcEndpointInfos>(Arena*);
template<> ::exec::user::RunQuery* Arena::CreateMaybeMessage<::exec::user::RunQuery>(Arena*);
template<> ::exec::user::SchemaMetadata* Arena::CreateMaybeMessage<::exec::user::SchemaMetadata>(Arena*);
template<> ::exec::user::ServerMeta* Arena::CreateMaybeMessage<::exec::user::ServerMeta>(Arena*);
template<> ::exec::user::TableMetadata* Arena::CreateMaybeMessage<::exec::user::TableMetadata>(Arena*);
template<> ::exec::user::UserProperties* Arena::CreateMaybeMessage<::exec::user::UserProperties>(Arena*);
template<> ::exec::user::UserToBitHandshake* Arena::CreateMaybeMessage<::exec::user::UserToBitHandshake>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace exec {
namespace user {

enum RpcType : int {
  HANDSHAKE = 0,
  ACK = 1,
  GOODBYE = 2,
  RUN_QUERY = 3,
  CANCEL_QUERY = 4,
  REQUEST_RESULTS = 5,
  RESUME_PAUSED_QUERY = 11,
  GET_QUERY_PLAN_FRAGMENTS = 12,
  GET_CATALOGS = 14,
  GET_SCHEMAS = 15,
  GET_TABLES = 16,
  GET_COLUMNS = 17,
  CREATE_PREPARED_STATEMENT = 22,
  GET_SERVER_META = 8,
  QUERY_DATA = 6,
  QUERY_HANDLE = 7,
  QUERY_PLAN_FRAGMENTS = 13,
  CATALOGS = 18,
  SCHEMAS = 19,
  TABLES = 20,
  COLUMNS = 21,
  PREPARED_STATEMENT = 23,
  SERVER_META = 9,
  QUERY_RESULT = 10,
  SASL_MESSAGE = 24
};
bool RpcType_IsValid(int value);
constexpr RpcType RpcType_MIN = HANDSHAKE;
constexpr RpcType RpcType_MAX = SASL_MESSAGE;
constexpr int RpcType_ARRAYSIZE = RpcType_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* RpcType_descriptor();
template<typename T>
inline const std::string& RpcType_Name(T enum_t_value) {
  static_assert(::std::is_same<T, RpcType>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function RpcType_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    RpcType_descriptor(), enum_t_value);
}
inline bool RpcType_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, RpcType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<RpcType>(
    RpcType_descriptor(), name, value);
}
enum SaslSupport : int {
  UNKNOWN_SASL_SUPPORT = 0,
  SASL_AUTH = 1,
  SASL_PRIVACY = 2
};
bool SaslSupport_IsValid(int value);
constexpr SaslSupport SaslSupport_MIN = UNKNOWN_SASL_SUPPORT;
constexpr SaslSupport SaslSupport_MAX = SASL_PRIVACY;
constexpr int SaslSupport_ARRAYSIZE = SaslSupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* SaslSupport_descriptor();
template<typename T>
inline const std::string& SaslSupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, SaslSupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function SaslSupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    SaslSupport_descriptor(), enum_t_value);
}
inline bool SaslSupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, SaslSupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<SaslSupport>(
    SaslSupport_descriptor(), name, value);
}
enum QueryResultsMode : int {
  STREAM_FULL = 1
};
bool QueryResultsMode_IsValid(int value);
constexpr QueryResultsMode QueryResultsMode_MIN = STREAM_FULL;
constexpr QueryResultsMode QueryResultsMode_MAX = STREAM_FULL;
constexpr int QueryResultsMode_ARRAYSIZE = QueryResultsMode_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* QueryResultsMode_descriptor();
template<typename T>
inline const std::string& QueryResultsMode_Name(T enum_t_value) {
  static_assert(::std::is_same<T, QueryResultsMode>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function QueryResultsMode_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    QueryResultsMode_descriptor(), enum_t_value);
}
inline bool QueryResultsMode_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, QueryResultsMode* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<QueryResultsMode>(
    QueryResultsMode_descriptor(), name, value);
}
enum HandshakeStatus : int {
  SUCCESS = 1,
  RPC_VERSION_MISMATCH = 2,
  AUTH_FAILED = 3,
  UNKNOWN_FAILURE = 4,
  AUTH_REQUIRED = 5
};
bool HandshakeStatus_IsValid(int value);
constexpr HandshakeStatus HandshakeStatus_MIN = SUCCESS;
constexpr HandshakeStatus HandshakeStatus_MAX = AUTH_REQUIRED;
constexpr int HandshakeStatus_ARRAYSIZE = HandshakeStatus_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* HandshakeStatus_descriptor();
template<typename T>
inline const std::string& HandshakeStatus_Name(T enum_t_value) {
  static_assert(::std::is_same<T, HandshakeStatus>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function HandshakeStatus_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    HandshakeStatus_descriptor(), enum_t_value);
}
inline bool HandshakeStatus_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, HandshakeStatus* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<HandshakeStatus>(
    HandshakeStatus_descriptor(), name, value);
}
enum RequestStatus : int {
  UNKNOWN_STATUS = 0,
  OK = 1,
  FAILED = 2,
  TIMEOUT = 3
};
bool RequestStatus_IsValid(int value);
constexpr RequestStatus RequestStatus_MIN = UNKNOWN_STATUS;
constexpr RequestStatus RequestStatus_MAX = TIMEOUT;
constexpr int RequestStatus_ARRAYSIZE = RequestStatus_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* RequestStatus_descriptor();
template<typename T>
inline const std::string& RequestStatus_Name(T enum_t_value) {
  static_assert(::std::is_same<T, RequestStatus>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function RequestStatus_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    RequestStatus_descriptor(), enum_t_value);
}
inline bool RequestStatus_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, RequestStatus* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<RequestStatus>(
    RequestStatus_descriptor(), name, value);
}
enum ColumnSearchability : int {
  UNKNOWN_SEARCHABILITY = 0,
  NONE = 1,
  CHAR = 2,
  NUMBER = 3,
  ALL = 4
};
bool ColumnSearchability_IsValid(int value);
constexpr ColumnSearchability ColumnSearchability_MIN = UNKNOWN_SEARCHABILITY;
constexpr ColumnSearchability ColumnSearchability_MAX = ALL;
constexpr int ColumnSearchability_ARRAYSIZE = ColumnSearchability_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ColumnSearchability_descriptor();
template<typename T>
inline const std::string& ColumnSearchability_Name(T enum_t_value) {
  static_assert(::std::is_same<T, ColumnSearchability>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function ColumnSearchability_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    ColumnSearchability_descriptor(), enum_t_value);
}
inline bool ColumnSearchability_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ColumnSearchability* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ColumnSearchability>(
    ColumnSearchability_descriptor(), name, value);
}
enum ColumnUpdatability : int {
  UNKNOWN_UPDATABILITY = 0,
  READ_ONLY = 1,
  WRITABLE = 2
};
bool ColumnUpdatability_IsValid(int value);
constexpr ColumnUpdatability ColumnUpdatability_MIN = UNKNOWN_UPDATABILITY;
constexpr ColumnUpdatability ColumnUpdatability_MAX = WRITABLE;
constexpr int ColumnUpdatability_ARRAYSIZE = ColumnUpdatability_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* ColumnUpdatability_descriptor();
template<typename T>
inline const std::string& ColumnUpdatability_Name(T enum_t_value) {
  static_assert(::std::is_same<T, ColumnUpdatability>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function ColumnUpdatability_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    ColumnUpdatability_descriptor(), enum_t_value);
}
inline bool ColumnUpdatability_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ColumnUpdatability* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<ColumnUpdatability>(
    ColumnUpdatability_descriptor(), name, value);
}
enum CollateSupport : int {
  CS_UNKNOWN = 0,
  CS_GROUP_BY = 1
};
bool CollateSupport_IsValid(int value);
constexpr CollateSupport CollateSupport_MIN = CS_UNKNOWN;
constexpr CollateSupport CollateSupport_MAX = CS_GROUP_BY;
constexpr int CollateSupport_ARRAYSIZE = CollateSupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CollateSupport_descriptor();
template<typename T>
inline const std::string& CollateSupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, CollateSupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function CollateSupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    CollateSupport_descriptor(), enum_t_value);
}
inline bool CollateSupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, CollateSupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<CollateSupport>(
    CollateSupport_descriptor(), name, value);
}
enum CorrelationNamesSupport : int {
  CN_NONE = 1,
  CN_DIFFERENT_NAMES = 2,
  CN_ANY = 3
};
bool CorrelationNamesSupport_IsValid(int value);
constexpr CorrelationNamesSupport CorrelationNamesSupport_MIN = CN_NONE;
constexpr CorrelationNamesSupport CorrelationNamesSupport_MAX = CN_ANY;
constexpr int CorrelationNamesSupport_ARRAYSIZE = CorrelationNamesSupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* CorrelationNamesSupport_descriptor();
template<typename T>
inline const std::string& CorrelationNamesSupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, CorrelationNamesSupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function CorrelationNamesSupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    CorrelationNamesSupport_descriptor(), enum_t_value);
}
inline bool CorrelationNamesSupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, CorrelationNamesSupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<CorrelationNamesSupport>(
    CorrelationNamesSupport_descriptor(), name, value);
}
enum DateTimeLiteralsSupport : int {
  DL_UNKNOWN = 0,
  DL_DATE = 1,
  DL_TIME = 2,
  DL_TIMESTAMP = 3,
  DL_INTERVAL_YEAR = 4,
  DL_INTERVAL_MONTH = 5,
  DL_INTERVAL_DAY = 6,
  DL_INTERVAL_HOUR = 7,
  DL_INTERVAL_MINUTE = 8,
  DL_INTERVAL_SECOND = 9,
  DL_INTERVAL_YEAR_TO_MONTH = 10,
  DL_INTERVAL_DAY_TO_HOUR = 11,
  DL_INTERVAL_DAY_TO_MINUTE = 12,
  DL_INTERVAL_DAY_TO_SECOND = 13,
  DL_INTERVAL_HOUR_TO_MINUTE = 14,
  DL_INTERVAL_HOUR_TO_SECOND = 15,
  DL_INTERVAL_MINUTE_TO_SECOND = 16
};
bool DateTimeLiteralsSupport_IsValid(int value);
constexpr DateTimeLiteralsSupport DateTimeLiteralsSupport_MIN = DL_UNKNOWN;
constexpr DateTimeLiteralsSupport DateTimeLiteralsSupport_MAX = DL_INTERVAL_MINUTE_TO_SECOND;
constexpr int DateTimeLiteralsSupport_ARRAYSIZE = DateTimeLiteralsSupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* DateTimeLiteralsSupport_descriptor();
template<typename T>
inline const std::string& DateTimeLiteralsSupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, DateTimeLiteralsSupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function DateTimeLiteralsSupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    DateTimeLiteralsSupport_descriptor(), enum_t_value);
}
inline bool DateTimeLiteralsSupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DateTimeLiteralsSupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<DateTimeLiteralsSupport>(
    DateTimeLiteralsSupport_descriptor(), name, value);
}
enum GroupBySupport : int {
  GB_NONE = 1,
  GB_SELECT_ONLY = 2,
  GB_BEYOND_SELECT = 3,
  GB_UNRELATED = 4
};
bool GroupBySupport_IsValid(int value);
constexpr GroupBySupport GroupBySupport_MIN = GB_NONE;
constexpr GroupBySupport GroupBySupport_MAX = GB_UNRELATED;
constexpr int GroupBySupport_ARRAYSIZE = GroupBySupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* GroupBySupport_descriptor();
template<typename T>
inline const std::string& GroupBySupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, GroupBySupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function GroupBySupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    GroupBySupport_descriptor(), enum_t_value);
}
inline bool GroupBySupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, GroupBySupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<GroupBySupport>(
    GroupBySupport_descriptor(), name, value);
}
enum IdentifierCasing : int {
  IC_UNKNOWN = 0,
  IC_STORES_LOWER = 1,
  IC_STORES_MIXED = 2,
  IC_STORES_UPPER = 3,
  IC_SUPPORTS_MIXED = 4
};
bool IdentifierCasing_IsValid(int value);
constexpr IdentifierCasing IdentifierCasing_MIN = IC_UNKNOWN;
constexpr IdentifierCasing IdentifierCasing_MAX = IC_SUPPORTS_MIXED;
constexpr int IdentifierCasing_ARRAYSIZE = IdentifierCasing_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* IdentifierCasing_descriptor();
template<typename T>
inline const std::string& IdentifierCasing_Name(T enum_t_value) {
  static_assert(::std::is_same<T, IdentifierCasing>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function IdentifierCasing_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    IdentifierCasing_descriptor(), enum_t_value);
}
inline bool IdentifierCasing_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, IdentifierCasing* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<IdentifierCasing>(
    IdentifierCasing_descriptor(), name, value);
}
enum NullCollation : int {
  NC_UNKNOWN = 0,
  NC_AT_START = 1,
  NC_AT_END = 2,
  NC_HIGH = 3,
  NC_LOW = 4
};
bool NullCollation_IsValid(int value);
constexpr NullCollation NullCollation_MIN = NC_UNKNOWN;
constexpr NullCollation NullCollation_MAX = NC_LOW;
constexpr int NullCollation_ARRAYSIZE = NullCollation_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* NullCollation_descriptor();
template<typename T>
inline const std::string& NullCollation_Name(T enum_t_value) {
  static_assert(::std::is_same<T, NullCollation>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function NullCollation_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    NullCollation_descriptor(), enum_t_value);
}
inline bool NullCollation_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, NullCollation* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<NullCollation>(
    NullCollation_descriptor(), name, value);
}
enum OrderBySupport : int {
  OB_UNKNOWN = 0,
  OB_UNRELATED = 1,
  OB_EXPRESSION = 2
};
bool OrderBySupport_IsValid(int value);
constexpr OrderBySupport OrderBySupport_MIN = OB_UNKNOWN;
constexpr OrderBySupport OrderBySupport_MAX = OB_EXPRESSION;
constexpr int OrderBySupport_ARRAYSIZE = OrderBySupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* OrderBySupport_descriptor();
template<typename T>
inline const std::string& OrderBySupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, OrderBySupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function OrderBySupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    OrderBySupport_descriptor(), enum_t_value);
}
inline bool OrderBySupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OrderBySupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<OrderBySupport>(
    OrderBySupport_descriptor(), name, value);
}
enum OuterJoinSupport : int {
  OJ_UNKNOWN = 0,
  OJ_LEFT = 1,
  OJ_RIGHT = 2,
  OJ_FULL = 3,
  OJ_NESTED = 4,
  OJ_NOT_ORDERED = 5,
  OJ_INNER = 6,
  OJ_ALL_COMPARISON_OPS = 7
};
bool OuterJoinSupport_IsValid(int value);
constexpr OuterJoinSupport OuterJoinSupport_MIN = OJ_UNKNOWN;
constexpr OuterJoinSupport OuterJoinSupport_MAX = OJ_ALL_COMPARISON_OPS;
constexpr int OuterJoinSupport_ARRAYSIZE = OuterJoinSupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* OuterJoinSupport_descriptor();
template<typename T>
inline const std::string& OuterJoinSupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, OuterJoinSupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function OuterJoinSupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    OuterJoinSupport_descriptor(), enum_t_value);
}
inline bool OuterJoinSupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, OuterJoinSupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<OuterJoinSupport>(
    OuterJoinSupport_descriptor(), name, value);
}
enum SubQuerySupport : int {
  SQ_UNKNOWN = 0,
  SQ_CORRELATED = 1,
  SQ_IN_COMPARISON = 2,
  SQ_IN_EXISTS = 3,
  SQ_IN_INSERT = 4,
  SQ_IN_QUANTIFIED = 5
};
bool SubQuerySupport_IsValid(int value);
constexpr SubQuerySupport SubQuerySupport_MIN = SQ_UNKNOWN;
constexpr SubQuerySupport SubQuerySupport_MAX = SQ_IN_QUANTIFIED;
constexpr int SubQuerySupport_ARRAYSIZE = SubQuerySupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* SubQuerySupport_descriptor();
template<typename T>
inline const std::string& SubQuerySupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, SubQuerySupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function SubQuerySupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    SubQuerySupport_descriptor(), enum_t_value);
}
inline bool SubQuerySupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, SubQuerySupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<SubQuerySupport>(
    SubQuerySupport_descriptor(), name, value);
}
enum UnionSupport : int {
  U_UNKNOWN = 0,
  U_UNION = 1,
  U_UNION_ALL = 2
};
bool UnionSupport_IsValid(int value);
constexpr UnionSupport UnionSupport_MIN = U_UNKNOWN;
constexpr UnionSupport UnionSupport_MAX = U_UNION_ALL;
constexpr int UnionSupport_ARRAYSIZE = UnionSupport_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* UnionSupport_descriptor();
template<typename T>
inline const std::string& UnionSupport_Name(T enum_t_value) {
  static_assert(::std::is_same<T, UnionSupport>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function UnionSupport_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    UnionSupport_descriptor(), enum_t_value);
}
inline bool UnionSupport_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, UnionSupport* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<UnionSupport>(
    UnionSupport_descriptor(), name, value);
}
// ===================================================================

class Property PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.Property) */ {
 public:
  inline Property() : Property(nullptr) {}
  ~Property() override;
  explicit constexpr Property(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  Property(const Property& from);
  Property(Property&& from) noexcept
    : Property() {
    *this = ::std::move(from);
  }

  inline Property& operator=(const Property& from) {
    CopyFrom(from);
    return *this;
  }
  inline Property& operator=(Property&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const Property& default_instance() {
    return *internal_default_instance();
  }
  static inline const Property* internal_default_instance() {
    return reinterpret_cast<const Property*>(
               &_Property_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(Property& a, Property& b) {
    a.Swap(&b);
  }
  inline void Swap(Property* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(Property* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline Property* New() const final {
    return CreateMaybeMessage<Property>(nullptr);
  }

  Property* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<Property>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const Property& from);
  void MergeFrom(const Property& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(Property* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.Property";
  }
  protected:
  explicit Property(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kKeyFieldNumber = 1,
    kValueFieldNumber = 2,
  };
  // required string key = 1;
  bool has_key() const;
  private:
  bool _internal_has_key() const;
  public:
  void clear_key();
  const std::string& key() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_key(ArgT0&& arg0, ArgT... args);
  std::string* mutable_key();
  std::string* release_key();
  void set_allocated_key(std::string* key);
  private:
  const std::string& _internal_key() const;
  void _internal_set_key(const std::string& value);
  std::string* _internal_mutable_key();
  public:

  // required string value = 2;
  bool has_value() const;
  private:
  bool _internal_has_value() const;
  public:
  void clear_value();
  const std::string& value() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_value();
  std::string* release_value();
  void set_allocated_value(std::string* value);
  private:
  const std::string& _internal_value() const;
  void _internal_set_value(const std::string& value);
  std::string* _internal_mutable_value();
  public:

  // @@protoc_insertion_point(class_scope:exec.user.Property)
 private:
  class _Internal;

  // helper for ByteSizeLong()
  size_t RequiredFieldsByteSizeFallback() const;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr key_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr value_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class UserProperties PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.UserProperties) */ {
 public:
  inline UserProperties() : UserProperties(nullptr) {}
  ~UserProperties() override;
  explicit constexpr UserProperties(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  UserProperties(const UserProperties& from);
  UserProperties(UserProperties&& from) noexcept
    : UserProperties() {
    *this = ::std::move(from);
  }

  inline UserProperties& operator=(const UserProperties& from) {
    CopyFrom(from);
    return *this;
  }
  inline UserProperties& operator=(UserProperties&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const UserProperties& default_instance() {
    return *internal_default_instance();
  }
  static inline const UserProperties* internal_default_instance() {
    return reinterpret_cast<const UserProperties*>(
               &_UserProperties_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  friend void swap(UserProperties& a, UserProperties& b) {
    a.Swap(&b);
  }
  inline void Swap(UserProperties* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(UserProperties* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline UserProperties* New() const final {
    return CreateMaybeMessage<UserProperties>(nullptr);
  }

  UserProperties* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<UserProperties>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const UserProperties& from);
  void MergeFrom(const UserProperties& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(UserProperties* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.UserProperties";
  }
  protected:
  explicit UserProperties(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kPropertiesFieldNumber = 1,
  };
  // repeated .exec.user.Property properties = 1;
  int properties_size() const;
  private:
  int _internal_properties_size() const;
  public:
  void clear_properties();
  ::exec::user::Property* mutable_properties(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::Property >*
      mutable_properties();
  private:
  const ::exec::user::Property& _internal_properties(int index) const;
  ::exec::user::Property* _internal_add_properties();
  public:
  const ::exec::user::Property& properties(int index) const;
  ::exec::user::Property* add_properties();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::Property >&
      properties() const;

  // @@protoc_insertion_point(class_scope:exec.user.UserProperties)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::Property > properties_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class RpcEndpointInfos PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.RpcEndpointInfos) */ {
 public:
  inline RpcEndpointInfos() : RpcEndpointInfos(nullptr) {}
  ~RpcEndpointInfos() override;
  explicit constexpr RpcEndpointInfos(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  RpcEndpointInfos(const RpcEndpointInfos& from);
  RpcEndpointInfos(RpcEndpointInfos&& from) noexcept
    : RpcEndpointInfos() {
    *this = ::std::move(from);
  }

  inline RpcEndpointInfos& operator=(const RpcEndpointInfos& from) {
    CopyFrom(from);
    return *this;
  }
  inline RpcEndpointInfos& operator=(RpcEndpointInfos&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const RpcEndpointInfos& default_instance() {
    return *internal_default_instance();
  }
  static inline const RpcEndpointInfos* internal_default_instance() {
    return reinterpret_cast<const RpcEndpointInfos*>(
               &_RpcEndpointInfos_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  friend void swap(RpcEndpointInfos& a, RpcEndpointInfos& b) {
    a.Swap(&b);
  }
  inline void Swap(RpcEndpointInfos* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(RpcEndpointInfos* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline RpcEndpointInfos* New() const final {
    return CreateMaybeMessage<RpcEndpointInfos>(nullptr);
  }

  RpcEndpointInfos* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<RpcEndpointInfos>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const RpcEndpointInfos& from);
  void MergeFrom(const RpcEndpointInfos& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RpcEndpointInfos* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.RpcEndpointInfos";
  }
  protected:
  explicit RpcEndpointInfos(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kNameFieldNumber = 1,
    kVersionFieldNumber = 2,
    kApplicationFieldNumber = 6,
    kVersionQualifierFieldNumber = 8,
    kMajorVersionFieldNumber = 3,
    kMinorVersionFieldNumber = 4,
    kPatchVersionFieldNumber = 5,
    kBuildNumberFieldNumber = 7,
  };
  // optional string name = 1;
  bool has_name() const;
  private:
  bool _internal_has_name() const;
  public:
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();
  public:

  // optional string version = 2;
  bool has_version() const;
  private:
  bool _internal_has_version() const;
  public:
  void clear_version();
  const std::string& version() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_version(ArgT0&& arg0, ArgT... args);
  std::string* mutable_version();
  std::string* release_version();
  void set_allocated_version(std::string* version);
  private:
  const std::string& _internal_version() const;
  void _internal_set_version(const std::string& value);
  std::string* _internal_mutable_version();
  public:

  // optional string application = 6;
  bool has_application() const;
  private:
  bool _internal_has_application() const;
  public:
  void clear_application();
  const std::string& application() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_application(ArgT0&& arg0, ArgT... args);
  std::string* mutable_application();
  std::string* release_application();
  void set_allocated_application(std::string* application);
  private:
  const std::string& _internal_application() const;
  void _internal_set_application(const std::string& value);
  std::string* _internal_mutable_application();
  public:

  // optional string versionQualifier = 8;
  bool has_versionqualifier() const;
  private:
  bool _internal_has_versionqualifier() const;
  public:
  void clear_versionqualifier();
  const std::string& versionqualifier() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_versionqualifier(ArgT0&& arg0, ArgT... args);
  std::string* mutable_versionqualifier();
  std::string* release_versionqualifier();
  void set_allocated_versionqualifier(std::string* versionqualifier);
  private:
  const std::string& _internal_versionqualifier() const;
  void _internal_set_versionqualifier(const std::string& value);
  std::string* _internal_mutable_versionqualifier();
  public:

  // optional uint32 majorVersion = 3;
  bool has_majorversion() const;
  private:
  bool _internal_has_majorversion() const;
  public:
  void clear_majorversion();
  ::PROTOBUF_NAMESPACE_ID::uint32 majorversion() const;
  void set_majorversion(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_majorversion() const;
  void _internal_set_majorversion(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 minorVersion = 4;
  bool has_minorversion() const;
  private:
  bool _internal_has_minorversion() const;
  public:
  void clear_minorversion();
  ::PROTOBUF_NAMESPACE_ID::uint32 minorversion() const;
  void set_minorversion(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_minorversion() const;
  void _internal_set_minorversion(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 patchVersion = 5;
  bool has_patchversion() const;
  private:
  bool _internal_has_patchversion() const;
  public:
  void clear_patchversion();
  ::PROTOBUF_NAMESPACE_ID::uint32 patchversion() const;
  void set_patchversion(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_patchversion() const;
  void _internal_set_patchversion(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 buildNumber = 7;
  bool has_buildnumber() const;
  private:
  bool _internal_has_buildnumber() const;
  public:
  void clear_buildnumber();
  ::PROTOBUF_NAMESPACE_ID::uint32 buildnumber() const;
  void set_buildnumber(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_buildnumber() const;
  void _internal_set_buildnumber(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.RpcEndpointInfos)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr version_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr application_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr versionqualifier_;
  ::PROTOBUF_NAMESPACE_ID::uint32 majorversion_;
  ::PROTOBUF_NAMESPACE_ID::uint32 minorversion_;
  ::PROTOBUF_NAMESPACE_ID::uint32 patchversion_;
  ::PROTOBUF_NAMESPACE_ID::uint32 buildnumber_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class UserToBitHandshake PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.UserToBitHandshake) */ {
 public:
  inline UserToBitHandshake() : UserToBitHandshake(nullptr) {}
  ~UserToBitHandshake() override;
  explicit constexpr UserToBitHandshake(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  UserToBitHandshake(const UserToBitHandshake& from);
  UserToBitHandshake(UserToBitHandshake&& from) noexcept
    : UserToBitHandshake() {
    *this = ::std::move(from);
  }

  inline UserToBitHandshake& operator=(const UserToBitHandshake& from) {
    CopyFrom(from);
    return *this;
  }
  inline UserToBitHandshake& operator=(UserToBitHandshake&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const UserToBitHandshake& default_instance() {
    return *internal_default_instance();
  }
  static inline const UserToBitHandshake* internal_default_instance() {
    return reinterpret_cast<const UserToBitHandshake*>(
               &_UserToBitHandshake_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  friend void swap(UserToBitHandshake& a, UserToBitHandshake& b) {
    a.Swap(&b);
  }
  inline void Swap(UserToBitHandshake* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(UserToBitHandshake* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline UserToBitHandshake* New() const final {
    return CreateMaybeMessage<UserToBitHandshake>(nullptr);
  }

  UserToBitHandshake* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<UserToBitHandshake>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const UserToBitHandshake& from);
  void MergeFrom(const UserToBitHandshake& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(UserToBitHandshake* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.UserToBitHandshake";
  }
  protected:
  explicit UserToBitHandshake(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCredentialsFieldNumber = 4,
    kPropertiesFieldNumber = 5,
    kClientInfosFieldNumber = 8,
    kRpcVersionFieldNumber = 3,
    kSupportListeningFieldNumber = 2,
    kSupportComplexTypesFieldNumber = 6,
    kSupportTimeoutFieldNumber = 7,
    kSaslSupportFieldNumber = 9,
    kChannelFieldNumber = 1,
  };
  // optional .exec.shared.UserCredentials credentials = 4;
  bool has_credentials() const;
  private:
  bool _internal_has_credentials() const;
  public:
  void clear_credentials();
  const ::exec::shared::UserCredentials& credentials() const;
  ::exec::shared::UserCredentials* release_credentials();
  ::exec::shared::UserCredentials* mutable_credentials();
  void set_allocated_credentials(::exec::shared::UserCredentials* credentials);
  private:
  const ::exec::shared::UserCredentials& _internal_credentials() const;
  ::exec::shared::UserCredentials* _internal_mutable_credentials();
  public:
  void unsafe_arena_set_allocated_credentials(
      ::exec::shared::UserCredentials* credentials);
  ::exec::shared::UserCredentials* unsafe_arena_release_credentials();

  // optional .exec.user.UserProperties properties = 5;
  bool has_properties() const;
  private:
  bool _internal_has_properties() const;
  public:
  void clear_properties();
  const ::exec::user::UserProperties& properties() const;
  ::exec::user::UserProperties* release_properties();
  ::exec::user::UserProperties* mutable_properties();
  void set_allocated_properties(::exec::user::UserProperties* properties);
  private:
  const ::exec::user::UserProperties& _internal_properties() const;
  ::exec::user::UserProperties* _internal_mutable_properties();
  public:
  void unsafe_arena_set_allocated_properties(
      ::exec::user::UserProperties* properties);
  ::exec::user::UserProperties* unsafe_arena_release_properties();

  // optional .exec.user.RpcEndpointInfos client_infos = 8;
  bool has_client_infos() const;
  private:
  bool _internal_has_client_infos() const;
  public:
  void clear_client_infos();
  const ::exec::user::RpcEndpointInfos& client_infos() const;
  ::exec::user::RpcEndpointInfos* release_client_infos();
  ::exec::user::RpcEndpointInfos* mutable_client_infos();
  void set_allocated_client_infos(::exec::user::RpcEndpointInfos* client_infos);
  private:
  const ::exec::user::RpcEndpointInfos& _internal_client_infos() const;
  ::exec::user::RpcEndpointInfos* _internal_mutable_client_infos();
  public:
  void unsafe_arena_set_allocated_client_infos(
      ::exec::user::RpcEndpointInfos* client_infos);
  ::exec::user::RpcEndpointInfos* unsafe_arena_release_client_infos();

  // optional int32 rpc_version = 3;
  bool has_rpc_version() const;
  private:
  bool _internal_has_rpc_version() const;
  public:
  void clear_rpc_version();
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_version() const;
  void set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_rpc_version() const;
  void _internal_set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool support_listening = 2;
  bool has_support_listening() const;
  private:
  bool _internal_has_support_listening() const;
  public:
  void clear_support_listening();
  bool support_listening() const;
  void set_support_listening(bool value);
  private:
  bool _internal_support_listening() const;
  void _internal_set_support_listening(bool value);
  public:

  // optional bool support_complex_types = 6 [default = false];
  bool has_support_complex_types() const;
  private:
  bool _internal_has_support_complex_types() const;
  public:
  void clear_support_complex_types();
  bool support_complex_types() const;
  void set_support_complex_types(bool value);
  private:
  bool _internal_support_complex_types() const;
  void _internal_set_support_complex_types(bool value);
  public:

  // optional bool support_timeout = 7 [default = false];
  bool has_support_timeout() const;
  private:
  bool _internal_has_support_timeout() const;
  public:
  void clear_support_timeout();
  bool support_timeout() const;
  void set_support_timeout(bool value);
  private:
  bool _internal_support_timeout() const;
  void _internal_set_support_timeout(bool value);
  public:

  // optional .exec.user.SaslSupport sasl_support = 9;
  bool has_sasl_support() const;
  private:
  bool _internal_has_sasl_support() const;
  public:
  void clear_sasl_support();
  ::exec::user::SaslSupport sasl_support() const;
  void set_sasl_support(::exec::user::SaslSupport value);
  private:
  ::exec::user::SaslSupport _internal_sasl_support() const;
  void _internal_set_sasl_support(::exec::user::SaslSupport value);
  public:

  // optional .exec.shared.RpcChannel channel = 1 [default = USER];
  bool has_channel() const;
  private:
  bool _internal_has_channel() const;
  public:
  void clear_channel();
  ::exec::shared::RpcChannel channel() const;
  void set_channel(::exec::shared::RpcChannel value);
  private:
  ::exec::shared::RpcChannel _internal_channel() const;
  void _internal_set_channel(::exec::shared::RpcChannel value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.UserToBitHandshake)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::shared::UserCredentials* credentials_;
  ::exec::user::UserProperties* properties_;
  ::exec::user::RpcEndpointInfos* client_infos_;
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_version_;
  bool support_listening_;
  bool support_complex_types_;
  bool support_timeout_;
  int sasl_support_;
  int channel_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class RequestResults PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.RequestResults) */ {
 public:
  inline RequestResults() : RequestResults(nullptr) {}
  ~RequestResults() override;
  explicit constexpr RequestResults(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  RequestResults(const RequestResults& from);
  RequestResults(RequestResults&& from) noexcept
    : RequestResults() {
    *this = ::std::move(from);
  }

  inline RequestResults& operator=(const RequestResults& from) {
    CopyFrom(from);
    return *this;
  }
  inline RequestResults& operator=(RequestResults&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const RequestResults& default_instance() {
    return *internal_default_instance();
  }
  static inline const RequestResults* internal_default_instance() {
    return reinterpret_cast<const RequestResults*>(
               &_RequestResults_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  friend void swap(RequestResults& a, RequestResults& b) {
    a.Swap(&b);
  }
  inline void Swap(RequestResults* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(RequestResults* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline RequestResults* New() const final {
    return CreateMaybeMessage<RequestResults>(nullptr);
  }

  RequestResults* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<RequestResults>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const RequestResults& from);
  void MergeFrom(const RequestResults& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RequestResults* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.RequestResults";
  }
  protected:
  explicit RequestResults(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kQueryIdFieldNumber = 1,
    kMaximumResponsesFieldNumber = 2,
  };
  // optional .exec.shared.QueryId query_id = 1;
  bool has_query_id() const;
  private:
  bool _internal_has_query_id() const;
  public:
  void clear_query_id();
  const ::exec::shared::QueryId& query_id() const;
  ::exec::shared::QueryId* release_query_id();
  ::exec::shared::QueryId* mutable_query_id();
  void set_allocated_query_id(::exec::shared::QueryId* query_id);
  private:
  const ::exec::shared::QueryId& _internal_query_id() const;
  ::exec::shared::QueryId* _internal_mutable_query_id();
  public:
  void unsafe_arena_set_allocated_query_id(
      ::exec::shared::QueryId* query_id);
  ::exec::shared::QueryId* unsafe_arena_release_query_id();

  // optional int32 maximum_responses = 2;
  bool has_maximum_responses() const;
  private:
  bool _internal_has_maximum_responses() const;
  public:
  void clear_maximum_responses();
  ::PROTOBUF_NAMESPACE_ID::int32 maximum_responses() const;
  void set_maximum_responses(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_maximum_responses() const;
  void _internal_set_maximum_responses(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.RequestResults)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::shared::QueryId* query_id_;
  ::PROTOBUF_NAMESPACE_ID::int32 maximum_responses_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetQueryPlanFragments PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetQueryPlanFragments) */ {
 public:
  inline GetQueryPlanFragments() : GetQueryPlanFragments(nullptr) {}
  ~GetQueryPlanFragments() override;
  explicit constexpr GetQueryPlanFragments(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetQueryPlanFragments(const GetQueryPlanFragments& from);
  GetQueryPlanFragments(GetQueryPlanFragments&& from) noexcept
    : GetQueryPlanFragments() {
    *this = ::std::move(from);
  }

  inline GetQueryPlanFragments& operator=(const GetQueryPlanFragments& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetQueryPlanFragments& operator=(GetQueryPlanFragments&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetQueryPlanFragments& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetQueryPlanFragments* internal_default_instance() {
    return reinterpret_cast<const GetQueryPlanFragments*>(
               &_GetQueryPlanFragments_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    5;

  friend void swap(GetQueryPlanFragments& a, GetQueryPlanFragments& b) {
    a.Swap(&b);
  }
  inline void Swap(GetQueryPlanFragments* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetQueryPlanFragments* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetQueryPlanFragments* New() const final {
    return CreateMaybeMessage<GetQueryPlanFragments>(nullptr);
  }

  GetQueryPlanFragments* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetQueryPlanFragments>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetQueryPlanFragments& from);
  void MergeFrom(const GetQueryPlanFragments& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetQueryPlanFragments* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetQueryPlanFragments";
  }
  protected:
  explicit GetQueryPlanFragments(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kQueryFieldNumber = 1,
    kSplitPlanFieldNumber = 3,
    kTypeFieldNumber = 2,
  };
  // required string query = 1;
  bool has_query() const;
  private:
  bool _internal_has_query() const;
  public:
  void clear_query();
  const std::string& query() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_query(ArgT0&& arg0, ArgT... args);
  std::string* mutable_query();
  std::string* release_query();
  void set_allocated_query(std::string* query);
  private:
  const std::string& _internal_query() const;
  void _internal_set_query(const std::string& value);
  std::string* _internal_mutable_query();
  public:

  // optional bool split_plan = 3 [default = false];
  bool has_split_plan() const;
  private:
  bool _internal_has_split_plan() const;
  public:
  void clear_split_plan();
  bool split_plan() const;
  void set_split_plan(bool value);
  private:
  bool _internal_split_plan() const;
  void _internal_set_split_plan(bool value);
  public:

  // optional .exec.shared.QueryType type = 2;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  ::exec::shared::QueryType type() const;
  void set_type(::exec::shared::QueryType value);
  private:
  ::exec::shared::QueryType _internal_type() const;
  void _internal_set_type(::exec::shared::QueryType value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.GetQueryPlanFragments)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr query_;
  bool split_plan_;
  int type_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class QueryPlanFragments PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.QueryPlanFragments) */ {
 public:
  inline QueryPlanFragments() : QueryPlanFragments(nullptr) {}
  ~QueryPlanFragments() override;
  explicit constexpr QueryPlanFragments(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  QueryPlanFragments(const QueryPlanFragments& from);
  QueryPlanFragments(QueryPlanFragments&& from) noexcept
    : QueryPlanFragments() {
    *this = ::std::move(from);
  }

  inline QueryPlanFragments& operator=(const QueryPlanFragments& from) {
    CopyFrom(from);
    return *this;
  }
  inline QueryPlanFragments& operator=(QueryPlanFragments&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const QueryPlanFragments& default_instance() {
    return *internal_default_instance();
  }
  static inline const QueryPlanFragments* internal_default_instance() {
    return reinterpret_cast<const QueryPlanFragments*>(
               &_QueryPlanFragments_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    6;

  friend void swap(QueryPlanFragments& a, QueryPlanFragments& b) {
    a.Swap(&b);
  }
  inline void Swap(QueryPlanFragments* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(QueryPlanFragments* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline QueryPlanFragments* New() const final {
    return CreateMaybeMessage<QueryPlanFragments>(nullptr);
  }

  QueryPlanFragments* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<QueryPlanFragments>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const QueryPlanFragments& from);
  void MergeFrom(const QueryPlanFragments& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(QueryPlanFragments* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.QueryPlanFragments";
  }
  protected:
  explicit QueryPlanFragments(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kFragmentsFieldNumber = 3,
    kQueryIdFieldNumber = 2,
    kErrorFieldNumber = 4,
    kStatusFieldNumber = 1,
  };
  // repeated .exec.bit.control.PlanFragment fragments = 3;
  int fragments_size() const;
  private:
  int _internal_fragments_size() const;
  public:
  void clear_fragments();
  ::exec::bit::control::PlanFragment* mutable_fragments(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >*
      mutable_fragments();
  private:
  const ::exec::bit::control::PlanFragment& _internal_fragments(int index) const;
  ::exec::bit::control::PlanFragment* _internal_add_fragments();
  public:
  const ::exec::bit::control::PlanFragment& fragments(int index) const;
  ::exec::bit::control::PlanFragment* add_fragments();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >&
      fragments() const;

  // optional .exec.shared.QueryId query_id = 2;
  bool has_query_id() const;
  private:
  bool _internal_has_query_id() const;
  public:
  void clear_query_id();
  const ::exec::shared::QueryId& query_id() const;
  ::exec::shared::QueryId* release_query_id();
  ::exec::shared::QueryId* mutable_query_id();
  void set_allocated_query_id(::exec::shared::QueryId* query_id);
  private:
  const ::exec::shared::QueryId& _internal_query_id() const;
  ::exec::shared::QueryId* _internal_mutable_query_id();
  public:
  void unsafe_arena_set_allocated_query_id(
      ::exec::shared::QueryId* query_id);
  ::exec::shared::QueryId* unsafe_arena_release_query_id();

  // optional .exec.shared.DrillPBError error = 4;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // required .exec.shared.QueryResult.QueryState status = 1;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::shared::QueryResult_QueryState status() const;
  void set_status(::exec::shared::QueryResult_QueryState value);
  private:
  ::exec::shared::QueryResult_QueryState _internal_status() const;
  void _internal_set_status(::exec::shared::QueryResult_QueryState value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.QueryPlanFragments)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment > fragments_;
  ::exec::shared::QueryId* query_id_;
  ::exec::shared::DrillPBError* error_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class BitToUserHandshake PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.BitToUserHandshake) */ {
 public:
  inline BitToUserHandshake() : BitToUserHandshake(nullptr) {}
  ~BitToUserHandshake() override;
  explicit constexpr BitToUserHandshake(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  BitToUserHandshake(const BitToUserHandshake& from);
  BitToUserHandshake(BitToUserHandshake&& from) noexcept
    : BitToUserHandshake() {
    *this = ::std::move(from);
  }

  inline BitToUserHandshake& operator=(const BitToUserHandshake& from) {
    CopyFrom(from);
    return *this;
  }
  inline BitToUserHandshake& operator=(BitToUserHandshake&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const BitToUserHandshake& default_instance() {
    return *internal_default_instance();
  }
  static inline const BitToUserHandshake* internal_default_instance() {
    return reinterpret_cast<const BitToUserHandshake*>(
               &_BitToUserHandshake_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    7;

  friend void swap(BitToUserHandshake& a, BitToUserHandshake& b) {
    a.Swap(&b);
  }
  inline void Swap(BitToUserHandshake* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(BitToUserHandshake* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline BitToUserHandshake* New() const final {
    return CreateMaybeMessage<BitToUserHandshake>(nullptr);
  }

  BitToUserHandshake* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<BitToUserHandshake>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const BitToUserHandshake& from);
  void MergeFrom(const BitToUserHandshake& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(BitToUserHandshake* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.BitToUserHandshake";
  }
  protected:
  explicit BitToUserHandshake(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kAuthenticationMechanismsFieldNumber = 7,
    kSupportedMethodsFieldNumber = 8,
    kErrorIdFieldNumber = 4,
    kErrorMessageFieldNumber = 5,
    kServerInfosFieldNumber = 6,
    kRpcVersionFieldNumber = 2,
    kEncryptedFieldNumber = 9,
    kMaxWrappedSizeFieldNumber = 10,
    kStatusFieldNumber = 3,
  };
  // repeated string authenticationMechanisms = 7;
  int authenticationmechanisms_size() const;
  private:
  int _internal_authenticationmechanisms_size() const;
  public:
  void clear_authenticationmechanisms();
  const std::string& authenticationmechanisms(int index) const;
  std::string* mutable_authenticationmechanisms(int index);
  void set_authenticationmechanisms(int index, const std::string& value);
  void set_authenticationmechanisms(int index, std::string&& value);
  void set_authenticationmechanisms(int index, const char* value);
  void set_authenticationmechanisms(int index, const char* value, size_t size);
  std::string* add_authenticationmechanisms();
  void add_authenticationmechanisms(const std::string& value);
  void add_authenticationmechanisms(std::string&& value);
  void add_authenticationmechanisms(const char* value);
  void add_authenticationmechanisms(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& authenticationmechanisms() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_authenticationmechanisms();
  private:
  const std::string& _internal_authenticationmechanisms(int index) const;
  std::string* _internal_add_authenticationmechanisms();
  public:

  // repeated .exec.user.RpcType supported_methods = 8;
  int supported_methods_size() const;
  private:
  int _internal_supported_methods_size() const;
  public:
  void clear_supported_methods();
  private:
  ::exec::user::RpcType _internal_supported_methods(int index) const;
  void _internal_add_supported_methods(::exec::user::RpcType value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_supported_methods();
  public:
  ::exec::user::RpcType supported_methods(int index) const;
  void set_supported_methods(int index, ::exec::user::RpcType value);
  void add_supported_methods(::exec::user::RpcType value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& supported_methods() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_supported_methods();

  // optional string errorId = 4;
  bool has_errorid() const;
  private:
  bool _internal_has_errorid() const;
  public:
  void clear_errorid();
  const std::string& errorid() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_errorid(ArgT0&& arg0, ArgT... args);
  std::string* mutable_errorid();
  std::string* release_errorid();
  void set_allocated_errorid(std::string* errorid);
  private:
  const std::string& _internal_errorid() const;
  void _internal_set_errorid(const std::string& value);
  std::string* _internal_mutable_errorid();
  public:

  // optional string errorMessage = 5;
  bool has_errormessage() const;
  private:
  bool _internal_has_errormessage() const;
  public:
  void clear_errormessage();
  const std::string& errormessage() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_errormessage(ArgT0&& arg0, ArgT... args);
  std::string* mutable_errormessage();
  std::string* release_errormessage();
  void set_allocated_errormessage(std::string* errormessage);
  private:
  const std::string& _internal_errormessage() const;
  void _internal_set_errormessage(const std::string& value);
  std::string* _internal_mutable_errormessage();
  public:

  // optional .exec.user.RpcEndpointInfos server_infos = 6;
  bool has_server_infos() const;
  private:
  bool _internal_has_server_infos() const;
  public:
  void clear_server_infos();
  const ::exec::user::RpcEndpointInfos& server_infos() const;
  ::exec::user::RpcEndpointInfos* release_server_infos();
  ::exec::user::RpcEndpointInfos* mutable_server_infos();
  void set_allocated_server_infos(::exec::user::RpcEndpointInfos* server_infos);
  private:
  const ::exec::user::RpcEndpointInfos& _internal_server_infos() const;
  ::exec::user::RpcEndpointInfos* _internal_mutable_server_infos();
  public:
  void unsafe_arena_set_allocated_server_infos(
      ::exec::user::RpcEndpointInfos* server_infos);
  ::exec::user::RpcEndpointInfos* unsafe_arena_release_server_infos();

  // optional int32 rpc_version = 2;
  bool has_rpc_version() const;
  private:
  bool _internal_has_rpc_version() const;
  public:
  void clear_rpc_version();
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_version() const;
  void set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_rpc_version() const;
  void _internal_set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool encrypted = 9;
  bool has_encrypted() const;
  private:
  bool _internal_has_encrypted() const;
  public:
  void clear_encrypted();
  bool encrypted() const;
  void set_encrypted(bool value);
  private:
  bool _internal_encrypted() const;
  void _internal_set_encrypted(bool value);
  public:

  // optional int32 maxWrappedSize = 10;
  bool has_maxwrappedsize() const;
  private:
  bool _internal_has_maxwrappedsize() const;
  public:
  void clear_maxwrappedsize();
  ::PROTOBUF_NAMESPACE_ID::int32 maxwrappedsize() const;
  void set_maxwrappedsize(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_maxwrappedsize() const;
  void _internal_set_maxwrappedsize(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional .exec.user.HandshakeStatus status = 3;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::user::HandshakeStatus status() const;
  void set_status(::exec::user::HandshakeStatus value);
  private:
  ::exec::user::HandshakeStatus _internal_status() const;
  void _internal_set_status(::exec::user::HandshakeStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.BitToUserHandshake)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> authenticationmechanisms_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> supported_methods_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr errorid_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr errormessage_;
  ::exec::user::RpcEndpointInfos* server_infos_;
  ::PROTOBUF_NAMESPACE_ID::int32 rpc_version_;
  bool encrypted_;
  ::PROTOBUF_NAMESPACE_ID::int32 maxwrappedsize_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class LikeFilter PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.LikeFilter) */ {
 public:
  inline LikeFilter() : LikeFilter(nullptr) {}
  ~LikeFilter() override;
  explicit constexpr LikeFilter(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  LikeFilter(const LikeFilter& from);
  LikeFilter(LikeFilter&& from) noexcept
    : LikeFilter() {
    *this = ::std::move(from);
  }

  inline LikeFilter& operator=(const LikeFilter& from) {
    CopyFrom(from);
    return *this;
  }
  inline LikeFilter& operator=(LikeFilter&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const LikeFilter& default_instance() {
    return *internal_default_instance();
  }
  static inline const LikeFilter* internal_default_instance() {
    return reinterpret_cast<const LikeFilter*>(
               &_LikeFilter_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    8;

  friend void swap(LikeFilter& a, LikeFilter& b) {
    a.Swap(&b);
  }
  inline void Swap(LikeFilter* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(LikeFilter* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline LikeFilter* New() const final {
    return CreateMaybeMessage<LikeFilter>(nullptr);
  }

  LikeFilter* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<LikeFilter>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const LikeFilter& from);
  void MergeFrom(const LikeFilter& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(LikeFilter* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.LikeFilter";
  }
  protected:
  explicit LikeFilter(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kPatternFieldNumber = 1,
    kEscapeFieldNumber = 2,
  };
  // optional string pattern = 1;
  bool has_pattern() const;
  private:
  bool _internal_has_pattern() const;
  public:
  void clear_pattern();
  const std::string& pattern() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_pattern(ArgT0&& arg0, ArgT... args);
  std::string* mutable_pattern();
  std::string* release_pattern();
  void set_allocated_pattern(std::string* pattern);
  private:
  const std::string& _internal_pattern() const;
  void _internal_set_pattern(const std::string& value);
  std::string* _internal_mutable_pattern();
  public:

  // optional string escape = 2;
  bool has_escape() const;
  private:
  bool _internal_has_escape() const;
  public:
  void clear_escape();
  const std::string& escape() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_escape(ArgT0&& arg0, ArgT... args);
  std::string* mutable_escape();
  std::string* release_escape();
  void set_allocated_escape(std::string* escape);
  private:
  const std::string& _internal_escape() const;
  void _internal_set_escape(const std::string& value);
  std::string* _internal_mutable_escape();
  public:

  // @@protoc_insertion_point(class_scope:exec.user.LikeFilter)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr pattern_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr escape_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetCatalogsReq PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetCatalogsReq) */ {
 public:
  inline GetCatalogsReq() : GetCatalogsReq(nullptr) {}
  ~GetCatalogsReq() override;
  explicit constexpr GetCatalogsReq(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetCatalogsReq(const GetCatalogsReq& from);
  GetCatalogsReq(GetCatalogsReq&& from) noexcept
    : GetCatalogsReq() {
    *this = ::std::move(from);
  }

  inline GetCatalogsReq& operator=(const GetCatalogsReq& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetCatalogsReq& operator=(GetCatalogsReq&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetCatalogsReq& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetCatalogsReq* internal_default_instance() {
    return reinterpret_cast<const GetCatalogsReq*>(
               &_GetCatalogsReq_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    9;

  friend void swap(GetCatalogsReq& a, GetCatalogsReq& b) {
    a.Swap(&b);
  }
  inline void Swap(GetCatalogsReq* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetCatalogsReq* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetCatalogsReq* New() const final {
    return CreateMaybeMessage<GetCatalogsReq>(nullptr);
  }

  GetCatalogsReq* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetCatalogsReq>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetCatalogsReq& from);
  void MergeFrom(const GetCatalogsReq& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetCatalogsReq* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetCatalogsReq";
  }
  protected:
  explicit GetCatalogsReq(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFilterFieldNumber = 1,
  };
  // optional .exec.user.LikeFilter catalog_name_filter = 1;
  bool has_catalog_name_filter() const;
  private:
  bool _internal_has_catalog_name_filter() const;
  public:
  void clear_catalog_name_filter();
  const ::exec::user::LikeFilter& catalog_name_filter() const;
  ::exec::user::LikeFilter* release_catalog_name_filter();
  ::exec::user::LikeFilter* mutable_catalog_name_filter();
  void set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_catalog_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_catalog_name_filter();
  public:
  void unsafe_arena_set_allocated_catalog_name_filter(
      ::exec::user::LikeFilter* catalog_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_catalog_name_filter();

  // @@protoc_insertion_point(class_scope:exec.user.GetCatalogsReq)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::user::LikeFilter* catalog_name_filter_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class CatalogMetadata PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.CatalogMetadata) */ {
 public:
  inline CatalogMetadata() : CatalogMetadata(nullptr) {}
  ~CatalogMetadata() override;
  explicit constexpr CatalogMetadata(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  CatalogMetadata(const CatalogMetadata& from);
  CatalogMetadata(CatalogMetadata&& from) noexcept
    : CatalogMetadata() {
    *this = ::std::move(from);
  }

  inline CatalogMetadata& operator=(const CatalogMetadata& from) {
    CopyFrom(from);
    return *this;
  }
  inline CatalogMetadata& operator=(CatalogMetadata&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CatalogMetadata& default_instance() {
    return *internal_default_instance();
  }
  static inline const CatalogMetadata* internal_default_instance() {
    return reinterpret_cast<const CatalogMetadata*>(
               &_CatalogMetadata_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    10;

  friend void swap(CatalogMetadata& a, CatalogMetadata& b) {
    a.Swap(&b);
  }
  inline void Swap(CatalogMetadata* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CatalogMetadata* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline CatalogMetadata* New() const final {
    return CreateMaybeMessage<CatalogMetadata>(nullptr);
  }

  CatalogMetadata* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<CatalogMetadata>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const CatalogMetadata& from);
  void MergeFrom(const CatalogMetadata& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(CatalogMetadata* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.CatalogMetadata";
  }
  protected:
  explicit CatalogMetadata(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFieldNumber = 1,
    kDescriptionFieldNumber = 2,
    kConnectFieldNumber = 3,
  };
  // optional string catalog_name = 1;
  bool has_catalog_name() const;
  private:
  bool _internal_has_catalog_name() const;
  public:
  void clear_catalog_name();
  const std::string& catalog_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_catalog_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_catalog_name();
  std::string* release_catalog_name();
  void set_allocated_catalog_name(std::string* catalog_name);
  private:
  const std::string& _internal_catalog_name() const;
  void _internal_set_catalog_name(const std::string& value);
  std::string* _internal_mutable_catalog_name();
  public:

  // optional string description = 2;
  bool has_description() const;
  private:
  bool _internal_has_description() const;
  public:
  void clear_description();
  const std::string& description() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_description(ArgT0&& arg0, ArgT... args);
  std::string* mutable_description();
  std::string* release_description();
  void set_allocated_description(std::string* description);
  private:
  const std::string& _internal_description() const;
  void _internal_set_description(const std::string& value);
  std::string* _internal_mutable_description();
  public:

  // optional string connect = 3;
  bool has_connect() const;
  private:
  bool _internal_has_connect() const;
  public:
  void clear_connect();
  const std::string& connect() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_connect(ArgT0&& arg0, ArgT... args);
  std::string* mutable_connect();
  std::string* release_connect();
  void set_allocated_connect(std::string* connect);
  private:
  const std::string& _internal_connect() const;
  void _internal_set_connect(const std::string& value);
  std::string* _internal_mutable_connect();
  public:

  // @@protoc_insertion_point(class_scope:exec.user.CatalogMetadata)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr catalog_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr description_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr connect_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetCatalogsResp PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetCatalogsResp) */ {
 public:
  inline GetCatalogsResp() : GetCatalogsResp(nullptr) {}
  ~GetCatalogsResp() override;
  explicit constexpr GetCatalogsResp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetCatalogsResp(const GetCatalogsResp& from);
  GetCatalogsResp(GetCatalogsResp&& from) noexcept
    : GetCatalogsResp() {
    *this = ::std::move(from);
  }

  inline GetCatalogsResp& operator=(const GetCatalogsResp& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetCatalogsResp& operator=(GetCatalogsResp&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetCatalogsResp& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetCatalogsResp* internal_default_instance() {
    return reinterpret_cast<const GetCatalogsResp*>(
               &_GetCatalogsResp_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    11;

  friend void swap(GetCatalogsResp& a, GetCatalogsResp& b) {
    a.Swap(&b);
  }
  inline void Swap(GetCatalogsResp* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetCatalogsResp* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetCatalogsResp* New() const final {
    return CreateMaybeMessage<GetCatalogsResp>(nullptr);
  }

  GetCatalogsResp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetCatalogsResp>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetCatalogsResp& from);
  void MergeFrom(const GetCatalogsResp& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetCatalogsResp* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetCatalogsResp";
  }
  protected:
  explicit GetCatalogsResp(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogsFieldNumber = 2,
    kErrorFieldNumber = 3,
    kStatusFieldNumber = 1,
  };
  // repeated .exec.user.CatalogMetadata catalogs = 2;
  int catalogs_size() const;
  private:
  int _internal_catalogs_size() const;
  public:
  void clear_catalogs();
  ::exec::user::CatalogMetadata* mutable_catalogs(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::CatalogMetadata >*
      mutable_catalogs();
  private:
  const ::exec::user::CatalogMetadata& _internal_catalogs(int index) const;
  ::exec::user::CatalogMetadata* _internal_add_catalogs();
  public:
  const ::exec::user::CatalogMetadata& catalogs(int index) const;
  ::exec::user::CatalogMetadata* add_catalogs();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::CatalogMetadata >&
      catalogs() const;

  // optional .exec.shared.DrillPBError error = 3;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // optional .exec.user.RequestStatus status = 1;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::user::RequestStatus status() const;
  void set_status(::exec::user::RequestStatus value);
  private:
  ::exec::user::RequestStatus _internal_status() const;
  void _internal_set_status(::exec::user::RequestStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.GetCatalogsResp)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::CatalogMetadata > catalogs_;
  ::exec::shared::DrillPBError* error_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetSchemasReq PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetSchemasReq) */ {
 public:
  inline GetSchemasReq() : GetSchemasReq(nullptr) {}
  ~GetSchemasReq() override;
  explicit constexpr GetSchemasReq(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetSchemasReq(const GetSchemasReq& from);
  GetSchemasReq(GetSchemasReq&& from) noexcept
    : GetSchemasReq() {
    *this = ::std::move(from);
  }

  inline GetSchemasReq& operator=(const GetSchemasReq& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetSchemasReq& operator=(GetSchemasReq&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetSchemasReq& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetSchemasReq* internal_default_instance() {
    return reinterpret_cast<const GetSchemasReq*>(
               &_GetSchemasReq_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    12;

  friend void swap(GetSchemasReq& a, GetSchemasReq& b) {
    a.Swap(&b);
  }
  inline void Swap(GetSchemasReq* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetSchemasReq* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetSchemasReq* New() const final {
    return CreateMaybeMessage<GetSchemasReq>(nullptr);
  }

  GetSchemasReq* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetSchemasReq>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetSchemasReq& from);
  void MergeFrom(const GetSchemasReq& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetSchemasReq* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetSchemasReq";
  }
  protected:
  explicit GetSchemasReq(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFilterFieldNumber = 1,
    kSchemaNameFilterFieldNumber = 2,
  };
  // optional .exec.user.LikeFilter catalog_name_filter = 1;
  bool has_catalog_name_filter() const;
  private:
  bool _internal_has_catalog_name_filter() const;
  public:
  void clear_catalog_name_filter();
  const ::exec::user::LikeFilter& catalog_name_filter() const;
  ::exec::user::LikeFilter* release_catalog_name_filter();
  ::exec::user::LikeFilter* mutable_catalog_name_filter();
  void set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_catalog_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_catalog_name_filter();
  public:
  void unsafe_arena_set_allocated_catalog_name_filter(
      ::exec::user::LikeFilter* catalog_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_catalog_name_filter();

  // optional .exec.user.LikeFilter schema_name_filter = 2;
  bool has_schema_name_filter() const;
  private:
  bool _internal_has_schema_name_filter() const;
  public:
  void clear_schema_name_filter();
  const ::exec::user::LikeFilter& schema_name_filter() const;
  ::exec::user::LikeFilter* release_schema_name_filter();
  ::exec::user::LikeFilter* mutable_schema_name_filter();
  void set_allocated_schema_name_filter(::exec::user::LikeFilter* schema_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_schema_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_schema_name_filter();
  public:
  void unsafe_arena_set_allocated_schema_name_filter(
      ::exec::user::LikeFilter* schema_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_schema_name_filter();

  // @@protoc_insertion_point(class_scope:exec.user.GetSchemasReq)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::user::LikeFilter* catalog_name_filter_;
  ::exec::user::LikeFilter* schema_name_filter_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class SchemaMetadata PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.SchemaMetadata) */ {
 public:
  inline SchemaMetadata() : SchemaMetadata(nullptr) {}
  ~SchemaMetadata() override;
  explicit constexpr SchemaMetadata(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  SchemaMetadata(const SchemaMetadata& from);
  SchemaMetadata(SchemaMetadata&& from) noexcept
    : SchemaMetadata() {
    *this = ::std::move(from);
  }

  inline SchemaMetadata& operator=(const SchemaMetadata& from) {
    CopyFrom(from);
    return *this;
  }
  inline SchemaMetadata& operator=(SchemaMetadata&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const SchemaMetadata& default_instance() {
    return *internal_default_instance();
  }
  static inline const SchemaMetadata* internal_default_instance() {
    return reinterpret_cast<const SchemaMetadata*>(
               &_SchemaMetadata_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    13;

  friend void swap(SchemaMetadata& a, SchemaMetadata& b) {
    a.Swap(&b);
  }
  inline void Swap(SchemaMetadata* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(SchemaMetadata* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline SchemaMetadata* New() const final {
    return CreateMaybeMessage<SchemaMetadata>(nullptr);
  }

  SchemaMetadata* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<SchemaMetadata>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const SchemaMetadata& from);
  void MergeFrom(const SchemaMetadata& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(SchemaMetadata* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.SchemaMetadata";
  }
  protected:
  explicit SchemaMetadata(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFieldNumber = 1,
    kSchemaNameFieldNumber = 2,
    kOwnerFieldNumber = 3,
    kTypeFieldNumber = 4,
    kMutableFieldNumber = 5,
  };
  // optional string catalog_name = 1;
  bool has_catalog_name() const;
  private:
  bool _internal_has_catalog_name() const;
  public:
  void clear_catalog_name();
  const std::string& catalog_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_catalog_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_catalog_name();
  std::string* release_catalog_name();
  void set_allocated_catalog_name(std::string* catalog_name);
  private:
  const std::string& _internal_catalog_name() const;
  void _internal_set_catalog_name(const std::string& value);
  std::string* _internal_mutable_catalog_name();
  public:

  // optional string schema_name = 2;
  bool has_schema_name() const;
  private:
  bool _internal_has_schema_name() const;
  public:
  void clear_schema_name();
  const std::string& schema_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_schema_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_schema_name();
  std::string* release_schema_name();
  void set_allocated_schema_name(std::string* schema_name);
  private:
  const std::string& _internal_schema_name() const;
  void _internal_set_schema_name(const std::string& value);
  std::string* _internal_mutable_schema_name();
  public:

  // optional string owner = 3;
  bool has_owner() const;
  private:
  bool _internal_has_owner() const;
  public:
  void clear_owner();
  const std::string& owner() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_owner(ArgT0&& arg0, ArgT... args);
  std::string* mutable_owner();
  std::string* release_owner();
  void set_allocated_owner(std::string* owner);
  private:
  const std::string& _internal_owner() const;
  void _internal_set_owner(const std::string& value);
  std::string* _internal_mutable_owner();
  public:

  // optional string type = 4;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  const std::string& type() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_type(ArgT0&& arg0, ArgT... args);
  std::string* mutable_type();
  std::string* release_type();
  void set_allocated_type(std::string* type);
  private:
  const std::string& _internal_type() const;
  void _internal_set_type(const std::string& value);
  std::string* _internal_mutable_type();
  public:

  // optional string mutable = 5;
  bool has_mutable_() const;
  private:
  bool _internal_has_mutable_() const;
  public:
  void clear_mutable_();
  const std::string& mutable_() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_mutable_(ArgT0&& arg0, ArgT... args);
  std::string* mutable_mutable_();
  std::string* release_mutable_();
  void set_allocated_mutable_(std::string* mutable_);
  private:
  const std::string& _internal_mutable_() const;
  void _internal_set_mutable_(const std::string& value);
  std::string* _internal_mutable_mutable_();
  public:

  // @@protoc_insertion_point(class_scope:exec.user.SchemaMetadata)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr catalog_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr schema_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr owner_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr mutable__;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetSchemasResp PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetSchemasResp) */ {
 public:
  inline GetSchemasResp() : GetSchemasResp(nullptr) {}
  ~GetSchemasResp() override;
  explicit constexpr GetSchemasResp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetSchemasResp(const GetSchemasResp& from);
  GetSchemasResp(GetSchemasResp&& from) noexcept
    : GetSchemasResp() {
    *this = ::std::move(from);
  }

  inline GetSchemasResp& operator=(const GetSchemasResp& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetSchemasResp& operator=(GetSchemasResp&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetSchemasResp& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetSchemasResp* internal_default_instance() {
    return reinterpret_cast<const GetSchemasResp*>(
               &_GetSchemasResp_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    14;

  friend void swap(GetSchemasResp& a, GetSchemasResp& b) {
    a.Swap(&b);
  }
  inline void Swap(GetSchemasResp* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetSchemasResp* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetSchemasResp* New() const final {
    return CreateMaybeMessage<GetSchemasResp>(nullptr);
  }

  GetSchemasResp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetSchemasResp>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetSchemasResp& from);
  void MergeFrom(const GetSchemasResp& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetSchemasResp* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetSchemasResp";
  }
  protected:
  explicit GetSchemasResp(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kSchemasFieldNumber = 2,
    kErrorFieldNumber = 3,
    kStatusFieldNumber = 1,
  };
  // repeated .exec.user.SchemaMetadata schemas = 2;
  int schemas_size() const;
  private:
  int _internal_schemas_size() const;
  public:
  void clear_schemas();
  ::exec::user::SchemaMetadata* mutable_schemas(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::SchemaMetadata >*
      mutable_schemas();
  private:
  const ::exec::user::SchemaMetadata& _internal_schemas(int index) const;
  ::exec::user::SchemaMetadata* _internal_add_schemas();
  public:
  const ::exec::user::SchemaMetadata& schemas(int index) const;
  ::exec::user::SchemaMetadata* add_schemas();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::SchemaMetadata >&
      schemas() const;

  // optional .exec.shared.DrillPBError error = 3;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // optional .exec.user.RequestStatus status = 1;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::user::RequestStatus status() const;
  void set_status(::exec::user::RequestStatus value);
  private:
  ::exec::user::RequestStatus _internal_status() const;
  void _internal_set_status(::exec::user::RequestStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.GetSchemasResp)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::SchemaMetadata > schemas_;
  ::exec::shared::DrillPBError* error_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetTablesReq PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetTablesReq) */ {
 public:
  inline GetTablesReq() : GetTablesReq(nullptr) {}
  ~GetTablesReq() override;
  explicit constexpr GetTablesReq(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetTablesReq(const GetTablesReq& from);
  GetTablesReq(GetTablesReq&& from) noexcept
    : GetTablesReq() {
    *this = ::std::move(from);
  }

  inline GetTablesReq& operator=(const GetTablesReq& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetTablesReq& operator=(GetTablesReq&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetTablesReq& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetTablesReq* internal_default_instance() {
    return reinterpret_cast<const GetTablesReq*>(
               &_GetTablesReq_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    15;

  friend void swap(GetTablesReq& a, GetTablesReq& b) {
    a.Swap(&b);
  }
  inline void Swap(GetTablesReq* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetTablesReq* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetTablesReq* New() const final {
    return CreateMaybeMessage<GetTablesReq>(nullptr);
  }

  GetTablesReq* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetTablesReq>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetTablesReq& from);
  void MergeFrom(const GetTablesReq& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetTablesReq* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetTablesReq";
  }
  protected:
  explicit GetTablesReq(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kTableTypeFilterFieldNumber = 4,
    kCatalogNameFilterFieldNumber = 1,
    kSchemaNameFilterFieldNumber = 2,
    kTableNameFilterFieldNumber = 3,
  };
  // repeated string table_type_filter = 4;
  int table_type_filter_size() const;
  private:
  int _internal_table_type_filter_size() const;
  public:
  void clear_table_type_filter();
  const std::string& table_type_filter(int index) const;
  std::string* mutable_table_type_filter(int index);
  void set_table_type_filter(int index, const std::string& value);
  void set_table_type_filter(int index, std::string&& value);
  void set_table_type_filter(int index, const char* value);
  void set_table_type_filter(int index, const char* value, size_t size);
  std::string* add_table_type_filter();
  void add_table_type_filter(const std::string& value);
  void add_table_type_filter(std::string&& value);
  void add_table_type_filter(const char* value);
  void add_table_type_filter(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& table_type_filter() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_table_type_filter();
  private:
  const std::string& _internal_table_type_filter(int index) const;
  std::string* _internal_add_table_type_filter();
  public:

  // optional .exec.user.LikeFilter catalog_name_filter = 1;
  bool has_catalog_name_filter() const;
  private:
  bool _internal_has_catalog_name_filter() const;
  public:
  void clear_catalog_name_filter();
  const ::exec::user::LikeFilter& catalog_name_filter() const;
  ::exec::user::LikeFilter* release_catalog_name_filter();
  ::exec::user::LikeFilter* mutable_catalog_name_filter();
  void set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_catalog_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_catalog_name_filter();
  public:
  void unsafe_arena_set_allocated_catalog_name_filter(
      ::exec::user::LikeFilter* catalog_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_catalog_name_filter();

  // optional .exec.user.LikeFilter schema_name_filter = 2;
  bool has_schema_name_filter() const;
  private:
  bool _internal_has_schema_name_filter() const;
  public:
  void clear_schema_name_filter();
  const ::exec::user::LikeFilter& schema_name_filter() const;
  ::exec::user::LikeFilter* release_schema_name_filter();
  ::exec::user::LikeFilter* mutable_schema_name_filter();
  void set_allocated_schema_name_filter(::exec::user::LikeFilter* schema_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_schema_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_schema_name_filter();
  public:
  void unsafe_arena_set_allocated_schema_name_filter(
      ::exec::user::LikeFilter* schema_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_schema_name_filter();

  // optional .exec.user.LikeFilter table_name_filter = 3;
  bool has_table_name_filter() const;
  private:
  bool _internal_has_table_name_filter() const;
  public:
  void clear_table_name_filter();
  const ::exec::user::LikeFilter& table_name_filter() const;
  ::exec::user::LikeFilter* release_table_name_filter();
  ::exec::user::LikeFilter* mutable_table_name_filter();
  void set_allocated_table_name_filter(::exec::user::LikeFilter* table_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_table_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_table_name_filter();
  public:
  void unsafe_arena_set_allocated_table_name_filter(
      ::exec::user::LikeFilter* table_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_table_name_filter();

  // @@protoc_insertion_point(class_scope:exec.user.GetTablesReq)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> table_type_filter_;
  ::exec::user::LikeFilter* catalog_name_filter_;
  ::exec::user::LikeFilter* schema_name_filter_;
  ::exec::user::LikeFilter* table_name_filter_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class TableMetadata PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.TableMetadata) */ {
 public:
  inline TableMetadata() : TableMetadata(nullptr) {}
  ~TableMetadata() override;
  explicit constexpr TableMetadata(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  TableMetadata(const TableMetadata& from);
  TableMetadata(TableMetadata&& from) noexcept
    : TableMetadata() {
    *this = ::std::move(from);
  }

  inline TableMetadata& operator=(const TableMetadata& from) {
    CopyFrom(from);
    return *this;
  }
  inline TableMetadata& operator=(TableMetadata&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const TableMetadata& default_instance() {
    return *internal_default_instance();
  }
  static inline const TableMetadata* internal_default_instance() {
    return reinterpret_cast<const TableMetadata*>(
               &_TableMetadata_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    16;

  friend void swap(TableMetadata& a, TableMetadata& b) {
    a.Swap(&b);
  }
  inline void Swap(TableMetadata* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(TableMetadata* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline TableMetadata* New() const final {
    return CreateMaybeMessage<TableMetadata>(nullptr);
  }

  TableMetadata* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<TableMetadata>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const TableMetadata& from);
  void MergeFrom(const TableMetadata& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(TableMetadata* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.TableMetadata";
  }
  protected:
  explicit TableMetadata(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFieldNumber = 1,
    kSchemaNameFieldNumber = 2,
    kTableNameFieldNumber = 3,
    kTypeFieldNumber = 4,
  };
  // optional string catalog_name = 1;
  bool has_catalog_name() const;
  private:
  bool _internal_has_catalog_name() const;
  public:
  void clear_catalog_name();
  const std::string& catalog_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_catalog_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_catalog_name();
  std::string* release_catalog_name();
  void set_allocated_catalog_name(std::string* catalog_name);
  private:
  const std::string& _internal_catalog_name() const;
  void _internal_set_catalog_name(const std::string& value);
  std::string* _internal_mutable_catalog_name();
  public:

  // optional string schema_name = 2;
  bool has_schema_name() const;
  private:
  bool _internal_has_schema_name() const;
  public:
  void clear_schema_name();
  const std::string& schema_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_schema_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_schema_name();
  std::string* release_schema_name();
  void set_allocated_schema_name(std::string* schema_name);
  private:
  const std::string& _internal_schema_name() const;
  void _internal_set_schema_name(const std::string& value);
  std::string* _internal_mutable_schema_name();
  public:

  // optional string table_name = 3;
  bool has_table_name() const;
  private:
  bool _internal_has_table_name() const;
  public:
  void clear_table_name();
  const std::string& table_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_table_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_table_name();
  std::string* release_table_name();
  void set_allocated_table_name(std::string* table_name);
  private:
  const std::string& _internal_table_name() const;
  void _internal_set_table_name(const std::string& value);
  std::string* _internal_mutable_table_name();
  public:

  // optional string type = 4;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  const std::string& type() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_type(ArgT0&& arg0, ArgT... args);
  std::string* mutable_type();
  std::string* release_type();
  void set_allocated_type(std::string* type);
  private:
  const std::string& _internal_type() const;
  void _internal_set_type(const std::string& value);
  std::string* _internal_mutable_type();
  public:

  // @@protoc_insertion_point(class_scope:exec.user.TableMetadata)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr catalog_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr schema_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr table_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetTablesResp PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetTablesResp) */ {
 public:
  inline GetTablesResp() : GetTablesResp(nullptr) {}
  ~GetTablesResp() override;
  explicit constexpr GetTablesResp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetTablesResp(const GetTablesResp& from);
  GetTablesResp(GetTablesResp&& from) noexcept
    : GetTablesResp() {
    *this = ::std::move(from);
  }

  inline GetTablesResp& operator=(const GetTablesResp& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetTablesResp& operator=(GetTablesResp&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetTablesResp& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetTablesResp* internal_default_instance() {
    return reinterpret_cast<const GetTablesResp*>(
               &_GetTablesResp_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    17;

  friend void swap(GetTablesResp& a, GetTablesResp& b) {
    a.Swap(&b);
  }
  inline void Swap(GetTablesResp* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetTablesResp* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetTablesResp* New() const final {
    return CreateMaybeMessage<GetTablesResp>(nullptr);
  }

  GetTablesResp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetTablesResp>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetTablesResp& from);
  void MergeFrom(const GetTablesResp& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetTablesResp* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetTablesResp";
  }
  protected:
  explicit GetTablesResp(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kTablesFieldNumber = 2,
    kErrorFieldNumber = 3,
    kStatusFieldNumber = 1,
  };
  // repeated .exec.user.TableMetadata tables = 2;
  int tables_size() const;
  private:
  int _internal_tables_size() const;
  public:
  void clear_tables();
  ::exec::user::TableMetadata* mutable_tables(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::TableMetadata >*
      mutable_tables();
  private:
  const ::exec::user::TableMetadata& _internal_tables(int index) const;
  ::exec::user::TableMetadata* _internal_add_tables();
  public:
  const ::exec::user::TableMetadata& tables(int index) const;
  ::exec::user::TableMetadata* add_tables();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::TableMetadata >&
      tables() const;

  // optional .exec.shared.DrillPBError error = 3;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // optional .exec.user.RequestStatus status = 1;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::user::RequestStatus status() const;
  void set_status(::exec::user::RequestStatus value);
  private:
  ::exec::user::RequestStatus _internal_status() const;
  void _internal_set_status(::exec::user::RequestStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.GetTablesResp)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::TableMetadata > tables_;
  ::exec::shared::DrillPBError* error_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetColumnsReq PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetColumnsReq) */ {
 public:
  inline GetColumnsReq() : GetColumnsReq(nullptr) {}
  ~GetColumnsReq() override;
  explicit constexpr GetColumnsReq(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetColumnsReq(const GetColumnsReq& from);
  GetColumnsReq(GetColumnsReq&& from) noexcept
    : GetColumnsReq() {
    *this = ::std::move(from);
  }

  inline GetColumnsReq& operator=(const GetColumnsReq& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetColumnsReq& operator=(GetColumnsReq&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetColumnsReq& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetColumnsReq* internal_default_instance() {
    return reinterpret_cast<const GetColumnsReq*>(
               &_GetColumnsReq_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    18;

  friend void swap(GetColumnsReq& a, GetColumnsReq& b) {
    a.Swap(&b);
  }
  inline void Swap(GetColumnsReq* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetColumnsReq* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetColumnsReq* New() const final {
    return CreateMaybeMessage<GetColumnsReq>(nullptr);
  }

  GetColumnsReq* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetColumnsReq>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetColumnsReq& from);
  void MergeFrom(const GetColumnsReq& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetColumnsReq* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetColumnsReq";
  }
  protected:
  explicit GetColumnsReq(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFilterFieldNumber = 1,
    kSchemaNameFilterFieldNumber = 2,
    kTableNameFilterFieldNumber = 3,
    kColumnNameFilterFieldNumber = 4,
  };
  // optional .exec.user.LikeFilter catalog_name_filter = 1;
  bool has_catalog_name_filter() const;
  private:
  bool _internal_has_catalog_name_filter() const;
  public:
  void clear_catalog_name_filter();
  const ::exec::user::LikeFilter& catalog_name_filter() const;
  ::exec::user::LikeFilter* release_catalog_name_filter();
  ::exec::user::LikeFilter* mutable_catalog_name_filter();
  void set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_catalog_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_catalog_name_filter();
  public:
  void unsafe_arena_set_allocated_catalog_name_filter(
      ::exec::user::LikeFilter* catalog_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_catalog_name_filter();

  // optional .exec.user.LikeFilter schema_name_filter = 2;
  bool has_schema_name_filter() const;
  private:
  bool _internal_has_schema_name_filter() const;
  public:
  void clear_schema_name_filter();
  const ::exec::user::LikeFilter& schema_name_filter() const;
  ::exec::user::LikeFilter* release_schema_name_filter();
  ::exec::user::LikeFilter* mutable_schema_name_filter();
  void set_allocated_schema_name_filter(::exec::user::LikeFilter* schema_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_schema_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_schema_name_filter();
  public:
  void unsafe_arena_set_allocated_schema_name_filter(
      ::exec::user::LikeFilter* schema_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_schema_name_filter();

  // optional .exec.user.LikeFilter table_name_filter = 3;
  bool has_table_name_filter() const;
  private:
  bool _internal_has_table_name_filter() const;
  public:
  void clear_table_name_filter();
  const ::exec::user::LikeFilter& table_name_filter() const;
  ::exec::user::LikeFilter* release_table_name_filter();
  ::exec::user::LikeFilter* mutable_table_name_filter();
  void set_allocated_table_name_filter(::exec::user::LikeFilter* table_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_table_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_table_name_filter();
  public:
  void unsafe_arena_set_allocated_table_name_filter(
      ::exec::user::LikeFilter* table_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_table_name_filter();

  // optional .exec.user.LikeFilter column_name_filter = 4;
  bool has_column_name_filter() const;
  private:
  bool _internal_has_column_name_filter() const;
  public:
  void clear_column_name_filter();
  const ::exec::user::LikeFilter& column_name_filter() const;
  ::exec::user::LikeFilter* release_column_name_filter();
  ::exec::user::LikeFilter* mutable_column_name_filter();
  void set_allocated_column_name_filter(::exec::user::LikeFilter* column_name_filter);
  private:
  const ::exec::user::LikeFilter& _internal_column_name_filter() const;
  ::exec::user::LikeFilter* _internal_mutable_column_name_filter();
  public:
  void unsafe_arena_set_allocated_column_name_filter(
      ::exec::user::LikeFilter* column_name_filter);
  ::exec::user::LikeFilter* unsafe_arena_release_column_name_filter();

  // @@protoc_insertion_point(class_scope:exec.user.GetColumnsReq)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::user::LikeFilter* catalog_name_filter_;
  ::exec::user::LikeFilter* schema_name_filter_;
  ::exec::user::LikeFilter* table_name_filter_;
  ::exec::user::LikeFilter* column_name_filter_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class ColumnMetadata PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.ColumnMetadata) */ {
 public:
  inline ColumnMetadata() : ColumnMetadata(nullptr) {}
  ~ColumnMetadata() override;
  explicit constexpr ColumnMetadata(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ColumnMetadata(const ColumnMetadata& from);
  ColumnMetadata(ColumnMetadata&& from) noexcept
    : ColumnMetadata() {
    *this = ::std::move(from);
  }

  inline ColumnMetadata& operator=(const ColumnMetadata& from) {
    CopyFrom(from);
    return *this;
  }
  inline ColumnMetadata& operator=(ColumnMetadata&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ColumnMetadata& default_instance() {
    return *internal_default_instance();
  }
  static inline const ColumnMetadata* internal_default_instance() {
    return reinterpret_cast<const ColumnMetadata*>(
               &_ColumnMetadata_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    19;

  friend void swap(ColumnMetadata& a, ColumnMetadata& b) {
    a.Swap(&b);
  }
  inline void Swap(ColumnMetadata* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ColumnMetadata* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline ColumnMetadata* New() const final {
    return CreateMaybeMessage<ColumnMetadata>(nullptr);
  }

  ColumnMetadata* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<ColumnMetadata>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const ColumnMetadata& from);
  void MergeFrom(const ColumnMetadata& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ColumnMetadata* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.ColumnMetadata";
  }
  protected:
  explicit ColumnMetadata(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFieldNumber = 1,
    kSchemaNameFieldNumber = 2,
    kTableNameFieldNumber = 3,
    kColumnNameFieldNumber = 4,
    kDefaultValueFieldNumber = 6,
    kDataTypeFieldNumber = 8,
    kIntervalTypeFieldNumber = 15,
    kOrdinalPositionFieldNumber = 5,
    kIsNullableFieldNumber = 7,
    kCharMaxLengthFieldNumber = 9,
    kCharOctetLengthFieldNumber = 10,
    kNumericPrecisionFieldNumber = 11,
    kNumericPrecisionRadixFieldNumber = 12,
    kNumericScaleFieldNumber = 13,
    kDateTimePrecisionFieldNumber = 14,
    kIntervalPrecisionFieldNumber = 16,
    kColumnSizeFieldNumber = 17,
  };
  // optional string catalog_name = 1;
  bool has_catalog_name() const;
  private:
  bool _internal_has_catalog_name() const;
  public:
  void clear_catalog_name();
  const std::string& catalog_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_catalog_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_catalog_name();
  std::string* release_catalog_name();
  void set_allocated_catalog_name(std::string* catalog_name);
  private:
  const std::string& _internal_catalog_name() const;
  void _internal_set_catalog_name(const std::string& value);
  std::string* _internal_mutable_catalog_name();
  public:

  // optional string schema_name = 2;
  bool has_schema_name() const;
  private:
  bool _internal_has_schema_name() const;
  public:
  void clear_schema_name();
  const std::string& schema_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_schema_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_schema_name();
  std::string* release_schema_name();
  void set_allocated_schema_name(std::string* schema_name);
  private:
  const std::string& _internal_schema_name() const;
  void _internal_set_schema_name(const std::string& value);
  std::string* _internal_mutable_schema_name();
  public:

  // optional string table_name = 3;
  bool has_table_name() const;
  private:
  bool _internal_has_table_name() const;
  public:
  void clear_table_name();
  const std::string& table_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_table_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_table_name();
  std::string* release_table_name();
  void set_allocated_table_name(std::string* table_name);
  private:
  const std::string& _internal_table_name() const;
  void _internal_set_table_name(const std::string& value);
  std::string* _internal_mutable_table_name();
  public:

  // optional string column_name = 4;
  bool has_column_name() const;
  private:
  bool _internal_has_column_name() const;
  public:
  void clear_column_name();
  const std::string& column_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_column_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_column_name();
  std::string* release_column_name();
  void set_allocated_column_name(std::string* column_name);
  private:
  const std::string& _internal_column_name() const;
  void _internal_set_column_name(const std::string& value);
  std::string* _internal_mutable_column_name();
  public:

  // optional string default_value = 6;
  bool has_default_value() const;
  private:
  bool _internal_has_default_value() const;
  public:
  void clear_default_value();
  const std::string& default_value() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_default_value(ArgT0&& arg0, ArgT... args);
  std::string* mutable_default_value();
  std::string* release_default_value();
  void set_allocated_default_value(std::string* default_value);
  private:
  const std::string& _internal_default_value() const;
  void _internal_set_default_value(const std::string& value);
  std::string* _internal_mutable_default_value();
  public:

  // optional string data_type = 8;
  bool has_data_type() const;
  private:
  bool _internal_has_data_type() const;
  public:
  void clear_data_type();
  const std::string& data_type() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_data_type(ArgT0&& arg0, ArgT... args);
  std::string* mutable_data_type();
  std::string* release_data_type();
  void set_allocated_data_type(std::string* data_type);
  private:
  const std::string& _internal_data_type() const;
  void _internal_set_data_type(const std::string& value);
  std::string* _internal_mutable_data_type();
  public:

  // optional string interval_type = 15;
  bool has_interval_type() const;
  private:
  bool _internal_has_interval_type() const;
  public:
  void clear_interval_type();
  const std::string& interval_type() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_interval_type(ArgT0&& arg0, ArgT... args);
  std::string* mutable_interval_type();
  std::string* release_interval_type();
  void set_allocated_interval_type(std::string* interval_type);
  private:
  const std::string& _internal_interval_type() const;
  void _internal_set_interval_type(const std::string& value);
  std::string* _internal_mutable_interval_type();
  public:

  // optional int32 ordinal_position = 5;
  bool has_ordinal_position() const;
  private:
  bool _internal_has_ordinal_position() const;
  public:
  void clear_ordinal_position();
  ::PROTOBUF_NAMESPACE_ID::int32 ordinal_position() const;
  void set_ordinal_position(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_ordinal_position() const;
  void _internal_set_ordinal_position(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool is_nullable = 7;
  bool has_is_nullable() const;
  private:
  bool _internal_has_is_nullable() const;
  public:
  void clear_is_nullable();
  bool is_nullable() const;
  void set_is_nullable(bool value);
  private:
  bool _internal_is_nullable() const;
  void _internal_set_is_nullable(bool value);
  public:

  // optional int32 char_max_length = 9;
  bool has_char_max_length() const;
  private:
  bool _internal_has_char_max_length() const;
  public:
  void clear_char_max_length();
  ::PROTOBUF_NAMESPACE_ID::int32 char_max_length() const;
  void set_char_max_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_char_max_length() const;
  void _internal_set_char_max_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 char_octet_length = 10;
  bool has_char_octet_length() const;
  private:
  bool _internal_has_char_octet_length() const;
  public:
  void clear_char_octet_length();
  ::PROTOBUF_NAMESPACE_ID::int32 char_octet_length() const;
  void set_char_octet_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_char_octet_length() const;
  void _internal_set_char_octet_length(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 numeric_precision = 11;
  bool has_numeric_precision() const;
  private:
  bool _internal_has_numeric_precision() const;
  public:
  void clear_numeric_precision();
  ::PROTOBUF_NAMESPACE_ID::int32 numeric_precision() const;
  void set_numeric_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_numeric_precision() const;
  void _internal_set_numeric_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 numeric_precision_radix = 12;
  bool has_numeric_precision_radix() const;
  private:
  bool _internal_has_numeric_precision_radix() const;
  public:
  void clear_numeric_precision_radix();
  ::PROTOBUF_NAMESPACE_ID::int32 numeric_precision_radix() const;
  void set_numeric_precision_radix(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_numeric_precision_radix() const;
  void _internal_set_numeric_precision_radix(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 numeric_scale = 13;
  bool has_numeric_scale() const;
  private:
  bool _internal_has_numeric_scale() const;
  public:
  void clear_numeric_scale();
  ::PROTOBUF_NAMESPACE_ID::int32 numeric_scale() const;
  void set_numeric_scale(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_numeric_scale() const;
  void _internal_set_numeric_scale(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 date_time_precision = 14;
  bool has_date_time_precision() const;
  private:
  bool _internal_has_date_time_precision() const;
  public:
  void clear_date_time_precision();
  ::PROTOBUF_NAMESPACE_ID::int32 date_time_precision() const;
  void set_date_time_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_date_time_precision() const;
  void _internal_set_date_time_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 interval_precision = 16;
  bool has_interval_precision() const;
  private:
  bool _internal_has_interval_precision() const;
  public:
  void clear_interval_precision();
  ::PROTOBUF_NAMESPACE_ID::int32 interval_precision() const;
  void set_interval_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_interval_precision() const;
  void _internal_set_interval_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 column_size = 17;
  bool has_column_size() const;
  private:
  bool _internal_has_column_size() const;
  public:
  void clear_column_size();
  ::PROTOBUF_NAMESPACE_ID::int32 column_size() const;
  void set_column_size(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_column_size() const;
  void _internal_set_column_size(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.ColumnMetadata)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr catalog_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr schema_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr table_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr column_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr default_value_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr data_type_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr interval_type_;
  ::PROTOBUF_NAMESPACE_ID::int32 ordinal_position_;
  bool is_nullable_;
  ::PROTOBUF_NAMESPACE_ID::int32 char_max_length_;
  ::PROTOBUF_NAMESPACE_ID::int32 char_octet_length_;
  ::PROTOBUF_NAMESPACE_ID::int32 numeric_precision_;
  ::PROTOBUF_NAMESPACE_ID::int32 numeric_precision_radix_;
  ::PROTOBUF_NAMESPACE_ID::int32 numeric_scale_;
  ::PROTOBUF_NAMESPACE_ID::int32 date_time_precision_;
  ::PROTOBUF_NAMESPACE_ID::int32 interval_precision_;
  ::PROTOBUF_NAMESPACE_ID::int32 column_size_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetColumnsResp PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetColumnsResp) */ {
 public:
  inline GetColumnsResp() : GetColumnsResp(nullptr) {}
  ~GetColumnsResp() override;
  explicit constexpr GetColumnsResp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetColumnsResp(const GetColumnsResp& from);
  GetColumnsResp(GetColumnsResp&& from) noexcept
    : GetColumnsResp() {
    *this = ::std::move(from);
  }

  inline GetColumnsResp& operator=(const GetColumnsResp& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetColumnsResp& operator=(GetColumnsResp&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetColumnsResp& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetColumnsResp* internal_default_instance() {
    return reinterpret_cast<const GetColumnsResp*>(
               &_GetColumnsResp_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    20;

  friend void swap(GetColumnsResp& a, GetColumnsResp& b) {
    a.Swap(&b);
  }
  inline void Swap(GetColumnsResp* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetColumnsResp* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetColumnsResp* New() const final {
    return CreateMaybeMessage<GetColumnsResp>(nullptr);
  }

  GetColumnsResp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetColumnsResp>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetColumnsResp& from);
  void MergeFrom(const GetColumnsResp& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetColumnsResp* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetColumnsResp";
  }
  protected:
  explicit GetColumnsResp(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kColumnsFieldNumber = 2,
    kErrorFieldNumber = 3,
    kStatusFieldNumber = 1,
  };
  // repeated .exec.user.ColumnMetadata columns = 2;
  int columns_size() const;
  private:
  int _internal_columns_size() const;
  public:
  void clear_columns();
  ::exec::user::ColumnMetadata* mutable_columns(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ColumnMetadata >*
      mutable_columns();
  private:
  const ::exec::user::ColumnMetadata& _internal_columns(int index) const;
  ::exec::user::ColumnMetadata* _internal_add_columns();
  public:
  const ::exec::user::ColumnMetadata& columns(int index) const;
  ::exec::user::ColumnMetadata* add_columns();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ColumnMetadata >&
      columns() const;

  // optional .exec.shared.DrillPBError error = 3;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // optional .exec.user.RequestStatus status = 1;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::user::RequestStatus status() const;
  void set_status(::exec::user::RequestStatus value);
  private:
  ::exec::user::RequestStatus _internal_status() const;
  void _internal_set_status(::exec::user::RequestStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.GetColumnsResp)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ColumnMetadata > columns_;
  ::exec::shared::DrillPBError* error_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class CreatePreparedStatementReq PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.CreatePreparedStatementReq) */ {
 public:
  inline CreatePreparedStatementReq() : CreatePreparedStatementReq(nullptr) {}
  ~CreatePreparedStatementReq() override;
  explicit constexpr CreatePreparedStatementReq(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  CreatePreparedStatementReq(const CreatePreparedStatementReq& from);
  CreatePreparedStatementReq(CreatePreparedStatementReq&& from) noexcept
    : CreatePreparedStatementReq() {
    *this = ::std::move(from);
  }

  inline CreatePreparedStatementReq& operator=(const CreatePreparedStatementReq& from) {
    CopyFrom(from);
    return *this;
  }
  inline CreatePreparedStatementReq& operator=(CreatePreparedStatementReq&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CreatePreparedStatementReq& default_instance() {
    return *internal_default_instance();
  }
  static inline const CreatePreparedStatementReq* internal_default_instance() {
    return reinterpret_cast<const CreatePreparedStatementReq*>(
               &_CreatePreparedStatementReq_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    21;

  friend void swap(CreatePreparedStatementReq& a, CreatePreparedStatementReq& b) {
    a.Swap(&b);
  }
  inline void Swap(CreatePreparedStatementReq* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CreatePreparedStatementReq* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline CreatePreparedStatementReq* New() const final {
    return CreateMaybeMessage<CreatePreparedStatementReq>(nullptr);
  }

  CreatePreparedStatementReq* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<CreatePreparedStatementReq>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const CreatePreparedStatementReq& from);
  void MergeFrom(const CreatePreparedStatementReq& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(CreatePreparedStatementReq* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.CreatePreparedStatementReq";
  }
  protected:
  explicit CreatePreparedStatementReq(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kSqlQueryFieldNumber = 1,
  };
  // optional string sql_query = 1;
  bool has_sql_query() const;
  private:
  bool _internal_has_sql_query() const;
  public:
  void clear_sql_query();
  const std::string& sql_query() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_sql_query(ArgT0&& arg0, ArgT... args);
  std::string* mutable_sql_query();
  std::string* release_sql_query();
  void set_allocated_sql_query(std::string* sql_query);
  private:
  const std::string& _internal_sql_query() const;
  void _internal_set_sql_query(const std::string& value);
  std::string* _internal_mutable_sql_query();
  public:

  // @@protoc_insertion_point(class_scope:exec.user.CreatePreparedStatementReq)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr sql_query_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class ResultColumnMetadata PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.ResultColumnMetadata) */ {
 public:
  inline ResultColumnMetadata() : ResultColumnMetadata(nullptr) {}
  ~ResultColumnMetadata() override;
  explicit constexpr ResultColumnMetadata(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ResultColumnMetadata(const ResultColumnMetadata& from);
  ResultColumnMetadata(ResultColumnMetadata&& from) noexcept
    : ResultColumnMetadata() {
    *this = ::std::move(from);
  }

  inline ResultColumnMetadata& operator=(const ResultColumnMetadata& from) {
    CopyFrom(from);
    return *this;
  }
  inline ResultColumnMetadata& operator=(ResultColumnMetadata&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ResultColumnMetadata& default_instance() {
    return *internal_default_instance();
  }
  static inline const ResultColumnMetadata* internal_default_instance() {
    return reinterpret_cast<const ResultColumnMetadata*>(
               &_ResultColumnMetadata_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    22;

  friend void swap(ResultColumnMetadata& a, ResultColumnMetadata& b) {
    a.Swap(&b);
  }
  inline void Swap(ResultColumnMetadata* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ResultColumnMetadata* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline ResultColumnMetadata* New() const final {
    return CreateMaybeMessage<ResultColumnMetadata>(nullptr);
  }

  ResultColumnMetadata* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<ResultColumnMetadata>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const ResultColumnMetadata& from);
  void MergeFrom(const ResultColumnMetadata& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ResultColumnMetadata* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.ResultColumnMetadata";
  }
  protected:
  explicit ResultColumnMetadata(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCatalogNameFieldNumber = 1,
    kSchemaNameFieldNumber = 2,
    kTableNameFieldNumber = 3,
    kColumnNameFieldNumber = 4,
    kLabelFieldNumber = 5,
    kDataTypeFieldNumber = 6,
    kClassNameFieldNumber = 18,
    kPrecisionFieldNumber = 8,
    kScaleFieldNumber = 9,
    kDisplaySizeFieldNumber = 11,
    kIsNullableFieldNumber = 7,
    kSignedFieldNumber = 10,
    kIsAliasedFieldNumber = 12,
    kAutoIncrementFieldNumber = 15,
    kSearchabilityFieldNumber = 13,
    kUpdatabilityFieldNumber = 14,
    kCaseSensitivityFieldNumber = 16,
    kSortableFieldNumber = 17,
    kIsCurrencyFieldNumber = 20,
  };
  // optional string catalog_name = 1;
  bool has_catalog_name() const;
  private:
  bool _internal_has_catalog_name() const;
  public:
  void clear_catalog_name();
  const std::string& catalog_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_catalog_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_catalog_name();
  std::string* release_catalog_name();
  void set_allocated_catalog_name(std::string* catalog_name);
  private:
  const std::string& _internal_catalog_name() const;
  void _internal_set_catalog_name(const std::string& value);
  std::string* _internal_mutable_catalog_name();
  public:

  // optional string schema_name = 2;
  bool has_schema_name() const;
  private:
  bool _internal_has_schema_name() const;
  public:
  void clear_schema_name();
  const std::string& schema_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_schema_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_schema_name();
  std::string* release_schema_name();
  void set_allocated_schema_name(std::string* schema_name);
  private:
  const std::string& _internal_schema_name() const;
  void _internal_set_schema_name(const std::string& value);
  std::string* _internal_mutable_schema_name();
  public:

  // optional string table_name = 3;
  bool has_table_name() const;
  private:
  bool _internal_has_table_name() const;
  public:
  void clear_table_name();
  const std::string& table_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_table_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_table_name();
  std::string* release_table_name();
  void set_allocated_table_name(std::string* table_name);
  private:
  const std::string& _internal_table_name() const;
  void _internal_set_table_name(const std::string& value);
  std::string* _internal_mutable_table_name();
  public:

  // optional string column_name = 4;
  bool has_column_name() const;
  private:
  bool _internal_has_column_name() const;
  public:
  void clear_column_name();
  const std::string& column_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_column_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_column_name();
  std::string* release_column_name();
  void set_allocated_column_name(std::string* column_name);
  private:
  const std::string& _internal_column_name() const;
  void _internal_set_column_name(const std::string& value);
  std::string* _internal_mutable_column_name();
  public:

  // optional string label = 5;
  bool has_label() const;
  private:
  bool _internal_has_label() const;
  public:
  void clear_label();
  const std::string& label() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_label(ArgT0&& arg0, ArgT... args);
  std::string* mutable_label();
  std::string* release_label();
  void set_allocated_label(std::string* label);
  private:
  const std::string& _internal_label() const;
  void _internal_set_label(const std::string& value);
  std::string* _internal_mutable_label();
  public:

  // optional string data_type = 6;
  bool has_data_type() const;
  private:
  bool _internal_has_data_type() const;
  public:
  void clear_data_type();
  const std::string& data_type() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_data_type(ArgT0&& arg0, ArgT... args);
  std::string* mutable_data_type();
  std::string* release_data_type();
  void set_allocated_data_type(std::string* data_type);
  private:
  const std::string& _internal_data_type() const;
  void _internal_set_data_type(const std::string& value);
  std::string* _internal_mutable_data_type();
  public:

  // optional string class_name = 18;
  bool has_class_name() const;
  private:
  bool _internal_has_class_name() const;
  public:
  void clear_class_name();
  const std::string& class_name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_class_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_class_name();
  std::string* release_class_name();
  void set_allocated_class_name(std::string* class_name);
  private:
  const std::string& _internal_class_name() const;
  void _internal_set_class_name(const std::string& value);
  std::string* _internal_mutable_class_name();
  public:

  // optional int32 precision = 8;
  bool has_precision() const;
  private:
  bool _internal_has_precision() const;
  public:
  void clear_precision();
  ::PROTOBUF_NAMESPACE_ID::int32 precision() const;
  void set_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_precision() const;
  void _internal_set_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 scale = 9;
  bool has_scale() const;
  private:
  bool _internal_has_scale() const;
  public:
  void clear_scale();
  ::PROTOBUF_NAMESPACE_ID::int32 scale() const;
  void set_scale(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_scale() const;
  void _internal_set_scale(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 display_size = 11;
  bool has_display_size() const;
  private:
  bool _internal_has_display_size() const;
  public:
  void clear_display_size();
  ::PROTOBUF_NAMESPACE_ID::int32 display_size() const;
  void set_display_size(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_display_size() const;
  void _internal_set_display_size(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional bool is_nullable = 7;
  bool has_is_nullable() const;
  private:
  bool _internal_has_is_nullable() const;
  public:
  void clear_is_nullable();
  bool is_nullable() const;
  void set_is_nullable(bool value);
  private:
  bool _internal_is_nullable() const;
  void _internal_set_is_nullable(bool value);
  public:

  // optional bool signed = 10;
  bool has_signed_() const;
  private:
  bool _internal_has_signed_() const;
  public:
  void clear_signed_();
  bool signed_() const;
  void set_signed_(bool value);
  private:
  bool _internal_signed_() const;
  void _internal_set_signed_(bool value);
  public:

  // optional bool is_aliased = 12;
  bool has_is_aliased() const;
  private:
  bool _internal_has_is_aliased() const;
  public:
  void clear_is_aliased();
  bool is_aliased() const;
  void set_is_aliased(bool value);
  private:
  bool _internal_is_aliased() const;
  void _internal_set_is_aliased(bool value);
  public:

  // optional bool auto_increment = 15;
  bool has_auto_increment() const;
  private:
  bool _internal_has_auto_increment() const;
  public:
  void clear_auto_increment();
  bool auto_increment() const;
  void set_auto_increment(bool value);
  private:
  bool _internal_auto_increment() const;
  void _internal_set_auto_increment(bool value);
  public:

  // optional .exec.user.ColumnSearchability searchability = 13;
  bool has_searchability() const;
  private:
  bool _internal_has_searchability() const;
  public:
  void clear_searchability();
  ::exec::user::ColumnSearchability searchability() const;
  void set_searchability(::exec::user::ColumnSearchability value);
  private:
  ::exec::user::ColumnSearchability _internal_searchability() const;
  void _internal_set_searchability(::exec::user::ColumnSearchability value);
  public:

  // optional .exec.user.ColumnUpdatability updatability = 14;
  bool has_updatability() const;
  private:
  bool _internal_has_updatability() const;
  public:
  void clear_updatability();
  ::exec::user::ColumnUpdatability updatability() const;
  void set_updatability(::exec::user::ColumnUpdatability value);
  private:
  ::exec::user::ColumnUpdatability _internal_updatability() const;
  void _internal_set_updatability(::exec::user::ColumnUpdatability value);
  public:

  // optional bool case_sensitivity = 16;
  bool has_case_sensitivity() const;
  private:
  bool _internal_has_case_sensitivity() const;
  public:
  void clear_case_sensitivity();
  bool case_sensitivity() const;
  void set_case_sensitivity(bool value);
  private:
  bool _internal_case_sensitivity() const;
  void _internal_set_case_sensitivity(bool value);
  public:

  // optional bool sortable = 17;
  bool has_sortable() const;
  private:
  bool _internal_has_sortable() const;
  public:
  void clear_sortable();
  bool sortable() const;
  void set_sortable(bool value);
  private:
  bool _internal_sortable() const;
  void _internal_set_sortable(bool value);
  public:

  // optional bool is_currency = 20;
  bool has_is_currency() const;
  private:
  bool _internal_has_is_currency() const;
  public:
  void clear_is_currency();
  bool is_currency() const;
  void set_is_currency(bool value);
  private:
  bool _internal_is_currency() const;
  void _internal_set_is_currency(bool value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.ResultColumnMetadata)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr catalog_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr schema_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr table_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr column_name_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr label_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr data_type_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr class_name_;
  ::PROTOBUF_NAMESPACE_ID::int32 precision_;
  ::PROTOBUF_NAMESPACE_ID::int32 scale_;
  ::PROTOBUF_NAMESPACE_ID::int32 display_size_;
  bool is_nullable_;
  bool signed__;
  bool is_aliased_;
  bool auto_increment_;
  int searchability_;
  int updatability_;
  bool case_sensitivity_;
  bool sortable_;
  bool is_currency_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class PreparedStatementHandle PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.PreparedStatementHandle) */ {
 public:
  inline PreparedStatementHandle() : PreparedStatementHandle(nullptr) {}
  ~PreparedStatementHandle() override;
  explicit constexpr PreparedStatementHandle(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  PreparedStatementHandle(const PreparedStatementHandle& from);
  PreparedStatementHandle(PreparedStatementHandle&& from) noexcept
    : PreparedStatementHandle() {
    *this = ::std::move(from);
  }

  inline PreparedStatementHandle& operator=(const PreparedStatementHandle& from) {
    CopyFrom(from);
    return *this;
  }
  inline PreparedStatementHandle& operator=(PreparedStatementHandle&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const PreparedStatementHandle& default_instance() {
    return *internal_default_instance();
  }
  static inline const PreparedStatementHandle* internal_default_instance() {
    return reinterpret_cast<const PreparedStatementHandle*>(
               &_PreparedStatementHandle_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    23;

  friend void swap(PreparedStatementHandle& a, PreparedStatementHandle& b) {
    a.Swap(&b);
  }
  inline void Swap(PreparedStatementHandle* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(PreparedStatementHandle* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline PreparedStatementHandle* New() const final {
    return CreateMaybeMessage<PreparedStatementHandle>(nullptr);
  }

  PreparedStatementHandle* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<PreparedStatementHandle>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const PreparedStatementHandle& from);
  void MergeFrom(const PreparedStatementHandle& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(PreparedStatementHandle* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.PreparedStatementHandle";
  }
  protected:
  explicit PreparedStatementHandle(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kServerInfoFieldNumber = 1,
  };
  // optional bytes server_info = 1;
  bool has_server_info() const;
  private:
  bool _internal_has_server_info() const;
  public:
  void clear_server_info();
  const std::string& server_info() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_server_info(ArgT0&& arg0, ArgT... args);
  std::string* mutable_server_info();
  std::string* release_server_info();
  void set_allocated_server_info(std::string* server_info);
  private:
  const std::string& _internal_server_info() const;
  void _internal_set_server_info(const std::string& value);
  std::string* _internal_mutable_server_info();
  public:

  // @@protoc_insertion_point(class_scope:exec.user.PreparedStatementHandle)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr server_info_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class PreparedStatement PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.PreparedStatement) */ {
 public:
  inline PreparedStatement() : PreparedStatement(nullptr) {}
  ~PreparedStatement() override;
  explicit constexpr PreparedStatement(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  PreparedStatement(const PreparedStatement& from);
  PreparedStatement(PreparedStatement&& from) noexcept
    : PreparedStatement() {
    *this = ::std::move(from);
  }

  inline PreparedStatement& operator=(const PreparedStatement& from) {
    CopyFrom(from);
    return *this;
  }
  inline PreparedStatement& operator=(PreparedStatement&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const PreparedStatement& default_instance() {
    return *internal_default_instance();
  }
  static inline const PreparedStatement* internal_default_instance() {
    return reinterpret_cast<const PreparedStatement*>(
               &_PreparedStatement_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    24;

  friend void swap(PreparedStatement& a, PreparedStatement& b) {
    a.Swap(&b);
  }
  inline void Swap(PreparedStatement* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(PreparedStatement* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline PreparedStatement* New() const final {
    return CreateMaybeMessage<PreparedStatement>(nullptr);
  }

  PreparedStatement* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<PreparedStatement>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const PreparedStatement& from);
  void MergeFrom(const PreparedStatement& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(PreparedStatement* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.PreparedStatement";
  }
  protected:
  explicit PreparedStatement(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kColumnsFieldNumber = 1,
    kServerHandleFieldNumber = 2,
  };
  // repeated .exec.user.ResultColumnMetadata columns = 1;
  int columns_size() const;
  private:
  int _internal_columns_size() const;
  public:
  void clear_columns();
  ::exec::user::ResultColumnMetadata* mutable_columns(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ResultColumnMetadata >*
      mutable_columns();
  private:
  const ::exec::user::ResultColumnMetadata& _internal_columns(int index) const;
  ::exec::user::ResultColumnMetadata* _internal_add_columns();
  public:
  const ::exec::user::ResultColumnMetadata& columns(int index) const;
  ::exec::user::ResultColumnMetadata* add_columns();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ResultColumnMetadata >&
      columns() const;

  // optional .exec.user.PreparedStatementHandle server_handle = 2;
  bool has_server_handle() const;
  private:
  bool _internal_has_server_handle() const;
  public:
  void clear_server_handle();
  const ::exec::user::PreparedStatementHandle& server_handle() const;
  ::exec::user::PreparedStatementHandle* release_server_handle();
  ::exec::user::PreparedStatementHandle* mutable_server_handle();
  void set_allocated_server_handle(::exec::user::PreparedStatementHandle* server_handle);
  private:
  const ::exec::user::PreparedStatementHandle& _internal_server_handle() const;
  ::exec::user::PreparedStatementHandle* _internal_mutable_server_handle();
  public:
  void unsafe_arena_set_allocated_server_handle(
      ::exec::user::PreparedStatementHandle* server_handle);
  ::exec::user::PreparedStatementHandle* unsafe_arena_release_server_handle();

  // @@protoc_insertion_point(class_scope:exec.user.PreparedStatement)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ResultColumnMetadata > columns_;
  ::exec::user::PreparedStatementHandle* server_handle_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class CreatePreparedStatementResp PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.CreatePreparedStatementResp) */ {
 public:
  inline CreatePreparedStatementResp() : CreatePreparedStatementResp(nullptr) {}
  ~CreatePreparedStatementResp() override;
  explicit constexpr CreatePreparedStatementResp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  CreatePreparedStatementResp(const CreatePreparedStatementResp& from);
  CreatePreparedStatementResp(CreatePreparedStatementResp&& from) noexcept
    : CreatePreparedStatementResp() {
    *this = ::std::move(from);
  }

  inline CreatePreparedStatementResp& operator=(const CreatePreparedStatementResp& from) {
    CopyFrom(from);
    return *this;
  }
  inline CreatePreparedStatementResp& operator=(CreatePreparedStatementResp&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const CreatePreparedStatementResp& default_instance() {
    return *internal_default_instance();
  }
  static inline const CreatePreparedStatementResp* internal_default_instance() {
    return reinterpret_cast<const CreatePreparedStatementResp*>(
               &_CreatePreparedStatementResp_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    25;

  friend void swap(CreatePreparedStatementResp& a, CreatePreparedStatementResp& b) {
    a.Swap(&b);
  }
  inline void Swap(CreatePreparedStatementResp* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(CreatePreparedStatementResp* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline CreatePreparedStatementResp* New() const final {
    return CreateMaybeMessage<CreatePreparedStatementResp>(nullptr);
  }

  CreatePreparedStatementResp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<CreatePreparedStatementResp>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const CreatePreparedStatementResp& from);
  void MergeFrom(const CreatePreparedStatementResp& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(CreatePreparedStatementResp* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.CreatePreparedStatementResp";
  }
  protected:
  explicit CreatePreparedStatementResp(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kPreparedStatementFieldNumber = 2,
    kErrorFieldNumber = 3,
    kStatusFieldNumber = 1,
  };
  // optional .exec.user.PreparedStatement prepared_statement = 2;
  bool has_prepared_statement() const;
  private:
  bool _internal_has_prepared_statement() const;
  public:
  void clear_prepared_statement();
  const ::exec::user::PreparedStatement& prepared_statement() const;
  ::exec::user::PreparedStatement* release_prepared_statement();
  ::exec::user::PreparedStatement* mutable_prepared_statement();
  void set_allocated_prepared_statement(::exec::user::PreparedStatement* prepared_statement);
  private:
  const ::exec::user::PreparedStatement& _internal_prepared_statement() const;
  ::exec::user::PreparedStatement* _internal_mutable_prepared_statement();
  public:
  void unsafe_arena_set_allocated_prepared_statement(
      ::exec::user::PreparedStatement* prepared_statement);
  ::exec::user::PreparedStatement* unsafe_arena_release_prepared_statement();

  // optional .exec.shared.DrillPBError error = 3;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // optional .exec.user.RequestStatus status = 1;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::user::RequestStatus status() const;
  void set_status(::exec::user::RequestStatus value);
  private:
  ::exec::user::RequestStatus _internal_status() const;
  void _internal_set_status(::exec::user::RequestStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.CreatePreparedStatementResp)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::user::PreparedStatement* prepared_statement_;
  ::exec::shared::DrillPBError* error_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetServerMetaReq PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetServerMetaReq) */ {
 public:
  inline GetServerMetaReq() : GetServerMetaReq(nullptr) {}
  ~GetServerMetaReq() override;
  explicit constexpr GetServerMetaReq(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetServerMetaReq(const GetServerMetaReq& from);
  GetServerMetaReq(GetServerMetaReq&& from) noexcept
    : GetServerMetaReq() {
    *this = ::std::move(from);
  }

  inline GetServerMetaReq& operator=(const GetServerMetaReq& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetServerMetaReq& operator=(GetServerMetaReq&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetServerMetaReq& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetServerMetaReq* internal_default_instance() {
    return reinterpret_cast<const GetServerMetaReq*>(
               &_GetServerMetaReq_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    26;

  friend void swap(GetServerMetaReq& a, GetServerMetaReq& b) {
    a.Swap(&b);
  }
  inline void Swap(GetServerMetaReq* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetServerMetaReq* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetServerMetaReq* New() const final {
    return CreateMaybeMessage<GetServerMetaReq>(nullptr);
  }

  GetServerMetaReq* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetServerMetaReq>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetServerMetaReq& from);
  void MergeFrom(const GetServerMetaReq& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetServerMetaReq* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetServerMetaReq";
  }
  protected:
  explicit GetServerMetaReq(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  // @@protoc_insertion_point(class_scope:exec.user.GetServerMetaReq)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class ConvertSupport PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.ConvertSupport) */ {
 public:
  inline ConvertSupport() : ConvertSupport(nullptr) {}
  ~ConvertSupport() override;
  explicit constexpr ConvertSupport(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ConvertSupport(const ConvertSupport& from);
  ConvertSupport(ConvertSupport&& from) noexcept
    : ConvertSupport() {
    *this = ::std::move(from);
  }

  inline ConvertSupport& operator=(const ConvertSupport& from) {
    CopyFrom(from);
    return *this;
  }
  inline ConvertSupport& operator=(ConvertSupport&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ConvertSupport& default_instance() {
    return *internal_default_instance();
  }
  static inline const ConvertSupport* internal_default_instance() {
    return reinterpret_cast<const ConvertSupport*>(
               &_ConvertSupport_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    27;

  friend void swap(ConvertSupport& a, ConvertSupport& b) {
    a.Swap(&b);
  }
  inline void Swap(ConvertSupport* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ConvertSupport* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline ConvertSupport* New() const final {
    return CreateMaybeMessage<ConvertSupport>(nullptr);
  }

  ConvertSupport* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<ConvertSupport>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const ConvertSupport& from);
  void MergeFrom(const ConvertSupport& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ConvertSupport* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.ConvertSupport";
  }
  protected:
  explicit ConvertSupport(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kFromFieldNumber = 1,
    kToFieldNumber = 2,
  };
  // required .common.MinorType from = 1;
  bool has_from() const;
  private:
  bool _internal_has_from() const;
  public:
  void clear_from();
  ::common::MinorType from() const;
  void set_from(::common::MinorType value);
  private:
  ::common::MinorType _internal_from() const;
  void _internal_set_from(::common::MinorType value);
  public:

  // required .common.MinorType to = 2;
  bool has_to() const;
  private:
  bool _internal_has_to() const;
  public:
  void clear_to();
  ::common::MinorType to() const;
  void set_to(::common::MinorType value);
  private:
  ::common::MinorType _internal_to() const;
  void _internal_set_to(::common::MinorType value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.ConvertSupport)
 private:
  class _Internal;

  // helper for ByteSizeLong()
  size_t RequiredFieldsByteSizeFallback() const;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  int from_;
  int to_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class GetServerMetaResp PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.GetServerMetaResp) */ {
 public:
  inline GetServerMetaResp() : GetServerMetaResp(nullptr) {}
  ~GetServerMetaResp() override;
  explicit constexpr GetServerMetaResp(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  GetServerMetaResp(const GetServerMetaResp& from);
  GetServerMetaResp(GetServerMetaResp&& from) noexcept
    : GetServerMetaResp() {
    *this = ::std::move(from);
  }

  inline GetServerMetaResp& operator=(const GetServerMetaResp& from) {
    CopyFrom(from);
    return *this;
  }
  inline GetServerMetaResp& operator=(GetServerMetaResp&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const GetServerMetaResp& default_instance() {
    return *internal_default_instance();
  }
  static inline const GetServerMetaResp* internal_default_instance() {
    return reinterpret_cast<const GetServerMetaResp*>(
               &_GetServerMetaResp_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    28;

  friend void swap(GetServerMetaResp& a, GetServerMetaResp& b) {
    a.Swap(&b);
  }
  inline void Swap(GetServerMetaResp* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(GetServerMetaResp* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline GetServerMetaResp* New() const final {
    return CreateMaybeMessage<GetServerMetaResp>(nullptr);
  }

  GetServerMetaResp* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<GetServerMetaResp>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const GetServerMetaResp& from);
  void MergeFrom(const GetServerMetaResp& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(GetServerMetaResp* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.GetServerMetaResp";
  }
  protected:
  explicit GetServerMetaResp(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kServerMetaFieldNumber = 2,
    kErrorFieldNumber = 3,
    kStatusFieldNumber = 1,
  };
  // optional .exec.user.ServerMeta server_meta = 2;
  bool has_server_meta() const;
  private:
  bool _internal_has_server_meta() const;
  public:
  void clear_server_meta();
  const ::exec::user::ServerMeta& server_meta() const;
  ::exec::user::ServerMeta* release_server_meta();
  ::exec::user::ServerMeta* mutable_server_meta();
  void set_allocated_server_meta(::exec::user::ServerMeta* server_meta);
  private:
  const ::exec::user::ServerMeta& _internal_server_meta() const;
  ::exec::user::ServerMeta* _internal_mutable_server_meta();
  public:
  void unsafe_arena_set_allocated_server_meta(
      ::exec::user::ServerMeta* server_meta);
  ::exec::user::ServerMeta* unsafe_arena_release_server_meta();

  // optional .exec.shared.DrillPBError error = 3;
  bool has_error() const;
  private:
  bool _internal_has_error() const;
  public:
  void clear_error();
  const ::exec::shared::DrillPBError& error() const;
  ::exec::shared::DrillPBError* release_error();
  ::exec::shared::DrillPBError* mutable_error();
  void set_allocated_error(::exec::shared::DrillPBError* error);
  private:
  const ::exec::shared::DrillPBError& _internal_error() const;
  ::exec::shared::DrillPBError* _internal_mutable_error();
  public:
  void unsafe_arena_set_allocated_error(
      ::exec::shared::DrillPBError* error);
  ::exec::shared::DrillPBError* unsafe_arena_release_error();

  // optional .exec.user.RequestStatus status = 1;
  bool has_status() const;
  private:
  bool _internal_has_status() const;
  public:
  void clear_status();
  ::exec::user::RequestStatus status() const;
  void set_status(::exec::user::RequestStatus value);
  private:
  ::exec::user::RequestStatus _internal_status() const;
  void _internal_set_status(::exec::user::RequestStatus value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.GetServerMetaResp)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::exec::user::ServerMeta* server_meta_;
  ::exec::shared::DrillPBError* error_;
  int status_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class ServerMeta PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.ServerMeta) */ {
 public:
  inline ServerMeta() : ServerMeta(nullptr) {}
  ~ServerMeta() override;
  explicit constexpr ServerMeta(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  ServerMeta(const ServerMeta& from);
  ServerMeta(ServerMeta&& from) noexcept
    : ServerMeta() {
    *this = ::std::move(from);
  }

  inline ServerMeta& operator=(const ServerMeta& from) {
    CopyFrom(from);
    return *this;
  }
  inline ServerMeta& operator=(ServerMeta&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const ServerMeta& default_instance() {
    return *internal_default_instance();
  }
  static inline const ServerMeta* internal_default_instance() {
    return reinterpret_cast<const ServerMeta*>(
               &_ServerMeta_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    29;

  friend void swap(ServerMeta& a, ServerMeta& b) {
    a.Swap(&b);
  }
  inline void Swap(ServerMeta* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(ServerMeta* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline ServerMeta* New() const final {
    return CreateMaybeMessage<ServerMeta>(nullptr);
  }

  ServerMeta* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<ServerMeta>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const ServerMeta& from);
  void MergeFrom(const ServerMeta& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(ServerMeta* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.ServerMeta";
  }
  protected:
  explicit ServerMeta(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kCollateSupportFieldNumber = 6,
    kConvertSupportFieldNumber = 8,
    kDateTimeFunctionsFieldNumber = 10,
    kDateTimeLiteralsSupportFieldNumber = 11,
    kNumericFunctionsFieldNumber = 34,
    kOrderBySupportFieldNumber = 35,
    kOuterJoinSupportFieldNumber = 36,
    kSqlKeywordsFieldNumber = 43,
    kStringFunctionsFieldNumber = 44,
    kSubquerySupportFieldNumber = 45,
    kSystemFunctionsFieldNumber = 46,
    kUnionSupportFieldNumber = 49,
    kCatalogSeparatorFieldNumber = 4,
    kCatalogTermFieldNumber = 5,
    kIdentifierQuoteStringFieldNumber = 14,
    kSchemaTermFieldNumber = 39,
    kSearchEscapeStringFieldNumber = 40,
    kSpecialCharactersFieldNumber = 42,
    kTableTermFieldNumber = 47,
    kCurrentSchemaFieldNumber = 50,
    kAllTablesSelectableFieldNumber = 1,
    kBlobIncludedInMaxRowSizeFieldNumber = 2,
    kCatalogAtStartFieldNumber = 3,
    kColumnAliasingSupportedFieldNumber = 7,
    kIdentifierCasingFieldNumber = 13,
    kMaxBinaryLiteralLengthFieldNumber = 16,
    kMaxCatalogNameLengthFieldNumber = 17,
    kMaxCharLiteralLengthFieldNumber = 18,
    kMaxColumnNameLengthFieldNumber = 19,
    kMaxColumnsInGroupByFieldNumber = 20,
    kMaxColumnsInOrderByFieldNumber = 21,
    kMaxColumnsInSelectFieldNumber = 22,
    kMaxCursorNameLengthFieldNumber = 23,
    kMaxLogicalLobSizeFieldNumber = 24,
    kMaxRowSizeFieldNumber = 25,
    kMaxSchemaNameLengthFieldNumber = 26,
    kMaxStatementLengthFieldNumber = 27,
    kMaxStatementsFieldNumber = 28,
    kMaxTableNameLengthFieldNumber = 29,
    kMaxTablesInSelectFieldNumber = 30,
    kMaxUserNameLengthFieldNumber = 31,
    kLikeEscapeClauseSupportedFieldNumber = 15,
    kNullPlusNonNullEqualsNullFieldNumber = 33,
    kReadOnlyFieldNumber = 38,
    kSelectForUpdateSupportedFieldNumber = 41,
    kNullCollationFieldNumber = 32,
    kQuotedIdentifierCasingFieldNumber = 37,
    kTransactionSupportedFieldNumber = 48,
    kCorrelationNamesSupportFieldNumber = 9,
    kGroupBySupportFieldNumber = 12,
  };
  // repeated .exec.user.CollateSupport collate_support = 6;
  int collate_support_size() const;
  private:
  int _internal_collate_support_size() const;
  public:
  void clear_collate_support();
  private:
  ::exec::user::CollateSupport _internal_collate_support(int index) const;
  void _internal_add_collate_support(::exec::user::CollateSupport value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_collate_support();
  public:
  ::exec::user::CollateSupport collate_support(int index) const;
  void set_collate_support(int index, ::exec::user::CollateSupport value);
  void add_collate_support(::exec::user::CollateSupport value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& collate_support() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_collate_support();

  // repeated .exec.user.ConvertSupport convert_support = 8;
  int convert_support_size() const;
  private:
  int _internal_convert_support_size() const;
  public:
  void clear_convert_support();
  ::exec::user::ConvertSupport* mutable_convert_support(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ConvertSupport >*
      mutable_convert_support();
  private:
  const ::exec::user::ConvertSupport& _internal_convert_support(int index) const;
  ::exec::user::ConvertSupport* _internal_add_convert_support();
  public:
  const ::exec::user::ConvertSupport& convert_support(int index) const;
  ::exec::user::ConvertSupport* add_convert_support();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ConvertSupport >&
      convert_support() const;

  // repeated string date_time_functions = 10;
  int date_time_functions_size() const;
  private:
  int _internal_date_time_functions_size() const;
  public:
  void clear_date_time_functions();
  const std::string& date_time_functions(int index) const;
  std::string* mutable_date_time_functions(int index);
  void set_date_time_functions(int index, const std::string& value);
  void set_date_time_functions(int index, std::string&& value);
  void set_date_time_functions(int index, const char* value);
  void set_date_time_functions(int index, const char* value, size_t size);
  std::string* add_date_time_functions();
  void add_date_time_functions(const std::string& value);
  void add_date_time_functions(std::string&& value);
  void add_date_time_functions(const char* value);
  void add_date_time_functions(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& date_time_functions() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_date_time_functions();
  private:
  const std::string& _internal_date_time_functions(int index) const;
  std::string* _internal_add_date_time_functions();
  public:

  // repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;
  int date_time_literals_support_size() const;
  private:
  int _internal_date_time_literals_support_size() const;
  public:
  void clear_date_time_literals_support();
  private:
  ::exec::user::DateTimeLiteralsSupport _internal_date_time_literals_support(int index) const;
  void _internal_add_date_time_literals_support(::exec::user::DateTimeLiteralsSupport value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_date_time_literals_support();
  public:
  ::exec::user::DateTimeLiteralsSupport date_time_literals_support(int index) const;
  void set_date_time_literals_support(int index, ::exec::user::DateTimeLiteralsSupport value);
  void add_date_time_literals_support(::exec::user::DateTimeLiteralsSupport value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& date_time_literals_support() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_date_time_literals_support();

  // repeated string numeric_functions = 34;
  int numeric_functions_size() const;
  private:
  int _internal_numeric_functions_size() const;
  public:
  void clear_numeric_functions();
  const std::string& numeric_functions(int index) const;
  std::string* mutable_numeric_functions(int index);
  void set_numeric_functions(int index, const std::string& value);
  void set_numeric_functions(int index, std::string&& value);
  void set_numeric_functions(int index, const char* value);
  void set_numeric_functions(int index, const char* value, size_t size);
  std::string* add_numeric_functions();
  void add_numeric_functions(const std::string& value);
  void add_numeric_functions(std::string&& value);
  void add_numeric_functions(const char* value);
  void add_numeric_functions(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& numeric_functions() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_numeric_functions();
  private:
  const std::string& _internal_numeric_functions(int index) const;
  std::string* _internal_add_numeric_functions();
  public:

  // repeated .exec.user.OrderBySupport order_by_support = 35;
  int order_by_support_size() const;
  private:
  int _internal_order_by_support_size() const;
  public:
  void clear_order_by_support();
  private:
  ::exec::user::OrderBySupport _internal_order_by_support(int index) const;
  void _internal_add_order_by_support(::exec::user::OrderBySupport value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_order_by_support();
  public:
  ::exec::user::OrderBySupport order_by_support(int index) const;
  void set_order_by_support(int index, ::exec::user::OrderBySupport value);
  void add_order_by_support(::exec::user::OrderBySupport value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& order_by_support() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_order_by_support();

  // repeated .exec.user.OuterJoinSupport outer_join_support = 36;
  int outer_join_support_size() const;
  private:
  int _internal_outer_join_support_size() const;
  public:
  void clear_outer_join_support();
  private:
  ::exec::user::OuterJoinSupport _internal_outer_join_support(int index) const;
  void _internal_add_outer_join_support(::exec::user::OuterJoinSupport value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_outer_join_support();
  public:
  ::exec::user::OuterJoinSupport outer_join_support(int index) const;
  void set_outer_join_support(int index, ::exec::user::OuterJoinSupport value);
  void add_outer_join_support(::exec::user::OuterJoinSupport value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& outer_join_support() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_outer_join_support();

  // repeated string sql_keywords = 43;
  int sql_keywords_size() const;
  private:
  int _internal_sql_keywords_size() const;
  public:
  void clear_sql_keywords();
  const std::string& sql_keywords(int index) const;
  std::string* mutable_sql_keywords(int index);
  void set_sql_keywords(int index, const std::string& value);
  void set_sql_keywords(int index, std::string&& value);
  void set_sql_keywords(int index, const char* value);
  void set_sql_keywords(int index, const char* value, size_t size);
  std::string* add_sql_keywords();
  void add_sql_keywords(const std::string& value);
  void add_sql_keywords(std::string&& value);
  void add_sql_keywords(const char* value);
  void add_sql_keywords(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& sql_keywords() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_sql_keywords();
  private:
  const std::string& _internal_sql_keywords(int index) const;
  std::string* _internal_add_sql_keywords();
  public:

  // repeated string string_functions = 44;
  int string_functions_size() const;
  private:
  int _internal_string_functions_size() const;
  public:
  void clear_string_functions();
  const std::string& string_functions(int index) const;
  std::string* mutable_string_functions(int index);
  void set_string_functions(int index, const std::string& value);
  void set_string_functions(int index, std::string&& value);
  void set_string_functions(int index, const char* value);
  void set_string_functions(int index, const char* value, size_t size);
  std::string* add_string_functions();
  void add_string_functions(const std::string& value);
  void add_string_functions(std::string&& value);
  void add_string_functions(const char* value);
  void add_string_functions(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& string_functions() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_string_functions();
  private:
  const std::string& _internal_string_functions(int index) const;
  std::string* _internal_add_string_functions();
  public:

  // repeated .exec.user.SubQuerySupport subquery_support = 45;
  int subquery_support_size() const;
  private:
  int _internal_subquery_support_size() const;
  public:
  void clear_subquery_support();
  private:
  ::exec::user::SubQuerySupport _internal_subquery_support(int index) const;
  void _internal_add_subquery_support(::exec::user::SubQuerySupport value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_subquery_support();
  public:
  ::exec::user::SubQuerySupport subquery_support(int index) const;
  void set_subquery_support(int index, ::exec::user::SubQuerySupport value);
  void add_subquery_support(::exec::user::SubQuerySupport value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& subquery_support() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_subquery_support();

  // repeated string system_functions = 46;
  int system_functions_size() const;
  private:
  int _internal_system_functions_size() const;
  public:
  void clear_system_functions();
  const std::string& system_functions(int index) const;
  std::string* mutable_system_functions(int index);
  void set_system_functions(int index, const std::string& value);
  void set_system_functions(int index, std::string&& value);
  void set_system_functions(int index, const char* value);
  void set_system_functions(int index, const char* value, size_t size);
  std::string* add_system_functions();
  void add_system_functions(const std::string& value);
  void add_system_functions(std::string&& value);
  void add_system_functions(const char* value);
  void add_system_functions(const char* value, size_t size);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>& system_functions() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>* mutable_system_functions();
  private:
  const std::string& _internal_system_functions(int index) const;
  std::string* _internal_add_system_functions();
  public:

  // repeated .exec.user.UnionSupport union_support = 49;
  int union_support_size() const;
  private:
  int _internal_union_support_size() const;
  public:
  void clear_union_support();
  private:
  ::exec::user::UnionSupport _internal_union_support(int index) const;
  void _internal_add_union_support(::exec::user::UnionSupport value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_union_support();
  public:
  ::exec::user::UnionSupport union_support(int index) const;
  void set_union_support(int index, ::exec::user::UnionSupport value);
  void add_union_support(::exec::user::UnionSupport value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& union_support() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_union_support();

  // optional string catalog_separator = 4;
  bool has_catalog_separator() const;
  private:
  bool _internal_has_catalog_separator() const;
  public:
  void clear_catalog_separator();
  const std::string& catalog_separator() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_catalog_separator(ArgT0&& arg0, ArgT... args);
  std::string* mutable_catalog_separator();
  std::string* release_catalog_separator();
  void set_allocated_catalog_separator(std::string* catalog_separator);
  private:
  const std::string& _internal_catalog_separator() const;
  void _internal_set_catalog_separator(const std::string& value);
  std::string* _internal_mutable_catalog_separator();
  public:

  // optional string catalog_term = 5;
  bool has_catalog_term() const;
  private:
  bool _internal_has_catalog_term() const;
  public:
  void clear_catalog_term();
  const std::string& catalog_term() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_catalog_term(ArgT0&& arg0, ArgT... args);
  std::string* mutable_catalog_term();
  std::string* release_catalog_term();
  void set_allocated_catalog_term(std::string* catalog_term);
  private:
  const std::string& _internal_catalog_term() const;
  void _internal_set_catalog_term(const std::string& value);
  std::string* _internal_mutable_catalog_term();
  public:

  // optional string identifier_quote_string = 14;
  bool has_identifier_quote_string() const;
  private:
  bool _internal_has_identifier_quote_string() const;
  public:
  void clear_identifier_quote_string();
  const std::string& identifier_quote_string() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_identifier_quote_string(ArgT0&& arg0, ArgT... args);
  std::string* mutable_identifier_quote_string();
  std::string* release_identifier_quote_string();
  void set_allocated_identifier_quote_string(std::string* identifier_quote_string);
  private:
  const std::string& _internal_identifier_quote_string() const;
  void _internal_set_identifier_quote_string(const std::string& value);
  std::string* _internal_mutable_identifier_quote_string();
  public:

  // optional string schema_term = 39;
  bool has_schema_term() const;
  private:
  bool _internal_has_schema_term() const;
  public:
  void clear_schema_term();
  const std::string& schema_term() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_schema_term(ArgT0&& arg0, ArgT... args);
  std::string* mutable_schema_term();
  std::string* release_schema_term();
  void set_allocated_schema_term(std::string* schema_term);
  private:
  const std::string& _internal_schema_term() const;
  void _internal_set_schema_term(const std::string& value);
  std::string* _internal_mutable_schema_term();
  public:

  // optional string search_escape_string = 40;
  bool has_search_escape_string() const;
  private:
  bool _internal_has_search_escape_string() const;
  public:
  void clear_search_escape_string();
  const std::string& search_escape_string() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_search_escape_string(ArgT0&& arg0, ArgT... args);
  std::string* mutable_search_escape_string();
  std::string* release_search_escape_string();
  void set_allocated_search_escape_string(std::string* search_escape_string);
  private:
  const std::string& _internal_search_escape_string() const;
  void _internal_set_search_escape_string(const std::string& value);
  std::string* _internal_mutable_search_escape_string();
  public:

  // optional string special_characters = 42;
  bool has_special_characters() const;
  private:
  bool _internal_has_special_characters() const;
  public:
  void clear_special_characters();
  const std::string& special_characters() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_special_characters(ArgT0&& arg0, ArgT... args);
  std::string* mutable_special_characters();
  std::string* release_special_characters();
  void set_allocated_special_characters(std::string* special_characters);
  private:
  const std::string& _internal_special_characters() const;
  void _internal_set_special_characters(const std::string& value);
  std::string* _internal_mutable_special_characters();
  public:

  // optional string table_term = 47;
  bool has_table_term() const;
  private:
  bool _internal_has_table_term() const;
  public:
  void clear_table_term();
  const std::string& table_term() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_table_term(ArgT0&& arg0, ArgT... args);
  std::string* mutable_table_term();
  std::string* release_table_term();
  void set_allocated_table_term(std::string* table_term);
  private:
  const std::string& _internal_table_term() const;
  void _internal_set_table_term(const std::string& value);
  std::string* _internal_mutable_table_term();
  public:

  // optional string current_schema = 50;
  bool has_current_schema() const;
  private:
  bool _internal_has_current_schema() const;
  public:
  void clear_current_schema();
  const std::string& current_schema() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_current_schema(ArgT0&& arg0, ArgT... args);
  std::string* mutable_current_schema();
  std::string* release_current_schema();
  void set_allocated_current_schema(std::string* current_schema);
  private:
  const std::string& _internal_current_schema() const;
  void _internal_set_current_schema(const std::string& value);
  std::string* _internal_mutable_current_schema();
  public:

  // optional bool all_tables_selectable = 1;
  bool has_all_tables_selectable() const;
  private:
  bool _internal_has_all_tables_selectable() const;
  public:
  void clear_all_tables_selectable();
  bool all_tables_selectable() const;
  void set_all_tables_selectable(bool value);
  private:
  bool _internal_all_tables_selectable() const;
  void _internal_set_all_tables_selectable(bool value);
  public:

  // optional bool blob_included_in_max_row_size = 2;
  bool has_blob_included_in_max_row_size() const;
  private:
  bool _internal_has_blob_included_in_max_row_size() const;
  public:
  void clear_blob_included_in_max_row_size();
  bool blob_included_in_max_row_size() const;
  void set_blob_included_in_max_row_size(bool value);
  private:
  bool _internal_blob_included_in_max_row_size() const;
  void _internal_set_blob_included_in_max_row_size(bool value);
  public:

  // optional bool catalog_at_start = 3;
  bool has_catalog_at_start() const;
  private:
  bool _internal_has_catalog_at_start() const;
  public:
  void clear_catalog_at_start();
  bool catalog_at_start() const;
  void set_catalog_at_start(bool value);
  private:
  bool _internal_catalog_at_start() const;
  void _internal_set_catalog_at_start(bool value);
  public:

  // optional bool column_aliasing_supported = 7;
  bool has_column_aliasing_supported() const;
  private:
  bool _internal_has_column_aliasing_supported() const;
  public:
  void clear_column_aliasing_supported();
  bool column_aliasing_supported() const;
  void set_column_aliasing_supported(bool value);
  private:
  bool _internal_column_aliasing_supported() const;
  void _internal_set_column_aliasing_supported(bool value);
  public:

  // optional .exec.user.IdentifierCasing identifier_casing = 13;
  bool has_identifier_casing() const;
  private:
  bool _internal_has_identifier_casing() const;
  public:
  void clear_identifier_casing();
  ::exec::user::IdentifierCasing identifier_casing() const;
  void set_identifier_casing(::exec::user::IdentifierCasing value);
  private:
  ::exec::user::IdentifierCasing _internal_identifier_casing() const;
  void _internal_set_identifier_casing(::exec::user::IdentifierCasing value);
  public:

  // optional uint32 max_binary_literal_length = 16;
  bool has_max_binary_literal_length() const;
  private:
  bool _internal_has_max_binary_literal_length() const;
  public:
  void clear_max_binary_literal_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_binary_literal_length() const;
  void set_max_binary_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_binary_literal_length() const;
  void _internal_set_max_binary_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_catalog_name_length = 17;
  bool has_max_catalog_name_length() const;
  private:
  bool _internal_has_max_catalog_name_length() const;
  public:
  void clear_max_catalog_name_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_catalog_name_length() const;
  void set_max_catalog_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_catalog_name_length() const;
  void _internal_set_max_catalog_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_char_literal_length = 18;
  bool has_max_char_literal_length() const;
  private:
  bool _internal_has_max_char_literal_length() const;
  public:
  void clear_max_char_literal_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_char_literal_length() const;
  void set_max_char_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_char_literal_length() const;
  void _internal_set_max_char_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_column_name_length = 19;
  bool has_max_column_name_length() const;
  private:
  bool _internal_has_max_column_name_length() const;
  public:
  void clear_max_column_name_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_column_name_length() const;
  void set_max_column_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_column_name_length() const;
  void _internal_set_max_column_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_columns_in_group_by = 20;
  bool has_max_columns_in_group_by() const;
  private:
  bool _internal_has_max_columns_in_group_by() const;
  public:
  void clear_max_columns_in_group_by();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_columns_in_group_by() const;
  void set_max_columns_in_group_by(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_columns_in_group_by() const;
  void _internal_set_max_columns_in_group_by(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_columns_in_order_by = 21;
  bool has_max_columns_in_order_by() const;
  private:
  bool _internal_has_max_columns_in_order_by() const;
  public:
  void clear_max_columns_in_order_by();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_columns_in_order_by() const;
  void set_max_columns_in_order_by(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_columns_in_order_by() const;
  void _internal_set_max_columns_in_order_by(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_columns_in_select = 22;
  bool has_max_columns_in_select() const;
  private:
  bool _internal_has_max_columns_in_select() const;
  public:
  void clear_max_columns_in_select();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_columns_in_select() const;
  void set_max_columns_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_columns_in_select() const;
  void _internal_set_max_columns_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_cursor_name_length = 23;
  bool has_max_cursor_name_length() const;
  private:
  bool _internal_has_max_cursor_name_length() const;
  public:
  void clear_max_cursor_name_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_cursor_name_length() const;
  void set_max_cursor_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_cursor_name_length() const;
  void _internal_set_max_cursor_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_logical_lob_size = 24;
  bool has_max_logical_lob_size() const;
  private:
  bool _internal_has_max_logical_lob_size() const;
  public:
  void clear_max_logical_lob_size();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_logical_lob_size() const;
  void set_max_logical_lob_size(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_logical_lob_size() const;
  void _internal_set_max_logical_lob_size(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_row_size = 25;
  bool has_max_row_size() const;
  private:
  bool _internal_has_max_row_size() const;
  public:
  void clear_max_row_size();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_row_size() const;
  void set_max_row_size(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_row_size() const;
  void _internal_set_max_row_size(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_schema_name_length = 26;
  bool has_max_schema_name_length() const;
  private:
  bool _internal_has_max_schema_name_length() const;
  public:
  void clear_max_schema_name_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_schema_name_length() const;
  void set_max_schema_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_schema_name_length() const;
  void _internal_set_max_schema_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_statement_length = 27;
  bool has_max_statement_length() const;
  private:
  bool _internal_has_max_statement_length() const;
  public:
  void clear_max_statement_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_statement_length() const;
  void set_max_statement_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_statement_length() const;
  void _internal_set_max_statement_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_statements = 28;
  bool has_max_statements() const;
  private:
  bool _internal_has_max_statements() const;
  public:
  void clear_max_statements();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_statements() const;
  void set_max_statements(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_statements() const;
  void _internal_set_max_statements(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_table_name_length = 29;
  bool has_max_table_name_length() const;
  private:
  bool _internal_has_max_table_name_length() const;
  public:
  void clear_max_table_name_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_table_name_length() const;
  void set_max_table_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_table_name_length() const;
  void _internal_set_max_table_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_tables_in_select = 30;
  bool has_max_tables_in_select() const;
  private:
  bool _internal_has_max_tables_in_select() const;
  public:
  void clear_max_tables_in_select();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_tables_in_select() const;
  void set_max_tables_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_tables_in_select() const;
  void _internal_set_max_tables_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional uint32 max_user_name_length = 31;
  bool has_max_user_name_length() const;
  private:
  bool _internal_has_max_user_name_length() const;
  public:
  void clear_max_user_name_length();
  ::PROTOBUF_NAMESPACE_ID::uint32 max_user_name_length() const;
  void set_max_user_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::uint32 _internal_max_user_name_length() const;
  void _internal_set_max_user_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value);
  public:

  // optional bool like_escape_clause_supported = 15;
  bool has_like_escape_clause_supported() const;
  private:
  bool _internal_has_like_escape_clause_supported() const;
  public:
  void clear_like_escape_clause_supported();
  bool like_escape_clause_supported() const;
  void set_like_escape_clause_supported(bool value);
  private:
  bool _internal_like_escape_clause_supported() const;
  void _internal_set_like_escape_clause_supported(bool value);
  public:

  // optional bool null_plus_non_null_equals_null = 33;
  bool has_null_plus_non_null_equals_null() const;
  private:
  bool _internal_has_null_plus_non_null_equals_null() const;
  public:
  void clear_null_plus_non_null_equals_null();
  bool null_plus_non_null_equals_null() const;
  void set_null_plus_non_null_equals_null(bool value);
  private:
  bool _internal_null_plus_non_null_equals_null() const;
  void _internal_set_null_plus_non_null_equals_null(bool value);
  public:

  // optional bool read_only = 38;
  bool has_read_only() const;
  private:
  bool _internal_has_read_only() const;
  public:
  void clear_read_only();
  bool read_only() const;
  void set_read_only(bool value);
  private:
  bool _internal_read_only() const;
  void _internal_set_read_only(bool value);
  public:

  // optional bool select_for_update_supported = 41;
  bool has_select_for_update_supported() const;
  private:
  bool _internal_has_select_for_update_supported() const;
  public:
  void clear_select_for_update_supported();
  bool select_for_update_supported() const;
  void set_select_for_update_supported(bool value);
  private:
  bool _internal_select_for_update_supported() const;
  void _internal_set_select_for_update_supported(bool value);
  public:

  // optional .exec.user.NullCollation null_collation = 32;
  bool has_null_collation() const;
  private:
  bool _internal_has_null_collation() const;
  public:
  void clear_null_collation();
  ::exec::user::NullCollation null_collation() const;
  void set_null_collation(::exec::user::NullCollation value);
  private:
  ::exec::user::NullCollation _internal_null_collation() const;
  void _internal_set_null_collation(::exec::user::NullCollation value);
  public:

  // optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;
  bool has_quoted_identifier_casing() const;
  private:
  bool _internal_has_quoted_identifier_casing() const;
  public:
  void clear_quoted_identifier_casing();
  ::exec::user::IdentifierCasing quoted_identifier_casing() const;
  void set_quoted_identifier_casing(::exec::user::IdentifierCasing value);
  private:
  ::exec::user::IdentifierCasing _internal_quoted_identifier_casing() const;
  void _internal_set_quoted_identifier_casing(::exec::user::IdentifierCasing value);
  public:

  // optional bool transaction_supported = 48;
  bool has_transaction_supported() const;
  private:
  bool _internal_has_transaction_supported() const;
  public:
  void clear_transaction_supported();
  bool transaction_supported() const;
  void set_transaction_supported(bool value);
  private:
  bool _internal_transaction_supported() const;
  void _internal_set_transaction_supported(bool value);
  public:

  // optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;
  bool has_correlation_names_support() const;
  private:
  bool _internal_has_correlation_names_support() const;
  public:
  void clear_correlation_names_support();
  ::exec::user::CorrelationNamesSupport correlation_names_support() const;
  void set_correlation_names_support(::exec::user::CorrelationNamesSupport value);
  private:
  ::exec::user::CorrelationNamesSupport _internal_correlation_names_support() const;
  void _internal_set_correlation_names_support(::exec::user::CorrelationNamesSupport value);
  public:

  // optional .exec.user.GroupBySupport group_by_support = 12;
  bool has_group_by_support() const;
  private:
  bool _internal_has_group_by_support() const;
  public:
  void clear_group_by_support();
  ::exec::user::GroupBySupport group_by_support() const;
  void set_group_by_support(::exec::user::GroupBySupport value);
  private:
  ::exec::user::GroupBySupport _internal_group_by_support() const;
  void _internal_set_group_by_support(::exec::user::GroupBySupport value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.ServerMeta)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<2> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> collate_support_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ConvertSupport > convert_support_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> date_time_functions_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> date_time_literals_support_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> numeric_functions_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> order_by_support_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> outer_join_support_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> sql_keywords_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> string_functions_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> subquery_support_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string> system_functions_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> union_support_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr catalog_separator_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr catalog_term_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr identifier_quote_string_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr schema_term_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr search_escape_string_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr special_characters_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr table_term_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr current_schema_;
  bool all_tables_selectable_;
  bool blob_included_in_max_row_size_;
  bool catalog_at_start_;
  bool column_aliasing_supported_;
  int identifier_casing_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_binary_literal_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_catalog_name_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_char_literal_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_column_name_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_columns_in_group_by_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_columns_in_order_by_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_columns_in_select_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_cursor_name_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_logical_lob_size_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_row_size_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_schema_name_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_statement_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_statements_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_table_name_length_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_tables_in_select_;
  ::PROTOBUF_NAMESPACE_ID::uint32 max_user_name_length_;
  bool like_escape_clause_supported_;
  bool null_plus_non_null_equals_null_;
  bool read_only_;
  bool select_for_update_supported_;
  int null_collation_;
  int quoted_identifier_casing_;
  bool transaction_supported_;
  int correlation_names_support_;
  int group_by_support_;
  friend struct ::TableStruct_User_2eproto;
};
// -------------------------------------------------------------------

class RunQuery PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:exec.user.RunQuery) */ {
 public:
  inline RunQuery() : RunQuery(nullptr) {}
  ~RunQuery() override;
  explicit constexpr RunQuery(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  RunQuery(const RunQuery& from);
  RunQuery(RunQuery&& from) noexcept
    : RunQuery() {
    *this = ::std::move(from);
  }

  inline RunQuery& operator=(const RunQuery& from) {
    CopyFrom(from);
    return *this;
  }
  inline RunQuery& operator=(RunQuery&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const RunQuery& default_instance() {
    return *internal_default_instance();
  }
  static inline const RunQuery* internal_default_instance() {
    return reinterpret_cast<const RunQuery*>(
               &_RunQuery_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    30;

  friend void swap(RunQuery& a, RunQuery& b) {
    a.Swap(&b);
  }
  inline void Swap(RunQuery* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(RunQuery* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline RunQuery* New() const final {
    return CreateMaybeMessage<RunQuery>(nullptr);
  }

  RunQuery* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<RunQuery>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const RunQuery& from);
  void MergeFrom(const RunQuery& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RunQuery* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "exec.user.RunQuery";
  }
  protected:
  explicit RunQuery(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kFragmentsFieldNumber = 4,
    kPlanFieldNumber = 3,
    kPreparedStatementHandleFieldNumber = 5,
    kAutolimitRowcountFieldNumber = 6,
    kResultsModeFieldNumber = 1,
    kTypeFieldNumber = 2,
  };
  // repeated .exec.bit.control.PlanFragment fragments = 4;
  int fragments_size() const;
  private:
  int _internal_fragments_size() const;
  public:
  void clear_fragments();
  ::exec::bit::control::PlanFragment* mutable_fragments(int index);
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >*
      mutable_fragments();
  private:
  const ::exec::bit::control::PlanFragment& _internal_fragments(int index) const;
  ::exec::bit::control::PlanFragment* _internal_add_fragments();
  public:
  const ::exec::bit::control::PlanFragment& fragments(int index) const;
  ::exec::bit::control::PlanFragment* add_fragments();
  const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >&
      fragments() const;

  // optional string plan = 3;
  bool has_plan() const;
  private:
  bool _internal_has_plan() const;
  public:
  void clear_plan();
  const std::string& plan() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_plan(ArgT0&& arg0, ArgT... args);
  std::string* mutable_plan();
  std::string* release_plan();
  void set_allocated_plan(std::string* plan);
  private:
  const std::string& _internal_plan() const;
  void _internal_set_plan(const std::string& value);
  std::string* _internal_mutable_plan();
  public:

  // optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;
  bool has_prepared_statement_handle() const;
  private:
  bool _internal_has_prepared_statement_handle() const;
  public:
  void clear_prepared_statement_handle();
  const ::exec::user::PreparedStatementHandle& prepared_statement_handle() const;
  ::exec::user::PreparedStatementHandle* release_prepared_statement_handle();
  ::exec::user::PreparedStatementHandle* mutable_prepared_statement_handle();
  void set_allocated_prepared_statement_handle(::exec::user::PreparedStatementHandle* prepared_statement_handle);
  private:
  const ::exec::user::PreparedStatementHandle& _internal_prepared_statement_handle() const;
  ::exec::user::PreparedStatementHandle* _internal_mutable_prepared_statement_handle();
  public:
  void unsafe_arena_set_allocated_prepared_statement_handle(
      ::exec::user::PreparedStatementHandle* prepared_statement_handle);
  ::exec::user::PreparedStatementHandle* unsafe_arena_release_prepared_statement_handle();

  // optional int32 autolimit_rowcount = 6;
  bool has_autolimit_rowcount() const;
  private:
  bool _internal_has_autolimit_rowcount() const;
  public:
  void clear_autolimit_rowcount();
  ::PROTOBUF_NAMESPACE_ID::int32 autolimit_rowcount() const;
  void set_autolimit_rowcount(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_autolimit_rowcount() const;
  void _internal_set_autolimit_rowcount(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional .exec.user.QueryResultsMode results_mode = 1;
  bool has_results_mode() const;
  private:
  bool _internal_has_results_mode() const;
  public:
  void clear_results_mode();
  ::exec::user::QueryResultsMode results_mode() const;
  void set_results_mode(::exec::user::QueryResultsMode value);
  private:
  ::exec::user::QueryResultsMode _internal_results_mode() const;
  void _internal_set_results_mode(::exec::user::QueryResultsMode value);
  public:

  // optional .exec.shared.QueryType type = 2;
  bool has_type() const;
  private:
  bool _internal_has_type() const;
  public:
  void clear_type();
  ::exec::shared::QueryType type() const;
  void set_type(::exec::shared::QueryType value);
  private:
  ::exec::shared::QueryType _internal_type() const;
  void _internal_set_type(::exec::shared::QueryType value);
  public:

  // @@protoc_insertion_point(class_scope:exec.user.RunQuery)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment > fragments_;
  ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr plan_;
  ::exec::user::PreparedStatementHandle* prepared_statement_handle_;
  ::PROTOBUF_NAMESPACE_ID::int32 autolimit_rowcount_;
  int results_mode_;
  int type_;
  friend struct ::TableStruct_User_2eproto;
};
// ===================================================================


// ===================================================================

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// Property

// required string key = 1;
inline bool Property::_internal_has_key() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool Property::has_key() const {
  return _internal_has_key();
}
inline void Property::clear_key() {
  key_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& Property::key() const {
  // @@protoc_insertion_point(field_get:exec.user.Property.key)
  return _internal_key();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void Property::set_key(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 key_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.Property.key)
}
inline std::string* Property::mutable_key() {
  // @@protoc_insertion_point(field_mutable:exec.user.Property.key)
  return _internal_mutable_key();
}
inline const std::string& Property::_internal_key() const {
  return key_.Get();
}
inline void Property::_internal_set_key(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  key_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* Property::_internal_mutable_key() {
  _has_bits_[0] |= 0x00000001u;
  return key_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* Property::release_key() {
  // @@protoc_insertion_point(field_release:exec.user.Property.key)
  if (!_internal_has_key()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return key_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void Property::set_allocated_key(std::string* key) {
  if (key != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  key_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), key,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.Property.key)
}

// required string value = 2;
inline bool Property::_internal_has_value() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool Property::has_value() const {
  return _internal_has_value();
}
inline void Property::clear_value() {
  value_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& Property::value() const {
  // @@protoc_insertion_point(field_get:exec.user.Property.value)
  return _internal_value();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void Property::set_value(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.Property.value)
}
inline std::string* Property::mutable_value() {
  // @@protoc_insertion_point(field_mutable:exec.user.Property.value)
  return _internal_mutable_value();
}
inline const std::string& Property::_internal_value() const {
  return value_.Get();
}
inline void Property::_internal_set_value(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* Property::_internal_mutable_value() {
  _has_bits_[0] |= 0x00000002u;
  return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* Property::release_value() {
  // @@protoc_insertion_point(field_release:exec.user.Property.value)
  if (!_internal_has_value()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void Property::set_allocated_value(std::string* value) {
  if (value != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.Property.value)
}

// -------------------------------------------------------------------

// UserProperties

// repeated .exec.user.Property properties = 1;
inline int UserProperties::_internal_properties_size() const {
  return properties_.size();
}
inline int UserProperties::properties_size() const {
  return _internal_properties_size();
}
inline void UserProperties::clear_properties() {
  properties_.Clear();
}
inline ::exec::user::Property* UserProperties::mutable_properties(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.UserProperties.properties)
  return properties_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::Property >*
UserProperties::mutable_properties() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.UserProperties.properties)
  return &properties_;
}
inline const ::exec::user::Property& UserProperties::_internal_properties(int index) const {
  return properties_.Get(index);
}
inline const ::exec::user::Property& UserProperties::properties(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.UserProperties.properties)
  return _internal_properties(index);
}
inline ::exec::user::Property* UserProperties::_internal_add_properties() {
  return properties_.Add();
}
inline ::exec::user::Property* UserProperties::add_properties() {
  // @@protoc_insertion_point(field_add:exec.user.UserProperties.properties)
  return _internal_add_properties();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::Property >&
UserProperties::properties() const {
  // @@protoc_insertion_point(field_list:exec.user.UserProperties.properties)
  return properties_;
}

// -------------------------------------------------------------------

// RpcEndpointInfos

// optional string name = 1;
inline bool RpcEndpointInfos::_internal_has_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_name() const {
  return _internal_has_name();
}
inline void RpcEndpointInfos::clear_name() {
  name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& RpcEndpointInfos::name() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.name)
  return _internal_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void RpcEndpointInfos::set_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.name)
}
inline std::string* RpcEndpointInfos::mutable_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.RpcEndpointInfos.name)
  return _internal_mutable_name();
}
inline const std::string& RpcEndpointInfos::_internal_name() const {
  return name_.Get();
}
inline void RpcEndpointInfos::_internal_set_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* RpcEndpointInfos::_internal_mutable_name() {
  _has_bits_[0] |= 0x00000001u;
  return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* RpcEndpointInfos::release_name() {
  // @@protoc_insertion_point(field_release:exec.user.RpcEndpointInfos.name)
  if (!_internal_has_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void RpcEndpointInfos::set_allocated_name(std::string* name) {
  if (name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.RpcEndpointInfos.name)
}

// optional string version = 2;
inline bool RpcEndpointInfos::_internal_has_version() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_version() const {
  return _internal_has_version();
}
inline void RpcEndpointInfos::clear_version() {
  version_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& RpcEndpointInfos::version() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.version)
  return _internal_version();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void RpcEndpointInfos::set_version(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.version)
}
inline std::string* RpcEndpointInfos::mutable_version() {
  // @@protoc_insertion_point(field_mutable:exec.user.RpcEndpointInfos.version)
  return _internal_mutable_version();
}
inline const std::string& RpcEndpointInfos::_internal_version() const {
  return version_.Get();
}
inline void RpcEndpointInfos::_internal_set_version(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* RpcEndpointInfos::_internal_mutable_version() {
  _has_bits_[0] |= 0x00000002u;
  return version_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* RpcEndpointInfos::release_version() {
  // @@protoc_insertion_point(field_release:exec.user.RpcEndpointInfos.version)
  if (!_internal_has_version()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return version_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void RpcEndpointInfos::set_allocated_version(std::string* version) {
  if (version != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  version_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), version,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.RpcEndpointInfos.version)
}

// optional uint32 majorVersion = 3;
inline bool RpcEndpointInfos::_internal_has_majorversion() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_majorversion() const {
  return _internal_has_majorversion();
}
inline void RpcEndpointInfos::clear_majorversion() {
  majorversion_ = 0u;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::_internal_majorversion() const {
  return majorversion_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::majorversion() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.majorVersion)
  return _internal_majorversion();
}
inline void RpcEndpointInfos::_internal_set_majorversion(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00000010u;
  majorversion_ = value;
}
inline void RpcEndpointInfos::set_majorversion(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_majorversion(value);
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.majorVersion)
}

// optional uint32 minorVersion = 4;
inline bool RpcEndpointInfos::_internal_has_minorversion() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_minorversion() const {
  return _internal_has_minorversion();
}
inline void RpcEndpointInfos::clear_minorversion() {
  minorversion_ = 0u;
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::_internal_minorversion() const {
  return minorversion_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::minorversion() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.minorVersion)
  return _internal_minorversion();
}
inline void RpcEndpointInfos::_internal_set_minorversion(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00000020u;
  minorversion_ = value;
}
inline void RpcEndpointInfos::set_minorversion(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_minorversion(value);
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.minorVersion)
}

// optional uint32 patchVersion = 5;
inline bool RpcEndpointInfos::_internal_has_patchversion() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_patchversion() const {
  return _internal_has_patchversion();
}
inline void RpcEndpointInfos::clear_patchversion() {
  patchversion_ = 0u;
  _has_bits_[0] &= ~0x00000040u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::_internal_patchversion() const {
  return patchversion_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::patchversion() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.patchVersion)
  return _internal_patchversion();
}
inline void RpcEndpointInfos::_internal_set_patchversion(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00000040u;
  patchversion_ = value;
}
inline void RpcEndpointInfos::set_patchversion(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_patchversion(value);
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.patchVersion)
}

// optional string application = 6;
inline bool RpcEndpointInfos::_internal_has_application() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_application() const {
  return _internal_has_application();
}
inline void RpcEndpointInfos::clear_application() {
  application_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& RpcEndpointInfos::application() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.application)
  return _internal_application();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void RpcEndpointInfos::set_application(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 application_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.application)
}
inline std::string* RpcEndpointInfos::mutable_application() {
  // @@protoc_insertion_point(field_mutable:exec.user.RpcEndpointInfos.application)
  return _internal_mutable_application();
}
inline const std::string& RpcEndpointInfos::_internal_application() const {
  return application_.Get();
}
inline void RpcEndpointInfos::_internal_set_application(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  application_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* RpcEndpointInfos::_internal_mutable_application() {
  _has_bits_[0] |= 0x00000004u;
  return application_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* RpcEndpointInfos::release_application() {
  // @@protoc_insertion_point(field_release:exec.user.RpcEndpointInfos.application)
  if (!_internal_has_application()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return application_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void RpcEndpointInfos::set_allocated_application(std::string* application) {
  if (application != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  application_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), application,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.RpcEndpointInfos.application)
}

// optional uint32 buildNumber = 7;
inline bool RpcEndpointInfos::_internal_has_buildnumber() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_buildnumber() const {
  return _internal_has_buildnumber();
}
inline void RpcEndpointInfos::clear_buildnumber() {
  buildnumber_ = 0u;
  _has_bits_[0] &= ~0x00000080u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::_internal_buildnumber() const {
  return buildnumber_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 RpcEndpointInfos::buildnumber() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.buildNumber)
  return _internal_buildnumber();
}
inline void RpcEndpointInfos::_internal_set_buildnumber(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00000080u;
  buildnumber_ = value;
}
inline void RpcEndpointInfos::set_buildnumber(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_buildnumber(value);
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.buildNumber)
}

// optional string versionQualifier = 8;
inline bool RpcEndpointInfos::_internal_has_versionqualifier() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool RpcEndpointInfos::has_versionqualifier() const {
  return _internal_has_versionqualifier();
}
inline void RpcEndpointInfos::clear_versionqualifier() {
  versionqualifier_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& RpcEndpointInfos::versionqualifier() const {
  // @@protoc_insertion_point(field_get:exec.user.RpcEndpointInfos.versionQualifier)
  return _internal_versionqualifier();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void RpcEndpointInfos::set_versionqualifier(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 versionqualifier_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.RpcEndpointInfos.versionQualifier)
}
inline std::string* RpcEndpointInfos::mutable_versionqualifier() {
  // @@protoc_insertion_point(field_mutable:exec.user.RpcEndpointInfos.versionQualifier)
  return _internal_mutable_versionqualifier();
}
inline const std::string& RpcEndpointInfos::_internal_versionqualifier() const {
  return versionqualifier_.Get();
}
inline void RpcEndpointInfos::_internal_set_versionqualifier(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  versionqualifier_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* RpcEndpointInfos::_internal_mutable_versionqualifier() {
  _has_bits_[0] |= 0x00000008u;
  return versionqualifier_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* RpcEndpointInfos::release_versionqualifier() {
  // @@protoc_insertion_point(field_release:exec.user.RpcEndpointInfos.versionQualifier)
  if (!_internal_has_versionqualifier()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return versionqualifier_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void RpcEndpointInfos::set_allocated_versionqualifier(std::string* versionqualifier) {
  if (versionqualifier != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  versionqualifier_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), versionqualifier,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.RpcEndpointInfos.versionQualifier)
}

// -------------------------------------------------------------------

// UserToBitHandshake

// optional .exec.shared.RpcChannel channel = 1 [default = USER];
inline bool UserToBitHandshake::_internal_has_channel() const {
  bool value = (_has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool UserToBitHandshake::has_channel() const {
  return _internal_has_channel();
}
inline void UserToBitHandshake::clear_channel() {
  channel_ = 2;
  _has_bits_[0] &= ~0x00000100u;
}
inline ::exec::shared::RpcChannel UserToBitHandshake::_internal_channel() const {
  return static_cast< ::exec::shared::RpcChannel >(channel_);
}
inline ::exec::shared::RpcChannel UserToBitHandshake::channel() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.channel)
  return _internal_channel();
}
inline void UserToBitHandshake::_internal_set_channel(::exec::shared::RpcChannel value) {
  assert(::exec::shared::RpcChannel_IsValid(value));
  _has_bits_[0] |= 0x00000100u;
  channel_ = value;
}
inline void UserToBitHandshake::set_channel(::exec::shared::RpcChannel value) {
  _internal_set_channel(value);
  // @@protoc_insertion_point(field_set:exec.user.UserToBitHandshake.channel)
}

// optional bool support_listening = 2;
inline bool UserToBitHandshake::_internal_has_support_listening() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool UserToBitHandshake::has_support_listening() const {
  return _internal_has_support_listening();
}
inline void UserToBitHandshake::clear_support_listening() {
  support_listening_ = false;
  _has_bits_[0] &= ~0x00000010u;
}
inline bool UserToBitHandshake::_internal_support_listening() const {
  return support_listening_;
}
inline bool UserToBitHandshake::support_listening() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.support_listening)
  return _internal_support_listening();
}
inline void UserToBitHandshake::_internal_set_support_listening(bool value) {
  _has_bits_[0] |= 0x00000010u;
  support_listening_ = value;
}
inline void UserToBitHandshake::set_support_listening(bool value) {
  _internal_set_support_listening(value);
  // @@protoc_insertion_point(field_set:exec.user.UserToBitHandshake.support_listening)
}

// optional int32 rpc_version = 3;
inline bool UserToBitHandshake::_internal_has_rpc_version() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool UserToBitHandshake::has_rpc_version() const {
  return _internal_has_rpc_version();
}
inline void UserToBitHandshake::clear_rpc_version() {
  rpc_version_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 UserToBitHandshake::_internal_rpc_version() const {
  return rpc_version_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 UserToBitHandshake::rpc_version() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.rpc_version)
  return _internal_rpc_version();
}
inline void UserToBitHandshake::_internal_set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  rpc_version_ = value;
}
inline void UserToBitHandshake::set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_rpc_version(value);
  // @@protoc_insertion_point(field_set:exec.user.UserToBitHandshake.rpc_version)
}

// optional .exec.shared.UserCredentials credentials = 4;
inline bool UserToBitHandshake::_internal_has_credentials() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || credentials_ != nullptr);
  return value;
}
inline bool UserToBitHandshake::has_credentials() const {
  return _internal_has_credentials();
}
inline const ::exec::shared::UserCredentials& UserToBitHandshake::_internal_credentials() const {
  const ::exec::shared::UserCredentials* p = credentials_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::UserCredentials&>(
      ::exec::shared::_UserCredentials_default_instance_);
}
inline const ::exec::shared::UserCredentials& UserToBitHandshake::credentials() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.credentials)
  return _internal_credentials();
}
inline void UserToBitHandshake::unsafe_arena_set_allocated_credentials(
    ::exec::shared::UserCredentials* credentials) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(credentials_);
  }
  credentials_ = credentials;
  if (credentials) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.UserToBitHandshake.credentials)
}
inline ::exec::shared::UserCredentials* UserToBitHandshake::release_credentials() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::UserCredentials* temp = credentials_;
  credentials_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::UserCredentials* UserToBitHandshake::unsafe_arena_release_credentials() {
  // @@protoc_insertion_point(field_release:exec.user.UserToBitHandshake.credentials)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::UserCredentials* temp = credentials_;
  credentials_ = nullptr;
  return temp;
}
inline ::exec::shared::UserCredentials* UserToBitHandshake::_internal_mutable_credentials() {
  _has_bits_[0] |= 0x00000001u;
  if (credentials_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::UserCredentials>(GetArena());
    credentials_ = p;
  }
  return credentials_;
}
inline ::exec::shared::UserCredentials* UserToBitHandshake::mutable_credentials() {
  // @@protoc_insertion_point(field_mutable:exec.user.UserToBitHandshake.credentials)
  return _internal_mutable_credentials();
}
inline void UserToBitHandshake::set_allocated_credentials(::exec::shared::UserCredentials* credentials) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(credentials_);
  }
  if (credentials) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(credentials)->GetArena();
    if (message_arena != submessage_arena) {
      credentials = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, credentials, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  credentials_ = credentials;
  // @@protoc_insertion_point(field_set_allocated:exec.user.UserToBitHandshake.credentials)
}

// optional .exec.user.UserProperties properties = 5;
inline bool UserToBitHandshake::_internal_has_properties() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || properties_ != nullptr);
  return value;
}
inline bool UserToBitHandshake::has_properties() const {
  return _internal_has_properties();
}
inline void UserToBitHandshake::clear_properties() {
  if (properties_ != nullptr) properties_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::user::UserProperties& UserToBitHandshake::_internal_properties() const {
  const ::exec::user::UserProperties* p = properties_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::UserProperties&>(
      ::exec::user::_UserProperties_default_instance_);
}
inline const ::exec::user::UserProperties& UserToBitHandshake::properties() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.properties)
  return _internal_properties();
}
inline void UserToBitHandshake::unsafe_arena_set_allocated_properties(
    ::exec::user::UserProperties* properties) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(properties_);
  }
  properties_ = properties;
  if (properties) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.UserToBitHandshake.properties)
}
inline ::exec::user::UserProperties* UserToBitHandshake::release_properties() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::UserProperties* temp = properties_;
  properties_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::UserProperties* UserToBitHandshake::unsafe_arena_release_properties() {
  // @@protoc_insertion_point(field_release:exec.user.UserToBitHandshake.properties)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::UserProperties* temp = properties_;
  properties_ = nullptr;
  return temp;
}
inline ::exec::user::UserProperties* UserToBitHandshake::_internal_mutable_properties() {
  _has_bits_[0] |= 0x00000002u;
  if (properties_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::UserProperties>(GetArena());
    properties_ = p;
  }
  return properties_;
}
inline ::exec::user::UserProperties* UserToBitHandshake::mutable_properties() {
  // @@protoc_insertion_point(field_mutable:exec.user.UserToBitHandshake.properties)
  return _internal_mutable_properties();
}
inline void UserToBitHandshake::set_allocated_properties(::exec::user::UserProperties* properties) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete properties_;
  }
  if (properties) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(properties);
    if (message_arena != submessage_arena) {
      properties = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, properties, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  properties_ = properties;
  // @@protoc_insertion_point(field_set_allocated:exec.user.UserToBitHandshake.properties)
}

// optional bool support_complex_types = 6 [default = false];
inline bool UserToBitHandshake::_internal_has_support_complex_types() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool UserToBitHandshake::has_support_complex_types() const {
  return _internal_has_support_complex_types();
}
inline void UserToBitHandshake::clear_support_complex_types() {
  support_complex_types_ = false;
  _has_bits_[0] &= ~0x00000020u;
}
inline bool UserToBitHandshake::_internal_support_complex_types() const {
  return support_complex_types_;
}
inline bool UserToBitHandshake::support_complex_types() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.support_complex_types)
  return _internal_support_complex_types();
}
inline void UserToBitHandshake::_internal_set_support_complex_types(bool value) {
  _has_bits_[0] |= 0x00000020u;
  support_complex_types_ = value;
}
inline void UserToBitHandshake::set_support_complex_types(bool value) {
  _internal_set_support_complex_types(value);
  // @@protoc_insertion_point(field_set:exec.user.UserToBitHandshake.support_complex_types)
}

// optional bool support_timeout = 7 [default = false];
inline bool UserToBitHandshake::_internal_has_support_timeout() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool UserToBitHandshake::has_support_timeout() const {
  return _internal_has_support_timeout();
}
inline void UserToBitHandshake::clear_support_timeout() {
  support_timeout_ = false;
  _has_bits_[0] &= ~0x00000040u;
}
inline bool UserToBitHandshake::_internal_support_timeout() const {
  return support_timeout_;
}
inline bool UserToBitHandshake::support_timeout() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.support_timeout)
  return _internal_support_timeout();
}
inline void UserToBitHandshake::_internal_set_support_timeout(bool value) {
  _has_bits_[0] |= 0x00000040u;
  support_timeout_ = value;
}
inline void UserToBitHandshake::set_support_timeout(bool value) {
  _internal_set_support_timeout(value);
  // @@protoc_insertion_point(field_set:exec.user.UserToBitHandshake.support_timeout)
}

// optional .exec.user.RpcEndpointInfos client_infos = 8;
inline bool UserToBitHandshake::_internal_has_client_infos() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || client_infos_ != nullptr);
  return value;
}
inline bool UserToBitHandshake::has_client_infos() const {
  return _internal_has_client_infos();
}
inline void UserToBitHandshake::clear_client_infos() {
  if (client_infos_ != nullptr) client_infos_->Clear();
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::user::RpcEndpointInfos& UserToBitHandshake::_internal_client_infos() const {
  const ::exec::user::RpcEndpointInfos* p = client_infos_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::RpcEndpointInfos&>(
      ::exec::user::_RpcEndpointInfos_default_instance_);
}
inline const ::exec::user::RpcEndpointInfos& UserToBitHandshake::client_infos() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.client_infos)
  return _internal_client_infos();
}
inline void UserToBitHandshake::unsafe_arena_set_allocated_client_infos(
    ::exec::user::RpcEndpointInfos* client_infos) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(client_infos_);
  }
  client_infos_ = client_infos;
  if (client_infos) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.UserToBitHandshake.client_infos)
}
inline ::exec::user::RpcEndpointInfos* UserToBitHandshake::release_client_infos() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::RpcEndpointInfos* temp = client_infos_;
  client_infos_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::RpcEndpointInfos* UserToBitHandshake::unsafe_arena_release_client_infos() {
  // @@protoc_insertion_point(field_release:exec.user.UserToBitHandshake.client_infos)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::RpcEndpointInfos* temp = client_infos_;
  client_infos_ = nullptr;
  return temp;
}
inline ::exec::user::RpcEndpointInfos* UserToBitHandshake::_internal_mutable_client_infos() {
  _has_bits_[0] |= 0x00000004u;
  if (client_infos_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::RpcEndpointInfos>(GetArena());
    client_infos_ = p;
  }
  return client_infos_;
}
inline ::exec::user::RpcEndpointInfos* UserToBitHandshake::mutable_client_infos() {
  // @@protoc_insertion_point(field_mutable:exec.user.UserToBitHandshake.client_infos)
  return _internal_mutable_client_infos();
}
inline void UserToBitHandshake::set_allocated_client_infos(::exec::user::RpcEndpointInfos* client_infos) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete client_infos_;
  }
  if (client_infos) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(client_infos);
    if (message_arena != submessage_arena) {
      client_infos = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, client_infos, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  client_infos_ = client_infos;
  // @@protoc_insertion_point(field_set_allocated:exec.user.UserToBitHandshake.client_infos)
}

// optional .exec.user.SaslSupport sasl_support = 9;
inline bool UserToBitHandshake::_internal_has_sasl_support() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool UserToBitHandshake::has_sasl_support() const {
  return _internal_has_sasl_support();
}
inline void UserToBitHandshake::clear_sasl_support() {
  sasl_support_ = 0;
  _has_bits_[0] &= ~0x00000080u;
}
inline ::exec::user::SaslSupport UserToBitHandshake::_internal_sasl_support() const {
  return static_cast< ::exec::user::SaslSupport >(sasl_support_);
}
inline ::exec::user::SaslSupport UserToBitHandshake::sasl_support() const {
  // @@protoc_insertion_point(field_get:exec.user.UserToBitHandshake.sasl_support)
  return _internal_sasl_support();
}
inline void UserToBitHandshake::_internal_set_sasl_support(::exec::user::SaslSupport value) {
  assert(::exec::user::SaslSupport_IsValid(value));
  _has_bits_[0] |= 0x00000080u;
  sasl_support_ = value;
}
inline void UserToBitHandshake::set_sasl_support(::exec::user::SaslSupport value) {
  _internal_set_sasl_support(value);
  // @@protoc_insertion_point(field_set:exec.user.UserToBitHandshake.sasl_support)
}

// -------------------------------------------------------------------

// RequestResults

// optional .exec.shared.QueryId query_id = 1;
inline bool RequestResults::_internal_has_query_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || query_id_ != nullptr);
  return value;
}
inline bool RequestResults::has_query_id() const {
  return _internal_has_query_id();
}
inline const ::exec::shared::QueryId& RequestResults::_internal_query_id() const {
  const ::exec::shared::QueryId* p = query_id_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::QueryId&>(
      ::exec::shared::_QueryId_default_instance_);
}
inline const ::exec::shared::QueryId& RequestResults::query_id() const {
  // @@protoc_insertion_point(field_get:exec.user.RequestResults.query_id)
  return _internal_query_id();
}
inline void RequestResults::unsafe_arena_set_allocated_query_id(
    ::exec::shared::QueryId* query_id) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  query_id_ = query_id;
  if (query_id) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.RequestResults.query_id)
}
inline ::exec::shared::QueryId* RequestResults::release_query_id() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::QueryId* RequestResults::unsafe_arena_release_query_id() {
  // @@protoc_insertion_point(field_release:exec.user.RequestResults.query_id)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  return temp;
}
inline ::exec::shared::QueryId* RequestResults::_internal_mutable_query_id() {
  _has_bits_[0] |= 0x00000001u;
  if (query_id_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArena());
    query_id_ = p;
  }
  return query_id_;
}
inline ::exec::shared::QueryId* RequestResults::mutable_query_id() {
  // @@protoc_insertion_point(field_mutable:exec.user.RequestResults.query_id)
  return _internal_mutable_query_id();
}
inline void RequestResults::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  if (query_id) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id)->GetArena();
    if (message_arena != submessage_arena) {
      query_id = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, query_id, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  query_id_ = query_id;
  // @@protoc_insertion_point(field_set_allocated:exec.user.RequestResults.query_id)
}

// optional int32 maximum_responses = 2;
inline bool RequestResults::_internal_has_maximum_responses() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool RequestResults::has_maximum_responses() const {
  return _internal_has_maximum_responses();
}
inline void RequestResults::clear_maximum_responses() {
  maximum_responses_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RequestResults::_internal_maximum_responses() const {
  return maximum_responses_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RequestResults::maximum_responses() const {
  // @@protoc_insertion_point(field_get:exec.user.RequestResults.maximum_responses)
  return _internal_maximum_responses();
}
inline void RequestResults::_internal_set_maximum_responses(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000002u;
  maximum_responses_ = value;
}
inline void RequestResults::set_maximum_responses(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_maximum_responses(value);
  // @@protoc_insertion_point(field_set:exec.user.RequestResults.maximum_responses)
}

// -------------------------------------------------------------------

// GetQueryPlanFragments

// required string query = 1;
inline bool GetQueryPlanFragments::_internal_has_query() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool GetQueryPlanFragments::has_query() const {
  return _internal_has_query();
}
inline void GetQueryPlanFragments::clear_query() {
  query_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& GetQueryPlanFragments::query() const {
  // @@protoc_insertion_point(field_get:exec.user.GetQueryPlanFragments.query)
  return _internal_query();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void GetQueryPlanFragments::set_query(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.GetQueryPlanFragments.query)
}
inline std::string* GetQueryPlanFragments::mutable_query() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetQueryPlanFragments.query)
  return _internal_mutable_query();
}
inline const std::string& GetQueryPlanFragments::_internal_query() const {
  return query_.Get();
}
inline void GetQueryPlanFragments::_internal_set_query(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* GetQueryPlanFragments::_internal_mutable_query() {
  _has_bits_[0] |= 0x00000001u;
  return query_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* GetQueryPlanFragments::release_query() {
  // @@protoc_insertion_point(field_release:exec.user.GetQueryPlanFragments.query)
  if (!_internal_has_query()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return query_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void GetQueryPlanFragments::set_allocated_query(std::string* query) {
  if (query != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  query_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), query,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetQueryPlanFragments.query)
}

// optional .exec.shared.QueryType type = 2;
inline bool GetQueryPlanFragments::_internal_has_type() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool GetQueryPlanFragments::has_type() const {
  return _internal_has_type();
}
inline void GetQueryPlanFragments::clear_type() {
  type_ = 1;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::shared::QueryType GetQueryPlanFragments::_internal_type() const {
  return static_cast< ::exec::shared::QueryType >(type_);
}
inline ::exec::shared::QueryType GetQueryPlanFragments::type() const {
  // @@protoc_insertion_point(field_get:exec.user.GetQueryPlanFragments.type)
  return _internal_type();
}
inline void GetQueryPlanFragments::_internal_set_type(::exec::shared::QueryType value) {
  assert(::exec::shared::QueryType_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  type_ = value;
}
inline void GetQueryPlanFragments::set_type(::exec::shared::QueryType value) {
  _internal_set_type(value);
  // @@protoc_insertion_point(field_set:exec.user.GetQueryPlanFragments.type)
}

// optional bool split_plan = 3 [default = false];
inline bool GetQueryPlanFragments::_internal_has_split_plan() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool GetQueryPlanFragments::has_split_plan() const {
  return _internal_has_split_plan();
}
inline void GetQueryPlanFragments::clear_split_plan() {
  split_plan_ = false;
  _has_bits_[0] &= ~0x00000002u;
}
inline bool GetQueryPlanFragments::_internal_split_plan() const {
  return split_plan_;
}
inline bool GetQueryPlanFragments::split_plan() const {
  // @@protoc_insertion_point(field_get:exec.user.GetQueryPlanFragments.split_plan)
  return _internal_split_plan();
}
inline void GetQueryPlanFragments::_internal_set_split_plan(bool value) {
  _has_bits_[0] |= 0x00000002u;
  split_plan_ = value;
}
inline void GetQueryPlanFragments::set_split_plan(bool value) {
  _internal_set_split_plan(value);
  // @@protoc_insertion_point(field_set:exec.user.GetQueryPlanFragments.split_plan)
}

// -------------------------------------------------------------------

// QueryPlanFragments

// required .exec.shared.QueryResult.QueryState status = 1;
inline bool QueryPlanFragments::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool QueryPlanFragments::has_status() const {
  return _internal_has_status();
}
inline void QueryPlanFragments::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::shared::QueryResult_QueryState QueryPlanFragments::_internal_status() const {
  return static_cast< ::exec::shared::QueryResult_QueryState >(status_);
}
inline ::exec::shared::QueryResult_QueryState QueryPlanFragments::status() const {
  // @@protoc_insertion_point(field_get:exec.user.QueryPlanFragments.status)
  return _internal_status();
}
inline void QueryPlanFragments::_internal_set_status(::exec::shared::QueryResult_QueryState value) {
  assert(::exec::shared::QueryResult_QueryState_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  status_ = value;
}
inline void QueryPlanFragments::set_status(::exec::shared::QueryResult_QueryState value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.QueryPlanFragments.status)
}

// optional .exec.shared.QueryId query_id = 2;
inline bool QueryPlanFragments::_internal_has_query_id() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || query_id_ != nullptr);
  return value;
}
inline bool QueryPlanFragments::has_query_id() const {
  return _internal_has_query_id();
}
inline const ::exec::shared::QueryId& QueryPlanFragments::_internal_query_id() const {
  const ::exec::shared::QueryId* p = query_id_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::QueryId&>(
      ::exec::shared::_QueryId_default_instance_);
}
inline const ::exec::shared::QueryId& QueryPlanFragments::query_id() const {
  // @@protoc_insertion_point(field_get:exec.user.QueryPlanFragments.query_id)
  return _internal_query_id();
}
inline void QueryPlanFragments::unsafe_arena_set_allocated_query_id(
    ::exec::shared::QueryId* query_id) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  query_id_ = query_id;
  if (query_id) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.QueryPlanFragments.query_id)
}
inline ::exec::shared::QueryId* QueryPlanFragments::release_query_id() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::QueryId* QueryPlanFragments::unsafe_arena_release_query_id() {
  // @@protoc_insertion_point(field_release:exec.user.QueryPlanFragments.query_id)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::QueryId* temp = query_id_;
  query_id_ = nullptr;
  return temp;
}
inline ::exec::shared::QueryId* QueryPlanFragments::_internal_mutable_query_id() {
  _has_bits_[0] |= 0x00000001u;
  if (query_id_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::QueryId>(GetArena());
    query_id_ = p;
  }
  return query_id_;
}
inline ::exec::shared::QueryId* QueryPlanFragments::mutable_query_id() {
  // @@protoc_insertion_point(field_mutable:exec.user.QueryPlanFragments.query_id)
  return _internal_mutable_query_id();
}
inline void QueryPlanFragments::set_allocated_query_id(::exec::shared::QueryId* query_id) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id_);
  }
  if (query_id) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(query_id)->GetArena();
    if (message_arena != submessage_arena) {
      query_id = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, query_id, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  query_id_ = query_id;
  // @@protoc_insertion_point(field_set_allocated:exec.user.QueryPlanFragments.query_id)
}

// repeated .exec.bit.control.PlanFragment fragments = 3;
inline int QueryPlanFragments::_internal_fragments_size() const {
  return fragments_.size();
}
inline int QueryPlanFragments::fragments_size() const {
  return _internal_fragments_size();
}
inline ::exec::bit::control::PlanFragment* QueryPlanFragments::mutable_fragments(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.QueryPlanFragments.fragments)
  return fragments_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >*
QueryPlanFragments::mutable_fragments() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.QueryPlanFragments.fragments)
  return &fragments_;
}
inline const ::exec::bit::control::PlanFragment& QueryPlanFragments::_internal_fragments(int index) const {
  return fragments_.Get(index);
}
inline const ::exec::bit::control::PlanFragment& QueryPlanFragments::fragments(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.QueryPlanFragments.fragments)
  return _internal_fragments(index);
}
inline ::exec::bit::control::PlanFragment* QueryPlanFragments::_internal_add_fragments() {
  return fragments_.Add();
}
inline ::exec::bit::control::PlanFragment* QueryPlanFragments::add_fragments() {
  // @@protoc_insertion_point(field_add:exec.user.QueryPlanFragments.fragments)
  return _internal_add_fragments();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >&
QueryPlanFragments::fragments() const {
  // @@protoc_insertion_point(field_list:exec.user.QueryPlanFragments.fragments)
  return fragments_;
}

// optional .exec.shared.DrillPBError error = 4;
inline bool QueryPlanFragments::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool QueryPlanFragments::has_error() const {
  return _internal_has_error();
}
inline const ::exec::shared::DrillPBError& QueryPlanFragments::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& QueryPlanFragments::error() const {
  // @@protoc_insertion_point(field_get:exec.user.QueryPlanFragments.error)
  return _internal_error();
}
inline void QueryPlanFragments::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.QueryPlanFragments.error)
}
inline ::exec::shared::DrillPBError* QueryPlanFragments::release_error() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* QueryPlanFragments::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.user.QueryPlanFragments.error)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* QueryPlanFragments::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000002u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* QueryPlanFragments::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.user.QueryPlanFragments.error)
  return _internal_mutable_error();
}
inline void QueryPlanFragments::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error)->GetArena();
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.user.QueryPlanFragments.error)
}

// -------------------------------------------------------------------

// BitToUserHandshake

// optional int32 rpc_version = 2;
inline bool BitToUserHandshake::_internal_has_rpc_version() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool BitToUserHandshake::has_rpc_version() const {
  return _internal_has_rpc_version();
}
inline void BitToUserHandshake::clear_rpc_version() {
  rpc_version_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 BitToUserHandshake::_internal_rpc_version() const {
  return rpc_version_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 BitToUserHandshake::rpc_version() const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.rpc_version)
  return _internal_rpc_version();
}
inline void BitToUserHandshake::_internal_set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  rpc_version_ = value;
}
inline void BitToUserHandshake::set_rpc_version(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_rpc_version(value);
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.rpc_version)
}

// optional .exec.user.HandshakeStatus status = 3;
inline bool BitToUserHandshake::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool BitToUserHandshake::has_status() const {
  return _internal_has_status();
}
inline void BitToUserHandshake::clear_status() {
  status_ = 1;
  _has_bits_[0] &= ~0x00000040u;
}
inline ::exec::user::HandshakeStatus BitToUserHandshake::_internal_status() const {
  return static_cast< ::exec::user::HandshakeStatus >(status_);
}
inline ::exec::user::HandshakeStatus BitToUserHandshake::status() const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.status)
  return _internal_status();
}
inline void BitToUserHandshake::_internal_set_status(::exec::user::HandshakeStatus value) {
  assert(::exec::user::HandshakeStatus_IsValid(value));
  _has_bits_[0] |= 0x00000040u;
  status_ = value;
}
inline void BitToUserHandshake::set_status(::exec::user::HandshakeStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.status)
}

// optional string errorId = 4;
inline bool BitToUserHandshake::_internal_has_errorid() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool BitToUserHandshake::has_errorid() const {
  return _internal_has_errorid();
}
inline void BitToUserHandshake::clear_errorid() {
  errorid_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& BitToUserHandshake::errorid() const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.errorId)
  return _internal_errorid();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void BitToUserHandshake::set_errorid(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 errorid_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.errorId)
}
inline std::string* BitToUserHandshake::mutable_errorid() {
  // @@protoc_insertion_point(field_mutable:exec.user.BitToUserHandshake.errorId)
  return _internal_mutable_errorid();
}
inline const std::string& BitToUserHandshake::_internal_errorid() const {
  return errorid_.Get();
}
inline void BitToUserHandshake::_internal_set_errorid(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  errorid_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* BitToUserHandshake::_internal_mutable_errorid() {
  _has_bits_[0] |= 0x00000001u;
  return errorid_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* BitToUserHandshake::release_errorid() {
  // @@protoc_insertion_point(field_release:exec.user.BitToUserHandshake.errorId)
  if (!_internal_has_errorid()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return errorid_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void BitToUserHandshake::set_allocated_errorid(std::string* errorid) {
  if (errorid != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  errorid_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), errorid,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.BitToUserHandshake.errorId)
}

// optional string errorMessage = 5;
inline bool BitToUserHandshake::_internal_has_errormessage() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool BitToUserHandshake::has_errormessage() const {
  return _internal_has_errormessage();
}
inline void BitToUserHandshake::clear_errormessage() {
  errormessage_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& BitToUserHandshake::errormessage() const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.errorMessage)
  return _internal_errormessage();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void BitToUserHandshake::set_errormessage(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 errormessage_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.errorMessage)
}
inline std::string* BitToUserHandshake::mutable_errormessage() {
  // @@protoc_insertion_point(field_mutable:exec.user.BitToUserHandshake.errorMessage)
  return _internal_mutable_errormessage();
}
inline const std::string& BitToUserHandshake::_internal_errormessage() const {
  return errormessage_.Get();
}
inline void BitToUserHandshake::_internal_set_errormessage(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  errormessage_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* BitToUserHandshake::_internal_mutable_errormessage() {
  _has_bits_[0] |= 0x00000002u;
  return errormessage_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* BitToUserHandshake::release_errormessage() {
  // @@protoc_insertion_point(field_release:exec.user.BitToUserHandshake.errorMessage)
  if (!_internal_has_errormessage()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return errormessage_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void BitToUserHandshake::set_allocated_errormessage(std::string* errormessage) {
  if (errormessage != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  errormessage_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), errormessage,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.BitToUserHandshake.errorMessage)
}

// optional .exec.user.RpcEndpointInfos server_infos = 6;
inline bool BitToUserHandshake::_internal_has_server_infos() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || server_infos_ != nullptr);
  return value;
}
inline bool BitToUserHandshake::has_server_infos() const {
  return _internal_has_server_infos();
}
inline void BitToUserHandshake::clear_server_infos() {
  if (server_infos_ != nullptr) server_infos_->Clear();
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::user::RpcEndpointInfos& BitToUserHandshake::_internal_server_infos() const {
  const ::exec::user::RpcEndpointInfos* p = server_infos_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::RpcEndpointInfos&>(
      ::exec::user::_RpcEndpointInfos_default_instance_);
}
inline const ::exec::user::RpcEndpointInfos& BitToUserHandshake::server_infos() const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.server_infos)
  return _internal_server_infos();
}
inline void BitToUserHandshake::unsafe_arena_set_allocated_server_infos(
    ::exec::user::RpcEndpointInfos* server_infos) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(server_infos_);
  }
  server_infos_ = server_infos;
  if (server_infos) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.BitToUserHandshake.server_infos)
}
inline ::exec::user::RpcEndpointInfos* BitToUserHandshake::release_server_infos() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::RpcEndpointInfos* temp = server_infos_;
  server_infos_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::RpcEndpointInfos* BitToUserHandshake::unsafe_arena_release_server_infos() {
  // @@protoc_insertion_point(field_release:exec.user.BitToUserHandshake.server_infos)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::RpcEndpointInfos* temp = server_infos_;
  server_infos_ = nullptr;
  return temp;
}
inline ::exec::user::RpcEndpointInfos* BitToUserHandshake::_internal_mutable_server_infos() {
  _has_bits_[0] |= 0x00000004u;
  if (server_infos_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::RpcEndpointInfos>(GetArena());
    server_infos_ = p;
  }
  return server_infos_;
}
inline ::exec::user::RpcEndpointInfos* BitToUserHandshake::mutable_server_infos() {
  // @@protoc_insertion_point(field_mutable:exec.user.BitToUserHandshake.server_infos)
  return _internal_mutable_server_infos();
}
inline void BitToUserHandshake::set_allocated_server_infos(::exec::user::RpcEndpointInfos* server_infos) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete server_infos_;
  }
  if (server_infos) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(server_infos);
    if (message_arena != submessage_arena) {
      server_infos = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, server_infos, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  server_infos_ = server_infos;
  // @@protoc_insertion_point(field_set_allocated:exec.user.BitToUserHandshake.server_infos)
}

// repeated string authenticationMechanisms = 7;
inline int BitToUserHandshake::_internal_authenticationmechanisms_size() const {
  return authenticationmechanisms_.size();
}
inline int BitToUserHandshake::authenticationmechanisms_size() const {
  return _internal_authenticationmechanisms_size();
}
inline void BitToUserHandshake::clear_authenticationmechanisms() {
  authenticationmechanisms_.Clear();
}
inline std::string* BitToUserHandshake::add_authenticationmechanisms() {
  // @@protoc_insertion_point(field_add_mutable:exec.user.BitToUserHandshake.authenticationMechanisms)
  return _internal_add_authenticationmechanisms();
}
inline const std::string& BitToUserHandshake::_internal_authenticationmechanisms(int index) const {
  return authenticationmechanisms_.Get(index);
}
inline const std::string& BitToUserHandshake::authenticationmechanisms(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.authenticationMechanisms)
  return _internal_authenticationmechanisms(index);
}
inline std::string* BitToUserHandshake::mutable_authenticationmechanisms(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.BitToUserHandshake.authenticationMechanisms)
  return authenticationmechanisms_.Mutable(index);
}
inline void BitToUserHandshake::set_authenticationmechanisms(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.authenticationMechanisms)
  authenticationmechanisms_.Mutable(index)->assign(value);
}
inline void BitToUserHandshake::set_authenticationmechanisms(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.authenticationMechanisms)
  authenticationmechanisms_.Mutable(index)->assign(std::move(value));
}
inline void BitToUserHandshake::set_authenticationmechanisms(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  authenticationmechanisms_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.user.BitToUserHandshake.authenticationMechanisms)
}
inline void BitToUserHandshake::set_authenticationmechanisms(int index, const char* value, size_t size) {
  authenticationmechanisms_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.user.BitToUserHandshake.authenticationMechanisms)
}
inline std::string* BitToUserHandshake::_internal_add_authenticationmechanisms() {
  return authenticationmechanisms_.Add();
}
inline void BitToUserHandshake::add_authenticationmechanisms(const std::string& value) {
  authenticationmechanisms_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.user.BitToUserHandshake.authenticationMechanisms)
}
inline void BitToUserHandshake::add_authenticationmechanisms(std::string&& value) {
  authenticationmechanisms_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.user.BitToUserHandshake.authenticationMechanisms)
}
inline void BitToUserHandshake::add_authenticationmechanisms(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  authenticationmechanisms_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.user.BitToUserHandshake.authenticationMechanisms)
}
inline void BitToUserHandshake::add_authenticationmechanisms(const char* value, size_t size) {
  authenticationmechanisms_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.user.BitToUserHandshake.authenticationMechanisms)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
BitToUserHandshake::authenticationmechanisms() const {
  // @@protoc_insertion_point(field_list:exec.user.BitToUserHandshake.authenticationMechanisms)
  return authenticationmechanisms_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
BitToUserHandshake::mutable_authenticationmechanisms() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.BitToUserHandshake.authenticationMechanisms)
  return &authenticationmechanisms_;
}

// repeated .exec.user.RpcType supported_methods = 8;
inline int BitToUserHandshake::_internal_supported_methods_size() const {
  return supported_methods_.size();
}
inline int BitToUserHandshake::supported_methods_size() const {
  return _internal_supported_methods_size();
}
inline void BitToUserHandshake::clear_supported_methods() {
  supported_methods_.Clear();
}
inline ::exec::user::RpcType BitToUserHandshake::_internal_supported_methods(int index) const {
  return static_cast< ::exec::user::RpcType >(supported_methods_.Get(index));
}
inline ::exec::user::RpcType BitToUserHandshake::supported_methods(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.supported_methods)
  return _internal_supported_methods(index);
}
inline void BitToUserHandshake::set_supported_methods(int index, ::exec::user::RpcType value) {
  assert(::exec::user::RpcType_IsValid(value));
  supported_methods_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.supported_methods)
}
inline void BitToUserHandshake::_internal_add_supported_methods(::exec::user::RpcType value) {
  assert(::exec::user::RpcType_IsValid(value));
  supported_methods_.Add(value);
}
inline void BitToUserHandshake::add_supported_methods(::exec::user::RpcType value) {
  // @@protoc_insertion_point(field_add:exec.user.BitToUserHandshake.supported_methods)
  _internal_add_supported_methods(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
BitToUserHandshake::supported_methods() const {
  // @@protoc_insertion_point(field_list:exec.user.BitToUserHandshake.supported_methods)
  return supported_methods_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
BitToUserHandshake::_internal_mutable_supported_methods() {
  return &supported_methods_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
BitToUserHandshake::mutable_supported_methods() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.BitToUserHandshake.supported_methods)
  return _internal_mutable_supported_methods();
}

// optional bool encrypted = 9;
inline bool BitToUserHandshake::_internal_has_encrypted() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool BitToUserHandshake::has_encrypted() const {
  return _internal_has_encrypted();
}
inline void BitToUserHandshake::clear_encrypted() {
  encrypted_ = false;
  _has_bits_[0] &= ~0x00000010u;
}
inline bool BitToUserHandshake::_internal_encrypted() const {
  return encrypted_;
}
inline bool BitToUserHandshake::encrypted() const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.encrypted)
  return _internal_encrypted();
}
inline void BitToUserHandshake::_internal_set_encrypted(bool value) {
  _has_bits_[0] |= 0x00000010u;
  encrypted_ = value;
}
inline void BitToUserHandshake::set_encrypted(bool value) {
  _internal_set_encrypted(value);
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.encrypted)
}

// optional int32 maxWrappedSize = 10;
inline bool BitToUserHandshake::_internal_has_maxwrappedsize() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool BitToUserHandshake::has_maxwrappedsize() const {
  return _internal_has_maxwrappedsize();
}
inline void BitToUserHandshake::clear_maxwrappedsize() {
  maxwrappedsize_ = 0;
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 BitToUserHandshake::_internal_maxwrappedsize() const {
  return maxwrappedsize_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 BitToUserHandshake::maxwrappedsize() const {
  // @@protoc_insertion_point(field_get:exec.user.BitToUserHandshake.maxWrappedSize)
  return _internal_maxwrappedsize();
}
inline void BitToUserHandshake::_internal_set_maxwrappedsize(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000020u;
  maxwrappedsize_ = value;
}
inline void BitToUserHandshake::set_maxwrappedsize(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_maxwrappedsize(value);
  // @@protoc_insertion_point(field_set:exec.user.BitToUserHandshake.maxWrappedSize)
}

// -------------------------------------------------------------------

// LikeFilter

// optional string pattern = 1;
inline bool LikeFilter::_internal_has_pattern() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool LikeFilter::has_pattern() const {
  return _internal_has_pattern();
}
inline void LikeFilter::clear_pattern() {
  pattern_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& LikeFilter::pattern() const {
  // @@protoc_insertion_point(field_get:exec.user.LikeFilter.pattern)
  return _internal_pattern();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void LikeFilter::set_pattern(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 pattern_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.LikeFilter.pattern)
}
inline std::string* LikeFilter::mutable_pattern() {
  // @@protoc_insertion_point(field_mutable:exec.user.LikeFilter.pattern)
  return _internal_mutable_pattern();
}
inline const std::string& LikeFilter::_internal_pattern() const {
  return pattern_.Get();
}
inline void LikeFilter::_internal_set_pattern(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  pattern_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* LikeFilter::_internal_mutable_pattern() {
  _has_bits_[0] |= 0x00000001u;
  return pattern_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* LikeFilter::release_pattern() {
  // @@protoc_insertion_point(field_release:exec.user.LikeFilter.pattern)
  if (!_internal_has_pattern()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return pattern_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void LikeFilter::set_allocated_pattern(std::string* pattern) {
  if (pattern != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  pattern_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), pattern,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.LikeFilter.pattern)
}

// optional string escape = 2;
inline bool LikeFilter::_internal_has_escape() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool LikeFilter::has_escape() const {
  return _internal_has_escape();
}
inline void LikeFilter::clear_escape() {
  escape_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& LikeFilter::escape() const {
  // @@protoc_insertion_point(field_get:exec.user.LikeFilter.escape)
  return _internal_escape();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void LikeFilter::set_escape(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 escape_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.LikeFilter.escape)
}
inline std::string* LikeFilter::mutable_escape() {
  // @@protoc_insertion_point(field_mutable:exec.user.LikeFilter.escape)
  return _internal_mutable_escape();
}
inline const std::string& LikeFilter::_internal_escape() const {
  return escape_.Get();
}
inline void LikeFilter::_internal_set_escape(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  escape_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* LikeFilter::_internal_mutable_escape() {
  _has_bits_[0] |= 0x00000002u;
  return escape_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* LikeFilter::release_escape() {
  // @@protoc_insertion_point(field_release:exec.user.LikeFilter.escape)
  if (!_internal_has_escape()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return escape_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void LikeFilter::set_allocated_escape(std::string* escape) {
  if (escape != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  escape_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), escape,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.LikeFilter.escape)
}

// -------------------------------------------------------------------

// GetCatalogsReq

// optional .exec.user.LikeFilter catalog_name_filter = 1;
inline bool GetCatalogsReq::_internal_has_catalog_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || catalog_name_filter_ != nullptr);
  return value;
}
inline bool GetCatalogsReq::has_catalog_name_filter() const {
  return _internal_has_catalog_name_filter();
}
inline void GetCatalogsReq::clear_catalog_name_filter() {
  if (catalog_name_filter_ != nullptr) catalog_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::user::LikeFilter& GetCatalogsReq::_internal_catalog_name_filter() const {
  const ::exec::user::LikeFilter* p = catalog_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetCatalogsReq::catalog_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetCatalogsReq.catalog_name_filter)
  return _internal_catalog_name_filter();
}
inline void GetCatalogsReq::unsafe_arena_set_allocated_catalog_name_filter(
    ::exec::user::LikeFilter* catalog_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(catalog_name_filter_);
  }
  catalog_name_filter_ = catalog_name_filter;
  if (catalog_name_filter) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetCatalogsReq.catalog_name_filter)
}
inline ::exec::user::LikeFilter* GetCatalogsReq::release_catalog_name_filter() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetCatalogsReq::unsafe_arena_release_catalog_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetCatalogsReq.catalog_name_filter)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetCatalogsReq::_internal_mutable_catalog_name_filter() {
  _has_bits_[0] |= 0x00000001u;
  if (catalog_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    catalog_name_filter_ = p;
  }
  return catalog_name_filter_;
}
inline ::exec::user::LikeFilter* GetCatalogsReq::mutable_catalog_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetCatalogsReq.catalog_name_filter)
  return _internal_mutable_catalog_name_filter();
}
inline void GetCatalogsReq::set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete catalog_name_filter_;
  }
  if (catalog_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(catalog_name_filter);
    if (message_arena != submessage_arena) {
      catalog_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, catalog_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_filter_ = catalog_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetCatalogsReq.catalog_name_filter)
}

// -------------------------------------------------------------------

// CatalogMetadata

// optional string catalog_name = 1;
inline bool CatalogMetadata::_internal_has_catalog_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool CatalogMetadata::has_catalog_name() const {
  return _internal_has_catalog_name();
}
inline void CatalogMetadata::clear_catalog_name() {
  catalog_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CatalogMetadata::catalog_name() const {
  // @@protoc_insertion_point(field_get:exec.user.CatalogMetadata.catalog_name)
  return _internal_catalog_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void CatalogMetadata::set_catalog_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.CatalogMetadata.catalog_name)
}
inline std::string* CatalogMetadata::mutable_catalog_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.CatalogMetadata.catalog_name)
  return _internal_mutable_catalog_name();
}
inline const std::string& CatalogMetadata::_internal_catalog_name() const {
  return catalog_name_.Get();
}
inline void CatalogMetadata::_internal_set_catalog_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* CatalogMetadata::_internal_mutable_catalog_name() {
  _has_bits_[0] |= 0x00000001u;
  return catalog_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* CatalogMetadata::release_catalog_name() {
  // @@protoc_insertion_point(field_release:exec.user.CatalogMetadata.catalog_name)
  if (!_internal_has_catalog_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return catalog_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void CatalogMetadata::set_allocated_catalog_name(std::string* catalog_name) {
  if (catalog_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), catalog_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.CatalogMetadata.catalog_name)
}

// optional string description = 2;
inline bool CatalogMetadata::_internal_has_description() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool CatalogMetadata::has_description() const {
  return _internal_has_description();
}
inline void CatalogMetadata::clear_description() {
  description_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& CatalogMetadata::description() const {
  // @@protoc_insertion_point(field_get:exec.user.CatalogMetadata.description)
  return _internal_description();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void CatalogMetadata::set_description(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 description_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.CatalogMetadata.description)
}
inline std::string* CatalogMetadata::mutable_description() {
  // @@protoc_insertion_point(field_mutable:exec.user.CatalogMetadata.description)
  return _internal_mutable_description();
}
inline const std::string& CatalogMetadata::_internal_description() const {
  return description_.Get();
}
inline void CatalogMetadata::_internal_set_description(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  description_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* CatalogMetadata::_internal_mutable_description() {
  _has_bits_[0] |= 0x00000002u;
  return description_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* CatalogMetadata::release_description() {
  // @@protoc_insertion_point(field_release:exec.user.CatalogMetadata.description)
  if (!_internal_has_description()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return description_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void CatalogMetadata::set_allocated_description(std::string* description) {
  if (description != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  description_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), description,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.CatalogMetadata.description)
}

// optional string connect = 3;
inline bool CatalogMetadata::_internal_has_connect() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool CatalogMetadata::has_connect() const {
  return _internal_has_connect();
}
inline void CatalogMetadata::clear_connect() {
  connect_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& CatalogMetadata::connect() const {
  // @@protoc_insertion_point(field_get:exec.user.CatalogMetadata.connect)
  return _internal_connect();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void CatalogMetadata::set_connect(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 connect_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.CatalogMetadata.connect)
}
inline std::string* CatalogMetadata::mutable_connect() {
  // @@protoc_insertion_point(field_mutable:exec.user.CatalogMetadata.connect)
  return _internal_mutable_connect();
}
inline const std::string& CatalogMetadata::_internal_connect() const {
  return connect_.Get();
}
inline void CatalogMetadata::_internal_set_connect(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  connect_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* CatalogMetadata::_internal_mutable_connect() {
  _has_bits_[0] |= 0x00000004u;
  return connect_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* CatalogMetadata::release_connect() {
  // @@protoc_insertion_point(field_release:exec.user.CatalogMetadata.connect)
  if (!_internal_has_connect()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return connect_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void CatalogMetadata::set_allocated_connect(std::string* connect) {
  if (connect != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  connect_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), connect,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.CatalogMetadata.connect)
}

// -------------------------------------------------------------------

// GetCatalogsResp

// optional .exec.user.RequestStatus status = 1;
inline bool GetCatalogsResp::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool GetCatalogsResp::has_status() const {
  return _internal_has_status();
}
inline void GetCatalogsResp::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::exec::user::RequestStatus GetCatalogsResp::_internal_status() const {
  return static_cast< ::exec::user::RequestStatus >(status_);
}
inline ::exec::user::RequestStatus GetCatalogsResp::status() const {
  // @@protoc_insertion_point(field_get:exec.user.GetCatalogsResp.status)
  return _internal_status();
}
inline void GetCatalogsResp::_internal_set_status(::exec::user::RequestStatus value) {
  assert(::exec::user::RequestStatus_IsValid(value));
  _has_bits_[0] |= 0x00000002u;
  status_ = value;
}
inline void GetCatalogsResp::set_status(::exec::user::RequestStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.GetCatalogsResp.status)
}

// repeated .exec.user.CatalogMetadata catalogs = 2;
inline int GetCatalogsResp::_internal_catalogs_size() const {
  return catalogs_.size();
}
inline int GetCatalogsResp::catalogs_size() const {
  return _internal_catalogs_size();
}
inline void GetCatalogsResp::clear_catalogs() {
  catalogs_.Clear();
}
inline ::exec::user::CatalogMetadata* GetCatalogsResp::mutable_catalogs(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.GetCatalogsResp.catalogs)
  return catalogs_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::CatalogMetadata >*
GetCatalogsResp::mutable_catalogs() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.GetCatalogsResp.catalogs)
  return &catalogs_;
}
inline const ::exec::user::CatalogMetadata& GetCatalogsResp::_internal_catalogs(int index) const {
  return catalogs_.Get(index);
}
inline const ::exec::user::CatalogMetadata& GetCatalogsResp::catalogs(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.GetCatalogsResp.catalogs)
  return _internal_catalogs(index);
}
inline ::exec::user::CatalogMetadata* GetCatalogsResp::_internal_add_catalogs() {
  return catalogs_.Add();
}
inline ::exec::user::CatalogMetadata* GetCatalogsResp::add_catalogs() {
  // @@protoc_insertion_point(field_add:exec.user.GetCatalogsResp.catalogs)
  return _internal_add_catalogs();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::CatalogMetadata >&
GetCatalogsResp::catalogs() const {
  // @@protoc_insertion_point(field_list:exec.user.GetCatalogsResp.catalogs)
  return catalogs_;
}

// optional .exec.shared.DrillPBError error = 3;
inline bool GetCatalogsResp::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool GetCatalogsResp::has_error() const {
  return _internal_has_error();
}
inline const ::exec::shared::DrillPBError& GetCatalogsResp::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& GetCatalogsResp::error() const {
  // @@protoc_insertion_point(field_get:exec.user.GetCatalogsResp.error)
  return _internal_error();
}
inline void GetCatalogsResp::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetCatalogsResp.error)
}
inline ::exec::shared::DrillPBError* GetCatalogsResp::release_error() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* GetCatalogsResp::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.user.GetCatalogsResp.error)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* GetCatalogsResp::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000001u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* GetCatalogsResp::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetCatalogsResp.error)
  return _internal_mutable_error();
}
inline void GetCatalogsResp::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error)->GetArena();
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetCatalogsResp.error)
}

// -------------------------------------------------------------------

// GetSchemasReq

// optional .exec.user.LikeFilter catalog_name_filter = 1;
inline bool GetSchemasReq::_internal_has_catalog_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || catalog_name_filter_ != nullptr);
  return value;
}
inline bool GetSchemasReq::has_catalog_name_filter() const {
  return _internal_has_catalog_name_filter();
}
inline void GetSchemasReq::clear_catalog_name_filter() {
  if (catalog_name_filter_ != nullptr) catalog_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::user::LikeFilter& GetSchemasReq::_internal_catalog_name_filter() const {
  const ::exec::user::LikeFilter* p = catalog_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetSchemasReq::catalog_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetSchemasReq.catalog_name_filter)
  return _internal_catalog_name_filter();
}
inline void GetSchemasReq::unsafe_arena_set_allocated_catalog_name_filter(
    ::exec::user::LikeFilter* catalog_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(catalog_name_filter_);
  }
  catalog_name_filter_ = catalog_name_filter;
  if (catalog_name_filter) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetSchemasReq.catalog_name_filter)
}
inline ::exec::user::LikeFilter* GetSchemasReq::release_catalog_name_filter() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetSchemasReq::unsafe_arena_release_catalog_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetSchemasReq.catalog_name_filter)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetSchemasReq::_internal_mutable_catalog_name_filter() {
  _has_bits_[0] |= 0x00000001u;
  if (catalog_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    catalog_name_filter_ = p;
  }
  return catalog_name_filter_;
}
inline ::exec::user::LikeFilter* GetSchemasReq::mutable_catalog_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetSchemasReq.catalog_name_filter)
  return _internal_mutable_catalog_name_filter();
}
inline void GetSchemasReq::set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete catalog_name_filter_;
  }
  if (catalog_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(catalog_name_filter);
    if (message_arena != submessage_arena) {
      catalog_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, catalog_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_filter_ = catalog_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetSchemasReq.catalog_name_filter)
}

// optional .exec.user.LikeFilter schema_name_filter = 2;
inline bool GetSchemasReq::_internal_has_schema_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || schema_name_filter_ != nullptr);
  return value;
}
inline bool GetSchemasReq::has_schema_name_filter() const {
  return _internal_has_schema_name_filter();
}
inline void GetSchemasReq::clear_schema_name_filter() {
  if (schema_name_filter_ != nullptr) schema_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::user::LikeFilter& GetSchemasReq::_internal_schema_name_filter() const {
  const ::exec::user::LikeFilter* p = schema_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetSchemasReq::schema_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetSchemasReq.schema_name_filter)
  return _internal_schema_name_filter();
}
inline void GetSchemasReq::unsafe_arena_set_allocated_schema_name_filter(
    ::exec::user::LikeFilter* schema_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(schema_name_filter_);
  }
  schema_name_filter_ = schema_name_filter;
  if (schema_name_filter) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetSchemasReq.schema_name_filter)
}
inline ::exec::user::LikeFilter* GetSchemasReq::release_schema_name_filter() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::LikeFilter* temp = schema_name_filter_;
  schema_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetSchemasReq::unsafe_arena_release_schema_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetSchemasReq.schema_name_filter)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::LikeFilter* temp = schema_name_filter_;
  schema_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetSchemasReq::_internal_mutable_schema_name_filter() {
  _has_bits_[0] |= 0x00000002u;
  if (schema_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    schema_name_filter_ = p;
  }
  return schema_name_filter_;
}
inline ::exec::user::LikeFilter* GetSchemasReq::mutable_schema_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetSchemasReq.schema_name_filter)
  return _internal_mutable_schema_name_filter();
}
inline void GetSchemasReq::set_allocated_schema_name_filter(::exec::user::LikeFilter* schema_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete schema_name_filter_;
  }
  if (schema_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(schema_name_filter);
    if (message_arena != submessage_arena) {
      schema_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, schema_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  schema_name_filter_ = schema_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetSchemasReq.schema_name_filter)
}

// -------------------------------------------------------------------

// SchemaMetadata

// optional string catalog_name = 1;
inline bool SchemaMetadata::_internal_has_catalog_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool SchemaMetadata::has_catalog_name() const {
  return _internal_has_catalog_name();
}
inline void SchemaMetadata::clear_catalog_name() {
  catalog_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& SchemaMetadata::catalog_name() const {
  // @@protoc_insertion_point(field_get:exec.user.SchemaMetadata.catalog_name)
  return _internal_catalog_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void SchemaMetadata::set_catalog_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.SchemaMetadata.catalog_name)
}
inline std::string* SchemaMetadata::mutable_catalog_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.SchemaMetadata.catalog_name)
  return _internal_mutable_catalog_name();
}
inline const std::string& SchemaMetadata::_internal_catalog_name() const {
  return catalog_name_.Get();
}
inline void SchemaMetadata::_internal_set_catalog_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* SchemaMetadata::_internal_mutable_catalog_name() {
  _has_bits_[0] |= 0x00000001u;
  return catalog_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* SchemaMetadata::release_catalog_name() {
  // @@protoc_insertion_point(field_release:exec.user.SchemaMetadata.catalog_name)
  if (!_internal_has_catalog_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return catalog_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void SchemaMetadata::set_allocated_catalog_name(std::string* catalog_name) {
  if (catalog_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), catalog_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.SchemaMetadata.catalog_name)
}

// optional string schema_name = 2;
inline bool SchemaMetadata::_internal_has_schema_name() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool SchemaMetadata::has_schema_name() const {
  return _internal_has_schema_name();
}
inline void SchemaMetadata::clear_schema_name() {
  schema_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& SchemaMetadata::schema_name() const {
  // @@protoc_insertion_point(field_get:exec.user.SchemaMetadata.schema_name)
  return _internal_schema_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void SchemaMetadata::set_schema_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.SchemaMetadata.schema_name)
}
inline std::string* SchemaMetadata::mutable_schema_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.SchemaMetadata.schema_name)
  return _internal_mutable_schema_name();
}
inline const std::string& SchemaMetadata::_internal_schema_name() const {
  return schema_name_.Get();
}
inline void SchemaMetadata::_internal_set_schema_name(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* SchemaMetadata::_internal_mutable_schema_name() {
  _has_bits_[0] |= 0x00000002u;
  return schema_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* SchemaMetadata::release_schema_name() {
  // @@protoc_insertion_point(field_release:exec.user.SchemaMetadata.schema_name)
  if (!_internal_has_schema_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return schema_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void SchemaMetadata::set_allocated_schema_name(std::string* schema_name) {
  if (schema_name != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  schema_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), schema_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.SchemaMetadata.schema_name)
}

// optional string owner = 3;
inline bool SchemaMetadata::_internal_has_owner() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool SchemaMetadata::has_owner() const {
  return _internal_has_owner();
}
inline void SchemaMetadata::clear_owner() {
  owner_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& SchemaMetadata::owner() const {
  // @@protoc_insertion_point(field_get:exec.user.SchemaMetadata.owner)
  return _internal_owner();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void SchemaMetadata::set_owner(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 owner_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.SchemaMetadata.owner)
}
inline std::string* SchemaMetadata::mutable_owner() {
  // @@protoc_insertion_point(field_mutable:exec.user.SchemaMetadata.owner)
  return _internal_mutable_owner();
}
inline const std::string& SchemaMetadata::_internal_owner() const {
  return owner_.Get();
}
inline void SchemaMetadata::_internal_set_owner(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  owner_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* SchemaMetadata::_internal_mutable_owner() {
  _has_bits_[0] |= 0x00000004u;
  return owner_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* SchemaMetadata::release_owner() {
  // @@protoc_insertion_point(field_release:exec.user.SchemaMetadata.owner)
  if (!_internal_has_owner()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return owner_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void SchemaMetadata::set_allocated_owner(std::string* owner) {
  if (owner != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  owner_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), owner,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.SchemaMetadata.owner)
}

// optional string type = 4;
inline bool SchemaMetadata::_internal_has_type() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool SchemaMetadata::has_type() const {
  return _internal_has_type();
}
inline void SchemaMetadata::clear_type() {
  type_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& SchemaMetadata::type() const {
  // @@protoc_insertion_point(field_get:exec.user.SchemaMetadata.type)
  return _internal_type();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void SchemaMetadata::set_type(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.SchemaMetadata.type)
}
inline std::string* SchemaMetadata::mutable_type() {
  // @@protoc_insertion_point(field_mutable:exec.user.SchemaMetadata.type)
  return _internal_mutable_type();
}
inline const std::string& SchemaMetadata::_internal_type() const {
  return type_.Get();
}
inline void SchemaMetadata::_internal_set_type(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* SchemaMetadata::_internal_mutable_type() {
  _has_bits_[0] |= 0x00000008u;
  return type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* SchemaMetadata::release_type() {
  // @@protoc_insertion_point(field_release:exec.user.SchemaMetadata.type)
  if (!_internal_has_type()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void SchemaMetadata::set_allocated_type(std::string* type) {
  if (type != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.SchemaMetadata.type)
}

// optional string mutable = 5;
inline bool SchemaMetadata::_internal_has_mutable_() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool SchemaMetadata::has_mutable_() const {
  return _internal_has_mutable_();
}
inline void SchemaMetadata::clear_mutable_() {
  mutable__.ClearToEmpty();
  _has_bits_[0] &= ~0x00000010u;
}
inline const std::string& SchemaMetadata::mutable_() const {
  // @@protoc_insertion_point(field_get:exec.user.SchemaMetadata.mutable)
  return _internal_mutable_();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void SchemaMetadata::set_mutable_(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000010u;
 mutable__.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.SchemaMetadata.mutable)
}
inline std::string* SchemaMetadata::mutable_mutable_() {
  // @@protoc_insertion_point(field_mutable:exec.user.SchemaMetadata.mutable)
  return _internal_mutable_mutable_();
}
inline const std::string& SchemaMetadata::_internal_mutable_() const {
  return mutable__.Get();
}
inline void SchemaMetadata::_internal_set_mutable_(const std::string& value) {
  _has_bits_[0] |= 0x00000010u;
  mutable__.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* SchemaMetadata::_internal_mutable_mutable_() {
  _has_bits_[0] |= 0x00000010u;
  return mutable__.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* SchemaMetadata::release_mutable_() {
  // @@protoc_insertion_point(field_release:exec.user.SchemaMetadata.mutable)
  if (!_internal_has_mutable_()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000010u;
  return mutable__.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void SchemaMetadata::set_allocated_mutable_(std::string* mutable_) {
  if (mutable_ != nullptr) {
    _has_bits_[0] |= 0x00000010u;
  } else {
    _has_bits_[0] &= ~0x00000010u;
  }
  mutable__.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), mutable_,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.SchemaMetadata.mutable)
}

// -------------------------------------------------------------------

// GetSchemasResp

// optional .exec.user.RequestStatus status = 1;
inline bool GetSchemasResp::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool GetSchemasResp::has_status() const {
  return _internal_has_status();
}
inline void GetSchemasResp::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::exec::user::RequestStatus GetSchemasResp::_internal_status() const {
  return static_cast< ::exec::user::RequestStatus >(status_);
}
inline ::exec::user::RequestStatus GetSchemasResp::status() const {
  // @@protoc_insertion_point(field_get:exec.user.GetSchemasResp.status)
  return _internal_status();
}
inline void GetSchemasResp::_internal_set_status(::exec::user::RequestStatus value) {
  assert(::exec::user::RequestStatus_IsValid(value));
  _has_bits_[0] |= 0x00000002u;
  status_ = value;
}
inline void GetSchemasResp::set_status(::exec::user::RequestStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.GetSchemasResp.status)
}

// repeated .exec.user.SchemaMetadata schemas = 2;
inline int GetSchemasResp::_internal_schemas_size() const {
  return schemas_.size();
}
inline int GetSchemasResp::schemas_size() const {
  return _internal_schemas_size();
}
inline void GetSchemasResp::clear_schemas() {
  schemas_.Clear();
}
inline ::exec::user::SchemaMetadata* GetSchemasResp::mutable_schemas(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.GetSchemasResp.schemas)
  return schemas_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::SchemaMetadata >*
GetSchemasResp::mutable_schemas() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.GetSchemasResp.schemas)
  return &schemas_;
}
inline const ::exec::user::SchemaMetadata& GetSchemasResp::_internal_schemas(int index) const {
  return schemas_.Get(index);
}
inline const ::exec::user::SchemaMetadata& GetSchemasResp::schemas(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.GetSchemasResp.schemas)
  return _internal_schemas(index);
}
inline ::exec::user::SchemaMetadata* GetSchemasResp::_internal_add_schemas() {
  return schemas_.Add();
}
inline ::exec::user::SchemaMetadata* GetSchemasResp::add_schemas() {
  // @@protoc_insertion_point(field_add:exec.user.GetSchemasResp.schemas)
  return _internal_add_schemas();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::SchemaMetadata >&
GetSchemasResp::schemas() const {
  // @@protoc_insertion_point(field_list:exec.user.GetSchemasResp.schemas)
  return schemas_;
}

// optional .exec.shared.DrillPBError error = 3;
inline bool GetSchemasResp::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool GetSchemasResp::has_error() const {
  return _internal_has_error();
}
inline const ::exec::shared::DrillPBError& GetSchemasResp::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& GetSchemasResp::error() const {
  // @@protoc_insertion_point(field_get:exec.user.GetSchemasResp.error)
  return _internal_error();
}
inline void GetSchemasResp::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetSchemasResp.error)
}
inline ::exec::shared::DrillPBError* GetSchemasResp::release_error() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* GetSchemasResp::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.user.GetSchemasResp.error)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* GetSchemasResp::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000001u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* GetSchemasResp::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetSchemasResp.error)
  return _internal_mutable_error();
}
inline void GetSchemasResp::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error)->GetArena();
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetSchemasResp.error)
}

// -------------------------------------------------------------------

// GetTablesReq

// optional .exec.user.LikeFilter catalog_name_filter = 1;
inline bool GetTablesReq::_internal_has_catalog_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || catalog_name_filter_ != nullptr);
  return value;
}
inline bool GetTablesReq::has_catalog_name_filter() const {
  return _internal_has_catalog_name_filter();
}
inline void GetTablesReq::clear_catalog_name_filter() {
  if (catalog_name_filter_ != nullptr) catalog_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::user::LikeFilter& GetTablesReq::_internal_catalog_name_filter() const {
  const ::exec::user::LikeFilter* p = catalog_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetTablesReq::catalog_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetTablesReq.catalog_name_filter)
  return _internal_catalog_name_filter();
}
inline void GetTablesReq::unsafe_arena_set_allocated_catalog_name_filter(
    ::exec::user::LikeFilter* catalog_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(catalog_name_filter_);
  }
  catalog_name_filter_ = catalog_name_filter;
  if (catalog_name_filter) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetTablesReq.catalog_name_filter)
}
inline ::exec::user::LikeFilter* GetTablesReq::release_catalog_name_filter() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetTablesReq::unsafe_arena_release_catalog_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetTablesReq.catalog_name_filter)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetTablesReq::_internal_mutable_catalog_name_filter() {
  _has_bits_[0] |= 0x00000001u;
  if (catalog_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    catalog_name_filter_ = p;
  }
  return catalog_name_filter_;
}
inline ::exec::user::LikeFilter* GetTablesReq::mutable_catalog_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetTablesReq.catalog_name_filter)
  return _internal_mutable_catalog_name_filter();
}
inline void GetTablesReq::set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete catalog_name_filter_;
  }
  if (catalog_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(catalog_name_filter);
    if (message_arena != submessage_arena) {
      catalog_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, catalog_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_filter_ = catalog_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetTablesReq.catalog_name_filter)
}

// optional .exec.user.LikeFilter schema_name_filter = 2;
inline bool GetTablesReq::_internal_has_schema_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || schema_name_filter_ != nullptr);
  return value;
}
inline bool GetTablesReq::has_schema_name_filter() const {
  return _internal_has_schema_name_filter();
}
inline void GetTablesReq::clear_schema_name_filter() {
  if (schema_name_filter_ != nullptr) schema_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::user::LikeFilter& GetTablesReq::_internal_schema_name_filter() const {
  const ::exec::user::LikeFilter* p = schema_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetTablesReq::schema_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetTablesReq.schema_name_filter)
  return _internal_schema_name_filter();
}
inline void GetTablesReq::unsafe_arena_set_allocated_schema_name_filter(
    ::exec::user::LikeFilter* schema_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(schema_name_filter_);
  }
  schema_name_filter_ = schema_name_filter;
  if (schema_name_filter) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetTablesReq.schema_name_filter)
}
inline ::exec::user::LikeFilter* GetTablesReq::release_schema_name_filter() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::LikeFilter* temp = schema_name_filter_;
  schema_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetTablesReq::unsafe_arena_release_schema_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetTablesReq.schema_name_filter)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::LikeFilter* temp = schema_name_filter_;
  schema_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetTablesReq::_internal_mutable_schema_name_filter() {
  _has_bits_[0] |= 0x00000002u;
  if (schema_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    schema_name_filter_ = p;
  }
  return schema_name_filter_;
}
inline ::exec::user::LikeFilter* GetTablesReq::mutable_schema_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetTablesReq.schema_name_filter)
  return _internal_mutable_schema_name_filter();
}
inline void GetTablesReq::set_allocated_schema_name_filter(::exec::user::LikeFilter* schema_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete schema_name_filter_;
  }
  if (schema_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(schema_name_filter);
    if (message_arena != submessage_arena) {
      schema_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, schema_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  schema_name_filter_ = schema_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetTablesReq.schema_name_filter)
}

// optional .exec.user.LikeFilter table_name_filter = 3;
inline bool GetTablesReq::_internal_has_table_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || table_name_filter_ != nullptr);
  return value;
}
inline bool GetTablesReq::has_table_name_filter() const {
  return _internal_has_table_name_filter();
}
inline void GetTablesReq::clear_table_name_filter() {
  if (table_name_filter_ != nullptr) table_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::user::LikeFilter& GetTablesReq::_internal_table_name_filter() const {
  const ::exec::user::LikeFilter* p = table_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetTablesReq::table_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetTablesReq.table_name_filter)
  return _internal_table_name_filter();
}
inline void GetTablesReq::unsafe_arena_set_allocated_table_name_filter(
    ::exec::user::LikeFilter* table_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(table_name_filter_);
  }
  table_name_filter_ = table_name_filter;
  if (table_name_filter) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetTablesReq.table_name_filter)
}
inline ::exec::user::LikeFilter* GetTablesReq::release_table_name_filter() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::LikeFilter* temp = table_name_filter_;
  table_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetTablesReq::unsafe_arena_release_table_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetTablesReq.table_name_filter)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::LikeFilter* temp = table_name_filter_;
  table_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetTablesReq::_internal_mutable_table_name_filter() {
  _has_bits_[0] |= 0x00000004u;
  if (table_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    table_name_filter_ = p;
  }
  return table_name_filter_;
}
inline ::exec::user::LikeFilter* GetTablesReq::mutable_table_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetTablesReq.table_name_filter)
  return _internal_mutable_table_name_filter();
}
inline void GetTablesReq::set_allocated_table_name_filter(::exec::user::LikeFilter* table_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete table_name_filter_;
  }
  if (table_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(table_name_filter);
    if (message_arena != submessage_arena) {
      table_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, table_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  table_name_filter_ = table_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetTablesReq.table_name_filter)
}

// repeated string table_type_filter = 4;
inline int GetTablesReq::_internal_table_type_filter_size() const {
  return table_type_filter_.size();
}
inline int GetTablesReq::table_type_filter_size() const {
  return _internal_table_type_filter_size();
}
inline void GetTablesReq::clear_table_type_filter() {
  table_type_filter_.Clear();
}
inline std::string* GetTablesReq::add_table_type_filter() {
  // @@protoc_insertion_point(field_add_mutable:exec.user.GetTablesReq.table_type_filter)
  return _internal_add_table_type_filter();
}
inline const std::string& GetTablesReq::_internal_table_type_filter(int index) const {
  return table_type_filter_.Get(index);
}
inline const std::string& GetTablesReq::table_type_filter(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.GetTablesReq.table_type_filter)
  return _internal_table_type_filter(index);
}
inline std::string* GetTablesReq::mutable_table_type_filter(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.GetTablesReq.table_type_filter)
  return table_type_filter_.Mutable(index);
}
inline void GetTablesReq::set_table_type_filter(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.user.GetTablesReq.table_type_filter)
  table_type_filter_.Mutable(index)->assign(value);
}
inline void GetTablesReq::set_table_type_filter(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.user.GetTablesReq.table_type_filter)
  table_type_filter_.Mutable(index)->assign(std::move(value));
}
inline void GetTablesReq::set_table_type_filter(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  table_type_filter_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.user.GetTablesReq.table_type_filter)
}
inline void GetTablesReq::set_table_type_filter(int index, const char* value, size_t size) {
  table_type_filter_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.user.GetTablesReq.table_type_filter)
}
inline std::string* GetTablesReq::_internal_add_table_type_filter() {
  return table_type_filter_.Add();
}
inline void GetTablesReq::add_table_type_filter(const std::string& value) {
  table_type_filter_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.user.GetTablesReq.table_type_filter)
}
inline void GetTablesReq::add_table_type_filter(std::string&& value) {
  table_type_filter_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.user.GetTablesReq.table_type_filter)
}
inline void GetTablesReq::add_table_type_filter(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  table_type_filter_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.user.GetTablesReq.table_type_filter)
}
inline void GetTablesReq::add_table_type_filter(const char* value, size_t size) {
  table_type_filter_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.user.GetTablesReq.table_type_filter)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
GetTablesReq::table_type_filter() const {
  // @@protoc_insertion_point(field_list:exec.user.GetTablesReq.table_type_filter)
  return table_type_filter_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
GetTablesReq::mutable_table_type_filter() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.GetTablesReq.table_type_filter)
  return &table_type_filter_;
}

// -------------------------------------------------------------------

// TableMetadata

// optional string catalog_name = 1;
inline bool TableMetadata::_internal_has_catalog_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool TableMetadata::has_catalog_name() const {
  return _internal_has_catalog_name();
}
inline void TableMetadata::clear_catalog_name() {
  catalog_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& TableMetadata::catalog_name() const {
  // @@protoc_insertion_point(field_get:exec.user.TableMetadata.catalog_name)
  return _internal_catalog_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void TableMetadata::set_catalog_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.TableMetadata.catalog_name)
}
inline std::string* TableMetadata::mutable_catalog_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.TableMetadata.catalog_name)
  return _internal_mutable_catalog_name();
}
inline const std::string& TableMetadata::_internal_catalog_name() const {
  return catalog_name_.Get();
}
inline void TableMetadata::_internal_set_catalog_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* TableMetadata::_internal_mutable_catalog_name() {
  _has_bits_[0] |= 0x00000001u;
  return catalog_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* TableMetadata::release_catalog_name() {
  // @@protoc_insertion_point(field_release:exec.user.TableMetadata.catalog_name)
  if (!_internal_has_catalog_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return catalog_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void TableMetadata::set_allocated_catalog_name(std::string* catalog_name) {
  if (catalog_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), catalog_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.TableMetadata.catalog_name)
}

// optional string schema_name = 2;
inline bool TableMetadata::_internal_has_schema_name() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool TableMetadata::has_schema_name() const {
  return _internal_has_schema_name();
}
inline void TableMetadata::clear_schema_name() {
  schema_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& TableMetadata::schema_name() const {
  // @@protoc_insertion_point(field_get:exec.user.TableMetadata.schema_name)
  return _internal_schema_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void TableMetadata::set_schema_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.TableMetadata.schema_name)
}
inline std::string* TableMetadata::mutable_schema_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.TableMetadata.schema_name)
  return _internal_mutable_schema_name();
}
inline const std::string& TableMetadata::_internal_schema_name() const {
  return schema_name_.Get();
}
inline void TableMetadata::_internal_set_schema_name(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* TableMetadata::_internal_mutable_schema_name() {
  _has_bits_[0] |= 0x00000002u;
  return schema_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* TableMetadata::release_schema_name() {
  // @@protoc_insertion_point(field_release:exec.user.TableMetadata.schema_name)
  if (!_internal_has_schema_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return schema_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void TableMetadata::set_allocated_schema_name(std::string* schema_name) {
  if (schema_name != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  schema_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), schema_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.TableMetadata.schema_name)
}

// optional string table_name = 3;
inline bool TableMetadata::_internal_has_table_name() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool TableMetadata::has_table_name() const {
  return _internal_has_table_name();
}
inline void TableMetadata::clear_table_name() {
  table_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& TableMetadata::table_name() const {
  // @@protoc_insertion_point(field_get:exec.user.TableMetadata.table_name)
  return _internal_table_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void TableMetadata::set_table_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 table_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.TableMetadata.table_name)
}
inline std::string* TableMetadata::mutable_table_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.TableMetadata.table_name)
  return _internal_mutable_table_name();
}
inline const std::string& TableMetadata::_internal_table_name() const {
  return table_name_.Get();
}
inline void TableMetadata::_internal_set_table_name(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  table_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* TableMetadata::_internal_mutable_table_name() {
  _has_bits_[0] |= 0x00000004u;
  return table_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* TableMetadata::release_table_name() {
  // @@protoc_insertion_point(field_release:exec.user.TableMetadata.table_name)
  if (!_internal_has_table_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return table_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void TableMetadata::set_allocated_table_name(std::string* table_name) {
  if (table_name != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  table_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), table_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.TableMetadata.table_name)
}

// optional string type = 4;
inline bool TableMetadata::_internal_has_type() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool TableMetadata::has_type() const {
  return _internal_has_type();
}
inline void TableMetadata::clear_type() {
  type_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& TableMetadata::type() const {
  // @@protoc_insertion_point(field_get:exec.user.TableMetadata.type)
  return _internal_type();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void TableMetadata::set_type(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.TableMetadata.type)
}
inline std::string* TableMetadata::mutable_type() {
  // @@protoc_insertion_point(field_mutable:exec.user.TableMetadata.type)
  return _internal_mutable_type();
}
inline const std::string& TableMetadata::_internal_type() const {
  return type_.Get();
}
inline void TableMetadata::_internal_set_type(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* TableMetadata::_internal_mutable_type() {
  _has_bits_[0] |= 0x00000008u;
  return type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* TableMetadata::release_type() {
  // @@protoc_insertion_point(field_release:exec.user.TableMetadata.type)
  if (!_internal_has_type()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void TableMetadata::set_allocated_type(std::string* type) {
  if (type != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), type,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.TableMetadata.type)
}

// -------------------------------------------------------------------

// GetTablesResp

// optional .exec.user.RequestStatus status = 1;
inline bool GetTablesResp::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool GetTablesResp::has_status() const {
  return _internal_has_status();
}
inline void GetTablesResp::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::exec::user::RequestStatus GetTablesResp::_internal_status() const {
  return static_cast< ::exec::user::RequestStatus >(status_);
}
inline ::exec::user::RequestStatus GetTablesResp::status() const {
  // @@protoc_insertion_point(field_get:exec.user.GetTablesResp.status)
  return _internal_status();
}
inline void GetTablesResp::_internal_set_status(::exec::user::RequestStatus value) {
  assert(::exec::user::RequestStatus_IsValid(value));
  _has_bits_[0] |= 0x00000002u;
  status_ = value;
}
inline void GetTablesResp::set_status(::exec::user::RequestStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.GetTablesResp.status)
}

// repeated .exec.user.TableMetadata tables = 2;
inline int GetTablesResp::_internal_tables_size() const {
  return tables_.size();
}
inline int GetTablesResp::tables_size() const {
  return _internal_tables_size();
}
inline void GetTablesResp::clear_tables() {
  tables_.Clear();
}
inline ::exec::user::TableMetadata* GetTablesResp::mutable_tables(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.GetTablesResp.tables)
  return tables_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::TableMetadata >*
GetTablesResp::mutable_tables() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.GetTablesResp.tables)
  return &tables_;
}
inline const ::exec::user::TableMetadata& GetTablesResp::_internal_tables(int index) const {
  return tables_.Get(index);
}
inline const ::exec::user::TableMetadata& GetTablesResp::tables(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.GetTablesResp.tables)
  return _internal_tables(index);
}
inline ::exec::user::TableMetadata* GetTablesResp::_internal_add_tables() {
  return tables_.Add();
}
inline ::exec::user::TableMetadata* GetTablesResp::add_tables() {
  // @@protoc_insertion_point(field_add:exec.user.GetTablesResp.tables)
  return _internal_add_tables();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::TableMetadata >&
GetTablesResp::tables() const {
  // @@protoc_insertion_point(field_list:exec.user.GetTablesResp.tables)
  return tables_;
}

// optional .exec.shared.DrillPBError error = 3;
inline bool GetTablesResp::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool GetTablesResp::has_error() const {
  return _internal_has_error();
}
inline const ::exec::shared::DrillPBError& GetTablesResp::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& GetTablesResp::error() const {
  // @@protoc_insertion_point(field_get:exec.user.GetTablesResp.error)
  return _internal_error();
}
inline void GetTablesResp::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetTablesResp.error)
}
inline ::exec::shared::DrillPBError* GetTablesResp::release_error() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* GetTablesResp::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.user.GetTablesResp.error)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* GetTablesResp::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000001u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* GetTablesResp::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetTablesResp.error)
  return _internal_mutable_error();
}
inline void GetTablesResp::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error)->GetArena();
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetTablesResp.error)
}

// -------------------------------------------------------------------

// GetColumnsReq

// optional .exec.user.LikeFilter catalog_name_filter = 1;
inline bool GetColumnsReq::_internal_has_catalog_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || catalog_name_filter_ != nullptr);
  return value;
}
inline bool GetColumnsReq::has_catalog_name_filter() const {
  return _internal_has_catalog_name_filter();
}
inline void GetColumnsReq::clear_catalog_name_filter() {
  if (catalog_name_filter_ != nullptr) catalog_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::user::LikeFilter& GetColumnsReq::_internal_catalog_name_filter() const {
  const ::exec::user::LikeFilter* p = catalog_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetColumnsReq::catalog_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetColumnsReq.catalog_name_filter)
  return _internal_catalog_name_filter();
}
inline void GetColumnsReq::unsafe_arena_set_allocated_catalog_name_filter(
    ::exec::user::LikeFilter* catalog_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(catalog_name_filter_);
  }
  catalog_name_filter_ = catalog_name_filter;
  if (catalog_name_filter) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetColumnsReq.catalog_name_filter)
}
inline ::exec::user::LikeFilter* GetColumnsReq::release_catalog_name_filter() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::unsafe_arena_release_catalog_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetColumnsReq.catalog_name_filter)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::LikeFilter* temp = catalog_name_filter_;
  catalog_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::_internal_mutable_catalog_name_filter() {
  _has_bits_[0] |= 0x00000001u;
  if (catalog_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    catalog_name_filter_ = p;
  }
  return catalog_name_filter_;
}
inline ::exec::user::LikeFilter* GetColumnsReq::mutable_catalog_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetColumnsReq.catalog_name_filter)
  return _internal_mutable_catalog_name_filter();
}
inline void GetColumnsReq::set_allocated_catalog_name_filter(::exec::user::LikeFilter* catalog_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete catalog_name_filter_;
  }
  if (catalog_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(catalog_name_filter);
    if (message_arena != submessage_arena) {
      catalog_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, catalog_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_filter_ = catalog_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetColumnsReq.catalog_name_filter)
}

// optional .exec.user.LikeFilter schema_name_filter = 2;
inline bool GetColumnsReq::_internal_has_schema_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || schema_name_filter_ != nullptr);
  return value;
}
inline bool GetColumnsReq::has_schema_name_filter() const {
  return _internal_has_schema_name_filter();
}
inline void GetColumnsReq::clear_schema_name_filter() {
  if (schema_name_filter_ != nullptr) schema_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::user::LikeFilter& GetColumnsReq::_internal_schema_name_filter() const {
  const ::exec::user::LikeFilter* p = schema_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetColumnsReq::schema_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetColumnsReq.schema_name_filter)
  return _internal_schema_name_filter();
}
inline void GetColumnsReq::unsafe_arena_set_allocated_schema_name_filter(
    ::exec::user::LikeFilter* schema_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(schema_name_filter_);
  }
  schema_name_filter_ = schema_name_filter;
  if (schema_name_filter) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetColumnsReq.schema_name_filter)
}
inline ::exec::user::LikeFilter* GetColumnsReq::release_schema_name_filter() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::LikeFilter* temp = schema_name_filter_;
  schema_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::unsafe_arena_release_schema_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetColumnsReq.schema_name_filter)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::LikeFilter* temp = schema_name_filter_;
  schema_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::_internal_mutable_schema_name_filter() {
  _has_bits_[0] |= 0x00000002u;
  if (schema_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    schema_name_filter_ = p;
  }
  return schema_name_filter_;
}
inline ::exec::user::LikeFilter* GetColumnsReq::mutable_schema_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetColumnsReq.schema_name_filter)
  return _internal_mutable_schema_name_filter();
}
inline void GetColumnsReq::set_allocated_schema_name_filter(::exec::user::LikeFilter* schema_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete schema_name_filter_;
  }
  if (schema_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(schema_name_filter);
    if (message_arena != submessage_arena) {
      schema_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, schema_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  schema_name_filter_ = schema_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetColumnsReq.schema_name_filter)
}

// optional .exec.user.LikeFilter table_name_filter = 3;
inline bool GetColumnsReq::_internal_has_table_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  PROTOBUF_ASSUME(!value || table_name_filter_ != nullptr);
  return value;
}
inline bool GetColumnsReq::has_table_name_filter() const {
  return _internal_has_table_name_filter();
}
inline void GetColumnsReq::clear_table_name_filter() {
  if (table_name_filter_ != nullptr) table_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000004u;
}
inline const ::exec::user::LikeFilter& GetColumnsReq::_internal_table_name_filter() const {
  const ::exec::user::LikeFilter* p = table_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetColumnsReq::table_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetColumnsReq.table_name_filter)
  return _internal_table_name_filter();
}
inline void GetColumnsReq::unsafe_arena_set_allocated_table_name_filter(
    ::exec::user::LikeFilter* table_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(table_name_filter_);
  }
  table_name_filter_ = table_name_filter;
  if (table_name_filter) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetColumnsReq.table_name_filter)
}
inline ::exec::user::LikeFilter* GetColumnsReq::release_table_name_filter() {
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::LikeFilter* temp = table_name_filter_;
  table_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::unsafe_arena_release_table_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetColumnsReq.table_name_filter)
  _has_bits_[0] &= ~0x00000004u;
  ::exec::user::LikeFilter* temp = table_name_filter_;
  table_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::_internal_mutable_table_name_filter() {
  _has_bits_[0] |= 0x00000004u;
  if (table_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    table_name_filter_ = p;
  }
  return table_name_filter_;
}
inline ::exec::user::LikeFilter* GetColumnsReq::mutable_table_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetColumnsReq.table_name_filter)
  return _internal_mutable_table_name_filter();
}
inline void GetColumnsReq::set_allocated_table_name_filter(::exec::user::LikeFilter* table_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete table_name_filter_;
  }
  if (table_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(table_name_filter);
    if (message_arena != submessage_arena) {
      table_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, table_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  table_name_filter_ = table_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetColumnsReq.table_name_filter)
}

// optional .exec.user.LikeFilter column_name_filter = 4;
inline bool GetColumnsReq::_internal_has_column_name_filter() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  PROTOBUF_ASSUME(!value || column_name_filter_ != nullptr);
  return value;
}
inline bool GetColumnsReq::has_column_name_filter() const {
  return _internal_has_column_name_filter();
}
inline void GetColumnsReq::clear_column_name_filter() {
  if (column_name_filter_ != nullptr) column_name_filter_->Clear();
  _has_bits_[0] &= ~0x00000008u;
}
inline const ::exec::user::LikeFilter& GetColumnsReq::_internal_column_name_filter() const {
  const ::exec::user::LikeFilter* p = column_name_filter_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::LikeFilter&>(
      ::exec::user::_LikeFilter_default_instance_);
}
inline const ::exec::user::LikeFilter& GetColumnsReq::column_name_filter() const {
  // @@protoc_insertion_point(field_get:exec.user.GetColumnsReq.column_name_filter)
  return _internal_column_name_filter();
}
inline void GetColumnsReq::unsafe_arena_set_allocated_column_name_filter(
    ::exec::user::LikeFilter* column_name_filter) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(column_name_filter_);
  }
  column_name_filter_ = column_name_filter;
  if (column_name_filter) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetColumnsReq.column_name_filter)
}
inline ::exec::user::LikeFilter* GetColumnsReq::release_column_name_filter() {
  _has_bits_[0] &= ~0x00000008u;
  ::exec::user::LikeFilter* temp = column_name_filter_;
  column_name_filter_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::unsafe_arena_release_column_name_filter() {
  // @@protoc_insertion_point(field_release:exec.user.GetColumnsReq.column_name_filter)
  _has_bits_[0] &= ~0x00000008u;
  ::exec::user::LikeFilter* temp = column_name_filter_;
  column_name_filter_ = nullptr;
  return temp;
}
inline ::exec::user::LikeFilter* GetColumnsReq::_internal_mutable_column_name_filter() {
  _has_bits_[0] |= 0x00000008u;
  if (column_name_filter_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::LikeFilter>(GetArena());
    column_name_filter_ = p;
  }
  return column_name_filter_;
}
inline ::exec::user::LikeFilter* GetColumnsReq::mutable_column_name_filter() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetColumnsReq.column_name_filter)
  return _internal_mutable_column_name_filter();
}
inline void GetColumnsReq::set_allocated_column_name_filter(::exec::user::LikeFilter* column_name_filter) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete column_name_filter_;
  }
  if (column_name_filter) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(column_name_filter);
    if (message_arena != submessage_arena) {
      column_name_filter = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, column_name_filter, submessage_arena);
    }
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  column_name_filter_ = column_name_filter;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetColumnsReq.column_name_filter)
}

// -------------------------------------------------------------------

// ColumnMetadata

// optional string catalog_name = 1;
inline bool ColumnMetadata::_internal_has_catalog_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool ColumnMetadata::has_catalog_name() const {
  return _internal_has_catalog_name();
}
inline void ColumnMetadata::clear_catalog_name() {
  catalog_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& ColumnMetadata::catalog_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.catalog_name)
  return _internal_catalog_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ColumnMetadata::set_catalog_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.catalog_name)
}
inline std::string* ColumnMetadata::mutable_catalog_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ColumnMetadata.catalog_name)
  return _internal_mutable_catalog_name();
}
inline const std::string& ColumnMetadata::_internal_catalog_name() const {
  return catalog_name_.Get();
}
inline void ColumnMetadata::_internal_set_catalog_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ColumnMetadata::_internal_mutable_catalog_name() {
  _has_bits_[0] |= 0x00000001u;
  return catalog_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ColumnMetadata::release_catalog_name() {
  // @@protoc_insertion_point(field_release:exec.user.ColumnMetadata.catalog_name)
  if (!_internal_has_catalog_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return catalog_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ColumnMetadata::set_allocated_catalog_name(std::string* catalog_name) {
  if (catalog_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), catalog_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ColumnMetadata.catalog_name)
}

// optional string schema_name = 2;
inline bool ColumnMetadata::_internal_has_schema_name() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool ColumnMetadata::has_schema_name() const {
  return _internal_has_schema_name();
}
inline void ColumnMetadata::clear_schema_name() {
  schema_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& ColumnMetadata::schema_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.schema_name)
  return _internal_schema_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ColumnMetadata::set_schema_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.schema_name)
}
inline std::string* ColumnMetadata::mutable_schema_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ColumnMetadata.schema_name)
  return _internal_mutable_schema_name();
}
inline const std::string& ColumnMetadata::_internal_schema_name() const {
  return schema_name_.Get();
}
inline void ColumnMetadata::_internal_set_schema_name(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ColumnMetadata::_internal_mutable_schema_name() {
  _has_bits_[0] |= 0x00000002u;
  return schema_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ColumnMetadata::release_schema_name() {
  // @@protoc_insertion_point(field_release:exec.user.ColumnMetadata.schema_name)
  if (!_internal_has_schema_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return schema_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ColumnMetadata::set_allocated_schema_name(std::string* schema_name) {
  if (schema_name != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  schema_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), schema_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ColumnMetadata.schema_name)
}

// optional string table_name = 3;
inline bool ColumnMetadata::_internal_has_table_name() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool ColumnMetadata::has_table_name() const {
  return _internal_has_table_name();
}
inline void ColumnMetadata::clear_table_name() {
  table_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& ColumnMetadata::table_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.table_name)
  return _internal_table_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ColumnMetadata::set_table_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 table_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.table_name)
}
inline std::string* ColumnMetadata::mutable_table_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ColumnMetadata.table_name)
  return _internal_mutable_table_name();
}
inline const std::string& ColumnMetadata::_internal_table_name() const {
  return table_name_.Get();
}
inline void ColumnMetadata::_internal_set_table_name(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  table_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ColumnMetadata::_internal_mutable_table_name() {
  _has_bits_[0] |= 0x00000004u;
  return table_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ColumnMetadata::release_table_name() {
  // @@protoc_insertion_point(field_release:exec.user.ColumnMetadata.table_name)
  if (!_internal_has_table_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return table_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ColumnMetadata::set_allocated_table_name(std::string* table_name) {
  if (table_name != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  table_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), table_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ColumnMetadata.table_name)
}

// optional string column_name = 4;
inline bool ColumnMetadata::_internal_has_column_name() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool ColumnMetadata::has_column_name() const {
  return _internal_has_column_name();
}
inline void ColumnMetadata::clear_column_name() {
  column_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& ColumnMetadata::column_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.column_name)
  return _internal_column_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ColumnMetadata::set_column_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 column_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.column_name)
}
inline std::string* ColumnMetadata::mutable_column_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ColumnMetadata.column_name)
  return _internal_mutable_column_name();
}
inline const std::string& ColumnMetadata::_internal_column_name() const {
  return column_name_.Get();
}
inline void ColumnMetadata::_internal_set_column_name(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  column_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ColumnMetadata::_internal_mutable_column_name() {
  _has_bits_[0] |= 0x00000008u;
  return column_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ColumnMetadata::release_column_name() {
  // @@protoc_insertion_point(field_release:exec.user.ColumnMetadata.column_name)
  if (!_internal_has_column_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return column_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ColumnMetadata::set_allocated_column_name(std::string* column_name) {
  if (column_name != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  column_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), column_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ColumnMetadata.column_name)
}

// optional int32 ordinal_position = 5;
inline bool ColumnMetadata::_internal_has_ordinal_position() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool ColumnMetadata::has_ordinal_position() const {
  return _internal_has_ordinal_position();
}
inline void ColumnMetadata::clear_ordinal_position() {
  ordinal_position_ = 0;
  _has_bits_[0] &= ~0x00000080u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_ordinal_position() const {
  return ordinal_position_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::ordinal_position() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.ordinal_position)
  return _internal_ordinal_position();
}
inline void ColumnMetadata::_internal_set_ordinal_position(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000080u;
  ordinal_position_ = value;
}
inline void ColumnMetadata::set_ordinal_position(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_ordinal_position(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.ordinal_position)
}

// optional string default_value = 6;
inline bool ColumnMetadata::_internal_has_default_value() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool ColumnMetadata::has_default_value() const {
  return _internal_has_default_value();
}
inline void ColumnMetadata::clear_default_value() {
  default_value_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000010u;
}
inline const std::string& ColumnMetadata::default_value() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.default_value)
  return _internal_default_value();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ColumnMetadata::set_default_value(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000010u;
 default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.default_value)
}
inline std::string* ColumnMetadata::mutable_default_value() {
  // @@protoc_insertion_point(field_mutable:exec.user.ColumnMetadata.default_value)
  return _internal_mutable_default_value();
}
inline const std::string& ColumnMetadata::_internal_default_value() const {
  return default_value_.Get();
}
inline void ColumnMetadata::_internal_set_default_value(const std::string& value) {
  _has_bits_[0] |= 0x00000010u;
  default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ColumnMetadata::_internal_mutable_default_value() {
  _has_bits_[0] |= 0x00000010u;
  return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ColumnMetadata::release_default_value() {
  // @@protoc_insertion_point(field_release:exec.user.ColumnMetadata.default_value)
  if (!_internal_has_default_value()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000010u;
  return default_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ColumnMetadata::set_allocated_default_value(std::string* default_value) {
  if (default_value != nullptr) {
    _has_bits_[0] |= 0x00000010u;
  } else {
    _has_bits_[0] &= ~0x00000010u;
  }
  default_value_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), default_value,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ColumnMetadata.default_value)
}

// optional bool is_nullable = 7;
inline bool ColumnMetadata::_internal_has_is_nullable() const {
  bool value = (_has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool ColumnMetadata::has_is_nullable() const {
  return _internal_has_is_nullable();
}
inline void ColumnMetadata::clear_is_nullable() {
  is_nullable_ = false;
  _has_bits_[0] &= ~0x00000100u;
}
inline bool ColumnMetadata::_internal_is_nullable() const {
  return is_nullable_;
}
inline bool ColumnMetadata::is_nullable() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.is_nullable)
  return _internal_is_nullable();
}
inline void ColumnMetadata::_internal_set_is_nullable(bool value) {
  _has_bits_[0] |= 0x00000100u;
  is_nullable_ = value;
}
inline void ColumnMetadata::set_is_nullable(bool value) {
  _internal_set_is_nullable(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.is_nullable)
}

// optional string data_type = 8;
inline bool ColumnMetadata::_internal_has_data_type() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool ColumnMetadata::has_data_type() const {
  return _internal_has_data_type();
}
inline void ColumnMetadata::clear_data_type() {
  data_type_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000020u;
}
inline const std::string& ColumnMetadata::data_type() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.data_type)
  return _internal_data_type();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ColumnMetadata::set_data_type(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000020u;
 data_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.data_type)
}
inline std::string* ColumnMetadata::mutable_data_type() {
  // @@protoc_insertion_point(field_mutable:exec.user.ColumnMetadata.data_type)
  return _internal_mutable_data_type();
}
inline const std::string& ColumnMetadata::_internal_data_type() const {
  return data_type_.Get();
}
inline void ColumnMetadata::_internal_set_data_type(const std::string& value) {
  _has_bits_[0] |= 0x00000020u;
  data_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ColumnMetadata::_internal_mutable_data_type() {
  _has_bits_[0] |= 0x00000020u;
  return data_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ColumnMetadata::release_data_type() {
  // @@protoc_insertion_point(field_release:exec.user.ColumnMetadata.data_type)
  if (!_internal_has_data_type()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000020u;
  return data_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ColumnMetadata::set_allocated_data_type(std::string* data_type) {
  if (data_type != nullptr) {
    _has_bits_[0] |= 0x00000020u;
  } else {
    _has_bits_[0] &= ~0x00000020u;
  }
  data_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), data_type,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ColumnMetadata.data_type)
}

// optional int32 char_max_length = 9;
inline bool ColumnMetadata::_internal_has_char_max_length() const {
  bool value = (_has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline bool ColumnMetadata::has_char_max_length() const {
  return _internal_has_char_max_length();
}
inline void ColumnMetadata::clear_char_max_length() {
  char_max_length_ = 0;
  _has_bits_[0] &= ~0x00000200u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_char_max_length() const {
  return char_max_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::char_max_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.char_max_length)
  return _internal_char_max_length();
}
inline void ColumnMetadata::_internal_set_char_max_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000200u;
  char_max_length_ = value;
}
inline void ColumnMetadata::set_char_max_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_char_max_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.char_max_length)
}

// optional int32 char_octet_length = 10;
inline bool ColumnMetadata::_internal_has_char_octet_length() const {
  bool value = (_has_bits_[0] & 0x00000400u) != 0;
  return value;
}
inline bool ColumnMetadata::has_char_octet_length() const {
  return _internal_has_char_octet_length();
}
inline void ColumnMetadata::clear_char_octet_length() {
  char_octet_length_ = 0;
  _has_bits_[0] &= ~0x00000400u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_char_octet_length() const {
  return char_octet_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::char_octet_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.char_octet_length)
  return _internal_char_octet_length();
}
inline void ColumnMetadata::_internal_set_char_octet_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000400u;
  char_octet_length_ = value;
}
inline void ColumnMetadata::set_char_octet_length(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_char_octet_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.char_octet_length)
}

// optional int32 numeric_precision = 11;
inline bool ColumnMetadata::_internal_has_numeric_precision() const {
  bool value = (_has_bits_[0] & 0x00000800u) != 0;
  return value;
}
inline bool ColumnMetadata::has_numeric_precision() const {
  return _internal_has_numeric_precision();
}
inline void ColumnMetadata::clear_numeric_precision() {
  numeric_precision_ = 0;
  _has_bits_[0] &= ~0x00000800u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_numeric_precision() const {
  return numeric_precision_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::numeric_precision() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.numeric_precision)
  return _internal_numeric_precision();
}
inline void ColumnMetadata::_internal_set_numeric_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000800u;
  numeric_precision_ = value;
}
inline void ColumnMetadata::set_numeric_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_numeric_precision(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.numeric_precision)
}

// optional int32 numeric_precision_radix = 12;
inline bool ColumnMetadata::_internal_has_numeric_precision_radix() const {
  bool value = (_has_bits_[0] & 0x00001000u) != 0;
  return value;
}
inline bool ColumnMetadata::has_numeric_precision_radix() const {
  return _internal_has_numeric_precision_radix();
}
inline void ColumnMetadata::clear_numeric_precision_radix() {
  numeric_precision_radix_ = 0;
  _has_bits_[0] &= ~0x00001000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_numeric_precision_radix() const {
  return numeric_precision_radix_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::numeric_precision_radix() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.numeric_precision_radix)
  return _internal_numeric_precision_radix();
}
inline void ColumnMetadata::_internal_set_numeric_precision_radix(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00001000u;
  numeric_precision_radix_ = value;
}
inline void ColumnMetadata::set_numeric_precision_radix(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_numeric_precision_radix(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.numeric_precision_radix)
}

// optional int32 numeric_scale = 13;
inline bool ColumnMetadata::_internal_has_numeric_scale() const {
  bool value = (_has_bits_[0] & 0x00002000u) != 0;
  return value;
}
inline bool ColumnMetadata::has_numeric_scale() const {
  return _internal_has_numeric_scale();
}
inline void ColumnMetadata::clear_numeric_scale() {
  numeric_scale_ = 0;
  _has_bits_[0] &= ~0x00002000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_numeric_scale() const {
  return numeric_scale_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::numeric_scale() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.numeric_scale)
  return _internal_numeric_scale();
}
inline void ColumnMetadata::_internal_set_numeric_scale(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00002000u;
  numeric_scale_ = value;
}
inline void ColumnMetadata::set_numeric_scale(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_numeric_scale(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.numeric_scale)
}

// optional int32 date_time_precision = 14;
inline bool ColumnMetadata::_internal_has_date_time_precision() const {
  bool value = (_has_bits_[0] & 0x00004000u) != 0;
  return value;
}
inline bool ColumnMetadata::has_date_time_precision() const {
  return _internal_has_date_time_precision();
}
inline void ColumnMetadata::clear_date_time_precision() {
  date_time_precision_ = 0;
  _has_bits_[0] &= ~0x00004000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_date_time_precision() const {
  return date_time_precision_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::date_time_precision() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.date_time_precision)
  return _internal_date_time_precision();
}
inline void ColumnMetadata::_internal_set_date_time_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00004000u;
  date_time_precision_ = value;
}
inline void ColumnMetadata::set_date_time_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_date_time_precision(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.date_time_precision)
}

// optional string interval_type = 15;
inline bool ColumnMetadata::_internal_has_interval_type() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool ColumnMetadata::has_interval_type() const {
  return _internal_has_interval_type();
}
inline void ColumnMetadata::clear_interval_type() {
  interval_type_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000040u;
}
inline const std::string& ColumnMetadata::interval_type() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.interval_type)
  return _internal_interval_type();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ColumnMetadata::set_interval_type(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000040u;
 interval_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.interval_type)
}
inline std::string* ColumnMetadata::mutable_interval_type() {
  // @@protoc_insertion_point(field_mutable:exec.user.ColumnMetadata.interval_type)
  return _internal_mutable_interval_type();
}
inline const std::string& ColumnMetadata::_internal_interval_type() const {
  return interval_type_.Get();
}
inline void ColumnMetadata::_internal_set_interval_type(const std::string& value) {
  _has_bits_[0] |= 0x00000040u;
  interval_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ColumnMetadata::_internal_mutable_interval_type() {
  _has_bits_[0] |= 0x00000040u;
  return interval_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ColumnMetadata::release_interval_type() {
  // @@protoc_insertion_point(field_release:exec.user.ColumnMetadata.interval_type)
  if (!_internal_has_interval_type()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000040u;
  return interval_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ColumnMetadata::set_allocated_interval_type(std::string* interval_type) {
  if (interval_type != nullptr) {
    _has_bits_[0] |= 0x00000040u;
  } else {
    _has_bits_[0] &= ~0x00000040u;
  }
  interval_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), interval_type,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ColumnMetadata.interval_type)
}

// optional int32 interval_precision = 16;
inline bool ColumnMetadata::_internal_has_interval_precision() const {
  bool value = (_has_bits_[0] & 0x00008000u) != 0;
  return value;
}
inline bool ColumnMetadata::has_interval_precision() const {
  return _internal_has_interval_precision();
}
inline void ColumnMetadata::clear_interval_precision() {
  interval_precision_ = 0;
  _has_bits_[0] &= ~0x00008000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_interval_precision() const {
  return interval_precision_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::interval_precision() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.interval_precision)
  return _internal_interval_precision();
}
inline void ColumnMetadata::_internal_set_interval_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00008000u;
  interval_precision_ = value;
}
inline void ColumnMetadata::set_interval_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_interval_precision(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.interval_precision)
}

// optional int32 column_size = 17;
inline bool ColumnMetadata::_internal_has_column_size() const {
  bool value = (_has_bits_[0] & 0x00010000u) != 0;
  return value;
}
inline bool ColumnMetadata::has_column_size() const {
  return _internal_has_column_size();
}
inline void ColumnMetadata::clear_column_size() {
  column_size_ = 0;
  _has_bits_[0] &= ~0x00010000u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::_internal_column_size() const {
  return column_size_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ColumnMetadata::column_size() const {
  // @@protoc_insertion_point(field_get:exec.user.ColumnMetadata.column_size)
  return _internal_column_size();
}
inline void ColumnMetadata::_internal_set_column_size(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00010000u;
  column_size_ = value;
}
inline void ColumnMetadata::set_column_size(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_column_size(value);
  // @@protoc_insertion_point(field_set:exec.user.ColumnMetadata.column_size)
}

// -------------------------------------------------------------------

// GetColumnsResp

// optional .exec.user.RequestStatus status = 1;
inline bool GetColumnsResp::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool GetColumnsResp::has_status() const {
  return _internal_has_status();
}
inline void GetColumnsResp::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::exec::user::RequestStatus GetColumnsResp::_internal_status() const {
  return static_cast< ::exec::user::RequestStatus >(status_);
}
inline ::exec::user::RequestStatus GetColumnsResp::status() const {
  // @@protoc_insertion_point(field_get:exec.user.GetColumnsResp.status)
  return _internal_status();
}
inline void GetColumnsResp::_internal_set_status(::exec::user::RequestStatus value) {
  assert(::exec::user::RequestStatus_IsValid(value));
  _has_bits_[0] |= 0x00000002u;
  status_ = value;
}
inline void GetColumnsResp::set_status(::exec::user::RequestStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.GetColumnsResp.status)
}

// repeated .exec.user.ColumnMetadata columns = 2;
inline int GetColumnsResp::_internal_columns_size() const {
  return columns_.size();
}
inline int GetColumnsResp::columns_size() const {
  return _internal_columns_size();
}
inline void GetColumnsResp::clear_columns() {
  columns_.Clear();
}
inline ::exec::user::ColumnMetadata* GetColumnsResp::mutable_columns(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.GetColumnsResp.columns)
  return columns_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ColumnMetadata >*
GetColumnsResp::mutable_columns() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.GetColumnsResp.columns)
  return &columns_;
}
inline const ::exec::user::ColumnMetadata& GetColumnsResp::_internal_columns(int index) const {
  return columns_.Get(index);
}
inline const ::exec::user::ColumnMetadata& GetColumnsResp::columns(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.GetColumnsResp.columns)
  return _internal_columns(index);
}
inline ::exec::user::ColumnMetadata* GetColumnsResp::_internal_add_columns() {
  return columns_.Add();
}
inline ::exec::user::ColumnMetadata* GetColumnsResp::add_columns() {
  // @@protoc_insertion_point(field_add:exec.user.GetColumnsResp.columns)
  return _internal_add_columns();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ColumnMetadata >&
GetColumnsResp::columns() const {
  // @@protoc_insertion_point(field_list:exec.user.GetColumnsResp.columns)
  return columns_;
}

// optional .exec.shared.DrillPBError error = 3;
inline bool GetColumnsResp::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool GetColumnsResp::has_error() const {
  return _internal_has_error();
}
inline const ::exec::shared::DrillPBError& GetColumnsResp::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& GetColumnsResp::error() const {
  // @@protoc_insertion_point(field_get:exec.user.GetColumnsResp.error)
  return _internal_error();
}
inline void GetColumnsResp::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetColumnsResp.error)
}
inline ::exec::shared::DrillPBError* GetColumnsResp::release_error() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* GetColumnsResp::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.user.GetColumnsResp.error)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* GetColumnsResp::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000001u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* GetColumnsResp::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetColumnsResp.error)
  return _internal_mutable_error();
}
inline void GetColumnsResp::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error)->GetArena();
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetColumnsResp.error)
}

// -------------------------------------------------------------------

// CreatePreparedStatementReq

// optional string sql_query = 1;
inline bool CreatePreparedStatementReq::_internal_has_sql_query() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool CreatePreparedStatementReq::has_sql_query() const {
  return _internal_has_sql_query();
}
inline void CreatePreparedStatementReq::clear_sql_query() {
  sql_query_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& CreatePreparedStatementReq::sql_query() const {
  // @@protoc_insertion_point(field_get:exec.user.CreatePreparedStatementReq.sql_query)
  return _internal_sql_query();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void CreatePreparedStatementReq::set_sql_query(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 sql_query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.CreatePreparedStatementReq.sql_query)
}
inline std::string* CreatePreparedStatementReq::mutable_sql_query() {
  // @@protoc_insertion_point(field_mutable:exec.user.CreatePreparedStatementReq.sql_query)
  return _internal_mutable_sql_query();
}
inline const std::string& CreatePreparedStatementReq::_internal_sql_query() const {
  return sql_query_.Get();
}
inline void CreatePreparedStatementReq::_internal_set_sql_query(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  sql_query_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* CreatePreparedStatementReq::_internal_mutable_sql_query() {
  _has_bits_[0] |= 0x00000001u;
  return sql_query_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* CreatePreparedStatementReq::release_sql_query() {
  // @@protoc_insertion_point(field_release:exec.user.CreatePreparedStatementReq.sql_query)
  if (!_internal_has_sql_query()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return sql_query_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void CreatePreparedStatementReq::set_allocated_sql_query(std::string* sql_query) {
  if (sql_query != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  sql_query_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), sql_query,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.CreatePreparedStatementReq.sql_query)
}

// -------------------------------------------------------------------

// ResultColumnMetadata

// optional string catalog_name = 1;
inline bool ResultColumnMetadata::_internal_has_catalog_name() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_catalog_name() const {
  return _internal_has_catalog_name();
}
inline void ResultColumnMetadata::clear_catalog_name() {
  catalog_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& ResultColumnMetadata::catalog_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.catalog_name)
  return _internal_catalog_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ResultColumnMetadata::set_catalog_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.catalog_name)
}
inline std::string* ResultColumnMetadata::mutable_catalog_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ResultColumnMetadata.catalog_name)
  return _internal_mutable_catalog_name();
}
inline const std::string& ResultColumnMetadata::_internal_catalog_name() const {
  return catalog_name_.Get();
}
inline void ResultColumnMetadata::_internal_set_catalog_name(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  catalog_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ResultColumnMetadata::_internal_mutable_catalog_name() {
  _has_bits_[0] |= 0x00000001u;
  return catalog_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ResultColumnMetadata::release_catalog_name() {
  // @@protoc_insertion_point(field_release:exec.user.ResultColumnMetadata.catalog_name)
  if (!_internal_has_catalog_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return catalog_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ResultColumnMetadata::set_allocated_catalog_name(std::string* catalog_name) {
  if (catalog_name != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), catalog_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ResultColumnMetadata.catalog_name)
}

// optional string schema_name = 2;
inline bool ResultColumnMetadata::_internal_has_schema_name() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_schema_name() const {
  return _internal_has_schema_name();
}
inline void ResultColumnMetadata::clear_schema_name() {
  schema_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& ResultColumnMetadata::schema_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.schema_name)
  return _internal_schema_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ResultColumnMetadata::set_schema_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.schema_name)
}
inline std::string* ResultColumnMetadata::mutable_schema_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ResultColumnMetadata.schema_name)
  return _internal_mutable_schema_name();
}
inline const std::string& ResultColumnMetadata::_internal_schema_name() const {
  return schema_name_.Get();
}
inline void ResultColumnMetadata::_internal_set_schema_name(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  schema_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ResultColumnMetadata::_internal_mutable_schema_name() {
  _has_bits_[0] |= 0x00000002u;
  return schema_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ResultColumnMetadata::release_schema_name() {
  // @@protoc_insertion_point(field_release:exec.user.ResultColumnMetadata.schema_name)
  if (!_internal_has_schema_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return schema_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ResultColumnMetadata::set_allocated_schema_name(std::string* schema_name) {
  if (schema_name != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  schema_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), schema_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ResultColumnMetadata.schema_name)
}

// optional string table_name = 3;
inline bool ResultColumnMetadata::_internal_has_table_name() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_table_name() const {
  return _internal_has_table_name();
}
inline void ResultColumnMetadata::clear_table_name() {
  table_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& ResultColumnMetadata::table_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.table_name)
  return _internal_table_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ResultColumnMetadata::set_table_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 table_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.table_name)
}
inline std::string* ResultColumnMetadata::mutable_table_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ResultColumnMetadata.table_name)
  return _internal_mutable_table_name();
}
inline const std::string& ResultColumnMetadata::_internal_table_name() const {
  return table_name_.Get();
}
inline void ResultColumnMetadata::_internal_set_table_name(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  table_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ResultColumnMetadata::_internal_mutable_table_name() {
  _has_bits_[0] |= 0x00000004u;
  return table_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ResultColumnMetadata::release_table_name() {
  // @@protoc_insertion_point(field_release:exec.user.ResultColumnMetadata.table_name)
  if (!_internal_has_table_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return table_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ResultColumnMetadata::set_allocated_table_name(std::string* table_name) {
  if (table_name != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  table_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), table_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ResultColumnMetadata.table_name)
}

// optional string column_name = 4;
inline bool ResultColumnMetadata::_internal_has_column_name() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_column_name() const {
  return _internal_has_column_name();
}
inline void ResultColumnMetadata::clear_column_name() {
  column_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& ResultColumnMetadata::column_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.column_name)
  return _internal_column_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ResultColumnMetadata::set_column_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 column_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.column_name)
}
inline std::string* ResultColumnMetadata::mutable_column_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ResultColumnMetadata.column_name)
  return _internal_mutable_column_name();
}
inline const std::string& ResultColumnMetadata::_internal_column_name() const {
  return column_name_.Get();
}
inline void ResultColumnMetadata::_internal_set_column_name(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  column_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ResultColumnMetadata::_internal_mutable_column_name() {
  _has_bits_[0] |= 0x00000008u;
  return column_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ResultColumnMetadata::release_column_name() {
  // @@protoc_insertion_point(field_release:exec.user.ResultColumnMetadata.column_name)
  if (!_internal_has_column_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return column_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ResultColumnMetadata::set_allocated_column_name(std::string* column_name) {
  if (column_name != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  column_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), column_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ResultColumnMetadata.column_name)
}

// optional string label = 5;
inline bool ResultColumnMetadata::_internal_has_label() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_label() const {
  return _internal_has_label();
}
inline void ResultColumnMetadata::clear_label() {
  label_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000010u;
}
inline const std::string& ResultColumnMetadata::label() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.label)
  return _internal_label();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ResultColumnMetadata::set_label(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000010u;
 label_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.label)
}
inline std::string* ResultColumnMetadata::mutable_label() {
  // @@protoc_insertion_point(field_mutable:exec.user.ResultColumnMetadata.label)
  return _internal_mutable_label();
}
inline const std::string& ResultColumnMetadata::_internal_label() const {
  return label_.Get();
}
inline void ResultColumnMetadata::_internal_set_label(const std::string& value) {
  _has_bits_[0] |= 0x00000010u;
  label_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ResultColumnMetadata::_internal_mutable_label() {
  _has_bits_[0] |= 0x00000010u;
  return label_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ResultColumnMetadata::release_label() {
  // @@protoc_insertion_point(field_release:exec.user.ResultColumnMetadata.label)
  if (!_internal_has_label()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000010u;
  return label_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ResultColumnMetadata::set_allocated_label(std::string* label) {
  if (label != nullptr) {
    _has_bits_[0] |= 0x00000010u;
  } else {
    _has_bits_[0] &= ~0x00000010u;
  }
  label_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), label,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ResultColumnMetadata.label)
}

// optional string data_type = 6;
inline bool ResultColumnMetadata::_internal_has_data_type() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_data_type() const {
  return _internal_has_data_type();
}
inline void ResultColumnMetadata::clear_data_type() {
  data_type_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000020u;
}
inline const std::string& ResultColumnMetadata::data_type() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.data_type)
  return _internal_data_type();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ResultColumnMetadata::set_data_type(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000020u;
 data_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.data_type)
}
inline std::string* ResultColumnMetadata::mutable_data_type() {
  // @@protoc_insertion_point(field_mutable:exec.user.ResultColumnMetadata.data_type)
  return _internal_mutable_data_type();
}
inline const std::string& ResultColumnMetadata::_internal_data_type() const {
  return data_type_.Get();
}
inline void ResultColumnMetadata::_internal_set_data_type(const std::string& value) {
  _has_bits_[0] |= 0x00000020u;
  data_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ResultColumnMetadata::_internal_mutable_data_type() {
  _has_bits_[0] |= 0x00000020u;
  return data_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ResultColumnMetadata::release_data_type() {
  // @@protoc_insertion_point(field_release:exec.user.ResultColumnMetadata.data_type)
  if (!_internal_has_data_type()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000020u;
  return data_type_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ResultColumnMetadata::set_allocated_data_type(std::string* data_type) {
  if (data_type != nullptr) {
    _has_bits_[0] |= 0x00000020u;
  } else {
    _has_bits_[0] &= ~0x00000020u;
  }
  data_type_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), data_type,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ResultColumnMetadata.data_type)
}

// optional bool is_nullable = 7;
inline bool ResultColumnMetadata::_internal_has_is_nullable() const {
  bool value = (_has_bits_[0] & 0x00000400u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_is_nullable() const {
  return _internal_has_is_nullable();
}
inline void ResultColumnMetadata::clear_is_nullable() {
  is_nullable_ = false;
  _has_bits_[0] &= ~0x00000400u;
}
inline bool ResultColumnMetadata::_internal_is_nullable() const {
  return is_nullable_;
}
inline bool ResultColumnMetadata::is_nullable() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.is_nullable)
  return _internal_is_nullable();
}
inline void ResultColumnMetadata::_internal_set_is_nullable(bool value) {
  _has_bits_[0] |= 0x00000400u;
  is_nullable_ = value;
}
inline void ResultColumnMetadata::set_is_nullable(bool value) {
  _internal_set_is_nullable(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.is_nullable)
}

// optional int32 precision = 8;
inline bool ResultColumnMetadata::_internal_has_precision() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_precision() const {
  return _internal_has_precision();
}
inline void ResultColumnMetadata::clear_precision() {
  precision_ = 0;
  _has_bits_[0] &= ~0x00000080u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ResultColumnMetadata::_internal_precision() const {
  return precision_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ResultColumnMetadata::precision() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.precision)
  return _internal_precision();
}
inline void ResultColumnMetadata::_internal_set_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000080u;
  precision_ = value;
}
inline void ResultColumnMetadata::set_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_precision(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.precision)
}

// optional int32 scale = 9;
inline bool ResultColumnMetadata::_internal_has_scale() const {
  bool value = (_has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_scale() const {
  return _internal_has_scale();
}
inline void ResultColumnMetadata::clear_scale() {
  scale_ = 0;
  _has_bits_[0] &= ~0x00000100u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ResultColumnMetadata::_internal_scale() const {
  return scale_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ResultColumnMetadata::scale() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.scale)
  return _internal_scale();
}
inline void ResultColumnMetadata::_internal_set_scale(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000100u;
  scale_ = value;
}
inline void ResultColumnMetadata::set_scale(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_scale(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.scale)
}

// optional bool signed = 10;
inline bool ResultColumnMetadata::_internal_has_signed_() const {
  bool value = (_has_bits_[0] & 0x00000800u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_signed_() const {
  return _internal_has_signed_();
}
inline void ResultColumnMetadata::clear_signed_() {
  signed__ = false;
  _has_bits_[0] &= ~0x00000800u;
}
inline bool ResultColumnMetadata::_internal_signed_() const {
  return signed__;
}
inline bool ResultColumnMetadata::signed_() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.signed)
  return _internal_signed_();
}
inline void ResultColumnMetadata::_internal_set_signed_(bool value) {
  _has_bits_[0] |= 0x00000800u;
  signed__ = value;
}
inline void ResultColumnMetadata::set_signed_(bool value) {
  _internal_set_signed_(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.signed)
}

// optional int32 display_size = 11;
inline bool ResultColumnMetadata::_internal_has_display_size() const {
  bool value = (_has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_display_size() const {
  return _internal_has_display_size();
}
inline void ResultColumnMetadata::clear_display_size() {
  display_size_ = 0;
  _has_bits_[0] &= ~0x00000200u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ResultColumnMetadata::_internal_display_size() const {
  return display_size_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 ResultColumnMetadata::display_size() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.display_size)
  return _internal_display_size();
}
inline void ResultColumnMetadata::_internal_set_display_size(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000200u;
  display_size_ = value;
}
inline void ResultColumnMetadata::set_display_size(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_display_size(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.display_size)
}

// optional bool is_aliased = 12;
inline bool ResultColumnMetadata::_internal_has_is_aliased() const {
  bool value = (_has_bits_[0] & 0x00001000u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_is_aliased() const {
  return _internal_has_is_aliased();
}
inline void ResultColumnMetadata::clear_is_aliased() {
  is_aliased_ = false;
  _has_bits_[0] &= ~0x00001000u;
}
inline bool ResultColumnMetadata::_internal_is_aliased() const {
  return is_aliased_;
}
inline bool ResultColumnMetadata::is_aliased() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.is_aliased)
  return _internal_is_aliased();
}
inline void ResultColumnMetadata::_internal_set_is_aliased(bool value) {
  _has_bits_[0] |= 0x00001000u;
  is_aliased_ = value;
}
inline void ResultColumnMetadata::set_is_aliased(bool value) {
  _internal_set_is_aliased(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.is_aliased)
}

// optional .exec.user.ColumnSearchability searchability = 13;
inline bool ResultColumnMetadata::_internal_has_searchability() const {
  bool value = (_has_bits_[0] & 0x00004000u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_searchability() const {
  return _internal_has_searchability();
}
inline void ResultColumnMetadata::clear_searchability() {
  searchability_ = 0;
  _has_bits_[0] &= ~0x00004000u;
}
inline ::exec::user::ColumnSearchability ResultColumnMetadata::_internal_searchability() const {
  return static_cast< ::exec::user::ColumnSearchability >(searchability_);
}
inline ::exec::user::ColumnSearchability ResultColumnMetadata::searchability() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.searchability)
  return _internal_searchability();
}
inline void ResultColumnMetadata::_internal_set_searchability(::exec::user::ColumnSearchability value) {
  assert(::exec::user::ColumnSearchability_IsValid(value));
  _has_bits_[0] |= 0x00004000u;
  searchability_ = value;
}
inline void ResultColumnMetadata::set_searchability(::exec::user::ColumnSearchability value) {
  _internal_set_searchability(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.searchability)
}

// optional .exec.user.ColumnUpdatability updatability = 14;
inline bool ResultColumnMetadata::_internal_has_updatability() const {
  bool value = (_has_bits_[0] & 0x00008000u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_updatability() const {
  return _internal_has_updatability();
}
inline void ResultColumnMetadata::clear_updatability() {
  updatability_ = 0;
  _has_bits_[0] &= ~0x00008000u;
}
inline ::exec::user::ColumnUpdatability ResultColumnMetadata::_internal_updatability() const {
  return static_cast< ::exec::user::ColumnUpdatability >(updatability_);
}
inline ::exec::user::ColumnUpdatability ResultColumnMetadata::updatability() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.updatability)
  return _internal_updatability();
}
inline void ResultColumnMetadata::_internal_set_updatability(::exec::user::ColumnUpdatability value) {
  assert(::exec::user::ColumnUpdatability_IsValid(value));
  _has_bits_[0] |= 0x00008000u;
  updatability_ = value;
}
inline void ResultColumnMetadata::set_updatability(::exec::user::ColumnUpdatability value) {
  _internal_set_updatability(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.updatability)
}

// optional bool auto_increment = 15;
inline bool ResultColumnMetadata::_internal_has_auto_increment() const {
  bool value = (_has_bits_[0] & 0x00002000u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_auto_increment() const {
  return _internal_has_auto_increment();
}
inline void ResultColumnMetadata::clear_auto_increment() {
  auto_increment_ = false;
  _has_bits_[0] &= ~0x00002000u;
}
inline bool ResultColumnMetadata::_internal_auto_increment() const {
  return auto_increment_;
}
inline bool ResultColumnMetadata::auto_increment() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.auto_increment)
  return _internal_auto_increment();
}
inline void ResultColumnMetadata::_internal_set_auto_increment(bool value) {
  _has_bits_[0] |= 0x00002000u;
  auto_increment_ = value;
}
inline void ResultColumnMetadata::set_auto_increment(bool value) {
  _internal_set_auto_increment(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.auto_increment)
}

// optional bool case_sensitivity = 16;
inline bool ResultColumnMetadata::_internal_has_case_sensitivity() const {
  bool value = (_has_bits_[0] & 0x00010000u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_case_sensitivity() const {
  return _internal_has_case_sensitivity();
}
inline void ResultColumnMetadata::clear_case_sensitivity() {
  case_sensitivity_ = false;
  _has_bits_[0] &= ~0x00010000u;
}
inline bool ResultColumnMetadata::_internal_case_sensitivity() const {
  return case_sensitivity_;
}
inline bool ResultColumnMetadata::case_sensitivity() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.case_sensitivity)
  return _internal_case_sensitivity();
}
inline void ResultColumnMetadata::_internal_set_case_sensitivity(bool value) {
  _has_bits_[0] |= 0x00010000u;
  case_sensitivity_ = value;
}
inline void ResultColumnMetadata::set_case_sensitivity(bool value) {
  _internal_set_case_sensitivity(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.case_sensitivity)
}

// optional bool sortable = 17;
inline bool ResultColumnMetadata::_internal_has_sortable() const {
  bool value = (_has_bits_[0] & 0x00020000u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_sortable() const {
  return _internal_has_sortable();
}
inline void ResultColumnMetadata::clear_sortable() {
  sortable_ = false;
  _has_bits_[0] &= ~0x00020000u;
}
inline bool ResultColumnMetadata::_internal_sortable() const {
  return sortable_;
}
inline bool ResultColumnMetadata::sortable() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.sortable)
  return _internal_sortable();
}
inline void ResultColumnMetadata::_internal_set_sortable(bool value) {
  _has_bits_[0] |= 0x00020000u;
  sortable_ = value;
}
inline void ResultColumnMetadata::set_sortable(bool value) {
  _internal_set_sortable(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.sortable)
}

// optional string class_name = 18;
inline bool ResultColumnMetadata::_internal_has_class_name() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_class_name() const {
  return _internal_has_class_name();
}
inline void ResultColumnMetadata::clear_class_name() {
  class_name_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000040u;
}
inline const std::string& ResultColumnMetadata::class_name() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.class_name)
  return _internal_class_name();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ResultColumnMetadata::set_class_name(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000040u;
 class_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.class_name)
}
inline std::string* ResultColumnMetadata::mutable_class_name() {
  // @@protoc_insertion_point(field_mutable:exec.user.ResultColumnMetadata.class_name)
  return _internal_mutable_class_name();
}
inline const std::string& ResultColumnMetadata::_internal_class_name() const {
  return class_name_.Get();
}
inline void ResultColumnMetadata::_internal_set_class_name(const std::string& value) {
  _has_bits_[0] |= 0x00000040u;
  class_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ResultColumnMetadata::_internal_mutable_class_name() {
  _has_bits_[0] |= 0x00000040u;
  return class_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ResultColumnMetadata::release_class_name() {
  // @@protoc_insertion_point(field_release:exec.user.ResultColumnMetadata.class_name)
  if (!_internal_has_class_name()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000040u;
  return class_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ResultColumnMetadata::set_allocated_class_name(std::string* class_name) {
  if (class_name != nullptr) {
    _has_bits_[0] |= 0x00000040u;
  } else {
    _has_bits_[0] &= ~0x00000040u;
  }
  class_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), class_name,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ResultColumnMetadata.class_name)
}

// optional bool is_currency = 20;
inline bool ResultColumnMetadata::_internal_has_is_currency() const {
  bool value = (_has_bits_[0] & 0x00040000u) != 0;
  return value;
}
inline bool ResultColumnMetadata::has_is_currency() const {
  return _internal_has_is_currency();
}
inline void ResultColumnMetadata::clear_is_currency() {
  is_currency_ = false;
  _has_bits_[0] &= ~0x00040000u;
}
inline bool ResultColumnMetadata::_internal_is_currency() const {
  return is_currency_;
}
inline bool ResultColumnMetadata::is_currency() const {
  // @@protoc_insertion_point(field_get:exec.user.ResultColumnMetadata.is_currency)
  return _internal_is_currency();
}
inline void ResultColumnMetadata::_internal_set_is_currency(bool value) {
  _has_bits_[0] |= 0x00040000u;
  is_currency_ = value;
}
inline void ResultColumnMetadata::set_is_currency(bool value) {
  _internal_set_is_currency(value);
  // @@protoc_insertion_point(field_set:exec.user.ResultColumnMetadata.is_currency)
}

// -------------------------------------------------------------------

// PreparedStatementHandle

// optional bytes server_info = 1;
inline bool PreparedStatementHandle::_internal_has_server_info() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool PreparedStatementHandle::has_server_info() const {
  return _internal_has_server_info();
}
inline void PreparedStatementHandle::clear_server_info() {
  server_info_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& PreparedStatementHandle::server_info() const {
  // @@protoc_insertion_point(field_get:exec.user.PreparedStatementHandle.server_info)
  return _internal_server_info();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void PreparedStatementHandle::set_server_info(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 server_info_.SetBytes(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.PreparedStatementHandle.server_info)
}
inline std::string* PreparedStatementHandle::mutable_server_info() {
  // @@protoc_insertion_point(field_mutable:exec.user.PreparedStatementHandle.server_info)
  return _internal_mutable_server_info();
}
inline const std::string& PreparedStatementHandle::_internal_server_info() const {
  return server_info_.Get();
}
inline void PreparedStatementHandle::_internal_set_server_info(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  server_info_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* PreparedStatementHandle::_internal_mutable_server_info() {
  _has_bits_[0] |= 0x00000001u;
  return server_info_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* PreparedStatementHandle::release_server_info() {
  // @@protoc_insertion_point(field_release:exec.user.PreparedStatementHandle.server_info)
  if (!_internal_has_server_info()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return server_info_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void PreparedStatementHandle::set_allocated_server_info(std::string* server_info) {
  if (server_info != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  server_info_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), server_info,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.PreparedStatementHandle.server_info)
}

// -------------------------------------------------------------------

// PreparedStatement

// repeated .exec.user.ResultColumnMetadata columns = 1;
inline int PreparedStatement::_internal_columns_size() const {
  return columns_.size();
}
inline int PreparedStatement::columns_size() const {
  return _internal_columns_size();
}
inline void PreparedStatement::clear_columns() {
  columns_.Clear();
}
inline ::exec::user::ResultColumnMetadata* PreparedStatement::mutable_columns(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.PreparedStatement.columns)
  return columns_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ResultColumnMetadata >*
PreparedStatement::mutable_columns() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.PreparedStatement.columns)
  return &columns_;
}
inline const ::exec::user::ResultColumnMetadata& PreparedStatement::_internal_columns(int index) const {
  return columns_.Get(index);
}
inline const ::exec::user::ResultColumnMetadata& PreparedStatement::columns(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.PreparedStatement.columns)
  return _internal_columns(index);
}
inline ::exec::user::ResultColumnMetadata* PreparedStatement::_internal_add_columns() {
  return columns_.Add();
}
inline ::exec::user::ResultColumnMetadata* PreparedStatement::add_columns() {
  // @@protoc_insertion_point(field_add:exec.user.PreparedStatement.columns)
  return _internal_add_columns();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ResultColumnMetadata >&
PreparedStatement::columns() const {
  // @@protoc_insertion_point(field_list:exec.user.PreparedStatement.columns)
  return columns_;
}

// optional .exec.user.PreparedStatementHandle server_handle = 2;
inline bool PreparedStatement::_internal_has_server_handle() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || server_handle_ != nullptr);
  return value;
}
inline bool PreparedStatement::has_server_handle() const {
  return _internal_has_server_handle();
}
inline void PreparedStatement::clear_server_handle() {
  if (server_handle_ != nullptr) server_handle_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::user::PreparedStatementHandle& PreparedStatement::_internal_server_handle() const {
  const ::exec::user::PreparedStatementHandle* p = server_handle_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::PreparedStatementHandle&>(
      ::exec::user::_PreparedStatementHandle_default_instance_);
}
inline const ::exec::user::PreparedStatementHandle& PreparedStatement::server_handle() const {
  // @@protoc_insertion_point(field_get:exec.user.PreparedStatement.server_handle)
  return _internal_server_handle();
}
inline void PreparedStatement::unsafe_arena_set_allocated_server_handle(
    ::exec::user::PreparedStatementHandle* server_handle) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(server_handle_);
  }
  server_handle_ = server_handle;
  if (server_handle) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.PreparedStatement.server_handle)
}
inline ::exec::user::PreparedStatementHandle* PreparedStatement::release_server_handle() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::PreparedStatementHandle* temp = server_handle_;
  server_handle_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::PreparedStatementHandle* PreparedStatement::unsafe_arena_release_server_handle() {
  // @@protoc_insertion_point(field_release:exec.user.PreparedStatement.server_handle)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::PreparedStatementHandle* temp = server_handle_;
  server_handle_ = nullptr;
  return temp;
}
inline ::exec::user::PreparedStatementHandle* PreparedStatement::_internal_mutable_server_handle() {
  _has_bits_[0] |= 0x00000001u;
  if (server_handle_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::PreparedStatementHandle>(GetArena());
    server_handle_ = p;
  }
  return server_handle_;
}
inline ::exec::user::PreparedStatementHandle* PreparedStatement::mutable_server_handle() {
  // @@protoc_insertion_point(field_mutable:exec.user.PreparedStatement.server_handle)
  return _internal_mutable_server_handle();
}
inline void PreparedStatement::set_allocated_server_handle(::exec::user::PreparedStatementHandle* server_handle) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete server_handle_;
  }
  if (server_handle) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(server_handle);
    if (message_arena != submessage_arena) {
      server_handle = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, server_handle, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  server_handle_ = server_handle;
  // @@protoc_insertion_point(field_set_allocated:exec.user.PreparedStatement.server_handle)
}

// -------------------------------------------------------------------

// CreatePreparedStatementResp

// optional .exec.user.RequestStatus status = 1;
inline bool CreatePreparedStatementResp::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool CreatePreparedStatementResp::has_status() const {
  return _internal_has_status();
}
inline void CreatePreparedStatementResp::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::user::RequestStatus CreatePreparedStatementResp::_internal_status() const {
  return static_cast< ::exec::user::RequestStatus >(status_);
}
inline ::exec::user::RequestStatus CreatePreparedStatementResp::status() const {
  // @@protoc_insertion_point(field_get:exec.user.CreatePreparedStatementResp.status)
  return _internal_status();
}
inline void CreatePreparedStatementResp::_internal_set_status(::exec::user::RequestStatus value) {
  assert(::exec::user::RequestStatus_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  status_ = value;
}
inline void CreatePreparedStatementResp::set_status(::exec::user::RequestStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.CreatePreparedStatementResp.status)
}

// optional .exec.user.PreparedStatement prepared_statement = 2;
inline bool CreatePreparedStatementResp::_internal_has_prepared_statement() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || prepared_statement_ != nullptr);
  return value;
}
inline bool CreatePreparedStatementResp::has_prepared_statement() const {
  return _internal_has_prepared_statement();
}
inline void CreatePreparedStatementResp::clear_prepared_statement() {
  if (prepared_statement_ != nullptr) prepared_statement_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::user::PreparedStatement& CreatePreparedStatementResp::_internal_prepared_statement() const {
  const ::exec::user::PreparedStatement* p = prepared_statement_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::PreparedStatement&>(
      ::exec::user::_PreparedStatement_default_instance_);
}
inline const ::exec::user::PreparedStatement& CreatePreparedStatementResp::prepared_statement() const {
  // @@protoc_insertion_point(field_get:exec.user.CreatePreparedStatementResp.prepared_statement)
  return _internal_prepared_statement();
}
inline void CreatePreparedStatementResp::unsafe_arena_set_allocated_prepared_statement(
    ::exec::user::PreparedStatement* prepared_statement) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(prepared_statement_);
  }
  prepared_statement_ = prepared_statement;
  if (prepared_statement) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.CreatePreparedStatementResp.prepared_statement)
}
inline ::exec::user::PreparedStatement* CreatePreparedStatementResp::release_prepared_statement() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::PreparedStatement* temp = prepared_statement_;
  prepared_statement_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::PreparedStatement* CreatePreparedStatementResp::unsafe_arena_release_prepared_statement() {
  // @@protoc_insertion_point(field_release:exec.user.CreatePreparedStatementResp.prepared_statement)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::PreparedStatement* temp = prepared_statement_;
  prepared_statement_ = nullptr;
  return temp;
}
inline ::exec::user::PreparedStatement* CreatePreparedStatementResp::_internal_mutable_prepared_statement() {
  _has_bits_[0] |= 0x00000001u;
  if (prepared_statement_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::PreparedStatement>(GetArena());
    prepared_statement_ = p;
  }
  return prepared_statement_;
}
inline ::exec::user::PreparedStatement* CreatePreparedStatementResp::mutable_prepared_statement() {
  // @@protoc_insertion_point(field_mutable:exec.user.CreatePreparedStatementResp.prepared_statement)
  return _internal_mutable_prepared_statement();
}
inline void CreatePreparedStatementResp::set_allocated_prepared_statement(::exec::user::PreparedStatement* prepared_statement) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete prepared_statement_;
  }
  if (prepared_statement) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(prepared_statement);
    if (message_arena != submessage_arena) {
      prepared_statement = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, prepared_statement, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  prepared_statement_ = prepared_statement;
  // @@protoc_insertion_point(field_set_allocated:exec.user.CreatePreparedStatementResp.prepared_statement)
}

// optional .exec.shared.DrillPBError error = 3;
inline bool CreatePreparedStatementResp::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool CreatePreparedStatementResp::has_error() const {
  return _internal_has_error();
}
inline const ::exec::shared::DrillPBError& CreatePreparedStatementResp::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& CreatePreparedStatementResp::error() const {
  // @@protoc_insertion_point(field_get:exec.user.CreatePreparedStatementResp.error)
  return _internal_error();
}
inline void CreatePreparedStatementResp::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.CreatePreparedStatementResp.error)
}
inline ::exec::shared::DrillPBError* CreatePreparedStatementResp::release_error() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* CreatePreparedStatementResp::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.user.CreatePreparedStatementResp.error)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* CreatePreparedStatementResp::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000002u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* CreatePreparedStatementResp::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.user.CreatePreparedStatementResp.error)
  return _internal_mutable_error();
}
inline void CreatePreparedStatementResp::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error)->GetArena();
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.user.CreatePreparedStatementResp.error)
}

// -------------------------------------------------------------------

// GetServerMetaReq

// -------------------------------------------------------------------

// ConvertSupport

// required .common.MinorType from = 1;
inline bool ConvertSupport::_internal_has_from() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool ConvertSupport::has_from() const {
  return _internal_has_from();
}
inline void ConvertSupport::clear_from() {
  from_ = 0;
  _has_bits_[0] &= ~0x00000001u;
}
inline ::common::MinorType ConvertSupport::_internal_from() const {
  return static_cast< ::common::MinorType >(from_);
}
inline ::common::MinorType ConvertSupport::from() const {
  // @@protoc_insertion_point(field_get:exec.user.ConvertSupport.from)
  return _internal_from();
}
inline void ConvertSupport::_internal_set_from(::common::MinorType value) {
  assert(::common::MinorType_IsValid(value));
  _has_bits_[0] |= 0x00000001u;
  from_ = value;
}
inline void ConvertSupport::set_from(::common::MinorType value) {
  _internal_set_from(value);
  // @@protoc_insertion_point(field_set:exec.user.ConvertSupport.from)
}

// required .common.MinorType to = 2;
inline bool ConvertSupport::_internal_has_to() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool ConvertSupport::has_to() const {
  return _internal_has_to();
}
inline void ConvertSupport::clear_to() {
  to_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::common::MinorType ConvertSupport::_internal_to() const {
  return static_cast< ::common::MinorType >(to_);
}
inline ::common::MinorType ConvertSupport::to() const {
  // @@protoc_insertion_point(field_get:exec.user.ConvertSupport.to)
  return _internal_to();
}
inline void ConvertSupport::_internal_set_to(::common::MinorType value) {
  assert(::common::MinorType_IsValid(value));
  _has_bits_[0] |= 0x00000002u;
  to_ = value;
}
inline void ConvertSupport::set_to(::common::MinorType value) {
  _internal_set_to(value);
  // @@protoc_insertion_point(field_set:exec.user.ConvertSupport.to)
}

// -------------------------------------------------------------------

// GetServerMetaResp

// optional .exec.user.RequestStatus status = 1;
inline bool GetServerMetaResp::_internal_has_status() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool GetServerMetaResp::has_status() const {
  return _internal_has_status();
}
inline void GetServerMetaResp::clear_status() {
  status_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::exec::user::RequestStatus GetServerMetaResp::_internal_status() const {
  return static_cast< ::exec::user::RequestStatus >(status_);
}
inline ::exec::user::RequestStatus GetServerMetaResp::status() const {
  // @@protoc_insertion_point(field_get:exec.user.GetServerMetaResp.status)
  return _internal_status();
}
inline void GetServerMetaResp::_internal_set_status(::exec::user::RequestStatus value) {
  assert(::exec::user::RequestStatus_IsValid(value));
  _has_bits_[0] |= 0x00000004u;
  status_ = value;
}
inline void GetServerMetaResp::set_status(::exec::user::RequestStatus value) {
  _internal_set_status(value);
  // @@protoc_insertion_point(field_set:exec.user.GetServerMetaResp.status)
}

// optional .exec.user.ServerMeta server_meta = 2;
inline bool GetServerMetaResp::_internal_has_server_meta() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  PROTOBUF_ASSUME(!value || server_meta_ != nullptr);
  return value;
}
inline bool GetServerMetaResp::has_server_meta() const {
  return _internal_has_server_meta();
}
inline void GetServerMetaResp::clear_server_meta() {
  if (server_meta_ != nullptr) server_meta_->Clear();
  _has_bits_[0] &= ~0x00000001u;
}
inline const ::exec::user::ServerMeta& GetServerMetaResp::_internal_server_meta() const {
  const ::exec::user::ServerMeta* p = server_meta_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::ServerMeta&>(
      ::exec::user::_ServerMeta_default_instance_);
}
inline const ::exec::user::ServerMeta& GetServerMetaResp::server_meta() const {
  // @@protoc_insertion_point(field_get:exec.user.GetServerMetaResp.server_meta)
  return _internal_server_meta();
}
inline void GetServerMetaResp::unsafe_arena_set_allocated_server_meta(
    ::exec::user::ServerMeta* server_meta) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(server_meta_);
  }
  server_meta_ = server_meta;
  if (server_meta) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetServerMetaResp.server_meta)
}
inline ::exec::user::ServerMeta* GetServerMetaResp::release_server_meta() {
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::ServerMeta* temp = server_meta_;
  server_meta_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::ServerMeta* GetServerMetaResp::unsafe_arena_release_server_meta() {
  // @@protoc_insertion_point(field_release:exec.user.GetServerMetaResp.server_meta)
  _has_bits_[0] &= ~0x00000001u;
  ::exec::user::ServerMeta* temp = server_meta_;
  server_meta_ = nullptr;
  return temp;
}
inline ::exec::user::ServerMeta* GetServerMetaResp::_internal_mutable_server_meta() {
  _has_bits_[0] |= 0x00000001u;
  if (server_meta_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::ServerMeta>(GetArena());
    server_meta_ = p;
  }
  return server_meta_;
}
inline ::exec::user::ServerMeta* GetServerMetaResp::mutable_server_meta() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetServerMetaResp.server_meta)
  return _internal_mutable_server_meta();
}
inline void GetServerMetaResp::set_allocated_server_meta(::exec::user::ServerMeta* server_meta) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete server_meta_;
  }
  if (server_meta) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(server_meta);
    if (message_arena != submessage_arena) {
      server_meta = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, server_meta, submessage_arena);
    }
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  server_meta_ = server_meta;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetServerMetaResp.server_meta)
}

// optional .exec.shared.DrillPBError error = 3;
inline bool GetServerMetaResp::_internal_has_error() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || error_ != nullptr);
  return value;
}
inline bool GetServerMetaResp::has_error() const {
  return _internal_has_error();
}
inline const ::exec::shared::DrillPBError& GetServerMetaResp::_internal_error() const {
  const ::exec::shared::DrillPBError* p = error_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::shared::DrillPBError&>(
      ::exec::shared::_DrillPBError_default_instance_);
}
inline const ::exec::shared::DrillPBError& GetServerMetaResp::error() const {
  // @@protoc_insertion_point(field_get:exec.user.GetServerMetaResp.error)
  return _internal_error();
}
inline void GetServerMetaResp::unsafe_arena_set_allocated_error(
    ::exec::shared::DrillPBError* error) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  error_ = error;
  if (error) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.GetServerMetaResp.error)
}
inline ::exec::shared::DrillPBError* GetServerMetaResp::release_error() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::shared::DrillPBError* GetServerMetaResp::unsafe_arena_release_error() {
  // @@protoc_insertion_point(field_release:exec.user.GetServerMetaResp.error)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::shared::DrillPBError* temp = error_;
  error_ = nullptr;
  return temp;
}
inline ::exec::shared::DrillPBError* GetServerMetaResp::_internal_mutable_error() {
  _has_bits_[0] |= 0x00000002u;
  if (error_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::shared::DrillPBError>(GetArena());
    error_ = p;
  }
  return error_;
}
inline ::exec::shared::DrillPBError* GetServerMetaResp::mutable_error() {
  // @@protoc_insertion_point(field_mutable:exec.user.GetServerMetaResp.error)
  return _internal_mutable_error();
}
inline void GetServerMetaResp::set_allocated_error(::exec::shared::DrillPBError* error) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete reinterpret_cast< ::PROTOBUF_NAMESPACE_ID::MessageLite*>(error_);
  }
  if (error) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(error)->GetArena();
    if (message_arena != submessage_arena) {
      error = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, error, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  error_ = error;
  // @@protoc_insertion_point(field_set_allocated:exec.user.GetServerMetaResp.error)
}

// -------------------------------------------------------------------

// ServerMeta

// optional bool all_tables_selectable = 1;
inline bool ServerMeta::_internal_has_all_tables_selectable() const {
  bool value = (_has_bits_[0] & 0x00000100u) != 0;
  return value;
}
inline bool ServerMeta::has_all_tables_selectable() const {
  return _internal_has_all_tables_selectable();
}
inline void ServerMeta::clear_all_tables_selectable() {
  all_tables_selectable_ = false;
  _has_bits_[0] &= ~0x00000100u;
}
inline bool ServerMeta::_internal_all_tables_selectable() const {
  return all_tables_selectable_;
}
inline bool ServerMeta::all_tables_selectable() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.all_tables_selectable)
  return _internal_all_tables_selectable();
}
inline void ServerMeta::_internal_set_all_tables_selectable(bool value) {
  _has_bits_[0] |= 0x00000100u;
  all_tables_selectable_ = value;
}
inline void ServerMeta::set_all_tables_selectable(bool value) {
  _internal_set_all_tables_selectable(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.all_tables_selectable)
}

// optional bool blob_included_in_max_row_size = 2;
inline bool ServerMeta::_internal_has_blob_included_in_max_row_size() const {
  bool value = (_has_bits_[0] & 0x00000200u) != 0;
  return value;
}
inline bool ServerMeta::has_blob_included_in_max_row_size() const {
  return _internal_has_blob_included_in_max_row_size();
}
inline void ServerMeta::clear_blob_included_in_max_row_size() {
  blob_included_in_max_row_size_ = false;
  _has_bits_[0] &= ~0x00000200u;
}
inline bool ServerMeta::_internal_blob_included_in_max_row_size() const {
  return blob_included_in_max_row_size_;
}
inline bool ServerMeta::blob_included_in_max_row_size() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.blob_included_in_max_row_size)
  return _internal_blob_included_in_max_row_size();
}
inline void ServerMeta::_internal_set_blob_included_in_max_row_size(bool value) {
  _has_bits_[0] |= 0x00000200u;
  blob_included_in_max_row_size_ = value;
}
inline void ServerMeta::set_blob_included_in_max_row_size(bool value) {
  _internal_set_blob_included_in_max_row_size(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.blob_included_in_max_row_size)
}

// optional bool catalog_at_start = 3;
inline bool ServerMeta::_internal_has_catalog_at_start() const {
  bool value = (_has_bits_[0] & 0x00000400u) != 0;
  return value;
}
inline bool ServerMeta::has_catalog_at_start() const {
  return _internal_has_catalog_at_start();
}
inline void ServerMeta::clear_catalog_at_start() {
  catalog_at_start_ = false;
  _has_bits_[0] &= ~0x00000400u;
}
inline bool ServerMeta::_internal_catalog_at_start() const {
  return catalog_at_start_;
}
inline bool ServerMeta::catalog_at_start() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.catalog_at_start)
  return _internal_catalog_at_start();
}
inline void ServerMeta::_internal_set_catalog_at_start(bool value) {
  _has_bits_[0] |= 0x00000400u;
  catalog_at_start_ = value;
}
inline void ServerMeta::set_catalog_at_start(bool value) {
  _internal_set_catalog_at_start(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.catalog_at_start)
}

// optional string catalog_separator = 4;
inline bool ServerMeta::_internal_has_catalog_separator() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool ServerMeta::has_catalog_separator() const {
  return _internal_has_catalog_separator();
}
inline void ServerMeta::clear_catalog_separator() {
  catalog_separator_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& ServerMeta::catalog_separator() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.catalog_separator)
  return _internal_catalog_separator();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_catalog_separator(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 catalog_separator_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.catalog_separator)
}
inline std::string* ServerMeta::mutable_catalog_separator() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.catalog_separator)
  return _internal_mutable_catalog_separator();
}
inline const std::string& ServerMeta::_internal_catalog_separator() const {
  return catalog_separator_.Get();
}
inline void ServerMeta::_internal_set_catalog_separator(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  catalog_separator_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_catalog_separator() {
  _has_bits_[0] |= 0x00000001u;
  return catalog_separator_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_catalog_separator() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.catalog_separator)
  if (!_internal_has_catalog_separator()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return catalog_separator_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_catalog_separator(std::string* catalog_separator) {
  if (catalog_separator != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  catalog_separator_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), catalog_separator,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.catalog_separator)
}

// optional string catalog_term = 5;
inline bool ServerMeta::_internal_has_catalog_term() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool ServerMeta::has_catalog_term() const {
  return _internal_has_catalog_term();
}
inline void ServerMeta::clear_catalog_term() {
  catalog_term_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000002u;
}
inline const std::string& ServerMeta::catalog_term() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.catalog_term)
  return _internal_catalog_term();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_catalog_term(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000002u;
 catalog_term_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.catalog_term)
}
inline std::string* ServerMeta::mutable_catalog_term() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.catalog_term)
  return _internal_mutable_catalog_term();
}
inline const std::string& ServerMeta::_internal_catalog_term() const {
  return catalog_term_.Get();
}
inline void ServerMeta::_internal_set_catalog_term(const std::string& value) {
  _has_bits_[0] |= 0x00000002u;
  catalog_term_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_catalog_term() {
  _has_bits_[0] |= 0x00000002u;
  return catalog_term_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_catalog_term() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.catalog_term)
  if (!_internal_has_catalog_term()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000002u;
  return catalog_term_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_catalog_term(std::string* catalog_term) {
  if (catalog_term != nullptr) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  catalog_term_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), catalog_term,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.catalog_term)
}

// repeated .exec.user.CollateSupport collate_support = 6;
inline int ServerMeta::_internal_collate_support_size() const {
  return collate_support_.size();
}
inline int ServerMeta::collate_support_size() const {
  return _internal_collate_support_size();
}
inline void ServerMeta::clear_collate_support() {
  collate_support_.Clear();
}
inline ::exec::user::CollateSupport ServerMeta::_internal_collate_support(int index) const {
  return static_cast< ::exec::user::CollateSupport >(collate_support_.Get(index));
}
inline ::exec::user::CollateSupport ServerMeta::collate_support(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.collate_support)
  return _internal_collate_support(index);
}
inline void ServerMeta::set_collate_support(int index, ::exec::user::CollateSupport value) {
  assert(::exec::user::CollateSupport_IsValid(value));
  collate_support_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.collate_support)
}
inline void ServerMeta::_internal_add_collate_support(::exec::user::CollateSupport value) {
  assert(::exec::user::CollateSupport_IsValid(value));
  collate_support_.Add(value);
}
inline void ServerMeta::add_collate_support(::exec::user::CollateSupport value) {
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.collate_support)
  _internal_add_collate_support(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
ServerMeta::collate_support() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.collate_support)
  return collate_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::_internal_mutable_collate_support() {
  return &collate_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::mutable_collate_support() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.collate_support)
  return _internal_mutable_collate_support();
}

// optional bool column_aliasing_supported = 7;
inline bool ServerMeta::_internal_has_column_aliasing_supported() const {
  bool value = (_has_bits_[0] & 0x00000800u) != 0;
  return value;
}
inline bool ServerMeta::has_column_aliasing_supported() const {
  return _internal_has_column_aliasing_supported();
}
inline void ServerMeta::clear_column_aliasing_supported() {
  column_aliasing_supported_ = false;
  _has_bits_[0] &= ~0x00000800u;
}
inline bool ServerMeta::_internal_column_aliasing_supported() const {
  return column_aliasing_supported_;
}
inline bool ServerMeta::column_aliasing_supported() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.column_aliasing_supported)
  return _internal_column_aliasing_supported();
}
inline void ServerMeta::_internal_set_column_aliasing_supported(bool value) {
  _has_bits_[0] |= 0x00000800u;
  column_aliasing_supported_ = value;
}
inline void ServerMeta::set_column_aliasing_supported(bool value) {
  _internal_set_column_aliasing_supported(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.column_aliasing_supported)
}

// repeated .exec.user.ConvertSupport convert_support = 8;
inline int ServerMeta::_internal_convert_support_size() const {
  return convert_support_.size();
}
inline int ServerMeta::convert_support_size() const {
  return _internal_convert_support_size();
}
inline void ServerMeta::clear_convert_support() {
  convert_support_.Clear();
}
inline ::exec::user::ConvertSupport* ServerMeta::mutable_convert_support(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.convert_support)
  return convert_support_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ConvertSupport >*
ServerMeta::mutable_convert_support() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.convert_support)
  return &convert_support_;
}
inline const ::exec::user::ConvertSupport& ServerMeta::_internal_convert_support(int index) const {
  return convert_support_.Get(index);
}
inline const ::exec::user::ConvertSupport& ServerMeta::convert_support(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.convert_support)
  return _internal_convert_support(index);
}
inline ::exec::user::ConvertSupport* ServerMeta::_internal_add_convert_support() {
  return convert_support_.Add();
}
inline ::exec::user::ConvertSupport* ServerMeta::add_convert_support() {
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.convert_support)
  return _internal_add_convert_support();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::user::ConvertSupport >&
ServerMeta::convert_support() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.convert_support)
  return convert_support_;
}

// optional .exec.user.CorrelationNamesSupport correlation_names_support = 9;
inline bool ServerMeta::_internal_has_correlation_names_support() const {
  bool value = (_has_bits_[1] & 0x00000010u) != 0;
  return value;
}
inline bool ServerMeta::has_correlation_names_support() const {
  return _internal_has_correlation_names_support();
}
inline void ServerMeta::clear_correlation_names_support() {
  correlation_names_support_ = 1;
  _has_bits_[1] &= ~0x00000010u;
}
inline ::exec::user::CorrelationNamesSupport ServerMeta::_internal_correlation_names_support() const {
  return static_cast< ::exec::user::CorrelationNamesSupport >(correlation_names_support_);
}
inline ::exec::user::CorrelationNamesSupport ServerMeta::correlation_names_support() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.correlation_names_support)
  return _internal_correlation_names_support();
}
inline void ServerMeta::_internal_set_correlation_names_support(::exec::user::CorrelationNamesSupport value) {
  assert(::exec::user::CorrelationNamesSupport_IsValid(value));
  _has_bits_[1] |= 0x00000010u;
  correlation_names_support_ = value;
}
inline void ServerMeta::set_correlation_names_support(::exec::user::CorrelationNamesSupport value) {
  _internal_set_correlation_names_support(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.correlation_names_support)
}

// repeated string date_time_functions = 10;
inline int ServerMeta::_internal_date_time_functions_size() const {
  return date_time_functions_.size();
}
inline int ServerMeta::date_time_functions_size() const {
  return _internal_date_time_functions_size();
}
inline void ServerMeta::clear_date_time_functions() {
  date_time_functions_.Clear();
}
inline std::string* ServerMeta::add_date_time_functions() {
  // @@protoc_insertion_point(field_add_mutable:exec.user.ServerMeta.date_time_functions)
  return _internal_add_date_time_functions();
}
inline const std::string& ServerMeta::_internal_date_time_functions(int index) const {
  return date_time_functions_.Get(index);
}
inline const std::string& ServerMeta::date_time_functions(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.date_time_functions)
  return _internal_date_time_functions(index);
}
inline std::string* ServerMeta::mutable_date_time_functions(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.date_time_functions)
  return date_time_functions_.Mutable(index);
}
inline void ServerMeta::set_date_time_functions(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.date_time_functions)
  date_time_functions_.Mutable(index)->assign(value);
}
inline void ServerMeta::set_date_time_functions(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.date_time_functions)
  date_time_functions_.Mutable(index)->assign(std::move(value));
}
inline void ServerMeta::set_date_time_functions(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  date_time_functions_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.user.ServerMeta.date_time_functions)
}
inline void ServerMeta::set_date_time_functions(int index, const char* value, size_t size) {
  date_time_functions_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.user.ServerMeta.date_time_functions)
}
inline std::string* ServerMeta::_internal_add_date_time_functions() {
  return date_time_functions_.Add();
}
inline void ServerMeta::add_date_time_functions(const std::string& value) {
  date_time_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.date_time_functions)
}
inline void ServerMeta::add_date_time_functions(std::string&& value) {
  date_time_functions_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.date_time_functions)
}
inline void ServerMeta::add_date_time_functions(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  date_time_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.user.ServerMeta.date_time_functions)
}
inline void ServerMeta::add_date_time_functions(const char* value, size_t size) {
  date_time_functions_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.user.ServerMeta.date_time_functions)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
ServerMeta::date_time_functions() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.date_time_functions)
  return date_time_functions_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
ServerMeta::mutable_date_time_functions() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.date_time_functions)
  return &date_time_functions_;
}

// repeated .exec.user.DateTimeLiteralsSupport date_time_literals_support = 11;
inline int ServerMeta::_internal_date_time_literals_support_size() const {
  return date_time_literals_support_.size();
}
inline int ServerMeta::date_time_literals_support_size() const {
  return _internal_date_time_literals_support_size();
}
inline void ServerMeta::clear_date_time_literals_support() {
  date_time_literals_support_.Clear();
}
inline ::exec::user::DateTimeLiteralsSupport ServerMeta::_internal_date_time_literals_support(int index) const {
  return static_cast< ::exec::user::DateTimeLiteralsSupport >(date_time_literals_support_.Get(index));
}
inline ::exec::user::DateTimeLiteralsSupport ServerMeta::date_time_literals_support(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.date_time_literals_support)
  return _internal_date_time_literals_support(index);
}
inline void ServerMeta::set_date_time_literals_support(int index, ::exec::user::DateTimeLiteralsSupport value) {
  assert(::exec::user::DateTimeLiteralsSupport_IsValid(value));
  date_time_literals_support_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.date_time_literals_support)
}
inline void ServerMeta::_internal_add_date_time_literals_support(::exec::user::DateTimeLiteralsSupport value) {
  assert(::exec::user::DateTimeLiteralsSupport_IsValid(value));
  date_time_literals_support_.Add(value);
}
inline void ServerMeta::add_date_time_literals_support(::exec::user::DateTimeLiteralsSupport value) {
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.date_time_literals_support)
  _internal_add_date_time_literals_support(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
ServerMeta::date_time_literals_support() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.date_time_literals_support)
  return date_time_literals_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::_internal_mutable_date_time_literals_support() {
  return &date_time_literals_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::mutable_date_time_literals_support() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.date_time_literals_support)
  return _internal_mutable_date_time_literals_support();
}

// optional .exec.user.GroupBySupport group_by_support = 12;
inline bool ServerMeta::_internal_has_group_by_support() const {
  bool value = (_has_bits_[1] & 0x00000020u) != 0;
  return value;
}
inline bool ServerMeta::has_group_by_support() const {
  return _internal_has_group_by_support();
}
inline void ServerMeta::clear_group_by_support() {
  group_by_support_ = 1;
  _has_bits_[1] &= ~0x00000020u;
}
inline ::exec::user::GroupBySupport ServerMeta::_internal_group_by_support() const {
  return static_cast< ::exec::user::GroupBySupport >(group_by_support_);
}
inline ::exec::user::GroupBySupport ServerMeta::group_by_support() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.group_by_support)
  return _internal_group_by_support();
}
inline void ServerMeta::_internal_set_group_by_support(::exec::user::GroupBySupport value) {
  assert(::exec::user::GroupBySupport_IsValid(value));
  _has_bits_[1] |= 0x00000020u;
  group_by_support_ = value;
}
inline void ServerMeta::set_group_by_support(::exec::user::GroupBySupport value) {
  _internal_set_group_by_support(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.group_by_support)
}

// optional .exec.user.IdentifierCasing identifier_casing = 13;
inline bool ServerMeta::_internal_has_identifier_casing() const {
  bool value = (_has_bits_[0] & 0x00001000u) != 0;
  return value;
}
inline bool ServerMeta::has_identifier_casing() const {
  return _internal_has_identifier_casing();
}
inline void ServerMeta::clear_identifier_casing() {
  identifier_casing_ = 0;
  _has_bits_[0] &= ~0x00001000u;
}
inline ::exec::user::IdentifierCasing ServerMeta::_internal_identifier_casing() const {
  return static_cast< ::exec::user::IdentifierCasing >(identifier_casing_);
}
inline ::exec::user::IdentifierCasing ServerMeta::identifier_casing() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.identifier_casing)
  return _internal_identifier_casing();
}
inline void ServerMeta::_internal_set_identifier_casing(::exec::user::IdentifierCasing value) {
  assert(::exec::user::IdentifierCasing_IsValid(value));
  _has_bits_[0] |= 0x00001000u;
  identifier_casing_ = value;
}
inline void ServerMeta::set_identifier_casing(::exec::user::IdentifierCasing value) {
  _internal_set_identifier_casing(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.identifier_casing)
}

// optional string identifier_quote_string = 14;
inline bool ServerMeta::_internal_has_identifier_quote_string() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool ServerMeta::has_identifier_quote_string() const {
  return _internal_has_identifier_quote_string();
}
inline void ServerMeta::clear_identifier_quote_string() {
  identifier_quote_string_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000004u;
}
inline const std::string& ServerMeta::identifier_quote_string() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.identifier_quote_string)
  return _internal_identifier_quote_string();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_identifier_quote_string(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000004u;
 identifier_quote_string_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.identifier_quote_string)
}
inline std::string* ServerMeta::mutable_identifier_quote_string() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.identifier_quote_string)
  return _internal_mutable_identifier_quote_string();
}
inline const std::string& ServerMeta::_internal_identifier_quote_string() const {
  return identifier_quote_string_.Get();
}
inline void ServerMeta::_internal_set_identifier_quote_string(const std::string& value) {
  _has_bits_[0] |= 0x00000004u;
  identifier_quote_string_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_identifier_quote_string() {
  _has_bits_[0] |= 0x00000004u;
  return identifier_quote_string_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_identifier_quote_string() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.identifier_quote_string)
  if (!_internal_has_identifier_quote_string()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000004u;
  return identifier_quote_string_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_identifier_quote_string(std::string* identifier_quote_string) {
  if (identifier_quote_string != nullptr) {
    _has_bits_[0] |= 0x00000004u;
  } else {
    _has_bits_[0] &= ~0x00000004u;
  }
  identifier_quote_string_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), identifier_quote_string,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.identifier_quote_string)
}

// optional bool like_escape_clause_supported = 15;
inline bool ServerMeta::_internal_has_like_escape_clause_supported() const {
  bool value = (_has_bits_[0] & 0x20000000u) != 0;
  return value;
}
inline bool ServerMeta::has_like_escape_clause_supported() const {
  return _internal_has_like_escape_clause_supported();
}
inline void ServerMeta::clear_like_escape_clause_supported() {
  like_escape_clause_supported_ = false;
  _has_bits_[0] &= ~0x20000000u;
}
inline bool ServerMeta::_internal_like_escape_clause_supported() const {
  return like_escape_clause_supported_;
}
inline bool ServerMeta::like_escape_clause_supported() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.like_escape_clause_supported)
  return _internal_like_escape_clause_supported();
}
inline void ServerMeta::_internal_set_like_escape_clause_supported(bool value) {
  _has_bits_[0] |= 0x20000000u;
  like_escape_clause_supported_ = value;
}
inline void ServerMeta::set_like_escape_clause_supported(bool value) {
  _internal_set_like_escape_clause_supported(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.like_escape_clause_supported)
}

// optional uint32 max_binary_literal_length = 16;
inline bool ServerMeta::_internal_has_max_binary_literal_length() const {
  bool value = (_has_bits_[0] & 0x00002000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_binary_literal_length() const {
  return _internal_has_max_binary_literal_length();
}
inline void ServerMeta::clear_max_binary_literal_length() {
  max_binary_literal_length_ = 0u;
  _has_bits_[0] &= ~0x00002000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_binary_literal_length() const {
  return max_binary_literal_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_binary_literal_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_binary_literal_length)
  return _internal_max_binary_literal_length();
}
inline void ServerMeta::_internal_set_max_binary_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00002000u;
  max_binary_literal_length_ = value;
}
inline void ServerMeta::set_max_binary_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_binary_literal_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_binary_literal_length)
}

// optional uint32 max_catalog_name_length = 17;
inline bool ServerMeta::_internal_has_max_catalog_name_length() const {
  bool value = (_has_bits_[0] & 0x00004000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_catalog_name_length() const {
  return _internal_has_max_catalog_name_length();
}
inline void ServerMeta::clear_max_catalog_name_length() {
  max_catalog_name_length_ = 0u;
  _has_bits_[0] &= ~0x00004000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_catalog_name_length() const {
  return max_catalog_name_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_catalog_name_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_catalog_name_length)
  return _internal_max_catalog_name_length();
}
inline void ServerMeta::_internal_set_max_catalog_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00004000u;
  max_catalog_name_length_ = value;
}
inline void ServerMeta::set_max_catalog_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_catalog_name_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_catalog_name_length)
}

// optional uint32 max_char_literal_length = 18;
inline bool ServerMeta::_internal_has_max_char_literal_length() const {
  bool value = (_has_bits_[0] & 0x00008000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_char_literal_length() const {
  return _internal_has_max_char_literal_length();
}
inline void ServerMeta::clear_max_char_literal_length() {
  max_char_literal_length_ = 0u;
  _has_bits_[0] &= ~0x00008000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_char_literal_length() const {
  return max_char_literal_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_char_literal_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_char_literal_length)
  return _internal_max_char_literal_length();
}
inline void ServerMeta::_internal_set_max_char_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00008000u;
  max_char_literal_length_ = value;
}
inline void ServerMeta::set_max_char_literal_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_char_literal_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_char_literal_length)
}

// optional uint32 max_column_name_length = 19;
inline bool ServerMeta::_internal_has_max_column_name_length() const {
  bool value = (_has_bits_[0] & 0x00010000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_column_name_length() const {
  return _internal_has_max_column_name_length();
}
inline void ServerMeta::clear_max_column_name_length() {
  max_column_name_length_ = 0u;
  _has_bits_[0] &= ~0x00010000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_column_name_length() const {
  return max_column_name_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_column_name_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_column_name_length)
  return _internal_max_column_name_length();
}
inline void ServerMeta::_internal_set_max_column_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00010000u;
  max_column_name_length_ = value;
}
inline void ServerMeta::set_max_column_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_column_name_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_column_name_length)
}

// optional uint32 max_columns_in_group_by = 20;
inline bool ServerMeta::_internal_has_max_columns_in_group_by() const {
  bool value = (_has_bits_[0] & 0x00020000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_columns_in_group_by() const {
  return _internal_has_max_columns_in_group_by();
}
inline void ServerMeta::clear_max_columns_in_group_by() {
  max_columns_in_group_by_ = 0u;
  _has_bits_[0] &= ~0x00020000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_columns_in_group_by() const {
  return max_columns_in_group_by_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_columns_in_group_by() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_columns_in_group_by)
  return _internal_max_columns_in_group_by();
}
inline void ServerMeta::_internal_set_max_columns_in_group_by(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00020000u;
  max_columns_in_group_by_ = value;
}
inline void ServerMeta::set_max_columns_in_group_by(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_columns_in_group_by(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_columns_in_group_by)
}

// optional uint32 max_columns_in_order_by = 21;
inline bool ServerMeta::_internal_has_max_columns_in_order_by() const {
  bool value = (_has_bits_[0] & 0x00040000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_columns_in_order_by() const {
  return _internal_has_max_columns_in_order_by();
}
inline void ServerMeta::clear_max_columns_in_order_by() {
  max_columns_in_order_by_ = 0u;
  _has_bits_[0] &= ~0x00040000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_columns_in_order_by() const {
  return max_columns_in_order_by_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_columns_in_order_by() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_columns_in_order_by)
  return _internal_max_columns_in_order_by();
}
inline void ServerMeta::_internal_set_max_columns_in_order_by(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00040000u;
  max_columns_in_order_by_ = value;
}
inline void ServerMeta::set_max_columns_in_order_by(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_columns_in_order_by(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_columns_in_order_by)
}

// optional uint32 max_columns_in_select = 22;
inline bool ServerMeta::_internal_has_max_columns_in_select() const {
  bool value = (_has_bits_[0] & 0x00080000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_columns_in_select() const {
  return _internal_has_max_columns_in_select();
}
inline void ServerMeta::clear_max_columns_in_select() {
  max_columns_in_select_ = 0u;
  _has_bits_[0] &= ~0x00080000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_columns_in_select() const {
  return max_columns_in_select_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_columns_in_select() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_columns_in_select)
  return _internal_max_columns_in_select();
}
inline void ServerMeta::_internal_set_max_columns_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00080000u;
  max_columns_in_select_ = value;
}
inline void ServerMeta::set_max_columns_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_columns_in_select(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_columns_in_select)
}

// optional uint32 max_cursor_name_length = 23;
inline bool ServerMeta::_internal_has_max_cursor_name_length() const {
  bool value = (_has_bits_[0] & 0x00100000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_cursor_name_length() const {
  return _internal_has_max_cursor_name_length();
}
inline void ServerMeta::clear_max_cursor_name_length() {
  max_cursor_name_length_ = 0u;
  _has_bits_[0] &= ~0x00100000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_cursor_name_length() const {
  return max_cursor_name_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_cursor_name_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_cursor_name_length)
  return _internal_max_cursor_name_length();
}
inline void ServerMeta::_internal_set_max_cursor_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00100000u;
  max_cursor_name_length_ = value;
}
inline void ServerMeta::set_max_cursor_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_cursor_name_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_cursor_name_length)
}

// optional uint32 max_logical_lob_size = 24;
inline bool ServerMeta::_internal_has_max_logical_lob_size() const {
  bool value = (_has_bits_[0] & 0x00200000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_logical_lob_size() const {
  return _internal_has_max_logical_lob_size();
}
inline void ServerMeta::clear_max_logical_lob_size() {
  max_logical_lob_size_ = 0u;
  _has_bits_[0] &= ~0x00200000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_logical_lob_size() const {
  return max_logical_lob_size_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_logical_lob_size() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_logical_lob_size)
  return _internal_max_logical_lob_size();
}
inline void ServerMeta::_internal_set_max_logical_lob_size(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00200000u;
  max_logical_lob_size_ = value;
}
inline void ServerMeta::set_max_logical_lob_size(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_logical_lob_size(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_logical_lob_size)
}

// optional uint32 max_row_size = 25;
inline bool ServerMeta::_internal_has_max_row_size() const {
  bool value = (_has_bits_[0] & 0x00400000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_row_size() const {
  return _internal_has_max_row_size();
}
inline void ServerMeta::clear_max_row_size() {
  max_row_size_ = 0u;
  _has_bits_[0] &= ~0x00400000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_row_size() const {
  return max_row_size_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_row_size() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_row_size)
  return _internal_max_row_size();
}
inline void ServerMeta::_internal_set_max_row_size(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00400000u;
  max_row_size_ = value;
}
inline void ServerMeta::set_max_row_size(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_row_size(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_row_size)
}

// optional uint32 max_schema_name_length = 26;
inline bool ServerMeta::_internal_has_max_schema_name_length() const {
  bool value = (_has_bits_[0] & 0x00800000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_schema_name_length() const {
  return _internal_has_max_schema_name_length();
}
inline void ServerMeta::clear_max_schema_name_length() {
  max_schema_name_length_ = 0u;
  _has_bits_[0] &= ~0x00800000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_schema_name_length() const {
  return max_schema_name_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_schema_name_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_schema_name_length)
  return _internal_max_schema_name_length();
}
inline void ServerMeta::_internal_set_max_schema_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x00800000u;
  max_schema_name_length_ = value;
}
inline void ServerMeta::set_max_schema_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_schema_name_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_schema_name_length)
}

// optional uint32 max_statement_length = 27;
inline bool ServerMeta::_internal_has_max_statement_length() const {
  bool value = (_has_bits_[0] & 0x01000000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_statement_length() const {
  return _internal_has_max_statement_length();
}
inline void ServerMeta::clear_max_statement_length() {
  max_statement_length_ = 0u;
  _has_bits_[0] &= ~0x01000000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_statement_length() const {
  return max_statement_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_statement_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_statement_length)
  return _internal_max_statement_length();
}
inline void ServerMeta::_internal_set_max_statement_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x01000000u;
  max_statement_length_ = value;
}
inline void ServerMeta::set_max_statement_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_statement_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_statement_length)
}

// optional uint32 max_statements = 28;
inline bool ServerMeta::_internal_has_max_statements() const {
  bool value = (_has_bits_[0] & 0x02000000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_statements() const {
  return _internal_has_max_statements();
}
inline void ServerMeta::clear_max_statements() {
  max_statements_ = 0u;
  _has_bits_[0] &= ~0x02000000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_statements() const {
  return max_statements_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_statements() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_statements)
  return _internal_max_statements();
}
inline void ServerMeta::_internal_set_max_statements(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x02000000u;
  max_statements_ = value;
}
inline void ServerMeta::set_max_statements(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_statements(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_statements)
}

// optional uint32 max_table_name_length = 29;
inline bool ServerMeta::_internal_has_max_table_name_length() const {
  bool value = (_has_bits_[0] & 0x04000000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_table_name_length() const {
  return _internal_has_max_table_name_length();
}
inline void ServerMeta::clear_max_table_name_length() {
  max_table_name_length_ = 0u;
  _has_bits_[0] &= ~0x04000000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_table_name_length() const {
  return max_table_name_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_table_name_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_table_name_length)
  return _internal_max_table_name_length();
}
inline void ServerMeta::_internal_set_max_table_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x04000000u;
  max_table_name_length_ = value;
}
inline void ServerMeta::set_max_table_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_table_name_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_table_name_length)
}

// optional uint32 max_tables_in_select = 30;
inline bool ServerMeta::_internal_has_max_tables_in_select() const {
  bool value = (_has_bits_[0] & 0x08000000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_tables_in_select() const {
  return _internal_has_max_tables_in_select();
}
inline void ServerMeta::clear_max_tables_in_select() {
  max_tables_in_select_ = 0u;
  _has_bits_[0] &= ~0x08000000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_tables_in_select() const {
  return max_tables_in_select_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_tables_in_select() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_tables_in_select)
  return _internal_max_tables_in_select();
}
inline void ServerMeta::_internal_set_max_tables_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x08000000u;
  max_tables_in_select_ = value;
}
inline void ServerMeta::set_max_tables_in_select(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_tables_in_select(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_tables_in_select)
}

// optional uint32 max_user_name_length = 31;
inline bool ServerMeta::_internal_has_max_user_name_length() const {
  bool value = (_has_bits_[0] & 0x10000000u) != 0;
  return value;
}
inline bool ServerMeta::has_max_user_name_length() const {
  return _internal_has_max_user_name_length();
}
inline void ServerMeta::clear_max_user_name_length() {
  max_user_name_length_ = 0u;
  _has_bits_[0] &= ~0x10000000u;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::_internal_max_user_name_length() const {
  return max_user_name_length_;
}
inline ::PROTOBUF_NAMESPACE_ID::uint32 ServerMeta::max_user_name_length() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.max_user_name_length)
  return _internal_max_user_name_length();
}
inline void ServerMeta::_internal_set_max_user_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _has_bits_[0] |= 0x10000000u;
  max_user_name_length_ = value;
}
inline void ServerMeta::set_max_user_name_length(::PROTOBUF_NAMESPACE_ID::uint32 value) {
  _internal_set_max_user_name_length(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.max_user_name_length)
}

// optional .exec.user.NullCollation null_collation = 32;
inline bool ServerMeta::_internal_has_null_collation() const {
  bool value = (_has_bits_[1] & 0x00000002u) != 0;
  return value;
}
inline bool ServerMeta::has_null_collation() const {
  return _internal_has_null_collation();
}
inline void ServerMeta::clear_null_collation() {
  null_collation_ = 0;
  _has_bits_[1] &= ~0x00000002u;
}
inline ::exec::user::NullCollation ServerMeta::_internal_null_collation() const {
  return static_cast< ::exec::user::NullCollation >(null_collation_);
}
inline ::exec::user::NullCollation ServerMeta::null_collation() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.null_collation)
  return _internal_null_collation();
}
inline void ServerMeta::_internal_set_null_collation(::exec::user::NullCollation value) {
  assert(::exec::user::NullCollation_IsValid(value));
  _has_bits_[1] |= 0x00000002u;
  null_collation_ = value;
}
inline void ServerMeta::set_null_collation(::exec::user::NullCollation value) {
  _internal_set_null_collation(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.null_collation)
}

// optional bool null_plus_non_null_equals_null = 33;
inline bool ServerMeta::_internal_has_null_plus_non_null_equals_null() const {
  bool value = (_has_bits_[0] & 0x40000000u) != 0;
  return value;
}
inline bool ServerMeta::has_null_plus_non_null_equals_null() const {
  return _internal_has_null_plus_non_null_equals_null();
}
inline void ServerMeta::clear_null_plus_non_null_equals_null() {
  null_plus_non_null_equals_null_ = false;
  _has_bits_[0] &= ~0x40000000u;
}
inline bool ServerMeta::_internal_null_plus_non_null_equals_null() const {
  return null_plus_non_null_equals_null_;
}
inline bool ServerMeta::null_plus_non_null_equals_null() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.null_plus_non_null_equals_null)
  return _internal_null_plus_non_null_equals_null();
}
inline void ServerMeta::_internal_set_null_plus_non_null_equals_null(bool value) {
  _has_bits_[0] |= 0x40000000u;
  null_plus_non_null_equals_null_ = value;
}
inline void ServerMeta::set_null_plus_non_null_equals_null(bool value) {
  _internal_set_null_plus_non_null_equals_null(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.null_plus_non_null_equals_null)
}

// repeated string numeric_functions = 34;
inline int ServerMeta::_internal_numeric_functions_size() const {
  return numeric_functions_.size();
}
inline int ServerMeta::numeric_functions_size() const {
  return _internal_numeric_functions_size();
}
inline void ServerMeta::clear_numeric_functions() {
  numeric_functions_.Clear();
}
inline std::string* ServerMeta::add_numeric_functions() {
  // @@protoc_insertion_point(field_add_mutable:exec.user.ServerMeta.numeric_functions)
  return _internal_add_numeric_functions();
}
inline const std::string& ServerMeta::_internal_numeric_functions(int index) const {
  return numeric_functions_.Get(index);
}
inline const std::string& ServerMeta::numeric_functions(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.numeric_functions)
  return _internal_numeric_functions(index);
}
inline std::string* ServerMeta::mutable_numeric_functions(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.numeric_functions)
  return numeric_functions_.Mutable(index);
}
inline void ServerMeta::set_numeric_functions(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.numeric_functions)
  numeric_functions_.Mutable(index)->assign(value);
}
inline void ServerMeta::set_numeric_functions(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.numeric_functions)
  numeric_functions_.Mutable(index)->assign(std::move(value));
}
inline void ServerMeta::set_numeric_functions(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  numeric_functions_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.user.ServerMeta.numeric_functions)
}
inline void ServerMeta::set_numeric_functions(int index, const char* value, size_t size) {
  numeric_functions_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.user.ServerMeta.numeric_functions)
}
inline std::string* ServerMeta::_internal_add_numeric_functions() {
  return numeric_functions_.Add();
}
inline void ServerMeta::add_numeric_functions(const std::string& value) {
  numeric_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.numeric_functions)
}
inline void ServerMeta::add_numeric_functions(std::string&& value) {
  numeric_functions_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.numeric_functions)
}
inline void ServerMeta::add_numeric_functions(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  numeric_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.user.ServerMeta.numeric_functions)
}
inline void ServerMeta::add_numeric_functions(const char* value, size_t size) {
  numeric_functions_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.user.ServerMeta.numeric_functions)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
ServerMeta::numeric_functions() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.numeric_functions)
  return numeric_functions_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
ServerMeta::mutable_numeric_functions() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.numeric_functions)
  return &numeric_functions_;
}

// repeated .exec.user.OrderBySupport order_by_support = 35;
inline int ServerMeta::_internal_order_by_support_size() const {
  return order_by_support_.size();
}
inline int ServerMeta::order_by_support_size() const {
  return _internal_order_by_support_size();
}
inline void ServerMeta::clear_order_by_support() {
  order_by_support_.Clear();
}
inline ::exec::user::OrderBySupport ServerMeta::_internal_order_by_support(int index) const {
  return static_cast< ::exec::user::OrderBySupport >(order_by_support_.Get(index));
}
inline ::exec::user::OrderBySupport ServerMeta::order_by_support(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.order_by_support)
  return _internal_order_by_support(index);
}
inline void ServerMeta::set_order_by_support(int index, ::exec::user::OrderBySupport value) {
  assert(::exec::user::OrderBySupport_IsValid(value));
  order_by_support_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.order_by_support)
}
inline void ServerMeta::_internal_add_order_by_support(::exec::user::OrderBySupport value) {
  assert(::exec::user::OrderBySupport_IsValid(value));
  order_by_support_.Add(value);
}
inline void ServerMeta::add_order_by_support(::exec::user::OrderBySupport value) {
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.order_by_support)
  _internal_add_order_by_support(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
ServerMeta::order_by_support() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.order_by_support)
  return order_by_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::_internal_mutable_order_by_support() {
  return &order_by_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::mutable_order_by_support() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.order_by_support)
  return _internal_mutable_order_by_support();
}

// repeated .exec.user.OuterJoinSupport outer_join_support = 36;
inline int ServerMeta::_internal_outer_join_support_size() const {
  return outer_join_support_.size();
}
inline int ServerMeta::outer_join_support_size() const {
  return _internal_outer_join_support_size();
}
inline void ServerMeta::clear_outer_join_support() {
  outer_join_support_.Clear();
}
inline ::exec::user::OuterJoinSupport ServerMeta::_internal_outer_join_support(int index) const {
  return static_cast< ::exec::user::OuterJoinSupport >(outer_join_support_.Get(index));
}
inline ::exec::user::OuterJoinSupport ServerMeta::outer_join_support(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.outer_join_support)
  return _internal_outer_join_support(index);
}
inline void ServerMeta::set_outer_join_support(int index, ::exec::user::OuterJoinSupport value) {
  assert(::exec::user::OuterJoinSupport_IsValid(value));
  outer_join_support_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.outer_join_support)
}
inline void ServerMeta::_internal_add_outer_join_support(::exec::user::OuterJoinSupport value) {
  assert(::exec::user::OuterJoinSupport_IsValid(value));
  outer_join_support_.Add(value);
}
inline void ServerMeta::add_outer_join_support(::exec::user::OuterJoinSupport value) {
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.outer_join_support)
  _internal_add_outer_join_support(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
ServerMeta::outer_join_support() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.outer_join_support)
  return outer_join_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::_internal_mutable_outer_join_support() {
  return &outer_join_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::mutable_outer_join_support() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.outer_join_support)
  return _internal_mutable_outer_join_support();
}

// optional .exec.user.IdentifierCasing quoted_identifier_casing = 37;
inline bool ServerMeta::_internal_has_quoted_identifier_casing() const {
  bool value = (_has_bits_[1] & 0x00000004u) != 0;
  return value;
}
inline bool ServerMeta::has_quoted_identifier_casing() const {
  return _internal_has_quoted_identifier_casing();
}
inline void ServerMeta::clear_quoted_identifier_casing() {
  quoted_identifier_casing_ = 0;
  _has_bits_[1] &= ~0x00000004u;
}
inline ::exec::user::IdentifierCasing ServerMeta::_internal_quoted_identifier_casing() const {
  return static_cast< ::exec::user::IdentifierCasing >(quoted_identifier_casing_);
}
inline ::exec::user::IdentifierCasing ServerMeta::quoted_identifier_casing() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.quoted_identifier_casing)
  return _internal_quoted_identifier_casing();
}
inline void ServerMeta::_internal_set_quoted_identifier_casing(::exec::user::IdentifierCasing value) {
  assert(::exec::user::IdentifierCasing_IsValid(value));
  _has_bits_[1] |= 0x00000004u;
  quoted_identifier_casing_ = value;
}
inline void ServerMeta::set_quoted_identifier_casing(::exec::user::IdentifierCasing value) {
  _internal_set_quoted_identifier_casing(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.quoted_identifier_casing)
}

// optional bool read_only = 38;
inline bool ServerMeta::_internal_has_read_only() const {
  bool value = (_has_bits_[0] & 0x80000000u) != 0;
  return value;
}
inline bool ServerMeta::has_read_only() const {
  return _internal_has_read_only();
}
inline void ServerMeta::clear_read_only() {
  read_only_ = false;
  _has_bits_[0] &= ~0x80000000u;
}
inline bool ServerMeta::_internal_read_only() const {
  return read_only_;
}
inline bool ServerMeta::read_only() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.read_only)
  return _internal_read_only();
}
inline void ServerMeta::_internal_set_read_only(bool value) {
  _has_bits_[0] |= 0x80000000u;
  read_only_ = value;
}
inline void ServerMeta::set_read_only(bool value) {
  _internal_set_read_only(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.read_only)
}

// optional string schema_term = 39;
inline bool ServerMeta::_internal_has_schema_term() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool ServerMeta::has_schema_term() const {
  return _internal_has_schema_term();
}
inline void ServerMeta::clear_schema_term() {
  schema_term_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000008u;
}
inline const std::string& ServerMeta::schema_term() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.schema_term)
  return _internal_schema_term();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_schema_term(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000008u;
 schema_term_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.schema_term)
}
inline std::string* ServerMeta::mutable_schema_term() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.schema_term)
  return _internal_mutable_schema_term();
}
inline const std::string& ServerMeta::_internal_schema_term() const {
  return schema_term_.Get();
}
inline void ServerMeta::_internal_set_schema_term(const std::string& value) {
  _has_bits_[0] |= 0x00000008u;
  schema_term_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_schema_term() {
  _has_bits_[0] |= 0x00000008u;
  return schema_term_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_schema_term() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.schema_term)
  if (!_internal_has_schema_term()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000008u;
  return schema_term_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_schema_term(std::string* schema_term) {
  if (schema_term != nullptr) {
    _has_bits_[0] |= 0x00000008u;
  } else {
    _has_bits_[0] &= ~0x00000008u;
  }
  schema_term_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), schema_term,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.schema_term)
}

// optional string search_escape_string = 40;
inline bool ServerMeta::_internal_has_search_escape_string() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool ServerMeta::has_search_escape_string() const {
  return _internal_has_search_escape_string();
}
inline void ServerMeta::clear_search_escape_string() {
  search_escape_string_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000010u;
}
inline const std::string& ServerMeta::search_escape_string() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.search_escape_string)
  return _internal_search_escape_string();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_search_escape_string(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000010u;
 search_escape_string_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.search_escape_string)
}
inline std::string* ServerMeta::mutable_search_escape_string() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.search_escape_string)
  return _internal_mutable_search_escape_string();
}
inline const std::string& ServerMeta::_internal_search_escape_string() const {
  return search_escape_string_.Get();
}
inline void ServerMeta::_internal_set_search_escape_string(const std::string& value) {
  _has_bits_[0] |= 0x00000010u;
  search_escape_string_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_search_escape_string() {
  _has_bits_[0] |= 0x00000010u;
  return search_escape_string_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_search_escape_string() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.search_escape_string)
  if (!_internal_has_search_escape_string()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000010u;
  return search_escape_string_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_search_escape_string(std::string* search_escape_string) {
  if (search_escape_string != nullptr) {
    _has_bits_[0] |= 0x00000010u;
  } else {
    _has_bits_[0] &= ~0x00000010u;
  }
  search_escape_string_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), search_escape_string,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.search_escape_string)
}

// optional bool select_for_update_supported = 41;
inline bool ServerMeta::_internal_has_select_for_update_supported() const {
  bool value = (_has_bits_[1] & 0x00000001u) != 0;
  return value;
}
inline bool ServerMeta::has_select_for_update_supported() const {
  return _internal_has_select_for_update_supported();
}
inline void ServerMeta::clear_select_for_update_supported() {
  select_for_update_supported_ = false;
  _has_bits_[1] &= ~0x00000001u;
}
inline bool ServerMeta::_internal_select_for_update_supported() const {
  return select_for_update_supported_;
}
inline bool ServerMeta::select_for_update_supported() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.select_for_update_supported)
  return _internal_select_for_update_supported();
}
inline void ServerMeta::_internal_set_select_for_update_supported(bool value) {
  _has_bits_[1] |= 0x00000001u;
  select_for_update_supported_ = value;
}
inline void ServerMeta::set_select_for_update_supported(bool value) {
  _internal_set_select_for_update_supported(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.select_for_update_supported)
}

// optional string special_characters = 42;
inline bool ServerMeta::_internal_has_special_characters() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool ServerMeta::has_special_characters() const {
  return _internal_has_special_characters();
}
inline void ServerMeta::clear_special_characters() {
  special_characters_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000020u;
}
inline const std::string& ServerMeta::special_characters() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.special_characters)
  return _internal_special_characters();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_special_characters(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000020u;
 special_characters_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.special_characters)
}
inline std::string* ServerMeta::mutable_special_characters() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.special_characters)
  return _internal_mutable_special_characters();
}
inline const std::string& ServerMeta::_internal_special_characters() const {
  return special_characters_.Get();
}
inline void ServerMeta::_internal_set_special_characters(const std::string& value) {
  _has_bits_[0] |= 0x00000020u;
  special_characters_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_special_characters() {
  _has_bits_[0] |= 0x00000020u;
  return special_characters_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_special_characters() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.special_characters)
  if (!_internal_has_special_characters()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000020u;
  return special_characters_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_special_characters(std::string* special_characters) {
  if (special_characters != nullptr) {
    _has_bits_[0] |= 0x00000020u;
  } else {
    _has_bits_[0] &= ~0x00000020u;
  }
  special_characters_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), special_characters,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.special_characters)
}

// repeated string sql_keywords = 43;
inline int ServerMeta::_internal_sql_keywords_size() const {
  return sql_keywords_.size();
}
inline int ServerMeta::sql_keywords_size() const {
  return _internal_sql_keywords_size();
}
inline void ServerMeta::clear_sql_keywords() {
  sql_keywords_.Clear();
}
inline std::string* ServerMeta::add_sql_keywords() {
  // @@protoc_insertion_point(field_add_mutable:exec.user.ServerMeta.sql_keywords)
  return _internal_add_sql_keywords();
}
inline const std::string& ServerMeta::_internal_sql_keywords(int index) const {
  return sql_keywords_.Get(index);
}
inline const std::string& ServerMeta::sql_keywords(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.sql_keywords)
  return _internal_sql_keywords(index);
}
inline std::string* ServerMeta::mutable_sql_keywords(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.sql_keywords)
  return sql_keywords_.Mutable(index);
}
inline void ServerMeta::set_sql_keywords(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.sql_keywords)
  sql_keywords_.Mutable(index)->assign(value);
}
inline void ServerMeta::set_sql_keywords(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.sql_keywords)
  sql_keywords_.Mutable(index)->assign(std::move(value));
}
inline void ServerMeta::set_sql_keywords(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  sql_keywords_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.user.ServerMeta.sql_keywords)
}
inline void ServerMeta::set_sql_keywords(int index, const char* value, size_t size) {
  sql_keywords_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.user.ServerMeta.sql_keywords)
}
inline std::string* ServerMeta::_internal_add_sql_keywords() {
  return sql_keywords_.Add();
}
inline void ServerMeta::add_sql_keywords(const std::string& value) {
  sql_keywords_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.sql_keywords)
}
inline void ServerMeta::add_sql_keywords(std::string&& value) {
  sql_keywords_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.sql_keywords)
}
inline void ServerMeta::add_sql_keywords(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  sql_keywords_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.user.ServerMeta.sql_keywords)
}
inline void ServerMeta::add_sql_keywords(const char* value, size_t size) {
  sql_keywords_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.user.ServerMeta.sql_keywords)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
ServerMeta::sql_keywords() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.sql_keywords)
  return sql_keywords_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
ServerMeta::mutable_sql_keywords() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.sql_keywords)
  return &sql_keywords_;
}

// repeated string string_functions = 44;
inline int ServerMeta::_internal_string_functions_size() const {
  return string_functions_.size();
}
inline int ServerMeta::string_functions_size() const {
  return _internal_string_functions_size();
}
inline void ServerMeta::clear_string_functions() {
  string_functions_.Clear();
}
inline std::string* ServerMeta::add_string_functions() {
  // @@protoc_insertion_point(field_add_mutable:exec.user.ServerMeta.string_functions)
  return _internal_add_string_functions();
}
inline const std::string& ServerMeta::_internal_string_functions(int index) const {
  return string_functions_.Get(index);
}
inline const std::string& ServerMeta::string_functions(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.string_functions)
  return _internal_string_functions(index);
}
inline std::string* ServerMeta::mutable_string_functions(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.string_functions)
  return string_functions_.Mutable(index);
}
inline void ServerMeta::set_string_functions(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.string_functions)
  string_functions_.Mutable(index)->assign(value);
}
inline void ServerMeta::set_string_functions(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.string_functions)
  string_functions_.Mutable(index)->assign(std::move(value));
}
inline void ServerMeta::set_string_functions(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  string_functions_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.user.ServerMeta.string_functions)
}
inline void ServerMeta::set_string_functions(int index, const char* value, size_t size) {
  string_functions_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.user.ServerMeta.string_functions)
}
inline std::string* ServerMeta::_internal_add_string_functions() {
  return string_functions_.Add();
}
inline void ServerMeta::add_string_functions(const std::string& value) {
  string_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.string_functions)
}
inline void ServerMeta::add_string_functions(std::string&& value) {
  string_functions_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.string_functions)
}
inline void ServerMeta::add_string_functions(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  string_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.user.ServerMeta.string_functions)
}
inline void ServerMeta::add_string_functions(const char* value, size_t size) {
  string_functions_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.user.ServerMeta.string_functions)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
ServerMeta::string_functions() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.string_functions)
  return string_functions_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
ServerMeta::mutable_string_functions() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.string_functions)
  return &string_functions_;
}

// repeated .exec.user.SubQuerySupport subquery_support = 45;
inline int ServerMeta::_internal_subquery_support_size() const {
  return subquery_support_.size();
}
inline int ServerMeta::subquery_support_size() const {
  return _internal_subquery_support_size();
}
inline void ServerMeta::clear_subquery_support() {
  subquery_support_.Clear();
}
inline ::exec::user::SubQuerySupport ServerMeta::_internal_subquery_support(int index) const {
  return static_cast< ::exec::user::SubQuerySupport >(subquery_support_.Get(index));
}
inline ::exec::user::SubQuerySupport ServerMeta::subquery_support(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.subquery_support)
  return _internal_subquery_support(index);
}
inline void ServerMeta::set_subquery_support(int index, ::exec::user::SubQuerySupport value) {
  assert(::exec::user::SubQuerySupport_IsValid(value));
  subquery_support_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.subquery_support)
}
inline void ServerMeta::_internal_add_subquery_support(::exec::user::SubQuerySupport value) {
  assert(::exec::user::SubQuerySupport_IsValid(value));
  subquery_support_.Add(value);
}
inline void ServerMeta::add_subquery_support(::exec::user::SubQuerySupport value) {
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.subquery_support)
  _internal_add_subquery_support(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
ServerMeta::subquery_support() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.subquery_support)
  return subquery_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::_internal_mutable_subquery_support() {
  return &subquery_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::mutable_subquery_support() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.subquery_support)
  return _internal_mutable_subquery_support();
}

// repeated string system_functions = 46;
inline int ServerMeta::_internal_system_functions_size() const {
  return system_functions_.size();
}
inline int ServerMeta::system_functions_size() const {
  return _internal_system_functions_size();
}
inline void ServerMeta::clear_system_functions() {
  system_functions_.Clear();
}
inline std::string* ServerMeta::add_system_functions() {
  // @@protoc_insertion_point(field_add_mutable:exec.user.ServerMeta.system_functions)
  return _internal_add_system_functions();
}
inline const std::string& ServerMeta::_internal_system_functions(int index) const {
  return system_functions_.Get(index);
}
inline const std::string& ServerMeta::system_functions(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.system_functions)
  return _internal_system_functions(index);
}
inline std::string* ServerMeta::mutable_system_functions(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.system_functions)
  return system_functions_.Mutable(index);
}
inline void ServerMeta::set_system_functions(int index, const std::string& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.system_functions)
  system_functions_.Mutable(index)->assign(value);
}
inline void ServerMeta::set_system_functions(int index, std::string&& value) {
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.system_functions)
  system_functions_.Mutable(index)->assign(std::move(value));
}
inline void ServerMeta::set_system_functions(int index, const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  system_functions_.Mutable(index)->assign(value);
  // @@protoc_insertion_point(field_set_char:exec.user.ServerMeta.system_functions)
}
inline void ServerMeta::set_system_functions(int index, const char* value, size_t size) {
  system_functions_.Mutable(index)->assign(
    reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_set_pointer:exec.user.ServerMeta.system_functions)
}
inline std::string* ServerMeta::_internal_add_system_functions() {
  return system_functions_.Add();
}
inline void ServerMeta::add_system_functions(const std::string& value) {
  system_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.system_functions)
}
inline void ServerMeta::add_system_functions(std::string&& value) {
  system_functions_.Add(std::move(value));
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.system_functions)
}
inline void ServerMeta::add_system_functions(const char* value) {
  GOOGLE_DCHECK(value != nullptr);
  system_functions_.Add()->assign(value);
  // @@protoc_insertion_point(field_add_char:exec.user.ServerMeta.system_functions)
}
inline void ServerMeta::add_system_functions(const char* value, size_t size) {
  system_functions_.Add()->assign(reinterpret_cast<const char*>(value), size);
  // @@protoc_insertion_point(field_add_pointer:exec.user.ServerMeta.system_functions)
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>&
ServerMeta::system_functions() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.system_functions)
  return system_functions_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField<std::string>*
ServerMeta::mutable_system_functions() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.system_functions)
  return &system_functions_;
}

// optional string table_term = 47;
inline bool ServerMeta::_internal_has_table_term() const {
  bool value = (_has_bits_[0] & 0x00000040u) != 0;
  return value;
}
inline bool ServerMeta::has_table_term() const {
  return _internal_has_table_term();
}
inline void ServerMeta::clear_table_term() {
  table_term_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000040u;
}
inline const std::string& ServerMeta::table_term() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.table_term)
  return _internal_table_term();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_table_term(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000040u;
 table_term_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.table_term)
}
inline std::string* ServerMeta::mutable_table_term() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.table_term)
  return _internal_mutable_table_term();
}
inline const std::string& ServerMeta::_internal_table_term() const {
  return table_term_.Get();
}
inline void ServerMeta::_internal_set_table_term(const std::string& value) {
  _has_bits_[0] |= 0x00000040u;
  table_term_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_table_term() {
  _has_bits_[0] |= 0x00000040u;
  return table_term_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_table_term() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.table_term)
  if (!_internal_has_table_term()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000040u;
  return table_term_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_table_term(std::string* table_term) {
  if (table_term != nullptr) {
    _has_bits_[0] |= 0x00000040u;
  } else {
    _has_bits_[0] &= ~0x00000040u;
  }
  table_term_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), table_term,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.table_term)
}

// optional bool transaction_supported = 48;
inline bool ServerMeta::_internal_has_transaction_supported() const {
  bool value = (_has_bits_[1] & 0x00000008u) != 0;
  return value;
}
inline bool ServerMeta::has_transaction_supported() const {
  return _internal_has_transaction_supported();
}
inline void ServerMeta::clear_transaction_supported() {
  transaction_supported_ = false;
  _has_bits_[1] &= ~0x00000008u;
}
inline bool ServerMeta::_internal_transaction_supported() const {
  return transaction_supported_;
}
inline bool ServerMeta::transaction_supported() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.transaction_supported)
  return _internal_transaction_supported();
}
inline void ServerMeta::_internal_set_transaction_supported(bool value) {
  _has_bits_[1] |= 0x00000008u;
  transaction_supported_ = value;
}
inline void ServerMeta::set_transaction_supported(bool value) {
  _internal_set_transaction_supported(value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.transaction_supported)
}

// repeated .exec.user.UnionSupport union_support = 49;
inline int ServerMeta::_internal_union_support_size() const {
  return union_support_.size();
}
inline int ServerMeta::union_support_size() const {
  return _internal_union_support_size();
}
inline void ServerMeta::clear_union_support() {
  union_support_.Clear();
}
inline ::exec::user::UnionSupport ServerMeta::_internal_union_support(int index) const {
  return static_cast< ::exec::user::UnionSupport >(union_support_.Get(index));
}
inline ::exec::user::UnionSupport ServerMeta::union_support(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.union_support)
  return _internal_union_support(index);
}
inline void ServerMeta::set_union_support(int index, ::exec::user::UnionSupport value) {
  assert(::exec::user::UnionSupport_IsValid(value));
  union_support_.Set(index, value);
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.union_support)
}
inline void ServerMeta::_internal_add_union_support(::exec::user::UnionSupport value) {
  assert(::exec::user::UnionSupport_IsValid(value));
  union_support_.Add(value);
}
inline void ServerMeta::add_union_support(::exec::user::UnionSupport value) {
  // @@protoc_insertion_point(field_add:exec.user.ServerMeta.union_support)
  _internal_add_union_support(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
ServerMeta::union_support() const {
  // @@protoc_insertion_point(field_list:exec.user.ServerMeta.union_support)
  return union_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::_internal_mutable_union_support() {
  return &union_support_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
ServerMeta::mutable_union_support() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.ServerMeta.union_support)
  return _internal_mutable_union_support();
}

// optional string current_schema = 50;
inline bool ServerMeta::_internal_has_current_schema() const {
  bool value = (_has_bits_[0] & 0x00000080u) != 0;
  return value;
}
inline bool ServerMeta::has_current_schema() const {
  return _internal_has_current_schema();
}
inline void ServerMeta::clear_current_schema() {
  current_schema_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000080u;
}
inline const std::string& ServerMeta::current_schema() const {
  // @@protoc_insertion_point(field_get:exec.user.ServerMeta.current_schema)
  return _internal_current_schema();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void ServerMeta::set_current_schema(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000080u;
 current_schema_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.ServerMeta.current_schema)
}
inline std::string* ServerMeta::mutable_current_schema() {
  // @@protoc_insertion_point(field_mutable:exec.user.ServerMeta.current_schema)
  return _internal_mutable_current_schema();
}
inline const std::string& ServerMeta::_internal_current_schema() const {
  return current_schema_.Get();
}
inline void ServerMeta::_internal_set_current_schema(const std::string& value) {
  _has_bits_[0] |= 0x00000080u;
  current_schema_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* ServerMeta::_internal_mutable_current_schema() {
  _has_bits_[0] |= 0x00000080u;
  return current_schema_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* ServerMeta::release_current_schema() {
  // @@protoc_insertion_point(field_release:exec.user.ServerMeta.current_schema)
  if (!_internal_has_current_schema()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000080u;
  return current_schema_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void ServerMeta::set_allocated_current_schema(std::string* current_schema) {
  if (current_schema != nullptr) {
    _has_bits_[0] |= 0x00000080u;
  } else {
    _has_bits_[0] &= ~0x00000080u;
  }
  current_schema_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), current_schema,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.ServerMeta.current_schema)
}

// -------------------------------------------------------------------

// RunQuery

// optional .exec.user.QueryResultsMode results_mode = 1;
inline bool RunQuery::_internal_has_results_mode() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool RunQuery::has_results_mode() const {
  return _internal_has_results_mode();
}
inline void RunQuery::clear_results_mode() {
  results_mode_ = 1;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::exec::user::QueryResultsMode RunQuery::_internal_results_mode() const {
  return static_cast< ::exec::user::QueryResultsMode >(results_mode_);
}
inline ::exec::user::QueryResultsMode RunQuery::results_mode() const {
  // @@protoc_insertion_point(field_get:exec.user.RunQuery.results_mode)
  return _internal_results_mode();
}
inline void RunQuery::_internal_set_results_mode(::exec::user::QueryResultsMode value) {
  assert(::exec::user::QueryResultsMode_IsValid(value));
  _has_bits_[0] |= 0x00000008u;
  results_mode_ = value;
}
inline void RunQuery::set_results_mode(::exec::user::QueryResultsMode value) {
  _internal_set_results_mode(value);
  // @@protoc_insertion_point(field_set:exec.user.RunQuery.results_mode)
}

// optional .exec.shared.QueryType type = 2;
inline bool RunQuery::_internal_has_type() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool RunQuery::has_type() const {
  return _internal_has_type();
}
inline void RunQuery::clear_type() {
  type_ = 1;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::exec::shared::QueryType RunQuery::_internal_type() const {
  return static_cast< ::exec::shared::QueryType >(type_);
}
inline ::exec::shared::QueryType RunQuery::type() const {
  // @@protoc_insertion_point(field_get:exec.user.RunQuery.type)
  return _internal_type();
}
inline void RunQuery::_internal_set_type(::exec::shared::QueryType value) {
  assert(::exec::shared::QueryType_IsValid(value));
  _has_bits_[0] |= 0x00000010u;
  type_ = value;
}
inline void RunQuery::set_type(::exec::shared::QueryType value) {
  _internal_set_type(value);
  // @@protoc_insertion_point(field_set:exec.user.RunQuery.type)
}

// optional string plan = 3;
inline bool RunQuery::_internal_has_plan() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool RunQuery::has_plan() const {
  return _internal_has_plan();
}
inline void RunQuery::clear_plan() {
  plan_.ClearToEmpty();
  _has_bits_[0] &= ~0x00000001u;
}
inline const std::string& RunQuery::plan() const {
  // @@protoc_insertion_point(field_get:exec.user.RunQuery.plan)
  return _internal_plan();
}
template <typename ArgT0, typename... ArgT>
PROTOBUF_ALWAYS_INLINE
inline void RunQuery::set_plan(ArgT0&& arg0, ArgT... args) {
 _has_bits_[0] |= 0x00000001u;
 plan_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArena());
  // @@protoc_insertion_point(field_set:exec.user.RunQuery.plan)
}
inline std::string* RunQuery::mutable_plan() {
  // @@protoc_insertion_point(field_mutable:exec.user.RunQuery.plan)
  return _internal_mutable_plan();
}
inline const std::string& RunQuery::_internal_plan() const {
  return plan_.Get();
}
inline void RunQuery::_internal_set_plan(const std::string& value) {
  _has_bits_[0] |= 0x00000001u;
  plan_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena());
}
inline std::string* RunQuery::_internal_mutable_plan() {
  _has_bits_[0] |= 0x00000001u;
  return plan_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena());
}
inline std::string* RunQuery::release_plan() {
  // @@protoc_insertion_point(field_release:exec.user.RunQuery.plan)
  if (!_internal_has_plan()) {
    return nullptr;
  }
  _has_bits_[0] &= ~0x00000001u;
  return plan_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena());
}
inline void RunQuery::set_allocated_plan(std::string* plan) {
  if (plan != nullptr) {
    _has_bits_[0] |= 0x00000001u;
  } else {
    _has_bits_[0] &= ~0x00000001u;
  }
  plan_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), plan,
      GetArena());
  // @@protoc_insertion_point(field_set_allocated:exec.user.RunQuery.plan)
}

// repeated .exec.bit.control.PlanFragment fragments = 4;
inline int RunQuery::_internal_fragments_size() const {
  return fragments_.size();
}
inline int RunQuery::fragments_size() const {
  return _internal_fragments_size();
}
inline ::exec::bit::control::PlanFragment* RunQuery::mutable_fragments(int index) {
  // @@protoc_insertion_point(field_mutable:exec.user.RunQuery.fragments)
  return fragments_.Mutable(index);
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >*
RunQuery::mutable_fragments() {
  // @@protoc_insertion_point(field_mutable_list:exec.user.RunQuery.fragments)
  return &fragments_;
}
inline const ::exec::bit::control::PlanFragment& RunQuery::_internal_fragments(int index) const {
  return fragments_.Get(index);
}
inline const ::exec::bit::control::PlanFragment& RunQuery::fragments(int index) const {
  // @@protoc_insertion_point(field_get:exec.user.RunQuery.fragments)
  return _internal_fragments(index);
}
inline ::exec::bit::control::PlanFragment* RunQuery::_internal_add_fragments() {
  return fragments_.Add();
}
inline ::exec::bit::control::PlanFragment* RunQuery::add_fragments() {
  // @@protoc_insertion_point(field_add:exec.user.RunQuery.fragments)
  return _internal_add_fragments();
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedPtrField< ::exec::bit::control::PlanFragment >&
RunQuery::fragments() const {
  // @@protoc_insertion_point(field_list:exec.user.RunQuery.fragments)
  return fragments_;
}

// optional .exec.user.PreparedStatementHandle prepared_statement_handle = 5;
inline bool RunQuery::_internal_has_prepared_statement_handle() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  PROTOBUF_ASSUME(!value || prepared_statement_handle_ != nullptr);
  return value;
}
inline bool RunQuery::has_prepared_statement_handle() const {
  return _internal_has_prepared_statement_handle();
}
inline void RunQuery::clear_prepared_statement_handle() {
  if (prepared_statement_handle_ != nullptr) prepared_statement_handle_->Clear();
  _has_bits_[0] &= ~0x00000002u;
}
inline const ::exec::user::PreparedStatementHandle& RunQuery::_internal_prepared_statement_handle() const {
  const ::exec::user::PreparedStatementHandle* p = prepared_statement_handle_;
  return p != nullptr ? *p : reinterpret_cast<const ::exec::user::PreparedStatementHandle&>(
      ::exec::user::_PreparedStatementHandle_default_instance_);
}
inline const ::exec::user::PreparedStatementHandle& RunQuery::prepared_statement_handle() const {
  // @@protoc_insertion_point(field_get:exec.user.RunQuery.prepared_statement_handle)
  return _internal_prepared_statement_handle();
}
inline void RunQuery::unsafe_arena_set_allocated_prepared_statement_handle(
    ::exec::user::PreparedStatementHandle* prepared_statement_handle) {
  if (GetArena() == nullptr) {
    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(prepared_statement_handle_);
  }
  prepared_statement_handle_ = prepared_statement_handle;
  if (prepared_statement_handle) {
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:exec.user.RunQuery.prepared_statement_handle)
}
inline ::exec::user::PreparedStatementHandle* RunQuery::release_prepared_statement_handle() {
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::PreparedStatementHandle* temp = prepared_statement_handle_;
  prepared_statement_handle_ = nullptr;
  if (GetArena() != nullptr) {
    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
  }
  return temp;
}
inline ::exec::user::PreparedStatementHandle* RunQuery::unsafe_arena_release_prepared_statement_handle() {
  // @@protoc_insertion_point(field_release:exec.user.RunQuery.prepared_statement_handle)
  _has_bits_[0] &= ~0x00000002u;
  ::exec::user::PreparedStatementHandle* temp = prepared_statement_handle_;
  prepared_statement_handle_ = nullptr;
  return temp;
}
inline ::exec::user::PreparedStatementHandle* RunQuery::_internal_mutable_prepared_statement_handle() {
  _has_bits_[0] |= 0x00000002u;
  if (prepared_statement_handle_ == nullptr) {
    auto* p = CreateMaybeMessage<::exec::user::PreparedStatementHandle>(GetArena());
    prepared_statement_handle_ = p;
  }
  return prepared_statement_handle_;
}
inline ::exec::user::PreparedStatementHandle* RunQuery::mutable_prepared_statement_handle() {
  // @@protoc_insertion_point(field_mutable:exec.user.RunQuery.prepared_statement_handle)
  return _internal_mutable_prepared_statement_handle();
}
inline void RunQuery::set_allocated_prepared_statement_handle(::exec::user::PreparedStatementHandle* prepared_statement_handle) {
  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArena();
  if (message_arena == nullptr) {
    delete prepared_statement_handle_;
  }
  if (prepared_statement_handle) {
    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
      ::PROTOBUF_NAMESPACE_ID::Arena::GetArena(prepared_statement_handle);
    if (message_arena != submessage_arena) {
      prepared_statement_handle = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
          message_arena, prepared_statement_handle, submessage_arena);
    }
    _has_bits_[0] |= 0x00000002u;
  } else {
    _has_bits_[0] &= ~0x00000002u;
  }
  prepared_statement_handle_ = prepared_statement_handle;
  // @@protoc_insertion_point(field_set_allocated:exec.user.RunQuery.prepared_statement_handle)
}

// optional int32 autolimit_rowcount = 6;
inline bool RunQuery::_internal_has_autolimit_rowcount() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool RunQuery::has_autolimit_rowcount() const {
  return _internal_has_autolimit_rowcount();
}
inline void RunQuery::clear_autolimit_rowcount() {
  autolimit_rowcount_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RunQuery::_internal_autolimit_rowcount() const {
  return autolimit_rowcount_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 RunQuery::autolimit_rowcount() const {
  // @@protoc_insertion_point(field_get:exec.user.RunQuery.autolimit_rowcount)
  return _internal_autolimit_rowcount();
}
inline void RunQuery::_internal_set_autolimit_rowcount(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  autolimit_rowcount_ = value;
}
inline void RunQuery::set_autolimit_rowcount(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_autolimit_rowcount(value);
  // @@protoc_insertion_point(field_set:exec.user.RunQuery.autolimit_rowcount)
}

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__
// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------

// -------------------------------------------------------------------


// @@protoc_insertion_point(namespace_scope)

}  // namespace user
}  // namespace exec

PROTOBUF_NAMESPACE_OPEN

template <> struct is_proto_enum< ::exec::user::RpcType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::RpcType>() {
  return ::exec::user::RpcType_descriptor();
}
template <> struct is_proto_enum< ::exec::user::SaslSupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::SaslSupport>() {
  return ::exec::user::SaslSupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::QueryResultsMode> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::QueryResultsMode>() {
  return ::exec::user::QueryResultsMode_descriptor();
}
template <> struct is_proto_enum< ::exec::user::HandshakeStatus> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::HandshakeStatus>() {
  return ::exec::user::HandshakeStatus_descriptor();
}
template <> struct is_proto_enum< ::exec::user::RequestStatus> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::RequestStatus>() {
  return ::exec::user::RequestStatus_descriptor();
}
template <> struct is_proto_enum< ::exec::user::ColumnSearchability> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::ColumnSearchability>() {
  return ::exec::user::ColumnSearchability_descriptor();
}
template <> struct is_proto_enum< ::exec::user::ColumnUpdatability> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::ColumnUpdatability>() {
  return ::exec::user::ColumnUpdatability_descriptor();
}
template <> struct is_proto_enum< ::exec::user::CollateSupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::CollateSupport>() {
  return ::exec::user::CollateSupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::CorrelationNamesSupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::CorrelationNamesSupport>() {
  return ::exec::user::CorrelationNamesSupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::DateTimeLiteralsSupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::DateTimeLiteralsSupport>() {
  return ::exec::user::DateTimeLiteralsSupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::GroupBySupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::GroupBySupport>() {
  return ::exec::user::GroupBySupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::IdentifierCasing> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::IdentifierCasing>() {
  return ::exec::user::IdentifierCasing_descriptor();
}
template <> struct is_proto_enum< ::exec::user::NullCollation> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::NullCollation>() {
  return ::exec::user::NullCollation_descriptor();
}
template <> struct is_proto_enum< ::exec::user::OrderBySupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::OrderBySupport>() {
  return ::exec::user::OrderBySupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::OuterJoinSupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::OuterJoinSupport>() {
  return ::exec::user::OuterJoinSupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::SubQuerySupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::SubQuerySupport>() {
  return ::exec::user::SubQuerySupport_descriptor();
}
template <> struct is_proto_enum< ::exec::user::UnionSupport> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::exec::user::UnionSupport>() {
  return ::exec::user::UnionSupport_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_User_2eproto
