From 64d90370e74010b74599e5801446cb93d1467579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Thu, 18 Apr 2024 07:41:02 +0200 Subject: [PATCH] Prepare schema tracking for all UDFs (#15732) --- changelog/20.0/20.0.0/summary.md | 9 +- go/flags/endtoend/flags_test.go | 2 +- go/flags/endtoend/vtcombo.txt | 2 +- go/flags/endtoend/vtgate.txt | 2 +- go/vt/proto/query/query.pb.go | 417 +++++++++------ go/vt/proto/query/query_vtproto.pb.go | 276 ++++++++++ go/vt/vtgate/schema/tracker.go | 9 +- go/vt/vtgate/schema/tracker_test.go | 206 +++++--- go/vt/vtgate/vtgate.go | 2 +- go/vt/vttablet/endtoend/framework/client.go | 15 +- go/vt/vttablet/endtoend/rpc_test.go | 3 +- go/vt/vttablet/endtoend/udfs_test.go | 13 +- go/vt/vttablet/sandboxconn/sandboxconn.go | 16 +- go/vt/vttablet/tabletserver/query_executor.go | 17 +- go/vt/vttablet/tabletserver/schema/db.go | 2 +- proto/query.proto | 22 +- web/vtadmin/src/proto/vtadmin.d.ts | 117 ++++- web/vtadmin/src/proto/vtadmin.js | 485 +++++++++++++++++- 18 files changed, 1328 insertions(+), 287 deletions(-) diff --git a/changelog/20.0/20.0.0/summary.md b/changelog/20.0/20.0.0/summary.md index 64588cd8be4..ca0b6182a3d 100644 --- a/changelog/20.0/20.0.0/summary.md +++ b/changelog/20.0/20.0.0/summary.md @@ -25,6 +25,7 @@ - **[Flag changes](#flag-changes)** - [`pprof-http` default change](#pprof-http-default) - [New `healthcheck-dial-concurrency` flag](#healthcheck-dial-concurrency-flag) + - [New `track-udfs` vtgate flag](#vtgate-track-udfs-flag) - **[Minor Changes](#minor-changes)** - **[New Stats](#new-stats)** - [VTTablet Query Cache Hits and Misses](#vttablet-query-cache-hits-and-misses) @@ -189,7 +190,9 @@ More details about how it works is available in [MySQL Docs](https://dev.mysql.c VTGate can track any user defined functions for better planning. User Defined Functions (UDFs) should be directly loaded in the underlying MySQL. -It should be enabled in VTGate with the `--enable-udfs` flag. +It should be enabled in VTGate with the `--track-udfs` flag. +This will enable the tracking of UDFs in VTGate and will be used for planning. +Without this flag, VTGate will not be aware that there might be aggregating user-defined functions in the query that need to be pushed down to MySQL. More details about how to load UDFs is available in [MySQL Docs](https://dev.mysql.com/doc/extending-mysql/8.0/en/adding-loadable-function.html) @@ -205,6 +208,10 @@ To continue enabling these endpoints, explicitly set `--pprof-http` when startin The new `--healthcheck-dial-concurrency` flag defines the maximum number of healthcheck connections that can open concurrently. This limit is to avoid hitting Go runtime panics on deployments watching enough tablets [to hit the runtime's maximum thread limit of `10000`](https://pkg.go.dev/runtime/debug#SetMaxThreads) due to blocking network syscalls. This flag applies to `vtcombo`, `vtctld` and `vtgate` only and a value less than the runtime max thread limit _(`10000`)_ is recommended. +#### New `--track-udfs` vtgate flag + +The new `--track-udfs` flag enables VTGate to track user defined functions for better planning. + ## Minor Changes ### New Stats diff --git a/go/flags/endtoend/flags_test.go b/go/flags/endtoend/flags_test.go index 25cca54caf9..cfc237dae5c 100644 --- a/go/flags/endtoend/flags_test.go +++ b/go/flags/endtoend/flags_test.go @@ -118,7 +118,7 @@ var ( func TestHelpOutput(t *testing.T) { wd, err := os.Getwd() require.NoError(t, err) - + t.Parallel() args := []string{"--help"} for binary, helptext := range helpOutput { t.Run(binary, func(t *testing.T) { diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index 8871cf05f43..fd09f940b76 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -115,7 +115,6 @@ Flags: --enable-partial-keyspace-migration (Experimental) Follow shard routing rules: enable only while migrating a keyspace shard by shard. See documentation on Partial MoveTables for more. (default false) --enable-per-workload-table-metrics If true, query counts and query error metrics include a label that identifies the workload --enable-tx-throttler Synonym to -enable_tx_throttler - --enable-udfs Enable UDFs support in vtgate. --enable-views Enable views support in vtgate. --enable_buffer Enable buffering (stalling) of primary traffic during failovers. --enable_buffer_dry_run Detect and log failover events, but do not actually buffer requests. @@ -377,6 +376,7 @@ Flags: --tracing-enable-logging whether to enable logging in the tracing service --tracing-sampling-rate float sampling rate for the probabilistic jaeger sampler (default 0.1) --tracing-sampling-type string sampling strategy to use for jaeger. possible values are 'const', 'probabilistic', 'rateLimiting', or 'remote' (default "const") + --track-udfs Track UDFs in vtgate. --track_schema_versions When enabled, vttablet will store versions of schemas at each position that a DDL is applied and allow retrieval of the schema corresponding to a position --transaction-log-stream-handler string URL handler for streaming transactions log (default "/debug/txlog") --transaction_limit_by_component Include CallerID.component when considering who the user is for the purpose of transaction limit. diff --git a/go/flags/endtoend/vtgate.txt b/go/flags/endtoend/vtgate.txt index 98a7d709246..7d0b3272cc8 100644 --- a/go/flags/endtoend/vtgate.txt +++ b/go/flags/endtoend/vtgate.txt @@ -54,7 +54,6 @@ Flags: --discovery_low_replication_lag duration Threshold below which replication lag is considered low enough to be healthy. (default 30s) --emit_stats If set, emit stats to push-based monitoring and stats backends --enable-partial-keyspace-migration (Experimental) Follow shard routing rules: enable only while migrating a keyspace shard by shard. See documentation on Partial MoveTables for more. (default false) - --enable-udfs Enable UDFs support in vtgate. --enable-views Enable views support in vtgate. --enable_buffer Enable buffering (stalling) of primary traffic during failovers. --enable_buffer_dry_run Detect and log failover events, but do not actually buffer requests. @@ -229,6 +228,7 @@ Flags: --tracing-enable-logging whether to enable logging in the tracing service --tracing-sampling-rate float sampling rate for the probabilistic jaeger sampler (default 0.1) --tracing-sampling-type string sampling strategy to use for jaeger. possible values are 'const', 'probabilistic', 'rateLimiting', or 'remote' (default "const") + --track-udfs Track UDFs in vtgate. --transaction_mode string SINGLE: disallow multi-db transactions, MULTI: allow multi-db transactions with best effort commit, TWOPC: allow multi-db transactions with 2pc commit (default "MULTI") --truncate-error-len int truncate errors sent to client if they are longer than this value (0 means do not truncate) --v Level log level for V logs diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go index 4875e2c56f3..39e2a9e8f32 100644 --- a/go/vt/proto/query/query.pb.go +++ b/go/vt/proto/query/query.pb.go @@ -479,10 +479,10 @@ func (TransactionState) EnumDescriptor() ([]byte, []int) { type SchemaTableType int32 const ( - SchemaTableType_VIEWS SchemaTableType = 0 - SchemaTableType_TABLES SchemaTableType = 1 - SchemaTableType_ALL SchemaTableType = 2 - SchemaTableType_UDF_AGGREGATE SchemaTableType = 3 + SchemaTableType_VIEWS SchemaTableType = 0 + SchemaTableType_TABLES SchemaTableType = 1 + SchemaTableType_ALL SchemaTableType = 2 + SchemaTableType_UDFS SchemaTableType = 3 ) // Enum value maps for SchemaTableType. @@ -491,13 +491,13 @@ var ( 0: "VIEWS", 1: "TABLES", 2: "ALL", - 3: "UDF_AGGREGATE", + 3: "UDFS", } SchemaTableType_value = map[string]int32{ - "VIEWS": 0, - "TABLES": 1, - "ALL": 2, - "UDF_AGGREGATE": 3, + "VIEWS": 0, + "TABLES": 1, + "ALL": 2, + "UDFS": 3, } ) @@ -5514,20 +5514,85 @@ func (x *GetSchemaRequest) GetTableNames() []string { return nil } +// UDFInfo represents the information about a UDF. +type UDFInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Aggregating bool `protobuf:"varint,2,opt,name=aggregating,proto3" json:"aggregating,omitempty"` + ReturnType Type `protobuf:"varint,3,opt,name=return_type,json=returnType,proto3,enum=query.Type" json:"return_type,omitempty"` +} + +func (x *UDFInfo) Reset() { + *x = UDFInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_query_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UDFInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UDFInfo) ProtoMessage() {} + +func (x *UDFInfo) ProtoReflect() protoreflect.Message { + mi := &file_query_proto_msgTypes[63] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UDFInfo.ProtoReflect.Descriptor instead. +func (*UDFInfo) Descriptor() ([]byte, []int) { + return file_query_proto_rawDescGZIP(), []int{63} +} + +func (x *UDFInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UDFInfo) GetAggregating() bool { + if x != nil { + return x.Aggregating + } + return false +} + +func (x *UDFInfo) GetReturnType() Type { + if x != nil { + return x.ReturnType + } + return Type_NULL_TYPE +} + // GetSchemaResponse is the returned value from GetSchema type GetSchemaResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // this is for the schema definition for the requested tables. + Udfs []*UDFInfo `protobuf:"bytes,1,rep,name=udfs,proto3" json:"udfs,omitempty"` + // this is for the schema definition for the requested tables and views. TableDefinition map[string]string `protobuf:"bytes,2,rep,name=table_definition,json=tableDefinition,proto3" json:"table_definition,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *GetSchemaResponse) Reset() { *x = GetSchemaResponse{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[63] + mi := &file_query_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5540,7 +5605,7 @@ func (x *GetSchemaResponse) String() string { func (*GetSchemaResponse) ProtoMessage() {} func (x *GetSchemaResponse) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[63] + mi := &file_query_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5553,7 +5618,14 @@ func (x *GetSchemaResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSchemaResponse.ProtoReflect.Descriptor instead. func (*GetSchemaResponse) Descriptor() ([]byte, []int) { - return file_query_proto_rawDescGZIP(), []int{63} + return file_query_proto_rawDescGZIP(), []int{64} +} + +func (x *GetSchemaResponse) GetUdfs() []*UDFInfo { + if x != nil { + return x.Udfs + } + return nil } func (x *GetSchemaResponse) GetTableDefinition() map[string]string { @@ -5582,7 +5654,7 @@ type StreamEvent_Statement struct { func (x *StreamEvent_Statement) Reset() { *x = StreamEvent_Statement{} if protoimpl.UnsafeEnabled { - mi := &file_query_proto_msgTypes[65] + mi := &file_query_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5595,7 +5667,7 @@ func (x *StreamEvent_Statement) String() string { func (*StreamEvent_Statement) ProtoMessage() {} func (x *StreamEvent_Statement) ProtoReflect() protoreflect.Message { - mi := &file_query_proto_msgTypes[65] + mi := &file_query_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6481,91 +6553,99 @@ var file_query_proto_rawDesc = []byte{ 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x58, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x1a, 0x42, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x92, 0x03, 0x0a, 0x09, 0x4d, 0x79, 0x53, 0x71, 0x6c, 0x46, 0x6c, - 0x61, 0x67, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, 0x12, 0x11, 0x0a, - 0x0d, 0x4e, 0x4f, 0x54, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x01, - 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, - 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x4b, 0x45, 0x59, - 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x55, 0x4c, 0x54, 0x49, - 0x50, 0x4c, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x08, 0x12, 0x0d, - 0x0a, 0x09, 0x42, 0x4c, 0x4f, 0x42, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x10, 0x12, 0x11, 0x0a, - 0x0d, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x20, - 0x12, 0x11, 0x0a, 0x0d, 0x5a, 0x45, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x4c, 0x5f, 0x46, 0x4c, 0x41, - 0x47, 0x10, 0x40, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x46, 0x4c, - 0x41, 0x47, 0x10, 0x80, 0x01, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x46, 0x4c, - 0x41, 0x47, 0x10, 0x80, 0x02, 0x12, 0x18, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x49, 0x4e, - 0x43, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x04, 0x12, - 0x13, 0x0a, 0x0e, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, 0x46, 0x4c, 0x41, - 0x47, 0x10, 0x80, 0x08, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x45, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, - 0x10, 0x80, 0x10, 0x12, 0x1a, 0x0a, 0x15, 0x4e, 0x4f, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, - 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x20, 0x12, - 0x17, 0x0a, 0x12, 0x4f, 0x4e, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x57, - 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x40, 0x12, 0x0e, 0x0a, 0x08, 0x4e, 0x55, 0x4d, 0x5f, - 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x02, 0x12, 0x13, 0x0a, 0x0d, 0x50, 0x41, 0x52, 0x54, - 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x01, 0x12, 0x10, 0x0a, - 0x0a, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x02, 0x12, - 0x11, 0x0a, 0x0b, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, - 0x80, 0x04, 0x12, 0x11, 0x0a, 0x0b, 0x42, 0x49, 0x4e, 0x43, 0x4d, 0x50, 0x5f, 0x46, 0x4c, 0x41, - 0x47, 0x10, 0x80, 0x80, 0x08, 0x1a, 0x02, 0x10, 0x01, 0x2a, 0x6b, 0x0a, 0x04, 0x46, 0x6c, 0x61, - 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0a, 0x49, - 0x53, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x4c, 0x10, 0x80, 0x02, 0x12, 0x0f, 0x0a, 0x0a, - 0x49, 0x53, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x10, 0x80, 0x04, 0x12, 0x0c, 0x0a, - 0x07, 0x49, 0x53, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x80, 0x08, 0x12, 0x0d, 0x0a, 0x08, 0x49, - 0x53, 0x51, 0x55, 0x4f, 0x54, 0x45, 0x44, 0x10, 0x80, 0x10, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x53, - 0x54, 0x45, 0x58, 0x54, 0x10, 0x80, 0x20, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x53, 0x42, 0x49, 0x4e, - 0x41, 0x52, 0x59, 0x10, 0x80, 0x40, 0x2a, 0xc0, 0x03, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x0d, 0x0a, 0x09, 0x4e, 0x55, 0x4c, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x09, - 0x0a, 0x04, 0x49, 0x4e, 0x54, 0x38, 0x10, 0x81, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x55, 0x49, 0x4e, - 0x54, 0x38, 0x10, 0x82, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x31, 0x36, 0x10, 0x83, - 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x31, 0x36, 0x10, 0x84, 0x06, 0x12, 0x0a, - 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x32, 0x34, 0x10, 0x85, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, - 0x4e, 0x54, 0x32, 0x34, 0x10, 0x86, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, - 0x10, 0x87, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x88, 0x06, - 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x89, 0x02, 0x12, 0x0b, 0x0a, 0x06, - 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x8a, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x4c, 0x4f, - 0x41, 0x54, 0x33, 0x32, 0x10, 0x8b, 0x08, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x4c, 0x4f, 0x41, 0x54, - 0x36, 0x34, 0x10, 0x8c, 0x08, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, - 0x4d, 0x50, 0x10, 0x8d, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, 0x10, 0x8e, 0x10, - 0x12, 0x09, 0x0a, 0x04, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x8f, 0x10, 0x12, 0x0d, 0x0a, 0x08, 0x44, - 0x41, 0x54, 0x45, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x90, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x59, 0x45, - 0x41, 0x52, 0x10, 0x91, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x43, 0x49, 0x4d, 0x41, 0x4c, - 0x10, 0x12, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, 0x93, 0x30, 0x12, 0x09, 0x0a, - 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x94, 0x50, 0x12, 0x0c, 0x0a, 0x07, 0x56, 0x41, 0x52, 0x43, - 0x48, 0x41, 0x52, 0x10, 0x95, 0x30, 0x12, 0x0e, 0x0a, 0x09, 0x56, 0x41, 0x52, 0x42, 0x49, 0x4e, - 0x41, 0x52, 0x59, 0x10, 0x96, 0x50, 0x12, 0x09, 0x0a, 0x04, 0x43, 0x48, 0x41, 0x52, 0x10, 0x97, - 0x30, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x98, 0x50, 0x12, 0x08, - 0x0a, 0x03, 0x42, 0x49, 0x54, 0x10, 0x99, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x45, 0x4e, 0x55, 0x4d, - 0x10, 0x9a, 0x10, 0x12, 0x08, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x9b, 0x10, 0x12, 0x09, 0x0a, - 0x05, 0x54, 0x55, 0x50, 0x4c, 0x45, 0x10, 0x1c, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x45, 0x4f, 0x4d, - 0x45, 0x54, 0x52, 0x59, 0x10, 0x9d, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x4a, 0x53, 0x4f, 0x4e, 0x10, - 0x9e, 0x10, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x58, 0x50, 0x52, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, - 0x10, 0x1f, 0x12, 0x0b, 0x0a, 0x06, 0x48, 0x45, 0x58, 0x4e, 0x55, 0x4d, 0x10, 0xa0, 0x20, 0x12, - 0x0b, 0x0a, 0x06, 0x48, 0x45, 0x58, 0x56, 0x41, 0x4c, 0x10, 0xa1, 0x20, 0x12, 0x0b, 0x0a, 0x06, - 0x42, 0x49, 0x54, 0x4e, 0x55, 0x4d, 0x10, 0xa2, 0x20, 0x2a, 0x46, 0x0a, 0x10, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, - 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x52, - 0x45, 0x50, 0x41, 0x52, 0x45, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, - 0x54, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, - 0x03, 0x2a, 0x44, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x45, 0x57, 0x53, 0x10, 0x00, 0x12, - 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, - 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x44, 0x46, 0x5f, 0x41, 0x47, 0x47, 0x52, - 0x45, 0x47, 0x41, 0x54, 0x45, 0x10, 0x03, 0x42, 0x35, 0x0a, 0x0f, 0x69, 0x6f, 0x2e, 0x76, 0x69, - 0x74, 0x65, 0x73, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x22, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, - 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x6d, 0x0a, 0x07, 0x55, 0x44, 0x46, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6e, + 0x67, 0x12, 0x2c, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, + 0xd5, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x75, 0x64, 0x66, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x55, 0x44, 0x46, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x75, 0x64, 0x66, 0x73, 0x12, 0x58, 0x0a, 0x10, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x1a, 0x42, 0x0a, 0x14, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x92, 0x03, 0x0a, 0x09, 0x4d, 0x79, 0x53, 0x71, + 0x6c, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x00, + 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x4f, 0x54, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, 0x5f, 0x46, 0x4c, 0x41, + 0x47, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x49, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, + 0x4c, 0x41, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, + 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x4d, 0x55, + 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, + 0x08, 0x12, 0x0d, 0x0a, 0x09, 0x42, 0x4c, 0x4f, 0x42, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x10, + 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x46, 0x4c, 0x41, + 0x47, 0x10, 0x20, 0x12, 0x11, 0x0a, 0x0d, 0x5a, 0x45, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x4c, 0x5f, + 0x46, 0x4c, 0x41, 0x47, 0x10, 0x40, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, + 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x01, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x4e, 0x55, 0x4d, + 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x02, 0x12, 0x18, 0x0a, 0x13, 0x41, 0x55, 0x54, 0x4f, + 0x5f, 0x49, 0x4e, 0x43, 0x52, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, + 0x80, 0x04, 0x12, 0x13, 0x0a, 0x0e, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x5f, + 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x08, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x45, 0x54, 0x5f, 0x46, + 0x4c, 0x41, 0x47, 0x10, 0x80, 0x10, 0x12, 0x1a, 0x0a, 0x15, 0x4e, 0x4f, 0x5f, 0x44, 0x45, 0x46, + 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, + 0x80, 0x20, 0x12, 0x17, 0x0a, 0x12, 0x4f, 0x4e, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, + 0x4e, 0x4f, 0x57, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x40, 0x12, 0x0e, 0x0a, 0x08, 0x4e, + 0x55, 0x4d, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x02, 0x12, 0x13, 0x0a, 0x0d, 0x50, + 0x41, 0x52, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x01, + 0x12, 0x10, 0x0a, 0x0a, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, + 0x80, 0x02, 0x12, 0x11, 0x0a, 0x0b, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x5f, 0x46, 0x4c, 0x41, + 0x47, 0x10, 0x80, 0x80, 0x04, 0x12, 0x11, 0x0a, 0x0b, 0x42, 0x49, 0x4e, 0x43, 0x4d, 0x50, 0x5f, + 0x46, 0x4c, 0x41, 0x47, 0x10, 0x80, 0x80, 0x08, 0x1a, 0x02, 0x10, 0x01, 0x2a, 0x6b, 0x0a, 0x04, + 0x46, 0x6c, 0x61, 0x67, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0f, + 0x0a, 0x0a, 0x49, 0x53, 0x49, 0x4e, 0x54, 0x45, 0x47, 0x52, 0x41, 0x4c, 0x10, 0x80, 0x02, 0x12, + 0x0f, 0x0a, 0x0a, 0x49, 0x53, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x10, 0x80, 0x04, + 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x53, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x80, 0x08, 0x12, 0x0d, + 0x0a, 0x08, 0x49, 0x53, 0x51, 0x55, 0x4f, 0x54, 0x45, 0x44, 0x10, 0x80, 0x10, 0x12, 0x0b, 0x0a, + 0x06, 0x49, 0x53, 0x54, 0x45, 0x58, 0x54, 0x10, 0x80, 0x20, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x53, + 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x80, 0x40, 0x2a, 0xc0, 0x03, 0x0a, 0x04, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x55, 0x4c, 0x4c, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, + 0x00, 0x12, 0x09, 0x0a, 0x04, 0x49, 0x4e, 0x54, 0x38, 0x10, 0x81, 0x02, 0x12, 0x0a, 0x0a, 0x05, + 0x55, 0x49, 0x4e, 0x54, 0x38, 0x10, 0x82, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x31, + 0x36, 0x10, 0x83, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x31, 0x36, 0x10, 0x84, + 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x32, 0x34, 0x10, 0x85, 0x02, 0x12, 0x0b, 0x0a, + 0x06, 0x55, 0x49, 0x4e, 0x54, 0x32, 0x34, 0x10, 0x86, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, + 0x54, 0x33, 0x32, 0x10, 0x87, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, + 0x10, 0x88, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x89, 0x02, 0x12, + 0x0b, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x8a, 0x06, 0x12, 0x0c, 0x0a, 0x07, + 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x33, 0x32, 0x10, 0x8b, 0x08, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x4c, + 0x4f, 0x41, 0x54, 0x36, 0x34, 0x10, 0x8c, 0x08, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x49, 0x4d, 0x45, + 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x8d, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, + 0x10, 0x8e, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x8f, 0x10, 0x12, 0x0d, + 0x0a, 0x08, 0x44, 0x41, 0x54, 0x45, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x90, 0x10, 0x12, 0x09, 0x0a, + 0x04, 0x59, 0x45, 0x41, 0x52, 0x10, 0x91, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x43, 0x49, + 0x4d, 0x41, 0x4c, 0x10, 0x12, 0x12, 0x09, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, 0x93, 0x30, + 0x12, 0x09, 0x0a, 0x04, 0x42, 0x4c, 0x4f, 0x42, 0x10, 0x94, 0x50, 0x12, 0x0c, 0x0a, 0x07, 0x56, + 0x41, 0x52, 0x43, 0x48, 0x41, 0x52, 0x10, 0x95, 0x30, 0x12, 0x0e, 0x0a, 0x09, 0x56, 0x41, 0x52, + 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x96, 0x50, 0x12, 0x09, 0x0a, 0x04, 0x43, 0x48, 0x41, + 0x52, 0x10, 0x97, 0x30, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x98, + 0x50, 0x12, 0x08, 0x0a, 0x03, 0x42, 0x49, 0x54, 0x10, 0x99, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x45, + 0x4e, 0x55, 0x4d, 0x10, 0x9a, 0x10, 0x12, 0x08, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x9b, 0x10, + 0x12, 0x09, 0x0a, 0x05, 0x54, 0x55, 0x50, 0x4c, 0x45, 0x10, 0x1c, 0x12, 0x0d, 0x0a, 0x08, 0x47, + 0x45, 0x4f, 0x4d, 0x45, 0x54, 0x52, 0x59, 0x10, 0x9d, 0x10, 0x12, 0x09, 0x0a, 0x04, 0x4a, 0x53, + 0x4f, 0x4e, 0x10, 0x9e, 0x10, 0x12, 0x0e, 0x0a, 0x0a, 0x45, 0x58, 0x50, 0x52, 0x45, 0x53, 0x53, + 0x49, 0x4f, 0x4e, 0x10, 0x1f, 0x12, 0x0b, 0x0a, 0x06, 0x48, 0x45, 0x58, 0x4e, 0x55, 0x4d, 0x10, + 0xa0, 0x20, 0x12, 0x0b, 0x0a, 0x06, 0x48, 0x45, 0x58, 0x56, 0x41, 0x4c, 0x10, 0xa1, 0x20, 0x12, + 0x0b, 0x0a, 0x06, 0x42, 0x49, 0x54, 0x4e, 0x55, 0x4d, 0x10, 0xa2, 0x20, 0x2a, 0x46, 0x0a, 0x10, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, + 0x07, 0x50, 0x52, 0x45, 0x50, 0x41, 0x52, 0x45, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, + 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, + 0x43, 0x4b, 0x10, 0x03, 0x2a, 0x3b, 0x0a, 0x0f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x45, 0x57, 0x53, + 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x01, 0x12, 0x07, + 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x55, 0x44, 0x46, 0x53, 0x10, + 0x03, 0x42, 0x35, 0x0a, 0x0f, 0x69, 0x6f, 0x2e, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x22, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, + 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -6581,7 +6661,7 @@ func file_query_proto_rawDescGZIP() []byte { } var file_query_proto_enumTypes = make([]protoimpl.EnumInfo, 12) -var file_query_proto_msgTypes = make([]protoimpl.MessageInfo, 67) +var file_query_proto_msgTypes = make([]protoimpl.MessageInfo, 68) var file_query_proto_goTypes = []interface{}{ (MySqlFlag)(0), // 0: query.MySqlFlag (Flag)(0), // 1: query.Flag @@ -6658,21 +6738,22 @@ var file_query_proto_goTypes = []interface{}{ (*StreamHealthResponse)(nil), // 72: query.StreamHealthResponse (*TransactionMetadata)(nil), // 73: query.TransactionMetadata (*GetSchemaRequest)(nil), // 74: query.GetSchemaRequest - (*GetSchemaResponse)(nil), // 75: query.GetSchemaResponse - nil, // 76: query.BoundQuery.BindVariablesEntry - (*StreamEvent_Statement)(nil), // 77: query.StreamEvent.Statement - nil, // 78: query.GetSchemaResponse.TableDefinitionEntry - (topodata.TabletType)(0), // 79: topodata.TabletType - (*vtrpc.CallerID)(nil), // 80: vtrpc.CallerID - (*vtrpc.RPCError)(nil), // 81: vtrpc.RPCError - (*topodata.TabletAlias)(nil), // 82: topodata.TabletAlias + (*UDFInfo)(nil), // 75: query.UDFInfo + (*GetSchemaResponse)(nil), // 76: query.GetSchemaResponse + nil, // 77: query.BoundQuery.BindVariablesEntry + (*StreamEvent_Statement)(nil), // 78: query.StreamEvent.Statement + nil, // 79: query.GetSchemaResponse.TableDefinitionEntry + (topodata.TabletType)(0), // 80: topodata.TabletType + (*vtrpc.CallerID)(nil), // 81: vtrpc.CallerID + (*vtrpc.RPCError)(nil), // 82: vtrpc.RPCError + (*topodata.TabletAlias)(nil), // 83: topodata.TabletAlias } var file_query_proto_depIdxs = []int32{ - 79, // 0: query.Target.tablet_type:type_name -> topodata.TabletType + 80, // 0: query.Target.tablet_type:type_name -> topodata.TabletType 2, // 1: query.Value.type:type_name -> query.Type 2, // 2: query.BindVariable.type:type_name -> query.Type 15, // 3: query.BindVariable.values:type_name -> query.Value - 76, // 4: query.BoundQuery.bind_variables:type_name -> query.BoundQuery.BindVariablesEntry + 77, // 4: query.BoundQuery.bind_variables:type_name -> query.BoundQuery.BindVariablesEntry 5, // 5: query.ExecuteOptions.included_fields:type_name -> query.ExecuteOptions.IncludedFields 6, // 6: query.ExecuteOptions.workload:type_name -> query.ExecuteOptions.Workload 7, // 7: query.ExecuteOptions.transaction_isolation:type_name -> query.ExecuteOptions.TransactionIsolation @@ -6682,136 +6763,138 @@ var file_query_proto_depIdxs = []int32{ 2, // 11: query.Field.type:type_name -> query.Type 19, // 12: query.QueryResult.fields:type_name -> query.Field 20, // 13: query.QueryResult.rows:type_name -> query.Row - 77, // 14: query.StreamEvent.statements:type_name -> query.StreamEvent.Statement + 78, // 14: query.StreamEvent.statements:type_name -> query.StreamEvent.Statement 14, // 15: query.StreamEvent.event_token:type_name -> query.EventToken - 80, // 16: query.ExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 16: query.ExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 17: query.ExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 18: query.ExecuteRequest.target:type_name -> query.Target 17, // 19: query.ExecuteRequest.query:type_name -> query.BoundQuery 18, // 20: query.ExecuteRequest.options:type_name -> query.ExecuteOptions 21, // 21: query.ExecuteResponse.result:type_name -> query.QueryResult - 81, // 22: query.ResultWithError.error:type_name -> vtrpc.RPCError + 82, // 22: query.ResultWithError.error:type_name -> vtrpc.RPCError 21, // 23: query.ResultWithError.result:type_name -> query.QueryResult - 80, // 24: query.StreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 24: query.StreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 25: query.StreamExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 26: query.StreamExecuteRequest.target:type_name -> query.Target 17, // 27: query.StreamExecuteRequest.query:type_name -> query.BoundQuery 18, // 28: query.StreamExecuteRequest.options:type_name -> query.ExecuteOptions 21, // 29: query.StreamExecuteResponse.result:type_name -> query.QueryResult - 80, // 30: query.BeginRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 30: query.BeginRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 31: query.BeginRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 32: query.BeginRequest.target:type_name -> query.Target 18, // 33: query.BeginRequest.options:type_name -> query.ExecuteOptions - 82, // 34: query.BeginResponse.tablet_alias:type_name -> topodata.TabletAlias - 80, // 35: query.CommitRequest.effective_caller_id:type_name -> vtrpc.CallerID + 83, // 34: query.BeginResponse.tablet_alias:type_name -> topodata.TabletAlias + 81, // 35: query.CommitRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 36: query.CommitRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 37: query.CommitRequest.target:type_name -> query.Target - 80, // 38: query.RollbackRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 38: query.RollbackRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 39: query.RollbackRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 40: query.RollbackRequest.target:type_name -> query.Target - 80, // 41: query.PrepareRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 41: query.PrepareRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 42: query.PrepareRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 43: query.PrepareRequest.target:type_name -> query.Target - 80, // 44: query.CommitPreparedRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 44: query.CommitPreparedRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 45: query.CommitPreparedRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 46: query.CommitPreparedRequest.target:type_name -> query.Target - 80, // 47: query.RollbackPreparedRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 47: query.RollbackPreparedRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 48: query.RollbackPreparedRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 49: query.RollbackPreparedRequest.target:type_name -> query.Target - 80, // 50: query.CreateTransactionRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 50: query.CreateTransactionRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 51: query.CreateTransactionRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 52: query.CreateTransactionRequest.target:type_name -> query.Target 12, // 53: query.CreateTransactionRequest.participants:type_name -> query.Target - 80, // 54: query.StartCommitRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 54: query.StartCommitRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 55: query.StartCommitRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 56: query.StartCommitRequest.target:type_name -> query.Target - 80, // 57: query.SetRollbackRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 57: query.SetRollbackRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 58: query.SetRollbackRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 59: query.SetRollbackRequest.target:type_name -> query.Target - 80, // 60: query.ConcludeTransactionRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 60: query.ConcludeTransactionRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 61: query.ConcludeTransactionRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 62: query.ConcludeTransactionRequest.target:type_name -> query.Target - 80, // 63: query.ReadTransactionRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 63: query.ReadTransactionRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 64: query.ReadTransactionRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 65: query.ReadTransactionRequest.target:type_name -> query.Target 73, // 66: query.ReadTransactionResponse.metadata:type_name -> query.TransactionMetadata - 80, // 67: query.BeginExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 67: query.BeginExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 68: query.BeginExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 69: query.BeginExecuteRequest.target:type_name -> query.Target 17, // 70: query.BeginExecuteRequest.query:type_name -> query.BoundQuery 18, // 71: query.BeginExecuteRequest.options:type_name -> query.ExecuteOptions - 81, // 72: query.BeginExecuteResponse.error:type_name -> vtrpc.RPCError + 82, // 72: query.BeginExecuteResponse.error:type_name -> vtrpc.RPCError 21, // 73: query.BeginExecuteResponse.result:type_name -> query.QueryResult - 82, // 74: query.BeginExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias - 80, // 75: query.BeginStreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 83, // 74: query.BeginExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias + 81, // 75: query.BeginStreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 76: query.BeginStreamExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 77: query.BeginStreamExecuteRequest.target:type_name -> query.Target 17, // 78: query.BeginStreamExecuteRequest.query:type_name -> query.BoundQuery 18, // 79: query.BeginStreamExecuteRequest.options:type_name -> query.ExecuteOptions - 81, // 80: query.BeginStreamExecuteResponse.error:type_name -> vtrpc.RPCError + 82, // 80: query.BeginStreamExecuteResponse.error:type_name -> vtrpc.RPCError 21, // 81: query.BeginStreamExecuteResponse.result:type_name -> query.QueryResult - 82, // 82: query.BeginStreamExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias - 80, // 83: query.MessageStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID + 83, // 82: query.BeginStreamExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias + 81, // 83: query.MessageStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 84: query.MessageStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 85: query.MessageStreamRequest.target:type_name -> query.Target 21, // 86: query.MessageStreamResponse.result:type_name -> query.QueryResult - 80, // 87: query.MessageAckRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 87: query.MessageAckRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 88: query.MessageAckRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 89: query.MessageAckRequest.target:type_name -> query.Target 15, // 90: query.MessageAckRequest.ids:type_name -> query.Value 21, // 91: query.MessageAckResponse.result:type_name -> query.QueryResult - 80, // 92: query.ReserveExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 81, // 92: query.ReserveExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 93: query.ReserveExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 94: query.ReserveExecuteRequest.target:type_name -> query.Target 17, // 95: query.ReserveExecuteRequest.query:type_name -> query.BoundQuery 18, // 96: query.ReserveExecuteRequest.options:type_name -> query.ExecuteOptions - 81, // 97: query.ReserveExecuteResponse.error:type_name -> vtrpc.RPCError + 82, // 97: query.ReserveExecuteResponse.error:type_name -> vtrpc.RPCError 21, // 98: query.ReserveExecuteResponse.result:type_name -> query.QueryResult - 82, // 99: query.ReserveExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias - 80, // 100: query.ReserveStreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 83, // 99: query.ReserveExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias + 81, // 100: query.ReserveStreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 101: query.ReserveStreamExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 102: query.ReserveStreamExecuteRequest.target:type_name -> query.Target 17, // 103: query.ReserveStreamExecuteRequest.query:type_name -> query.BoundQuery 18, // 104: query.ReserveStreamExecuteRequest.options:type_name -> query.ExecuteOptions - 81, // 105: query.ReserveStreamExecuteResponse.error:type_name -> vtrpc.RPCError + 82, // 105: query.ReserveStreamExecuteResponse.error:type_name -> vtrpc.RPCError 21, // 106: query.ReserveStreamExecuteResponse.result:type_name -> query.QueryResult - 82, // 107: query.ReserveStreamExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias - 80, // 108: query.ReserveBeginExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 83, // 107: query.ReserveStreamExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias + 81, // 108: query.ReserveBeginExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 109: query.ReserveBeginExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 110: query.ReserveBeginExecuteRequest.target:type_name -> query.Target 17, // 111: query.ReserveBeginExecuteRequest.query:type_name -> query.BoundQuery 18, // 112: query.ReserveBeginExecuteRequest.options:type_name -> query.ExecuteOptions - 81, // 113: query.ReserveBeginExecuteResponse.error:type_name -> vtrpc.RPCError + 82, // 113: query.ReserveBeginExecuteResponse.error:type_name -> vtrpc.RPCError 21, // 114: query.ReserveBeginExecuteResponse.result:type_name -> query.QueryResult - 82, // 115: query.ReserveBeginExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias - 80, // 116: query.ReserveBeginStreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID + 83, // 115: query.ReserveBeginExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias + 81, // 116: query.ReserveBeginStreamExecuteRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 117: query.ReserveBeginStreamExecuteRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 118: query.ReserveBeginStreamExecuteRequest.target:type_name -> query.Target 17, // 119: query.ReserveBeginStreamExecuteRequest.query:type_name -> query.BoundQuery 18, // 120: query.ReserveBeginStreamExecuteRequest.options:type_name -> query.ExecuteOptions - 81, // 121: query.ReserveBeginStreamExecuteResponse.error:type_name -> vtrpc.RPCError + 82, // 121: query.ReserveBeginStreamExecuteResponse.error:type_name -> vtrpc.RPCError 21, // 122: query.ReserveBeginStreamExecuteResponse.result:type_name -> query.QueryResult - 82, // 123: query.ReserveBeginStreamExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias - 80, // 124: query.ReleaseRequest.effective_caller_id:type_name -> vtrpc.CallerID + 83, // 123: query.ReserveBeginStreamExecuteResponse.tablet_alias:type_name -> topodata.TabletAlias + 81, // 124: query.ReleaseRequest.effective_caller_id:type_name -> vtrpc.CallerID 13, // 125: query.ReleaseRequest.immediate_caller_id:type_name -> query.VTGateCallerID 12, // 126: query.ReleaseRequest.target:type_name -> query.Target 12, // 127: query.StreamHealthResponse.target:type_name -> query.Target 70, // 128: query.StreamHealthResponse.realtime_stats:type_name -> query.RealtimeStats - 82, // 129: query.StreamHealthResponse.tablet_alias:type_name -> topodata.TabletAlias + 83, // 129: query.StreamHealthResponse.tablet_alias:type_name -> topodata.TabletAlias 3, // 130: query.TransactionMetadata.state:type_name -> query.TransactionState 12, // 131: query.TransactionMetadata.participants:type_name -> query.Target 12, // 132: query.GetSchemaRequest.target:type_name -> query.Target 4, // 133: query.GetSchemaRequest.table_type:type_name -> query.SchemaTableType - 78, // 134: query.GetSchemaResponse.table_definition:type_name -> query.GetSchemaResponse.TableDefinitionEntry - 16, // 135: query.BoundQuery.BindVariablesEntry.value:type_name -> query.BindVariable - 11, // 136: query.StreamEvent.Statement.category:type_name -> query.StreamEvent.Statement.Category - 19, // 137: query.StreamEvent.Statement.primary_key_fields:type_name -> query.Field - 20, // 138: query.StreamEvent.Statement.primary_key_values:type_name -> query.Row - 139, // [139:139] is the sub-list for method output_type - 139, // [139:139] is the sub-list for method input_type - 139, // [139:139] is the sub-list for extension type_name - 139, // [139:139] is the sub-list for extension extendee - 0, // [0:139] is the sub-list for field type_name + 2, // 134: query.UDFInfo.return_type:type_name -> query.Type + 75, // 135: query.GetSchemaResponse.udfs:type_name -> query.UDFInfo + 79, // 136: query.GetSchemaResponse.table_definition:type_name -> query.GetSchemaResponse.TableDefinitionEntry + 16, // 137: query.BoundQuery.BindVariablesEntry.value:type_name -> query.BindVariable + 11, // 138: query.StreamEvent.Statement.category:type_name -> query.StreamEvent.Statement.Category + 19, // 139: query.StreamEvent.Statement.primary_key_fields:type_name -> query.Field + 20, // 140: query.StreamEvent.Statement.primary_key_values:type_name -> query.Row + 141, // [141:141] is the sub-list for method output_type + 141, // [141:141] is the sub-list for method input_type + 141, // [141:141] is the sub-list for extension type_name + 141, // [141:141] is the sub-list for extension extendee + 0, // [0:141] is the sub-list for field type_name } func init() { file_query_proto_init() } @@ -7577,6 +7660,18 @@ func file_query_proto_init() { } } file_query_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UDFInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_query_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GetSchemaResponse); i { case 0: return &v.state @@ -7588,7 +7683,7 @@ func file_query_proto_init() { return nil } } - file_query_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + file_query_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StreamEvent_Statement); i { case 0: return &v.state @@ -7607,7 +7702,7 @@ func file_query_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_query_proto_rawDesc, NumEnums: 12, - NumMessages: 67, + NumMessages: 68, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/query/query_vtproto.pb.go b/go/vt/proto/query/query_vtproto.pb.go index 3132fa124dd..636c950642d 100644 --- a/go/vt/proto/query/query_vtproto.pb.go +++ b/go/vt/proto/query/query_vtproto.pb.go @@ -1476,11 +1476,38 @@ func (m *GetSchemaRequest) CloneMessageVT() proto.Message { return m.CloneVT() } +func (m *UDFInfo) CloneVT() *UDFInfo { + if m == nil { + return (*UDFInfo)(nil) + } + r := &UDFInfo{ + Name: m.Name, + Aggregating: m.Aggregating, + ReturnType: m.ReturnType, + } + if len(m.unknownFields) > 0 { + r.unknownFields = make([]byte, len(m.unknownFields)) + copy(r.unknownFields, m.unknownFields) + } + return r +} + +func (m *UDFInfo) CloneMessageVT() proto.Message { + return m.CloneVT() +} + func (m *GetSchemaResponse) CloneVT() *GetSchemaResponse { if m == nil { return (*GetSchemaResponse)(nil) } r := &GetSchemaResponse{} + if rhs := m.Udfs; rhs != nil { + tmpContainer := make([]*UDFInfo, len(rhs)) + for k, v := range rhs { + tmpContainer[k] = v.CloneVT() + } + r.Udfs = tmpContainer + } if rhs := m.TableDefinition; rhs != nil { tmpContainer := make(map[string]string, len(rhs)) for k, v := range rhs { @@ -5660,6 +5687,61 @@ func (m *GetSchemaRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *UDFInfo) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UDFInfo) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *UDFInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.ReturnType != 0 { + i = encodeVarint(dAtA, i, uint64(m.ReturnType)) + i-- + dAtA[i] = 0x18 + } + if m.Aggregating { + i-- + if m.Aggregating { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarint(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *GetSchemaResponse) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -5709,6 +5791,18 @@ func (m *GetSchemaResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { dAtA[i] = 0x12 } } + if len(m.Udfs) > 0 { + for iNdEx := len(m.Udfs) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Udfs[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + } return len(dAtA) - i, nil } @@ -7347,12 +7441,38 @@ func (m *GetSchemaRequest) SizeVT() (n int) { return n } +func (m *UDFInfo) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.Aggregating { + n += 2 + } + if m.ReturnType != 0 { + n += 1 + sov(uint64(m.ReturnType)) + } + n += len(m.unknownFields) + return n +} + func (m *GetSchemaResponse) SizeVT() (n int) { if m == nil { return 0 } var l int _ = l + if len(m.Udfs) > 0 { + for _, e := range m.Udfs { + l = e.SizeVT() + n += 1 + l + sov(uint64(l)) + } + } if len(m.TableDefinition) > 0 { for k, v := range m.TableDefinition { _ = k @@ -18198,6 +18318,128 @@ func (m *GetSchemaRequest) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *UDFInfo) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UDFInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UDFInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Aggregating", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Aggregating = bool(v != 0) + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ReturnType", wireType) + } + m.ReturnType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ReturnType |= Type(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *GetSchemaResponse) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -18227,6 +18469,40 @@ func (m *GetSchemaResponse) UnmarshalVT(dAtA []byte) error { return fmt.Errorf("proto: GetSchemaResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Udfs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Udfs = append(m.Udfs, &UDFInfo{}) + if err := m.Udfs[len(m.Udfs)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field TableDefinition", wireType) diff --git a/go/vt/vtgate/schema/tracker.go b/go/vt/vtgate/schema/tracker.go index ce1686e9938..bc622a7ca1f 100644 --- a/go/vt/vtgate/schema/tracker.go +++ b/go/vt/vtgate/schema/tracker.go @@ -164,10 +164,13 @@ func (t *Tracker) loadUDFs(conn queryservice.QueryService, target *querypb.Targe t.mu.Lock() defer t.mu.Unlock() - err := conn.GetSchema(t.ctx, target, querypb.SchemaTableType_UDF_AGGREGATE, nil, func(schemaRes *querypb.GetSchemaResponse) error { + err := conn.GetSchema(t.ctx, target, querypb.SchemaTableType_UDFS, nil, func(schemaRes *querypb.GetSchemaResponse) error { var udfs []string - for name := range schemaRes.TableDefinition { - udfs = append(udfs, name) + for _, udf := range schemaRes.Udfs { + if !udf.Aggregating { + continue + } + udfs = append(udfs, udf.Name) } t.udfs[target.Keyspace] = udfs diff --git a/go/vt/vtgate/schema/tracker_test.go b/go/vt/vtgate/schema/tracker_test.go index 3c9b08d71dd..1ee15ba99cb 100644 --- a/go/vt/vtgate/schema/tracker_test.go +++ b/go/vt/vtgate/schema/tracker_test.go @@ -26,6 +26,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/log" @@ -168,21 +170,39 @@ func TestTrackerGetKeyspaceUpdateController(t *testing.T) { assert.Nil(t, ks3.reloadKeyspace, "ks3 already initialized") } +type myTable struct { + name, create string +} + +func tbl(name, create string) myTable { + return myTable{name: name, create: create} +} + +func tables(tables ...myTable) sandboxconn.SchemaResult { + m := map[string]string{} + for _, table := range tables { + m[table.name] = table.create + } + return sandboxconn.SchemaResult{TablesAndViews: m} +} + // TestTableTracking tests that the tracker is able to track table schema changes. func TestTableTracking(t *testing.T) { - schemaDefResult := []map[string]string{{ - "prior": "create table prior(id int primary key)", - }, { - // initial load of view - kept empty - }, { - "t1": "create table t1(id bigint primary key, name varchar(50), email varchar(50) not null default 'a@b.com')", - "T1": "create table T1(id varchar(50) primary key)", - }, { - "T1": "create table T1(id varchar(50) primary key, name varchar(50))", - "t3": "create table t3(id datetime primary key)", - }, { - "t4": "create table t4(name varchar(50) primary key)", - }} + schemaResponse := []sandboxconn.SchemaResult{ + tables(tbl("prior", "create table prior(id int primary key)")), + empty(), /*initial load of view*/ + tables( + tbl("t1", "create table t1(id bigint primary key, name varchar(50), email varchar(50) not null default 'a@b.com')"), + tbl("T1", "create table T1(id varchar(50) primary key)"), + ), + tables( + tbl("T1", "create table T1(id varchar(50) primary key, name varchar(50))"), + tbl("t3", "create table t3(id datetime primary key)"), + ), + tables( + tbl("t4", "create table t4(name varchar(50) primary key)"), + ), + } testcases := []testCases{{ testName: "initial table load", @@ -216,24 +236,24 @@ func TestTableTracking(t *testing.T) { }, }} - testTracker(t, false, schemaDefResult, testcases) + testTracker(t, false, schemaResponse, testcases) } // TestViewsTracking tests that the tracker is able to track views. func TestViewsTracking(t *testing.T) { - schemaDefResult := []map[string]string{{ - // initial load of table - kept empty - }, { - "prior": "create view prior as select 1 from tbl", - }, { - "t1": "create view t1 as select 1 from tbl1", - "V1": "create view V1 as select 1 from tbl2", - }, { - "V1": "create view V1 as select 1,2 from tbl2", - "t3": "create view t3 as select 1 from tbl3", - }, { - "t4": "create view t4 as select 1 from tbl4", - }} + schemaDefResult := []sandboxconn.SchemaResult{ + empty(), /*initial load of view*/ + tables(tbl("prior", "create view prior as select 1 from tbl")), + tables( + tbl("t1", "create view t1 as select 1 from tbl1"), + tbl("V1", "create view V1 as select 1 from tbl2"), + ), + tables( + tbl("V1", "create view V1 as select 1,2 from tbl2"), + tbl("t3", "create view t3 as select 1 from tbl3"), + ), + tables(tbl("t4", "create view t4 as select 1 from tbl4")), + } testcases := []testCases{{ testName: "initial view load", @@ -268,27 +288,26 @@ func TestViewsTracking(t *testing.T) { // TestFKInfoRetrieval tests that the tracker is able to retrieve required foreign key information from ddl statement. func TestFKInfoRetrieval(t *testing.T) { - schemaDefResult := []map[string]string{{ - "my_tbl": "CREATE TABLE `my_tbl` (" + - "`id` bigint NOT NULL AUTO_INCREMENT," + - "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL," + - "`email` varbinary(100) DEFAULT NULL," + - "PRIMARY KEY (`id`)," + - "KEY `id` (`id`,`name`)) " + - "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", - }, { - // initial load of view - kept empty - }, { - "my_child_tbl": "CREATE TABLE `my_child_tbl` (" + - "`id` bigint NOT NULL AUTO_INCREMENT," + - "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL," + - "`code` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL," + - "`my_id` bigint DEFAULT NULL," + - "PRIMARY KEY (`id`)," + - "KEY `my_id` (`my_id`,`name`)," + - "CONSTRAINT `my_child_tbl_ibfk_1` FOREIGN KEY (`my_id`, `name`) REFERENCES `my_tbl` (`id`, `name`) ON DELETE CASCADE) " + - "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", - }} + schemaDefResult := []sandboxconn.SchemaResult{ + tables(tbl("my_tbl", "CREATE TABLE `my_tbl` ("+ + "`id` bigint NOT NULL AUTO_INCREMENT,"+ + "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,"+ + "`email` varbinary(100) DEFAULT NULL,"+ + "PRIMARY KEY (`id`),"+ + "KEY `id` (`id`,`name`)) "+ + "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci")), + empty(), + tables(tbl( + "my_child_tbl", "CREATE TABLE `my_child_tbl` ("+ + "`id` bigint NOT NULL AUTO_INCREMENT,"+ + "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,"+ + "`code` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,"+ + "`my_id` bigint DEFAULT NULL,"+ + "PRIMARY KEY (`id`),"+ + "KEY `my_id` (`my_id`,`name`),"+ + "CONSTRAINT `my_child_tbl_ibfk_1` FOREIGN KEY (`my_id`, `name`) REFERENCES `my_tbl` (`id`, `name`) ON DELETE CASCADE) "+ + "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci")), + } testcases := []testCases{{ testName: "initial table load", @@ -326,26 +345,26 @@ func TestFKInfoRetrieval(t *testing.T) { // TestIndexInfoRetrieval tests that the tracker is able to retrieve required index information from ddl statement. func TestIndexInfoRetrieval(t *testing.T) { - schemaDefResult := []map[string]string{{ - "my_tbl": "CREATE TABLE `my_tbl` (" + - "`id` bigint NOT NULL AUTO_INCREMENT," + - "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL," + - "`email` varbinary(100) DEFAULT NULL," + - "PRIMARY KEY (`id`)," + - "KEY `id` (`id`,`name`)) " + - "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", - }, { - // initial load of view - kept empty - }, { - "my_tbl": "CREATE TABLE `my_tbl` (" + - "`id` bigint NOT NULL AUTO_INCREMENT," + - "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL," + - "`email` varbinary(100) DEFAULT NULL," + - "PRIMARY KEY (`id`)," + - "KEY `id` (`id`,`name`), " + - "UNIQUE KEY `email` (`email`)) " + - "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci", - }} + schemaDefResult := []sandboxconn.SchemaResult{ + tables(tbl( + "my_tbl", "CREATE TABLE `my_tbl` ("+ + "`id` bigint NOT NULL AUTO_INCREMENT,"+ + "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,"+ + "`email` varbinary(100) DEFAULT NULL,"+ + "PRIMARY KEY (`id`),"+ + "KEY `id` (`id`,`name`)) "+ + "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci")), + empty(), /*initial load of view*/ + tables(tbl( + "my_tbl", "CREATE TABLE `my_tbl` ("+ + "`id` bigint NOT NULL AUTO_INCREMENT,"+ + "`name` varchar(50) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,"+ + "`email` varbinary(100) DEFAULT NULL,"+ + "PRIMARY KEY (`id`),"+ + "KEY `id` (`id`,`name`), "+ + "UNIQUE KEY `email` (`email`)) "+ + "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci")), + } testcases := []testCases{{ testName: "initial table load", @@ -384,21 +403,24 @@ func TestIndexInfoRetrieval(t *testing.T) { testTracker(t, false, schemaDefResult, testcases) } +func empty() sandboxconn.SchemaResult { + return sandboxconn.SchemaResult{TablesAndViews: map[string]string{}} +} + // TestUDFRetrieval tests that the tracker is able to retrieve required UDF information. func TestUDFRetrieval(t *testing.T) { - schemaDefResult := []map[string]string{{ - // initial load of table - kept empty - }, { - // initial load of view - kept empty - }, { - "my_udf": "int", - }, { - "my_udf2": "char", - "my_udf3": "int", - }, { - "my_udf2": "char", - "my_udf4": "int", - }} + schemaDefResult := []sandboxconn.SchemaResult{ + empty(), // initial load of table + empty(), + udfs(udf("my_udf", true, sqltypes.Int32)), + udfs( + udf("my_udf2", true, sqltypes.Char), + udf("my_udf3", true, sqltypes.Int32), + ), + udfs( + udf("my_udf2", true, sqltypes.Char), + udf("my_udf4", true, sqltypes.Int32), + )} testcases := []testCases{{ testName: "initial load", @@ -416,6 +438,21 @@ func TestUDFRetrieval(t *testing.T) { testTracker(t, true, schemaDefResult, testcases) } +func udfs(udfs ...*querypb.UDFInfo) sandboxconn.SchemaResult { + return sandboxconn.SchemaResult{ + TablesAndViews: map[string]string{}, + UDFs: udfs, + } +} + +func udf(name string, aggr bool, typ querypb.Type) *querypb.UDFInfo { + return &querypb.UDFInfo{ + Name: name, + Aggregating: aggr, + ReturnType: typ, + } +} + type testCases struct { testName string @@ -431,7 +468,7 @@ type testCases struct { expUDFs []string } -func testTracker(t *testing.T, enableUDFs bool, schemaDefResult []map[string]string, tcases []testCases) { +func testTracker(t *testing.T, enableUDFs bool, schemaDefResult []sandboxconn.SchemaResult, tcases []testCases) { ch := make(chan *discovery.TabletHealth) tracker := NewTracker(ch, true, enableUDFs, sqlparser.NewTestParser()) tracker.consumeDelay = 1 * time.Millisecond @@ -470,8 +507,9 @@ func testTracker(t *testing.T, enableUDFs bool, schemaDefResult []map[string]str _, keyspacePresent := tracker.tracked[target.Keyspace] require.Equal(t, true, keyspacePresent) - for k, v := range tcase.expTbl { - utils.MustMatch(t, v, tracker.GetColumns(keyspace, k), "mismatch columns for table: ", k) + for k, expectedCols := range tcase.expTbl { + actualCols := tracker.GetColumns(keyspace, k) + utils.MustMatch(t, expectedCols, actualCols, "mismatch columns for table: ", k) if len(tcase.expFk[k]) > 0 { fks := tracker.GetForeignKeys(keyspace, k) for _, fk := range fks { diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index e08292087bf..d7b28d47226 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -149,7 +149,7 @@ func registerFlags(fs *pflag.FlagSet) { fs.IntVar(&queryLogBufferSize, "querylog-buffer-size", queryLogBufferSize, "Maximum number of buffered query logs before throttling log output") fs.DurationVar(&messageStreamGracePeriod, "message_stream_grace_period", messageStreamGracePeriod, "the amount of time to give for a vttablet to resume if it ends a message stream, usually because of a reparent.") fs.BoolVar(&enableViews, "enable-views", enableViews, "Enable views support in vtgate.") - fs.BoolVar(&enableViews, "enable-udfs", enableUdfs, "Enable UDFs support in vtgate.") + fs.BoolVar(&enableViews, "track-udfs", enableUdfs, "Track UDFs in vtgate.") fs.BoolVar(&allowKillStmt, "allow-kill-statement", allowKillStmt, "Allows the execution of kill statement") fs.IntVar(&warmingReadsPercent, "warming-reads-percent", 0, "Percentage of reads on the primary to forward to replicas. Useful for keeping buffer pools warm") fs.IntVar(&warmingReadsConcurrency, "warming-reads-concurrency", 500, "Number of concurrent warming reads allowed") diff --git a/go/vt/vttablet/endtoend/framework/client.go b/go/vt/vttablet/endtoend/framework/client.go index eb70eaeb9cb..dc4b7f9f339 100644 --- a/go/vt/vttablet/endtoend/framework/client.go +++ b/go/vt/vttablet/endtoend/framework/client.go @@ -431,16 +431,17 @@ func (client *QueryClient) UpdateContext(ctx context.Context) { client.ctx = ctx } -func (client *QueryClient) GetSchema(tableType querypb.SchemaTableType, tableNames ...string) (map[string]string, error) { - schemaDef := make(map[string]string) - err := client.server.GetSchema(client.ctx, client.target, tableType, tableNames, func(schemaRes *querypb.GetSchemaResponse) error { +func (client *QueryClient) GetSchema( + tableType querypb.SchemaTableType, + tableNames ...string, +) (schemaDef map[string]string, udfs []*querypb.UDFInfo, err error) { + schemaDef = make(map[string]string) + err = client.server.GetSchema(client.ctx, client.target, tableType, tableNames, func(schemaRes *querypb.GetSchemaResponse) error { for tableName, schemaDefinition := range schemaRes.TableDefinition { schemaDef[tableName] = schemaDefinition } + udfs = append(udfs, schemaRes.Udfs...) return nil }) - if err != nil { - return nil, err - } - return schemaDef, nil + return } diff --git a/go/vt/vttablet/endtoend/rpc_test.go b/go/vt/vttablet/endtoend/rpc_test.go index e24137e1340..e1ee7dff411 100644 --- a/go/vt/vttablet/endtoend/rpc_test.go +++ b/go/vt/vttablet/endtoend/rpc_test.go @@ -218,8 +218,9 @@ func TestGetSchemaRPC(t *testing.T) { t.Errorf("Schema tracking hasn't caught up") return case <-time.After(1 * time.Second): - schemaDefs, err := client.GetSchema(testcase.getSchemaQueryType, testcase.getSchemaTables...) + schemaDefs, udfs, err := client.GetSchema(testcase.getSchemaQueryType, testcase.getSchemaTables...) require.NoError(t, err) + require.Empty(t, udfs) success := true for tableName, expectedCreateStatement := range testcase.mapToExpect { if schemaDefs[tableName] != expectedCreateStatement { diff --git a/go/vt/vttablet/endtoend/udfs_test.go b/go/vt/vttablet/endtoend/udfs_test.go index aed7c3c5a97..a8808ce2c96 100644 --- a/go/vt/vttablet/endtoend/udfs_test.go +++ b/go/vt/vttablet/endtoend/udfs_test.go @@ -100,8 +100,8 @@ func validateHealthStreamSignal(t *testing.T, client *framework.QueryClient, ch require.Equal(t, expected[1], fmt.Sprintf("%v", qr.Rows)) } -// TestUDFRFC will validate that UDFs are received through the rfc call. -func TestUDFRFC(t *testing.T) { +// TestUDF_RPC will validate that UDFs are received through the rpc call. +func TestUDF_RPC(t *testing.T) { client := framework.NewClient() client.UpdateContext(callerid.NewContext( @@ -115,7 +115,7 @@ func TestUDFRFC(t *testing.T) { err := cluster.Execute([]string{"CREATE AGGREGATE FUNCTION myudf RETURNS REAL SONAME 'udf.so';"}, "vttest") require.NoError(t, err) - validateRPC(t, client, func(udfs map[string]string) bool { + validateRPC(t, client, func(udfs []*querypb.UDFInfo) bool { // keep checking till the udf is added. return len(udfs) == 0 }) @@ -124,13 +124,13 @@ func TestUDFRFC(t *testing.T) { err = cluster.Execute([]string{"drop function myudf"}, "vttest") require.NoError(t, err) - validateRPC(t, client, func(udfs map[string]string) bool { + validateRPC(t, client, func(udfs []*querypb.UDFInfo) bool { // keep checking till the udf is removed. return len(udfs) != 0 }) } -func validateRPC(t *testing.T, client *framework.QueryClient, cond func(udfs map[string]string) bool) (<-chan time.Time, bool) { +func validateRPC(t *testing.T, client *framework.QueryClient, cond func(udfs []*querypb.UDFInfo) bool) (<-chan time.Time, bool) { timeout := time.After(30 * time.Second) conditionNotMet := true for conditionNotMet { @@ -139,8 +139,9 @@ func validateRPC(t *testing.T, client *framework.QueryClient, cond func(udfs map case <-timeout: t.Fatal("timed out waiting for updated udf") default: - udfs, err := client.GetSchema(querypb.SchemaTableType_UDF_AGGREGATE) + schemaDef, udfs, err := client.GetSchema(querypb.SchemaTableType_UDFS, "") require.NoError(t, err) + require.Empty(t, schemaDef) conditionNotMet = cond(udfs) } } diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 2d0f5d9fff1..1f8a4027f8e 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -130,11 +130,16 @@ type SandboxConn struct { NotServing bool - getSchemaResult []map[string]string + getSchemaResult []SchemaResult parser *sqlparser.Parser } +type SchemaResult struct { + TablesAndViews map[string]string + UDFs []*querypb.UDFInfo +} + var _ queryservice.QueryService = (*SandboxConn)(nil) // compile-time interface check // NewSandboxConn returns a new SandboxConn targeted to the provided tablet. @@ -203,7 +208,7 @@ func (sbc *SandboxConn) SetResults(r []*sqltypes.Result) { } // SetSchemaResult sets what GetSchema should return on each call. -func (sbc *SandboxConn) SetSchemaResult(r []map[string]string) { +func (sbc *SandboxConn) SetSchemaResult(r []SchemaResult) { sbc.getSchemaResult = r } @@ -662,7 +667,12 @@ func (sbc *SandboxConn) GetSchema(ctx context.Context, target *querypb.Target, t } resp := sbc.getSchemaResult[0] sbc.getSchemaResult = sbc.getSchemaResult[1:] - return callback(&querypb.GetSchemaResponse{TableDefinition: resp}) + + response := &querypb.GetSchemaResponse{ + TableDefinition: resp.TablesAndViews, + Udfs: resp.UDFs, + } + return callback(response) } // Close does not change ExecCount diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index 78351ab23be..b538f9342eb 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -1161,7 +1161,7 @@ func (qre *QueryExecutor) GetSchemaDefinitions(tableType querypb.SchemaTableType return qre.getTableDefinitions(tableNames, callback) case querypb.SchemaTableType_ALL: return qre.getAllDefinitions(tableNames, callback) - case querypb.SchemaTableType_UDF_AGGREGATE: + case querypb.SchemaTableType_UDFS: return qre.getUDFs(callback) } return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid table type %v", tableType) @@ -1225,11 +1225,18 @@ func (qre *QueryExecutor) getUDFs(callback func(schemaRes *querypb.GetSchemaResp defer conn.Recycle() return qre.execStreamSQL(conn, false /* isTransaction */, query, func(result *sqltypes.Result) error { - schemaDef := make(map[string]string) + var udfs []*querypb.UDFInfo for _, row := range result.Rows { - udf := row[0].ToString() - schemaDef[udf] = row[1].ToString() + aggr := strings.EqualFold(row[2].ToString(), "aggregate") + udf := &querypb.UDFInfo{ + Name: row[0].ToString(), + Aggregating: aggr, + ReturnType: sqlparser.SQLTypeToQueryType(row[1].ToString(), false), + } + udfs = append(udfs, udf) } - return callback(&querypb.GetSchemaResponse{TableDefinition: schemaDef}) + return callback(&querypb.GetSchemaResponse{ + Udfs: udfs, + }) }) } diff --git a/go/vt/vttablet/tabletserver/schema/db.go b/go/vt/vttablet/tabletserver/schema/db.go index 4fa7062ebca..7b328c518d2 100644 --- a/go/vt/vttablet/tabletserver/schema/db.go +++ b/go/vt/vttablet/tabletserver/schema/db.go @@ -113,7 +113,7 @@ LIMIT 1 SELECT f.name, i.UDF_RETURN_TYPE, f.type FROM mysql.func f left join performance_schema.user_defined_functions i on f.name = i.udf_name ` // fetchAggregateUdfs queries fetches all the aggregate user defined functions. - fetchAggregateUdfs = `select function_name, function_return_type from %s.udfs where function_type = 'aggregate'` + fetchAggregateUdfs = `select function_name, function_return_type, function_type from %s.udfs` ) // reloadTablesDataInDB reloads teh tables information we have stored in our database we use for schema-tracking. diff --git a/proto/query.proto b/proto/query.proto index 696dadd6ffe..d4e99af7c7d 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -71,7 +71,7 @@ message EventToken { // Flags sent from the MySQL C API enum MySqlFlag { option allow_alias = true; - + EMPTY = 0; NOT_NULL_FLAG = 1; PRI_KEY_FLAG = 2; @@ -277,7 +277,7 @@ message ExecuteOptions { // query timeouts are shorter. // OLAP: DMLS not allowed, no limit on row count, timeouts // can be as high as desired. - // DBA: no limit on rowcount or timeout, all queries allowed + // DBA: no limit on rowcount or timeout, all queries allowed // but intended for long DMLs and DDLs. Workload workload = 6; @@ -317,8 +317,8 @@ message ExecuteOptions { Gen4CompareV3 = 6; V3Insert = 7; } - - // PlannerVersion specifies which planner to use. + + // PlannerVersion specifies which planner to use. // If DEFAULT is chosen, whatever vtgate was started with will be used PlannerVersion planner_version = 11; @@ -992,7 +992,7 @@ enum SchemaTableType { VIEWS = 0; TABLES = 1; ALL = 2; - UDF_AGGREGATE = 3; + UDFS = 3; } // GetSchemaRequest is the payload to GetSchema @@ -1002,8 +1002,16 @@ message GetSchemaRequest { repeated string table_names = 3; } +// UDFInfo represents the information about a UDF. +message UDFInfo { + string name = 1; + bool aggregating = 2; + Type return_type = 3; +} + // GetSchemaResponse is the returned value from GetSchema message GetSchemaResponse { - // this is for the schema definition for the requested tables. + repeated UDFInfo udfs = 1; + // this is for the schema definition for the requested tables and views. map table_definition = 2; -} \ No newline at end of file +} diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 480b1a7be91..9ef0ce1dd76 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -41782,7 +41782,7 @@ export namespace query { VIEWS = 0, TABLES = 1, ALL = 2, - UDF_AGGREGATE = 3 + UDFS = 3 } /** Properties of a GetSchemaRequest. */ @@ -41894,9 +41894,121 @@ export namespace query { public static getTypeUrl(typeUrlPrefix?: string): string; } + /** Properties of a UDFInfo. */ + interface IUDFInfo { + + /** UDFInfo name */ + name?: (string|null); + + /** UDFInfo aggregating */ + aggregating?: (boolean|null); + + /** UDFInfo return_type */ + return_type?: (query.Type|null); + } + + /** Represents a UDFInfo. */ + class UDFInfo implements IUDFInfo { + + /** + * Constructs a new UDFInfo. + * @param [properties] Properties to set + */ + constructor(properties?: query.IUDFInfo); + + /** UDFInfo name. */ + public name: string; + + /** UDFInfo aggregating. */ + public aggregating: boolean; + + /** UDFInfo return_type. */ + public return_type: query.Type; + + /** + * Creates a new UDFInfo instance using the specified properties. + * @param [properties] Properties to set + * @returns UDFInfo instance + */ + public static create(properties?: query.IUDFInfo): query.UDFInfo; + + /** + * Encodes the specified UDFInfo message. Does not implicitly {@link query.UDFInfo.verify|verify} messages. + * @param message UDFInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: query.IUDFInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified UDFInfo message, length delimited. Does not implicitly {@link query.UDFInfo.verify|verify} messages. + * @param message UDFInfo message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: query.IUDFInfo, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a UDFInfo message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns UDFInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): query.UDFInfo; + + /** + * Decodes a UDFInfo message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns UDFInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): query.UDFInfo; + + /** + * Verifies a UDFInfo message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a UDFInfo message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns UDFInfo + */ + public static fromObject(object: { [k: string]: any }): query.UDFInfo; + + /** + * Creates a plain object from a UDFInfo message. Also converts values to other types if specified. + * @param message UDFInfo + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: query.UDFInfo, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this UDFInfo to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + + /** + * Gets the default type url for UDFInfo + * @param [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns The default type url + */ + public static getTypeUrl(typeUrlPrefix?: string): string; + } + /** Properties of a GetSchemaResponse. */ interface IGetSchemaResponse { + /** GetSchemaResponse udfs */ + udfs?: (query.IUDFInfo[]|null); + /** GetSchemaResponse table_definition */ table_definition?: ({ [k: string]: string }|null); } @@ -41910,6 +42022,9 @@ export namespace query { */ constructor(properties?: query.IGetSchemaResponse); + /** GetSchemaResponse udfs. */ + public udfs: query.IUDFInfo[]; + /** GetSchemaResponse table_definition. */ public table_definition: { [k: string]: string }; diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 83e44a04d4d..14d9ac922fc 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -101118,14 +101118,14 @@ export const query = $root.query = (() => { * @property {number} VIEWS=0 VIEWS value * @property {number} TABLES=1 TABLES value * @property {number} ALL=2 ALL value - * @property {number} UDF_AGGREGATE=3 UDF_AGGREGATE value + * @property {number} UDFS=3 UDFS value */ query.SchemaTableType = (function() { const valuesById = {}, values = Object.create(valuesById); values[valuesById[0] = "VIEWS"] = 0; values[valuesById[1] = "TABLES"] = 1; values[valuesById[2] = "ALL"] = 2; - values[valuesById[3] = "UDF_AGGREGATE"] = 3; + values[valuesById[3] = "UDFS"] = 3; return values; })(); @@ -101355,7 +101355,7 @@ export const query = $root.query = (() => { case 2: message.table_type = 2; break; - case "UDF_AGGREGATE": + case "UDFS": case 3: message.table_type = 3; break; @@ -101430,12 +101430,447 @@ export const query = $root.query = (() => { return GetSchemaRequest; })(); + query.UDFInfo = (function() { + + /** + * Properties of a UDFInfo. + * @memberof query + * @interface IUDFInfo + * @property {string|null} [name] UDFInfo name + * @property {boolean|null} [aggregating] UDFInfo aggregating + * @property {query.Type|null} [return_type] UDFInfo return_type + */ + + /** + * Constructs a new UDFInfo. + * @memberof query + * @classdesc Represents a UDFInfo. + * @implements IUDFInfo + * @constructor + * @param {query.IUDFInfo=} [properties] Properties to set + */ + function UDFInfo(properties) { + if (properties) + for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * UDFInfo name. + * @member {string} name + * @memberof query.UDFInfo + * @instance + */ + UDFInfo.prototype.name = ""; + + /** + * UDFInfo aggregating. + * @member {boolean} aggregating + * @memberof query.UDFInfo + * @instance + */ + UDFInfo.prototype.aggregating = false; + + /** + * UDFInfo return_type. + * @member {query.Type} return_type + * @memberof query.UDFInfo + * @instance + */ + UDFInfo.prototype.return_type = 0; + + /** + * Creates a new UDFInfo instance using the specified properties. + * @function create + * @memberof query.UDFInfo + * @static + * @param {query.IUDFInfo=} [properties] Properties to set + * @returns {query.UDFInfo} UDFInfo instance + */ + UDFInfo.create = function create(properties) { + return new UDFInfo(properties); + }; + + /** + * Encodes the specified UDFInfo message. Does not implicitly {@link query.UDFInfo.verify|verify} messages. + * @function encode + * @memberof query.UDFInfo + * @static + * @param {query.IUDFInfo} message UDFInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UDFInfo.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, "name")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); + if (message.aggregating != null && Object.hasOwnProperty.call(message, "aggregating")) + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.aggregating); + if (message.return_type != null && Object.hasOwnProperty.call(message, "return_type")) + writer.uint32(/* id 3, wireType 0 =*/24).int32(message.return_type); + return writer; + }; + + /** + * Encodes the specified UDFInfo message, length delimited. Does not implicitly {@link query.UDFInfo.verify|verify} messages. + * @function encodeDelimited + * @memberof query.UDFInfo + * @static + * @param {query.IUDFInfo} message UDFInfo message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + UDFInfo.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a UDFInfo message from the specified reader or buffer. + * @function decode + * @memberof query.UDFInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {query.UDFInfo} UDFInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UDFInfo.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + let end = length === undefined ? reader.len : reader.pos + length, message = new $root.query.UDFInfo(); + while (reader.pos < end) { + let tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + message.name = reader.string(); + break; + } + case 2: { + message.aggregating = reader.bool(); + break; + } + case 3: { + message.return_type = reader.int32(); + break; + } + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a UDFInfo message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof query.UDFInfo + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {query.UDFInfo} UDFInfo + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + UDFInfo.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a UDFInfo message. + * @function verify + * @memberof query.UDFInfo + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + UDFInfo.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.name != null && message.hasOwnProperty("name")) + if (!$util.isString(message.name)) + return "name: string expected"; + if (message.aggregating != null && message.hasOwnProperty("aggregating")) + if (typeof message.aggregating !== "boolean") + return "aggregating: boolean expected"; + if (message.return_type != null && message.hasOwnProperty("return_type")) + switch (message.return_type) { + default: + return "return_type: enum value expected"; + case 0: + case 257: + case 770: + case 259: + case 772: + case 261: + case 774: + case 263: + case 776: + case 265: + case 778: + case 1035: + case 1036: + case 2061: + case 2062: + case 2063: + case 2064: + case 785: + case 18: + case 6163: + case 10260: + case 6165: + case 10262: + case 6167: + case 10264: + case 2073: + case 2074: + case 2075: + case 28: + case 2077: + case 2078: + case 31: + case 4128: + case 4129: + case 4130: + break; + } + return null; + }; + + /** + * Creates a UDFInfo message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof query.UDFInfo + * @static + * @param {Object.} object Plain object + * @returns {query.UDFInfo} UDFInfo + */ + UDFInfo.fromObject = function fromObject(object) { + if (object instanceof $root.query.UDFInfo) + return object; + let message = new $root.query.UDFInfo(); + if (object.name != null) + message.name = String(object.name); + if (object.aggregating != null) + message.aggregating = Boolean(object.aggregating); + switch (object.return_type) { + default: + if (typeof object.return_type === "number") { + message.return_type = object.return_type; + break; + } + break; + case "NULL_TYPE": + case 0: + message.return_type = 0; + break; + case "INT8": + case 257: + message.return_type = 257; + break; + case "UINT8": + case 770: + message.return_type = 770; + break; + case "INT16": + case 259: + message.return_type = 259; + break; + case "UINT16": + case 772: + message.return_type = 772; + break; + case "INT24": + case 261: + message.return_type = 261; + break; + case "UINT24": + case 774: + message.return_type = 774; + break; + case "INT32": + case 263: + message.return_type = 263; + break; + case "UINT32": + case 776: + message.return_type = 776; + break; + case "INT64": + case 265: + message.return_type = 265; + break; + case "UINT64": + case 778: + message.return_type = 778; + break; + case "FLOAT32": + case 1035: + message.return_type = 1035; + break; + case "FLOAT64": + case 1036: + message.return_type = 1036; + break; + case "TIMESTAMP": + case 2061: + message.return_type = 2061; + break; + case "DATE": + case 2062: + message.return_type = 2062; + break; + case "TIME": + case 2063: + message.return_type = 2063; + break; + case "DATETIME": + case 2064: + message.return_type = 2064; + break; + case "YEAR": + case 785: + message.return_type = 785; + break; + case "DECIMAL": + case 18: + message.return_type = 18; + break; + case "TEXT": + case 6163: + message.return_type = 6163; + break; + case "BLOB": + case 10260: + message.return_type = 10260; + break; + case "VARCHAR": + case 6165: + message.return_type = 6165; + break; + case "VARBINARY": + case 10262: + message.return_type = 10262; + break; + case "CHAR": + case 6167: + message.return_type = 6167; + break; + case "BINARY": + case 10264: + message.return_type = 10264; + break; + case "BIT": + case 2073: + message.return_type = 2073; + break; + case "ENUM": + case 2074: + message.return_type = 2074; + break; + case "SET": + case 2075: + message.return_type = 2075; + break; + case "TUPLE": + case 28: + message.return_type = 28; + break; + case "GEOMETRY": + case 2077: + message.return_type = 2077; + break; + case "JSON": + case 2078: + message.return_type = 2078; + break; + case "EXPRESSION": + case 31: + message.return_type = 31; + break; + case "HEXNUM": + case 4128: + message.return_type = 4128; + break; + case "HEXVAL": + case 4129: + message.return_type = 4129; + break; + case "BITNUM": + case 4130: + message.return_type = 4130; + break; + } + return message; + }; + + /** + * Creates a plain object from a UDFInfo message. Also converts values to other types if specified. + * @function toObject + * @memberof query.UDFInfo + * @static + * @param {query.UDFInfo} message UDFInfo + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + UDFInfo.toObject = function toObject(message, options) { + if (!options) + options = {}; + let object = {}; + if (options.defaults) { + object.name = ""; + object.aggregating = false; + object.return_type = options.enums === String ? "NULL_TYPE" : 0; + } + if (message.name != null && message.hasOwnProperty("name")) + object.name = message.name; + if (message.aggregating != null && message.hasOwnProperty("aggregating")) + object.aggregating = message.aggregating; + if (message.return_type != null && message.hasOwnProperty("return_type")) + object.return_type = options.enums === String ? $root.query.Type[message.return_type] === undefined ? message.return_type : $root.query.Type[message.return_type] : message.return_type; + return object; + }; + + /** + * Converts this UDFInfo to JSON. + * @function toJSON + * @memberof query.UDFInfo + * @instance + * @returns {Object.} JSON object + */ + UDFInfo.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + /** + * Gets the default type url for UDFInfo + * @function getTypeUrl + * @memberof query.UDFInfo + * @static + * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default "type.googleapis.com") + * @returns {string} The default type url + */ + UDFInfo.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = "type.googleapis.com"; + } + return typeUrlPrefix + "/query.UDFInfo"; + }; + + return UDFInfo; + })(); + query.GetSchemaResponse = (function() { /** * Properties of a GetSchemaResponse. * @memberof query * @interface IGetSchemaResponse + * @property {Array.|null} [udfs] GetSchemaResponse udfs * @property {Object.|null} [table_definition] GetSchemaResponse table_definition */ @@ -101448,6 +101883,7 @@ export const query = $root.query = (() => { * @param {query.IGetSchemaResponse=} [properties] Properties to set */ function GetSchemaResponse(properties) { + this.udfs = []; this.table_definition = {}; if (properties) for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) @@ -101455,6 +101891,14 @@ export const query = $root.query = (() => { this[keys[i]] = properties[keys[i]]; } + /** + * GetSchemaResponse udfs. + * @member {Array.} udfs + * @memberof query.GetSchemaResponse + * @instance + */ + GetSchemaResponse.prototype.udfs = $util.emptyArray; + /** * GetSchemaResponse table_definition. * @member {Object.} table_definition @@ -101487,6 +101931,9 @@ export const query = $root.query = (() => { GetSchemaResponse.encode = function encode(message, writer) { if (!writer) writer = $Writer.create(); + if (message.udfs != null && message.udfs.length) + for (let i = 0; i < message.udfs.length; ++i) + $root.query.UDFInfo.encode(message.udfs[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); if (message.table_definition != null && Object.hasOwnProperty.call(message, "table_definition")) for (let keys = Object.keys(message.table_definition), i = 0; i < keys.length; ++i) writer.uint32(/* id 2, wireType 2 =*/18).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.table_definition[keys[i]]).ldelim(); @@ -101524,6 +101971,12 @@ export const query = $root.query = (() => { while (reader.pos < end) { let tag = reader.uint32(); switch (tag >>> 3) { + case 1: { + if (!(message.udfs && message.udfs.length)) + message.udfs = []; + message.udfs.push($root.query.UDFInfo.decode(reader, reader.uint32())); + break; + } case 2: { if (message.table_definition === $util.emptyObject) message.table_definition = {}; @@ -101582,6 +102035,15 @@ export const query = $root.query = (() => { GetSchemaResponse.verify = function verify(message) { if (typeof message !== "object" || message === null) return "object expected"; + if (message.udfs != null && message.hasOwnProperty("udfs")) { + if (!Array.isArray(message.udfs)) + return "udfs: array expected"; + for (let i = 0; i < message.udfs.length; ++i) { + let error = $root.query.UDFInfo.verify(message.udfs[i]); + if (error) + return "udfs." + error; + } + } if (message.table_definition != null && message.hasOwnProperty("table_definition")) { if (!$util.isObject(message.table_definition)) return "table_definition: object expected"; @@ -101605,6 +102067,16 @@ export const query = $root.query = (() => { if (object instanceof $root.query.GetSchemaResponse) return object; let message = new $root.query.GetSchemaResponse(); + if (object.udfs) { + if (!Array.isArray(object.udfs)) + throw TypeError(".query.GetSchemaResponse.udfs: array expected"); + message.udfs = []; + for (let i = 0; i < object.udfs.length; ++i) { + if (typeof object.udfs[i] !== "object") + throw TypeError(".query.GetSchemaResponse.udfs: object expected"); + message.udfs[i] = $root.query.UDFInfo.fromObject(object.udfs[i]); + } + } if (object.table_definition) { if (typeof object.table_definition !== "object") throw TypeError(".query.GetSchemaResponse.table_definition: object expected"); @@ -101628,8 +102100,15 @@ export const query = $root.query = (() => { if (!options) options = {}; let object = {}; + if (options.arrays || options.defaults) + object.udfs = []; if (options.objects || options.defaults) object.table_definition = {}; + if (message.udfs && message.udfs.length) { + object.udfs = []; + for (let j = 0; j < message.udfs.length; ++j) + object.udfs[j] = $root.query.UDFInfo.toObject(message.udfs[j], options); + } let keys2; if (message.table_definition && (keys2 = Object.keys(message.table_definition)).length) { object.table_definition = {};