Adding ResultExtras to Result for Invalidation.

ResultExtras is part of Query Result. It contains:
- an optional EventToken (returned if ExecuteOptions.include_event_token
  is set)
- an optional 'fresher' flag (set if ExecuteOptions.compare_event_token
  is set, and that token is older than the current TabletServer event
  token.)

The flags are set by TabletServer, and merged by VtGate.ScatterConn.
This commit is contained in:
Alain Jobart 2016-09-16 09:21:08 -07:00
Родитель 4edf1b231a
Коммит f840e69b36
14 изменённых файлов: 772 добавлений и 244 удалений

Просмотреть файл

@ -67,6 +67,7 @@ func ResultToProto3(qr *Result) *querypb.QueryResult {
RowsAffected: qr.RowsAffected,
InsertId: qr.InsertID,
Rows: RowsToProto3(qr.Rows),
Extras: qr.Extras,
}
}
@ -81,6 +82,7 @@ func Proto3ToResult(qr *querypb.QueryResult) *Result {
RowsAffected: qr.RowsAffected,
InsertID: qr.InsertId,
Rows: proto3ToRows(qr.Fields, qr.Rows),
Extras: qr.Extras,
}
}
@ -96,6 +98,7 @@ func CustomProto3ToResult(fields []*querypb.Field, qr *querypb.QueryResult) *Res
RowsAffected: qr.RowsAffected,
InsertID: qr.InsertId,
Rows: proto3ToRows(fields, qr.Rows),
Extras: qr.Extras,
}
}

Просмотреть файл

@ -35,6 +35,13 @@ func TestResult(t *testing.T) {
NULL,
NULL,
}},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "shard0",
Position: "position0",
},
},
}
p3Result := &querypb.QueryResult{
Fields: fields,
@ -47,6 +54,13 @@ func TestResult(t *testing.T) {
Lengths: []int64{2, -1, -1},
Values: []byte("bb"),
}},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "shard0",
Position: "position0",
},
},
}
p3converted := ResultToProto3(sqlResult)
if !reflect.DeepEqual(p3converted, p3Result) {
@ -97,6 +111,13 @@ func TestResults(t *testing.T) {
testVal(Int64, "1"),
testVal(Float64, "2"),
}},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "shard0",
Position: "position0",
},
},
}, {
Fields: fields2,
InsertID: 3,
@ -106,6 +127,13 @@ func TestResults(t *testing.T) {
testVal(Int64, "3"),
testVal(Float64, "4"),
}},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "shard1",
Position: "position1",
},
},
}}
p3Results := []*querypb.QueryResult{{
Fields: fields1,
@ -115,6 +143,13 @@ func TestResults(t *testing.T) {
Lengths: []int64{2, 1, 1},
Values: []byte("aa12"),
}},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "shard0",
Position: "position0",
},
},
}, {
Fields: fields2,
InsertId: 3,
@ -123,6 +158,13 @@ func TestResults(t *testing.T) {
Lengths: []int64{2, 1, 1},
Values: []byte("bb34"),
}},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "shard1",
Position: "position1",
},
},
}}
p3converted := ResultsToProto3(sqlResults)
if !reflect.DeepEqual(p3converted, p3Results) {

Просмотреть файл

@ -8,10 +8,11 @@ import querypb "github.com/youtube/vitess/go/vt/proto/query"
// Result represents a query result.
type Result struct {
Fields []*querypb.Field `json:"fields"`
RowsAffected uint64 `json:"rows_affected"`
InsertID uint64 `json:"insert_id"`
Rows [][]Value `json:"rows"`
Fields []*querypb.Field `json:"fields"`
RowsAffected uint64 `json:"rows_affected"`
InsertID uint64 `json:"insert_id"`
Rows [][]Value `json:"rows"`
Extras *querypb.ResultExtras `json:"extras"`
}
// ResultStream is an interface for receiving Result. It is used for
@ -67,6 +68,18 @@ func (result *Result) Copy() *Result {
}
out.Rows = rows
}
if result.Extras != nil {
out.Extras = &querypb.ResultExtras{
Fresher: result.Extras.Fresher,
}
if result.Extras.EventToken != nil {
out.Extras.EventToken = &querypb.EventToken{
Timestamp: result.Extras.EventToken.Timestamp,
Shard: result.Extras.EventToken.Shard,
Position: result.Extras.EventToken.Position,
}
}
}
return out
}
@ -90,22 +103,17 @@ func MakeRowTrusted(fields []*querypb.Field, row *querypb.Row) []Value {
// StripFieldNames will return a new Result that has the same Rows,
// but the Field objects will have their Name emptied. Note we don't
// proto.Copy each Field for performance reasons, but we only copy the
// Type field. If/when more fields are added to pb.Field, they will
// also need to be copied. Same for Result.
// individual fields.
func (result *Result) StripFieldNames() *Result {
if len(result.Fields) == 0 {
return result
}
r := &Result{
Fields: make([]*querypb.Field, len(result.Fields)),
RowsAffected: result.RowsAffected,
InsertID: result.InsertID,
Rows: result.Rows,
}
r := *result
r.Fields = make([]*querypb.Field, len(result.Fields))
newFieldsArray := make([]querypb.Field, len(result.Fields))
for i, f := range result.Fields {
r.Fields[i] = &newFieldsArray[i]
newFieldsArray[i].Type = f.Type
}
return r
return &r
}

Просмотреть файл

@ -49,6 +49,14 @@ func TestCopy(t *testing.T) {
{testVal(Int64, "2"), MakeTrusted(VarChar, nil)},
{testVal(Int64, "3"), testVal(VarChar, "")},
},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "sh",
Position: "po",
},
Fresher: true,
},
}
want := &Result{
Fields: []*querypb.Field{{
@ -63,6 +71,14 @@ func TestCopy(t *testing.T) {
{testVal(Int64, "2"), testVal(VarChar, "")},
{testVal(Int64, "3"), testVal(VarChar, "")},
},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "sh",
Position: "po",
},
Fresher: true,
},
}
out := in.Copy()
// Change in so we're sure out got actually copied

Просмотреть файл

@ -0,0 +1,48 @@
// Package eventtoken includes utility methods for event token
// handling.
//
// FIXME(alainjobart): it will be used to compare event tokens in
// other ways later, but for now it's a bit small.
package eventtoken
import (
querypb "github.com/youtube/vitess/go/vt/proto/query"
)
// Minimum returns an event token that is guaranteed to happen before
// both provided EventToken objects.
//
// FIXME(alainjobart) for now, we always strip the shard and position,
// and only look at timestamp. It is only used across shards so it's
// not a big deal. When we compare values within a shard, we'll have
// to fix this.
func Minimum(ev1, ev2 *querypb.EventToken) *querypb.EventToken {
if ev1 == nil || ev2 == nil {
// One or the other is not set, we can't do anything.
return nil
}
if ev1.Timestamp < ev2.Timestamp {
return &querypb.EventToken{
Timestamp: ev1.Timestamp,
}
}
return &querypb.EventToken{
Timestamp: ev2.Timestamp,
}
}
// Fresher returns true if ev1 is fresher than ev2. In case of doubt,
// it returns false.
//
// FIXME(alainjobart): if both events come from the same shard, we can
// compare replication position (after parsing it). Need to implement that.
// FIMXE(alainjobart): when it's more than just a simple compare, add
// unit tests too.
func Fresher(ev1, ev2 *querypb.EventToken) bool {
if ev1 == nil || ev2 == nil {
return false
}
return ev1.Timestamp > ev2.Timestamp
}

Просмотреть файл

@ -0,0 +1,63 @@
package eventtoken
import (
"testing"
"github.com/golang/protobuf/proto"
querypb "github.com/youtube/vitess/go/vt/proto/query"
)
func TestMinimum(t *testing.T) {
testcases := []struct {
ev1 *querypb.EventToken
ev2 *querypb.EventToken
expected *querypb.EventToken
}{{
ev1: nil,
ev2: nil,
expected: nil,
}, {
ev1: &querypb.EventToken{
Timestamp: 123,
},
ev2: nil,
expected: nil,
}, {
ev1: nil,
ev2: &querypb.EventToken{
Timestamp: 123,
},
expected: nil,
}, {
ev1: &querypb.EventToken{
Timestamp: 123,
},
ev2: &querypb.EventToken{
Timestamp: 456,
},
expected: &querypb.EventToken{
Timestamp: 123,
},
}, {
ev1: &querypb.EventToken{
Timestamp: 456,
},
ev2: &querypb.EventToken{
Timestamp: 123,
},
expected: &querypb.EventToken{
Timestamp: 123,
},
}}
for _, tcase := range testcases {
got := Minimum(tcase.ev1, tcase.ev2)
if tcase.expected == nil && got != nil {
t.Errorf("expected nil result for Minimum(%v, %v) but got: %v", tcase.ev1, tcase.ev2, got)
continue
}
if !proto.Equal(got, tcase.expected) {
t.Errorf("got %v but expected %v for Minimum(%v, %v)", got, tcase.expected, tcase.ev1, tcase.ev2)
}
}
}

Просмотреть файл

