diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt index 5a1e4000fea..1c57dd0c08e 100644 --- a/go/flags/endtoend/vtcombo.txt +++ b/go/flags/endtoend/vtcombo.txt @@ -22,15 +22,7 @@ Flags: --backup_storage_number_blocks int if backup_storage_compress is true, backup_storage_number_blocks sets the number of blocks that can be processed, in parallel, before the writer blocks, during compression (default is 2). It should be equal to the number of CPUs available for compression. (default 2) --bind-address string Bind address for the server. If empty, the server will listen on all available unicast and anycast IP addresses of the local system. --binlog-in-memory-decompressor-max-size uint This value sets the uncompressed transaction payload size at which we switch from in-memory buffer based decompression to the slower streaming mode. (default 134217728) - --binlog_host string PITR restore parameter: hostname/IP of binlog server. - --binlog_password string PITR restore parameter: password of binlog server. --binlog_player_protocol string the protocol to download binlogs from a vttablet (default "grpc") - --binlog_port int PITR restore parameter: port of binlog server. - --binlog_ssl_ca string PITR restore parameter: Filename containing TLS CA certificate to verify binlog server TLS certificate against. - --binlog_ssl_cert string PITR restore parameter: Filename containing mTLS client certificate to present to binlog server as authentication. - --binlog_ssl_key string PITR restore parameter: Filename containing mTLS client private key for use in binlog server authentication. - --binlog_ssl_server_name string PITR restore parameter: TLS server name (common name) to verify against for the binlog server we are connecting to (If not set: use the hostname or IP supplied in --binlog_host). - --binlog_user string PITR restore parameter: username of binlog server. --buffer_drain_concurrency int Maximum number of requests retried simultaneously. More concurrency will increase the load on the PRIMARY vttablet when draining the buffer. (default 1) --buffer_keyspace_shards string If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable_buffer=true. --buffer_max_failover_duration duration Stop buffering completely if a failover takes longer than this duration. (default 20s) @@ -261,7 +253,6 @@ Flags: --onclose_timeout duration wait no more than this for OnClose handlers before stopping (default 10s) --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --pid_file string If set, the process will write its pid to the named file, and delete it on graceful shutdown. - --pitr_gtid_lookup_timeout duration PITR restore parameter: timeout for fetching gtid from timestamp. (default 1m0s) --planner-version string Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right --pool_hostname_resolve_interval duration if set force an update to all hostnames and reconnect if changed, defaults to 0 (disabled) --port int port for the server diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt index 132c2d06344..48776d0e8e0 100644 --- a/go/flags/endtoend/vttablet.txt +++ b/go/flags/endtoend/vttablet.txt @@ -57,20 +57,12 @@ Flags: --backup_storage_number_blocks int if backup_storage_compress is true, backup_storage_number_blocks sets the number of blocks that can be processed, in parallel, before the writer blocks, during compression (default is 2). It should be equal to the number of CPUs available for compression. (default 2) --bind-address string Bind address for the server. If empty, the server will listen on all available unicast and anycast IP addresses of the local system. --binlog-in-memory-decompressor-max-size uint This value sets the uncompressed transaction payload size at which we switch from in-memory buffer based decompression to the slower streaming mode. (default 134217728) - --binlog_host string PITR restore parameter: hostname/IP of binlog server. - --binlog_password string PITR restore parameter: password of binlog server. --binlog_player_grpc_ca string the server ca to use to validate servers when connecting --binlog_player_grpc_cert string the cert to use to connect --binlog_player_grpc_crl string the server crl to use to validate server certificates when connecting --binlog_player_grpc_key string the key to use to connect --binlog_player_grpc_server_name string the server name to use to validate server certificate --binlog_player_protocol string the protocol to download binlogs from a vttablet (default "grpc") - --binlog_port int PITR restore parameter: port of binlog server. - --binlog_ssl_ca string PITR restore parameter: Filename containing TLS CA certificate to verify binlog server TLS certificate against. - --binlog_ssl_cert string PITR restore parameter: Filename containing mTLS client certificate to present to binlog server as authentication. - --binlog_ssl_key string PITR restore parameter: Filename containing mTLS client private key for use in binlog server authentication. - --binlog_ssl_server_name string PITR restore parameter: TLS server name (common name) to verify against for the binlog server we are connecting to (If not set: use the hostname or IP supplied in --binlog_host). - --binlog_user string PITR restore parameter: username of binlog server. --builtinbackup-file-read-buffer-size uint read files using an IO buffer of this many bytes. Golang defaults are used when set to 0. --builtinbackup-file-write-buffer-size uint write files using an IO buffer of this many bytes. Golang defaults are used when set to 0. (default 2097152) --builtinbackup-incremental-restore-path string the directory where incremental restore files, namely binlog files, are extracted to. In k8s environments, this should be set to a directory that is shared between the vttablet and mysqld pods. The path should exist. When empty, the default OS temp dir is assumed. @@ -259,7 +251,6 @@ Flags: --onterm_timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s) --opentsdb_uri string URI of opentsdb /api/put method --pid_file string If set, the process will write its pid to the named file, and delete it on graceful shutdown. - --pitr_gtid_lookup_timeout duration PITR restore parameter: timeout for fetching gtid from timestamp. (default 1m0s) --pool_hostname_resolve_interval duration if set force an update to all hostnames and reconnect if changed, defaults to 0 (disabled) --port int port for the server --pprof strings enable profiling diff --git a/go/mysql/conn.go b/go/mysql/conn.go index d4f870e660f..7eedc094c1e 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -399,7 +399,7 @@ func (c *Conn) readHeaderFrom(r io.Reader) (int, error) { return 0, vterrors.Wrapf(err, "io.ReadFull(header size) failed") } - sequence := uint8(c.header[3]) + sequence := c.header[3] if sequence != c.sequence { return 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "invalid sequence, expected %v got %v", c.sequence, sequence) } diff --git a/go/mysql/flavor_filepos.go b/go/mysql/flavor_filepos.go index 03d745468be..43278c9a0c4 100644 --- a/go/mysql/flavor_filepos.go +++ b/go/mysql/flavor_filepos.go @@ -84,7 +84,7 @@ func (flv *filePosFlavor) gtidMode(c *Conn) (string, error) { // serverUUID is part of the Flavor interface. func (flv *filePosFlavor) serverUUID(c *Conn) (string, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.server_uuid", 1, false) if err != nil { return "", err diff --git a/go/mysql/flavor_mysql.go b/go/mysql/flavor_mysql.go index b109e5ca385..e405dc401ec 100644 --- a/go/mysql/flavor_mysql.go +++ b/go/mysql/flavor_mysql.go @@ -60,7 +60,7 @@ var _ flavor = (*mysqlFlavor82)(nil) // primaryGTIDSet is part of the Flavor interface. func (mysqlFlavor) primaryGTIDSet(c *Conn) (replication.GTIDSet, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.gtid_executed", 1, false) if err != nil { return nil, err @@ -73,7 +73,7 @@ func (mysqlFlavor) primaryGTIDSet(c *Conn) (replication.GTIDSet, error) { // purgedGTIDSet is part of the Flavor interface. func (mysqlFlavor) purgedGTIDSet(c *Conn) (replication.GTIDSet, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.gtid_purged", 1, false) if err != nil { return nil, err @@ -86,7 +86,7 @@ func (mysqlFlavor) purgedGTIDSet(c *Conn) (replication.GTIDSet, error) { // serverUUID is part of the Flavor interface. func (mysqlFlavor) serverUUID(c *Conn) (string, error) { - // keep @@global as lowercase, as some servers like the Ripple binlog server only honors a lowercase `global` value + // keep @@global as lowercase, as some servers like a binlog server only honors a lowercase `global` value qr, err := c.ExecuteFetch("SELECT @@global.server_uuid", 1, false) if err != nil { return "", err diff --git a/go/mysql/query.go b/go/mysql/query.go index 26582cecbd9..720a533a772 100644 --- a/go/mysql/query.go +++ b/go/mysql/query.go @@ -404,6 +404,7 @@ func (c *Conn) ReadQueryResult(maxrows int, wantfields bool) (*sqltypes.Result, return &sqltypes.Result{ RowsAffected: packetOk.affectedRows, InsertID: packetOk.lastInsertID, + InsertIDChanged: packetOk.lastInsertID > 0, SessionStateChanges: packetOk.sessionStateData, StatusFlags: packetOk.statusFlags, Info: packetOk.info, diff --git a/go/mysql/query_test.go b/go/mysql/query_test.go index 6892508ac0c..01cbd6a8f30 100644 --- a/go/mysql/query_test.go +++ b/go/mysql/query_test.go @@ -22,17 +22,13 @@ import ( "sync" "testing" - "google.golang.org/protobuf/proto" - - "vitess.io/vitess/go/mysql/sqlerror" - - "vitess.io/vitess/go/mysql/collations" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "vitess.io/vitess/go/mysql/collations" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" ) @@ -393,8 +389,9 @@ func TestQueries(t *testing.T) { // Typical Insert result checkQuery(t, "insert", sConn, cConn, &sqltypes.Result{ - RowsAffected: 0x8010203040506070, - InsertID: 0x0102030405060708, + RowsAffected: 0x8010203040506070, + InsertID: 0x0102030405060708, + InsertIDChanged: true, }) // Typical Select with TYPE_AND_NAME. @@ -702,6 +699,7 @@ func checkQueryInternal(t *testing.T, query string, sConn, cConn *Conn, result * got = &sqltypes.Result{} got.RowsAffected = result.RowsAffected got.InsertID = result.InsertID + got.InsertIDChanged = result.InsertIDUpdated() got.Fields, err = cConn.Fields() if err != nil { fatalError = fmt.Sprintf("Fields(%v) failed: %v", query, err) diff --git a/go/sqltypes/proto3.go b/go/sqltypes/proto3.go index 6eaefcf4b0c..0ca03b153cf 100644 --- a/go/sqltypes/proto3.go +++ b/go/sqltypes/proto3.go @@ -103,6 +103,7 @@ func ResultToProto3(qr *Result) *querypb.QueryResult { Fields: qr.Fields, RowsAffected: qr.RowsAffected, InsertId: qr.InsertID, + InsertIdChanged: qr.InsertIDChanged, Rows: RowsToProto3(qr.Rows), Info: qr.Info, SessionStateChanges: qr.SessionStateChanges, @@ -119,6 +120,7 @@ func Proto3ToResult(qr *querypb.QueryResult) *Result { Fields: qr.Fields, RowsAffected: qr.RowsAffected, InsertID: qr.InsertId, + InsertIDChanged: qr.InsertIdChanged, Rows: proto3ToRows(qr.Fields, qr.Rows), Info: qr.Info, SessionStateChanges: qr.SessionStateChanges, @@ -136,6 +138,7 @@ func CustomProto3ToResult(fields []*querypb.Field, qr *querypb.QueryResult) *Res Fields: qr.Fields, RowsAffected: qr.RowsAffected, InsertID: qr.InsertId, + InsertIDChanged: qr.InsertIdChanged, Rows: proto3ToRows(fields, qr.Rows), Info: qr.Info, SessionStateChanges: qr.SessionStateChanges, diff --git a/go/sqltypes/proto3_test.go b/go/sqltypes/proto3_test.go index 5e0bffd2a73..61674b2d1e4 100644 --- a/go/sqltypes/proto3_test.go +++ b/go/sqltypes/proto3_test.go @@ -39,9 +39,10 @@ func TestResult(t *testing.T) { Type: Float64, }} sqlResult := &Result{ - Fields: fields, - InsertID: 1, - RowsAffected: 2, + Fields: fields, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{{ TestValue(VarChar, "aa"), TestValue(Int64, "1"), @@ -53,9 +54,10 @@ func TestResult(t *testing.T) { }}, } p3Result := &querypb.QueryResult{ - Fields: fields, - InsertId: 1, - RowsAffected: 2, + Fields: fields, + InsertId: 1, + InsertIdChanged: true, + RowsAffected: 2, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("aa12"), @@ -105,18 +107,20 @@ func TestResults(t *testing.T) { Type: Float64, }} sqlResults := []Result{{ - Fields: fields1, - InsertID: 1, - RowsAffected: 2, + Fields: fields1, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{{ TestValue(VarChar, "aa"), TestValue(Int64, "1"), TestValue(Float64, "2"), }}, }, { - Fields: fields2, - InsertID: 3, - RowsAffected: 4, + Fields: fields2, + InsertID: 3, + InsertIDChanged: true, + RowsAffected: 4, Rows: [][]Value{{ TestValue(VarChar, "bb"), TestValue(Int64, "3"), @@ -124,17 +128,19 @@ func TestResults(t *testing.T) { }}, }} p3Results := []*querypb.QueryResult{{ - Fields: fields1, - InsertId: 1, - RowsAffected: 2, + Fields: fields1, + InsertId: 1, + InsertIdChanged: true, + RowsAffected: 2, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("aa12"), }}, }, { - Fields: fields2, - InsertId: 3, - RowsAffected: 4, + Fields: fields2, + InsertId: 3, + InsertIdChanged: true, + RowsAffected: 4, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("bb34"), @@ -176,9 +182,10 @@ func TestQueryReponses(t *testing.T) { queryResponses := []QueryResponse{ { QueryResult: &Result{ - Fields: fields1, - InsertID: 1, - RowsAffected: 2, + Fields: fields1, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{{ TestValue(VarChar, "aa"), TestValue(Int64, "1"), @@ -188,9 +195,10 @@ func TestQueryReponses(t *testing.T) { QueryError: nil, }, { QueryResult: &Result{ - Fields: fields2, - InsertID: 3, - RowsAffected: 4, + Fields: fields2, + InsertID: 3, + InsertIDChanged: true, + RowsAffected: 4, Rows: [][]Value{{ TestValue(VarChar, "bb"), TestValue(Int64, "3"), @@ -208,9 +216,10 @@ func TestQueryReponses(t *testing.T) { { Error: nil, Result: &querypb.QueryResult{ - Fields: fields1, - InsertId: 1, - RowsAffected: 2, + Fields: fields1, + InsertId: 1, + InsertIdChanged: true, + RowsAffected: 2, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("aa12"), @@ -219,9 +228,10 @@ func TestQueryReponses(t *testing.T) { }, { Error: nil, Result: &querypb.QueryResult{ - Fields: fields2, - InsertId: 3, - RowsAffected: 4, + Fields: fields2, + InsertId: 3, + InsertIdChanged: true, + RowsAffected: 4, Rows: []*querypb.Row{{ Lengths: []int64{2, 1, 1}, Values: []byte("bb34"), diff --git a/go/sqltypes/result.go b/go/sqltypes/result.go index 389b7fff620..b3cc0fd5573 100644 --- a/go/sqltypes/result.go +++ b/go/sqltypes/result.go @@ -31,6 +31,7 @@ type Result struct { Fields []*querypb.Field `json:"fields"` RowsAffected uint64 `json:"rows_affected"` InsertID uint64 `json:"insert_id"` + InsertIDChanged bool `json:"insert_id_changed"` Rows []Row `json:"rows"` SessionStateChanges string `json:"session_state_changes"` StatusFlags uint16 `json:"status_flags"` @@ -92,6 +93,7 @@ func (result *Result) Copy() *Result { out := &Result{ RowsAffected: result.RowsAffected, InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, SessionStateChanges: result.SessionStateChanges, StatusFlags: result.StatusFlags, Info: result.Info, @@ -116,6 +118,7 @@ func (result *Result) ShallowCopy() *Result { return &Result{ Fields: result.Fields, InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, RowsAffected: result.RowsAffected, Info: result.Info, SessionStateChanges: result.SessionStateChanges, @@ -129,6 +132,7 @@ func (result *Result) Metadata() *Result { return &Result{ Fields: result.Fields, InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, RowsAffected: result.RowsAffected, Info: result.Info, SessionStateChanges: result.SessionStateChanges, @@ -153,6 +157,7 @@ func (result *Result) Truncate(l int) *Result { out := &Result{ InsertID: result.InsertID, + InsertIDChanged: result.InsertIDChanged, RowsAffected: result.RowsAffected, Info: result.Info, SessionStateChanges: result.SessionStateChanges, @@ -198,6 +203,7 @@ func (result *Result) Equal(other *Result) bool { return FieldsEqual(result.Fields, other.Fields) && result.RowsAffected == other.RowsAffected && result.InsertID == other.InsertID && + result.InsertIDChanged == other.InsertIDChanged && slices.EqualFunc(result.Rows, other.Rows, func(a, b Row) bool { return RowEqual(a, b) }) @@ -324,15 +330,13 @@ func (result *Result) StripMetadata(incl querypb.ExecuteOptions_IncludedFields) // to another result.Note currently it doesn't handle cases like // if two results have different fields.We will enhance this function. func (result *Result) AppendResult(src *Result) { - if src.RowsAffected == 0 && len(src.Rows) == 0 && len(src.Fields) == 0 { - return - } - if result.Fields == nil { - result.Fields = src.Fields - } result.RowsAffected += src.RowsAffected - if src.InsertID != 0 { + if src.InsertIDUpdated() { result.InsertID = src.InsertID + result.InsertIDChanged = true + } + if len(result.Fields) == 0 { + result.Fields = src.Fields } result.Rows = append(result.Rows, src.Rows...) } @@ -351,3 +355,7 @@ func (result *Result) IsMoreResultsExists() bool { func (result *Result) IsInTransaction() bool { return result.StatusFlags&ServerStatusInTrans == ServerStatusInTrans } + +func (result *Result) InsertIDUpdated() bool { + return result.InsertIDChanged || result.InsertID > 0 +} diff --git a/go/sqltypes/result_test.go b/go/sqltypes/result_test.go index d8075ec0633..c358497baf3 100644 --- a/go/sqltypes/result_test.go +++ b/go/sqltypes/result_test.go @@ -21,11 +21,17 @@ import ( "github.com/stretchr/testify/assert" - "vitess.io/vitess/go/test/utils" - querypb "vitess.io/vitess/go/vt/proto/query" ) +func assertEqualResults(t *testing.T, a, b *Result) { + t.Helper() + assert.Truef(t, a.Equal(b), "Results are not equal: \n%v\n%v", a, b) + if !a.Equal(b) { + t.Errorf("Results are not equal: %v %v", a, b) + } +} + func TestRepair(t *testing.T) { fields := []*querypb.Field{{ Type: Int64, @@ -45,9 +51,7 @@ func TestRepair(t *testing.T) { }, } in.Repair(fields) - if !in.Equal(want) { - t.Errorf("Repair:\n%#v, want\n%#v", in, want) - } + assertEqualResults(t, in, want) } func TestCopy(t *testing.T) { @@ -57,8 +61,9 @@ func TestCopy(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 2, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, @@ -66,7 +71,7 @@ func TestCopy(t *testing.T) { }, } out := in.Copy() - utils.MustMatch(t, in, out) + assertEqualResults(t, in, out) } func TestTruncate(t *testing.T) { @@ -76,8 +81,9 @@ func TestTruncate(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 2, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, @@ -86,26 +92,23 @@ func TestTruncate(t *testing.T) { } out := in.Truncate(0) - if !out.Equal(in) { - t.Errorf("Truncate(0):\n%v, want\n%v", out, in) - } + assertEqualResults(t, in, out) out = in.Truncate(1) want := &Result{ Fields: []*querypb.Field{{ Type: Int64, }}, - InsertID: 1, - RowsAffected: 2, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "1")}, {TestValue(Int64, "2")}, {TestValue(Int64, "3")}, }, } - if !out.Equal(want) { - t.Errorf("Truncate(1):\n%v, want\n%v", out, want) - } + assertEqualResults(t, out, want) } func TestStripMetaData(t *testing.T) { @@ -283,9 +286,7 @@ func TestStripMetaData(t *testing.T) { t.Run(tcase.name, func(t *testing.T) { inCopy := tcase.in.Copy() out := inCopy.StripMetadata(tcase.includedFields) - if !out.Equal(tcase.expected) { - t.Errorf("StripMetaData unexpected result for %v: %v", tcase.name, out) - } + assertEqualResults(t, out, tcase.expected) if len(tcase.in.Fields) > 0 { // check the out array is different than the in array. if out.Fields[0] == inCopy.Fields[0] && tcase.includedFields != querypb.ExecuteOptions_ALL { @@ -293,7 +294,7 @@ func TestStripMetaData(t *testing.T) { } } // check we didn't change the original result. - utils.MustMatch(t, tcase.in, inCopy) + assertEqualResults(t, tcase.in, inCopy) }) } } @@ -305,8 +306,9 @@ func TestAppendResult(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 2, + InsertIDChanged: true, + InsertID: 1, + RowsAffected: 2, Rows: [][]Value{ {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, {TestValue(Int64, "3"), TestValue(VarChar, "")}, @@ -319,8 +321,9 @@ func TestAppendResult(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 3, - RowsAffected: 4, + InsertID: 3, + InsertIDChanged: true, + RowsAffected: 4, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, }, @@ -332,8 +335,9 @@ func TestAppendResult(t *testing.T) { }, { Type: VarChar, }}, - InsertID: 1, - RowsAffected: 6, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 6, Rows: [][]Value{ {TestValue(Int64, "1"), MakeTrusted(Null, nil)}, {TestValue(Int64, "2"), MakeTrusted(VarChar, nil)}, @@ -342,10 +346,7 @@ func TestAppendResult(t *testing.T) { } result.AppendResult(src) - - if !result.Equal(want) { - t.Errorf("Got:\n%#v, want:\n%#v", result, want) - } + assertEqualResults(t, result, want) } func TestReplaceKeyspace(t *testing.T) { diff --git a/go/test/endtoend/recovery/pitr/binlog_server.go b/go/test/endtoend/recovery/pitr/binlog_server.go deleted file mode 100644 index 3b78b0d4ad7..00000000000 --- a/go/test/endtoend/recovery/pitr/binlog_server.go +++ /dev/null @@ -1,137 +0,0 @@ -/* -Copyright 2020 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package pitr - -import ( - "fmt" - "os" - "os/exec" - "path" - "strings" - "syscall" - "time" - - "vitess.io/vitess/go/vt/log" -) - -const ( - binlogExecutableName = "rippled" - binlogDataDir = "binlog_dir" - binlogUser = "ripple" - binlogPassword = "ripplepassword" - binlogPasswordHash = "D4CDF66E273494CEA9592162BEBB6D62D94C4168" -) - -type binLogServer struct { - hostname string - port int - username string - password string - passwordHash string - dataDirectory string - executablePath string - - proc *exec.Cmd - exit chan error -} - -type mysqlSource struct { - hostname string - port int - username string - password string -} - -// newBinlogServer returns an instance of binlog server -func newBinlogServer(hostname string, port int) (*binLogServer, error) { - dataDir := path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("%s_%d", binlogDataDir, port)) - fmt.Println(dataDir) - if _, err := os.Stat(dataDir); os.IsNotExist(err) { - err := os.Mkdir(dataDir, 0700) - if err != nil { - log.Error(err) - return nil, err - } - } - return &binLogServer{ - executablePath: path.Join(os.Getenv("EXTRA_BIN"), binlogExecutableName), - dataDirectory: dataDir, - username: binlogUser, - password: binlogPassword, - passwordHash: binlogPasswordHash, - hostname: hostname, - port: port, - }, nil -} - -// start starts the binlog server points to running mysql port -func (bs *binLogServer) start(source mysqlSource) error { - bs.proc = exec.Command( - bs.executablePath, - fmt.Sprintf("-ripple_datadir=%s", bs.dataDirectory), - fmt.Sprintf("-ripple_server_password_hash=%s", bs.passwordHash), - fmt.Sprintf("-ripple_master_address=%s", source.hostname), - fmt.Sprintf("-ripple_master_port=%d", source.port), - fmt.Sprintf("-ripple_master_user=%s", source.username), - fmt.Sprintf("-ripple_server_ports=%d", bs.port), - ) - if source.password != "" { - bs.proc.Args = append(bs.proc.Args, fmt.Sprintf("-ripple_master_password=%s", source.password)) - } - - errFile, err := os.Create(path.Join(bs.dataDirectory, "log.txt")) - if err != nil { - log.Errorf("cannot create error log file for binlog server: %v", err) - return err - } - bs.proc.Stderr = errFile - - bs.proc.Env = append(bs.proc.Env, os.Environ()...) - - log.Infof("Running binlog server with command: %v", strings.Join(bs.proc.Args, " ")) - - err = bs.proc.Start() - if err != nil { - return err - } - bs.exit = make(chan error) - go func() { - if bs.proc != nil { - bs.exit <- bs.proc.Wait() - } - }() - return nil -} - -func (bs *binLogServer) stop() error { - if bs.proc == nil || bs.exit == nil { - return nil - } - // Attempt graceful shutdown with SIGTERM first - bs.proc.Process.Signal(syscall.SIGTERM) - - select { - case err := <-bs.exit: - bs.proc = nil - return err - - case <-time.After(10 * time.Second): - bs.proc.Process.Kill() - bs.proc = nil - return <-bs.exit - } -} diff --git a/go/test/endtoend/recovery/pitr/shardedpitr_test.go b/go/test/endtoend/recovery/pitr/shardedpitr_test.go deleted file mode 100644 index 3bb2399737e..00000000000 --- a/go/test/endtoend/recovery/pitr/shardedpitr_test.go +++ /dev/null @@ -1,602 +0,0 @@ -/* -Copyright 2020 The Vitess Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package pitr - -import ( - "context" - "fmt" - "os" - "os/exec" - "path" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/constants/sidecar" - "vitess.io/vitess/go/json2" - "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/test/endtoend/cluster" - "vitess.io/vitess/go/test/endtoend/utils" - "vitess.io/vitess/go/vt/log" - - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" -) - -var ( - createTable = `create table product (id bigint(20) primary key, name char(10), created bigint(20));` - insertTable = `insert into product (id, name, created) values(%d, '%s', unix_timestamp());` - getCountID = `select count(*) from product` -) - -var ( - clusterInstance *cluster.LocalProcessCluster - - primary *cluster.Vttablet - replica1 *cluster.Vttablet - replica2 *cluster.Vttablet - shard0Primary *cluster.Vttablet - shard0Replica1 *cluster.Vttablet - shard0Replica2 *cluster.Vttablet - shard1Primary *cluster.Vttablet - shard1Replica1 *cluster.Vttablet - shard1Replica2 *cluster.Vttablet - - cell = "zone1" - hostname = "localhost" - binlogHost = "127.0.0.1" - keyspaceName = "ks" - restoreKS1Name = "restoreks1" - restoreKS2Name = "restoreks2" - restoreKS3Name = "restoreks3" - shardName = "0" - shard0Name = "-80" - shard1Name = "80-" - dbName = "vt_ks" - mysqlUserName = "vt_dba" - mysqlPassword = "VtDbaPass" - dbCredentialFile = "" - initDBFileWithPassword = "" - vSchema = `{ - "sharded": true, - "vindexes": { - "hash_index": { - "type": "hash" - } - }, - "tables": { - "product": { - "column_vindexes": [ - { - "column": "id", - "name": "hash_index" - } - ] - } - } - }` - commonTabletArg = []string{ - "--vreplication_retry_delay", "1s", - "--degraded_threshold", "5s", - "--lock_tables_timeout", "5s", - "--watch_replication_stream", - "--serving_state_grace_period", "1s"} - - defaultTimeout = 30 * time.Second - defaultTick = 1 * time.Second -) - -// Test pitr (Point in time recovery). -// ------------------------------------------- -// The following test will: -// - create a shard with primary and replica -// - run InitShardPrimary -// - point binlog server to primary -// - insert some data using vtgate (e.g. here we have inserted rows 1,2) -// - verify the replication -// - take backup of replica -// - insert some data using vtgate (e.g. we inserted rows 3 4 5 6), while inserting row-4, note down the time (restoreTime1) -// - perform a resharding to create 2 shards (-80, 80-), and delete the old shard -// - point binlog server to primary of both shards -// - insert some data using vtgate (e.g. we will insert 7 8 9 10) and verify we get required number of rows in -80, 80- shard -// - take backup of both shards -// - insert some more data using vtgate (e.g. we will insert 11 12 13 14 15), while inserting row-13, note down the time (restoreTime2) -// - note down the current time (restoreTime3) - -// - Till now we did all the presetup for assertions - -// - asserting that restoring to restoreTime1 (going from 2 shards to 1 shard) is working, i.e. we should get 4 rows. -// - asserting that while restoring if we give small timeout value, it will restore upto to the last available backup (asserting only -80 shard) -// - asserting that restoring to restoreTime2 (going from 2 shards to 2 shards with past time) is working, it will assert for both shards -// - asserting that restoring to restoreTime3 is working, we should get complete data after restoring, as we have in existing shards. -func TestPITRRecovery(t *testing.T) { - initializeCluster(t) - defer clusterInstance.Teardown() - - // start the binlog server and point it to primary - bs := startBinlogServer(t, primary) - defer bs.stop() - - // Creating the table - _, err := primary.VttabletProcess.QueryTablet(createTable, keyspaceName, true) - require.NoError(t, err) - - insertRow(t, 1, "prd-1", false) - insertRow(t, 2, "prd-2", false) - - cluster.VerifyRowsInTabletForTable(t, replica1, keyspaceName, 2, "product") - - // backup the replica - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Backup", replica1.Alias) - require.NoError(t, err) - - // check that the backup shows up in the listing - output, err := clusterInstance.ListBackups("ks/0") - require.NoError(t, err) - assert.Equal(t, 1, len(output)) - - // now insert some more data to simulate the changes after regular backup - // every insert has some time lag/difference to simulate the time gap between rows - // and when we recover to certain time, this time gap will be able to identify the exact eligible row - var restoreTime1 string - for counter := 3; counter <= 6; counter++ { - if counter == 4 { // we want to recovery till this, so noting the time - tm := time.Now().Add(1 * time.Second).UTC() - restoreTime1 = tm.Format(time.RFC3339) - } - insertRow(t, counter, fmt.Sprintf("prd-%d", counter), true) - } - - // starting resharding process - performResharding(t) - - // start the binlog server and point it to shard0Primary - bs0 := startBinlogServer(t, shard0Primary) - defer bs0.stop() - - // start the binlog server and point it to shard1Primary - bs1 := startBinlogServer(t, shard1Primary) - defer bs1.stop() - - for counter := 7; counter <= 10; counter++ { - insertRow(t, counter, fmt.Sprintf("prd-%d", counter), false) - } - - // wait till all the shards have required data - cluster.VerifyRowsInTabletForTable(t, shard0Replica1, keyspaceName, 6, "product") - cluster.VerifyRowsInTabletForTable(t, shard1Replica1, keyspaceName, 4, "product") - - // take the backup (to simulate the regular backup) - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Backup", shard0Replica1.Alias) - require.NoError(t, err) - // take the backup (to simulate the regular backup) - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Backup", shard1Replica1.Alias) - require.NoError(t, err) - - backups, err := clusterInstance.ListBackups(keyspaceName + "/-80") - require.NoError(t, err) - require.Equal(t, len(backups), 1) - - backups, err = clusterInstance.ListBackups(keyspaceName + "/80-") - require.NoError(t, err) - require.Equal(t, len(backups), 1) - - // now insert some more data to simulate the changes after regular backup - // every insert has some time lag/difference to simulate the time gap between rows - // and when we recover to certain time, this time gap will be able to identify the exact eligible row - var restoreTime2 string - for counter := 11; counter <= 15; counter++ { - if counter == 13 { // we want to recovery till this, so noting the time - tm := time.Now().Add(1 * time.Second).UTC() - restoreTime2 = tm.Format(time.RFC3339) - } - insertRow(t, counter, fmt.Sprintf("prd-%d", counter), true) - } - restoreTime3 := time.Now().UTC().Format(time.RFC3339) - - // creating restore keyspace with snapshot time as restoreTime1 - createRestoreKeyspace(t, restoreTime1, restoreKS1Name) - - // Launching a recovery tablet which recovers data from the primary till the restoreTime1 - testTabletRecovery(t, bs, "2m", restoreKS1Name, "0", "INT64(4)") - - // create restoreKeyspace with snapshot time as restoreTime2 - createRestoreKeyspace(t, restoreTime2, restoreKS2Name) - - // test the recovery with smaller binlog_lookup_timeout for shard0 - // since we have small lookup timeout, it will just get whatever available in the backup - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 1 | prd-1 | 1597219030 | - // | 2 | prd-2 | 1597219030 | - // | 3 | prd-3 | 1597219043 | - // | 5 | prd-5 | 1597219045 | - // | 9 | prd-9 | 1597219130 | - // | 10 | prd-10 | 1597219130 | - // +----+--------+------------+ - testTabletRecovery(t, bs0, "1ms", restoreKS2Name, "-80", "INT64(6)") - - // test the recovery with valid binlog_lookup_timeout for shard0 and getting the data till the restoreTime2 - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 1 | prd-1 | 1597219030 | - // | 2 | prd-2 | 1597219030 | - // | 3 | prd-3 | 1597219043 | - // | 5 | prd-5 | 1597219045 | - // | 9 | prd-9 | 1597219130 | - // | 10 | prd-10 | 1597219130 | - // | 13 | prd-13 | 1597219141 | - // +----+--------+------------+ - testTabletRecovery(t, bs0, "2m", restoreKS2Name, "-80", "INT64(7)") - - // test the recovery with valid binlog_lookup_timeout for shard1 and getting the data till the restoreTime2 - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 4 | prd-4 | 1597219044 | - // | 6 | prd-6 | 1597219046 | - // | 7 | prd-7 | 1597219130 | - // | 8 | prd-8 | 1597219130 | - // | 11 | prd-11 | 1597219139 | - // | 12 | prd-12 | 1597219140 | - // +----+--------+------------+ - testTabletRecovery(t, bs1, "2m", restoreKS2Name, "80-", "INT64(6)") - - // test the recovery with timetorecover > (timestmap of last binlog event in binlog server) - createRestoreKeyspace(t, restoreTime3, restoreKS3Name) - - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 1 | prd-1 | 1597219030 | - // | 2 | prd-2 | 1597219030 | - // | 3 | prd-3 | 1597219043 | - // | 5 | prd-5 | 1597219045 | - // | 9 | prd-9 | 1597219130 | - // | 10 | prd-10 | 1597219130 | - // | 13 | prd-13 | 1597219141 | - // | 15 | prd-15 | 1597219142 | - // +----+--------+------------+ - testTabletRecovery(t, bs0, "2m", restoreKS3Name, "-80", "INT64(8)") - - // mysql> select * from product; - // +----+--------+------------+ - // | id | name | created | - // +----+--------+------------+ - // | 4 | prd-4 | 1597219044 | - // | 6 | prd-6 | 1597219046 | - // | 7 | prd-7 | 1597219130 | - // | 8 | prd-8 | 1597219130 | - // | 11 | prd-11 | 1597219139 | - // | 12 | prd-12 | 1597219140 | - // | 14 | prd-14 | 1597219142 | - // +----+--------+------------+ - testTabletRecovery(t, bs1, "2m", restoreKS3Name, "80-", "INT64(7)") -} - -func performResharding(t *testing.T) { - err := clusterInstance.VtctldClientProcess.ApplyVSchema(keyspaceName, vSchema) - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "create", "--source-shards=0", "--target-shards=-80,80-", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - waitTimeout := 30 * time.Second - shard0Primary.VttabletProcess.WaitForVReplicationToCatchup(t, "ks.reshardWorkflow", dbName, sidecar.DefaultName, waitTimeout) - shard1Primary.VttabletProcess.WaitForVReplicationToCatchup(t, "ks.reshardWorkflow", dbName, sidecar.DefaultName, waitTimeout) - - waitForNoWorkflowLag(t, clusterInstance, "ks", "reshardWorkflow") - - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "SwitchTraffic", "--tablet-types=rdonly", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "SwitchTraffic", "--tablet-types=replica", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - // then serve primary from the split shards - err = clusterInstance.VtctldClientProcess.ExecuteCommand("Reshard", "SwitchTraffic", "--tablet-types=primary", "--target-keyspace", "ks", "--workflow", "reshardWorkflow") - require.NoError(t, err) - - // remove the original tablets in the original shard - removeTablets(t, []*cluster.Vttablet{primary, replica1, replica2}) - - for _, tablet := range []*cluster.Vttablet{replica1, replica2} { - err = clusterInstance.VtctldClientProcess.ExecuteCommand("DeleteTablets", tablet.Alias) - require.NoError(t, err) - } - err = clusterInstance.VtctldClientProcess.ExecuteCommand("DeleteTablets", "--allow-primary", primary.Alias) - require.NoError(t, err) - - // rebuild the serving graph, all mentions of the old shards should be gone - err = clusterInstance.VtctldClientProcess.ExecuteCommand("RebuildKeyspaceGraph", "ks") - require.NoError(t, err) - - // delete the original shard - err = clusterInstance.VtctldClientProcess.ExecuteCommand("DeleteShards", "ks/0") - require.NoError(t, err) - - // Restart vtgate process - err = clusterInstance.VtgateProcess.TearDown() - require.NoError(t, err) - - err = clusterInstance.VtgateProcess.Setup() - require.NoError(t, err) - - clusterInstance.WaitForTabletsToHealthyInVtgate() -} - -func startBinlogServer(t *testing.T, primaryTablet *cluster.Vttablet) *binLogServer { - bs, err := newBinlogServer(hostname, clusterInstance.GetAndReservePort()) - require.NoError(t, err) - - err = bs.start(mysqlSource{ - hostname: binlogHost, - port: primaryTablet.MysqlctlProcess.MySQLPort, - username: mysqlUserName, - password: mysqlPassword, - }) - require.NoError(t, err) - return bs -} - -func removeTablets(t *testing.T, tablets []*cluster.Vttablet) { - var mysqlProcs []*exec.Cmd - for _, tablet := range tablets { - proc, _ := tablet.MysqlctlProcess.StopProcess() - mysqlProcs = append(mysqlProcs, proc) - } - for _, proc := range mysqlProcs { - err := proc.Wait() - require.NoError(t, err) - } - for _, tablet := range tablets { - tablet.VttabletProcess.TearDown() - } -} - -func initializeCluster(t *testing.T) { - clusterInstance = cluster.NewCluster(cell, hostname) - - // Start topo server - err := clusterInstance.StartTopo() - require.NoError(t, err) - - // Start keyspace - keyspace := &cluster.Keyspace{ - Name: keyspaceName, - } - clusterInstance.Keyspaces = append(clusterInstance.Keyspaces, *keyspace) - - shard := &cluster.Shard{ - Name: shardName, - } - shard0 := &cluster.Shard{ - Name: shard0Name, - } - shard1 := &cluster.Shard{ - Name: shard1Name, - } - - // Defining all the tablets - primary = clusterInstance.NewVttabletInstance("replica", 0, "") - replica1 = clusterInstance.NewVttabletInstance("replica", 0, "") - replica2 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard0Primary = clusterInstance.NewVttabletInstance("replica", 0, "") - shard0Replica1 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard0Replica2 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard1Primary = clusterInstance.NewVttabletInstance("replica", 0, "") - shard1Replica1 = clusterInstance.NewVttabletInstance("replica", 0, "") - shard1Replica2 = clusterInstance.NewVttabletInstance("replica", 0, "") - - shard.Vttablets = []*cluster.Vttablet{primary, replica1, replica2} - shard0.Vttablets = []*cluster.Vttablet{shard0Primary, shard0Replica1, shard0Replica2} - shard1.Vttablets = []*cluster.Vttablet{shard1Primary, shard1Replica1, shard1Replica2} - - dbCredentialFile = cluster.WriteDbCredentialToTmp(clusterInstance.TmpDirectory) - extraArgs := []string{"--db-credentials-file", dbCredentialFile} - commonTabletArg = append(commonTabletArg, "--db-credentials-file", dbCredentialFile) - - clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, commonTabletArg...) - clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, "--restore_from_backup") - - err = clusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard, *shard0, *shard1}) - require.NoError(t, err) - vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", clusterInstance.VtctldProcess.GrpcPort, clusterInstance.TmpDirectory) - out, err := vtctldClientProcess.ExecuteCommandWithOutput("SetKeyspaceDurabilityPolicy", keyspaceName, "--durability-policy=semi_sync") - require.NoError(t, err, out) - - initDb, _ := os.ReadFile(path.Join(os.Getenv("VTROOT"), "/config/init_db.sql")) - sql := string(initDb) - // The original init_db.sql does not have any passwords. Here we update the init file with passwords - sql, err = utils.GetInitDBSQL(sql, cluster.GetPasswordUpdateSQL(clusterInstance), "") - require.NoError(t, err, "expected to load init_db file") - initDBFileWithPassword = path.Join(clusterInstance.TmpDirectory, "init_db_with_passwords.sql") - err = os.WriteFile(initDBFileWithPassword, []byte(sql), 0660) - require.NoError(t, err, "expected to load init_db file") - - // Start MySql - var mysqlCtlProcessList []*exec.Cmd - for _, shard := range clusterInstance.Keyspaces[0].Shards { - for _, tablet := range shard.Vttablets { - tablet.MysqlctlProcess.InitDBFile = initDBFileWithPassword - tablet.VttabletProcess.DbPassword = mysqlPassword - tablet.MysqlctlProcess.ExtraArgs = extraArgs - proc, err := tablet.MysqlctlProcess.StartProcess() - require.NoError(t, err) - mysqlCtlProcessList = append(mysqlCtlProcessList, proc) - } - } - - // Wait for mysql processes to start - for _, proc := range mysqlCtlProcessList { - err = proc.Wait() - require.NoError(t, err) - } - - for _, shard := range clusterInstance.Keyspaces[0].Shards { - for _, tablet := range shard.Vttablets { - err = tablet.VttabletProcess.Setup() - require.NoError(t, err) - } - } - - err = clusterInstance.VtctldClientProcess.InitShardPrimary(keyspaceName, shard.Name, cell, primary.TabletUID) - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.InitShardPrimary(keyspaceName, shard0.Name, cell, shard0Primary.TabletUID) - require.NoError(t, err) - - err = clusterInstance.VtctldClientProcess.InitShardPrimary(keyspaceName, shard1.Name, cell, shard1Primary.TabletUID) - require.NoError(t, err) - - err = clusterInstance.StartVTOrc(keyspaceName) - require.NoError(t, err) - - // Start vtgate - err = clusterInstance.StartVtgate() - require.NoError(t, err) -} - -func insertRow(t *testing.T, id int, productName string, isSlow bool) { - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: clusterInstance.Hostname, - Port: clusterInstance.VtgateMySQLPort, - } - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - - insertSmt := fmt.Sprintf(insertTable, id, productName) - _, err = conn.ExecuteFetch(insertSmt, 1000, true) - require.NoError(t, err) - - if isSlow { - time.Sleep(1 * time.Second) - } -} - -func createRestoreKeyspace(t *testing.T, timeToRecover, restoreKeyspaceName string) { - output, err := clusterInstance.VtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", - "--type=SNAPSHOT", "--base-keyspace="+keyspaceName, - "--snapshot-timestamp", timeToRecover, restoreKeyspaceName) - log.Info(output) - require.NoError(t, err) -} - -func testTabletRecovery(t *testing.T, binlogServer *binLogServer, lookupTimeout, restoreKeyspaceName, shardName, expectedRows string) { - recoveryTablet := clusterInstance.NewVttabletInstance("replica", 0, cell) - launchRecoveryTablet(t, recoveryTablet, binlogServer, lookupTimeout, restoreKeyspaceName, shardName) - - sqlRes, err := recoveryTablet.VttabletProcess.QueryTablet(getCountID, keyspaceName, true) - require.NoError(t, err) - assert.Equal(t, expectedRows, sqlRes.Rows[0][0].String()) - - defer recoveryTablet.MysqlctlProcess.Stop() - defer recoveryTablet.VttabletProcess.TearDown() -} - -func launchRecoveryTablet(t *testing.T, tablet *cluster.Vttablet, binlogServer *binLogServer, lookupTimeout, restoreKeyspaceName, shardName string) { - mysqlctlProcess, err := cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, clusterInstance.TmpDirectory) - require.NoError(t, err) - tablet.MysqlctlProcess = *mysqlctlProcess - extraArgs := []string{"--db-credentials-file", dbCredentialFile} - tablet.MysqlctlProcess.InitDBFile = initDBFileWithPassword - tablet.MysqlctlProcess.ExtraArgs = extraArgs - err = tablet.MysqlctlProcess.Start() - require.NoError(t, err) - - tablet.VttabletProcess = cluster.VttabletProcessInstance( - tablet.HTTPPort, - tablet.GrpcPort, - tablet.TabletUID, - clusterInstance.Cell, - shardName, - keyspaceName, - clusterInstance.VtctldProcess.Port, - tablet.Type, - clusterInstance.TopoProcess.Port, - clusterInstance.Hostname, - clusterInstance.TmpDirectory, - clusterInstance.VtTabletExtraArgs, - clusterInstance.DefaultCharset) - tablet.Alias = tablet.VttabletProcess.TabletPath - tablet.VttabletProcess.DbPassword = mysqlPassword - tablet.VttabletProcess.SupportsBackup = true - tablet.VttabletProcess.Keyspace = restoreKeyspaceName - tablet.VttabletProcess.ExtraArgs = []string{ - "--disable_active_reparents", - "--enable_replication_reporter=false", - "--init_db_name_override", dbName, - "--init_tablet_type", "replica", - "--init_keyspace", restoreKeyspaceName, - "--init_shard", shardName, - "--binlog_host", binlogServer.hostname, - "--binlog_port", fmt.Sprintf("%d", binlogServer.port), - "--binlog_user", binlogServer.username, - "--binlog_password", binlogServer.password, - "--pitr_gtid_lookup_timeout", lookupTimeout, - "--vreplication_retry_delay", "1s", - "--degraded_threshold", "5s", - "--lock_tables_timeout", "5s", - "--watch_replication_stream", - "--serving_state_grace_period", "1s", - "--db-credentials-file", dbCredentialFile, - } - tablet.VttabletProcess.ServingStatus = "" - - err = tablet.VttabletProcess.Setup() - require.NoError(t, err) - - tablet.VttabletProcess.WaitForTabletStatusesForTimeout([]string{"SERVING"}, 20*time.Second) -} - -// waitForNoWorkflowLag waits for the VReplication workflow's MaxVReplicationTransactionLag -// value to be 0. -func waitForNoWorkflowLag(t *testing.T, vc *cluster.LocalProcessCluster, ks string, workflow string) { - var lag int64 - timer := time.NewTimer(defaultTimeout) - defer timer.Stop() - for { - output, err := vc.VtctldClientProcess.ExecuteCommandWithOutput("Workflow", "--keyspace", ks, "show", "--workflow", workflow) - require.NoError(t, err) - - var resp vtctldatapb.GetWorkflowsResponse - err = json2.UnmarshalPB([]byte(output), &resp) - require.NoError(t, err) - require.GreaterOrEqual(t, len(resp.Workflows), 1, "responce should have at least one workflow") - lag = resp.Workflows[0].MaxVReplicationTransactionLag - if lag == 0 { - return - } - select { - case <-timer.C: - require.FailNow(t, fmt.Sprintf("workflow %q did not eliminate VReplication lag before the timeout of %s; last seen MaxVReplicationTransactionLag: %d", - strings.Join([]string{ks, workflow}, "."), defaultTimeout, lag)) - default: - time.Sleep(defaultTick) - } - } -} diff --git a/go/test/endtoend/utils/cmp.go b/go/test/endtoend/utils/cmp.go index 7d94c181abd..dd9614e79fa 100644 --- a/go/test/endtoend/utils/cmp.go +++ b/go/test/endtoend/utils/cmp.go @@ -313,3 +313,10 @@ func (mcmp *MySQLCompare) ExecAllowError(query string) (*sqltypes.Result, error) } return vtQr, vtErr } + +func (mcmp *MySQLCompare) VExplain(query string) string { + mcmp.t.Helper() + vtQr, vtErr := mcmp.VtConn.ExecuteFetch("vexplain plan "+query, 1, true) + require.NoError(mcmp.t, vtErr, "[Vitess Error] for query: "+query) + return vtQr.Rows[0][0].ToString() +} diff --git a/go/test/endtoend/vtgate/plan_tests/main_test.go b/go/test/endtoend/vtgate/plan_tests/main_test.go index d3915af0c8d..504ec3ffb26 100644 --- a/go/test/endtoend/vtgate/plan_tests/main_test.go +++ b/go/test/endtoend/vtgate/plan_tests/main_test.go @@ -27,6 +27,7 @@ import ( "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/test/endtoend/cluster" "vitess.io/vitess/go/test/endtoend/utils" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/planbuilder" ) @@ -128,6 +129,31 @@ func start(t *testing.T) (utils.MySQLCompare, func()) { } } +// splitSQL statements - querySQL may be a multi-line sql blob +func splitSQL(querySQL ...string) ([]string, error) { + parser := sqlparser.NewTestParser() + var sqls []string + for _, sql := range querySQL { + split, err := parser.SplitStatementToPieces(sql) + if err != nil { + return nil, err + } + sqls = append(sqls, split...) + } + return sqls, nil +} + +func loadSampleData(t *testing.T, mcmp utils.MySQLCompare) { + sampleDataSQL := readFile("sampledata/user.sql") + insertSQL, err := splitSQL(sampleDataSQL) + if err != nil { + require.NoError(t, err) + } + for _, sql := range insertSQL { + mcmp.ExecNoCompare(sql) + } +} + func readJSONTests(filename string) []planbuilder.PlanTest { var output []planbuilder.PlanTest file, err := os.Open(locateFile(filename)) diff --git a/go/test/endtoend/vtgate/plan_tests/plan_e2e_test.go b/go/test/endtoend/vtgate/plan_tests/plan_e2e_test.go index 1594e9b392c..5c5447fe6b6 100644 --- a/go/test/endtoend/vtgate/plan_tests/plan_e2e_test.go +++ b/go/test/endtoend/vtgate/plan_tests/plan_e2e_test.go @@ -22,21 +22,25 @@ import ( "vitess.io/vitess/go/test/endtoend/utils" ) -func TestSelectCases(t *testing.T) { +func TestE2ECases(t *testing.T) { + e2eTestCaseFiles := []string{"select_cases.json", "filter_cases.json", "dml_cases.json"} mcmp, closer := start(t) defer closer() - tests := readJSONTests("select_cases.json") - for _, test := range tests { - mcmp.Run(test.Comment, func(mcmp *utils.MySQLCompare) { - if test.SkipE2E { - mcmp.AsT().Skip(test.Query) - } - mcmp.Exec(test.Query) - pd := utils.ExecTrace(mcmp.AsT(), mcmp.VtConn, test.Query) - verifyTestExpectations(mcmp.AsT(), pd, test) - if mcmp.VtConn.IsClosed() { - mcmp.AsT().Fatal("vtgate connection is closed") - } - }) + loadSampleData(t, mcmp) + for _, fileName := range e2eTestCaseFiles { + tests := readJSONTests(fileName) + for _, test := range tests { + mcmp.Run(test.Comment, func(mcmp *utils.MySQLCompare) { + if test.SkipE2E { + mcmp.AsT().Skip(test.Query) + } + mcmp.Exec(test.Query) + pd := utils.ExecTrace(mcmp.AsT(), mcmp.VtConn, test.Query) + verifyTestExpectations(mcmp.AsT(), pd, test) + if mcmp.VtConn.IsClosed() { + mcmp.AsT().Fatal("vtgate connection is closed") + } + }) + } } } diff --git a/go/test/endtoend/vtgate/queries/misc/misc_test.go b/go/test/endtoend/vtgate/queries/misc/misc_test.go index 8738baf3267..62b859ab1d3 100644 --- a/go/test/endtoend/vtgate/queries/misc/misc_test.go +++ b/go/test/endtoend/vtgate/queries/misc/misc_test.go @@ -131,6 +131,61 @@ func TestCast(t *testing.T) { mcmp.AssertMatches("select cast('3.2' as unsigned)", `[[UINT64(3)]]`) } +// TestSetAndGetLastInsertID tests that the last_insert_id function works as intended when used with different arguments. +func TestSetAndGetLastInsertID(t *testing.T) { + notZero := 1 + checkQuery := func(i string, workload string, tx bool, mcmp utils.MySQLCompare) { + for _, val := range []int{notZero, 0, notZero * 2} { + query := fmt.Sprintf(i, val) + name := fmt.Sprintf("%s - %s", workload, query) + if tx { + name = "tx - " + name + } + mcmp.Run(name, func(mcmp *utils.MySQLCompare) { + mcmp.Exec(query) + mcmp.Exec("select last_insert_id()") + t := mcmp.AsT() + if t.Failed() { + t.Log(mcmp.VExplain(query)) + } + }) + } + // we need this value to be not zero, and then we keep changing it so different queries don't interact with each other + notZero++ + } + + queries := []string{ + "select last_insert_id(%d)", + "select last_insert_id(%d), id1, id2 from t1 limit 1", + "select last_insert_id(%d), id1, id2 from t1 where 1 = 2", + "select 12 from t1 where last_insert_id(%d)", + "update t1 set id2 = last_insert_id(%d) where id1 = 1", + "update t1 set id2 = last_insert_id(%d) where id1 = 2", + "update t1 set id2 = 88 where id1 = last_insert_id(%d)", + "delete from t1 where id1 = last_insert_id(%d)", + } + + for _, workload := range []string{"olap", "oltp"} { + for _, tx := range []bool{true, false} { + mcmp, closer := start(t) + _, err := mcmp.VtConn.ExecuteFetch(fmt.Sprintf("set workload = %s", workload), 1000, false) + require.NoError(t, err) + if tx { + _, err := mcmp.VtConn.ExecuteFetch("begin", 1000, false) + require.NoError(t, err) + } + + // Insert a row for UPDATE tests + mcmp.Exec("insert into t1 (id1, id2) values (1, 10)") + + for _, query := range queries { + checkQuery(query, workload, tx, mcmp) + } + closer() + } + } +} + // TestVindexHints tests that vindex hints work as intended. func TestVindexHints(t *testing.T) { mcmp, closer := start(t) diff --git a/go/vt/key/key.go b/go/vt/key/key.go index dcdcda47f81..89d956bd433 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -90,6 +90,11 @@ func Empty(id []byte) bool { // KeyRange helper methods // +// Make a Key Range +func NewKeyRange(start []byte, end []byte) *topodatapb.KeyRange { + return &topodatapb.KeyRange{Start: start, End: end} +} + // KeyRangeAdd adds two adjacent KeyRange values (in any order) into a single value. If the values are not adjacent, // it returns false. func KeyRangeAdd(a, b *topodatapb.KeyRange) (*topodatapb.KeyRange, bool) { diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go index 8c4bcb93f47..a03e5fa9025 100644 --- a/go/vt/proto/query/query.pb.go +++ b/go/vt/proto/query/query.pb.go @@ -1397,6 +1397,11 @@ type ExecuteOptions struct { // // *ExecuteOptions_AuthoritativeTimeout Timeout isExecuteOptions_Timeout `protobuf_oneof:"timeout"` + // fetch_last_insert_id indicates that after executing a DML involving last_insert_id(x), + // a subsequent "SELECT last_insert_id()" should be performed to retrieve the updated value. + // This is to circumvent a bug where setting last_insert_id(x) to zero is not signaled by mysql + // https://bugs.mysql.com/bug.php?id=116939 + FetchLastInsertId bool `protobuf:"varint,18,opt,name=fetch_last_insert_id,json=fetchLastInsertId,proto3" json:"fetch_last_insert_id,omitempty"` } func (x *ExecuteOptions) Reset() { @@ -1527,6 +1532,13 @@ func (x *ExecuteOptions) GetAuthoritativeTimeout() int64 { return 0 } +func (x *ExecuteOptions) GetFetchLastInsertId() bool { + if x != nil { + return x.FetchLastInsertId + } + return false +} + type isExecuteOptions_Timeout interface { isExecuteOptions_Timeout() } @@ -1752,6 +1764,7 @@ type QueryResult struct { Rows []*Row `protobuf:"bytes,4,rep,name=rows,proto3" json:"rows,omitempty"` Info string `protobuf:"bytes,6,opt,name=info,proto3" json:"info,omitempty"` SessionStateChanges string `protobuf:"bytes,7,opt,name=session_state_changes,json=sessionStateChanges,proto3" json:"session_state_changes,omitempty"` + InsertIdChanged bool `protobuf:"varint,8,opt,name=insert_id_changed,json=insertIdChanged,proto3" json:"insert_id_changed,omitempty"` } func (x *QueryResult) Reset() { @@ -1826,6 +1839,13 @@ func (x *QueryResult) GetSessionStateChanges() string { return "" } +func (x *QueryResult) GetInsertIdChanged() bool { + if x != nil { + return x.InsertIdChanged + } + return false +} + // QueryWarning is used to convey out of band query execution warnings // by storing in the vtgate.Session type QueryWarning struct { @@ -5855,7 +5875,7 @@ var file_query_proto_rawDesc = []byte{ 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x69, 0x6e, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0xda, 0x0b, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x8b, 0x0c, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4d, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, @@ -5906,220 +5926,208 @@ var file_query_proto_rawDesc = []byte{ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x14, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x22, 0x3b, 0x0a, 0x0e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x46, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4e, 0x44, 0x5f, - 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4f, - 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x22, 0x38, - 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x4f, - 0x4c, 0x54, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x4c, 0x41, 0x50, 0x10, 0x02, 0x12, - 0x07, 0x0a, 0x03, 0x44, 0x42, 0x41, 0x10, 0x03, 0x22, 0xa7, 0x01, 0x0a, 0x14, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x13, - 0x0a, 0x0f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x52, 0x45, 0x41, - 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x43, 0x4f, 0x4d, 0x4d, - 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x41, 0x44, 0x5f, - 0x55, 0x4e, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x10, 0x0a, - 0x0c, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, 0x12, - 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x4e, - 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, - 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x55, 0x54, 0x4f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, - 0x10, 0x06, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, - 0x5f, 0x50, 0x4c, 0x41, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x56, 0x33, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x65, 0x6e, 0x34, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, - 0x47, 0x65, 0x6e, 0x34, 0x47, 0x72, 0x65, 0x65, 0x64, 0x79, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, - 0x47, 0x65, 0x6e, 0x34, 0x4c, 0x65, 0x66, 0x74, 0x32, 0x52, 0x69, 0x67, 0x68, 0x74, 0x10, 0x04, - 0x12, 0x14, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x34, 0x57, 0x69, 0x74, 0x68, 0x46, 0x61, 0x6c, 0x6c, - 0x62, 0x61, 0x63, 0x6b, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x34, 0x43, 0x6f, - 0x6d, 0x70, 0x61, 0x72, 0x65, 0x56, 0x33, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x56, 0x33, 0x49, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x07, 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x53, - 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, - 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, - 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x43, - 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x41, 0x42, - 0x4c, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x53, 0x10, 0x03, 0x22, 0x4f, - 0x0a, 0x15, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x53, 0x49, - 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, 0x00, - 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, - 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, 0x42, - 0x09, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, - 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xb8, 0x02, 0x0a, - 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x72, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, - 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, - 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, - 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, - 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x6f, - 0x6c, 0x75, 0x6d, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, - 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x72, 0x73, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x37, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, 0x18, - 0x0a, 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x12, 0x52, - 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x22, 0xe3, 0x01, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x77, 0x73, 0x5f, 0x61, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x72, - 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, - 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, - 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, - 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x3c, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x57, - 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0xa0, 0x03, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x32, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0a, 0x65, 0x76, 0x65, 0x6e, - 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x9e, 0x02, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x08, 0x63, - 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x12, 0x38, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, - 0x73, 0x71, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x22, 0x27, - 0x0a, 0x08, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x4d, 0x4c, 0x10, 0x01, 0x12, 0x07, - 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, 0x02, 0x22, 0xe1, 0x02, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, - 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, - 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x3d, 0x0a, 0x0f, 0x45, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x64, 0x0a, 0x0f, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x57, 0x69, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, - 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x22, 0xe7, 0x02, 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, - 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, - 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x15, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0xee, 0x01, 0x0a, 0x0c, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, - 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x22, 0xa4, 0x01, 0x0a, 0x0d, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, - 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, - 0x31, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x49, 0x64, 0x22, 0xe7, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, + 0x74, 0x12, 0x2f, 0x0a, 0x14, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x11, 0x66, 0x65, 0x74, 0x63, 0x68, 0x4c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x49, 0x64, 0x22, 0x3b, 0x0a, 0x0e, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x4e, 0x44, + 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x4c, 0x4c, 0x10, 0x02, 0x22, + 0x38, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x0f, 0x0a, 0x0b, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, + 0x4f, 0x4c, 0x54, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4f, 0x4c, 0x41, 0x50, 0x10, 0x02, + 0x12, 0x07, 0x0a, 0x03, 0x44, 0x42, 0x41, 0x10, 0x03, 0x22, 0xa7, 0x01, 0x0a, 0x14, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, + 0x13, 0x0a, 0x0f, 0x52, 0x45, 0x50, 0x45, 0x41, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x43, 0x4f, 0x4d, + 0x4d, 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x41, 0x44, + 0x5f, 0x55, 0x4e, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, 0x10, + 0x0a, 0x0c, 0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x04, + 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4e, 0x53, 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, + 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, + 0x59, 0x10, 0x05, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x55, 0x54, 0x4f, 0x43, 0x4f, 0x4d, 0x4d, 0x49, + 0x54, 0x10, 0x06, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, + 0x54, 0x5f, 0x50, 0x4c, 0x41, 0x4e, 0x4e, 0x45, 0x52, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x56, + 0x33, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x65, 0x6e, 0x34, 0x10, 0x02, 0x12, 0x0e, 0x0a, + 0x0a, 0x47, 0x65, 0x6e, 0x34, 0x47, 0x72, 0x65, 0x65, 0x64, 0x79, 0x10, 0x03, 0x12, 0x12, 0x0a, + 0x0e, 0x47, 0x65, 0x6e, 0x34, 0x4c, 0x65, 0x66, 0x74, 0x32, 0x52, 0x69, 0x67, 0x68, 0x74, 0x10, + 0x04, 0x12, 0x14, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x34, 0x57, 0x69, 0x74, 0x68, 0x46, 0x61, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x34, 0x43, + 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x56, 0x33, 0x10, 0x06, 0x12, 0x0c, 0x0a, 0x08, 0x56, 0x33, + 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x07, 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, + 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, + 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x4f, 0x4e, 0x53, 0x4f, + 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, + 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, + 0x43, 0x4f, 0x4e, 0x53, 0x4f, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x41, + 0x42, 0x4c, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x50, 0x4c, 0x49, 0x43, 0x41, 0x53, 0x10, 0x03, 0x22, + 0x4f, 0x0a, 0x15, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4e, 0x53, + 0x49, 0x53, 0x54, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x53, 0x48, 0x4f, 0x54, 0x10, + 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, + 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x02, + 0x42, 0x09, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4a, 0x04, 0x08, 0x01, 0x10, + 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xb8, 0x02, + 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0b, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x72, 0x67, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x72, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6f, + 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, + 0x72, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, + 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, + 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x37, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, + 0x18, 0x0a, 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x12, + 0x52, 0x07, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x22, 0x8f, 0x02, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, + 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x6f, 0x77, 0x73, 0x5f, + 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, + 0x72, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, + 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x4a, 0x04, 0x08, + 0x05, 0x10, 0x06, 0x22, 0x3c, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x57, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0xa0, 0x03, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x32, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x1a, 0x9e, 0x02, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x41, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, + 0x67, 0x6f, 0x72, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x10, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, + 0x38, 0x0a, 0x12, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x10, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x4b, 0x65, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x71, 0x6c, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x22, 0x27, 0x0a, 0x08, 0x43, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x4d, 0x4c, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x44, + 0x44, 0x4c, 0x10, 0x02, 0x22, 0xe1, 0x02, 0x0a, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, + 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, + 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x3d, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x64, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x57, 0x69, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, + 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe7, 0x02, + 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, + 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, + 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, + 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, + 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xee, 0x01, 0x0a, + 0x0c, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, + 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa4, 0x01, + 0x0a, 0x0d, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x13, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, @@ -6133,81 +6141,29 @@ var file_query_proto_rawDesc = []byte{ 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x10, - 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, - 0x64, 0x22, 0xfa, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x11, - 0x0a, 0x0f, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0xda, 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, - 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, - 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, - 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, - 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x18, - 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x02, 0x0a, 0x17, 0x52, 0x6f, 0x6c, - 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1a, - 0x0a, 0x18, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x90, 0x02, 0x0a, 0x18, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, - 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, - 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x1b, 0x0a, - 0x19, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x31, 0x0a, 0x0e, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, + 0xe7, 0x01, 0x0a, 0x0f, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, + 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x10, 0x52, 0x6f, 0x6c, + 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0xfa, + 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, @@ -6222,31 +6178,10 @@ var file_query_proto_rawDesc = []byte{ 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x44, 0x0a, 0x13, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x17, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, - 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, - 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, - 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, - 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x1a, 0x43, 0x6f, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x50, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xda, + 0x01, 0x0a, 0x15, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, @@ -6258,10 +6193,85 @@ var file_query_proto_rawDesc = []byte{ 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x43, - 0x6f, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x16, 0x52, - 0x65, 0x61, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x83, 0x02, 0x0a, 0x17, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, + 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x52, + 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x90, 0x02, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xfe, 0x01, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, + 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, + 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x44, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xfe, + 0x01, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x74, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, + 0x15, 0x0a, 0x13, 0x53, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x63, 0x6c, + 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, @@ -6274,130 +6284,30 @@ var file_query_proto_rawDesc = []byte{ 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xef, 0x01, 0x0a, 0x1d, - 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, - 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, - 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, - 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0a, 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x41, 0x67, 0x65, 0x22, 0x60, 0x0a, - 0x1e, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x3e, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, - 0xe0, 0x02, 0x0a, 0x13, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, - 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, - 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, - 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, - 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x14, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, - 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x22, 0xe6, 0x02, 0x0a, 0x19, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, - 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, - 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, - 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x84, 0x02, 0x0a, - 0x1a, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, - 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x22, 0xd9, 0x01, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, - 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, - 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x43, 0x0a, 0x15, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x22, 0xf6, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x41, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, + 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x1d, 0x0a, 0x1b, 0x43, 0x6f, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xdb, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x61, 0x64, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, + 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x64, 0x74, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x36, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xef, 0x01, 0x0a, 0x1d, 0x55, 0x6e, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, @@ -6408,16 +6318,94 @@ var file_query_proto_rawDesc = []byte{ 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, - 0x03, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x40, 0x0a, - 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0xe8, 0x02, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, + 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x62, 0x61, + 0x6e, 0x64, 0x6f, 0x6e, 0x5f, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, + 0x61, 0x62, 0x61, 0x6e, 0x64, 0x6f, 0x6e, 0x41, 0x67, 0x65, 0x22, 0x60, 0x0a, 0x1e, 0x55, 0x6e, + 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0c, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x0c, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe0, 0x02, 0x0a, + 0x13, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, + 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, + 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, + 0xfe, 0x01, 0x0a, 0x14, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x22, 0xe6, 0x02, 0x0a, 0x19, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, + 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, + 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, + 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x84, 0x02, 0x0a, 0x1a, 0x42, 0x65, + 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, + 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x22, 0xd9, 0x01, 0x0a, 0x14, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, @@ -6428,349 +6416,387 @@ var file_query_proto_rawDesc = []byte{ 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x43, 0x0a, 0x15, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0xf6, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x63, 0x6b, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, + 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x69, 0x64, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x40, 0x0a, 0x12, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xe8, 0x02, 0x0a, + 0x15, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, + 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, + 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, + 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x25, + 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, + 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x22, 0xee, 0x02, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, - 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x16, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x22, 0xee, 0x02, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, - 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, - 0x72, 0x69, 0x65, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x22, 0xf4, 0x02, 0x0a, 0x1a, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, - 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, - 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, - 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, - 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x74, 0x42, 0x65, - 0x67, 0x69, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa6, 0x02, 0x0a, 0x1b, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, - 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, - 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, - 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x22, 0xfa, 0x02, 0x0a, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, - 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, - 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, - 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, - 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, - 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, - 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, - 0x70, 0x6f, 0x73, 0x74, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x22, 0xac, 0x02, 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, - 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, - 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, - 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, - 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, - 0x87, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, - 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x52, 0x65, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0xbe, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x65, 0x70, 0x6c, + 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, + 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x22, 0xf4, 0x02, 0x0a, 0x1a, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, + 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, + 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, + 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, + 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6f, 0x73, 0x74, 0x42, 0x65, 0x67, 0x69, 0x6e, + 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xa6, 0x02, 0x0a, 0x1b, 0x52, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, + 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, + 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, + 0x49, 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x22, 0xfa, 0x02, 0x0a, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, + 0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x42, 0x6f, 0x75, 0x6e, + 0x64, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2f, 0x0a, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, + 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x65, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x12, + 0x2c, 0x0a, 0x12, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x71, 0x75, + 0x65, 0x72, 0x69, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x70, 0x6f, 0x73, + 0x74, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x69, 0x65, 0x73, 0x22, 0xac, 0x02, + 0x0a, 0x21, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x50, 0x43, 0x45, 0x72, + 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, + 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x12, 0x38, + 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x87, 0x02, 0x0a, + 0x0e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x25, + 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x64, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x64, 0x49, 0x64, 0x22, 0x11, 0x0a, 0x0f, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x22, 0xbe, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x5f, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x30, 0x0a, + 0x14, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x47, 0x0a, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, - 0x12, 0x30, 0x0a, 0x14, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x20, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x72, + 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1d, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, + 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x70, 0x75, 0x5f, + 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x63, 0x70, 0x75, + 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x70, 0x73, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x03, 0x71, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x76, 0x69, 0x65, + 0x77, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x76, 0x69, 0x65, 0x77, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x64, 0x66, + 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0b, 0x75, 0x64, 0x66, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x23, 0x0a, 0x0d, + 0x74, 0x78, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0c, 0x74, 0x78, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, + 0x64, 0x22, 0xf6, 0x01, 0x0a, 0x0e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x5f, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x12, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x75, 0x6e, 0x68, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x75, 0x6e, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, + 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x1b, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, + 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x69, 0x6e, 0x12, 0x3d, 0x0a, 0x1b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, 0x67, 0x5f, 0x73, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1d, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, - 0x70, 0x75, 0x5f, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, - 0x63, 0x70, 0x75, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x71, 0x70, 0x73, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x71, 0x70, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x64, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, - 0x76, 0x69, 0x65, 0x77, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x63, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x64, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x76, 0x69, 0x65, 0x77, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, - 0x75, 0x64, 0x66, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0b, 0x75, 0x64, 0x66, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, - 0x23, 0x0a, 0x0d, 0x74, 0x78, 0x5f, 0x75, 0x6e, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x74, 0x78, 0x55, 0x6e, 0x72, 0x65, 0x73, 0x6f, - 0x6c, 0x76, 0x65, 0x64, 0x22, 0xf6, 0x01, 0x0a, 0x0e, 0x41, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x12, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34, 0x0a, 0x16, 0x75, 0x6e, 0x68, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x14, 0x75, 0x6e, 0x68, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x79, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x3d, 0x0a, 0x1b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, - 0x61, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x69, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x69, 0x6e, 0x12, 0x3d, - 0x0a, 0x1b, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x61, - 0x67, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x4c, 0x61, 0x67, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x78, 0x22, 0x95, 0x02, - 0x0a, 0x14, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, - 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x5f, 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x54, 0x65, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x61, 0x6c, - 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, - 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x4a, - 0x04, 0x08, 0x06, 0x10, 0x07, 0x22, 0xae, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, - 0x04, 0x64, 0x74, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, - 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x17, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, - 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, - 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x74, - 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x54, 0x61, 0x62, 0x6c, 0x65, 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, 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, 0xd7, 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, 0x12, 0x0b, 0x0a, 0x06, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, - 0x10, 0xa3, 0x10, 0x12, 0x08, 0x0a, 0x03, 0x52, 0x41, 0x57, 0x10, 0xa4, 0x10, 0x2a, 0x36, 0x0a, - 0x10, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x08, - 0x0a, 0x04, 0x46, 0x61, 0x69, 0x6c, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x10, 0x02, 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, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, - 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 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, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x18, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x61, 0x67, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x4d, 0x61, 0x78, 0x22, 0x95, 0x02, 0x0a, 0x14, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x6e, 0x67, 0x12, 0x3f, 0x0a, 0x1c, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, + 0x74, 0x65, 0x72, 0x6d, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x54, 0x65, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3b, 0x0a, 0x0e, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, + 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, + 0x61, 0x74, 0x73, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x4a, 0x04, 0x08, 0x06, + 0x10, 0x07, 0x22, 0xae, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x74, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x74, 0x69, 0x64, 0x12, 0x2d, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, + 0x6e, 0x74, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x54, 0x61, 0x62, 0x6c, 0x65, 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, 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, 0xd7, 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, 0x12, 0x0b, 0x0a, 0x06, 0x56, 0x45, 0x43, 0x54, 0x4f, 0x52, 0x10, 0xa3, 0x10, + 0x12, 0x08, 0x0a, 0x03, 0x52, 0x41, 0x57, 0x10, 0xa4, 0x10, 0x2a, 0x36, 0x0a, 0x10, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, + 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x46, + 0x61, 0x69, 0x6c, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x10, 0x02, 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, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x0a, + 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 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 ( diff --git a/go/vt/proto/query/query_vtproto.pb.go b/go/vt/proto/query/query_vtproto.pb.go index 2cb69d9406d..21ab8776fc5 100644 --- a/go/vt/proto/query/query_vtproto.pb.go +++ b/go/vt/proto/query/query_vtproto.pb.go @@ -176,6 +176,7 @@ func (m *ExecuteOptions) CloneVT() *ExecuteOptions { r.Consolidator = m.Consolidator r.WorkloadName = m.WorkloadName r.Priority = m.Priority + r.FetchLastInsertId = m.FetchLastInsertId if rhs := m.TransactionAccessMode; rhs != nil { tmpContainer := make([]ExecuteOptions_TransactionAccessMode, len(rhs)) copy(tmpContainer, rhs) @@ -268,6 +269,7 @@ func (m *QueryResult) CloneVT() *QueryResult { r.InsertId = m.InsertId r.Info = m.Info r.SessionStateChanges = m.SessionStateChanges + r.InsertIdChanged = m.InsertIdChanged if rhs := m.Fields; rhs != nil { tmpContainer := make([]*Field, len(rhs)) for k, v := range rhs { @@ -1893,6 +1895,18 @@ func (m *ExecuteOptions) MarshalToSizedBufferVT(dAtA []byte) (int, error) { } i -= size } + if m.FetchLastInsertId { + i-- + if m.FetchLastInsertId { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x90 + } if len(m.Priority) > 0 { i -= len(m.Priority) copy(dAtA[i:], m.Priority) @@ -2198,6 +2212,16 @@ func (m *QueryResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.InsertIdChanged { + i-- + if m.InsertIdChanged { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } if len(m.SessionStateChanges) > 0 { i -= len(m.SessionStateChanges) copy(dAtA[i:], m.SessionStateChanges) @@ -6169,6 +6193,9 @@ func (m *ExecuteOptions) SizeVT() (n int) { if vtmsg, ok := m.Timeout.(interface{ SizeVT() int }); ok { n += vtmsg.SizeVT() } + if m.FetchLastInsertId { + n += 3 + } n += len(m.unknownFields) return n } @@ -6284,6 +6311,9 @@ func (m *QueryResult) SizeVT() (n int) { if l > 0 { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } + if m.InsertIdChanged { + n += 2 + } n += len(m.unknownFields) return n } @@ -8914,6 +8944,26 @@ func (m *ExecuteOptions) UnmarshalVT(dAtA []byte) error { } } m.Timeout = &ExecuteOptions_AuthoritativeTimeout{AuthoritativeTimeout: v} + case 18: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FetchLastInsertId", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.FetchLastInsertId = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) @@ -9636,6 +9686,26 @@ func (m *QueryResult) UnmarshalVT(dAtA []byte) error { } m.SessionStateChanges = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InsertIdChanged", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.InsertIdChanged = bool(v != 0) default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index c764a6aab08..e59832cdab5 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -465,7 +465,7 @@ func (cached *Insert) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(224) + size += int64(240) } // field InsertCommon vitess.io/vitess/go/vt/vtgate/engine.InsertCommon size += cached.InsertCommon.CachedSize(false) @@ -546,7 +546,7 @@ func (cached *InsertSelect) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(176) + size += int64(192) } // field InsertCommon vitess.io/vitess/go/vt/vtgate/engine.InsertCommon size += cached.InsertCommon.CachedSize(false) @@ -609,7 +609,7 @@ func (cached *Limit) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(48) + size += int64(64) } // field Count vitess.io/vitess/go/vt/vtgate/evalengine.Expr if cc, ok := cached.Count.(cachedObject); ok { diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 7783e6bdc12..152894d5eab 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -145,7 +145,7 @@ func (c *DBDDL) createDatabase(ctx context.Context, vcursor VCursor, plugin DBDD } for { - _, errors := vcursor.ExecuteMultiShard(ctx, c, destinations, queries, false, true) + _, errors := vcursor.ExecuteMultiShard(ctx, c, destinations, queries, false, true, false) noErr := true for _, err := range errors { diff --git a/go/vt/vtgate/engine/delete.go b/go/vt/vtgate/engine/delete.go index 91bcca5cf6a..14859fc2135 100644 --- a/go/vt/vtgate/engine/delete.go +++ b/go/vt/vtgate/engine/delete.go @@ -87,7 +87,7 @@ func (del *Delete) deleteVindexEntries(ctx context.Context, vcursor VCursor, bin for i := range rss { queries[i] = &querypb.BoundQuery{Sql: del.OwnedVindexQuery, BindVariables: bindVars} } - subQueryResults, errors := vcursor.ExecuteMultiShard(ctx, del, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + subQueryResults, errors := vcursor.ExecuteMultiShard(ctx, del, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, del.FetchLastInsertID) for _, err := range errors { if err != nil { return err @@ -131,6 +131,9 @@ func (del *Delete) description() PrimitiveDescription { } addFieldsIfNotEmpty(del.DML, other) + if del.FetchLastInsertID { + other["FetchLastInsertID"] = del.FetchLastInsertID + } return PrimitiveDescription{ OperatorType: "Delete", diff --git a/go/vt/vtgate/engine/dml.go b/go/vt/vtgate/engine/dml.go index db777c36698..9a0a044a3c4 100644 --- a/go/vt/vtgate/engine/dml.go +++ b/go/vt/vtgate/engine/dml.go @@ -65,6 +65,8 @@ type DML struct { PreventAutoCommit bool + FetchLastInsertID bool + // RoutingParameters parameters required for query routing. *RoutingParameters } @@ -75,7 +77,7 @@ func NewDML() *DML { } func (dml *DML) execUnsharded(ctx context.Context, primitive Primitive, vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard) (*sqltypes.Result, error) { - return execShard(ctx, primitive, vcursor, dml.Query, bindVars, rss[0], true /* rollbackOnError */, !dml.PreventAutoCommit /* canAutocommit */) + return execShard(ctx, primitive, vcursor, dml.Query, bindVars, rss[0], true /* rollbackOnError */, !dml.PreventAutoCommit /* canAutocommit */, dml.FetchLastInsertID) } func (dml *DML) execMultiDestination(ctx context.Context, primitive Primitive, vcursor VCursor, bindVars map[string]*querypb.BindVariable, rss []*srvtopo.ResolvedShard, dmlSpecialFunc func(context.Context, VCursor, @@ -94,7 +96,7 @@ func (dml *DML) execMultiDestination(ctx context.Context, primitive Primitive, v BindVariables: bvs[i], } } - return execMultiShard(ctx, primitive, vcursor, rss, queries, dml.MultiShardAutocommit) + return dml.execMultiShard(ctx, primitive, vcursor, rss, queries) } // RouteType returns a description of the query routing type used by the primitive @@ -130,9 +132,9 @@ func allowOnlyPrimary(rss ...*srvtopo.ResolvedShard) error { return nil } -func execMultiShard(ctx context.Context, primitive Primitive, vcursor VCursor, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, multiShardAutoCommit bool) (*sqltypes.Result, error) { - autocommit := (len(rss) == 1 || multiShardAutoCommit) && vcursor.AutocommitApproval() - result, errs := vcursor.ExecuteMultiShard(ctx, primitive, rss, queries, true /* rollbackOnError */, autocommit) +func (dml *DML) execMultiShard(ctx context.Context, primitive Primitive, vcursor VCursor, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery) (*sqltypes.Result, error) { + autocommit := (len(rss) == 1 || dml.MultiShardAutocommit) && vcursor.AutocommitApproval() + result, errs := vcursor.ExecuteMultiShard(ctx, primitive, rss, queries, true /*rollbackOnError*/, autocommit, dml.FetchLastInsertID) return result, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 9ba4fdc6a6b..f27ca380876 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -368,7 +368,7 @@ func (t *noopVCursor) Execute(ctx context.Context, method string, query string, panic("unimplemented") } -func (t *noopVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { +func (t *noopVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) { panic("unimplemented") } @@ -376,11 +376,11 @@ func (t *noopVCursor) AutocommitApproval() bool { panic("unimplemented") } -func (t *noopVCursor) ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { +func (t *noopVCursor) ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) { panic("unimplemented") } -func (t *noopVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error { +func (t *noopVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error { panic("unimplemented") } @@ -587,7 +587,7 @@ func (f *loggingVCursor) Execute(ctx context.Context, method string, query strin return f.nextResult() } -func (f *loggingVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { +func (f *loggingVCursor) ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) { f.mu.Lock() defer f.mu.Unlock() f.log = append(f.log, fmt.Sprintf("ExecuteMultiShard %v%v %v", printResolvedShardQueries(rss, queries), rollbackOnError, canAutocommit)) @@ -606,12 +606,12 @@ func (f *loggingVCursor) AutocommitApproval() bool { return true } -func (f *loggingVCursor) ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { +func (f *loggingVCursor) ExecuteStandalone(ctx context.Context, _ Primitive, query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) { f.log = append(f.log, fmt.Sprintf("ExecuteStandalone %s %v %s %s", query, printBindVars(bindvars), rs.Target.Keyspace, rs.Target.Shard)) return f.nextResult() } -func (f *loggingVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error { +func (f *loggingVCursor) StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error { f.mu.Lock() f.log = append(f.log, fmt.Sprintf("StreamExecuteMulti %s %s", query, printResolvedShardsBindVars(rss, bindVars))) if f.onStreamExecuteMultiFn != nil { diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index cd462966ccc..10a4048572f 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -58,6 +58,8 @@ type Insert struct { // Alias represents the row alias with columns if specified in the query. Alias string + + FetchLastInsertID bool } // newQueryInsert creates an Insert with a query string. @@ -169,13 +171,14 @@ func (ins *Insert) executeInsertQueries( if err != nil { return nil, err } - result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true /* rollbackOnError */, autocommit) + result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true /*rollbackOnError*/, autocommit, ins.FetchLastInsertID) if errs != nil { return nil, vterrors.Aggregate(errs) } if insertID != 0 { result.InsertID = insertID + result.InsertIDChanged = true } return result, nil } @@ -383,6 +386,10 @@ func (ins *Insert) description() PrimitiveDescription { } } + if ins.FetchLastInsertID { + other["FetchLastInsertID"] = true + } + return PrimitiveDescription{ OperatorType: "Insert", Keyspace: ins.Keyspace, diff --git a/go/vt/vtgate/engine/insert_common.go b/go/vt/vtgate/engine/insert_common.go index e29aa7fd792..629d848d978 100644 --- a/go/vt/vtgate/engine/insert_common.go +++ b/go/vt/vtgate/engine/insert_common.go @@ -77,6 +77,8 @@ type ( // ColVindexes are the vindexes that will use the VindexValues ColVindexes []*vindexes.ColumnVindex + FetchLastInsertID bool + // Prefix, Suffix are for sharded insert plans. Prefix string Suffix sqlparser.OnDup @@ -159,7 +161,7 @@ func (ins *InsertCommon) executeUnshardedTableQuery(ctx context.Context, vcursor if err != nil { return nil, err } - qr, err := execShard(ctx, loggingPrimitive, vcursor, query, bindVars, rss[0], true, !ins.PreventAutoCommit /* canAutocommit */) + qr, err := execShard(ctx, loggingPrimitive, vcursor, query, bindVars, rss[0], true, !ins.PreventAutoCommit /* canAutocommit */, false) if err != nil { return nil, err } @@ -169,6 +171,7 @@ func (ins *InsertCommon) executeUnshardedTableQuery(ctx context.Context, vcursor // values, we don't return an error because this behavior // is required to support migration. if insertID != 0 { + qr.InsertIDChanged = true qr.InsertID = insertID } return qr, nil @@ -451,7 +454,7 @@ func (ic *InsertCommon) execGenerate(ctx context.Context, vcursor VCursor, loggi return 0, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "auto sequence generation can happen through single shard only, it is getting routed to %d shards", len(rss)) } bindVars := map[string]*querypb.BindVariable{nextValBV: sqltypes.Int64BindVariable(count)} - qr, err := vcursor.ExecuteStandalone(ctx, loggingPrimitive, ic.Generate.Query, bindVars, rss[0]) + qr, err := vcursor.ExecuteStandalone(ctx, loggingPrimitive, ic.Generate.Query, bindVars, rss[0], ic.FetchLastInsertID) if err != nil { return 0, err } diff --git a/go/vt/vtgate/engine/insert_select.go b/go/vt/vtgate/engine/insert_select.go index f8f3936e323..bccee5f2cf9 100644 --- a/go/vt/vtgate/engine/insert_select.go +++ b/go/vt/vtgate/engine/insert_select.go @@ -207,7 +207,7 @@ func (ins *InsertSelect) executeInsertQueries( if err != nil { return nil, err } - result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true /* rollbackOnError */, autocommit) + result, errs := vcursor.ExecuteMultiShard(ctx, ins, rss, queries, true, autocommit, false) if errs != nil { return nil, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/limit.go b/go/vt/vtgate/engine/limit.go index 01fcde6bd82..d50a0d4adde 100644 --- a/go/vt/vtgate/engine/limit.go +++ b/go/vt/vtgate/engine/limit.go @@ -33,11 +33,22 @@ import ( var _ Primitive = (*Limit)(nil) -// Limit is a primitive that performs the LIMIT operation. +// Limit performs the LIMIT operation, restricting the number of rows returned. type Limit struct { - Count evalengine.Expr + // Count specifies the maximum number of rows to return. + Count evalengine.Expr + + // Offset specifies the number of rows to skip before returning results. Offset evalengine.Expr - Input Primitive + + // RequireCompleteInput determines if all input rows must be fully retrieved. + // - If true, all Result structs are passed through, and the total rows are limited. + // - If false, Limit returns io.EOF once the limit is reached in streaming mode, + // signaling the tablet to stop sending data. + RequireCompleteInput bool + + // Input provides the input rows. + Input Primitive } var UpperLimitStr = "__upper_limit" @@ -88,6 +99,10 @@ func (l *Limit) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[st return result, nil } +func (l *Limit) mustRetrieveAll(vcursor VCursor) bool { + return l.RequireCompleteInput || vcursor.Session().InTransaction() +} + // TryStreamExecute satisfies the Primitive interface. func (l *Limit) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { count, offset, err := l.getCountAndOffset(ctx, vcursor, bindVars) @@ -97,57 +112,78 @@ func (l *Limit) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars bindVars = copyBindVars(bindVars) - // When offset is present, we hijack the limit value so we can calculate - // the offset in memory from the result of the scatter query with count + offset. + // Adjust the upper limit so that the initial fetch includes both the offset and count. + // We do this because we want to skip the first `offset` rows locally rather than on the server side. bindVars[UpperLimitStr] = sqltypes.Int64BindVariable(int64(count + offset)) var mu sync.Mutex err = vcursor.StreamExecutePrimitive(ctx, l.Input, bindVars, wantfields, func(qr *sqltypes.Result) error { mu.Lock() defer mu.Unlock() - if wantfields && len(qr.Fields) != 0 { - if err := callback(&sqltypes.Result{Fields: qr.Fields}); err != nil { - return err - } - } - inputSize := len(qr.Rows) - if inputSize == 0 { - return nil - } - // we've still not seen all rows we need to see before we can return anything to the client + inputSize := len(qr.Rows) + // If we still need to skip `offset` rows before returning any to the client: if offset > 0 { if inputSize <= offset { - // not enough to return anything yet + // not enough to return anything yet, but we still want to pass on metadata such as last_insert_id offset -= inputSize - return nil + if !wantfields && !l.mustRetrieveAll(vcursor) { + return nil + } + if len(qr.Fields) > 0 { + wantfields = false + } + qr.Rows = nil + return callback(qr) } + // Skip `offset` rows from this batch and reset offset to 0. qr.Rows = qr.Rows[offset:] offset = 0 } + // At this point, we've dealt with the offset. Now handle the count (limit). if count == 0 { - return io.EOF + // If count is zero, we've fetched everything we need. + if !wantfields && !l.mustRetrieveAll(vcursor) { + return io.EOF + } + if len(qr.Fields) > 0 { + wantfields = false + } + + // If we require the complete input, or we are in a transaction, we cannot return io.EOF early. + // Instead, we return empty results as needed until input ends. + qr.Rows = nil + return callback(qr) + } + + if len(qr.Fields) > 0 { + wantfields = false } // reduce count till 0. - result := &sqltypes.Result{Rows: qr.Rows} - resultSize := len(result.Rows) + resultSize := len(qr.Rows) if count > resultSize { count -= resultSize - return callback(result) + return callback(qr) } - result.Rows = result.Rows[:count] + + qr.Rows = qr.Rows[:count] count = 0 - if err := callback(result); err != nil { + if err := callback(qr); err != nil { return err } + + // If we required complete input or are in a transaction, we must not exit early. + // We'll return empty batches until the input is done. + if l.mustRetrieveAll(vcursor) { + return nil + } + return io.EOF }) if err == io.EOF { - // We may get back the EOF we returned in the callback. - // If so, suppress it. return nil } if err != nil { @@ -217,6 +253,9 @@ func (l *Limit) description() PrimitiveDescription { if l.Offset != nil { other["Offset"] = sqlparser.String(l.Offset) } + if l.RequireCompleteInput { + other["RequireCompleteInput"] = true + } return PrimitiveDescription{ OperatorType: "Limit", diff --git a/go/vt/vtgate/engine/limit_test.go b/go/vt/vtgate/engine/limit_test.go index 8b91dadecb5..8ab31610e62 100644 --- a/go/vt/vtgate/engine/limit_test.go +++ b/go/vt/vtgate/engine/limit_test.go @@ -353,9 +353,7 @@ func TestLimitOffsetExecute(t *testing.T) { t.Errorf("l.Execute:\n got %v, want\n%v", result, wantResult) } } - func TestLimitStreamExecute(t *testing.T) { - bindVars := make(map[string]*querypb.BindVariable) fields := sqltypes.MakeTestFields( "col1|col2", "int64|varchar", @@ -366,88 +364,88 @@ func TestLimitStreamExecute(t *testing.T) { "b|2", "c|3", ) - fp := &fakePrimitive{ - results: []*sqltypes.Result{inputResult}, - } - - l := &Limit{ - Count: evalengine.NewLiteralInt(2), - Input: fp, - } - // Test with limit smaller than input. - var results []*sqltypes.Result - err := l.TryStreamExecute(context.Background(), &noopVCursor{}, bindVars, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - wantResults := sqltypes.MakeTestStreamingResults( - fields, - "a|1", - "b|2", - ) - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } - } + tests := []struct { + name string + countExpr evalengine.Expr + bindVars map[string]*querypb.BindVariable + want []*sqltypes.Result + RequireCompleteInput bool + }{{ + name: "limit smaller than input (literal)", + countExpr: evalengine.NewLiteralInt(2), + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + ), + }, { + name: "limit smaller than input (literal) - require complete input", + countExpr: evalengine.NewLiteralInt(2), + RequireCompleteInput: true, + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + "---", // this extra result is required by RequireCompleteInput + ), + }, { + name: "limit smaller than input (bind var)", + countExpr: evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)), + bindVars: map[string]*querypb.BindVariable{"l": sqltypes.Int64BindVariable(2)}, + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + ), + }, { + name: "limit equal to input", + countExpr: evalengine.NewLiteralInt(3), + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + "---", + "c|3", + ), + }, { + name: "limit higher than input", + countExpr: evalengine.NewLiteralInt(4), + // same as limit=3 + want: sqltypes.MakeTestStreamingResults( + fields, + "a|1", + "b|2", + "---", + "c|3", + ), + }} - // Test with bind vars. - fp.rewind() - l.Count = evalengine.NewBindVar("l", evalengine.NewType(sqltypes.Int64, collations.CollationBinaryID)) - results = nil - err = l.TryStreamExecute(context.Background(), &noopVCursor{}, map[string]*querypb.BindVariable{"l": sqltypes.Int64BindVariable(2)}, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } - } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fp := &fakePrimitive{ + results: []*sqltypes.Result{inputResult}, + } - // Test with limit equal to input - fp.rewind() - l.Count = evalengine.NewLiteralInt(3) - results = nil - err = l.TryStreamExecute(context.Background(), &noopVCursor{}, bindVars, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - wantResults = sqltypes.MakeTestStreamingResults( - fields, - "a|1", - "b|2", - "---", - "c|3", - ) - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } - } + l := &Limit{ + Count: tt.countExpr, + RequireCompleteInput: tt.RequireCompleteInput, + Input: fp, + } - // Test with limit higher than input. - fp.rewind() - l.Count = evalengine.NewLiteralInt(4) - results = nil - err = l.TryStreamExecute(context.Background(), &noopVCursor{}, bindVars, true, func(qr *sqltypes.Result) error { - results = append(results, qr) - return nil - }) - require.NoError(t, err) - // wantResults is same as before. - require.Len(t, results, len(wantResults)) - for i, result := range results { - if !result.Equal(wantResults[i]) { - t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(wantResults)) - } + var results []*sqltypes.Result + err := l.TryStreamExecute(context.Background(), &noopVCursor{}, tt.bindVars, true, func(qr *sqltypes.Result) error { + results = append(results, qr) + return nil + }) + require.NoError(t, err) + require.Len(t, results, len(tt.want)) + for i, result := range results { + if !result.Equal(tt.want[i]) { + t.Errorf("l.StreamExecute:\n%s, want\n%s", sqltypes.PrintResults(results), sqltypes.PrintResults(tt.want)) + } + } + }) } } diff --git a/go/vt/vtgate/engine/lock.go b/go/vt/vtgate/engine/lock.go index 7739cbcd0cc..a8ba9f46df3 100644 --- a/go/vt/vtgate/engine/lock.go +++ b/go/vt/vtgate/engine/lock.go @@ -173,7 +173,7 @@ func (l *Lock) GetFields(ctx context.Context, vcursor VCursor, bindVars map[stri Sql: l.FieldQuery, BindVariables: bindVars, }} - qr, errs := vcursor.ExecuteMultiShard(ctx, l, rss, boundQuery, false, true) + qr, errs := vcursor.ExecuteMultiShard(ctx, l, rss, boundQuery, false, true, false) if len(errs) > 0 { return nil, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/merge_sort.go b/go/vt/vtgate/engine/merge_sort.go index fac57c37ccb..abf2a65f311 100644 --- a/go/vt/vtgate/engine/merge_sort.go +++ b/go/vt/vtgate/engine/merge_sort.go @@ -21,19 +21,17 @@ import ( "io" "vitess.io/vitess/go/mysql/sqlerror" - "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/sqltypes" - querypb "vitess.io/vitess/go/vt/proto/query" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/evalengine" ) // StreamExecutor is a subset of Primitive that MergeSort // requires its inputs to satisfy. type StreamExecutor interface { - StreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error + StreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, fetchLastInsertID bool, callback func(*sqltypes.Result) error) error } var _ Primitive = (*MergeSort)(nil) @@ -54,6 +52,7 @@ type MergeSort struct { Primitives []StreamExecutor OrderBy evalengine.Comparison ScatterErrorsAsWarnings bool + FetchLastInsertID bool } // RouteType satisfies Primitive. @@ -85,7 +84,7 @@ func (ms *MergeSort) TryStreamExecute(ctx context.Context, vcursor VCursor, bind gotFields := wantfields handles := make([]*streamHandle, len(ms.Primitives)) for i, input := range ms.Primitives { - handles[i] = runOneStream(ctx, vcursor, input, bindVars, gotFields) + handles[i] = runOneStream(ctx, vcursor, input, bindVars, gotFields, ms.FetchLastInsertID) if !ms.ScatterErrorsAsWarnings { // we only need the fields from the first input, unless we allow ScatterErrorsAsWarnings. // in that case, we need to ask all the inputs for fields - we don't know which will return anything @@ -216,13 +215,20 @@ func (ms *MergeSort) description() PrimitiveDescription { // routine that pulls the rows out of each streamHandle can abort the stream // by calling canceling the context. type streamHandle struct { - fields chan []*querypb.Field - row chan []sqltypes.Value - err error + fields chan []*querypb.Field + fieldSeen bool + row chan []sqltypes.Value + err error } // runOnestream starts a streaming query on one shard, and returns a streamHandle for it. -func runOneStream(ctx context.Context, vcursor VCursor, input StreamExecutor, bindVars map[string]*querypb.BindVariable, wantfields bool) *streamHandle { +func runOneStream( + ctx context.Context, + vcursor VCursor, + input StreamExecutor, + bindVars map[string]*querypb.BindVariable, + wantfields, fetchLastInsertID bool, +) *streamHandle { handle := &streamHandle{ fields: make(chan []*querypb.Field, 1), row: make(chan []sqltypes.Value, 10), @@ -232,8 +238,9 @@ func runOneStream(ctx context.Context, vcursor VCursor, input StreamExecutor, bi defer close(handle.fields) defer close(handle.row) - handle.err = input.StreamExecute(ctx, vcursor, bindVars, wantfields, func(qr *sqltypes.Result) error { - if len(qr.Fields) != 0 { + handle.err = input.StreamExecute(ctx, vcursor, bindVars, wantfields, fetchLastInsertID, func(qr *sqltypes.Result) error { + if !handle.fieldSeen && len(qr.Fields) != 0 { + handle.fieldSeen = true select { case handle.fields <- qr.Fields: case <-ctx.Done(): diff --git a/go/vt/vtgate/engine/merge_sort_test.go b/go/vt/vtgate/engine/merge_sort_test.go index 6b383e12572..60890283f89 100644 --- a/go/vt/vtgate/engine/merge_sort_test.go +++ b/go/vt/vtgate/engine/merge_sort_test.go @@ -411,7 +411,7 @@ type shardResult struct { sendErr error } -func (sr *shardResult) StreamExecute(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (sr *shardResult) StreamExecute(_ context.Context, _ VCursor, _ map[string]*querypb.BindVariable, _ bool, _ bool, callback func(*sqltypes.Result) error) error { for _, r := range sr.results { if err := callback(r); err != nil { return err diff --git a/go/vt/vtgate/engine/plan_description.go b/go/vt/vtgate/engine/plan_description.go index e8e763c1ee1..f19be96123e 100644 --- a/go/vt/vtgate/engine/plan_description.go +++ b/go/vt/vtgate/engine/plan_description.go @@ -152,7 +152,11 @@ func PrimitiveDescriptionFromMap(data map[string]any) (pd PrimitiveDescription, } } if ttt, isPresent := data["TargetTabletType"]; isPresent { - pd.TargetTabletType = topodatapb.TabletType(ttt.(int)) + val, ok := topodatapb.TabletType_value[ttt.(string)] + if !ok { + panic(fmt.Sprintf("TargetTabletType is not a valid tablet type: %v", ttt)) + } + pd.TargetTabletType = topodatapb.TabletType(val) } if other, isPresent := data["Other"]; isPresent { pd.Other = other.(map[string]any) diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index 4f3a388d04f..e6fa102581e 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -70,9 +70,9 @@ type ( StreamExecutePrimitiveStandalone(ctx context.Context, primitive Primitive, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(result *sqltypes.Result) error) error // Shard-level functions. - ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) - ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) - StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error + ExecuteMultiShard(ctx context.Context, primitive Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) + ExecuteStandalone(ctx context.Context, primitive Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) + StreamExecuteMulti(ctx context.Context, primitive Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error // Keyspace ID level functions. ExecuteKeyspaceID(ctx context.Context, keyspace string, ksid []byte, query string, bindVars map[string]*querypb.BindVariable, rollbackOnError, autocommit bool) (*sqltypes.Result, error) diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 59682dd91fe..20ab7695f70 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -95,6 +95,8 @@ type Route struct { // select count(*) from tbl where lookupColumn = 'not there' // select exists() NoRoutesSpecialHandling bool + + FetchLastInsertID bool } // NewRoute creates a Route. @@ -181,7 +183,7 @@ func (route *Route) executeShards( } queries := getQueries(route.Query, bvs) - result, errs := vcursor.ExecuteMultiShard(ctx, route, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + result, errs := vcursor.ExecuteMultiShard(ctx, route, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, route.FetchLastInsertID) route.executeWarmingReplicaRead(ctx, vcursor, bindVars, queries) @@ -278,7 +280,7 @@ func (route *Route) streamExecuteShards( } if len(route.OrderBy) == 0 { - errs := vcursor.StreamExecuteMulti(ctx, route, route.Query, rss, bvs, false /* rollbackOnError */, false /* autocommit */, func(qr *sqltypes.Result) error { + errs := vcursor.StreamExecuteMulti(ctx, route, route.Query, rss, bvs, false /* rollbackOnError */, false /* autocommit */, route.FetchLastInsertID, func(qr *sqltypes.Result) error { return callback(qr.Truncate(route.TruncateColumnCount)) }) if len(errs) > 0 { @@ -316,10 +318,12 @@ func (route *Route) mergeSort( primitive: route, }) } + ms := MergeSort{ Primitives: prims, OrderBy: route.OrderBy, ScatterErrorsAsWarnings: route.ScatterErrorsAsWarnings, + FetchLastInsertID: route.FetchLastInsertID, } return vcursor.StreamExecutePrimitive(ctx, &ms, bindVars, wantfields, func(qr *sqltypes.Result) error { return callback(qr.Truncate(route.TruncateColumnCount)) @@ -351,7 +355,7 @@ func (route *Route) GetFields(ctx context.Context, vcursor VCursor, bindVars map } rs = rss[0] } - qr, err := execShard(ctx, route, vcursor, route.FieldQuery, bindVars, rs, false /* rollbackOnError */, false /* canAutocommit */) + qr, err := execShard(ctx, route, vcursor, route.FieldQuery, bindVars, rs, false /* rollbackOnError */, false /* canAutocommit */, route.FetchLastInsertID) if err != nil { return nil, err } @@ -374,6 +378,9 @@ func (route *Route) description() PrimitiveDescription { "Table": route.GetTableName(), "FieldQuery": route.FieldQuery, } + if route.FetchLastInsertID { + other["FetchLastInsertID"] = true + } if route.Vindex != nil { other["Vindex"] = route.Vindex.String() } @@ -479,7 +486,7 @@ func execShard( query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, - rollbackOnError, canAutocommit bool, + rollbackOnError, canAutocommit, fetchLastInsertID bool, ) (*sqltypes.Result, error) { autocommit := canAutocommit && vcursor.AutocommitApproval() result, errs := vcursor.ExecuteMultiShard(ctx, primitive, []*srvtopo.ResolvedShard{rs}, []*querypb.BoundQuery{ @@ -487,7 +494,7 @@ func execShard( Sql: query, BindVariables: bindVars, }, - }, rollbackOnError, autocommit) + }, rollbackOnError, autocommit, fetchLastInsertID) return result, vterrors.Aggregate(errs) } @@ -534,7 +541,7 @@ func (route *Route) executeWarmingReplicaRead(ctx context.Context, vcursor VCurs return } - _, errs := replicaVCursor.ExecuteMultiShard(ctx, route, rss, queries, false /* rollbackOnError */, false /* autocommit */) + _, errs := replicaVCursor.ExecuteMultiShard(ctx, route, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, route.FetchLastInsertID) if len(errs) > 0 { log.Warningf("Failed to execute warming replica read: %v", errs) } else { diff --git a/go/vt/vtgate/engine/routing.go b/go/vt/vtgate/engine/routing.go index e05366c4aeb..067278c1a93 100644 --- a/go/vt/vtgate/engine/routing.go +++ b/go/vt/vtgate/engine/routing.go @@ -51,6 +51,9 @@ const ( // IN is for routing a statement to a multi shard. // Requires: A Vindex, and a multi Values. IN + // Between is for routing a statement to a multi shard + // Requires: A Vindex, and start and end Value. + Between // MultiEqual is used for routing queries with IN with tuple clause // Requires: A Vindex, and a multi Tuple Values. MultiEqual @@ -78,6 +81,7 @@ var opName = map[Opcode]string{ EqualUnique: "EqualUnique", Equal: "Equal", IN: "IN", + Between: "Between", MultiEqual: "MultiEqual", Scatter: "Scatter", DBA: "DBA", @@ -157,6 +161,14 @@ func (rp *RoutingParameters) findRoute(ctx context.Context, vcursor VCursor, bin default: return rp.in(ctx, vcursor, bindVars) } + case Between: + switch rp.Vindex.(type) { + case vindexes.SingleColumn: + return rp.between(ctx, vcursor, bindVars) + default: + // Only SingleColumn vindex supported. + return nil, nil, vterrors.VT13001("between supported on SingleColumn vindex only") + } case MultiEqual: switch rp.Vindex.(type) { case vindexes.MultiColumn: @@ -396,6 +408,19 @@ func (rp *RoutingParameters) inMultiCol(ctx context.Context, vcursor VCursor, bi return rss, shardVarsMultiCol(bindVars, mapVals, isSingleVal), nil } +func (rp *RoutingParameters) between(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) ([]*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, error) { + env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) + value, err := env.Evaluate(rp.Values[0]) + if err != nil { + return nil, nil, err + } + rss, values, err := resolveShardsBetween(ctx, vcursor, rp.Vindex.(vindexes.Sequential), rp.Keyspace, value.TupleValues()) + if err != nil { + return nil, nil, err + } + return rss, shardVars(bindVars, values), nil +} + func (rp *RoutingParameters) multiEqual(ctx context.Context, vcursor VCursor, bindVars map[string]*querypb.BindVariable) ([]*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, error) { env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor) value, err := env.Evaluate(rp.Values[0]) @@ -520,6 +545,24 @@ func buildMultiColumnVindexValues(shardsValues [][][]sqltypes.Value) [][][]*quer return shardsIds } +func resolveShardsBetween(ctx context.Context, vcursor VCursor, vindex vindexes.Sequential, keyspace *vindexes.Keyspace, vindexKeys []sqltypes.Value) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error) { + // Convert vindexKeys to []*querypb.Value + ids := make([]*querypb.Value, len(vindexKeys)) + for i, vik := range vindexKeys { + ids[i] = sqltypes.ValueToProto(vik) + } + + // RangeMap using the Vindex + destinations, err := vindex.RangeMap(ctx, vcursor, vindexKeys[0], vindexKeys[1]) + if err != nil { + return nil, nil, err + + } + + // And use the Resolver to map to ResolvedShards. + return vcursor.ResolveDestinations(ctx, keyspace.Name, ids, destinations) +} + func shardVars(bv map[string]*querypb.BindVariable, mapVals [][]*querypb.Value) []map[string]*querypb.BindVariable { shardVars := make([]map[string]*querypb.BindVariable, len(mapVals)) for i, vals := range mapVals { diff --git a/go/vt/vtgate/engine/send.go b/go/vt/vtgate/engine/send.go index 2ebec5c679e..4655f680675 100644 --- a/go/vt/vtgate/engine/send.go +++ b/go/vt/vtgate/engine/send.go @@ -116,7 +116,7 @@ func (s *Send) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[str } rollbackOnError := s.IsDML // for non-dml queries, there's no need to do a rollback - result, errs := vcursor.ExecuteMultiShard(ctx, s, rss, queries, rollbackOnError, s.canAutoCommit(vcursor, rss)) + result, errs := vcursor.ExecuteMultiShard(ctx, s, rss, queries, rollbackOnError, s.canAutoCommit(vcursor, rss), false) err = vterrors.Aggregate(errs) if err != nil { return nil, err @@ -179,7 +179,7 @@ func (s *Send) TryStreamExecute(ctx context.Context, vcursor VCursor, bindVars m } multiBindVars[i] = bv } - errors := vcursor.StreamExecuteMulti(ctx, s, s.Query, rss, multiBindVars, s.IsDML, s.canAutoCommit(vcursor, rss), callback) + errors := vcursor.StreamExecuteMulti(ctx, s, s.Query, rss, multiBindVars, s.IsDML, s.canAutoCommit(vcursor, rss), false, callback) return vterrors.Aggregate(errors) } diff --git a/go/vt/vtgate/engine/set.go b/go/vt/vtgate/engine/set.go index 9d370b6ec36..95fb5c87a32 100644 --- a/go/vt/vtgate/engine/set.go +++ b/go/vt/vtgate/engine/set.go @@ -248,7 +248,7 @@ func (svci *SysVarCheckAndIgnore) Execute(ctx context.Context, vcursor VCursor, return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Unexpected error, DestinationKeyspaceID mapping to multiple shards: %v", svci.TargetDestination) } checkSysVarQuery := fmt.Sprintf("select 1 from dual where @@%s = %s", svci.Name, svci.Expr) - _, err = execShard(ctx, nil, vcursor, checkSysVarQuery, env.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */) + _, err = execShard(ctx, nil, vcursor, checkSysVarQuery, env.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */, false) if err != nil { // Rather than returning the error, we will just log the error // as the intention for executing the query it to validate the current setting and eventually ignore it anyways. @@ -308,7 +308,7 @@ func (svs *SysVarReservedConn) Execute(ctx context.Context, vcursor VCursor, env BindVariables: env.BindVars, } } - _, errs := vcursor.ExecuteMultiShard(ctx, nil, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + _, errs := vcursor.ExecuteMultiShard(ctx, nil /*primitive*/, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, false /*fetchLastInsertID*/) return vterrors.Aggregate(errs) } @@ -320,7 +320,7 @@ func (svs *SysVarReservedConn) execSetStatement(ctx context.Context, vcursor VCu BindVariables: env.BindVars, } } - _, errs := vcursor.ExecuteMultiShard(ctx, nil, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + _, errs := vcursor.ExecuteMultiShard(ctx, nil /*primitive*/, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, false /*fetchLastInsertID*/) return vterrors.Aggregate(errs) } @@ -333,7 +333,7 @@ func (svs *SysVarReservedConn) checkAndUpdateSysVar(ctx context.Context, vcursor if err != nil { return false, err } - qr, err := execShard(ctx, nil, vcursor, sysVarExprValidationQuery, res.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */) + qr, err := execShard(ctx, nil /*primitive*/, vcursor, sysVarExprValidationQuery, res.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */, false /*fetchLastInsertID*/) if err != nil { return false, err } diff --git a/go/vt/vtgate/engine/shard_route.go b/go/vt/vtgate/engine/shard_route.go index 8365c6fdf59..1e901b9a8ea 100644 --- a/go/vt/vtgate/engine/shard_route.go +++ b/go/vt/vtgate/engine/shard_route.go @@ -37,8 +37,8 @@ type shardRoute struct { } // StreamExecute performs a streaming exec. -func (sr *shardRoute) StreamExecute(ctx context.Context, vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool, callback func(*sqltypes.Result) error) error { +func (sr *shardRoute) StreamExecute(ctx context.Context, vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool, fetchLastInsertID bool, callback func(*sqltypes.Result) error) error { // TODO rollback on error and autocommit should probably not be used like this - errors := vcursor.StreamExecuteMulti(ctx, sr.primitive, sr.query, []*srvtopo.ResolvedShard{sr.rs}, []map[string]*querypb.BindVariable{sr.bv}, false /* rollbackOnError */, false /* autocommit */, callback) + errors := vcursor.StreamExecuteMulti(ctx, sr.primitive, sr.query, []*srvtopo.ResolvedShard{sr.rs}, []map[string]*querypb.BindVariable{sr.bv}, false /* rollbackOnError */, false /* autocommit */, fetchLastInsertID, callback) return vterrors.Aggregate(errors) } diff --git a/go/vt/vtgate/engine/unlock.go b/go/vt/vtgate/engine/unlock.go index 5addbb957fa..1047abb6ec5 100644 --- a/go/vt/vtgate/engine/unlock.go +++ b/go/vt/vtgate/engine/unlock.go @@ -60,7 +60,7 @@ func (u *Unlock) TryExecute(ctx context.Context, vcursor VCursor, bindVars map[s for i := 0; i < len(rss); i++ { bqs[i] = &querypb.BoundQuery{Sql: unlockTables} } - qr, errs := vcursor.ExecuteMultiShard(ctx, u, rss, bqs, true, false) + qr, errs := vcursor.ExecuteMultiShard(ctx, u, rss, bqs, true, false, false) return qr, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/engine/update.go b/go/vt/vtgate/engine/update.go index 27ca9ad12a1..49c8576fd84 100644 --- a/go/vt/vtgate/engine/update.go +++ b/go/vt/vtgate/engine/update.go @@ -102,7 +102,7 @@ func (upd *Update) updateVindexEntries(ctx context.Context, vcursor VCursor, bin for i := range rss { queries[i] = &querypb.BoundQuery{Sql: upd.OwnedVindexQuery, BindVariables: bindVars} } - subQueryResult, errors := vcursor.ExecuteMultiShard(ctx, upd, rss, queries, false /* rollbackOnError */, false /* canAutocommit */) + subQueryResult, errors := vcursor.ExecuteMultiShard(ctx, upd, rss, queries, false /*rollbackOnError*/, false /*canAutocommit*/, upd.FetchLastInsertID) for _, err := range errors { if err != nil { return err @@ -214,6 +214,9 @@ func (upd *Update) description() PrimitiveDescription { if len(changedVindexes) > 0 { other["ChangedVindexValues"] = changedVindexes } + if upd.FetchLastInsertID { + other["FetchLastInsertID"] = upd.FetchLastInsertID + } return PrimitiveDescription{ OperatorType: "Update", diff --git a/go/vt/vtgate/engine/vexplain.go b/go/vt/vtgate/engine/vexplain.go index 78941e8160f..0785f4d25ce 100644 --- a/go/vt/vtgate/engine/vexplain.go +++ b/go/vt/vtgate/engine/vexplain.go @@ -207,7 +207,7 @@ func (v *VExplain) convertToVExplainAllResult(ctx context.Context, vcursor VCurs res, err := vcursor.ExecuteStandalone(ctx, nil, explainQuery, nil, &srvtopo.ResolvedShard{ Target: entry.Target, Gateway: entry.Gateway, - }) + }, false) if err != nil { return nil, err } diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index c85c651415c..0281e28700f 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -238,9 +238,9 @@ func (e *Executor) Execute(ctx context.Context, mysqlCtx vtgateservice.MySQLConn stmtType, result, err := e.execute(ctx, mysqlCtx, safeSession, sql, bindVars, logStats) logStats.Error = err if result == nil { - saveSessionStats(safeSession, stmtType, 0, 0, 0, err) + saveSessionStats(safeSession, stmtType, 0, 0, err) } else { - saveSessionStats(safeSession, stmtType, result.RowsAffected, result.InsertID, len(result.Rows), err) + saveSessionStats(safeSession, stmtType, result.RowsAffected, len(result.Rows), err) } if result != nil && len(result.Rows) > warnMemoryRows { warnings.Add("ResultsExceeded", 1) @@ -270,7 +270,6 @@ type streaminResultReceiver struct { stmtType sqlparser.StatementType rowsAffected uint64 rowsReturned int - insertID uint64 callback func(*sqltypes.Result) error } @@ -279,9 +278,6 @@ func (s *streaminResultReceiver) storeResultStats(typ sqlparser.StatementType, q defer s.mu.Unlock() s.rowsAffected += qr.RowsAffected s.rowsReturned += len(qr.Rows) - if qr.InsertID != 0 { - s.insertID = qr.InsertID - } s.stmtType = typ return s.callback(qr) } @@ -383,7 +379,7 @@ func (e *Executor) StreamExecute( err = e.newExecute(ctx, mysqlCtx, safeSession, sql, bindVars, logStats, resultHandler, srr.storeResultStats) logStats.Error = err - saveSessionStats(safeSession, srr.stmtType, srr.rowsAffected, srr.insertID, srr.rowsReturned, err) + saveSessionStats(safeSession, srr.stmtType, srr.rowsAffected, srr.rowsReturned, err) if srr.rowsReturned > warnMemoryRows { warnings.Add("ResultsExceeded", 1) piiSafeSQL, err := e.env.Parser().RedactSQLQuery(sql) @@ -416,7 +412,7 @@ func canReturnRows(stmtType sqlparser.StatementType) bool { } } -func saveSessionStats(safeSession *econtext.SafeSession, stmtType sqlparser.StatementType, rowsAffected, insertID uint64, rowsReturned int, err error) { +func saveSessionStats(safeSession *econtext.SafeSession, stmtType sqlparser.StatementType, rowsAffected uint64, rowsReturned int, err error) { safeSession.RowCount = -1 if err != nil { return @@ -424,9 +420,6 @@ func saveSessionStats(safeSession *econtext.SafeSession, stmtType sqlparser.Stat if !safeSession.IsFoundRowsHandled() { safeSession.FoundRows = uint64(rowsReturned) } - if insertID > 0 { - safeSession.LastInsertId = insertID - } switch stmtType { case sqlparser.StmtInsert, sqlparser.StmtReplace, sqlparser.StmtUpdate, sqlparser.StmtDelete: safeSession.RowCount = int64(rowsAffected) @@ -682,7 +675,7 @@ func (e *Executor) executeSPInAllSessions(ctx context.Context, safeSession *econ }) queries = append(queries, &querypb.BoundQuery{Sql: sql}) } - qr, errs = e.ExecuteMultiShard(ctx, nil, rss, queries, safeSession, false /*autocommit*/, ignoreMaxMemoryRows, nullResultsObserver{}) + qr, errs = e.ExecuteMultiShard(ctx, nil, rss, queries, safeSession, false /*autocommit*/, ignoreMaxMemoryRows, nullResultsObserver{}, false) err := vterrors.Aggregate(errs) if err != nil { return nil, err @@ -1484,13 +1477,13 @@ func parseAndValidateQuery(query string, parser *sqlparser.Parser) (sqlparser.St } // ExecuteMultiShard implements the IExecutor interface -func (e *Executor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *econtext.SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver econtext.ResultsObserver) (qr *sqltypes.Result, errs []error) { - return e.scatterConn.ExecuteMultiShard(ctx, primitive, rss, queries, session, autocommit, ignoreMaxMemoryRows, resultsObserver) +func (e *Executor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *econtext.SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver econtext.ResultsObserver, fetchLastInsertID bool) (qr *sqltypes.Result, errs []error) { + return e.scatterConn.ExecuteMultiShard(ctx, primitive, rss, queries, session, autocommit, ignoreMaxMemoryRows, resultsObserver, fetchLastInsertID) } // StreamExecuteMulti implements the IExecutor interface -func (e *Executor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *econtext.SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, resultsObserver econtext.ResultsObserver) []error { - return e.scatterConn.StreamExecuteMulti(ctx, primitive, query, rss, vars, session, autocommit, callback, resultsObserver) +func (e *Executor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *econtext.SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, resultsObserver econtext.ResultsObserver, fetchLastInsertID bool) []error { + return e.scatterConn.StreamExecuteMulti(ctx, primitive, query, rss, vars, session, autocommit, callback, resultsObserver, fetchLastInsertID) } // ExecuteLock implements the IExecutor interface diff --git a/go/vt/vtgate/executor_dml_test.go b/go/vt/vtgate/executor_dml_test.go index 792e197f48d..503b5e5cd8b 100644 --- a/go/vt/vtgate/executor_dml_test.go +++ b/go/vt/vtgate/executor_dml_test.go @@ -1812,8 +1812,9 @@ func TestInsertGeneratorSharded(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -1840,8 +1841,9 @@ func TestInsertGeneratorSharded(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, } utils.MustMatch(t, wantResult, result) } @@ -1854,8 +1856,9 @@ func TestInsertAutoincSharded(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 2, + RowsAffected: 1, + InsertID: 2, + InsertIDChanged: true, } sbc.SetResults([]*sqltypes.Result{wantResult}) session := &vtgatepb.Session{ @@ -1894,8 +1897,9 @@ func TestInsertGeneratorUnsharded(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertID: 1, + InsertIDChanged: true, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } @@ -1912,8 +1916,9 @@ func TestInsertAutoincUnsharded(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 2, + RowsAffected: 1, + InsertID: 2, + InsertIDChanged: true, } sbclookup.SetResults([]*sqltypes.Result{wantResult}) @@ -1965,8 +1970,9 @@ func TestInsertLookupOwnedGenerator(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(4), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertID: 1, + InsertIDChanged: true, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -1993,8 +1999,9 @@ func TestInsertLookupOwnedGenerator(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 4, - RowsAffected: 1, + InsertID: 4, + InsertIDChanged: true, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } @@ -2226,8 +2233,9 @@ func TestMultiInsertGenerator(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -2258,8 +2266,9 @@ func TestMultiInsertGenerator(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } @@ -2271,8 +2280,9 @@ func TestMultiInsertGeneratorSparse(t *testing.T) { Rows: [][]sqltypes.Value{{ sqltypes.NewInt64(1), }}, - RowsAffected: 1, - InsertID: 1, + RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, }}) session := &vtgatepb.Session{ TargetString: "@primary", @@ -2307,8 +2317,9 @@ func TestMultiInsertGeneratorSparse(t *testing.T) { }} assertQueries(t, sbclookup, wantQueries) wantResult := &sqltypes.Result{ - InsertID: 1, - RowsAffected: 1, + InsertIDChanged: true, + InsertID: 1, + RowsAffected: 1, } utils.MustMatch(t, wantResult, result) } diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index c1e80440ebe..23969db384d 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -3302,6 +3302,49 @@ func TestSelectFromInformationSchema(t *testing.T) { sbc1.StringQueries()) } +func TestStreamOrderByWithMultipleResults(t *testing.T) { + ctx := utils.LeakCheckContext(t) + + // Special setup: Don't use createExecutorEnv. + cell := "aa" + hc := discovery.NewFakeHealthCheck(nil) + u := createSandbox(KsTestUnsharded) + s := createSandbox(KsTestSharded) + s.VSchema = executorVSchema + u.VSchema = unshardedVSchema + serv := newSandboxForCells(ctx, []string{cell}) + resolver := newTestResolver(ctx, hc, serv, cell) + shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"} + count := 1 + for _, shard := range shards { + sbc := hc.AddTestTablet(cell, shard, 1, "TestExecutor", shard, topodatapb.TabletType_PRIMARY, true, 1, nil) + sbc.SetResults([]*sqltypes.Result{ + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col|weight_string(id)", "int32|int32|varchar"), fmt.Sprintf("%d|%d|NULL", count, count)), + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col|weight_string(id)", "int32|int32|varchar"), fmt.Sprintf("%d|%d|NULL", count+10, count)), + }) + count++ + } + queryLogger := streamlog.New[*logstats.LogStats]("VTGate", queryLogBufferSize) + plans := DefaultPlanCache() + executor := NewExecutor(ctx, vtenv.NewTestEnv(), serv, cell, resolver, true, false, testBufferSize, plans, nil, false, querypb.ExecuteOptions_Gen4, 0) + executor.SetQueryLogger(queryLogger) + defer executor.Close() + // some sleep for all goroutines to start + time.Sleep(100 * time.Millisecond) + before := runtime.NumGoroutine() + + query := "select id, col from user order by id" + gotResult, err := executorStream(ctx, executor, query) + require.NoError(t, err) + + wantResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col", "int32|int32"), + "1|1", "2|2", "3|3", "4|4", "5|5", "6|6", "7|7", "8|8", "11|1", "12|2", "13|3", "14|4", "15|5", "16|6", "17|7", "18|8") + assert.Equal(t, fmt.Sprintf("%v", wantResult.Rows), fmt.Sprintf("%v", gotResult.Rows)) + // some sleep to close all goroutines. + time.Sleep(100 * time.Millisecond) + assert.GreaterOrEqual(t, before, runtime.NumGoroutine(), "left open goroutines lingering") +} + func TestStreamOrderByLimitWithMultipleResults(t *testing.T) { ctx := utils.LeakCheckContext(t) diff --git a/go/vt/vtgate/executorcontext/vcursor_impl.go b/go/vt/vtgate/executorcontext/vcursor_impl.go index c1f341b38cf..40317f5103a 100644 --- a/go/vt/vtgate/executorcontext/vcursor_impl.go +++ b/go/vt/vtgate/executorcontext/vcursor_impl.go @@ -95,8 +95,8 @@ type ( // vcursor_impl needs these facilities to be able to be able to execute queries for vindexes iExecute interface { Execute(ctx context.Context, mysqlCtx vtgateservice.MySQLConnection, method string, session *SafeSession, s string, vars map[string]*querypb.BindVariable) (*sqltypes.Result, error) - ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver) (qr *sqltypes.Result, errs []error) - StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver) []error + ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver, fetchLastInsertID bool) (qr *sqltypes.Result, errs []error) + StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver, fetchLastInsertID bool) []error ExecuteLock(ctx context.Context, rs *srvtopo.ResolvedShard, query *querypb.BoundQuery, session *SafeSession, lockFuncType sqlparser.LockingFuncType) (*sqltypes.Result, error) Commit(ctx context.Context, safeSession *SafeSession) error ExecuteMessageStream(ctx context.Context, rss []*srvtopo.ResolvedShard, name string, callback func(*sqltypes.Result) error) error @@ -675,12 +675,20 @@ func (vc *VCursorImpl) ExecutePrimitiveStandalone(ctx context.Context, primitive func (vc *VCursorImpl) wrapCallback(callback func(*sqltypes.Result) error, primitive engine.Primitive) func(*sqltypes.Result) error { if vc.interOpStats == nil { - return callback + return func(r *sqltypes.Result) error { + if r.InsertIDUpdated() { + vc.SafeSession.LastInsertId = r.InsertID + } + return callback(r) + } } - return func(result *sqltypes.Result) error { - vc.logOpTraffic(primitive, result) - return callback(result) + return func(r *sqltypes.Result) error { + if r.InsertIDUpdated() { + vc.SafeSession.LastInsertId = r.InsertID + } + vc.logOpTraffic(primitive, r) + return callback(r) } } @@ -753,7 +761,7 @@ func (vc *VCursorImpl) markSavepoint(ctx context.Context, needsRollbackOnParialE } // ExecuteMultiShard is part of the engine.VCursor interface. -func (vc *VCursorImpl) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { +func (vc *VCursorImpl) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit, fetchLastInsertID bool) (*sqltypes.Result, []error) { noOfShards := len(rss) atomic.AddUint64(&vc.logStats.ShardQueries, uint64(noOfShards)) err := vc.markSavepoint(ctx, rollbackOnError && (noOfShards > 1), map[string]*querypb.BindVariable{}) @@ -761,14 +769,17 @@ func (vc *VCursorImpl) ExecuteMultiShard(ctx context.Context, primitive engine.P return nil, []error{err} } - qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, commentedShardQueries(queries, vc.marginComments), vc.SafeSession, canAutocommit, vc.ignoreMaxMemoryRows, vc.observer) + qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, commentedShardQueries(queries, vc.marginComments), vc.SafeSession, canAutocommit, vc.ignoreMaxMemoryRows, vc.observer, fetchLastInsertID) vc.setRollbackOnPartialExecIfRequired(len(errs) != len(rss), rollbackOnError) vc.logShardsQueried(primitive, len(rss)) + if qr != nil && qr.InsertIDUpdated() { + vc.SafeSession.LastInsertId = qr.InsertID + } return qr, errs } // StreamExecuteMulti is the streaming version of ExecuteMultiShard. -func (vc *VCursorImpl) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError bool, autocommit bool, callback func(reply *sqltypes.Result) error) []error { +func (vc *VCursorImpl) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, rollbackOnError, autocommit, fetchLastInsertID bool, callback func(reply *sqltypes.Result) error) []error { callback = vc.wrapCallback(callback, primitive) noOfShards := len(rss) @@ -778,7 +789,7 @@ func (vc *VCursorImpl) StreamExecuteMulti(ctx context.Context, primitive engine. return []error{err} } - errs := vc.executor.StreamExecuteMulti(ctx, primitive, vc.marginComments.Leading+query+vc.marginComments.Trailing, rss, bindVars, vc.SafeSession, autocommit, callback, vc.observer) + errs := vc.executor.StreamExecuteMulti(ctx, primitive, vc.marginComments.Leading+query+vc.marginComments.Trailing, rss, bindVars, vc.SafeSession, autocommit, callback, vc.observer, fetchLastInsertID) vc.setRollbackOnPartialExecIfRequired(len(errs) != len(rss), rollbackOnError) return errs @@ -791,7 +802,7 @@ func (vc *VCursorImpl) ExecuteLock(ctx context.Context, rs *srvtopo.ResolvedShar } // ExecuteStandalone is part of the engine.VCursor interface. -func (vc *VCursorImpl) ExecuteStandalone(ctx context.Context, primitive engine.Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { +func (vc *VCursorImpl) ExecuteStandalone(ctx context.Context, primitive engine.Primitive, query string, bindVars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard, fetchLastInsertID bool) (*sqltypes.Result, error) { rss := []*srvtopo.ResolvedShard{rs} bqs := []*querypb.BoundQuery{ { @@ -801,8 +812,11 @@ func (vc *VCursorImpl) ExecuteStandalone(ctx context.Context, primitive engine.P } // The autocommit flag is always set to false because we currently don't // execute DMLs through ExecuteStandalone. - qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, bqs, NewAutocommitSession(vc.SafeSession.Session), false /* autocommit */, vc.ignoreMaxMemoryRows, vc.observer) + qr, errs := vc.executor.ExecuteMultiShard(ctx, primitive, rss, bqs, NewAutocommitSession(vc.SafeSession.Session), false /* autocommit */, vc.ignoreMaxMemoryRows, vc.observer, fetchLastInsertID) vc.logShardsQueried(primitive, len(rss)) + if qr.InsertIDUpdated() { + vc.SafeSession.LastInsertId = qr.InsertID + } return qr, vterrors.Aggregate(errs) } @@ -829,7 +843,7 @@ func (vc *VCursorImpl) ExecuteKeyspaceID(ctx context.Context, keyspace string, k vc.SafeSession.SetQueryFromVindex(false) }() } - qr, errs := vc.ExecuteMultiShard(ctx, nil, rss, queries, rollbackOnError, autocommit) + qr, errs := vc.ExecuteMultiShard(ctx, nil, rss, queries, rollbackOnError, autocommit, false) return qr, vterrors.Aggregate(errs) } diff --git a/go/vt/vtgate/executorcontext/vcursor_impl_test.go b/go/vt/vtgate/executorcontext/vcursor_impl_test.go index 16d2c03bf1c..08e27be4c51 100644 --- a/go/vt/vtgate/executorcontext/vcursor_impl_test.go +++ b/go/vt/vtgate/executorcontext/vcursor_impl_test.go @@ -389,12 +389,12 @@ func (f fakeExecutor) Execute(ctx context.Context, mysqlCtx vtgateservice.MySQLC panic("implement me") } -func (f fakeExecutor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver) (qr *sqltypes.Result, errs []error) { +func (f fakeExecutor) ExecuteMultiShard(ctx context.Context, primitive engine.Primitive, rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, session *SafeSession, autocommit bool, ignoreMaxMemoryRows bool, resultsObserver ResultsObserver, fetchLastInsertID bool) (qr *sqltypes.Result, errs []error) { // TODO implement me panic("implement me") } -func (f fakeExecutor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver) []error { +func (f fakeExecutor) StreamExecuteMulti(ctx context.Context, primitive engine.Primitive, query string, rss []*srvtopo.ResolvedShard, vars []map[string]*querypb.BindVariable, session *SafeSession, autocommit bool, callback func(reply *sqltypes.Result) error, observer ResultsObserver, fetchLastInsertID bool) []error { // TODO implement me panic("implement me") } diff --git a/go/vt/vtgate/grpcvtgateconn/suite_test.go b/go/vt/vtgate/grpcvtgateconn/suite_test.go index 0e544b05e66..32df3a2ab34 100644 --- a/go/vt/vtgate/grpcvtgateconn/suite_test.go +++ b/go/vt/vtgate/grpcvtgateconn/suite_test.go @@ -426,6 +426,7 @@ func testStreamExecute(t *testing.T, session *vtgateconn.VTGateSession) { wantResult := *execCase.result wantResult.RowsAffected = 0 wantResult.InsertID = 0 + wantResult.InsertIDChanged = false if !qr.Equal(&wantResult) { t.Errorf("Unexpected result from StreamExecute: got %+v want %+v", qr, wantResult) } @@ -563,8 +564,9 @@ var result1 = sqltypes.Result{ Type: sqltypes.Int32, }, }, - RowsAffected: 123, - InsertID: 72, + RowsAffected: 123, + InsertID: 72, + InsertIDChanged: true, Rows: [][]sqltypes.Value{ { sqltypes.TestValue(sqltypes.Int16, "1"), diff --git a/go/vt/vtgate/legacy_scatter_conn_test.go b/go/vt/vtgate/legacy_scatter_conn_test.go index 00f38a97f9f..fecd6c2a8b1 100644 --- a/go/vt/vtgate/legacy_scatter_conn_test.go +++ b/go/vt/vtgate/legacy_scatter_conn_test.go @@ -101,7 +101,7 @@ func TestLegacyExecuteFailOnAutocommit(t *testing.T) { }, Autocommit: false, } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}, false) err := vterrors.Aggregate(errs) require.Error(t, err) require.Contains(t, err.Error(), "in autocommit mode, transactionID should be zero but was: 123") @@ -125,7 +125,7 @@ func TestScatterConnExecuteMulti(t *testing.T) { } } - qr, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(nil), false /*autocommit*/, false, nullResultsObserver{}) + qr, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(nil), false /*autocommit*/, false, nullResultsObserver{}, false) return qr, vterrors.Aggregate(errs) }) } @@ -145,7 +145,7 @@ func TestScatterConnStreamExecuteMulti(t *testing.T) { defer mu.Unlock() qr.AppendResult(r) return nil - }, nullResultsObserver{}) + }, nullResultsObserver{}, false) return qr, vterrors.Aggregate(errors) }) } @@ -312,7 +312,7 @@ func TestMaxMemoryRows(t *testing.T) { sbc0.SetResults([]*sqltypes.Result{tworows, tworows}) sbc1.SetResults([]*sqltypes.Result{tworows, tworows}) - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, test.ignoreMaxMemoryRows, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, test.ignoreMaxMemoryRows, nullResultsObserver{}, false) if test.ignoreMaxMemoryRows { require.NoError(t, err) } else { @@ -344,7 +344,7 @@ func TestLegaceHealthCheckFailsOnReservedConnections(t *testing.T) { }) } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}, false) require.Error(t, vterrors.Aggregate(errs)) } @@ -367,7 +367,7 @@ func executeOnShardsReturnsErr(t *testing.T, ctx context.Context, res *srvtopo.R }) } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, nullResultsObserver{}, false) return vterrors.Aggregate(errs) } @@ -432,7 +432,7 @@ func TestMultiExecs(t *testing.T) { observer := recordingResultsObserver{} session := econtext.NewSafeSession(&vtgatepb.Session{}) - _, err := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, &observer) + _, err := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, false, false, &observer, false) require.NoError(t, vterrors.Aggregate(err)) if len(sbc0.Queries) == 0 || len(sbc1.Queries) == 0 { t.Fatalf("didn't get expected query") @@ -484,7 +484,7 @@ func TestMultiExecs(t *testing.T) { observer = recordingResultsObserver{} _ = sc.StreamExecuteMulti(ctx, nil, "query", rss, bvs, session, false /* autocommit */, func(*sqltypes.Result) error { return nil - }, &observer) + }, &observer, false) if !reflect.DeepEqual(sbc0.Queries[0].BindVariables, wantVars0) { t.Errorf("got %+v, want %+v", sbc0.Queries[0].BindVariables, wantVars0) } @@ -515,27 +515,27 @@ func TestScatterConnSingleDB(t *testing.T) { // TransactionMode_SINGLE in session session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, TransactionMode: vtgatepb.TransactionMode_SINGLE}) queries := []*querypb.BoundQuery{{Sql: "query1"}} - _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Error(t, errors[0]) assert.Contains(t, errors[0].Error(), want) // TransactionMode_SINGLE in txconn sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_SINGLE} session = econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Error(t, errors[0]) assert.Contains(t, errors[0].Error(), want) // TransactionMode_MULTI in txconn. Should not fail. sc.txConn.txMode = &StaticConfig{TxMode: vtgatepb.TransactionMode_MULTI} session = econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) - _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errors = sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errors) } diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go index df14745e6b2..bc71c7195b4 100644 --- a/go/vt/vtgate/planbuilder/operator_transformers.go +++ b/go/vt/vtgate/planbuilder/operator_transformers.go @@ -22,12 +22,10 @@ import ( "strconv" "strings" - "vitess.io/vitess/go/mysql/collations" "vitess.io/vitess/go/slice" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/sysvars" - "vitess.io/vitess/go/vt/vtenv" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vtgate/engine" "vitess.io/vitess/go/vt/vtgate/engine/opcode" @@ -536,6 +534,7 @@ func routeToEngineRoute(ctx *plancontext.PlanningContext, op *operators.Route, h TableName: strings.Join(tableNames, ", "), RoutingParameters: rp, TruncateColumnCount: op.ResultColumns, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), } if hints != nil { e.ScatterErrorsAsWarnings = hints.scatterErrorsAsWarnings @@ -601,7 +600,7 @@ func transformRoutePlan(ctx *plancontext.PlanningContext, op *operators.Route) ( case *sqlparser.Delete: return buildDeletePrimitive(ctx, op, dmlOp, stmt, hints) case *sqlparser.Insert: - return buildInsertPrimitive(op, dmlOp, stmt, hints) + return buildInsertPrimitive(ctx, op, dmlOp, stmt, hints) default: return nil, vterrors.VT13001(fmt.Sprintf("dont know how to %T", stmt)) } @@ -637,18 +636,22 @@ func buildRoutePrimitive(ctx *plancontext.PlanningContext, op *operators.Route, } func buildInsertPrimitive( - rb *operators.Route, op operators.Operator, stmt *sqlparser.Insert, + ctx *plancontext.PlanningContext, + rb *operators.Route, + op operators.Operator, + stmt *sqlparser.Insert, hints *queryHints, ) (engine.Primitive, error) { ins := op.(*operators.Insert) ic := engine.InsertCommon{ - Opcode: mapToInsertOpCode(rb.Routing.OpCode()), - Keyspace: rb.Routing.Keyspace(), - TableName: ins.VTable.Name.String(), - Ignore: ins.Ignore, - Generate: autoIncGenerate(ins.AutoIncrement), - ColVindexes: ins.ColVindexes, + Opcode: mapToInsertOpCode(rb.Routing.OpCode()), + Keyspace: rb.Routing.Keyspace(), + TableName: ins.VTable.Name.String(), + Ignore: ins.Ignore, + Generate: autoIncGenerate(ins.AutoIncrement), + ColVindexes: ins.ColVindexes, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), } if hints != nil { ic.MultiShardAutocommit = hints.multiShardAutocommit @@ -656,8 +659,9 @@ func buildInsertPrimitive( } eins := &engine.Insert{ - InsertCommon: ic, - VindexValues: ins.VindexValues, + InsertCommon: ic, + VindexValues: ins.VindexValues, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), } // we would need to generate the query on the fly. The only exception here is @@ -788,6 +792,7 @@ func createDMLPrimitive(ctx *plancontext.PlanningContext, rb *operators.Route, h Vindexes: colVindexes, OwnedVindexQuery: vindexQuery, RoutingParameters: rp, + FetchLastInsertID: ctx.SemTable.ShouldFetchLastInsertID(), } if rb.Routing.OpCode() != engine.Unsharded && vindexQuery != "" { @@ -880,18 +885,18 @@ func transformUnionPlan(ctx *plancontext.PlanningContext, op *operators.Union) ( } func transformLimit(ctx *plancontext.PlanningContext, op *operators.Limit) (engine.Primitive, error) { - plan, err := transformToPrimitive(ctx, op.Source) + input, err := transformToPrimitive(ctx, op.Source) if err != nil { return nil, err } - return createLimit(plan, op.AST, ctx.VSchema.Environment(), ctx.VSchema.ConnCollation()) + return createLimit(ctx, input, op.AST) } -func createLimit(input engine.Primitive, limit *sqlparser.Limit, env *vtenv.Environment, coll collations.ID) (engine.Primitive, error) { +func createLimit(ctx *plancontext.PlanningContext, input engine.Primitive, limit *sqlparser.Limit) (engine.Primitive, error) { cfg := &evalengine.Config{ - Collation: coll, - Environment: env, + Collation: ctx.VSchema.ConnCollation(), + Environment: ctx.VSchema.Environment(), } count, err := evalengine.Translate(limit.Rowcount, cfg) if err != nil { @@ -906,9 +911,10 @@ func createLimit(input engine.Primitive, limit *sqlparser.Limit, env *vtenv.Envi } return &engine.Limit{ - Input: input, - Count: count, - Offset: offset, + Count: count, + Offset: offset, + RequireCompleteInput: ctx.SemTable.ShouldFetchLastInsertID(), + Input: input, }, nil } diff --git a/go/vt/vtgate/planbuilder/operators/sharded_routing.go b/go/vt/vtgate/planbuilder/operators/sharded_routing.go index 066cb47d9a9..2c8873dee07 100644 --- a/go/vt/vtgate/planbuilder/operators/sharded_routing.go +++ b/go/vt/vtgate/planbuilder/operators/sharded_routing.go @@ -223,6 +223,9 @@ func (tr *ShardedRouting) resetRoutingLogic(ctx *plancontext.PlanningContext) Ro func (tr *ShardedRouting) searchForNewVindexes(ctx *plancontext.PlanningContext, predicate sqlparser.Expr) (Routing, bool) { newVindexFound := false switch node := predicate.(type) { + case *sqlparser.BetweenExpr: + return tr.planBetweenOp(ctx, node) + case *sqlparser.ComparisonExpr: return tr.planComparison(ctx, node) @@ -234,6 +237,35 @@ func (tr *ShardedRouting) searchForNewVindexes(ctx *plancontext.PlanningContext, return nil, newVindexFound } +func (tr *ShardedRouting) planBetweenOp(ctx *plancontext.PlanningContext, node *sqlparser.BetweenExpr) (routing Routing, foundNew bool) { + column, ok := node.Left.(*sqlparser.ColName) + if !ok { + return nil, false + } + var vdValue sqlparser.ValTuple = sqlparser.ValTuple([]sqlparser.Expr{node.From, node.To}) + + opcode := func(vindex *vindexes.ColumnVindex) engine.Opcode { + if _, ok := vindex.Vindex.(vindexes.Sequential); ok { + return engine.Between + } + return engine.Scatter + } + + sequentialVdx := func(vindex *vindexes.ColumnVindex) vindexes.Vindex { + if _, ok := vindex.Vindex.(vindexes.Sequential); ok { + return vindex.Vindex + } + // if vindex is not of type Sequential, we can't use this vindex at all + return nil + } + + val := makeEvalEngineExpr(ctx, vdValue) + if val == nil { + return nil, false + } + return nil, tr.haveMatchingVindex(ctx, node, vdValue, column, val, opcode, sequentialVdx) +} + func (tr *ShardedRouting) planComparison(ctx *plancontext.PlanningContext, cmp *sqlparser.ComparisonExpr) (routing Routing, foundNew bool) { switch cmp.Operator { case sqlparser.EqualOp: @@ -332,6 +364,8 @@ func (tr *ShardedRouting) Cost() int { return 5 case engine.IN: return 10 + case engine.Between: + return 10 case engine.MultiEqual: return 10 case engine.Scatter: @@ -441,6 +475,12 @@ func (tr *ShardedRouting) processMultiColumnVindex( return newVindexFound } + routeOpcode := opcode(v.ColVindex) + vindex := vfunc(v.ColVindex) + if vindex == nil || routeOpcode == engine.Scatter { + return newVindexFound + } + var newOption []*VindexOption for _, op := range v.Options { if op.Ready { diff --git a/go/vt/vtgate/planbuilder/plan_test.go b/go/vt/vtgate/planbuilder/plan_test.go index 7135f4dff29..df813b04dea 100644 --- a/go/vt/vtgate/planbuilder/plan_test.go +++ b/go/vt/vtgate/planbuilder/plan_test.go @@ -666,7 +666,7 @@ func (s *planTestSuite) testFile(filename string, vschema *vschemawrapper.VSchem current := PlanTest{ Comment: tcase.Comment, Query: tcase.Query, - SkipE2E: tcase.SkipE2E, + SkipE2E: true, } vschema.Version = Gen4 out := getPlanOutput(tcase, vschema, render) diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json index f796b935605..8893b4df0c0 100644 --- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json @@ -2,12 +2,14 @@ { "comment": "update table not found", "query": "update nouser set val = 1", - "plan": "table nouser not found" + "plan": "table nouser not found", + "skip_e2e": true }, { "comment": "delete table not found", "query": "delete from nouser", - "plan": "table nouser not found" + "plan": "table nouser not found", + "skip_e2e": true }, { "comment": "explicit keyspace reference", @@ -29,7 +31,8 @@ "TablesUsed": [ "main.m1" ] - } + }, + "skip_e2e": true }, { "comment": "update unsharded", @@ -51,7 +54,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "subqueries in unsharded update", @@ -73,7 +77,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded union in subquery of unsharded update", @@ -95,7 +100,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded join in subquery of unsharded update", @@ -117,7 +123,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "update with join subquery", @@ -139,7 +146,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "routing rules: updated of a routed table", @@ -165,7 +173,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update: routing rules for subquery.", @@ -188,7 +197,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "delete unsharded", @@ -210,7 +220,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "delete from sequence", @@ -232,7 +243,8 @@ "TablesUsed": [ "main.seq" ] - } + }, + "skip_e2e": true }, { "comment": "delete from reference table in unsharded keyspace", @@ -254,7 +266,8 @@ "TablesUsed": [ "main.unsharded_ref" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id", @@ -280,7 +293,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id with alias", @@ -306,7 +320,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id with parenthesized expression", @@ -332,7 +347,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id with multi-part where clause with parens", @@ -358,7 +374,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing one vindex column", @@ -390,12 +407,14 @@ "TablesUsed": [ "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing same vindex twice", "query": "update user_metadata set email = 'a', email = 'b' where user_id = 1", - "plan": "VT03015: column has duplicate set values: 'email'" + "plan": "VT03015: column has duplicate set values: 'email'", + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing multiple vindex columns", @@ -428,7 +447,8 @@ "TablesUsed": [ "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, changing one vindex column, using order by and limit", @@ -460,7 +480,8 @@ "TablesUsed": [ "user.user_metadata" ] - } + }, + "skip_e2e": true }, { "comment": "update changes non owned vindex column", @@ -492,7 +513,8 @@ "TablesUsed": [ "user.music_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, stray where clause", @@ -518,7 +540,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update by primary keyspace id, stray where clause with conversion error", @@ -544,7 +567,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from by primary keyspace id", @@ -573,7 +597,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi-table delete with comma join", @@ -596,7 +621,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "multi-table delete with ansi join", @@ -619,7 +645,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "delete with join from subquery", @@ -641,7 +668,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "routing rules: deleted from a routed table", @@ -670,7 +698,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete: routing rules for subquery", @@ -693,7 +722,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "update by lookup", @@ -719,7 +749,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "update multi-table ansi join", @@ -742,7 +773,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "update multi-table comma join", @@ -765,7 +797,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "delete from by lookup", @@ -794,7 +827,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "delete from, no owned vindexes", @@ -820,7 +854,8 @@ "TablesUsed": [ "user.music_extra" ] - } + }, + "skip_e2e": true }, { "comment": "simple insert, no values", @@ -842,7 +877,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "simple insert unsharded", @@ -864,7 +900,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "simple upsert unsharded", @@ -886,7 +923,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert, no col list with auto-inc and authoritative column list", @@ -909,7 +947,8 @@ "TablesUsed": [ "main.unsharded_authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "sharded upsert with sharding key set to vindex column", @@ -936,7 +975,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "sharded bulk upsert with sharding key set to vindex column", @@ -963,7 +1003,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded with select", @@ -986,7 +1027,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded with select with join", @@ -1009,7 +1051,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, invalid value for auto-inc", @@ -1032,7 +1075,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, column present", @@ -1055,7 +1099,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, column absent", @@ -1078,7 +1123,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, column absent", @@ -1101,7 +1147,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "insert unsharded, multi-val", @@ -1124,7 +1171,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert subquery in insert value", @@ -1146,7 +1194,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "sharded insert subquery in insert value", @@ -1174,7 +1223,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into a routed table", @@ -1202,12 +1252,14 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with mimatched column list", "query": "insert into user(id) values (1, 2)", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert no column list for sharded authoritative table", @@ -1232,7 +1284,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "insert sharded, no values", @@ -1260,7 +1313,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with one vindex", @@ -1288,7 +1342,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert ignore sharded", @@ -1317,7 +1372,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert on duplicate key", @@ -1346,7 +1402,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with one vindex and bind var", @@ -1374,7 +1431,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with non vindex", @@ -1402,7 +1460,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with default seq", @@ -1430,7 +1489,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with non vindex bool value", @@ -1458,7 +1518,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with all vindexes supplied", @@ -1486,7 +1547,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert for non-vindex autoinc", @@ -1512,7 +1574,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert for non-compliant names", @@ -1537,7 +1600,8 @@ "TablesUsed": [ "user.weird`name" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert from union", @@ -1560,7 +1624,8 @@ "main.dual", "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "insert for non-vindex autoinc, invalid value", @@ -1586,7 +1651,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert invalid index value", @@ -1612,17 +1678,20 @@ "TablesUsed": [ "user.music_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert invalid index value", "query": "insert into music_extra(music_id, user_id) values(1, id)", - "plan": "cannot lookup column 'id' (column access not supported here)" + "plan": "cannot lookup column 'id' (column access not supported here)", + "skip_e2e": true }, { "comment": "insert invalid table", "query": "insert into noexist(music_id, user_id) values(1, 18446744073709551616)", - "plan": "table noexist not found" + "plan": "table noexist not found", + "skip_e2e": true }, { "comment": "insert with multiple rows", @@ -1650,7 +1719,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with query timeout", @@ -1679,7 +1749,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert with multiple rows - multi-shard autocommit", @@ -1708,12 +1779,14 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into a vindex not allowed", "query": "insert into user_index(id) values(1)", - "plan": "VT09014: vindex cannot be modified" + "plan": "VT09014: vindex cannot be modified", + "skip_e2e": true }, { "comment": "simple replace unsharded", @@ -1735,7 +1808,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded with select", @@ -1758,7 +1832,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, invalid value for auto-inc", @@ -1781,7 +1856,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, column present", @@ -1804,7 +1880,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, column absent", @@ -1827,7 +1904,8 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace unsharded, multi-val", @@ -1850,12 +1928,14 @@ "TablesUsed": [ "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "replace invalid table", "query": "replace into noexist(music_id, user_id) values(1, 18446744073709551616)", - "plan": "table noexist not found" + "plan": "table noexist not found", + "skip_e2e": true }, { "comment": "insert a row in a multi column vindex table", @@ -1882,7 +1962,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "insert for overlapped vindex columns", @@ -1908,7 +1989,8 @@ "TablesUsed": [ "user.overlap_vindex" ] - } + }, + "skip_e2e": true }, { "comment": "insert multiple rows in a multi column vindex table", @@ -1935,7 +2017,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "delete row in a multi column vindex table", @@ -1964,7 +2047,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update columns of multi column vindex", @@ -1996,7 +2080,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update multiple vindexes, with multi column vindex", @@ -2029,7 +2114,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update with no primary vindex on where clause (scatter update)", @@ -2051,7 +2137,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with target destination", @@ -2073,7 +2160,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with no primary vindex on where clause (scatter update) - multi shard autocommit", @@ -2096,7 +2184,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with no primary vindex on where clause (scatter update) - query timeout", @@ -2119,7 +2208,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with non-comparison expr", @@ -2141,7 +2231,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with primary id through IN clause", @@ -2167,7 +2258,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with non-unique key", @@ -2189,7 +2281,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update by lookup with IN clause", @@ -2211,7 +2304,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with where clause with parens", @@ -2233,6 +2327,53 @@ "TablesUsed": [ "user.user_extra" ] + }, + "skip_e2e": true + }, + { + "comment": "update with last_insert_id in SET", + "query": "update user_extra set col = last_insert_id(123)", + "plan": { + "QueryType": "UPDATE", + "Original": "update user_extra set col = last_insert_id(123)", + "Instructions": { + "OperatorType": "Update", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "FetchLastInsertID": true, + "Query": "update user_extra set col = last_insert_id(123)", + "Table": "user_extra" + }, + "TablesUsed": [ + "user.user_extra" + ] + } + }, + { + "comment": "delete with last_insert_id in where", + "query": "delete from user_extra where col = last_insert_id(123)", + "plan": { + "QueryType": "DELETE", + "Original": "delete from user_extra where col = last_insert_id(123)", + "Instructions": { + "OperatorType": "Delete", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "TargetTabletType": "PRIMARY", + "FetchLastInsertID": true, + "Query": "delete from user_extra where col = last_insert_id(123)", + "Table": "user_extra" + }, + "TablesUsed": [ + "user.user_extra" + ] } }, { @@ -2255,7 +2396,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete with target destination", @@ -2277,7 +2419,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete with non-comparison expr", @@ -2299,7 +2442,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with no index match", @@ -2321,7 +2465,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with no index match - multi shard autocommit", @@ -2344,7 +2489,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with no index match - query timeout", @@ -2367,7 +2513,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete from with primary id in through IN clause", @@ -2393,7 +2540,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded update where inner query references outer query", @@ -2417,7 +2565,8 @@ "main.unsharded_a", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded delete where inner query references outer query", @@ -2440,7 +2589,8 @@ "main.unsharded", "main.unsharded_a" ] - } + }, + "skip_e2e": true }, { "comment": "update vindex value to null", @@ -2472,7 +2622,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using last_insert_id", @@ -2494,7 +2645,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "update vindex value to null with multiple primary keyspace id", @@ -2526,7 +2678,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update vindex value to null without a where clause", @@ -2554,7 +2707,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update vindex value to null with complex where clause", @@ -2582,7 +2736,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from user by primary keyspace id with in clause", @@ -2611,7 +2766,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from user by complex expression", @@ -2636,7 +2792,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete from user without a where clause", @@ -2661,7 +2818,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with single table targets", @@ -2690,7 +2848,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "scatter update table with owned vindexes without changing lookup vindex", @@ -2712,7 +2871,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "scatter delete with owned lookup vindex", @@ -2737,7 +2897,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update multi column vindex, without values for all the vindex columns", @@ -2769,7 +2930,8 @@ "TablesUsed": [ "user.multicolvin" ] - } + }, + "skip_e2e": true }, { "comment": "update with binary value", @@ -2801,7 +2963,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with binary value", @@ -2830,7 +2993,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with shard targeting", @@ -2855,7 +3019,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with shard targeting", @@ -2883,7 +3048,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with shard targeting without vindex", @@ -2905,7 +3071,8 @@ "TablesUsed": [ "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "multi-table delete with single table", @@ -2930,22 +3097,26 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with unknown reference", "query": "delete music from user where id = 1", - "plan": "VT03003: unknown table 'music' in MULTI DELETE" + "plan": "VT03003: unknown table 'music' in MULTI DELETE", + "skip_e2e": true }, { "comment": "delete with derived tables", "query": "delete music from (select * from user) music where id = 1", - "plan": "VT03004: the target table music of the DELETE is not updatable" + "plan": "VT03004: the target table music of the DELETE is not updatable", + "skip_e2e": true }, { "comment": "delete with derived tables with unknown table", "query": "delete user from (select * from user) music where id = 1", - "plan": "VT03003: unknown table 'user' in MULTI DELETE" + "plan": "VT03003: unknown table 'user' in MULTI DELETE", + "skip_e2e": true }, { "comment": "INSERT INTO main.user_privacy_consents (user_id, accepted_at) SELECT user_id, accepted_at FROM (SELECT 1 as user_id, 1629194864 as accepted_at) AS tmp WHERE NOT EXISTS (SELECT user_id FROM main.user_privacy_consents WHERE user_id = 1)", @@ -2968,7 +3139,8 @@ "main.dual", "main.user_privacy_consents" ] - } + }, + "skip_e2e": true }, { "comment": "Delete on backfilling unique lookup vindex should be a scatter", @@ -2993,7 +3165,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Update on backfilling unique lookup vindex should be a scatter", @@ -3021,7 +3194,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Delete on backfilling and non-backfilling unique lookup vindexes should be a delete equal", @@ -3050,7 +3224,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Update on backfilling and non-backfilling unique lookup vindexes should be an equal", @@ -3082,7 +3257,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Delete EQUAL and IN on backfilling and non-backfilling unique lookup vindexes should be a delete IN", @@ -3111,7 +3287,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "Update EQUAL and IN on backfilling and non-backfilling unique lookup vindexes should be an update IN", @@ -3143,7 +3320,8 @@ "TablesUsed": [ "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "update with alias table", @@ -3171,7 +3349,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with alias table", @@ -3196,7 +3375,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex", @@ -3223,7 +3403,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex - reverse order", @@ -3250,7 +3431,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex using an IN clause", @@ -3277,7 +3459,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with a multicol vindex using an IN clause", @@ -3304,7 +3487,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex", @@ -3334,7 +3518,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex - reverse order", @@ -3364,7 +3549,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex using an IN clause", @@ -3394,7 +3580,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with a multicol vindex using an IN clause", @@ -3424,7 +3611,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with multicol and an owned vindex which changes", @@ -3457,7 +3645,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using non-unique lookup vindex", @@ -3483,7 +3672,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column", @@ -3509,7 +3699,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column on lookup vindex", @@ -3541,7 +3732,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column with in query", @@ -3573,7 +3765,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using subsharding column with in query as lower cost over lookup vindex", @@ -3599,7 +3792,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using non-unique lookup vindex", @@ -3628,7 +3822,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using subsharding column", @@ -3657,7 +3852,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using subsharding column with in query", @@ -3686,7 +3882,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using subsharding column with in query as lower cost over lookup vindex", @@ -3715,7 +3912,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with simple table.", @@ -3754,22 +3952,26 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with more columns in insert", "query": "insert into music(id, user_id) select 1", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert using select with more columns in select", "query": "insert into music(id, user_id) select id, count(user_id), sum(user_id) from user group by id", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert using select with more columns in select after accounting for star column", "query": "insert into music(id, user_id) select id, *, 2 from user", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert using select with auto-inc column using vitess sequence, sequence column not present", @@ -3808,7 +4010,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with auto-inc column using vitess sequence, sequence column present", @@ -3847,7 +4050,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "sharded insert from select", @@ -3888,7 +4092,8 @@ "main.dual", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with sharding column is autoinc and not present in the insert column query", @@ -3929,12 +4134,14 @@ "main.dual", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert using select with sharding column is not an autoinc and not present in the insert column query", "query": "insert into user_extra(pattern) SELECT 1", - "plan": "VT09003: INSERT query does not have primary vindex column 'user_id' in the column list" + "plan": "VT09003: INSERT query does not have primary vindex column 'user_id' in the column list", + "skip_e2e": true }, { "comment": "sharded same keyspace", @@ -3973,7 +4180,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded same keyspace", @@ -3996,7 +4204,8 @@ "main.unsharded", "main.unsharded_auto" ] - } + }, + "skip_e2e": true }, { "comment": "sharded different keyspace", @@ -4035,7 +4244,8 @@ "user.user_extra", "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "sharded insert table, unsharded select table", @@ -4074,7 +4284,8 @@ "main_2.unsharded_tab", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded different keyspace", @@ -4109,7 +4320,8 @@ "main.unsharded", "main_2.unsharded_tab" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert table, sharded select table", @@ -4144,7 +4356,8 @@ "main.unsharded", "zlookup_unique.t1" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded subquery in sharded update, not the same keyspace between outer and inner", @@ -4189,7 +4402,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in unsharded update, not the same keyspace", @@ -4234,7 +4448,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded join unsharded subqueries in unsharded update", @@ -4305,7 +4520,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded update with sub query where the sources can be merged into a single query", @@ -4332,7 +4548,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "merge through correlated subquery", @@ -4359,7 +4576,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "merge through correlated subquery #2", @@ -4382,7 +4600,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "all defaults empty column, empty values", @@ -4407,12 +4626,14 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "vexplain all dml without any directive should fail", "query": "vexplain all delete from user", - "plan": "VT09008: vexplain queries/all will actually run queries" + "plan": "VT09008: vexplain queries/all will actually run queries", + "skip_e2e": true }, { "comment": "vexplain dml with actually_run_query directive", @@ -4443,7 +4664,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "explain dml with actually_run_query directive - 2", @@ -4474,7 +4696,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with join from multi table join subquery", @@ -4497,7 +4720,8 @@ "main.unsharded", "main.unsharded_b" ] - } + }, + "skip_e2e": true }, { "comment": "update with routing using multi column vindex", @@ -4523,7 +4747,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with routing using multi column vindex", @@ -4552,7 +4777,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into ref; TODO(maxeng) is this a bug?", @@ -4574,7 +4800,8 @@ "TablesUsed": [ "user.ref" ] - } + }, + "skip_e2e": true }, { "comment": "update using last_insert_id with an argument", @@ -4596,7 +4823,8 @@ "TablesUsed": [ "main.m1" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded update query with comment directive", @@ -4619,7 +4847,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded insert query with comment directive", @@ -4642,7 +4871,8 @@ "TablesUsed": [ "main.unsharded" ] - } + }, + "skip_e2e": true }, { "comment": "insert with select using same tables, cannot stream parallel", @@ -4685,7 +4915,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column - not provided", @@ -4712,7 +4943,8 @@ "TablesUsed": [ "user.mixed_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column - partially provided", @@ -4739,7 +4971,8 @@ "TablesUsed": [ "user.mixed_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column + select - not provided", @@ -4783,7 +5016,8 @@ "user.mixed_tbl", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert + lookup vindex + auto increment on lookup column + select - provided", @@ -4827,12 +5061,14 @@ "user.mixed_tbl", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "insert into a vindex not allowed", "query": "insert into user_index(id) values(1)", - "plan": "VT09014: vindex cannot be modified" + "plan": "VT09014: vindex cannot be modified", + "skip_e2e": true }, { "comment": "insert with select takes shared lock", @@ -4873,32 +5109,38 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Unsupported INSERT statement with a target destination", "query": "insert into `user[-]`.user_metadata (a, b) values (1,2)", - "plan": "VT09017: INSERT with a target destination is not allowed" + "plan": "VT09017: INSERT with a target destination is not allowed", + "skip_e2e": true }, { "comment": "Unsupported delete statement with a replica target destination", "query": "DELETE FROM `user[-]@replica`.user_metadata limit 1", - "plan": "VT09002: delete statement with a replica target" + "plan": "VT09002: delete statement with a replica target", + "skip_e2e": true }, { "comment": "Unsupported update statement with a replica target destination", "query": "update `user[-]@replica`.user_metadata set id=2", - "plan": "VT09002: update statement with a replica target" + "plan": "VT09002: update statement with a replica target", + "skip_e2e": true }, { "comment": "insert row values smaller than number of columns", "query": "insert into user(one, two, three, four) values (1, 2, 3)", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert row values greater than number of columns", "query": "insert into user(one, two, three) values (1, 2, 3, 4)", - "plan": "VT03006: column count does not match value count with the row" + "plan": "VT03006: column count does not match value count with the row", + "skip_e2e": true }, { "comment": "insert on duplicate key update with database qualifier", @@ -4925,7 +5167,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "delete from reference table - query send to source table", @@ -4947,7 +5190,8 @@ "TablesUsed": [ "main.source_of_ref" ] - } + }, + "skip_e2e": true }, { "comment": "delete from reference table - no source", @@ -4969,7 +5213,8 @@ "TablesUsed": [ "user.ref" ] - } + }, + "skip_e2e": true }, { "comment": "delete by target destination with limit", @@ -4994,7 +5239,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete sharded table with join with reference table", @@ -5020,7 +5266,8 @@ "user.ref_with_source", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete sharded table with join with another sharded table on vindex column", @@ -5046,7 +5293,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi delete multi table", @@ -5122,7 +5370,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "multi delete multi table with alias", @@ -5194,7 +5443,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "reverse the join order for delete", @@ -5266,7 +5516,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi table delete with join on vindex column", @@ -5292,7 +5543,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete 3 way join with sharding key and primary key same", @@ -5365,7 +5617,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "delete 3 way join with sharding key and primary key different", @@ -5438,7 +5691,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "sharded delete with limit clause", @@ -5493,7 +5747,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded delete with order by and limit clause", @@ -5549,7 +5804,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with limit clause", @@ -5601,7 +5857,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update a vindex column with limit", @@ -5659,7 +5916,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target", @@ -5738,7 +5996,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target modifying lookup vindex", @@ -5817,7 +6076,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target having dependent column update", @@ -5893,7 +6153,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with single target having multiple dependent column update", @@ -5969,7 +6230,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table join with multi target having dependent column update", @@ -6068,17 +6330,20 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table reference with multi target update on a derived table", "query": "update ignore (select foo, col, bar from user) u, music m set u.foo = 21, u.bar = 'abc' where u.col = m.col", - "plan": "VT03032: the target table (select foo, col, bar from `user`) as u of the UPDATE is not updatable" + "plan": "VT03032: the target table (select foo, col, bar from `user`) as u of the UPDATE is not updatable", + "skip_e2e": true }, { "comment": "update with derived table", "query": "update (select id from user) as u set id = 4", - "plan": "VT03032: the target table (select id from `user`) as u of the UPDATE is not updatable" + "plan": "VT03032: the target table (select id from `user`) as u of the UPDATE is not updatable", + "skip_e2e": true }, { "comment": "Delete with routed table on music", @@ -6103,7 +6368,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Update with routed table on music", @@ -6125,7 +6391,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "Insert with routed table on music", @@ -6151,7 +6418,8 @@ "TablesUsed": [ "user.music" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in sharded delete", @@ -6207,7 +6475,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "unsharded subquery in sharded delete", @@ -6255,7 +6524,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in unsharded delete", @@ -6300,7 +6570,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded subquery in unsharded subquery in unsharded delete", @@ -6367,7 +6638,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "sharded join unsharded subquery in unsharded delete", @@ -6438,7 +6710,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi target delete on sharded table", @@ -6530,7 +6803,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "delete with multi-table targets", @@ -6625,7 +6899,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi table delete with 2 sharded tables join on vindex column", @@ -6694,7 +6969,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi table delete with 2 sharded tables join on non-vindex column", @@ -6785,7 +7061,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "multi target delete with composite primary key having single column vindex", @@ -6851,7 +7128,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e": true }, { "comment": "multi target delete with composite primary key with lookup vindex as sharding column", @@ -6917,7 +7195,8 @@ "ordering.order", "ordering.order_event" ] - } + }, + "skip_e2e": true }, { "comment": "update with multi table reference with multi target update", @@ -7002,7 +7281,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias in INSERT", @@ -7028,7 +7308,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias with explicit columns in INSERT", @@ -7054,7 +7335,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias in INSERT (no column list)", @@ -7080,7 +7362,8 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true }, { "comment": "RowAlias with explicit columns in INSERT (no column list)", @@ -7106,6 +7389,7 @@ "TablesUsed": [ "user.authoritative" ] - } + }, + "skip_e2e": true } ] diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.json b/go/vt/vtgate/planbuilder/testdata/filter_cases.json index edce4ebd0cb..72b6c4ddd46 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.json @@ -699,7 +699,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Composite IN: RHS not tuple", @@ -722,7 +723,8 @@ "user.music", "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "Composite IN: RHS has no simple values", @@ -970,7 +972,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "Merging subqueries should remove keyspace from query", @@ -1095,7 +1098,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "Multi-table unique vindex constraint", @@ -1252,7 +1256,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Multi-route unique vindex route on both routes", @@ -1279,7 +1284,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Multi-route with cross-route constraint", @@ -1328,7 +1334,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Multi-route with non-route constraint, should use first route.", @@ -1373,7 +1380,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Route with multiple route constraints, SelectIN is the best constraint.", @@ -1654,7 +1662,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "routing rules: choose the redirected table", @@ -1680,7 +1689,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "subquery", @@ -1729,7 +1739,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "correlated subquery merge-able into a route of a join tree", @@ -1778,7 +1789,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "ensure subquery reordering gets us a better plan", @@ -1824,7 +1836,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "nested subquery", @@ -1873,7 +1886,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "Correlated subquery in where clause", @@ -1896,7 +1910,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "outer and inner subquery route by same int val", @@ -1923,7 +1938,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "outer and inner subquery route by same str val", @@ -1950,7 +1966,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "outer and inner subquery route by same val arg", @@ -1977,12 +1994,14 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "unresolved symbol in inner subquery.", "query": "select id from user where id = :a and user.col in (select user_extra.col from user_extra where user_extra.user_id = :a and foo.id = 1)", - "plan": "column 'foo.id' not found" + "plan": "column 'foo.id' not found", + "skip_e2e":true }, { "comment": "outer and inner subquery route by same outermost column value", @@ -2005,7 +2024,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "cross-shard subquery in IN clause.\n# Note the improved Underlying plan as SelectIN.", @@ -2290,7 +2310,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "routing rules subquery pullout", @@ -2339,7 +2360,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "Case preservation test", @@ -2366,7 +2388,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "database() call in where clause.", @@ -2649,7 +2672,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "solving LIKE query with a CFC prefix vindex", @@ -2701,7 +2725,8 @@ "TablesUsed": [ "user.samecolvin" ] - } + }, + "skip_e2e":true }, { "comment": "non unique predicate on vindex", @@ -2819,7 +2844,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "SelectDBA with uncorrelated subqueries", @@ -2838,7 +2864,8 @@ "Query": "select t.table_schema from information_schema.`tables` as t where t.table_schema in (select c.column_name from information_schema.`columns` as c)", "Table": "information_schema.`tables`" } - } + }, + "skip_e2e": true }, { "comment": "SelectReference with uncorrelated subqueries", @@ -3040,7 +3067,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "The outer and second inner are SelectEqualUnique with same Vindex value, the first inner has different Vindex value", @@ -3094,7 +3122,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "two correlated subqueries that can be merge in a single route", @@ -3117,7 +3146,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "transitive closures for the win", @@ -3166,7 +3196,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "not supported transitive closures with equality inside of an OR", @@ -3215,7 +3246,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "routing rules subquery merge with alias", @@ -3237,7 +3269,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "left join where clauses where we can optimize into an inner join", @@ -3282,12 +3315,14 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "this query lead to a nil pointer error", "query": "select user.id from user left join user_extra on user.col = user_extra.col where foo(user_extra.foobar)", - "plan": "expr cannot be translated, not supported: foo(user_extra.foobar)" + "plan": "expr cannot be translated, not supported: foo(user_extra.foobar)", + "skip_e2e" :true }, { "comment": "filter after outer join", @@ -3339,7 +3374,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "subquery on other table", @@ -3994,7 +4030,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "conditions following a null safe comparison operator can be used for routing", @@ -4444,7 +4481,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "two predicates that mean the same thing", @@ -4530,7 +4568,8 @@ "main.unsharded", "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "push filter under aggregation", @@ -4598,7 +4637,8 @@ "user.user", "user.user_extra" ] - } + }, + "skip_e2e":true }, { "comment": "query that would time out because planning was too slow", @@ -4628,7 +4668,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e":true }, { "comment": "union inside subquery. all routes can be merged by literal value", @@ -4682,7 +4723,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "list args: single column vindex on non-zero offset", @@ -4708,7 +4750,8 @@ "TablesUsed": [ "user.user" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex", @@ -4735,7 +4778,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex - subshard", @@ -4761,7 +4805,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex - more columns", @@ -4788,7 +4833,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "list args: multi column vindex - columns rearranged", @@ -4815,7 +4861,8 @@ "TablesUsed": [ "user.multicol_tbl" ] - } + }, + "skip_e2e": true }, { "comment": "order by with filter removing the keyspace from order by", @@ -4920,5 +4967,148 @@ "user.authoritative" ] } + }, + { + "comment": "Between clause on primary indexed id column (binary vindex on id)", + "query": "select id from unq_binary_idx where id between 1 and 5", + "plan": { + "QueryType": "SELECT", + "Original": "select id from unq_binary_idx where id between 1 and 5", + "Instructions": { + "OperatorType": "Route", + "Variant": "Between", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id from unq_binary_idx where 1 != 1", + "Query": "select id from unq_binary_idx where id between 1 and 5", + "Table": "unq_binary_idx", + "Values": [ + "(1, 5)" + ], + "Vindex": "binary" + }, + "TablesUsed": [ + "user.unq_binary_idx" + ] + } + }, +{ + "comment": "Between clause on customer.id column (xxhash vindex on id)", + "query": "select id from customer where id between 1 and 5", + "plan": { + "QueryType": "SELECT", + "Original": "select id from customer where id between 1 and 5", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id from customer where 1 != 1", + "Query": "select id from customer where id between 1 and 5", + "Table": "customer" + }, + "TablesUsed": [ + "user.customer" + ] + } + }, +{ + "comment": "Between clause on col1 column (there is no vindex on this column)", + "query": "select id, col1 from unq_binary_idx where col1 between 10 and 50", + "plan": { + "QueryType": "SELECT", + "Original": "select id, col1 from unq_binary_idx where col1 between 10 and 50", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id, col1 from unq_binary_idx where 1 != 1", + "Query": "select id, col1 from unq_binary_idx where col1 between 10 and 50", + "Table": "unq_binary_idx" + }, + "TablesUsed": [ + "user.unq_binary_idx" + ] + } +}, +{ + "comment": "Between clause on multicolumn vindex (cola,colb)", + "query": "select cola,colb,colc from multicol_tbl where cola between 1 and 5", + "plan": { + "QueryType": "SELECT", + "Original": "select cola,colb,colc from multicol_tbl where cola between 1 and 5", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select cola, colb, colc from multicol_tbl where 1 != 1", + "Query": "select cola, colb, colc from multicol_tbl where cola between 1 and 5", + "Table": "multicol_tbl" + }, + "TablesUsed": [ + "user.multicol_tbl" + ] + } +}, +{ + "comment": "Between clause on a binary vindex field with values from a different table", + "query": "select s.oid,s.col1, se.colb from sales s join sales_extra se on s.col1 = se.cola where s.oid between se.start and se.end", + "plan": { + "QueryType": "SELECT", + "Original": "select s.oid,s.col1, se.colb from sales s join sales_extra se on s.col1 = se.cola where s.oid between se.start and se.end", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "R:0,R:1,L:0", + "JoinVars": { + "se_cola": 1, + "se_end": 3, + "se_start": 2 + }, + "TableName": "sales_extra_sales", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select se.colb, se.cola, se.`start`, se.`end` from sales_extra as se where 1 != 1", + "Query": "select se.colb, se.cola, se.`start`, se.`end` from sales_extra as se", + "Table": "sales_extra" + }, + { + "OperatorType": "Route", + "Variant": "Between", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select s.oid, s.col1 from sales as s where 1 != 1", + "Query": "select s.oid, s.col1 from sales as s where s.oid between :se_start /* INT16 */ and :se_end /* INT16 */ and s.col1 = :se_cola /* VARCHAR */", + "Table": "sales", + "Values": [ + "(:se_start, :se_end)" + ], + "Vindex": "binary" + } + ] + }, + "TablesUsed": [ + "user.sales", + "user.sales_extra" + ] } +} ] diff --git a/go/vt/vtgate/planbuilder/testdata/sampledata/user.sql b/go/vt/vtgate/planbuilder/testdata/sampledata/user.sql new file mode 100644 index 00000000000..044a1ee140d --- /dev/null +++ b/go/vt/vtgate/planbuilder/testdata/sampledata/user.sql @@ -0,0 +1,14 @@ +INSERT INTO sales (oid, col1) + VALUES (1, 'a_1'); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (11, 'a_1', 'b_1',0, 500); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (12, 'a_2', 'b_2',500, 1000); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (13, 'a_3', 'b_3',1000, 1500); + +INSERT INTO sales_extra(colx, cola, colb, start, end) +VALUES (14, 'a_4', 'b_4',1500, 2000); \ No newline at end of file diff --git a/go/vt/vtgate/planbuilder/testdata/schemas/main.sql b/go/vt/vtgate/planbuilder/testdata/schemas/main.sql index 8c15b99218c..fb03b69419b 100644 --- a/go/vt/vtgate/planbuilder/testdata/schemas/main.sql +++ b/go/vt/vtgate/planbuilder/testdata/schemas/main.sql @@ -1,12 +1,26 @@ CREATE TABLE `unsharded` ( - `id` INT NOT NULL PRIMARY KEY, - `col1` VARCHAR(255) DEFAULT NULL, - `col2` VARCHAR(255) DEFAULT NULL, - `name` VARCHAR(255) DEFAULT NULL + `id` INT NOT NULL PRIMARY KEY, + `col` VARCHAR(255) DEFAULT NULL, + `col1` VARCHAR(255) DEFAULT NULL, + `col2` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL, + `baz` INT ); CREATE TABLE `unsharded_auto` ( - `id` INT NOT NULL PRIMARY KEY, + `id` INT NOT NULL PRIMARY KEY, `col1` VARCHAR(255) DEFAULT NULL, `col2` VARCHAR(255) DEFAULT NULL +); + +CREATE TABLE `unsharded_a` ( + `id` INT NOT NULL PRIMARY KEY, + `col` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL +); + +CREATE TABLE `unsharded_b` ( + `id` INT NOT NULL PRIMARY KEY, + `col` VARCHAR(255) DEFAULT NULL, + `name` VARCHAR(255) DEFAULT NULL ); \ No newline at end of file diff --git a/go/vt/vtgate/planbuilder/testdata/schemas/user.sql b/go/vt/vtgate/planbuilder/testdata/schemas/user.sql index 55f4078557a..818d2508069 100644 --- a/go/vt/vtgate/planbuilder/testdata/schemas/user.sql +++ b/go/vt/vtgate/planbuilder/testdata/schemas/user.sql @@ -1,12 +1,25 @@ CREATE TABLE user ( - id INT PRIMARY KEY, - col BIGINT, - predef1 VARCHAR(255), - predef2 VARCHAR(255), - textcol1 VARCHAR(255), - intcol BIGINT, - textcol2 VARCHAR(255) + id INT PRIMARY KEY, + col BIGINT, + intcol BIGINT, + user_id INT, + id1 INT, + id2 INT, + id3 INT, + m INT, + bar INT, + a INT, + name VARCHAR(255), + col1 VARCHAR(255), + col2 VARCHAR(255), + costly VARCHAR(255), + predef1 VARCHAR(255), + predef2 VARCHAR(255), + textcol1 VARCHAR(255), + textcol2 VARCHAR(255), + someColumn VARCHAR(255), + foo VARCHAR(255) ); CREATE TABLE user_metadata @@ -23,6 +36,10 @@ CREATE TABLE music ( user_id INT, id INT, + col1 VARCHAR(255), + col2 VARCHAR(255), + genre VARCHAR(255), + componist VARCHAR(255), PRIMARY KEY (user_id) ); @@ -35,9 +52,9 @@ CREATE TABLE samecolvin CREATE TABLE multicolvin ( kid INT, - column_a VARCHAR(255), - column_b VARCHAR(255), - column_c VARCHAR(255), + column_a INT, + column_b INT, + column_c INT, PRIMARY KEY (kid) ); @@ -97,4 +114,73 @@ CREATE TABLE authoritative col1 VARCHAR(255), col2 bigint, PRIMARY KEY (user_id) -) ENGINE=InnoDB; \ No newline at end of file +) ENGINE=InnoDB; + +CREATE TABLE colb_colc_map +( + colb INT PRIMARY KEY, + colc INT, + keyspace_id VARCHAR(255) +); + +CREATE TABLE seq +( + id INT, + next_id BIGINT, + cache BIGINT, + PRIMARY KEY (id) +) COMMENT 'vitess_sequence'; + +CREATE TABLE user_extra +( + id INT, + user_id INT, + extra_id INT, + col INT, + m2 INT, + PRIMARY KEY (id, extra_id) +); + +CREATE TABLE name_user_map +( + name VARCHAR(255), + keyspace_id VARCHAR(255) +); + +CREATE TABLE name_user_vdx +( + name VARCHAR(255), + keyspace_id VARCHAR(255) +); + +CREATE TABLE costly_map +( + costly VARCHAR(255), + keyspace_id VARCHAR(255) +); + +CREATE TABLE unq_binary_idx +( + id INT PRIMARY KEY, + col1 INT +); + +CREATE TABLE sales +( + oid INT PRIMARY KEY, + col1 VARCHAR(255) +); + +CREATE TABLE sales_extra +( + colx INT PRIMARY KEY, + cola VARCHAR(255), + colb VARCHAR(255), + start INT, + end INT +); + +CREATE TABLE ref +( + col INT PRIMARY KEY +); \ No newline at end of file diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index eac13216380..e18fa274d7e 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -4957,6 +4957,36 @@ ] } }, + { + "comment": "We are using last_insert_id with argument, so we need to fetch all results", + "query": "select last_insert_id(5) from user limit 12", + "plan": { + "QueryType": "SELECT", + "Original": "select last_insert_id(5) from user limit 12", + "Instructions": { + "OperatorType": "Limit", + "Count": "12", + "RequireCompleteInput": true, + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FetchLastInsertID": true, + "FieldQuery": "select last_insert_id(5) from `user` where 1 != 1", + "Query": "select last_insert_id(5) from `user` limit 12", + "Table": "`user`" + } + ] + }, + "TablesUsed": [ + "user.user" + ] + } + }, { "comment": "Unmergeable subquery with multiple levels of derived statements, using a multi value `IN` predicate", "query": "SELECT music.id FROM music WHERE music.id IN (SELECT * FROM (SELECT * FROM (SELECT music.id FROM music WHERE music.user_id IN (5, 6) LIMIT 10) subquery_for_limit) subquery_for_limit)", @@ -5599,6 +5629,7 @@ "Name": "user", "Sharded": true }, + "FetchLastInsertID": true, "FieldQuery": "select last_insert_id(id) from `user` where 1 != 1", "Query": "select last_insert_id(id) from `user`", "Table": "`user`" diff --git a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json index a5de9d3697e..aaa11727510 100644 --- a/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json +++ b/go/vt/vtgate/planbuilder/testdata/vschemas/schema.json @@ -214,6 +214,9 @@ "to": "keyspace_id", "write_only": "true" } + }, + "binary": { + "type": "binary" } }, "tables": { @@ -569,6 +572,62 @@ "name": "shard_index" } ] + }, + "unq_binary_idx": { + "column_vindexes" : [ + { + "column" : "id", + "name": "binary" + } + ], + "columns" :[ + { + "name": "col1", + "type": "INT16" + } + ] + }, + "sales": { + "column_vindexes" : [ + { + "column" : "oid", + "name" : "binary" + } + ], + "columns" : [ + { + "name" : "col1", + "type" : "VARCHAR" + } + ] + }, + "sales_extra" : { + "column_vindexes": [ + { + "columns": [ + "colx" + ], + "name": "shard_index" + } + ], + "columns" : [ + { + "name" : "cola", + "type" : "VARCHAR" + }, + { + "name" : "colb", + "type" : "VARCHAR" + }, + { + "name" : "start", + "type" : "INT16" + }, + { + "name" : "end", + "type" : "INT16" + } + ] } } }, diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index 7231d2d9c43..85f236a9a18 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -152,6 +152,7 @@ func (stc *ScatterConn) ExecuteMultiShard( autocommit bool, ignoreMaxMemoryRows bool, resultsObserver econtext.ResultsObserver, + fetchLastInsertID bool, ) (qr *sqltypes.Result, errs []error) { if len(rss) != len(queries) { @@ -166,6 +167,10 @@ func (stc *ScatterConn) ExecuteMultiShard( go stc.runLockQuery(ctx, session) } + if session.Options != nil { + session.Options.FetchLastInsertId = fetchLastInsertID + } + allErrors := stc.multiGoTransaction( ctx, "Execute", @@ -187,6 +192,10 @@ func (stc *ScatterConn) ExecuteMultiShard( opts = session.Session.Options } + if opts == nil && fetchLastInsertID { + opts = &querypb.ExecuteOptions{FetchLastInsertId: fetchLastInsertID} + } + if autocommit { // As this is auto-commit, the transactionID is supposed to be zero. if transactionID != int64(0) { @@ -373,6 +382,7 @@ func (stc *ScatterConn) StreamExecuteMulti( autocommit bool, callback func(reply *sqltypes.Result) error, resultsObserver econtext.ResultsObserver, + fetchLastInsertID bool, ) []error { if session.InLockSession() && triggerLockHeartBeat(session) { go stc.runLockQuery(ctx, session) @@ -384,6 +394,11 @@ func (stc *ScatterConn) StreamExecuteMulti( } return callback(reply) } + + if session.Options != nil { + session.Options.FetchLastInsertId = fetchLastInsertID + } + allErrors := stc.multiGoTransaction( ctx, "StreamExecute", @@ -404,6 +419,10 @@ func (stc *ScatterConn) StreamExecuteMulti( opts = session.Session.Options } + if opts == nil && fetchLastInsertID { + opts = &querypb.ExecuteOptions{FetchLastInsertId: fetchLastInsertID} + } + if autocommit { // As this is auto-commit, the transactionID is supposed to be zero. if transactionID != int64(0) { diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index ab8680ca5e6..e5c27c0de33 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -20,27 +20,23 @@ import ( "fmt" "testing" - "vitess.io/vitess/go/vt/log" - econtext "vitess.io/vitess/go/vt/vtgate/executorcontext" - - "vitess.io/vitess/go/mysql/sqlerror" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - + "github.com/aws/smithy-go/ptr" "github.com/stretchr/testify/assert" - - "vitess.io/vitess/go/vt/key" - - "vitess.io/vitess/go/test/utils" - "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/discovery" + "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/vterrors" + econtext "vitess.io/vitess/go/vt/vtgate/executorcontext" ) // This file uses the sandbox_test framework. @@ -101,7 +97,7 @@ func TestExecuteFailOnAutocommit(t *testing.T) { }, Autocommit: false, } - _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}, false) err := vterrors.Aggregate(errs) require.Error(t, err) require.Contains(t, err.Error(), "in autocommit mode, transactionID should be zero but was: 123") @@ -109,6 +105,117 @@ func TestExecuteFailOnAutocommit(t *testing.T) { utils.MustMatch(t, []*querypb.BoundQuery{queries[1]}, sbc1.Queries, "") } +func TestFetchLastInsertIDResets(t *testing.T) { + // This test verifies that the FetchLastInsertID flag is reset after a call to ExecuteMultiShard. + ks := "TestFetchLastInsertIDResets" + ctx := utils.LeakCheckContext(t) + + createSandbox(ks) + hc := discovery.NewFakeHealthCheck(nil) + sc := newTestScatterConn(ctx, hc, newSandboxForCells(ctx, []string{"aa"}), "aa") + sbc0 := hc.AddTestTablet("aa", "0", 1, ks, "0", topodatapb.TabletType_PRIMARY, true, 1, nil) + sbc1 := hc.AddTestTablet("aa", "1", 1, ks, "1", topodatapb.TabletType_PRIMARY, true, 1, nil) + + rss := []*srvtopo.ResolvedShard{{ + Target: &querypb.Target{ + Keyspace: ks, + Shard: "0", + TabletType: topodatapb.TabletType_PRIMARY, + }, + Gateway: sbc0, + }, { + Target: &querypb.Target{ + Keyspace: ks, + Shard: "1", + TabletType: topodatapb.TabletType_PRIMARY, + }, + Gateway: sbc1, + }} + queries := []*querypb.BoundQuery{{ + Sql: "query1", + BindVariables: map[string]*querypb.BindVariable{ + "bv0": sqltypes.Int64BindVariable(0), + }, + }, { + Sql: "query2", + BindVariables: map[string]*querypb.BindVariable{ + "bv1": sqltypes.Int64BindVariable(1), + }, + }} + tests := []struct { + name string + initialSessionOpts *querypb.ExecuteOptions + fetchLastInsertID bool + expectSessionNil bool + expectFetchLastID *bool // nil means checkLastOptionNil, otherwise checkLastOption(*bool) + }{ + { + name: "no session options, fetchLastInsertID = false", + initialSessionOpts: nil, + fetchLastInsertID: false, + expectSessionNil: true, + expectFetchLastID: nil, + }, + { + name: "no session options, fetchLastInsertID = true", + initialSessionOpts: nil, + fetchLastInsertID: true, + expectSessionNil: true, + + expectFetchLastID: ptr.Bool(true), + }, + { + name: "session options set, fetchLastInsertID = false", + initialSessionOpts: &querypb.ExecuteOptions{}, + fetchLastInsertID: false, + expectSessionNil: false, + expectFetchLastID: ptr.Bool(false), + }, + { + name: "session options set, fetchLastInsertID = true", + initialSessionOpts: &querypb.ExecuteOptions{}, + fetchLastInsertID: true, + expectSessionNil: false, + expectFetchLastID: ptr.Bool(true), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + session := econtext.NewSafeSession(nil) + session.Options = tt.initialSessionOpts + + checkLastOption := func(expected bool) { + require.Equal(t, 1, len(sbc0.Options)) + options := sbc0.Options[0] + assert.Equal(t, options.FetchLastInsertId, expected) + sbc0.Options = nil + } + checkLastOptionNil := func() { + require.Equal(t, 1, len(sbc0.Options)) + assert.Nil(t, sbc0.Options[0]) + sbc0.Options = nil + } + + _, errs := sc.ExecuteMultiShard(ctx, nil, rss, queries, session, true /*autocommit*/, false, nullResultsObserver{}, tt.fetchLastInsertID) + require.NoError(t, vterrors.Aggregate(errs)) + + if tt.expectSessionNil { + assert.Nil(t, session.Options) + } else { + assert.NotNil(t, session.Options) + assert.Equal(t, tt.fetchLastInsertID, session.Options.FetchLastInsertId) + } + + if tt.expectFetchLastID == nil { + checkLastOptionNil() + } else { + checkLastOption(*tt.expectFetchLastID) + } + }) + } +} + func TestExecutePanic(t *testing.T) { ctx := utils.LeakCheckContext(t) @@ -177,15 +284,10 @@ func TestExecutePanic(t *testing.T) { logMessage = fmt.Sprintf(format, args...) } - defer func() { - r := recover() - require.NotNil(t, r, "The code did not panic") - // assert we are seeing the stack trace - require.Contains(t, logMessage, "(*ScatterConn).multiGoTransaction") - }() - - _, _ = sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}) - + assert.Panics(t, func() { + _, _ = sc.ExecuteMultiShard(ctx, nil, rss, queries, econtext.NewSafeSession(session), true /*autocommit*/, false, nullResultsObserver{}, false) + }) + require.Contains(t, logMessage, "(*ScatterConn).multiGoTransaction") } func TestReservedOnMultiReplica(t *testing.T) { diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index 0a9d2480d9b..988932f4414 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -151,7 +151,7 @@ func (a *analyzer) newSemTable( ExpandedColumns: map[sqlparser.TableName][]*sqlparser.ColName{}, columns: map[*sqlparser.Union]sqlparser.SelectExprs{}, StatementIDs: a.scoper.statementIDs, - QuerySignature: QuerySignature{}, + QuerySignature: a.sig, childForeignKeysInvolved: map[TableSet][]vindexes.ChildFKInfo{}, parentForeignKeysInvolved: map[TableSet][]vindexes.ParentFKInfo{}, childFkToUpdExprs: map[string]sqlparser.UpdateExprs{}, @@ -362,6 +362,10 @@ func (a *analyzer) analyze(statement sqlparser.Statement) error { return a.err } + if a.earlyTables.lastInsertIdWithArgument { + a.sig.LastInsertIDArg = true + } + if a.canShortCut(statement) { return nil } diff --git a/go/vt/vtgate/semantics/analyzer_test.go b/go/vt/vtgate/semantics/analyzer_test.go index 0c42456b0ab..de8fbdee0d7 100644 --- a/go/vt/vtgate/semantics/analyzer_test.go +++ b/go/vt/vtgate/semantics/analyzer_test.go @@ -625,6 +625,36 @@ func TestSubqueryOrderByBinding(t *testing.T) { } } +func TestQuerySignatureLastInsertID(t *testing.T) { + queries := []struct { + query string + expected bool + }{{ + query: "select 12", + expected: false, + }, { + query: "select last_insert_id()", + expected: false, + }, { + query: "select last_insert_id(123)", + expected: true, + }, { + query: "update user_extra set val = last_insert_id(123)", + expected: true, + }} + + for _, tc := range queries { + t.Run(tc.query, func(t *testing.T) { + ast, err := sqlparser.NewTestParser().Parse(tc.query) + require.NoError(t, err) + + st, err := AnalyzeStrict(ast, "dbName", fakeSchemaInfo()) + require.NoError(t, err) + require.Equal(t, tc.expected, st.QuerySignature.LastInsertIDArg) + }) + } +} + func TestOrderByBindingTable(t *testing.T) { tcases := []struct { sql string diff --git a/go/vt/vtgate/semantics/semantic_table.go b/go/vt/vtgate/semantics/semantic_table.go index f9856a901a6..492259427c5 100644 --- a/go/vt/vtgate/semantics/semantic_table.go +++ b/go/vt/vtgate/semantics/semantic_table.go @@ -80,13 +80,14 @@ type ( // QuerySignature is used to identify shortcuts in the planning process QuerySignature struct { - Aggregation bool - DML bool - Distinct bool - HashJoin bool - SubQueries bool - Union bool - RecursiveCTE bool + Aggregation bool + DML bool + Distinct bool + HashJoin bool + SubQueries bool + Union bool + RecursiveCTE bool + LastInsertIDArg bool // LastInsertIDArg is true if the query has a LAST_INSERT_ID(x) with an argument } // MirrorInfo stores information used to produce mirror @@ -1013,6 +1014,13 @@ func (st *SemTable) GetMirrorInfo() MirrorInfo { return mirrorInfo(st.Tables) } +func (st *SemTable) ShouldFetchLastInsertID() bool { + if st == nil { + return false + } + return st.QuerySignature.LastInsertIDArg +} + // mirrorInfo looks through all tables with mirror rules defined, and returns a // MirrorInfo containing the lowest mirror percentage found across all rules. // diff --git a/go/vt/vtgate/semantics/table_collector.go b/go/vt/vtgate/semantics/table_collector.go index 191d9c3b38e..45a50fd23a2 100644 --- a/go/vt/vtgate/semantics/table_collector.go +++ b/go/vt/vtgate/semantics/table_collector.go @@ -46,6 +46,10 @@ type ( // cte is a map of CTE definitions that are used in the query cte map[string]*CTE + + // lastInsertIdWithArgument is used to signal to later stages that we + // need to do special handling of the engine primitive + lastInsertIdWithArgument bool } ) @@ -59,18 +63,22 @@ func newEarlyTableCollector(si SchemaInformation, currentDb string) *earlyTableC } func (etc *earlyTableCollector) down(cursor *sqlparser.Cursor) bool { - with, ok := cursor.Node().(*sqlparser.With) - if !ok { - return true - } - for _, cte := range with.CTEs { - etc.cte[cte.ID.String()] = &CTE{ - Name: cte.ID.String(), - Query: cte.Subquery, - Columns: cte.Columns, - Recursive: with.Recursive, + switch node := cursor.Node().(type) { + case *sqlparser.With: + for _, cte := range node.CTEs { + etc.cte[cte.ID.String()] = &CTE{ + Name: cte.ID.String(), + Query: cte.Subquery, + Columns: cte.Columns, + Recursive: node.Recursive, + } + } + case *sqlparser.FuncExpr: + if node.Name.EqualString("last_insert_id") && len(node.Exprs) == 1 { + etc.lastInsertIdWithArgument = true } } + return true } diff --git a/go/vt/vtgate/tx_conn_test.go b/go/vt/vtgate/tx_conn_test.go index a0322e09591..6d31aa4e543 100644 --- a/go/vt/vtgate/tx_conn_test.go +++ b/go/vt/vtgate/tx_conn_test.go @@ -58,7 +58,7 @@ func TestTxConnBegin(t *testing.T) { require.NoError(t, err) wantSession := vtgatepb.Session{InTransaction: true} utils.MustMatch(t, &wantSession, session, "Session") - _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, safeSession, false, false, nullResultsObserver{}) + _, errors := sc.ExecuteMultiShard(ctx, nil, rss0, queries, safeSession, false, false, nullResultsObserver{}, false) require.Empty(t, errors) // Begin again should cause a commit and a new begin. @@ -78,7 +78,7 @@ func TestTxConnCommitFailure(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rssm[0], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[0], queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -93,7 +93,7 @@ func TestTxConnCommitFailure(t *testing.T) { } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rssm[1], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[1], queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -116,7 +116,7 @@ func TestTxConnCommitFailure(t *testing.T) { } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rssa, threeQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssa, threeQueries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -185,7 +185,7 @@ func TestTxConnCommitFailureAfterNonAtomicCommitMaxShards(t *testing.T) { } for i := 0; i < 18; i++ { - sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}, false) wantSession.ShardSessions = append(wantSession.ShardSessions, &vtgatepb.Session_ShardSession{ Target: &querypb.Target{ Keyspace: "TestTxConn", @@ -239,7 +239,7 @@ func TestTxConnCommitFailureBeforeNonAtomicCommitMaxShards(t *testing.T) { } for i := 0; i < 17; i++ { - sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rssm[i], queries, session, false, false, nullResultsObserver{}, false) wantSession.ShardSessions = append(wantSession.ShardSessions, &vtgatepb.Session_ShardSession{ Target: &querypb.Target{ Keyspace: "TestTxConn", @@ -285,7 +285,7 @@ func TestTxConnCommitSuccess(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -299,7 +299,7 @@ func TestTxConnCommitSuccess(t *testing.T) { }}, } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -338,7 +338,7 @@ func TestTxConnReservedCommitSuccess(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -354,7 +354,7 @@ func TestTxConnReservedCommitSuccess(t *testing.T) { }}, } utils.MustMatch(t, &wantSession, session.Session, "Session") - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -425,9 +425,9 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndCommit(t *testing.T) { session := econtext.NewSafeSession(&vtgatepb.Session{InReservedConn: true}) // this will create reserved connections against all tablets - _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) - _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) wantSession := vtgatepb.Session{ @@ -455,7 +455,7 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndCommit(t *testing.T) { session.Session.InTransaction = true // start a transaction against rss0 - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -520,9 +520,9 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndRollback(t *testing.T) { session := econtext.NewSafeSession(&vtgatepb.Session{InReservedConn: true}) // this will create reserved connections against all tablets - _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + _, errs := sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) - _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + _, errs = sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) require.Empty(t, errs) wantSession := vtgatepb.Session{ @@ -550,7 +550,7 @@ func TestTxConnReservedOn2ShardTxOn1ShardAndRollback(t *testing.T) { session.Session.InTransaction = true // start a transaction against rss0 - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -614,13 +614,13 @@ func TestTxConnCommitOrderFailure1(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 err := sc.txConn.Commit(ctx, session) @@ -649,13 +649,13 @@ func TestTxConnCommitOrderFailure2(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(context.Background(), nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(context.Background(), nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(context.Background(), nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 err := sc.txConn.Commit(ctx, session) @@ -683,13 +683,13 @@ func TestTxConnCommitOrderFailure3(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 require.NoError(t, @@ -725,7 +725,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, ShardSessions: []*vtgatepb.Session_ShardSession{{ @@ -741,7 +741,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, PreSessions: []*vtgatepb.Session_ShardSession{{ @@ -766,7 +766,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, PreSessions: []*vtgatepb.Session_ShardSession{{ @@ -800,7 +800,7 @@ func TestTxConnCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") // Ensure nothing changes if we reuse a transaction. - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) utils.MustMatch(t, &wantSession, session.Session, "Session") require.NoError(t, @@ -823,7 +823,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { // Sequence the executes to ensure commit order session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession := vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -841,7 +841,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_PRE) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -869,7 +869,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") session.SetCommitOrder(vtgatepb.CommitOrder_POST) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) wantSession = vtgatepb.Session{ InTransaction: true, InReservedConn: true, @@ -907,7 +907,7 @@ func TestTxConnReservedCommitOrderSuccess(t *testing.T) { utils.MustMatch(t, &wantSession, session.Session, "Session") // Ensure nothing changes if we reuse a transaction. - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) utils.MustMatch(t, &wantSession, session.Session, "Session") require.NoError(t, @@ -960,8 +960,8 @@ func TestTxConnCommit2PC(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PC") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) session.TransactionMode = vtgatepb.TransactionMode_TWOPC require.NoError(t, sc.txConn.Commit(ctx, session)) @@ -977,7 +977,7 @@ func TestTxConnCommit2PCOneParticipant(t *testing.T) { sc, sbc0, _, rss0, _, _ := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCOneParticipant") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) session.TransactionMode = vtgatepb.TransactionMode_TWOPC require.NoError(t, sc.txConn.Commit(ctx, session)) @@ -990,8 +990,8 @@ func TestTxConnCommit2PCCreateTransactionFail(t *testing.T) { sc, sbc0, sbc1, rss0, rss1, _ := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCCreateTransactionFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss1, queries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailCreateTransaction = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1012,8 +1012,8 @@ func TestTxConnCommit2PCPrepareFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCPrepareFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailPrepare = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1038,8 +1038,8 @@ func TestTxConnCommit2PCStartCommitFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCStartCommitFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailStartCommit = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1057,8 +1057,8 @@ func TestTxConnCommit2PCStartCommitFail(t *testing.T) { sbc1.ResetCounter() session = econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) // Here the StartCommit failure is in uncertain state so rollback is not called and neither conclude. sbc0.MustFailStartCommitUncertain = 1 @@ -1080,8 +1080,8 @@ func TestTxConnCommit2PCCommitPreparedFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCCommitPreparedFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCommitPrepared = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1100,8 +1100,8 @@ func TestTxConnCommit2PCConcludeTransactionFail(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TestTxConnCommit2PCConcludeTransactionFail") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc0.MustFailConcludeTransaction = 1 session.TransactionMode = vtgatepb.TransactionMode_TWOPC @@ -1120,8 +1120,8 @@ func TestTxConnRollback(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TxConnRollback") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) require.NoError(t, sc.txConn.Rollback(ctx, session)) wantSession := vtgatepb.Session{} @@ -1136,8 +1136,8 @@ func TestTxConnReservedRollback(t *testing.T) { sc, sbc0, sbc1, rss0, _, rss01 := newTestTxConnEnv(t, ctx, "TxConnReservedRollback") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) require.NoError(t, sc.txConn.Rollback(ctx, session)) wantSession := vtgatepb.Session{ @@ -1173,8 +1173,8 @@ func TestTxConnReservedRollbackFailure(t *testing.T) { sc, sbc0, sbc1, rss0, rss1, rss01 := newTestTxConnEnv(t, ctx, "TxConnReservedRollback") session := econtext.NewSafeSession(&vtgatepb.Session{InTransaction: true, InReservedConn: true}) - sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}) - sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}) + sc.ExecuteMultiShard(ctx, nil, rss0, queries, session, false, false, nullResultsObserver{}, false) + sc.ExecuteMultiShard(ctx, nil, rss01, twoQueries, session, false, false, nullResultsObserver{}, false) sbc1.MustFailCodes[vtrpcpb.Code_INVALID_ARGUMENT] = 1 assert.Error(t, diff --git a/go/vt/vtgate/vindexes/binary.go b/go/vt/vtgate/vindexes/binary.go index b78451ca1fb..96a72b2c3f4 100644 --- a/go/vt/vtgate/vindexes/binary.go +++ b/go/vt/vtgate/vindexes/binary.go @@ -30,6 +30,7 @@ var ( _ Reversible = (*Binary)(nil) _ Hashing = (*Binary)(nil) _ ParamValidating = (*Binary)(nil) + _ Sequential = (*Binary)(nil) ) // Binary is a vindex that converts binary bits to a keyspace id. @@ -108,6 +109,20 @@ func (*Binary) ReverseMap(_ VCursor, ksids [][]byte) ([]sqltypes.Value, error) { return reverseIds, nil } +// RangeMap can map ids to key.Destination objects. +func (vind *Binary) RangeMap(ctx context.Context, vcursor VCursor, startId sqltypes.Value, endId sqltypes.Value) ([]key.Destination, error) { + startKsId, err := vind.Hash(startId) + if err != nil { + return nil, err + } + endKsId, err := vind.Hash(endId) + if err != nil { + return nil, err + } + out := []key.Destination{&key.DestinationKeyRange{KeyRange: key.NewKeyRange(startKsId, endKsId)}} + return out, nil +} + // UnknownParams implements the ParamValidating interface. func (vind *Binary) UnknownParams() []string { return vind.unknownParams diff --git a/go/vt/vtgate/vindexes/binary_test.go b/go/vt/vtgate/vindexes/binary_test.go index 27ae6ceca11..a6556ec958a 100644 --- a/go/vt/vtgate/vindexes/binary_test.go +++ b/go/vt/vtgate/vindexes/binary_test.go @@ -24,6 +24,7 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" @@ -145,3 +146,18 @@ func TestBinaryReverseMap(t *testing.T) { t.Errorf("ReverseMap(): %v, want %s", err, wantErr) } } + +// TestBinaryRangeMap takes start and env values, +// and checks against a destination keyrange. +func TestBinaryRangeMap(t *testing.T) { + + startInterval := "0x01" + endInterval := "0x10" + + got, err := binOnlyVindex.(Sequential).RangeMap(context.Background(), nil, sqltypes.NewHexNum([]byte(startInterval)), + sqltypes.NewHexNum([]byte(endInterval))) + require.NoError(t, err) + want := "DestinationKeyRange(01-10)" + assert.Equal(t, want, got[0].String()) + +} diff --git a/go/vt/vtgate/vindexes/numeric.go b/go/vt/vtgate/vindexes/numeric.go index 091807ec2cc..b40df13a997 100644 --- a/go/vt/vtgate/vindexes/numeric.go +++ b/go/vt/vtgate/vindexes/numeric.go @@ -31,6 +31,7 @@ var ( _ Reversible = (*Numeric)(nil) _ Hashing = (*Numeric)(nil) _ ParamValidating = (*Numeric)(nil) + _ Sequential = (*Numeric)(nil) ) // Numeric defines a bit-pattern mapping of a uint64 to the KeyspaceId. @@ -108,6 +109,20 @@ func (*Numeric) ReverseMap(_ VCursor, ksids [][]byte) ([]sqltypes.Value, error) return reverseIds, nil } +// RangeMap implements Between. +func (vind *Numeric) RangeMap(ctx context.Context, vcursor VCursor, startId sqltypes.Value, endId sqltypes.Value) ([]key.Destination, error) { + startKsId, err := vind.Hash(startId) + if err != nil { + return nil, err + } + endKsId, err := vind.Hash(endId) + if err != nil { + return nil, err + } + out := []key.Destination{&key.DestinationKeyRange{KeyRange: key.NewKeyRange(startKsId, endKsId)}} + return out, nil +} + // UnknownParams implements the ParamValidating interface. func (vind *Numeric) UnknownParams() []string { return vind.unknownParams diff --git a/go/vt/vtgate/vindexes/vindex.go b/go/vt/vtgate/vindexes/vindex.go index e3d5a6d7e4d..947877108e0 100644 --- a/go/vt/vtgate/vindexes/vindex.go +++ b/go/vt/vtgate/vindexes/vindex.go @@ -130,6 +130,13 @@ type ( ReverseMap(vcursor VCursor, ks [][]byte) ([]sqltypes.Value, error) } + // A Sequential vindex is an optional interface one that maps to a keyspace range + // instead of a single keyspace id. It's being used to reduce the fan out for + // 'BETWEEN' expressions. + Sequential interface { + RangeMap(ctx context.Context, vcursor VCursor, startId sqltypes.Value, endId sqltypes.Value) ([]key.Destination, error) + } + // A Prefixable vindex is one that maps the prefix of a id to a keyspace range // instead of a single keyspace id. It's being used to reduced the fan out for // 'LIKE' expressions. diff --git a/go/vt/vttablet/endtoend/misc_test.go b/go/vt/vttablet/endtoend/misc_test.go index 68f6f4b1af6..8d5630a5dd8 100644 --- a/go/vt/vttablet/endtoend/misc_test.go +++ b/go/vt/vttablet/endtoend/misc_test.go @@ -49,10 +49,7 @@ import ( func TestSimpleRead(t *testing.T) { vstart := framework.DebugVars() _, err := framework.NewClient().Execute("select * from vitess_test where intval=1", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) vend := framework.DebugVars() compareIntDiff(t, vend, "Queries/TotalCount", vstart, 1) compareIntDiff(t, vend, "Queries/Histograms/Select/Count", vstart, 1) @@ -69,15 +66,9 @@ func TestBinary(t *testing.T) { "(4, null, null, '\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\\x00\x0f\xf0\xff')", nil, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) qr, err := client.Execute("select binval from vitess_test where intval=4", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) want := sqltypes.Result{ Fields: []*querypb.Field{ { @@ -106,18 +97,10 @@ func TestBinary(t *testing.T) { "insert into vitess_test values(5, null, null, :bindata)", map[string]*querypb.BindVariable{"bindata": sqltypes.StringBindVariable(binaryData)}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) qr, err = client.Execute("select binval from vitess_test where intval=5", nil) - if err != nil { - t.Error(err) - return - } - if !qr.Equal(&want) { - t.Errorf("Execute: \n%#v, want \n%#v", prettyPrint(*qr), prettyPrint(want)) - } + require.NoError(t, err) + assert.Truef(t, qr.Equal(&want), "Execute: \n%#v, want \n%#v", prettyPrint(*qr), prettyPrint(want)) } func TestNocacheListArgs(t *testing.T) { @@ -130,10 +113,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{2, 3, 4}), }, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 2, len(qr.Rows)) qr, err = client.Execute( @@ -142,10 +122,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{3, 4}), }, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 1, len(qr.Rows)) qr, err = client.Execute( @@ -154,10 +131,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{3}), }, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 1, len(qr.Rows)) // Error case @@ -167,11 +141,7 @@ func TestNocacheListArgs(t *testing.T) { "list": sqltypes.TestBindVariable([]any{}), }, ) - want := "empty list supplied for list (CallerID: dev)" - if err == nil || err.Error() != want { - t.Errorf("Error: %v, want %s", err, want) - return - } + assert.EqualError(t, err, "empty list supplied for list (CallerID: dev)") } func TestIntegrityError(t *testing.T) { @@ -179,9 +149,7 @@ func TestIntegrityError(t *testing.T) { client := framework.NewClient() _, err := client.Execute("insert into vitess_test values(1, null, null, null)", nil) want := "Duplicate entry '1'" - if err == nil || !strings.HasPrefix(err.Error(), want) { - t.Errorf("Error: %v, want prefix %s", err, want) - } + assert.ErrorContains(t, err, want) compareIntDiff(t, framework.DebugVars(), "Errors/ALREADY_EXISTS", vstart, 1) } @@ -197,10 +165,7 @@ func TestTrailingComment(t *testing.T) { "select * from vitess_test where intval=:ival /* comment1 */ /* comment2 */", } { _, err := client.Execute(query, bindVars) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) v2 := framework.Server.QueryPlanCacheLen() if v2 != v1+1 { t.Errorf("QueryEnginePlanCacheLength(%s): %d, want %d", query, v2, v1+1) @@ -211,17 +176,11 @@ func TestTrailingComment(t *testing.T) { func TestSchemaReload(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &connParams) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer conn.Close() _, err = conn.ExecuteFetch("create table vitess_temp(intval int)", 10, false) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer conn.ExecuteFetch("drop table vitess_temp", 10, false) framework.Server.ReloadSchema(context.Background()) @@ -246,10 +205,7 @@ func TestSchemaReload(t *testing.T) { func TestSidecarTables(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &connParams) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer conn.Close() for _, table := range []string{ "redo_state", @@ -258,10 +214,7 @@ func TestSidecarTables(t *testing.T) { "dt_participant", } { _, err = conn.ExecuteFetch(fmt.Sprintf("describe _vt.%s", table), 10, false) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) } } @@ -336,10 +289,7 @@ func TestBindInSelect(t *testing.T) { "select :bv from dual", map[string]*querypb.BindVariable{"bv": sqltypes.StringBindVariable("abcd")}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) want := &sqltypes.Result{ Fields: []*querypb.Field{{ Name: "abcd", @@ -365,10 +315,7 @@ func TestBindInSelect(t *testing.T) { "select :bv from dual", map[string]*querypb.BindVariable{"bv": sqltypes.StringBindVariable("\x00\xff")}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) want = &sqltypes.Result{ Fields: []*querypb.Field{{ Name: "", @@ -392,16 +339,10 @@ func TestBindInSelect(t *testing.T) { func TestHealth(t *testing.T) { response, err := http.Get(fmt.Sprintf("%s/debug/health", framework.ServerAddress)) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) defer response.Body.Close() result, err := io.ReadAll(response.Body) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) if string(result) != "ok" { t.Errorf("Health check: %s, want ok", result) } @@ -567,27 +508,18 @@ func TestDBAStatements(t *testing.T) { client := framework.NewClient() qr, err := client.Execute("show variables like 'version'", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) wantCol := sqltypes.NewVarChar("version") if !reflect.DeepEqual(qr.Rows[0][0], wantCol) { t.Errorf("Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol) } qr, err = client.Execute("describe vitess_a", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 4, len(qr.Rows)) qr, err = client.Execute("explain vitess_a", nil) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) assert.Equal(t, 4, len(qr.Rows)) } @@ -664,37 +596,36 @@ func TestClientFoundRows(t *testing.T) { func TestLastInsertId(t *testing.T) { client := framework.NewClient() _, err := client.Execute("insert ignore into vitess_autoinc_seq SET name = 'foo', sequence = 0", nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) defer client.Execute("delete from vitess_autoinc_seq where name = 'foo'", nil) - - if err := client.Begin(true); err != nil { - t.Fatal(err) - } + err = client.Begin(true) + require.NoError(t, err) defer client.Rollback() res, err := client.Execute("insert ignore into vitess_autoinc_seq SET name = 'foo', sequence = 0", nil) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) qr, err := client.Execute("update vitess_autoinc_seq set sequence=last_insert_id(sequence + 1) where name='foo'", nil) require.NoError(t, err) insID := res.InsertID - - if want, got := insID+1, qr.InsertID; want != got { - t.Errorf("insertId mismatch; got %v, want %v", got, want) - } + assert.Equal(t, insID+1, qr.InsertID, "insertID") qr, err = client.Execute("select sequence from vitess_autoinc_seq where name = 'foo'", nil) require.NoError(t, err) wantCol := sqltypes.NewUint64(insID + uint64(1)) - if !reflect.DeepEqual(qr.Rows[0][0], wantCol) { - t.Errorf("Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol) - } + assert.Truef(t, qr.Rows[0][0].Equal(wantCol), "Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol) +} + +func TestSelectLastInsertId(t *testing.T) { + client := framework.NewClient() + rs, err := client.ExecuteWithOptions("select 1 from dual where last_insert_id(42) = 42", nil, &querypb.ExecuteOptions{ + IncludedFields: querypb.ExecuteOptions_ALL, + FetchLastInsertId: true, + }) + require.NoError(t, err) + assert.EqualValues(t, 42, rs.InsertID) } func TestAppDebugRequest(t *testing.T) { @@ -781,10 +712,7 @@ func TestSelectBooleanSystemVariables(t *testing.T) { fmt.Sprintf("select :%s", tc.Variable), map[string]*querypb.BindVariable{tc.Variable: sqltypes.BoolBindVariable(tc.Value)}, ) - if err != nil { - t.Error(err) - return - } + require.NoError(t, err) require.NotEmpty(t, qr.Fields, "fields should not be empty") require.Equal(t, tc.Type, qr.Fields[0].Type, fmt.Sprintf("invalid type, wants: %+v, but got: %+v\n", tc.Type, qr.Fields[0].Type)) } diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 35587124108..54813e11bf3 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -19,7 +19,6 @@ package tabletmanager import ( "context" "fmt" - "io" "time" "github.com/spf13/pflag" @@ -29,22 +28,17 @@ import ( "vitess.io/vitess/go/stats" - "vitess.io/vitess/go/mysql" - "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/hook" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/logutil" "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/mysqlctl/backupstats" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/proto/vttime" "vitess.io/vitess/go/vt/servenv" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" ) // This file handles the initial backup restore upon startup. @@ -80,31 +74,6 @@ func registerIncrementalRestoreFlags(fs *pflag.FlagSet) { fs.StringVar(&restoreToPos, "restore-to-pos", restoreToPos, "(init incremental restore parameter) if set, run a point in time recovery that ends with the given position. This will attempt to use one full backup followed by zero or more incremental backups") } -var ( - // Flags for PITR - old iteration - binlogHost string - binlogPort int - binlogUser string - binlogPwd string - timeoutForGTIDLookup = 60 * time.Second - binlogSslCa string - binlogSslCert string - binlogSslKey string - binlogSslServerName string -) - -func registerPointInTimeRestoreFlags(fs *pflag.FlagSet) { - fs.StringVar(&binlogHost, "binlog_host", binlogHost, "PITR restore parameter: hostname/IP of binlog server.") - fs.IntVar(&binlogPort, "binlog_port", binlogPort, "PITR restore parameter: port of binlog server.") - fs.StringVar(&binlogUser, "binlog_user", binlogUser, "PITR restore parameter: username of binlog server.") - fs.StringVar(&binlogPwd, "binlog_password", binlogPwd, "PITR restore parameter: password of binlog server.") - fs.DurationVar(&timeoutForGTIDLookup, "pitr_gtid_lookup_timeout", timeoutForGTIDLookup, "PITR restore parameter: timeout for fetching gtid from timestamp.") - fs.StringVar(&binlogSslCa, "binlog_ssl_ca", binlogSslCa, "PITR restore parameter: Filename containing TLS CA certificate to verify binlog server TLS certificate against.") - fs.StringVar(&binlogSslCert, "binlog_ssl_cert", binlogSslCert, "PITR restore parameter: Filename containing mTLS client certificate to present to binlog server as authentication.") - fs.StringVar(&binlogSslKey, "binlog_ssl_key", binlogSslKey, "PITR restore parameter: Filename containing mTLS client private key for use in binlog server authentication.") - fs.StringVar(&binlogSslServerName, "binlog_ssl_server_name", binlogSslServerName, "PITR restore parameter: TLS server name (common name) to verify against for the binlog server we are connecting to (If not set: use the hostname or IP supplied in --binlog_host).") -} - func init() { servenv.OnParseFor("vtcombo", registerRestoreFlags) servenv.OnParseFor("vttablet", registerRestoreFlags) @@ -112,9 +81,6 @@ func init() { servenv.OnParseFor("vtcombo", registerIncrementalRestoreFlags) servenv.OnParseFor("vttablet", registerIncrementalRestoreFlags) - servenv.OnParseFor("vtcombo", registerPointInTimeRestoreFlags) - servenv.OnParseFor("vttablet", registerPointInTimeRestoreFlags) - statsRestoreBackupTime = stats.NewString("RestoredBackupTime") statsRestoreBackupPosition = stats.NewString("RestorePosition") } @@ -299,15 +265,6 @@ func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.L pos = backupManifest.Position params.Logger.Infof("Restore: pos=%v", replication.EncodePosition(pos)) } - // If SnapshotTime is set , then apply the incremental change - if keyspaceInfo.SnapshotTime != nil { - params.Logger.Infof("Restore: Restoring to time %v from binlog", keyspaceInfo.SnapshotTime) - err = tm.restoreToTimeFromBinlog(ctx, pos, keyspaceInfo.SnapshotTime) - if err != nil { - log.Errorf("unable to restore to the specified time %s, error : %v", keyspaceInfo.SnapshotTime.String(), err) - return nil - } - } switch { case err == nil && backupManifest != nil: // Starting from here we won't be able to recover if we get stopped by a cancelled @@ -365,196 +322,6 @@ func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.L return tm.tmState.ChangeTabletType(bgCtx, originalType, DBActionNone) } -// restoreToTimeFromBinlog restores to the snapshot time of the keyspace -// currently this works with mysql based database only (as it uses mysql specific queries for restoring) -func (tm *TabletManager) restoreToTimeFromBinlog(ctx context.Context, pos replication.Position, restoreTime *vttime.Time) error { - // validate the minimal settings necessary for connecting to binlog server - if binlogHost == "" || binlogPort <= 0 || binlogUser == "" { - log.Warning("invalid binlog server setting, restoring to last available backup.") - return nil - } - - timeoutCtx, cancelFnc := context.WithTimeout(ctx, timeoutForGTIDLookup) - defer cancelFnc() - - afterGTIDPos, beforeGTIDPos, err := tm.getGTIDFromTimestamp(timeoutCtx, pos, restoreTime.Seconds) - if err != nil { - return err - } - - if afterGTIDPos == "" && beforeGTIDPos == "" { - return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, fmt.Sprintf("unable to fetch the GTID for the specified time - %s", restoreTime.String())) - } else if afterGTIDPos == "" && beforeGTIDPos != "" { - log.Info("no afterGTIDPos found, which implies we reached the end of all GTID events") - } - - log.Infof("going to restore upto the GTID - %s", afterGTIDPos) - // when we don't have before GTID, we will take it as current backup pos's last GTID - // this is case where someone tries to restore just to the 1st event after backup - if beforeGTIDPos == "" { - beforeGTIDPos = pos.GTIDSet.Last() - } - err = tm.catchupToGTID(timeoutCtx, afterGTIDPos, beforeGTIDPos) - if err != nil { - return vterrors.Wrapf(err, "unable to replicate upto desired GTID : %s", afterGTIDPos) - } - - return nil -} - -// getGTIDFromTimestamp computes 2 GTIDs based on restoreTime -// afterPos is the GTID of the first event at or after restoreTime. -// beforePos is the GTID of the last event before restoreTime. This is the GTID upto which replication will be applied -// afterPos can be used directly in the query `START SLAVE UNTIL SQL_BEFORE_GTIDS = ”` -// beforePos will be used to check if replication was able to catch up from the binlog server -func (tm *TabletManager) getGTIDFromTimestamp(ctx context.Context, pos replication.Position, restoreTime int64) (afterPos string, beforePos string, err error) { - connParams := &mysql.ConnParams{ - Host: binlogHost, - Port: binlogPort, - Uname: binlogUser, - SslCa: binlogSslCa, - SslCert: binlogSslCert, - SslKey: binlogSslKey, - ServerName: binlogSslServerName, - } - if binlogPwd != "" { - connParams.Pass = binlogPwd - } - if binlogSslCa != "" || binlogSslCert != "" { - connParams.EnableSSL() - } - dbCfgs := &dbconfigs.DBConfigs{ - Host: connParams.Host, - Port: connParams.Port, - } - dbCfgs.SetDbParams(*connParams, *connParams, *connParams) - vsClient := vreplication.NewReplicaConnector(tm.Env, connParams) - - filter := &binlogdatapb.Filter{ - Rules: []*binlogdatapb.Rule{{ - Match: "/.*", - }}, - } - - // get current lastPos of binlog server, so that if we hit that in vstream, we'll return from there - binlogConn, err := mysql.Connect(ctx, connParams) - if err != nil { - return "", "", err - } - defer binlogConn.Close() - lastPos, err := binlogConn.PrimaryPosition() - if err != nil { - return "", "", err - } - - gtidsChan := make(chan []string, 1) - - go func() { - err := vsClient.VStream(ctx, replication.EncodePosition(pos), filter, func(events []*binlogdatapb.VEvent) error { - for _, event := range events { - if event.Gtid != "" { - // check if we reached the lastPos then return - eventPos, err := replication.DecodePosition(event.Gtid) - if err != nil { - return err - } - - if event.Timestamp >= restoreTime { - afterPos = event.Gtid - gtidsChan <- []string{event.Gtid, beforePos} - return io.EOF - } - - if eventPos.AtLeast(lastPos) { - gtidsChan <- []string{"", beforePos} - return io.EOF - } - beforePos = event.Gtid - } - } - return nil - }) - if err != nil && err != io.EOF { - log.Warningf("Error using VStream to find timestamp for GTID position: %v error: %v", pos, err) - gtidsChan <- []string{"", ""} - } - }() - defer vsClient.Close() - select { - case val := <-gtidsChan: - return val[0], val[1], nil - case <-ctx.Done(): - log.Warningf("Can't find the GTID from restore time stamp, exiting.") - return "", beforePos, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "unable to find GTID from the snapshot time as context timed out") - } -} - -// catchupToGTID replicates upto specified GTID from binlog server -// -// copies the data from binlog server by pointing to as replica -// waits till all events to GTID replicated -// once done, it will reset the replication -func (tm *TabletManager) catchupToGTID(ctx context.Context, afterGTIDPos string, beforeGTIDPos string) error { - var afterGTID replication.Position - if afterGTIDPos != "" { - var err error - afterGTID, err = replication.DecodePosition(afterGTIDPos) - if err != nil { - return err - } - } - - beforeGTIDPosParsed, err := replication.DecodePosition(beforeGTIDPos) - if err != nil { - return err - } - - if err := tm.MysqlDaemon.CatchupToGTID(ctx, afterGTID); err != nil { - return vterrors.Wrap(err, fmt.Sprintf("failed to restart the replication until %s GTID", afterGTID.GTIDSet.Last())) - } - log.Infof("Waiting for position to reach", beforeGTIDPosParsed.GTIDSet.Last()) - // Could not use `agent.MysqlDaemon.WaitSourcePos` as replication is stopped with `START REPLICA UNTIL SQL_BEFORE_GTIDS` - // this is as per https://dev.mysql.com/doc/refman/8.0/en/start-replica.html - // We need to wait until replication catches upto the specified afterGTIDPos - chGTIDCaughtup := make(chan bool) - go func() { - timeToWait := time.Now().Add(timeoutForGTIDLookup) - for time.Now().Before(timeToWait) { - pos, err := tm.MysqlDaemon.PrimaryPosition(ctx) - if err != nil { - chGTIDCaughtup <- false - } - - if pos.AtLeast(beforeGTIDPosParsed) { - chGTIDCaughtup <- true - } - select { - case <-ctx.Done(): - chGTIDCaughtup <- false - default: - time.Sleep(300 * time.Millisecond) - } - } - }() - select { - case resp := <-chGTIDCaughtup: - if resp { - if err := tm.MysqlDaemon.StopReplication(ctx, nil); err != nil { - return vterrors.Wrap(err, "failed to stop replication") - } - if err := tm.MysqlDaemon.ResetReplicationParameters(ctx); err != nil { - return vterrors.Wrap(err, "failed to reset replication") - } - - return nil - } - return vterrors.Wrap(err, "error while fetching the current GTID position") - case <-ctx.Done(): - log.Warningf("Could not copy up to GTID.") - return vterrors.Wrapf(err, "context timeout while restoring up to specified GTID - %s", beforeGTIDPos) - } -} - // disableReplication stops and resets replication on the mysql server. It moreover sets impossible replication // source params, so that the replica can't possibly reconnect. It would take a `CHANGE [MASTER|REPLICATION SOURCE] TO ...` to // make the mysql server replicate again (available via tm.MysqlDaemon.SetReplicationPosition) diff --git a/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go b/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go index 6d016709cce..03be2271d34 100644 --- a/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go +++ b/go/vt/vttablet/tabletmanager/vdiff/shard_streamer.go @@ -37,9 +37,11 @@ type shardStreamer struct { err error } +var _ engine.StreamExecutor = (*shardStreamer)(nil) + // StreamExecute implements the StreamExecutor interface of the Primitive executor and // it simply waits for a result to be available for this shard and sends it to the merge sorter. -func (sm *shardStreamer) StreamExecute(ctx context.Context, vcursor engine.VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (sm *shardStreamer) StreamExecute(_ context.Context, _ engine.VCursor, _ map[string]*querypb.BindVariable, _, _ bool, callback func(*sqltypes.Result) error) error { for result := range sm.result { if err := callback(result); err != nil { return err diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go index 519b60b79d6..e4a165960fd 100644 --- a/go/vt/vttablet/tabletserver/query_executor.go +++ b/go/vt/vttablet/tabletserver/query_executor.go @@ -69,7 +69,9 @@ type QueryExecutor struct { } const ( - streamRowsSize = 256 + streamRowsSize = 256 + resetLastIDQuery = "select last_insert_id(18446744073709547416)" + resetLastIDValue = 18446744073709547416 ) var ( @@ -1111,42 +1113,97 @@ func (qre *QueryExecutor) getSelectLimit() int64 { func (qre *QueryExecutor) execDBConn(conn *connpool.Conn, sql string, wantfields bool) (*sqltypes.Result, error) { span, ctx := trace.NewSpan(qre.ctx, "QueryExecutor.execDBConn") defer span.Finish() - defer qre.logStats.AddRewrittenSQL(sql, time.Now()) qd := NewQueryDetail(qre.logStats.Ctx, conn) - err := qre.tsv.statelessql.Add(qd) - if err != nil { + + if err := qre.tsv.statelessql.Add(qd); err != nil { return nil, err } defer qre.tsv.statelessql.Remove(qd) - return conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err := qre.resetLastInsertIDIfNeeded(ctx, conn); err != nil { + return nil, err + } + + exec, err := conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err != nil { + return nil, err + } + + if err := qre.fetchLastInsertID(ctx, conn, exec); err != nil { + return nil, err + } + + return exec, nil } func (qre *QueryExecutor) execStatefulConn(conn *StatefulConnection, sql string, wantfields bool) (*sqltypes.Result, error) { span, ctx := trace.NewSpan(qre.ctx, "QueryExecutor.execStatefulConn") defer span.Finish() - defer qre.logStats.AddRewrittenSQL(sql, time.Now()) qd := NewQueryDetail(qre.logStats.Ctx, conn) - err := qre.tsv.statefulql.Add(qd) - if err != nil { + + if err := qre.tsv.statefulql.Add(qd); err != nil { return nil, err } defer qre.tsv.statefulql.Remove(qd) - return conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err := qre.resetLastInsertIDIfNeeded(ctx, conn.UnderlyingDBConn().Conn); err != nil { + return nil, err + } + + exec, err := conn.Exec(ctx, sql, int(qre.tsv.qe.maxResultSize.Load()), wantfields) + if err != nil { + return nil, err + } + + if err := qre.fetchLastInsertID(ctx, conn.UnderlyingDBConn().Conn, exec); err != nil { + return nil, err + } + + return exec, nil +} + +func (qre *QueryExecutor) resetLastInsertIDIfNeeded(ctx context.Context, conn *connpool.Conn) error { + if qre.options.GetFetchLastInsertId() { + // if the query contains a last_insert_id(x) function, + // we need to reset the last insert id to check if it was set by the query or not + _, err := conn.Exec(ctx, resetLastIDQuery, 1, false) + if err != nil { + return err + } + } + return nil +} + +func (qre *QueryExecutor) fetchLastInsertID(ctx context.Context, conn *connpool.Conn, exec *sqltypes.Result) error { + if exec.InsertIDUpdated() || !qre.options.GetFetchLastInsertId() { + return nil + } + + result, err := conn.Exec(ctx, "select last_insert_id()", 1, false) + if err != nil { + return err + } + + cell := result.Rows[0][0] + insertID, err := cell.ToCastUint64() + if err != nil { + return err + } + if resetLastIDValue != insertID { + exec.InsertID = insertID + exec.InsertIDChanged = true + } + return nil } func (qre *QueryExecutor) execStreamSQL(conn *connpool.PooledConn, isTransaction bool, sql string, callback func(*sqltypes.Result) error) error { span, ctx := trace.NewSpan(qre.ctx, "QueryExecutor.execStreamSQL") + defer span.Finish() trace.AnnotateSQL(span, sqlparser.Preview(sql)) - callBackClosingSpan := func(result *sqltypes.Result) error { - defer span.Finish() - return callback(result) - } start := time.Now() defer qre.logStats.AddRewrittenSQL(sql, start) @@ -1157,20 +1214,47 @@ func (qre *QueryExecutor) execStreamSQL(conn *connpool.PooledConn, isTransaction // This change will ensure that long-running streaming stateful queries get gracefully shutdown during ServingTypeChange // once their grace period is over. qd := NewQueryDetail(qre.logStats.Ctx, conn.Conn) + + if err := qre.resetLastInsertIDIfNeeded(ctx, conn.Conn); err != nil { + return err + } + + lastInsertIDSet := false + cb := func(result *sqltypes.Result) error { + if result != nil && result.InsertIDUpdated() { + lastInsertIDSet = true + } + return callback(result) + } + + var err error if isTransaction { - err := qre.tsv.statefulql.Add(qd) + err = qre.tsv.statefulql.Add(qd) if err != nil { return err } defer qre.tsv.statefulql.Remove(qd) - return conn.Conn.StreamOnce(ctx, sql, callBackClosingSpan, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) + err = conn.Conn.StreamOnce(ctx, sql, cb, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) + } else { + err = qre.tsv.olapql.Add(qd) + if err != nil { + return err + } + defer qre.tsv.olapql.Remove(qd) + err = conn.Conn.Stream(ctx, sql, cb, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) } - err := qre.tsv.olapql.Add(qd) - if err != nil { + + if err != nil || lastInsertIDSet || !qre.options.GetFetchLastInsertId() { return err } - defer qre.tsv.olapql.Remove(qd) - return conn.Conn.Stream(ctx, sql, callBackClosingSpan, allocStreamResult, int(qre.tsv.qe.streamBufferSize.Load()), sqltypes.IncludeFieldsOrDefault(qre.options)) + res := &sqltypes.Result{} + if err = qre.fetchLastInsertID(ctx, conn.Conn, res); err != nil { + return err + } + if res.InsertIDUpdated() { + return callback(res) + } + return nil } func (qre *QueryExecutor) recordUserQuery(queryType string, duration int64) { diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 4caad42ce1f..2e9fc5f508d 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -167,6 +167,8 @@ type shardStreamer struct { err error } +var _ engine.StreamExecutor = (*shardStreamer)(nil) + // VDiff reports differences between the sources and targets of a vreplication workflow. func (wr *Wrangler) VDiff(ctx context.Context, targetKeyspace, workflowName, sourceCell, targetCell, tabletTypesStr string, filteredReplicationWaitTime time.Duration, format string, maxRows int64, tables string, debug, onlyPks bool, @@ -1148,7 +1150,7 @@ func (pe *primitiveExecutor) drain(ctx context.Context) (int, error) { // ----------------------------------------------------------------- // shardStreamer -func (sm *shardStreamer) StreamExecute(ctx context.Context, vcursor engine.VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (sm *shardStreamer) StreamExecute(_ context.Context, _ engine.VCursor, _ map[string]*querypb.BindVariable, _, _ bool, callback func(*sqltypes.Result) error) error { for result := range sm.result { if err := callback(result); err != nil { return err diff --git a/proto/query.proto b/proto/query.proto index c5f53ea6e5d..27a04d77f0a 100644 --- a/proto/query.proto +++ b/proto/query.proto @@ -363,6 +363,12 @@ message ExecuteOptions { oneof timeout { int64 authoritative_timeout = 17; } + + // fetch_last_insert_id indicates that after executing a DML involving last_insert_id(x), + // a subsequent "SELECT last_insert_id()" should be performed to retrieve the updated value. + // This is to circumvent a bug where setting last_insert_id(x) to zero is not signaled by mysql + // https://bugs.mysql.com/bug.php?id=116939 + bool fetch_last_insert_id = 18; } // Field describes a single column returned by a query @@ -427,6 +433,7 @@ message QueryResult { repeated Row rows = 4; string info = 6; string session_state_changes = 7; + bool insert_id_changed=8; } // QueryWarning is used to convey out of band query execution warnings diff --git a/test/bin/.keep b/test/bin/.keep new file mode 100644 index 00000000000..7f6eda3a448 --- /dev/null +++ b/test/bin/.keep @@ -0,0 +1 @@ +Do not remove. Ensures existence of directory. diff --git a/test/bin/rippled b/test/bin/rippled deleted file mode 100755 index c7b6bea3b95..00000000000 Binary files a/test/bin/rippled and /dev/null differ diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 7b921fc034a..5be0e3ba031 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -40733,6 +40733,9 @@ export namespace query { /** ExecuteOptions authoritative_timeout */ authoritative_timeout?: (number|Long|null); + + /** ExecuteOptions fetch_last_insert_id */ + fetch_last_insert_id?: (boolean|null); } /** Represents an ExecuteOptions. */ @@ -40783,6 +40786,9 @@ export namespace query { /** ExecuteOptions authoritative_timeout. */ public authoritative_timeout?: (number|Long|null); + /** ExecuteOptions fetch_last_insert_id. */ + public fetch_last_insert_id: boolean; + /** ExecuteOptions timeout. */ public timeout?: "authoritative_timeout"; @@ -41200,6 +41206,9 @@ export namespace query { /** QueryResult session_state_changes */ session_state_changes?: (string|null); + + /** QueryResult insert_id_changed */ + insert_id_changed?: (boolean|null); } /** Represents a QueryResult. */ @@ -41229,6 +41238,9 @@ export namespace query { /** QueryResult session_state_changes. */ public session_state_changes: string; + /** QueryResult insert_id_changed. */ + public insert_id_changed: boolean; + /** * Creates a new QueryResult instance using the specified properties. * @param [properties] Properties to set diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index e5bcf766b40..11b70963fb0 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -97123,6 +97123,7 @@ export const query = $root.query = (() => { * @property {string|null} [WorkloadName] ExecuteOptions WorkloadName * @property {string|null} [priority] ExecuteOptions priority * @property {number|Long|null} [authoritative_timeout] ExecuteOptions authoritative_timeout + * @property {boolean|null} [fetch_last_insert_id] ExecuteOptions fetch_last_insert_id */ /** @@ -97245,6 +97246,14 @@ export const query = $root.query = (() => { */ ExecuteOptions.prototype.authoritative_timeout = null; + /** + * ExecuteOptions fetch_last_insert_id. + * @member {boolean} fetch_last_insert_id + * @memberof query.ExecuteOptions + * @instance + */ + ExecuteOptions.prototype.fetch_last_insert_id = false; + // OneOf field names bound to virtual getters and setters let $oneOfFields; @@ -97313,6 +97322,8 @@ export const query = $root.query = (() => { writer.uint32(/* id 16, wireType 2 =*/130).string(message.priority); if (message.authoritative_timeout != null && Object.hasOwnProperty.call(message, "authoritative_timeout")) writer.uint32(/* id 17, wireType 0 =*/136).int64(message.authoritative_timeout); + if (message.fetch_last_insert_id != null && Object.hasOwnProperty.call(message, "fetch_last_insert_id")) + writer.uint32(/* id 18, wireType 0 =*/144).bool(message.fetch_last_insert_id); return writer; }; @@ -97406,6 +97417,10 @@ export const query = $root.query = (() => { message.authoritative_timeout = reader.int64(); break; } + case 18: { + message.fetch_last_insert_id = reader.bool(); + break; + } default: reader.skipType(tag & 7); break; @@ -97534,6 +97549,9 @@ export const query = $root.query = (() => { if (!$util.isInteger(message.authoritative_timeout) && !(message.authoritative_timeout && $util.isInteger(message.authoritative_timeout.low) && $util.isInteger(message.authoritative_timeout.high))) return "authoritative_timeout: integer|Long expected"; } + if (message.fetch_last_insert_id != null && message.hasOwnProperty("fetch_last_insert_id")) + if (typeof message.fetch_last_insert_id !== "boolean") + return "fetch_last_insert_id: boolean expected"; return null; }; @@ -97746,6 +97764,8 @@ export const query = $root.query = (() => { message.authoritative_timeout = object.authoritative_timeout; else if (typeof object.authoritative_timeout === "object") message.authoritative_timeout = new $util.LongBits(object.authoritative_timeout.low >>> 0, object.authoritative_timeout.high >>> 0).toNumber(); + if (object.fetch_last_insert_id != null) + message.fetch_last_insert_id = Boolean(object.fetch_last_insert_id); return message; }; @@ -97780,6 +97800,7 @@ export const query = $root.query = (() => { object.consolidator = options.enums === String ? "CONSOLIDATOR_UNSPECIFIED" : 0; object.WorkloadName = ""; object.priority = ""; + object.fetch_last_insert_id = false; } if (message.included_fields != null && message.hasOwnProperty("included_fields")) object.included_fields = options.enums === String ? $root.query.ExecuteOptions.IncludedFields[message.included_fields] === undefined ? message.included_fields : $root.query.ExecuteOptions.IncludedFields[message.included_fields] : message.included_fields; @@ -97819,6 +97840,8 @@ export const query = $root.query = (() => { if (options.oneofs) object.timeout = "authoritative_timeout"; } + if (message.fetch_last_insert_id != null && message.hasOwnProperty("fetch_last_insert_id")) + object.fetch_last_insert_id = message.fetch_last_insert_id; return object; }; @@ -98879,6 +98902,7 @@ export const query = $root.query = (() => { * @property {Array.|null} [rows] QueryResult rows * @property {string|null} [info] QueryResult info * @property {string|null} [session_state_changes] QueryResult session_state_changes + * @property {boolean|null} [insert_id_changed] QueryResult insert_id_changed */ /** @@ -98946,6 +98970,14 @@ export const query = $root.query = (() => { */ QueryResult.prototype.session_state_changes = ""; + /** + * QueryResult insert_id_changed. + * @member {boolean} insert_id_changed + * @memberof query.QueryResult + * @instance + */ + QueryResult.prototype.insert_id_changed = false; + /** * Creates a new QueryResult instance using the specified properties. * @function create @@ -98984,6 +99016,8 @@ export const query = $root.query = (() => { writer.uint32(/* id 6, wireType 2 =*/50).string(message.info); if (message.session_state_changes != null && Object.hasOwnProperty.call(message, "session_state_changes")) writer.uint32(/* id 7, wireType 2 =*/58).string(message.session_state_changes); + if (message.insert_id_changed != null && Object.hasOwnProperty.call(message, "insert_id_changed")) + writer.uint32(/* id 8, wireType 0 =*/64).bool(message.insert_id_changed); return writer; }; @@ -99046,6 +99080,10 @@ export const query = $root.query = (() => { message.session_state_changes = reader.string(); break; } + case 8: { + message.insert_id_changed = reader.bool(); + break; + } default: reader.skipType(tag & 7); break; @@ -99111,6 +99149,9 @@ export const query = $root.query = (() => { if (message.session_state_changes != null && message.hasOwnProperty("session_state_changes")) if (!$util.isString(message.session_state_changes)) return "session_state_changes: string expected"; + if (message.insert_id_changed != null && message.hasOwnProperty("insert_id_changed")) + if (typeof message.insert_id_changed !== "boolean") + return "insert_id_changed: boolean expected"; return null; }; @@ -99168,6 +99209,8 @@ export const query = $root.query = (() => { message.info = String(object.info); if (object.session_state_changes != null) message.session_state_changes = String(object.session_state_changes); + if (object.insert_id_changed != null) + message.insert_id_changed = Boolean(object.insert_id_changed); return message; }; @@ -99201,6 +99244,7 @@ export const query = $root.query = (() => { object.insert_id = options.longs === String ? "0" : 0; object.info = ""; object.session_state_changes = ""; + object.insert_id_changed = false; } if (message.fields && message.fields.length) { object.fields = []; @@ -99226,6 +99270,8 @@ export const query = $root.query = (() => { object.info = message.info; if (message.session_state_changes != null && message.hasOwnProperty("session_state_changes")) object.session_state_changes = message.session_state_changes; + if (message.insert_id_changed != null && message.hasOwnProperty("insert_id_changed")) + object.insert_id_changed = message.insert_id_changed; return object; };