@ -18,6 +18,7 @@ It has these top-level messages:
ExecuteOptions
Field
Row
ResultExtras
QueryResult
StreamEvent
ExecuteRequest
@ -288,7 +289,7 @@ func (x StreamEvent_Statement_Category) String() string {
return proto.EnumName(StreamEvent_Statement_Category_name, int32(x))
}
func (StreamEvent_Statement_Category) EnumDescriptor() ([]byte, []int) {
return fileDescriptor0, []int{10, 0, 0}
return fileDescriptor0, []int{11, 0, 0}
}
type SplitQueryRequest_Algorithm int32
@ -311,7 +312,7 @@ func (x SplitQueryRequest_Algorithm) String() string {
return proto.EnumName(SplitQueryRequest_Algorithm_name, int32(x))
}
func (SplitQueryRequest_Algorithm) EnumDescriptor() ([]byte, []int) {
return fileDescriptor0, []int{27, 0}
return fileDescriptor0, []int{28, 0}
}
// Target describes what the client expects the tablet is.
@ -421,6 +422,12 @@ type ExecuteOptions struct {
// This is an optimization for high-QPS queries where the client knows
// what it's getting.
ExcludeFieldNames bool `protobuf:"varint,1,opt,name=exclude_field_names,json=excludeFieldNames" json:"exclude_field_names,omitempty"`
// If set, we will try to include an EventToken with the responses.
IncludeEventToken bool `protobuf:"varint,2,opt,name=include_event_token,json=includeEventToken" json:"include_event_token,omitempty"`
// If set, the fresher field may be set as a result comparison to this token.
// This is a shortcut so the application doesn't need to care about
// comparing EventTokens.
CompareEventToken *EventToken `protobuf:"bytes,3,opt,name=compare_event_token,json=compareEventToken" json:"compare_event_token,omitempty"`
}
func (m *ExecuteOptions) Reset() { *m = ExecuteOptions{} }
@ -428,6 +435,13 @@ func (m *ExecuteOptions) String() string { return proto.CompactTextSt
func (*ExecuteOptions) ProtoMessage() {}
func (*ExecuteOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *ExecuteOptions) GetCompareEventToken() *EventToken {
if m != nil {
return m.CompareEventToken
}
return nil
}
// Field describes a single column returned by a query
type Field struct {
// name of the field as returned by mysql C API
@ -457,6 +471,29 @@ func (m *Row) String() string { return proto.CompactTextString(m) }
func (*Row) ProtoMessage() {}
func (*Row) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
// ResultExtras contains optional out-of-band information. Usually the
// extras are requested by adding ExecuteOptions flags.
type ResultExtras struct {
// event_token is populated if the include_event_token flag is set
// in ExecuteOptions.
EventToken *EventToken `protobuf:"bytes,1,opt,name=event_token,json=eventToken" json:"event_token,omitempty"`
// If set, it means the data returned with this result is fresher
// than the compare_token passed in the ExecuteOptions.
Fresher bool `protobuf:"varint,2,opt,name=fresher" json:"fresher,omitempty"`
}
func (m *ResultExtras) Reset() { *m = ResultExtras{} }
func (m *ResultExtras) String() string { return proto.CompactTextString(m) }
func (*ResultExtras) ProtoMessage() {}
func (*ResultExtras) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (m *ResultExtras) GetEventToken() *EventToken {
if m != nil {
return m.EventToken
}
return nil
}
// QueryResult is returned by Execute and ExecuteStream.
//
// As returned by Execute, len(fields) is always equal to len(row)
@ -467,16 +504,17 @@ func (*Row) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
// len(QueryResult[0].fields) is always equal to len(row) (for each
// row in rows for each QueryResult in QueryResult[1:]).
type QueryResult struct {
Fields []*Field `protobuf:"bytes,1,rep,name=fields" json:"fields,omitempty"`
RowsAffected uint64 `protobuf:"varint,2,opt,name=rows_affected,json=rowsAffected" json:"rows_affected,omitempty"`
InsertId uint64 `protobuf:"varint,3,opt,name=insert_id,json=insertId" json:"insert_id,omitempty"`
Rows []*Row `protobuf:"bytes,4,rep,name=rows" json:"rows,omitempty"`
Fields []*Field `protobuf:"bytes,1,rep,name=fields" json:"fields,omitempty"`
RowsAffected uint64 `protobuf:"varint,2,opt,name=rows_affected,json=rowsAffected" json:"rows_affected,omitempty"`
InsertId uint64 `protobuf:"varint,3,opt,name=insert_id,json=insertId" json:"insert_id,omitempty"`
Rows []*Row `protobuf:"bytes,4,rep,name=rows" json:"rows,omitempty"`
Extras *ResultExtras `protobuf:"bytes,5,opt,name=extras" json:"extras,omitempty"`
}
func (m *QueryResult) Reset() { *m = QueryResult{} }
func (m *QueryResult) String() string { return proto.CompactTextString(m) }
func (*QueryResult) ProtoMessage() {}
func (*QueryResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (*QueryResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (m *QueryResult) GetFields() []*Field {
if m != nil {
@ -492,6 +530,13 @@ func (m *QueryResult) GetRows() []*Row {
return nil
}
func (m *QueryResult) GetExtras() *ResultExtras {
if m != nil {
return m.Extras
}
return nil
}
// StreamEvent describes a set of transformations that happened as a
// single transactional unit on a server. It is streamed back by the
// Update Stream calls.
@ -505,7 +550,7 @@ type StreamEvent struct {
func (m *StreamEvent) Reset() { *m = StreamEvent{} }
func (m *StreamEvent) String() string { return proto.CompactTextString(m) }
func (*StreamEvent) ProtoMessage() {}
func (*StreamEvent) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (*StreamEvent) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (m *StreamEvent) GetStatements() []*StreamEvent_Statement {
if m != nil {
@ -536,7 +581,7 @@ type StreamEvent_Statement struct {
func (m *StreamEvent_Statement) Reset() { *m = StreamEvent_Statement{} }
func (m *StreamEvent_Statement) String() string { return proto.CompactTextString(m) }
func (*StreamEvent_Statement) ProtoMessage() {}
func (*StreamEvent_Statement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10, 0} }
func (*StreamEvent_Statement) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} }
func (m *StreamEvent_Statement) GetPrimaryKeyFields() []*Field {
if m != nil {
@ -565,7 +610,7 @@ type ExecuteRequest struct {
func (m *ExecuteRequest) Reset() { *m = ExecuteRequest{} }
func (m *ExecuteRequest) String() string { return proto.CompactTextString(m) }
func (*ExecuteRequest) ProtoMessage() {}
func (*ExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (*ExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (m *ExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -610,7 +655,7 @@ type ExecuteResponse struct {
func (m *ExecuteResponse) Reset() { *m = ExecuteResponse{} }
func (m *ExecuteResponse) String() string { return proto.CompactTextString(m) }
func (*ExecuteResponse) ProtoMessage() {}
func (*ExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (*ExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (m *ExecuteResponse) GetResult() *QueryResult {
if m != nil {
@ -633,7 +678,7 @@ type ExecuteBatchRequest struct {
func (m *ExecuteBatchRequest) Reset() { *m = ExecuteBatchRequest{} }
func (m *ExecuteBatchRequest) String() string { return proto.CompactTextString(m) }
func (*ExecuteBatchRequest) ProtoMessage() {}
func (*ExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (*ExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
func (m *ExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -678,7 +723,7 @@ type ExecuteBatchResponse struct {
func (m *ExecuteBatchResponse) Reset() { *m = ExecuteBatchResponse{} }
func (m *ExecuteBatchResponse) String() string { return proto.CompactTextString(m) }
func (*ExecuteBatchResponse) ProtoMessage() {}
func (*ExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
func (*ExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
func (m *ExecuteBatchResponse) GetResults() []*QueryResult {
if m != nil {
@ -699,7 +744,7 @@ type StreamExecuteRequest struct {
func (m *StreamExecuteRequest) Reset() { *m = StreamExecuteRequest{} }
func (m *StreamExecuteRequest) String() string { return proto.CompactTextString(m) }
func (*StreamExecuteRequest) ProtoMessage() {}
func (*StreamExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
func (*StreamExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
func (m *StreamExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -744,7 +789,7 @@ type StreamExecuteResponse struct {
func (m *StreamExecuteResponse) Reset() { *m = StreamExecuteResponse{} }
func (m *StreamExecuteResponse) String() string { return proto.CompactTextString(m) }
func (*StreamExecuteResponse) ProtoMessage() {}
func (*StreamExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
func (*StreamExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
func (m *StreamExecuteResponse) GetResult() *QueryResult {
if m != nil {
@ -763,7 +808,7 @@ type BeginRequest struct {
func (m *BeginRequest) Reset() { *m = BeginRequest{} }
func (m *BeginRequest) String() string { return proto.CompactTextString(m) }
func (*BeginRequest) ProtoMessage() {}
func (*BeginRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
func (*BeginRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
func (m *BeginRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -794,7 +839,7 @@ type BeginResponse struct {
func (m *BeginResponse) Reset() { *m = BeginResponse{} }
func (m *BeginResponse) String() string { return proto.CompactTextString(m) }
func (*BeginResponse) ProtoMessage() {}
func (*BeginResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
func (*BeginResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
// CommitRequest is the payload to Commit
type CommitRequest struct {
@ -807,7 +852,7 @@ type CommitRequest struct {
func (m *CommitRequest) Reset() { *m = CommitRequest{} }
func (m *CommitRequest) String() string { return proto.CompactTextString(m) }
func (*CommitRequest) ProtoMessage() {}
func (*CommitRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
func (*CommitRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
func (m *CommitRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -837,7 +882,7 @@ type CommitResponse struct {
func (m *CommitResponse) Reset() { *m = CommitResponse{} }
func (m *CommitResponse) String() string { return proto.CompactTextString(m) }
func (*CommitResponse) ProtoMessage() {}
func (*CommitResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
func (*CommitResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
// RollbackRequest is the payload to Rollback
type RollbackRequest struct {
@ -850,7 +895,7 @@ type RollbackRequest struct {
func (m *RollbackRequest) Reset() { *m = RollbackRequest{} }
func (m *RollbackRequest) String() string { return proto.CompactTextString(m) }
func (*RollbackRequest) ProtoMessage() {}
func (*RollbackRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
func (*RollbackRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
func (m *RollbackRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -880,7 +925,7 @@ type RollbackResponse struct {
func (m *RollbackResponse) Reset() { *m = RollbackResponse{} }
func (m *RollbackResponse) String() string { return proto.CompactTextString(m) }
func (*RollbackResponse) ProtoMessage() {}
func (*RollbackResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
func (*RollbackResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
// BeginExecuteRequest is the payload to BeginExecute
type BeginExecuteRequest struct {
@ -894,7 +939,7 @@ type BeginExecuteRequest struct {
func (m *BeginExecuteRequest) Reset() { *m = BeginExecuteRequest{} }
func (m *BeginExecuteRequest) String() string { return proto.CompactTextString(m) }
func (*BeginExecuteRequest) ProtoMessage() {}
func (*BeginExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
func (*BeginExecuteRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
func (m *BeginExecuteRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -945,7 +990,7 @@ type BeginExecuteResponse struct {
func (m *BeginExecuteResponse) Reset() { *m = BeginExecuteResponse{} }
func (m *BeginExecuteResponse) String() string { return proto.CompactTextString(m) }
func (*BeginExecuteResponse) ProtoMessage() {}
func (*BeginExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
func (*BeginExecuteResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} }
func (m *BeginExecuteResponse) GetError() *vtrpc.RPCError {
if m != nil {
@ -974,7 +1019,7 @@ type BeginExecuteBatchRequest struct {
func (m *BeginExecuteBatchRequest) Reset() { *m = BeginExecuteBatchRequest{} }
func (m *BeginExecuteBatchRequest) String() string { return proto.CompactTextString(m) }
func (*BeginExecuteBatchRequest) ProtoMessage() {}
func (*BeginExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} }
func (*BeginExecuteBatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} }
func (m *BeginExecuteBatchRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -1025,7 +1070,7 @@ type BeginExecuteBatchResponse struct {
func (m *BeginExecuteBatchResponse) Reset() { *m = BeginExecuteBatchResponse{} }
func (m *BeginExecuteBatchResponse) String() string { return proto.CompactTextString(m) }
func (*BeginExecuteBatchResponse) ProtoMessage() {}
func (*BeginExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} }
func (*BeginExecuteBatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
func (m *BeginExecuteBatchResponse) GetError() *vtrpc.RPCError {
if m != nil {
@ -1067,7 +1112,7 @@ type SplitQueryRequest struct {
func (m *SplitQueryRequest) Reset() { *m = SplitQueryRequest{} }
func (m *SplitQueryRequest) String() string { return proto.CompactTextString(m) }
func (*SplitQueryRequest) ProtoMessage() {}
func (*SplitQueryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} }
func (*SplitQueryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} }
func (m *SplitQueryRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -1108,7 +1153,7 @@ type QuerySplit struct {
func (m *QuerySplit) Reset() { *m = QuerySplit{} }
func (m *QuerySplit) String() string { return proto.CompactTextString(m) }
func (*QuerySplit) ProtoMessage() {}
func (*QuerySplit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} }
func (*QuerySplit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} }
func (m *QuerySplit) GetQuery() *BoundQuery {
if m != nil {
@ -1126,7 +1171,7 @@ type SplitQueryResponse struct {
func (m *SplitQueryResponse) Reset() { *m = SplitQueryResponse{} }
func (m *SplitQueryResponse) String() string { return proto.CompactTextString(m) }
func (*SplitQueryResponse) ProtoMessage() {}
func (*SplitQueryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} }
func (*SplitQueryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} }
func (m *SplitQueryResponse) GetQueries() []*QuerySplit {
if m != nil {
@ -1142,7 +1187,7 @@ type StreamHealthRequest struct {
func (m *StreamHealthRequest) Reset() { *m = StreamHealthRequest{} }
func (m *StreamHealthRequest) String() string { return proto.CompactTextString(m) }
func (*StreamHealthRequest) ProtoMessage() {}
func (*StreamHealthRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} }
func (*StreamHealthRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} }
// RealtimeStats contains information about the tablet status
type RealtimeStats struct {
@ -1178,7 +1223,7 @@ type RealtimeStats struct {
func (m *RealtimeStats) Reset() { *m = RealtimeStats{} }
func (m *RealtimeStats) String() string { return proto.CompactTextString(m) }
func (*RealtimeStats) ProtoMessage() {}
func (*RealtimeStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} }
func (*RealtimeStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
// StreamHealthResponse is streamed by StreamHealth on a regular basis
type StreamHealthResponse struct {
@ -1202,7 +1247,7 @@ type StreamHealthResponse struct {
func (m *StreamHealthResponse) Reset() { *m = StreamHealthResponse{} }
func (m *StreamHealthResponse) String() string { return proto.CompactTextString(m) }
func (*StreamHealthResponse) ProtoMessage() {}
func (*StreamHealthResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} }
func (*StreamHealthResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
func (m *StreamHealthResponse) GetTarget() *Target {
if m != nil {
@ -1236,7 +1281,7 @@ type UpdateStreamRequest struct {
func (m *UpdateStreamRequest) Reset() { *m = UpdateStreamRequest{} }
func (m *UpdateStreamRequest) String() string { return proto.CompactTextString(m) }
func (*UpdateStreamRequest) ProtoMessage() {}
func (*UpdateStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} }
func (*UpdateStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} }
func (m *UpdateStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID {
if m != nil {
@ -1267,7 +1312,7 @@ type UpdateStreamResponse struct {
func (m *UpdateStreamResponse) Reset() { *m = UpdateStreamResponse{} }
func (m *UpdateStreamResponse) String() string { return proto.CompactTextString(m) }
func (*UpdateStreamResponse) ProtoMessage() {}
func (*UpdateStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} }
func (*UpdateStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} }
func (m *UpdateStreamResponse) GetEvent() *StreamEvent {
if m != nil {
@ -1286,6 +1331,7 @@ func init() {
proto.RegisterType((*ExecuteOptions)(nil), "query.ExecuteOptions")
proto.RegisterType((*Field)(nil), "query.Field")
proto.RegisterType((*Row)(nil), "query.Row")
proto.RegisterType((*ResultExtras)(nil), "query.ResultExtras")
proto.RegisterType((*QueryResult)(nil), "query.QueryResult")
proto.RegisterType((*StreamEvent)(nil), "query.StreamEvent")
proto.RegisterType((*StreamEvent_Statement)(nil), "query.StreamEvent.Statement")
@ -1322,129 +1368,134 @@ func init() {
func init() { proto.RegisterFile("query.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 1982 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0x7b, 0x6f, 0xdb, 0xd6,
0x15, 0x0f, 0xa9, 0x87, 0xa5, 0x23, 0xcb, 0xb9, 0xbe, 0x72, 0x36, 0xcd, 0xcd, 0xd6, 0x8c, 0x6d,
0x5a, 0x2f, 0x0d, 0xb4, 0x4c, 0xf1, 0xbc, 0xa0, 0xeb, 0xb6, 0x48, 0xb6, 0x9c, 0x0a, 0x95, 0x65,
0xe5, 0x8a, 0x32, 0x96, 0x61, 0x00, 0x41, 0x4b, 0x37, 0x32, 0x61, 0x8a, 0xa4, 0xc9, 0x4b, 0x3b,
0xfa, 0xcf, 0xeb, 0xde, 0xef, 0x0e, 0x5b, 0xd7, 0x3d, 0x80, 0x6e, 0xc0, 0x3e, 0xc7, 0x80, 0x61,
0x1f, 0x60, 0xdf, 0x62, 0x18, 0xf6, 0xd7, 0xf6, 0x09, 0x86, 0xe1, 0x5e, 0x5e, 0x52, 0x94, 0xa3,
0x36, 0x69, 0xff, 0x4b, 0xdb, 0xbf, 0x74, 0xef, 0x39, 0xe7, 0x9e, 0xd7, 0xef, 0x9c, 0x43, 0xf2,
0x0a, 0x4a, 0x27, 0x21, 0xf5, 0xa7, 0x35, 0xcf, 0x77, 0x99, 0x8b, 0x73, 0x62, 0xb3, 0xbe, 0xc2,
0x5c, 0xcf, 0x1d, 0x99, 0xcc, 0x8c, 0xc8, 0xeb, 0xa5, 0x53, 0xe6, 0x7b, 0xc3, 0x68, 0xa3, 0x9d,
0x40, 0x5e, 0x37, 0xfd, 0x31, 0x65, 0x78, 0x1d, 0x0a, 0xc7, 0x74, 0x1a, 0x78, 0xe6, 0x90, 0x56,
0x95, 0x6b, 0xca, 0x46, 0x91, 0x24, 0x7b, 0xbc, 0x06, 0xb9, 0xe0, 0xc8, 0xf4, 0x47, 0x55, 0x55,
0x30, 0xa2, 0x0d, 0xfe, 0x32, 0x94, 0x98, 0x79, 0x68, 0x53, 0x66, 0xb0, 0xa9, 0x47, 0xab, 0x99,
0x6b, 0xca, 0xc6, 0x4a, 0x7d, 0xad, 0x96, 0x98, 0xd3, 0x05, 0x53, 0x9f, 0x7a, 0x94, 0x00, 0x4b,
0xd6, 0xda, 0x4d, 0x58, 0x39, 0xd0, 0xef, 0x99, 0x8c, 0x6e, 0x9b, 0xb6, 0x4d, 0xfd, 0xf6, 0x0e,
0x37, 0x1d, 0x06, 0xd4, 0x77, 0xcc, 0x49, 0x62, 0x3a, 0xde, 0x6b, 0xdf, 0x06, 0x68, 0x9d, 0x52,
0x87, 0xe9, 0xee, 0x31, 0x75, 0xf0, 0x55, 0x28, 0x32, 0x6b, 0x42, 0x03, 0x66, 0x4e, 0x3c, 0x21,
0x9a, 0x21, 0x33, 0xc2, 0x7b, 0xb8, 0xb9, 0x0e, 0x05, 0xcf, 0x0d, 0x2c, 0x66, 0xb9, 0x8e, 0xf0,
0xb1, 0x48, 0x92, 0xbd, 0xf6, 0x75, 0xc8, 0x1d, 0x98, 0x76, 0x48, 0xf1, 0xf3, 0x90, 0x15, 0x41,
0x28, 0x22, 0x88, 0x52, 0x2d, 0xca, 0xa3, 0xf0, 0x5d, 0x30, 0xb8, 0xee, 0x53, 0x2e, 0x29, 0x74,
0x2f, 0x93, 0x68, 0xa3, 0x1d, 0xc3, 0x72, 0xd3, 0x72, 0x46, 0x07, 0xa6, 0x6f, 0xf1, 0x00, 0x3f,
0xa4, 0x1a, 0xfc, 0x22, 0xe4, 0xc5, 0x22, 0xa8, 0x66, 0xae, 0x65, 0x36, 0x4a, 0xf5, 0x65, 0x79,
0x50, 0xf8, 0x46, 0x24, 0x4f, 0xfb, 0xbb, 0x02, 0xd0, 0x74, 0x43, 0x67, 0x74, 0x9f, 0x33, 0x31,
0x82, 0x4c, 0x70, 0x62, 0xcb, 0x84, 0xf1, 0x25, 0x7e, 0x03, 0x56, 0x0e, 0x2d, 0x67, 0x64, 0x9c,
0x4a, 0x77, 0x82, 0xaa, 0x2a, 0xd4, 0xbd, 0x28, 0xd5, 0xcd, 0x0e, 0xd7, 0xd2, 0x5e, 0x07, 0x2d,
0x87, 0xf9, 0x53, 0x52, 0x3e, 0x4c, 0xd3, 0xd6, 0x07, 0x80, 0x1f, 0x17, 0xe2, 0x46, 0x8f, 0xe9,
0x34, 0x36, 0x7a, 0x4c, 0xa7, 0xf8, 0x0b, 0xe9, 0x88, 0x4a, 0xf5, 0x4a, 0x6c, 0x2b, 0x75, 0x56,
0x86, 0xf9, 0xaa, 0x7a, 0x47, 0xd1, 0xee, 0xc2, 0x4a, 0xeb, 0x11, 0x1d, 0x86, 0x8c, 0xee, 0x7b,
0x1c, 0x82, 0x00, 0xd7, 0xa0, 0x42, 0x1f, 0x0d, 0xed, 0x70, 0x44, 0x8d, 0x87, 0x16, 0xb5, 0x47,
0x06, 0xc7, 0x3d, 0x10, 0x26, 0x0a, 0x64, 0x55, 0xb2, 0x76, 0x39, 0xa7, 0xcb, 0x19, 0xda, 0x6b,
0x90, 0x13, 0x3b, 0x8c, 0x21, 0x9b, 0x2a, 0x19, 0xb1, 0x4e, 0x00, 0x50, 0xdf, 0x03, 0x00, 0xed,
0x2b, 0x90, 0x21, 0xee, 0x19, 0xae, 0xc2, 0x92, 0x4d, 0x9d, 0x31, 0x3b, 0xe2, 0x86, 0x32, 0x1b,
0x98, 0xc4, 0x5b, 0xfc, 0xa9, 0x04, 0x8b, 0x08, 0xa2, 0x38, 0xfb, 0x6f, 0x2b, 0x50, 0x12, 0xb9,
0x23, 0x34, 0x08, 0x6d, 0xc6, 0x31, 0x13, 0xee, 0x46, 0x0a, 0x66, 0x98, 0x09, 0xdf, 0x88, 0xe4,
0xe1, 0x17, 0xa0, 0xec, 0xbb, 0x67, 0x81, 0x61, 0x3e, 0x7c, 0x48, 0x87, 0x8c, 0x46, 0xa5, 0x99,
0x25, 0xcb, 0x9c, 0xd8, 0x90, 0x34, 0xfc, 0x1c, 0x14, 0x2d, 0x27, 0xa0, 0x3e, 0x33, 0xac, 0x91,
0x28, 0xd1, 0x2c, 0x29, 0x44, 0x84, 0xf6, 0x08, 0x7f, 0x0e, 0xb2, 0x5c, 0xb8, 0x9a, 0x15, 0x56,
0x40, 0x5a, 0x21, 0xee, 0x19, 0x11, 0x74, 0xed, 0xcf, 0x19, 0x28, 0xf5, 0x99, 0x4f, 0xcd, 0x89,
0xe8, 0x13, 0xfc, 0x1a, 0x40, 0xc0, 0x4c, 0x46, 0x27, 0xd4, 0x61, 0xb1, 0x6f, 0x57, 0xe5, 0xa9,
0x94, 0x5c, 0xad, 0x1f, 0x0b, 0x91, 0x94, 0x3c, 0xae, 0x43, 0x89, 0x72, 0xb6, 0xc1, 0x78, 0xbf,
0x49, 0x4c, 0x57, 0xe5, 0xf1, 0x59, 0x23, 0x12, 0xa0, 0xc9, 0x7a, 0xfd, 0x5d, 0x15, 0x8a, 0x89,
0x36, 0xdc, 0x80, 0xc2, 0xd0, 0x64, 0x74, 0xec, 0xfa, 0x53, 0xd9, 0x06, 0xd7, 0xdf, 0xcf, 0x7a,
0x6d, 0x5b, 0x0a, 0x93, 0xe4, 0x18, 0xfe, 0x2c, 0x44, 0xf3, 0x42, 0x54, 0x82, 0x6c, 0xe6, 0xa2,
0xa0, 0xf0, 0x0a, 0xc0, 0xaf, 0x02, 0xf6, 0x7c, 0x6b, 0x62, 0xfa, 0x53, 0xe3, 0x98, 0x4e, 0x0d,
0x89, 0x42, 0x66, 0x01, 0x0a, 0x48, 0xca, 0xbd, 0x41, 0xa7, 0xbb, 0x11, 0x1e, 0x77, 0xe6, 0xcf,
0x4a, 0xa4, 0x1f, 0xcf, 0x6d, 0xea, 0xa4, 0x68, 0xc2, 0x20, 0x6e, 0xb7, 0x9c, 0x28, 0x0a, 0xbe,
0xd4, 0x5e, 0x86, 0x42, 0xec, 0x3c, 0x2e, 0x42, 0xae, 0xe5, 0xfb, 0xae, 0x8f, 0x2e, 0xe1, 0x25,
0xc8, 0xec, 0xec, 0x75, 0x90, 0x22, 0x16, 0x3b, 0x1d, 0xa4, 0x6a, 0x7f, 0x53, 0x93, 0xa2, 0x27,
0xf4, 0x24, 0xa4, 0x01, 0xc3, 0xdf, 0x80, 0x0a, 0x15, 0xf0, 0x5b, 0xa7, 0xd4, 0x18, 0x8a, 0x41,
0xc8, 0xc1, 0x57, 0x44, 0xbe, 0x2f, 0xd7, 0xa2, 0x11, 0x1d, 0x0f, 0x48, 0xb2, 0x9a, 0xc8, 0x4a,
0xd2, 0x08, 0xb7, 0xa0, 0x62, 0x4d, 0x26, 0x74, 0x64, 0x99, 0x2c, 0xad, 0x20, 0x02, 0xec, 0x4a,
0x3c, 0x3f, 0xe6, 0xe6, 0x2c, 0x59, 0x4d, 0x4e, 0x24, 0x6a, 0xae, 0x43, 0x9e, 0x89, 0xf9, 0x2f,
0xea, 0xae, 0x54, 0x2f, 0xc7, 0x1d, 0x23, 0x88, 0x44, 0x32, 0xf1, 0xcb, 0x10, 0x3d, 0x4c, 0xaa,
0xd9, 0xb9, 0x82, 0x98, 0x0d, 0x14, 0x12, 0xf1, 0xf1, 0x75, 0x58, 0x61, 0xbe, 0xe9, 0x04, 0xe6,
0x90, 0x37, 0x37, 0xf7, 0x28, 0x27, 0xa6, 0x74, 0x39, 0x45, 0x6d, 0x8f, 0xf0, 0x17, 0x61, 0xc9,
0x8d, 0xda, 0xbf, 0x9a, 0x9f, 0xf3, 0x78, 0x7e, 0x36, 0x90, 0x58, 0x4a, 0xfb, 0x1a, 0x5c, 0x4e,
0x32, 0x18, 0x78, 0xae, 0x13, 0x50, 0x7c, 0x03, 0xf2, 0xbe, 0x68, 0x45, 0x99, 0x35, 0x2c, 0x55,
0xa4, 0x9a, 0x94, 0x48, 0x09, 0xed, 0xbf, 0x2a, 0x54, 0xe4, 0xf9, 0xa6, 0xc9, 0x86, 0x47, 0xcf,
0x28, 0x0c, 0xaf, 0xc0, 0x12, 0xa7, 0x5b, 0x49, 0xc9, 0x2e, 0x00, 0x22, 0x96, 0xe0, 0x50, 0x98,
0x81, 0x91, 0xca, 0xbb, 0x80, 0xa2, 0x40, 0xca, 0x66, 0xa0, 0xcf, 0x88, 0x0b, 0x10, 0xcb, 0x3f,
0x01, 0xb1, 0xa5, 0xa7, 0x42, 0x6c, 0x07, 0xd6, 0xe6, 0x33, 0x2e, 0x61, 0xbb, 0x09, 0x4b, 0x11,
0x28, 0xf1, 0x70, 0x5a, 0x84, 0x5b, 0x2c, 0xa2, 0xfd, 0x49, 0x85, 0x35, 0x39, 0x37, 0x3e, 0x1e,
0x0d, 0x94, 0xca, 0x73, 0xee, 0xa9, 0xf2, 0xbc, 0x0d, 0x57, 0x2e, 0x24, 0xe8, 0x43, 0xf4, 0xc7,
0x5f, 0x15, 0x58, 0x6e, 0xd2, 0xb1, 0xe5, 0x3c, 0x9b, 0xe9, 0xd5, 0xb6, 0xa0, 0x2c, 0xdd, 0x97,
0xc1, 0x3f, 0x5e, 0xd5, 0xca, 0x82, 0xaa, 0xd6, 0xfe, 0xa9, 0x40, 0x79, 0xdb, 0x9d, 0x4c, 0x2c,
0xf6, 0x8c, 0xd6, 0xd5, 0xe3, 0x71, 0x66, 0x17, 0xc5, 0x89, 0x60, 0x25, 0x0e, 0x33, 0x4a, 0x90,
0xf6, 0x2f, 0x05, 0x2e, 0x13, 0xd7, 0xb6, 0x0f, 0xcd, 0xe1, 0xf1, 0x47, 0x3b, 0x76, 0x0c, 0x68,
0x16, 0xa8, 0x8c, 0xfe, 0x5d, 0x15, 0x2a, 0xa2, 0x60, 0x3e, 0x99, 0x2a, 0x8b, 0xa7, 0xca, 0x5b,
0x0a, 0xac, 0xcd, 0x27, 0x28, 0x69, 0xac, 0x1c, 0xe5, 0x2f, 0x3a, 0x17, 0x72, 0x42, 0x7a, 0xdb,
0xe2, 0xfd, 0x87, 0x44, 0xdc, 0xd4, 0xf0, 0x51, 0x9f, 0x34, 0x7c, 0x16, 0xe0, 0x98, 0x59, 0x84,
0xe3, 0x3f, 0x54, 0xa8, 0xa6, 0x5d, 0xfa, 0xe4, 0x41, 0x3e, 0xff, 0x20, 0xff, 0xc0, 0xef, 0x54,
0xef, 0x28, 0xf0, 0x99, 0x05, 0x09, 0xfd, 0x60, 0x40, 0xa7, 0x1e, 0xe7, 0xea, 0x13, 0x1f, 0xe7,
0x4f, 0x0b, 0xf5, 0x9b, 0x59, 0x58, 0xed, 0x7b, 0xb6, 0xc5, 0xa4, 0x92, 0x8f, 0x76, 0x73, 0x7e,
0x1e, 0x96, 0x03, 0x1e, 0xac, 0x31, 0x74, 0xed, 0x70, 0xc2, 0xd1, 0xcd, 0x6c, 0x14, 0x49, 0x49,
0xd0, 0xb6, 0x05, 0x09, 0x3f, 0x0f, 0xa5, 0x58, 0x24, 0x74, 0x98, 0x7c, 0x43, 0x03, 0x29, 0x11,
0x3a, 0x0c, 0x6f, 0xc2, 0xa7, 0x9d, 0x70, 0x62, 0x88, 0x6f, 0x4d, 0x8f, 0xfa, 0x86, 0xd0, 0x6c,
0x78, 0xa6, 0xcf, 0xaa, 0x05, 0x21, 0x5c, 0x71, 0xc2, 0x09, 0x71, 0xcf, 0x82, 0x1e, 0xf5, 0x85,
0xf1, 0x9e, 0xe9, 0x33, 0x7c, 0x17, 0x8a, 0xa6, 0x3d, 0x76, 0x7d, 0x8b, 0x1d, 0x4d, 0xaa, 0x45,
0xf1, 0xb1, 0xa6, 0xc5, 0x1f, 0x6b, 0x17, 0xd3, 0x5f, 0x6b, 0xc4, 0x92, 0x64, 0x76, 0x08, 0xbf,
0x02, 0x38, 0x0c, 0xa8, 0x11, 0x39, 0x17, 0x19, 0x3d, 0xad, 0x57, 0x41, 0xd4, 0xe7, 0xe5, 0x30,
0xa0, 0x33, 0x35, 0x07, 0x75, 0xed, 0x26, 0x14, 0x13, 0x25, 0x18, 0xc1, 0x72, 0xeb, 0xfe, 0xa0,
0xd1, 0x31, 0xfa, 0xbd, 0x4e, 0x5b, 0xef, 0xa3, 0x4b, 0xb8, 0x0c, 0xc5, 0xdd, 0x41, 0xa7, 0x63,
0xf4, 0xb7, 0x1b, 0x5d, 0xa4, 0x68, 0x04, 0x40, 0x1c, 0x14, 0x2a, 0x66, 0xd9, 0x54, 0x9e, 0x90,
0xcd, 0xe7, 0xa0, 0xe8, 0xbb, 0x67, 0x32, 0x51, 0xaa, 0x88, 0xbd, 0xe0, 0xbb, 0x67, 0x22, 0x4d,
0x5a, 0x03, 0x70, 0x3a, 0x30, 0x59, 0xea, 0xa9, 0x6e, 0x54, 0xe6, 0xba, 0x71, 0x66, 0x3f, 0xe9,
0x46, 0xed, 0x0a, 0x54, 0xa2, 0xf7, 0xad, 0xd7, 0xa9, 0x69, 0xb3, 0x78, 0x00, 0x69, 0x7f, 0x51,
0xa1, 0x4c, 0x38, 0xc5, 0x9a, 0x50, 0xfe, 0x71, 0x1b, 0x70, 0x58, 0x8f, 0x84, 0x88, 0x31, 0xeb,
0xa3, 0x22, 0x29, 0x45, 0x34, 0xd1, 0x43, 0xb8, 0x0e, 0x57, 0x02, 0x3a, 0x74, 0x9d, 0x51, 0x60,
0x1c, 0xd2, 0x23, 0xcb, 0x19, 0x19, 0x13, 0x33, 0x60, 0xd4, 0x17, 0x7e, 0x97, 0x49, 0x45, 0x32,
0x9b, 0x82, 0xb7, 0x27, 0x58, 0xf8, 0x16, 0xac, 0x1d, 0x5a, 0x8e, 0xed, 0x8e, 0x0d, 0xcf, 0x36,
0xa7, 0xd4, 0x0f, 0x64, 0xa8, 0xbc, 0x16, 0x73, 0x04, 0x47, 0xbc, 0x5e, 0xc4, 0x8a, 0x6a, 0xe3,
0x5b, 0x70, 0x63, 0xa1, 0x15, 0xe3, 0xa1, 0x65, 0x33, 0xea, 0xd3, 0x91, 0xe1, 0x53, 0xcf, 0xb6,
0x86, 0xa6, 0x98, 0x2d, 0xd1, 0x33, 0xf4, 0xa5, 0x05, 0xa6, 0x77, 0xa5, 0x38, 0x99, 0x49, 0xf3,
0x6c, 0x0f, 0xbd, 0xd0, 0x08, 0x03, 0x73, 0x4c, 0xc5, 0x58, 0x52, 0x48, 0x61, 0xe8, 0x85, 0x03,
0xbe, 0xe7, 0x9f, 0xcc, 0x27, 0x5e, 0x34, 0x8d, 0x14, 0xc2, 0x97, 0xda, 0xbf, 0x95, 0xf8, 0x75,
0x3e, 0xce, 0x5e, 0x32, 0x6d, 0xe2, 0x9e, 0x52, 0xde, 0xaf, 0xa7, 0xaa, 0xb0, 0x14, 0x50, 0xff,
0xd4, 0x72, 0xc6, 0x22, 0x45, 0x05, 0x12, 0x6f, 0x71, 0x1f, 0x5e, 0x92, 0x97, 0x91, 0xf4, 0x11,
0xa3, 0xbe, 0x63, 0xda, 0xf6, 0x94, 0xc7, 0x65, 0xfa, 0xd4, 0x61, 0x74, 0x64, 0xcc, 0xae, 0x0d,
0xa3, 0x89, 0xf3, 0x42, 0x24, 0xdd, 0x4a, 0x84, 0x49, 0x22, 0xab, 0x27, 0x17, 0x8a, 0x5f, 0x85,
0x15, 0x5f, 0x62, 0x6a, 0x04, 0x1c, 0x54, 0xd9, 0xcb, 0x6b, 0xf1, 0x4d, 0x41, 0x1a, 0x70, 0x52,
0xf6, 0xd3, 0x5b, 0xed, 0x7f, 0x0a, 0x54, 0x06, 0xde, 0xc8, 0x64, 0x34, 0x8a, 0xf8, 0x19, 0x1d,
0x63, 0xe9, 0xeb, 0xd3, 0xec, 0xfc, 0xf5, 0xe9, 0xfc, 0x75, 0x6c, 0xee, 0xc2, 0x75, 0xac, 0x76,
0x17, 0xd6, 0xe6, 0xe3, 0x97, 0x58, 0x6f, 0x40, 0x4e, 0xdc, 0x1e, 0x5d, 0xf8, 0x2e, 0x49, 0x5d,
0x0f, 0x91, 0x48, 0xe0, 0xc6, 0x31, 0x64, 0x77, 0x6d, 0x73, 0x8c, 0x0b, 0x90, 0xed, 0xee, 0x77,
0x5b, 0xe8, 0x12, 0xbe, 0x0c, 0xd0, 0xee, 0xb7, 0xbb, 0x7a, 0xeb, 0x1e, 0x69, 0x74, 0xd0, 0xb9,
0x1a, 0x11, 0x06, 0xdd, 0x7e, 0xfb, 0x5e, 0xb7, 0xb5, 0x83, 0xce, 0xb3, 0x78, 0x19, 0x96, 0xda,
0xfd, 0xdd, 0xce, 0x7e, 0x43, 0x47, 0xe7, 0x05, 0x5c, 0x86, 0x42, 0xbb, 0x7f, 0x7f, 0xb0, 0xaf,
0x73, 0x26, 0xc2, 0x25, 0xc8, 0xb7, 0xfb, 0x7a, 0xeb, 0x9b, 0x3a, 0x3a, 0xbf, 0x16, 0xf1, 0x9a,
0xed, 0x6e, 0x83, 0x3c, 0x40, 0xe7, 0x77, 0x6f, 0xfc, 0x47, 0x85, 0xac, 0x3e, 0xf5, 0x28, 0x9f,
0x43, 0x5d, 0x3e, 0x87, 0xf4, 0x07, 0x3d, 0x6e, 0xb2, 0x08, 0xd9, 0x76, 0x57, 0xbf, 0x83, 0xbe,
0xa3, 0x62, 0x80, 0xdc, 0x40, 0xac, 0xdf, 0xcc, 0xf3, 0x75, 0xbb, 0xab, 0x7f, 0x69, 0x0b, 0x7d,
0x57, 0xe5, 0x6a, 0x07, 0xd1, 0xe6, 0x7b, 0x31, 0xa3, 0xbe, 0x89, 0xbe, 0x9f, 0x30, 0xea, 0x9b,
0xe8, 0x07, 0x31, 0xe3, 0x76, 0x1d, 0xfd, 0x30, 0x61, 0xdc, 0xae, 0xa3, 0x1f, 0xc5, 0x8c, 0xad,
0x4d, 0xf4, 0xe3, 0x84, 0xb1, 0xb5, 0x89, 0x7e, 0x92, 0xe7, 0xb1, 0x88, 0x48, 0x6e, 0xd7, 0xd1,
0x4f, 0x0b, 0xc9, 0x6e, 0x6b, 0x13, 0xfd, 0xac, 0x80, 0x57, 0xa0, 0xa8, 0xb7, 0xf7, 0x5a, 0x7d,
0xbd, 0xb1, 0xd7, 0x43, 0x3f, 0x47, 0xdc, 0xcd, 0x9d, 0x86, 0xde, 0x42, 0xbf, 0x10, 0x4b, 0xce,
0x42, 0xbf, 0x44, 0x3c, 0x46, 0x4e, 0x15, 0xdb, 0xb7, 0x04, 0xe7, 0x41, 0xab, 0x41, 0xd0, 0xaf,
0xf2, 0xb8, 0x04, 0x4b, 0x3b, 0xad, 0xed, 0xf6, 0x5e, 0xa3, 0x83, 0xb0, 0x38, 0xc1, 0xb3, 0xf2,
0xeb, 0x5b, 0x7c, 0xd9, 0xec, 0xec, 0x37, 0xd1, 0x6f, 0x7a, 0xdc, 0xe0, 0x41, 0x83, 0x6c, 0xbf,
0xde, 0x20, 0xe8, 0xed, 0x5b, 0xdc, 0xe0, 0x41, 0x83, 0xc8, 0x7c, 0xfd, 0xb6, 0xc7, 0x05, 0x05,
0xeb, 0x9d, 0x5b, 0xdc, 0x69, 0x49, 0xff, 0x5d, 0x0f, 0x17, 0x20, 0xd3, 0x6c, 0xeb, 0xe8, 0xf7,
0xc2, 0x5a, 0xab, 0x3b, 0xd8, 0x43, 0x7f, 0x40, 0x9c, 0xd8, 0x6f, 0xe9, 0xe8, 0x8f, 0x9c, 0x98,
0xd3, 0x07, 0xbd, 0x4e, 0x0b, 0x5d, 0x6d, 0xae, 0x43, 0x75, 0xe8, 0x4e, 0x6a, 0x53, 0x37, 0x64,
0xe1, 0x21, 0xad, 0x9d, 0x5a, 0x8c, 0x06, 0x41, 0xf4, 0xc7, 0xc4, 0x61, 0x5e, 0xfc, 0xdc, 0xfe,
0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x85, 0xe6, 0x02, 0xd7, 0xd2, 0x18, 0x00, 0x00,
// 2056 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x59, 0x5b, 0x6f, 0x1b, 0xc7,
0x15, 0xf6, 0x2e, 0xef, 0x87, 0xa2, 0x3c, 0x1a, 0xca, 0x2d, 0xab, 0xb8, 0x8d, 0xbb, 0x89, 0x13,
0xd5, 0x36, 0x58, 0x97, 0x56, 0x5d, 0x23, 0x4d, 0x5b, 0x93, 0x12, 0xe5, 0x10, 0xa1, 0x68, 0x7a,
0xb8, 0x14, 0xea, 0x22, 0xc0, 0x62, 0x45, 0x8e, 0xa4, 0x85, 0x96, 0xbb, 0xab, 0xdd, 0x59, 0xc9,
0x7c, 0x53, 0xd3, 0xfb, 0x3d, 0x45, 0x2f, 0xe9, 0x05, 0x48, 0x0b, 0xf4, 0x27, 0xf4, 0xb9, 0x40,
0xd1, 0x1f, 0xd0, 0x7f, 0x51, 0x14, 0x7d, 0x6a, 0x7f, 0x41, 0x51, 0xcc, 0xec, 0xec, 0x72, 0x29,
0xd3, 0xb1, 0x93, 0x37, 0xa7, 0x79, 0xd2, 0xcc, 0x39, 0xdf, 0x9c, 0xfb, 0x39, 0xc3, 0x1d, 0x41,
0xf9, 0x38, 0xa4, 0xfe, 0xb4, 0xee, 0xf9, 0x2e, 0x73, 0x71, 0x4e, 0x6c, 0xd6, 0x96, 0x99, 0xeb,
0xb9, 0x63, 0x93, 0x99, 0x11, 0x79, 0xad, 0x7c, 0xc2, 0x7c, 0x6f, 0x14, 0x6d, 0xb4, 0x63, 0xc8,
0xeb, 0xa6, 0x7f, 0x40, 0x19, 0x5e, 0x83, 0xe2, 0x11, 0x9d, 0x06, 0x9e, 0x39, 0xa2, 0x35, 0xe5,
0x8a, 0xb2, 0x5e, 0x22, 0xc9, 0x1e, 0xaf, 0x42, 0x2e, 0x38, 0x34, 0xfd, 0x71, 0x4d, 0x15, 0x8c,
0x68, 0x83, 0xbf, 0x08, 0x65, 0x66, 0xee, 0xd9, 0x94, 0x19, 0x6c, 0xea, 0xd1, 0x5a, 0xe6, 0x8a,
0xb2, 0xbe, 0xdc, 0x58, 0xad, 0x27, 0xea, 0x74, 0xc1, 0xd4, 0xa7, 0x1e, 0x25, 0xc0, 0x92, 0xb5,
0x76, 0x03, 0x96, 0x77, 0xf5, 0x7b, 0x26, 0xa3, 0x9b, 0xa6, 0x6d, 0x53, 0xbf, 0xb3, 0xc5, 0x55,
0x87, 0x01, 0xf5, 0x1d, 0x73, 0x92, 0xa8, 0x8e, 0xf7, 0xda, 0x5b, 0x00, 0xed, 0x13, 0xea, 0x30,
0xdd, 0x3d, 0xa2, 0x0e, 0xbe, 0x0c, 0x25, 0x66, 0x4d, 0x68, 0xc0, 0xcc, 0x89, 0x27, 0xa0, 0x19,
0x32, 0x23, 0x3c, 0xc1, 0xcc, 0x35, 0x28, 0x7a, 0x6e, 0x60, 0x31, 0xcb, 0x75, 0x84, 0x8d, 0x25,
0x92, 0xec, 0xb5, 0xaf, 0x42, 0x6e, 0xd7, 0xb4, 0x43, 0x8a, 0x5f, 0x84, 0xac, 0x70, 0x42, 0x11,
0x4e, 0x94, 0xeb, 0x51, 0x1c, 0x85, 0xed, 0x82, 0xc1, 0x65, 0x9f, 0x70, 0xa4, 0x90, 0xbd, 0x44,
0xa2, 0x8d, 0x76, 0x04, 0x4b, 0x2d, 0xcb, 0x19, 0xef, 0x9a, 0xbe, 0xc5, 0x1d, 0xfc, 0x90, 0x62,
0xf0, 0xcb, 0x90, 0x17, 0x8b, 0xa0, 0x96, 0xb9, 0x92, 0x59, 0x2f, 0x37, 0x96, 0xe4, 0x41, 0x61,
0x1b, 0x91, 0x3c, 0xed, 0x6f, 0x0a, 0x40, 0xcb, 0x0d, 0x9d, 0xf1, 0x03, 0xce, 0xc4, 0x08, 0x32,
0xc1, 0xb1, 0x2d, 0x03, 0xc6, 0x97, 0xf8, 0x4d, 0x58, 0xde, 0xb3, 0x9c, 0xb1, 0x71, 0x22, 0xcd,
0x09, 0x6a, 0xaa, 0x10, 0xf7, 0xb2, 0x14, 0x37, 0x3b, 0x5c, 0x4f, 0x5b, 0x1d, 0xb4, 0x1d, 0xe6,
0x4f, 0x49, 0x65, 0x2f, 0x4d, 0x5b, 0x1b, 0x02, 0x7e, 0x1c, 0xc4, 0x95, 0x1e, 0xd1, 0x69, 0xac,
0xf4, 0x88, 0x4e, 0xf1, 0xe7, 0xd2, 0x1e, 0x95, 0x1b, 0xd5, 0x58, 0x57, 0xea, 0xac, 0x74, 0xf3,
0x35, 0xf5, 0x8e, 0xa2, 0xfd, 0x59, 0x81, 0xe5, 0xf6, 0x23, 0x3a, 0x0a, 0x19, 0xbd, 0xef, 0xf1,
0x1c, 0x04, 0xb8, 0x0e, 0x55, 0xfa, 0x68, 0x64, 0x87, 0x63, 0x6a, 0xec, 0x5b, 0xd4, 0x1e, 0x1b,
0x3c, 0xf1, 0x81, 0xd0, 0x51, 0x24, 0x2b, 0x92, 0xb5, 0xcd, 0x39, 0x3d, 0xce, 0xe0, 0x78, 0xcb,
0x89, 0xf0, 0x94, 0x97, 0x86, 0xc1, 0x78, 0x6d, 0x08, 0xfd, 0x45, 0xb2, 0x22, 0x59, 0xa9, 0xa2,
0x69, 0x42, 0x75, 0xe4, 0x4e, 0x3c, 0xd3, 0x9f, 0xc7, 0x67, 0x84, 0xbd, 0x2b, 0xd2, 0xde, 0x19,
0x9e, 0xac, 0x48, 0xf4, 0x8c, 0xa4, 0xbd, 0x0e, 0x39, 0x61, 0x00, 0xc6, 0x90, 0x4d, 0x95, 0xa9,
0x58, 0x27, 0x49, 0x57, 0x9f, 0x90, 0x74, 0xed, 0x4b, 0x90, 0x21, 0xee, 0x29, 0xae, 0x41, 0xc1,
0xa6, 0xce, 0x01, 0x3b, 0xe4, 0xbe, 0x65, 0xd6, 0x31, 0x89, 0xb7, 0xf8, 0x13, 0x49, 0xfe, 0xa3,
0xb2, 0x88, 0x33, 0xfe, 0x16, 0x2c, 0x11, 0x1a, 0x84, 0x36, 0x6b, 0x3f, 0x62, 0xbe, 0x19, 0xe0,
0x06, 0x94, 0xd3, 0x1e, 0x28, 0x4f, 0xf2, 0x00, 0xe8, 0xcc, 0xfb, 0x1a, 0x14, 0xf6, 0x7d, 0x1a,
0x1c, 0x52, 0x5f, 0x46, 0x28, 0xde, 0xf2, 0x7a, 0x2a, 0x8b, 0x6a, 0x88, 0x74, 0xf0, 0x2a, 0x14,
0xf1, 0x8f, 0xcc, 0x9b, 0x55, 0xa1, 0xf0, 0x9c, 0x48, 0x1e, 0x7e, 0x09, 0x2a, 0xbe, 0x7b, 0x1a,
0x18, 0xe6, 0xfe, 0x3e, 0x1d, 0x31, 0x1a, 0x35, 0x5b, 0x96, 0x2c, 0x71, 0x62, 0x53, 0xd2, 0xf0,
0x0b, 0x50, 0xb2, 0x9c, 0x80, 0xfa, 0xcc, 0xb0, 0xc6, 0x22, 0xd0, 0x59, 0x52, 0x8c, 0x08, 0x9d,
0x31, 0xfe, 0x0c, 0x64, 0x39, 0xb8, 0x96, 0x15, 0x5a, 0x40, 0x6a, 0x21, 0xee, 0x29, 0x11, 0x74,
0x7c, 0x1d, 0xf2, 0x54, 0xf8, 0x5b, 0xcb, 0xcd, 0x95, 0x54, 0x3a, 0x14, 0x44, 0x42, 0xb4, 0x3f,
0x66, 0xa0, 0x3c, 0x60, 0x3e, 0x35, 0x27, 0xc2, 0x7f, 0xfc, 0x3a, 0x40, 0xc0, 0x4c, 0x46, 0x27,
0xd4, 0x61, 0xb1, 0x23, 0x97, 0xa5, 0x80, 0x14, 0xae, 0x3e, 0x88, 0x41, 0x24, 0x85, 0x3f, 0x1f,
0x60, 0xf5, 0x19, 0x02, 0xbc, 0xf6, 0x9e, 0x0a, 0xa5, 0x44, 0x1a, 0x6e, 0x42, 0x71, 0x64, 0x32,
0x7a, 0xe0, 0xfa, 0x53, 0x39, 0x05, 0xae, 0xbe, 0x9f, 0xf6, 0xfa, 0xa6, 0x04, 0x93, 0xe4, 0x18,
0xfe, 0x34, 0x44, 0xe3, 0x52, 0xf4, 0x81, 0x9c, 0x65, 0x25, 0x41, 0xe1, 0xf5, 0x8f, 0x5f, 0x03,
0xec, 0xf9, 0xd6, 0xc4, 0xf4, 0xa7, 0xc6, 0x11, 0x9d, 0x1a, 0x32, 0x65, 0x99, 0x05, 0x29, 0x43,
0x12, 0xf7, 0x26, 0x9d, 0x6e, 0x47, 0xc9, 0xbb, 0x33, 0x7f, 0x56, 0x16, 0xdd, 0xe3, 0x89, 0x48,
0x9d, 0x14, 0x33, 0x28, 0x88, 0xa7, 0x4d, 0x4e, 0xd4, 0x27, 0x5f, 0x6a, 0xaf, 0x42, 0x31, 0x36,
0x1e, 0x97, 0x20, 0xd7, 0xf6, 0x7d, 0xd7, 0x47, 0x17, 0x70, 0x01, 0x32, 0x5b, 0x3b, 0x5d, 0xa4,
0x88, 0xc5, 0x56, 0x17, 0xa9, 0xda, 0x5f, 0xd5, 0xa4, 0xe5, 0x09, 0x3d, 0x0e, 0x69, 0xc0, 0xf0,
0xd7, 0xa0, 0x4a, 0x45, 0xad, 0x58, 0x27, 0xd4, 0x18, 0x89, 0x7b, 0x80, 0x57, 0x4a, 0x54, 0xd0,
0x17, 0xeb, 0xd1, 0x0d, 0x15, 0xdf, 0x0f, 0x64, 0x25, 0xc1, 0x4a, 0xd2, 0x18, 0xb7, 0xa1, 0x6a,
0x4d, 0x26, 0x74, 0x6c, 0x99, 0x2c, 0x2d, 0x20, 0x4a, 0xd8, 0xa5, 0x78, 0x7c, 0xce, 0x5d, 0x33,
0x64, 0x25, 0x39, 0x91, 0x88, 0xb9, 0x0a, 0x79, 0x26, 0xae, 0x3f, 0x39, 0x0d, 0x2a, 0x71, 0xf3,
0x0a, 0x22, 0x91, 0x4c, 0xfc, 0x2a, 0x44, 0x77, 0x69, 0x2d, 0x3b, 0x57, 0x10, 0xb3, 0x79, 0x4a,
0x22, 0x3e, 0xbe, 0x0a, 0xcb, 0xcc, 0x37, 0x9d, 0xc0, 0x1c, 0xf1, 0xd1, 0xc6, 0x2d, 0xca, 0x89,
0x4b, 0xaa, 0x92, 0xa2, 0x76, 0xc6, 0xf8, 0xf3, 0x50, 0x70, 0xa3, 0xe1, 0x57, 0xcb, 0xcf, 0x59,
0x3c, 0x3f, 0x19, 0x49, 0x8c, 0xd2, 0xbe, 0x02, 0x17, 0x93, 0x08, 0x06, 0x9e, 0xeb, 0x04, 0x14,
0x5f, 0x83, 0xbc, 0x2f, 0x1a, 0x42, 0x46, 0x0d, 0x4b, 0x11, 0xa9, 0x8e, 0x26, 0x12, 0xa1, 0xfd,
0x47, 0x85, 0xaa, 0x3c, 0xdf, 0x32, 0xd9, 0xe8, 0xf0, 0x39, 0x4d, 0xc3, 0x75, 0x28, 0x70, 0xba,
0x95, 0x94, 0xec, 0x82, 0x44, 0xc4, 0x08, 0x9e, 0x0a, 0x33, 0x30, 0x52, 0x71, 0x17, 0xa9, 0x28,
0x92, 0x8a, 0x19, 0xe8, 0x33, 0xe2, 0x82, 0x8c, 0xe5, 0x9f, 0x92, 0xb1, 0xc2, 0x33, 0x65, 0x6c,
0x0b, 0x56, 0xe7, 0x23, 0x2e, 0xd3, 0x76, 0x03, 0x0a, 0x51, 0x52, 0xe2, 0xe1, 0xb4, 0x28, 0x6f,
0x31, 0x44, 0xfb, 0x83, 0x0a, 0xab, 0x72, 0x6e, 0xfc, 0x7f, 0x34, 0x50, 0x2a, 0xce, 0xb9, 0x67,
0x8a, 0xf3, 0x26, 0x5c, 0x3a, 0x17, 0xa0, 0x0f, 0xd1, 0x1f, 0x7f, 0x51, 0x60, 0xa9, 0x45, 0x0f,
0x2c, 0xe7, 0xf9, 0x0c, 0xaf, 0x76, 0x1b, 0x2a, 0xd2, 0x7c, 0xe9, 0xfc, 0xe3, 0x55, 0xad, 0x2c,
0xa8, 0x6a, 0xed, 0x1f, 0x0a, 0x54, 0x36, 0xdd, 0xc9, 0xc4, 0x62, 0xcf, 0x69, 0x5d, 0x3d, 0xee,
0x67, 0x76, 0x91, 0x9f, 0x08, 0x96, 0x63, 0x37, 0xa3, 0x00, 0x69, 0xff, 0x54, 0xe0, 0x22, 0x71,
0x6d, 0x7b, 0xcf, 0x1c, 0x1d, 0x7d, 0xb4, 0x7d, 0xc7, 0x80, 0x66, 0x8e, 0x4a, 0xef, 0xdf, 0x53,
0xa1, 0x2a, 0x0a, 0xe6, 0xe3, 0xa9, 0xb2, 0x78, 0xaa, 0xbc, 0xa3, 0xc0, 0xea, 0x7c, 0x80, 0x92,
0xc6, 0xca, 0x51, 0xfe, 0x43, 0xe7, 0x5c, 0x4c, 0x48, 0x7f, 0x53, 0xfc, 0xfe, 0x21, 0x11, 0x37,
0x35, 0x7c, 0xd4, 0xa7, 0x0d, 0x9f, 0x05, 0x79, 0xcc, 0x2c, 0xca, 0xe3, 0xdf, 0x55, 0xa8, 0xa5,
0x4d, 0xfa, 0xf8, 0x22, 0x9f, 0xbf, 0xc8, 0x3f, 0xf0, 0x6f, 0xaa, 0x77, 0x15, 0xf8, 0xd4, 0x82,
0x80, 0x7e, 0xb0, 0x44, 0xa7, 0xae, 0x73, 0xf5, 0xa9, 0xd7, 0xf9, 0xb3, 0xa6, 0xfa, 0xed, 0x2c,
0xac, 0x0c, 0x3c, 0xdb, 0x62, 0x52, 0xc8, 0x47, 0xbb, 0x39, 0x3f, 0x0b, 0x4b, 0x01, 0x77, 0xd6,
0x18, 0xb9, 0x76, 0x38, 0xe1, 0xd9, 0xcd, 0xac, 0x97, 0x48, 0x59, 0xd0, 0x36, 0x05, 0x09, 0xbf,
0x08, 0xe5, 0x18, 0x12, 0x3a, 0x4c, 0xfe, 0x42, 0x03, 0x89, 0x08, 0x1d, 0x86, 0x37, 0xe0, 0x93,
0x4e, 0x38, 0x31, 0xc4, 0x87, 0xa9, 0x47, 0x7d, 0x43, 0x48, 0x36, 0x3c, 0xd3, 0x67, 0xb5, 0xa2,
0x00, 0x57, 0x9d, 0x70, 0x42, 0xdc, 0xd3, 0xa0, 0x4f, 0x7d, 0xa1, 0xbc, 0x6f, 0xfa, 0x0c, 0xdf,
0x85, 0x92, 0x69, 0x1f, 0xb8, 0xbe, 0xc5, 0x0e, 0x27, 0xb5, 0x92, 0xf8, 0x58, 0xd3, 0xe2, 0x8f,
0xb5, 0xf3, 0xe1, 0xaf, 0x37, 0x63, 0x24, 0x99, 0x1d, 0xc2, 0xd7, 0x01, 0x87, 0x01, 0x35, 0x22,
0xe3, 0x22, 0xa5, 0x27, 0x8d, 0x1a, 0x88, 0xfa, 0xbc, 0x18, 0x06, 0x74, 0x26, 0x66, 0xb7, 0xa1,
0xdd, 0x80, 0x52, 0x22, 0x04, 0x23, 0x58, 0x6a, 0x3f, 0x18, 0x36, 0xbb, 0xc6, 0xa0, 0xdf, 0xed,
0xe8, 0x03, 0x74, 0x01, 0x57, 0xa0, 0xb4, 0x3d, 0xec, 0x76, 0x8d, 0xc1, 0x66, 0xb3, 0x87, 0x14,
0x8d, 0x00, 0x88, 0x83, 0x42, 0xc4, 0x2c, 0x9a, 0xca, 0x53, 0xa2, 0xf9, 0x02, 0x94, 0x7c, 0xf7,
0x54, 0x06, 0x4a, 0x15, 0xbe, 0x17, 0x7d, 0xf7, 0x54, 0x84, 0x49, 0x6b, 0x02, 0x4e, 0x3b, 0x26,
0x4b, 0x3d, 0xd5, 0x8d, 0xca, 0x5c, 0x37, 0xce, 0xf4, 0x27, 0xdd, 0xa8, 0x5d, 0x82, 0x6a, 0xf4,
0x7b, 0xeb, 0x0d, 0x6a, 0xda, 0x2c, 0x1e, 0x40, 0xda, 0x9f, 0x54, 0xa8, 0x10, 0x4e, 0xb1, 0x26,
0x94, 0x7f, 0xdc, 0x06, 0x3c, 0xad, 0x87, 0x02, 0x62, 0xcc, 0xfa, 0xa8, 0x44, 0xca, 0x11, 0x4d,
0xf4, 0x10, 0x6e, 0xc0, 0xa5, 0x80, 0x8e, 0x5c, 0x67, 0x1c, 0x18, 0x7b, 0xf4, 0xd0, 0x72, 0xc6,
0xc6, 0xc4, 0x0c, 0x98, 0x7c, 0xa8, 0xa8, 0x90, 0xaa, 0x64, 0xb6, 0x04, 0x6f, 0x47, 0xb0, 0xf0,
0x4d, 0x58, 0xdd, 0xb3, 0x1c, 0xdb, 0x3d, 0x30, 0x3c, 0xdb, 0x9c, 0x52, 0x3f, 0x90, 0xae, 0xf2,
0x5a, 0xcc, 0x11, 0x1c, 0xf1, 0xfa, 0x11, 0x2b, 0xaa, 0x8d, 0x6f, 0xc0, 0xb5, 0x85, 0x5a, 0x8c,
0x7d, 0xcb, 0x66, 0xd4, 0xa7, 0x63, 0xc3, 0xa7, 0x9e, 0x6d, 0x8d, 0x4c, 0x31, 0x5b, 0xa2, 0x3b,
0xf4, 0x95, 0x05, 0xaa, 0xb7, 0x25, 0x9c, 0xcc, 0xd0, 0x3c, 0xda, 0x23, 0x2f, 0x34, 0xc2, 0xc0,
0x3c, 0xa0, 0x62, 0x2c, 0x29, 0xa4, 0x38, 0xf2, 0xc2, 0x21, 0xdf, 0xf3, 0x4f, 0xe6, 0x63, 0x2f,
0x9a, 0x46, 0x0a, 0xe1, 0x4b, 0xed, 0x5f, 0x4a, 0xfc, 0x73, 0x3e, 0x8e, 0x5e, 0x32, 0x6d, 0xe2,
0x9e, 0x52, 0xde, 0xaf, 0xa7, 0x6a, 0x50, 0x08, 0xa8, 0x7f, 0x62, 0x39, 0x07, 0xf1, 0x5b, 0x8e,
0xdc, 0xe2, 0x01, 0xbc, 0x22, 0xdf, 0x62, 0xe9, 0x23, 0x46, 0x7d, 0xc7, 0xb4, 0xed, 0x29, 0xf7,
0xcb, 0xf4, 0xa9, 0xc3, 0xe8, 0xd8, 0x98, 0xbd, 0x9a, 0x46, 0x13, 0xe7, 0xa5, 0x08, 0xdd, 0x4e,
0xc0, 0x24, 0xc1, 0xea, 0xc9, 0x7b, 0xea, 0x97, 0x61, 0xd9, 0x97, 0x39, 0x35, 0x02, 0x9e, 0x54,
0xd9, 0xcb, 0xab, 0xc9, 0x83, 0x4c, 0x2a, 0xe1, 0xa4, 0xe2, 0xa7, 0xb7, 0xda, 0x7f, 0x15, 0xa8,
0x0e, 0xbd, 0xb1, 0xc9, 0x68, 0xe4, 0xf1, 0x73, 0x3a, 0xc6, 0xd2, 0xaf, 0xc7, 0xd9, 0xf9, 0xd7,
0xe3, 0xf9, 0xd7, 0xe8, 0xdc, 0xb9, 0xd7, 0x68, 0xed, 0x2e, 0xac, 0xce, 0xfb, 0x2f, 0x73, 0xbd,
0x0e, 0x39, 0xf1, 0x7a, 0x74, 0xee, 0xbb, 0x24, 0xf5, 0x3c, 0x44, 0x22, 0xc0, 0xb5, 0x23, 0xc8,
0x6e, 0xdb, 0xe6, 0x01, 0x2e, 0x42, 0xb6, 0x77, 0xbf, 0xd7, 0x46, 0x17, 0xf0, 0x45, 0x80, 0xce,
0xa0, 0xd3, 0xd3, 0xdb, 0xf7, 0x48, 0xb3, 0x8b, 0xce, 0xd4, 0x88, 0x30, 0xec, 0x0d, 0x3a, 0xf7,
0x7a, 0xed, 0x2d, 0x74, 0x96, 0xc5, 0x4b, 0x50, 0xe8, 0x0c, 0xb6, 0xbb, 0xf7, 0x9b, 0x3a, 0x3a,
0x2b, 0xe2, 0x0a, 0x14, 0x3b, 0x83, 0x07, 0xc3, 0xfb, 0x3a, 0x67, 0x22, 0x5c, 0x86, 0x7c, 0x67,
0xa0, 0xb7, 0xbf, 0xae, 0xa3, 0xb3, 0x2b, 0x11, 0xaf, 0xd5, 0xe9, 0x35, 0xc9, 0x43, 0x74, 0x76,
0xf7, 0xda, 0xbf, 0x55, 0xc8, 0xea, 0x53, 0x8f, 0xf2, 0x39, 0xd4, 0xe3, 0x73, 0x48, 0x7f, 0xd8,
0xe7, 0x2a, 0x4b, 0x90, 0xed, 0xf4, 0xf4, 0x3b, 0xe8, 0x9b, 0x2a, 0x06, 0xc8, 0x0d, 0xc5, 0xfa,
0xed, 0x3c, 0x5f, 0x77, 0x7a, 0xfa, 0x17, 0x6e, 0xa3, 0x6f, 0xa9, 0x5c, 0xec, 0x30, 0xda, 0x7c,
0x3b, 0x66, 0x34, 0x36, 0xd0, 0x77, 0x12, 0x46, 0x63, 0x03, 0x7d, 0x37, 0x66, 0xdc, 0x6a, 0xa0,
0xef, 0x25, 0x8c, 0x5b, 0x0d, 0xf4, 0xfd, 0x98, 0x71, 0x7b, 0x03, 0xfd, 0x20, 0x61, 0xdc, 0xde,
0x40, 0x3f, 0xcc, 0x73, 0x5f, 0x84, 0x27, 0xb7, 0x1a, 0xe8, 0x47, 0xc5, 0x64, 0x77, 0x7b, 0x03,
0xfd, 0xb8, 0x88, 0x97, 0xa1, 0xa4, 0x77, 0x76, 0xda, 0x03, 0xbd, 0xb9, 0xd3, 0x47, 0x3f, 0x41,
0xdc, 0xcc, 0xad, 0xa6, 0xde, 0x46, 0x3f, 0x15, 0x4b, 0xce, 0x42, 0x3f, 0x43, 0xdc, 0x47, 0x4e,
0x15, 0xdb, 0x77, 0x04, 0xe7, 0x61, 0xbb, 0x49, 0xd0, 0xcf, 0xf3, 0xb8, 0x0c, 0x85, 0xad, 0xf6,
0x66, 0x67, 0xa7, 0xd9, 0x45, 0x58, 0x9c, 0xe0, 0x51, 0xf9, 0xc5, 0x4d, 0xbe, 0x6c, 0x75, 0xef,
0xb7, 0xd0, 0x2f, 0xfb, 0x5c, 0xe1, 0x6e, 0x93, 0x6c, 0xbe, 0xd1, 0x24, 0xe8, 0x57, 0x37, 0xb9,
0xc2, 0xdd, 0x26, 0x91, 0xf1, 0xfa, 0x75, 0x9f, 0x03, 0x05, 0xeb, 0xdd, 0x9b, 0xdc, 0x68, 0x49,
0xff, 0x4d, 0x1f, 0x17, 0x21, 0xd3, 0xea, 0xe8, 0xe8, 0xb7, 0x42, 0x5b, 0xbb, 0x37, 0xdc, 0x41,
0xbf, 0x43, 0x9c, 0x38, 0x68, 0xeb, 0xe8, 0xf7, 0x9c, 0x98, 0xd3, 0x87, 0xfd, 0x6e, 0x1b, 0x5d,
0x6e, 0xad, 0x41, 0x6d, 0xe4, 0x4e, 0xea, 0x53, 0x37, 0x64, 0xe1, 0x1e, 0xad, 0x9f, 0x58, 0x8c,
0x06, 0x41, 0xf4, 0x7f, 0x99, 0xbd, 0xbc, 0xf8, 0x73, 0xeb, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff,
0x49, 0x1d, 0xea, 0xf8, 0xd1, 0x19, 0x00, 0x00,
}

Просмотреть файл

@ -71,6 +71,12 @@ var TestVTGateCallerID = &querypb.VTGateCallerID{
var TestExecuteOptions = &querypb.ExecuteOptions{
ExcludeFieldNames: true,
IncludeEventToken: true,
CompareEventToken: &querypb.EventToken{
Timestamp: 9876,
Shard: "ssss",
Position: "pppp",
},
}
const TestAsTransaction bool = true
@ -178,6 +184,14 @@ var ExecuteQueryResult = sqltypes.Result{
sqltypes.MakeTrusted(sqltypes.Char, []byte("row2 value2")),
},
},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 456321,
Shard: "test_shard",
Position: "test_position",
},
Fresher: true,
},
}
// Execute is part of the queryservice.QueryService interface
@ -307,6 +321,14 @@ var ExecuteBatchQueryResultList = []sqltypes.Result{
sqltypes.MakeTrusted(sqltypes.Int8, []byte("2")),
},
},
Extras: &querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 456322,
Shard: "test_shard2",
Position: "test_position2",
},
Fresher: true,
},
},
{
Fields: []*querypb.Field{

Просмотреть файл

@ -23,6 +23,7 @@ import (
"github.com/youtube/vitess/go/sync2"
"github.com/youtube/vitess/go/tb"
"github.com/youtube/vitess/go/vt/binlog"
"github.com/youtube/vitess/go/vt/binlog/eventtoken"
"github.com/youtube/vitess/go/vt/dbconfigs"
"github.com/youtube/vitess/go/vt/dbconnpool"
"github.com/youtube/vitess/go/vt/mysqlctl"
@ -776,16 +777,62 @@ func (tsv *TabletServer) Execute(ctx context.Context, target *querypb.Target, sq
logStats: logStats,
qe: tsv.qe,
}
extras := tsv.computeExtras(options)
result, err = qre.Execute()
if err != nil {
return nil, tsv.handleExecErrorNoPanic(sql, bindVariables, err, logStats)
}
result.Extras = extras
if options != nil && options.ExcludeFieldNames {
result = result.StripFieldNames()
}
return result, nil
}
// computeExtras returns the ResultExtras to include with the result.
func (tsv *TabletServer) computeExtras(options *querypb.ExecuteOptions) *querypb.ResultExtras {
if options == nil {
// No options passed in.
return nil
}
if !options.IncludeEventToken && options.CompareEventToken == nil {
// The flags that make extras exist are not there.
return nil
}
// Grab the current EventToken.
tsv.eventTokenMutex.RLock()
et := tsv.eventToken
tsv.eventTokenMutex.RUnlock()
if et == nil {
return nil
}
var extras *querypb.ResultExtras
// See if we need to fill in EventToken.
if options.IncludeEventToken {
extras = &querypb.ResultExtras{
EventToken: et,
}
}
// See if we need to compare.
if options.CompareEventToken != nil {
if eventtoken.Fresher(et, options.CompareEventToken) {
if extras == nil {
extras = &querypb.ResultExtras{
Fresher: true,
}
} else {
extras.Fresher = true
}
}
}
return extras
}
// StreamExecute executes the query and streams the result.
// The first QueryResult will have Fields set (and Rows nil).
// The subsequent QueryResult will have Rows set (and Fields nil).

Просмотреть файл

@ -16,6 +16,7 @@ import (
"github.com/youtube/vitess/go/sqltypes"
"github.com/youtube/vitess/go/stats"
"github.com/youtube/vitess/go/vt/binlog/eventtoken"
"github.com/youtube/vitess/go/vt/concurrency"
"github.com/youtube/vitess/go/vt/discovery"
"github.com/youtube/vitess/go/vt/tabletserver/querytypes"
@ -955,6 +956,31 @@ func appendResult(qr, innerqr *sqltypes.Result) {
if innerqr.InsertID != 0 {
qr.InsertID = innerqr.InsertID
}
if len(qr.Rows) == 0 {
// we haven't gotten any result yet, just save the new extras.
qr.Extras = innerqr.Extras
} else {
// Merge the EventTokens / Fresher flags within Extras.
if innerqr.Extras == nil {
// We didn't get any from innerq. Have to clear any
// we'd have gotten already.
if qr.Extras != nil {
qr.Extras.EventToken = nil
qr.Extras.Fresher = false
}
} else {
// We may have gotten an EventToken from
// innerqr. If we also got one earlier, merge
// it. If we didn't get one earlier, we
// discard the new one.
if qr.Extras != nil {
// Note if any of the two is nil, we get nil.
qr.Extras.EventToken = eventtoken.Minimum(qr.Extras.EventToken, innerqr.Extras.EventToken)
qr.Extras.Fresher = qr.Extras.Fresher && innerqr.Extras.Fresher
}
}
}
qr.Rows = append(qr.Rows, innerqr.Rows...)
}

Просмотреть файл

@ -1194,8 +1194,9 @@ func testStreamExecute(t *testing.T, conn *vtgateconn.VTGateConn) {
wantResult := *execCase.result
wantResult.RowsAffected = 0
wantResult.InsertID = 0
wantResult.Extras = nil
if !reflect.DeepEqual(qr, wantResult) {
t.Errorf("Unexpected result from Execute: got %+v want %+v", qr, wantResult)
t.Errorf("Unexpected result from StreamExecute: got %+v want %+v", qr, wantResult)
}
stream, err = conn.StreamExecute(ctx, "none", nil, topodatapb.TabletType_RDONLY, testExecuteOptions)
@ -1274,8 +1275,9 @@ func testStreamExecuteShards(t *testing.T, conn *vtgateconn.VTGateConn) {
wantResult := *execCase.result
wantResult.RowsAffected = 0
wantResult.InsertID = 0
wantResult.Extras = nil
if !reflect.DeepEqual(qr, wantResult) {
t.Errorf("Unexpected result from Execute: got %+v want %+v", qr, wantResult)
t.Errorf("Unexpected result from StreamExecuteShards: got %+v want %+v", qr, wantResult)
}
stream, err = conn.StreamExecuteShards(ctx, "none", "", []string{}, nil, topodatapb.TabletType_REPLICA, testExecuteOptions)
@ -1354,8 +1356,9 @@ func testStreamExecuteKeyRanges(t *testing.T, conn *vtgateconn.VTGateConn) {
wantResult := *execCase.result
wantResult.RowsAffected = 0
wantResult.InsertID = 0
wantResult.Extras = nil
if !reflect.DeepEqual(qr, wantResult) {
t.Errorf("Unexpected result from Execute: got %+v want %+v", qr, wantResult)
t.Errorf("Unexpected result from StreamExecuteKeyRanges: got %+v want %+v", qr, wantResult)
}
stream, err = conn.StreamExecuteKeyRanges(ctx, "none", "", []*topodatapb.KeyRange{}, nil, topodatapb.TabletType_REPLICA, testExecuteOptions)
@ -1434,8 +1437,9 @@ func testStreamExecuteKeyspaceIds(t *testing.T, conn *vtgateconn.VTGateConn) {
wantResult := *execCase.result
wantResult.RowsAffected = 0
wantResult.InsertID = 0
wantResult.Extras = nil
if !reflect.DeepEqual(qr, wantResult) {
t.Errorf("Unexpected result from Execute: got %+v want %+v", qr, wantResult)
t.Errorf("Unexpected result from StreamExecuteKeyspaceIds: got %+v want %+v", qr, wantResult)
}
stream, err = conn.StreamExecuteKeyspaceIds(ctx, "none", "", [][]byte{}, nil, topodatapb.TabletType_REPLICA, testExecuteOptions)
@ -1872,8 +1876,9 @@ func testUpdateStream(t *testing.T, conn *vtgateconn.VTGateConn) {
sqr := sqltypes.Proto3ToResult(&qr)
wantResult := *execCase.result
wantResult.InsertID = 0
wantResult.Extras = nil
if !reflect.DeepEqual(sqr, &wantResult) {
t.Errorf("Unexpected result from Execute: got %+v want %+v", sqr, wantResult)
t.Errorf("Unexpected result from UpdateStream: got %+v want %+v", sqr, wantResult)
}
stream, err = conn.UpdateStream(ctx, "none", nil, topodatapb.TabletType_RDONLY, 0, nil)
@ -1934,6 +1939,12 @@ var testCallerID = &vtrpcpb.CallerID{
var testExecuteOptions = &querypb.ExecuteOptions{
ExcludeFieldNames: true,
IncludeEventToken: true,
CompareEventToken: &querypb.EventToken{
Timestamp: 135,
Shard: "shrd",
Position: "pstn",
},
}
var execMap = map[string]struct {
@ -2321,6 +2332,15 @@ var execMap = map[string]struct {
},
}
var extras = querypb.ResultExtras{
EventToken: &querypb.EventToken{
Timestamp: 123,
Shard: "sh",
Position: "po",
},
Fresher: true,
}
var result1 = sqltypes.Result{
Fields: []*querypb.Field{
{
@ -2344,6 +2364,7 @@ var result1 = sqltypes.Result{
sqltypes.MakeTrusted(sqltypes.Int32, []byte("3")),
},
},
Extras: &extras,
}
// streamResultFields is only the fields, sent as the first packet

Просмотреть файл

@ -180,6 +180,14 @@ message ExecuteOptions {
// This is an optimization for high-QPS queries where the client knows
// what it's getting.
bool exclude_field_names = 1;
// If set, we will try to include an EventToken with the responses.
bool include_event_token = 2;
// If set, the fresher field may be set as a result comparison to this token.
// This is a shortcut so the application doesn't need to care about
// comparing EventTokens.
EventToken compare_event_token = 3;
}
// Field describes a single column returned by a query
@ -202,6 +210,18 @@ message Row {
bytes values = 2;
}
// ResultExtras contains optional out-of-band information. Usually the
// extras are requested by adding ExecuteOptions flags.
message ResultExtras {
// event_token is populated if the include_event_token flag is set
// in ExecuteOptions.
EventToken event_token = 1;
// If set, it means the data returned with this result is fresher
// than the compare_token passed in the ExecuteOptions.
bool fresher = 2;
}
// QueryResult is returned by Execute and ExecuteStream.
//
// As returned by Execute, len(fields) is always equal to len(row)
@ -216,6 +236,7 @@ message QueryResult {
uint64 rows_affected = 2;
uint64 insert_id = 3;
repeated Row rows = 4;
ResultExtras extras = 5;
}
// StreamEvent describes a set of transformations that happened as a

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -369,6 +369,96 @@ class TestUpdateStream(unittest.TestCase):
timeout = utils.wait_step(
'EventTokenPosition must be up to date but got %s' % value, timeout)
# With vttablet up to date, test a vttablet query returns the EventToken.
qr = replica_tablet.execute('select * from vt_insert_test',
execute_options='include_event_token:true ')
logging.debug('Got result: %s', qr)
self.assertIn('extras', qr)
self.assertIn('event_token', qr['extras'])
self.assertEqual(qr['extras']['event_token']['position'], replica_position)
# Same thing through vtgate
qr = utils.vtgate.execute('select * from vt_insert_test',
tablet_type='replica',
execute_options='include_event_token:true ')
logging.debug('Got result: %s', qr)
self.assertIn('extras', qr)
self.assertIn('event_token', qr['extras'])
self.assertEqual(qr['extras']['event_token']['position'], replica_position)
# Make sure the compare_event_token flag works, by sending a very
# old timestamp, or a timestamp in the future.
qr = replica_tablet.execute(
'select * from vt_insert_test',
execute_options='compare_event_token: <timestamp:123 > ')
self.assertIn('extras', qr)
self.assertIn('fresher', qr['extras'])
self.assertTrue(qr['extras']['fresher'])
future_timestamp = long(time.time()) + 100
qr = replica_tablet.execute(
'select * from vt_insert_test',
execute_options='compare_event_token: <timestamp:%d > ' %
future_timestamp)
self.assertTrue(qr['extras'] is None)
# Same thing through vtgate
qr = utils.vtgate.execute(
'select * from vt_insert_test', tablet_type='replica',
execute_options='compare_event_token: <timestamp:123 > ')
self.assertIn('extras', qr)
self.assertIn('fresher', qr['extras'])
self.assertTrue(qr['extras']['fresher'])
future_timestamp = long(time.time()) + 100
qr = utils.vtgate.execute(
'select * from vt_insert_test', tablet_type='replica',
execute_options='compare_event_token: <timestamp:%d > ' %
future_timestamp)
self.assertTrue(qr['extras'] is None)
# Make sure the compare_event_token flag works, by sending a very
# old timestamp, or a timestamp in the future, when combined with
# include_event_token flag.
qr = replica_tablet.execute('select * from vt_insert_test',
execute_options='include_event_token:true '
'compare_event_token: <timestamp:123 > ')
self.assertIn('extras', qr)
self.assertIn('fresher', qr['extras'])
self.assertTrue(qr['extras']['fresher'])
self.assertIn('event_token', qr['extras'])
self.assertEqual(qr['extras']['event_token']['position'], replica_position)
future_timestamp = long(time.time()) + 100
qr = replica_tablet.execute('select * from vt_insert_test',
execute_options='include_event_token:true '
'compare_event_token: <timestamp:%d > ' %
future_timestamp)
self.assertNotIn('fresher', qr['extras'])
self.assertIn('event_token', qr['extras'])
self.assertEqual(qr['extras']['event_token']['position'], replica_position)
# Same thing through vtgate
qr = utils.vtgate.execute('select * from vt_insert_test',
tablet_type='replica',
execute_options='include_event_token:true '
'compare_event_token: <timestamp:123 > ')
self.assertIn('extras', qr)
self.assertIn('fresher', qr['extras'])
self.assertTrue(qr['extras']['fresher'])
self.assertIn('event_token', qr['extras'])
self.assertEqual(qr['extras']['event_token']['position'], replica_position)
future_timestamp = long(time.time()) + 100
qr = utils.vtgate.execute('select * from vt_insert_test',
tablet_type='replica',
execute_options='include_event_token:true '
'compare_event_token: <timestamp:%d > ' %
future_timestamp)
self.assertNotIn('fresher', qr['extras'])
self.assertIn('event_token', qr['extras'])
self.assertEqual(qr['extras']['event_token']['position'], replica_position)
def test_update_stream_interrupt(self):
"""Checks that a running query is terminated on going non-serving."""
# Make sure the replica is replica type.