fix some Distinct key translation issues (e.g. empty index)

This commit changes executeDistinct to return either a *Row or a
SignedRow (instead of only being able to return a SignedRow). Distinct
on a set field will return a *Row while an int field will still return
a signed row.

We then add Field and Index fields to the Row object so that we can
determine how to translate the rows IDs to keys (if needed). This adds
a lot of logic around the translation which fixes bugs where Distinct
calls would fail to get translated.

There are, I think, still issues if you were to try to join a keyed
field to a keyed index which wasn't explicitly specified as the
field's foreign index. The IDs in the field wouldn't be using the same
translation as the IDs in the index, so the query might appear to work
but give incorrect results.
This commit is contained in:
Matt Jaffee 2020-12-23 14:14:51 -06:00
parent 385381e5f3
commit 9ee5f52a11
No known key found for this signature in database
GPG key ID: 08A3DFFF987B11BF
6 changed files with 408 additions and 150 deletions

View file

@ -1453,6 +1453,8 @@ func (s Serializer) decodeRow(pr *internal.Row) *pilosa.Row {
}
r.Attrs = s.decodeAttrs(pr.Attrs)
r.Keys = pr.Keys
r.Index = pr.Index
r.Field = pr.Field
return r
}
@ -1700,6 +1702,8 @@ func (s Serializer) encodeRow(r *pilosa.Row) *internal.Row {
ir := &internal.Row{
Keys: r.Keys,
Attrs: s.encodeAttrs(r.Attrs),
Index: r.Index,
Field: r.Field,
}
if s.RoaringRows {
ir.Roaring = r.Roaring()

View file

@ -563,6 +563,7 @@ func (e *executor) execute(ctx context.Context, qcx *Qcx, index string, q *pql.Q
} else {
v, err = e.executeCall(ctx, qcx, index, call, shards, opt)
}
if err != nil {
return nil, err
}
@ -1080,8 +1081,9 @@ func (e *executor) executeSum(ctx context.Context, qcx *Qcx, index string, c *pq
return other, nil
}
// executeDistinct executes a Distinct call on a field.
func (e *executor) executeDistinct(ctx context.Context, qcx *Qcx, index string, c *pql.Call, shards []uint64, opt *execOptions) (SignedRow, error) {
// executeDistinct executes a Distinct call on a field. It returns a
// SignedRow for int fields and a *Row for set/mutex/time fields.
func (e *executor) executeDistinct(ctx context.Context, qcx *Qcx, index string, c *pql.Call, shards []uint64, opt *execOptions) (interface{}, error) {
span, ctx := tracing.StartSpanFromContext(ctx, "Executor.executeDistinct")
defer span.Finish()
@ -1099,21 +1101,31 @@ func (e *executor) executeDistinct(ctx context.Context, qcx *Qcx, index string,
// Merge returned results at coordinating node.
reduceFn := func(ctx context.Context, prev, v interface{}) interface{} {
other, _ := prev.(SignedRow)
if err := ctx.Err(); err != nil {
return err
}
return other.union(v.(SignedRow))
switch other := prev.(type) {
case SignedRow:
return other.union(v.(SignedRow))
case *Row:
return other.Union(v.(*Row))
case nil:
return v
default:
return errors.Errorf("unexpected return type from executeDistinctShard: %+v %T", other, other)
}
}
result, err := e.mapReduce(ctx, index, shards, c, opt, mapFn, reduceFn)
if err != nil {
return SignedRow{}, err
return nil, err
}
other, _ := result.(SignedRow)
other.field = field
return other, nil
if other, ok := result.(SignedRow); ok {
other.field = field
}
return result, nil
}
// executeMin executes a Min() call.
@ -1302,7 +1314,7 @@ func (e *executor) executeBitmapCall(ctx context.Context, qcx *Qcx, index string
reduceFn := func(ctx context.Context, prev, v interface{}) interface{} {
other, _ := prev.(*Row)
if other == nil {
// TODO... what's going on on the following line
other = NewRow() // bug! this row ends up containing Badger Txn data that should be accessed outside the Txn.
}
if err := ctx.Err(); err != nil {
@ -1398,14 +1410,20 @@ func (e *executor) executeBitmapCallShard(ctx context.Context, qcx *Qcx, index s
// executeDistinctShard executes a Distinct call on a single shard, yielding
// a SignedRow of the values found.
func (e *executor) executeDistinctShard(ctx context.Context, qcx *Qcx, index string, fieldName string, c *pql.Call, shard uint64) (result SignedRow, err error) {
func (e *executor) executeDistinctShard(ctx context.Context, qcx *Qcx, index string, fieldName string, c *pql.Call, shard uint64) (result interface{}, err error) {
span, ctx := tracing.StartSpanFromContext(ctx, "Executor.executeDistinctShard")
defer span.Finish()
idx := e.Holder.Index(index)
field := e.Holder.Field(index, fieldName)
if field == nil {
return SignedRow{}, ErrFieldNotFound
return nil, ErrFieldNotFound
}
bsig := field.bsiGroup(fieldName)
if bsig == nil {
result = new(Row)
} else {
result = SignedRow{}
}
var filter *Row
@ -1427,28 +1445,27 @@ func (e *executor) executeDistinctShard(ctx context.Context, qcx *Qcx, index str
// can go ahead and save time by returning the empty results,
// because the filter excluded everything.
if filterBitmap == nil || !filterBitmap.Any() {
return SignedRow{}, nil
return result, nil
}
}
bsig := field.bsiGroup(fieldName)
if bsig == nil {
return executeDistinctShardSet(ctx, qcx, idx, fieldName, shard, filterBitmap)
}
return executeDistinctShardBSI(ctx, qcx, idx, fieldName, shard, bsig, filterBitmap)
}
func executeDistinctShardSet(ctx context.Context, qcx *Qcx, idx *Index, fieldName string, shard uint64, filterBitmap *roaring.Bitmap) (result SignedRow, err0 error) {
func executeDistinctShardSet(ctx context.Context, qcx *Qcx, idx *Index, fieldName string, shard uint64, filterBitmap *roaring.Bitmap) (result *Row, err0 error) {
index := idx.Name()
tx, finisher, err := qcx.GetTx(Txo{Write: !writable, Index: idx, Shard: shard})
if err != nil {
return SignedRow{}, err
return nil, err
}
defer finisher(&err0)
fragData, _, err := tx.ContainerIterator(index, fieldName, "standard", shard, 0)
if err != nil {
return SignedRow{}, errors.Wrap(err, "getting fragment data")
return nil, errors.Wrap(err, "getting fragment data")
}
defer fragData.Close()
// We can't grab the containers "for each row" from the set-type field,
@ -1486,20 +1503,22 @@ func executeDistinctShardSet(ctx context.Context, qcx *Qcx, idx *Index, fieldNam
if roaring.IntersectionAny(c, filter[k%(1<<shardVsContainerExponent)]) {
_, err = rows.Add(row)
if err != nil {
return SignedRow{}, errors.Wrap(err, "collecting results")
return nil, errors.Wrap(err, "collecting results")
}
seenThisRow = true
}
} else if c.N() != 0 {
_, err = rows.Add(row)
if err != nil {
return SignedRow{}, errors.Wrap(err, "recording results")
return nil, errors.Wrap(err, "recording results")
}
seenThisRow = true
}
}
return SignedRow{Pos: NewRowFromBitmap(rows)}, nil
result = NewRowFromBitmap(rows)
result.Index = idx.Name()
result.Field = fieldName
return result, nil
}
func executeDistinctShardBSI(ctx context.Context, qcx *Qcx, idx *Index, fieldName string, shard uint64, bsig *bsiGroup, filterBitmap *roaring.Bitmap) (result SignedRow, err0 error) {
@ -1612,10 +1631,14 @@ func executeDistinctShardBSI(ctx context.Context, qcx *Qcx, idx *Index, fieldNam
}
}
}
return SignedRow{
result = SignedRow{
Neg: NewRowFromBitmap(negBitmap),
Pos: NewRowFromBitmap(posBitmap),
}, nil
}
result.Neg.Index, result.Pos.Index = idx.Name(), idx.Name()
result.Neg.Field, result.Pos.Field = fieldName, fieldName
return result, nil
}
// executeSumCountShard calculates the sum and count for bsiGroups on a shard.
@ -6000,13 +6023,81 @@ func (e *executor) translateResults(ctx context.Context, index string, idx *Inde
return nil
}
type translationStrategy int
const (
byCurrentIndex translationStrategy = iota + 1
byRowField
byRowFieldForeignIndex
byRowIndex
noTranslation
)
// howToTranslate determines how a *Row object's bits should be
// translated to keys (if at all). There are several different options
// detailed by the various const values of translationStrategy. In
// order to do this it has to figure out the row's index and field
// which it also returns as the caller may need them to actually
// execute the translation or do whatever else it's doing with the
// translationStrategy information.
func (e *executor) howToTranslate(idx *Index, row *Row) (rowIdx *Index, rowField *Field, strat translationStrategy, err error) {
// First get the index and field the row specifies (if any).
rowIdx = idx
if row.Index != "" && row.Index != idx.Name() {
rowIdx = e.Holder.Index(row.Index)
if rowIdx == nil {
return nil, nil, 0, errors.Errorf("got a row with unknown index: %s", row.Index)
}
}
if row.Field != "" {
rowField = rowIdx.Field(row.Field)
if rowField == nil {
return nil, nil, 0, errors.Errorf("got a row with unknown index/field %s/%s", idx.Name(), row.Field)
}
}
// Handle the case where the Row has specified a field
if rowField != nil {
// Handle case where field has a foreign index.
if rowField.ForeignIndex() != "" {
fidx := e.Holder.Index(rowField.ForeignIndex())
if fidx == nil {
return nil, nil, 0, errors.Errorf("foreign index %s not found for field %s in index %s", rowField.ForeignIndex(), rowField.Name(), rowField.Index())
}
if fidx.Keys() {
return rowIdx, rowField, byRowFieldForeignIndex, nil
}
} else if rowField.Keys() {
return rowIdx, rowField, byRowField, nil
}
return rowIdx, rowField, noTranslation, nil
}
// In this case, the row has specified an index, but not a field, so we translate according to that index.
if rowIdx != idx && rowIdx.Keys() {
return rowIdx, rowField, byRowIndex, nil
}
// Handle normal case (row represents a set of records in
// the top level index, Row has not specifed a different index
// or field).
if rowIdx == idx && idx.Keys() && rowField == nil {
return rowIdx, rowField, byCurrentIndex, nil
}
return rowIdx, rowField, noTranslation, nil
}
func (e *executor) collectResultIDs(index string, idx *Index, call *pql.Call, result interface{}, idSet map[uint64]struct{}) error {
switch result := result.(type) {
case *Row:
if !idx.Keys() {
_, _, strategy, err := e.howToTranslate(idx, result)
if err != nil {
return errors.Wrap(err, "determining how to translate")
}
// Only collect result IDs if they are in the current index.
if strategy != byCurrentIndex {
return nil
}
for _, segment := range result.Segments() {
for _, col := range segment.Columns() {
idSet[col] = struct{}{}
@ -6035,10 +6126,14 @@ func (e *executor) preTranslateMatrixSet(mat ExtractedIDMatrix, fieldIdx uint, f
}
func (e *executor) translateResult(ctx context.Context, index string, idx *Index, call *pql.Call, result interface{}, idSet map[uint64]string) (_ interface{}, err error) {
switch result := result.(type) {
case *Row:
if idx.Keys() {
rowIdx, rowField, strategy, err := e.howToTranslate(idx, result)
if err != nil {
return nil, errors.Wrap(err, "determining translation strategy")
}
switch strategy {
case byCurrentIndex:
other := &Row{Attrs: result.Attrs}
for _, segment := range result.Segments() {
for _, col := range segment.Columns() {
@ -6046,11 +6141,40 @@ func (e *executor) translateResult(ctx context.Context, index string, idx *Index
}
}
return other, nil
}
case byRowField:
keys, err := e.Cluster.translateFieldListIDs(rowField, result.Columns())
if err != nil {
return nil, errors.Wrap(err, "translating Row to field keys")
}
result.Keys = keys
case byRowFieldForeignIndex:
idx = e.Holder.Index(rowField.ForeignIndex())
if idx == nil {
return nil, errors.Errorf("foreign index %s not found for field %s in index %s", rowField.ForeignIndex(), rowField.Name(), rowField.Index())
}
for _, segment := range result.Segments() {
keys, err := e.Cluster.translateIndexIDs(context.Background(), rowField.ForeignIndex(), segment.Columns())
if err != nil {
return nil, errors.Wrap(err, "translating index ids")
}
result.Keys = append(result.Keys, keys...)
}
// TODO: instead of supporting SignedRow here, we may be able to
// make the return type for an int field with a ForeignIndex be
// a *Row instead (because it should always be positive).
case byRowIndex:
for _, segment := range result.Segments() {
keys, err := e.Cluster.translateIndexIDs(context.Background(), rowIdx.Name(), segment.Columns())
if err != nil {
return nil, errors.Wrap(err, "translating index ids")
}
result.Keys = append(result.Keys, keys...)
}
return result, nil
case noTranslation:
return result, nil
default:
return nil, errors.Errorf("unknown translation strategy %d", strategy)
}
case SignedRow:
sr, err := func() (*SignedRow, error) {
fieldName := callArgString(call, "field")

View file

@ -6814,8 +6814,8 @@ func TestDistinctOnSetsKeyedIndex(t *testing.T) {
{
query: "Distinct(field=likenums)",
verifier: func(t *testing.T, resp pilosa.QueryResponse) {
if !reflect.DeepEqual(resp.Results[0].(pilosa.SignedRow).Pos.Columns(), []uint64{1, 2, 3, 4, 5, 6, 7}) {
t.Errorf("wrong values: %+v", resp.Results[0].(pilosa.SignedRow).Pos.Columns())
if !reflect.DeepEqual(resp.Results[0].(*pilosa.Row).Columns(), []uint64{1, 2, 3, 4, 5, 6, 7}) {
t.Errorf("wrong values: %+v %+v", resp.Results[0].(*pilosa.Row).Columns(), resp.Results[0].(*pilosa.Row))
}
},
},
@ -6838,6 +6838,26 @@ func TestDistinctOnSetsKeyedIndex(t *testing.T) {
}
},
},
{
query: "Distinct(Row(affinity>=0), field=affinity)",
verifier: func(t *testing.T, resp pilosa.QueryResponse) {
if !reflect.DeepEqual(resp.Results[0].(pilosa.SignedRow).Pos.Columns(), []uint64{0, 5, 10}) {
t.Errorf("wrong positive records: %+v", resp.Results[0].(pilosa.SignedRow).Pos.Columns())
}
if !reflect.DeepEqual(resp.Results[0].(pilosa.SignedRow).Neg.Columns(), []uint64{}) {
t.Errorf("wrong negative records: %+v", resp.Results[0].(pilosa.SignedRow).Neg.Columns())
}
},
},
{
query: "Count(Distinct(Row(affinity>=0), field=affinity))",
verifier: func(t *testing.T, resp pilosa.QueryResponse) {
if resp.Results[0].(uint64) != 3 {
t.Errorf("wrong number of values: %+v", resp.Results[0])
}
},
},
// handling this case properly will require changing the way
// that precomputed data is stored on Call objects. Currently
// if a Distinct is at all nested (e.g. within a Count) it
@ -6851,22 +6871,19 @@ func TestDistinctOnSetsKeyedIndex(t *testing.T) {
// }
// },
// },
// this case doesn't work due to the missing index issue
// {
// query: "Distinct(field=likes)",
// verifier: func(t *testing.T, resp pilosa.QueryResponse) {
// if !reflect.DeepEqual(resp.Results[0].(*pilosa.Row).Keys, []string{"molecula", "pilosa", "pangolin", "zebra", "toucan", "dog", "icecream"}) {
// t.Errorf("wrong values: %+v", resp.Results[0])
// }
// },
// },
{
query: "Distinct(field=likes)",
verifier: func(t *testing.T, resp pilosa.QueryResponse) {
if !reflect.DeepEqual(resp.Results[0].(*pilosa.Row).Keys, []string{"molecula", "pilosa", "pangolin", "zebra", "toucan", "dog", "icecream"}) {
t.Errorf("wrong values: %+v", resp.Results[0])
}
},
},
}
for i, tst := range tests {
t.Run(fmt.Sprintf("%d-%s", i, tst.query), func(t *testing.T) {
resp := c.Query(t, "users", tst.query)
fmt.Println(resp.Results[0])
tst.verifier(t, resp)
})
}

View file

@ -28,6 +28,8 @@ type Row struct {
Keys []string `protobuf:"bytes,3,rep,name=Keys,proto3" json:"Keys,omitempty"`
Attrs []*Attr `protobuf:"bytes,2,rep,name=Attrs,proto3" json:"Attrs,omitempty"`
Roaring []byte `protobuf:"bytes,4,opt,name=Roaring,proto3" json:"Roaring,omitempty"`
Index string `protobuf:"bytes,5,opt,name=Index,proto3" json:"Index,omitempty"`
Field string `protobuf:"bytes,6,opt,name=Field,proto3" json:"Field,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -94,6 +96,20 @@ func (m *Row) GetRoaring() []byte {
return nil
}
func (m *Row) GetIndex() string {
if m != nil {
return m.Index
}
return ""
}
func (m *Row) GetField() string {
if m != nil {
return m.Field
}
return ""
}
type RowMatrix struct {
Rows []*Row `protobuf:"bytes,1,rep,name=Rows,proto3" json:"Rows,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -2667,113 +2683,113 @@ func init() {
func init() { proto.RegisterFile("public.proto", fileDescriptor_413a91106d7bcce8) }
var fileDescriptor_413a91106d7bcce8 = []byte{
// 1682 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4f, 0x6f, 0xdb, 0xca,
0x11, 0x37, 0x45, 0xca, 0x92, 0x46, 0xb2, 0xe3, 0xb7, 0xd1, 0x7b, 0x25, 0x52, 0xc7, 0x4f, 0x25,
0xdc, 0x3e, 0xb5, 0x28, 0x1c, 0x38, 0x4d, 0x82, 0x5c, 0xda, 0xc6, 0x8e, 0x9c, 0x9a, 0x48, 0xed,
0xa6, 0x2b, 0xc3, 0xb9, 0x15, 0xa0, 0xa5, 0xad, 0x43, 0x94, 0x12, 0x55, 0x8a, 0x8a, 0xec, 0x4b,
0x81, 0x7e, 0x86, 0x5c, 0xfa, 0x11, 0x7a, 0xea, 0x87, 0xe8, 0xa5, 0x3d, 0xf6, 0x58, 0xa0, 0x97,
0x22, 0xed, 0xb7, 0xe8, 0xa5, 0x98, 0x59, 0x2e, 0x77, 0x49, 0xd1, 0x8e, 0x11, 0xbc, 0xdb, 0xce,
0x9f, 0x9d, 0x9d, 0xf9, 0xcd, 0xec, 0xec, 0x90, 0xd0, 0x99, 0x2d, 0x2e, 0xa2, 0x70, 0xb4, 0x37,
0x4b, 0xe2, 0x34, 0x66, 0xcd, 0x70, 0x9a, 0x8a, 0x64, 0x1a, 0x44, 0xde, 0x1c, 0x6c, 0x1e, 0x2f,
0x99, 0x0b, 0x8d, 0x97, 0x71, 0xb4, 0x98, 0x4c, 0xe7, 0xae, 0xd5, 0xb3, 0xfb, 0x0e, 0x57, 0x24,
0x63, 0xe0, 0xbc, 0x16, 0xd7, 0x73, 0xd7, 0xee, 0xd9, 0xfd, 0x16, 0xa7, 0x35, 0xdb, 0x85, 0xfa,
0x41, 0x9a, 0x26, 0x73, 0xb7, 0xd6, 0xb3, 0xfb, 0xed, 0xc7, 0x9b, 0x7b, 0xca, 0xdc, 0x1e, 0xb2,
0xb9, 0x14, 0xa2, 0x4d, 0x1e, 0x07, 0x49, 0x38, 0xbd, 0x74, 0x9d, 0x9e, 0xd5, 0xef, 0x70, 0x45,
0x7a, 0x7b, 0xd0, 0xe2, 0xf1, 0xf2, 0x24, 0x48, 0x93, 0xf0, 0x8a, 0x7d, 0x0f, 0x1c, 0x1e, 0x2f,
0xe5, 0xb9, 0xed, 0xc7, 0x1b, 0xda, 0x16, 0x8f, 0x97, 0x9c, 0x44, 0xde, 0x09, 0xb4, 0x86, 0xe1,
0xe5, 0x54, 0x8c, 0xd1, 0xd5, 0xaf, 0xc1, 0x7e, 0x13, 0xa3, 0xba, 0xb5, 0xaa, 0x8e, 0x12, 0x54,
0x38, 0x15, 0x97, 0x6e, 0xad, 0x52, 0xe1, 0x54, 0x5c, 0x7a, 0xcf, 0x61, 0x93, 0xc7, 0x4b, 0x7f,
0x2c, 0xa6, 0x69, 0xf8, 0xdb, 0x50, 0x24, 0x14, 0x64, 0xee, 0x83, 0x23, 0x0f, 0xcd, 0x03, 0xaf,
0xe9, 0xc0, 0xbd, 0x07, 0xb0, 0xee, 0x0f, 0x7e, 0x19, 0xce, 0x53, 0xb6, 0x05, 0xb6, 0x3f, 0x50,
0x1b, 0x70, 0xe9, 0xf9, 0xf0, 0xc5, 0xd1, 0x55, 0x9a, 0x04, 0xa3, 0x54, 0x8c, 0xfd, 0x81, 0x84,
0x8f, 0x6d, 0x42, 0xcd, 0x1f, 0x90, 0xaf, 0x0e, 0xaf, 0xf9, 0x03, 0xb6, 0x0b, 0xce, 0x79, 0x10,
0x29, 0xe0, 0xb6, 0xb4, 0x73, 0xd2, 0x2c, 0x27, 0xa9, 0x77, 0x51, 0x30, 0x95, 0xe1, 0xf4, 0x15,
0xac, 0xbf, 0x0a, 0x45, 0x34, 0x96, 0x87, 0xb6, 0x78, 0x46, 0xb1, 0xa7, 0x3a, 0x75, 0xd2, 0xea,
0x77, 0xb5, 0xd5, 0x15, 0x87, 0xf2, 0xbc, 0x7a, 0x0f, 0xa1, 0xf1, 0x5a, 0x5c, 0x53, 0x2c, 0x2a,
0x52, 0xcb, 0x88, 0xf4, 0x5f, 0x16, 0xdc, 0xcf, 0x77, 0x9f, 0x05, 0x17, 0x91, 0x38, 0x0f, 0xa2,
0x85, 0x60, 0xbb, 0x2a, 0x6e, 0xab, 0xca, 0xff, 0xe3, 0x35, 0xc2, 0x82, 0x7d, 0x93, 0x63, 0x87,
0x6a, 0x5f, 0x68, 0xb5, 0xec, 0xc8, 0xe3, 0xb5, 0xac, 0x92, 0xb6, 0xa1, 0x79, 0x38, 0xf4, 0xc9,
0xb4, 0x6b, 0xf7, 0xac, 0xbe, 0x7d, 0xbc, 0xc6, 0x73, 0x0e, 0x7b, 0x00, 0x8d, 0x93, 0x45, 0x2a,
0xae, 0xfc, 0x01, 0x55, 0x90, 0x73, 0xbc, 0xc6, 0x15, 0x03, 0x77, 0xd2, 0xf2, 0xb5, 0xb8, 0x76,
0xeb, 0x3d, 0xab, 0xdf, 0xc2, 0x9d, 0x8a, 0xc3, 0xba, 0xe0, 0x1c, 0xc6, 0x71, 0xe4, 0xae, 0xf7,
0xac, 0x7e, 0x13, 0x4f, 0x43, 0xea, 0xb0, 0x01, 0x75, 0x32, 0xec, 0xfd, 0x01, 0xba, 0xc5, 0xe0,
0xb2, 0x74, 0x31, 0xb0, 0xd1, 0x9e, 0x95, 0xd9, 0x43, 0x82, 0x6d, 0x51, 0x0a, 0x6b, 0xd9, 0xf9,
0x98, 0xc4, 0xa7, 0xb0, 0x4e, 0x66, 0xe4, 0xa5, 0x68, 0x3f, 0x7e, 0x58, 0x01, 0xb8, 0x86, 0x8c,
0x67, 0xca, 0x87, 0x2d, 0x42, 0xfc, 0x57, 0x89, 0x3f, 0xf0, 0x7e, 0x5a, 0x06, 0x97, 0x72, 0x89,
0x89, 0x38, 0x0d, 0x26, 0x42, 0x9e, 0xcf, 0x69, 0x8d, 0xbc, 0xb3, 0xeb, 0x99, 0x20, 0x07, 0x5a,
0x9c, 0xd6, 0xde, 0x1f, 0x2d, 0xd8, 0x2c, 0xee, 0x47, 0x9f, 0x8c, 0xea, 0xb8, 0xc5, 0x27, 0xd2,
0xca, 0x8b, 0xe7, 0x79, 0xb9, 0x78, 0x76, 0x6e, 0xda, 0x57, 0xae, 0x9f, 0x9f, 0x81, 0xf3, 0x26,
0x08, 0x93, 0x95, 0x0a, 0xdf, 0x92, 0x10, 0xda, 0xe4, 0xae, 0x2d, 0x73, 0x51, 0x7f, 0x19, 0x2f,
0xa6, 0xa9, 0xc4, 0x90, 0x4b, 0xc2, 0x3b, 0x82, 0x16, 0xee, 0x97, 0x81, 0x7b, 0xd2, 0x58, 0x56,
0x56, 0x46, 0x3f, 0x41, 0x2e, 0x97, 0x07, 0x75, 0xa1, 0x4e, 0xca, 0x19, 0x12, 0x92, 0xf0, 0x8e,
// 1694 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x4f, 0x73, 0x1b, 0x4b,
0x11, 0xf7, 0x6a, 0x57, 0x96, 0xd4, 0x92, 0x1d, 0xbf, 0x89, 0xde, 0x63, 0x2b, 0x38, 0x7e, 0x62,
0xcb, 0xf0, 0x04, 0x45, 0x39, 0xe5, 0x90, 0xa4, 0x72, 0x01, 0x62, 0x47, 0x0e, 0xde, 0x0a, 0x36,
0x61, 0xe4, 0x72, 0x6e, 0x54, 0xad, 0xa5, 0xc1, 0xd9, 0x62, 0xa5, 0x15, 0xab, 0x55, 0x64, 0x5f,
0xa8, 0xe2, 0x33, 0xe4, 0xc2, 0x8d, 0x2b, 0x27, 0x3e, 0x04, 0x17, 0x38, 0x72, 0xa4, 0x8a, 0x0b,
0x15, 0xf8, 0x16, 0x5c, 0xa8, 0xee, 0xd9, 0xd9, 0x99, 0x5d, 0xad, 0x1d, 0x57, 0x8a, 0xdb, 0xf4,
0x9f, 0xe9, 0xe9, 0xfe, 0x75, 0x4f, 0x4f, 0xef, 0x42, 0x67, 0xb6, 0xb8, 0x88, 0xc2, 0xd1, 0xde,
0x2c, 0x89, 0xd3, 0x98, 0x35, 0xc3, 0x69, 0x2a, 0x92, 0x69, 0x10, 0x79, 0x7f, 0xb4, 0xc0, 0xe6,
0xf1, 0x92, 0xb9, 0xd0, 0x78, 0x19, 0x47, 0x8b, 0xc9, 0x74, 0xee, 0x5a, 0x3d, 0xbb, 0xef, 0x70,
0x45, 0x32, 0x06, 0xce, 0x6b, 0x71, 0x3d, 0x77, 0xed, 0x9e, 0xdd, 0x6f, 0x71, 0x5a, 0xb3, 0x5d,
0xa8, 0x1f, 0xa4, 0x69, 0x32, 0x77, 0x6b, 0x3d, 0xbb, 0xdf, 0x7e, 0xbc, 0xb9, 0xa7, 0xec, 0xed,
0x21, 0x9b, 0x4b, 0x21, 0xda, 0xe4, 0x71, 0x90, 0x84, 0xd3, 0x4b, 0xd7, 0xe9, 0x59, 0xfd, 0x0e,
0x57, 0x24, 0xeb, 0x42, 0xdd, 0x9f, 0x8e, 0xc5, 0x95, 0x5b, 0xef, 0x59, 0xfd, 0x16, 0x97, 0x04,
0x72, 0x5f, 0x85, 0x22, 0x1a, 0xbb, 0xeb, 0x92, 0x4b, 0x84, 0xb7, 0x07, 0x2d, 0x1e, 0x2f, 0x4f,
0x82, 0x34, 0x09, 0xaf, 0xd8, 0x77, 0xc0, 0xe1, 0xf1, 0x52, 0xfa, 0xd8, 0x7e, 0xbc, 0xa1, 0xcf,
0xe5, 0xf1, 0x92, 0x93, 0xc8, 0x3b, 0x81, 0xd6, 0x30, 0xbc, 0x9c, 0x8a, 0x31, 0x86, 0xf5, 0x35,
0xd8, 0x6f, 0x62, 0x54, 0xb7, 0x56, 0xd5, 0x51, 0x82, 0x0a, 0xa7, 0xe2, 0xd2, 0xad, 0x55, 0x2a,
0x9c, 0x8a, 0x4b, 0xef, 0x39, 0x6c, 0xf2, 0x78, 0xe9, 0x8f, 0xc5, 0x34, 0x0d, 0x7f, 0x1d, 0x8a,
0x84, 0x00, 0xc9, 0x7d, 0x70, 0xe4, 0xa1, 0x39, 0x48, 0x35, 0x0d, 0x92, 0xf7, 0x00, 0xd6, 0xfd,
0xc1, 0xcf, 0xc3, 0x79, 0xca, 0xb6, 0xc0, 0xf6, 0x07, 0x6a, 0x03, 0x2e, 0x3d, 0x1f, 0xbe, 0x38,
0xba, 0x4a, 0x93, 0x60, 0x94, 0x8a, 0xb1, 0x3f, 0x90, 0x50, 0xb3, 0x4d, 0xa8, 0xf9, 0x03, 0xf2,
0xd5, 0xe1, 0x35, 0x7f, 0xc0, 0x76, 0xc1, 0x39, 0x0f, 0x22, 0x05, 0xf2, 0x96, 0x76, 0x4e, 0x9a,
0xe5, 0x24, 0xf5, 0x2e, 0x0a, 0xa6, 0x32, 0x9c, 0xbe, 0x82, 0x75, 0x42, 0x4f, 0x1e, 0xda, 0xe2,
0x19, 0xc5, 0x9e, 0xea, 0x34, 0x4b, 0xab, 0xdf, 0xd6, 0x56, 0x57, 0x1c, 0xca, 0x6b, 0xc0, 0x7b,
0x08, 0x8d, 0xd7, 0xe2, 0x9a, 0x62, 0x51, 0x91, 0x5a, 0x46, 0xa4, 0xff, 0xb4, 0xe0, 0x7e, 0xbe,
0xfb, 0x2c, 0xb8, 0x88, 0xc4, 0x79, 0x10, 0x2d, 0x04, 0xdb, 0x55, 0x71, 0x5b, 0x55, 0xfe, 0x1f,
0xaf, 0x11, 0x16, 0xec, 0x9b, 0x1c, 0x3b, 0x54, 0xfb, 0x42, 0xab, 0x65, 0x47, 0x1e, 0xaf, 0x65,
0x55, 0xb7, 0x0d, 0xcd, 0xc3, 0xa1, 0x4f, 0xa6, 0x5d, 0xbb, 0x67, 0xf5, 0xed, 0xe3, 0x35, 0x9e,
0x73, 0xd8, 0x03, 0x68, 0x9c, 0x2c, 0x52, 0x71, 0xe5, 0x0f, 0xa8, 0xda, 0x9c, 0xe3, 0x35, 0xae,
0x18, 0xb8, 0x93, 0x96, 0xaf, 0xc5, 0xb5, 0x2c, 0x39, 0xdc, 0xa9, 0x38, 0xac, 0x0b, 0xce, 0x61,
0x1c, 0x47, 0x54, 0x76, 0x4d, 0x3c, 0x0d, 0xa9, 0xc3, 0x06, 0xd4, 0xc9, 0xb0, 0xf7, 0x3b, 0xe8,
0x16, 0x83, 0xcb, 0xd2, 0xc5, 0xc0, 0x46, 0x7b, 0x56, 0x66, 0x0f, 0x09, 0xb6, 0x45, 0x29, 0xac,
0x65, 0xe7, 0x63, 0x12, 0x9f, 0xc2, 0x3a, 0x99, 0x91, 0x17, 0xa8, 0xfd, 0xf8, 0x61, 0x05, 0xe0,
0x1a, 0x32, 0x9e, 0x29, 0x1f, 0xb6, 0x08, 0xf1, 0x5f, 0x24, 0xfe, 0xc0, 0xfb, 0x71, 0x19, 0x5c,
0xca, 0x25, 0x26, 0xe2, 0x34, 0x98, 0x08, 0x79, 0x3e, 0xa7, 0x35, 0xf2, 0xce, 0xae, 0x67, 0x82,
0x1c, 0x68, 0x71, 0x5a, 0x7b, 0xbf, 0xb7, 0x60, 0xb3, 0xb8, 0x1f, 0x7d, 0x32, 0xaa, 0xe3, 0x16,
0x9f, 0x48, 0x2b, 0x2f, 0x9e, 0xe7, 0xe5, 0xe2, 0xd9, 0xb9, 0x69, 0x5f, 0xb9, 0x7e, 0x7e, 0x02,
0xce, 0x9b, 0x20, 0x4c, 0x56, 0x2a, 0x7c, 0x4b, 0x42, 0x68, 0x93, 0xbb, 0xb6, 0xcc, 0x45, 0xfd,
0x65, 0xbc, 0x98, 0xa6, 0x12, 0x43, 0x2e, 0x09, 0xef, 0x08, 0x5a, 0xb8, 0x5f, 0x06, 0xee, 0x49,
0x63, 0x59, 0x59, 0x19, 0xbd, 0x07, 0xb9, 0x5c, 0x1e, 0x94, 0xb7, 0x92, 0x9a, 0xd9, 0x4a, 0x8e,
0x01, 0x50, 0x3a, 0x97, 0x76, 0x76, 0xa1, 0x4e, 0x54, 0x06, 0x42, 0xd9, 0x90, 0x14, 0xde, 0x60,
0xe9, 0x21, 0xd4, 0xfd, 0x69, 0xfa, 0xec, 0x09, 0x8a, 0x65, 0x41, 0xa2, 0x37, 0x36, 0xcf, 0x4a,
0x66, 0x01, 0x4d, 0x09, 0x5d, 0xbc, 0xd4, 0x06, 0x2c, 0xc3, 0x00, 0x72, 0xb1, 0xad, 0x0c, 0x54,
0x9c, 0x44, 0xe0, 0xb5, 0xe5, 0xf1, 0x52, 0x43, 0x92, 0x51, 0xec, 0xfb, 0xea, 0x14, 0x87, 0x62,
0xbe, 0x67, 0x5c, 0x25, 0xf4, 0x42, 0x1d, 0xfb, 0x1b, 0x80, 0x5f, 0x24, 0xf1, 0x62, 0x46, 0xa0,
0xb1, 0x3e, 0xd4, 0x89, 0xca, 0xe2, 0x63, 0x7a, 0x93, 0xf2, 0x8d, 0x4b, 0x85, 0x6a, 0xd0, 0x31,
0x39, 0xc3, 0xc5, 0x44, 0xde, 0x34, 0x8e, 0x4b, 0x2c, 0xa5, 0xe6, 0x79, 0x10, 0xe5, 0xe2, 0xf3,
0x20, 0xca, 0xe2, 0xc6, 0x65, 0xd1, 0x8c, 0xad, 0xcc, 0x3c, 0x80, 0xe6, 0xab, 0x28, 0x0e, 0x52,
0x54, 0x46, 0x5b, 0x16, 0xcf, 0x69, 0xb6, 0x0f, 0x30, 0x10, 0xa3, 0x70, 0x12, 0x44, 0x28, 0x75,
0xca, 0x0d, 0x20, 0x93, 0x71, 0x43, 0xc9, 0x7b, 0x0a, 0x8d, 0x8c, 0xaa, 0xc6, 0x1e, 0xb9, 0xc3,
0x51, 0x10, 0x09, 0xe5, 0x05, 0x11, 0xde, 0x5b, 0xd8, 0x90, 0xc5, 0x88, 0xcf, 0xcd, 0x50, 0xa4,
0x77, 0x28, 0xc5, 0x3b, 0x3d, 0x5c, 0xde, 0x9f, 0x2d, 0x70, 0x70, 0xa5, 0x0c, 0x58, 0xda, 0x80,
0x79, 0x1b, 0x1d, 0x79, 0x1b, 0x59, 0x0f, 0xda, 0xc3, 0x14, 0xdf, 0x35, 0xdd, 0xc6, 0x5a, 0xdc,
0x64, 0x21, 0x5e, 0xfe, 0x34, 0xd5, 0xe9, 0xb6, 0x79, 0x4e, 0xb3, 0x6d, 0x68, 0x61, 0x6f, 0x92,
0x42, 0x6c, 0x64, 0x4d, 0xae, 0x19, 0x6c, 0x07, 0x40, 0x21, 0xbb, 0x10, 0xd4, 0xcd, 0x2c, 0x6e,
0x70, 0xbc, 0x47, 0xd0, 0x40, 0x4f, 0x4f, 0x82, 0x99, 0x8e, 0xcd, 0xba, 0x2d, 0xb6, 0xff, 0x59,
0xd0, 0xf9, 0xf5, 0x42, 0x24, 0xd7, 0x5c, 0xfc, 0x7e, 0x21, 0xe6, 0x29, 0x62, 0x4b, 0xb4, 0xaa,
0x65, 0x22, 0xb0, 0x6a, 0x87, 0xef, 0x82, 0x64, 0x2c, 0x91, 0x72, 0x78, 0x46, 0x61, 0xac, 0x1a,
0xf3, 0x39, 0xc5, 0xda, 0xe4, 0x26, 0x8b, 0xea, 0x5d, 0x4c, 0xe2, 0x54, 0x05, 0x93, 0x51, 0xac,
0x0f, 0xf7, 0x8e, 0xae, 0x46, 0xd1, 0x62, 0x2c, 0x78, 0xbc, 0x94, 0xbb, 0xa9, 0x39, 0xf3, 0x32,
0x9b, 0xfd, 0x00, 0x9b, 0x1b, 0xb1, 0x54, 0x6b, 0x6a, 0x90, 0x62, 0x89, 0xcb, 0xf6, 0xa1, 0x73,
0x34, 0xb9, 0x10, 0xe3, 0xb1, 0x18, 0x0f, 0x82, 0x34, 0x70, 0x9b, 0x55, 0x03, 0x44, 0x41, 0xc5,
0xfb, 0x60, 0xc1, 0x46, 0x16, 0xfd, 0x7c, 0x16, 0x4f, 0xe7, 0x02, 0x53, 0x7c, 0x94, 0x24, 0x2a,
0xc5, 0x47, 0x49, 0xc2, 0x1e, 0x41, 0x83, 0x8b, 0xf9, 0x22, 0x4a, 0x55, 0x95, 0x7c, 0xa9, 0x2d,
0xaa, 0xbd, 0x8b, 0x28, 0xe5, 0x4a, 0x8b, 0xfd, 0x1c, 0x36, 0x0b, 0x75, 0xa8, 0x9e, 0x85, 0xef,
0xe8, 0x7d, 0x05, 0x39, 0x2f, 0xa9, 0x7b, 0x7f, 0xa9, 0x43, 0xdb, 0xb0, 0x9c, 0x17, 0x19, 0xe2,
0xb3, 0x91, 0x15, 0xd9, 0xd7, 0x34, 0xa7, 0xdd, 0x30, 0xf5, 0x60, 0x4f, 0xea, 0x80, 0x75, 0x9a,
0x95, 0xa5, 0x75, 0xaa, 0x1b, 0xa1, 0x7d, 0x5b, 0x23, 0xc4, 0xa9, 0xef, 0x5d, 0x30, 0xbd, 0x14,
0x63, 0x2a, 0xcb, 0x26, 0x57, 0x24, 0xdb, 0xd3, 0x5d, 0x81, 0xf2, 0x58, 0xe8, 0x35, 0x4a, 0xc2,
0x75, 0xe7, 0x90, 0x5d, 0x0e, 0x27, 0x83, 0x86, 0xac, 0x17, 0x49, 0xb1, 0x67, 0xd0, 0xd6, 0xed,
0x6b, 0x9e, 0xa5, 0xa8, 0xab, 0x4d, 0x69, 0x21, 0x37, 0x15, 0xd9, 0x8b, 0xf2, 0x88, 0xe6, 0xb6,
0xc8, 0x0b, 0xb7, 0x10, 0xb9, 0x21, 0xe7, 0xe5, 0x91, 0x6e, 0xdf, 0x98, 0x19, 0x5d, 0xa0, 0xcd,
0xf7, 0xf5, 0xe6, 0x5c, 0xc4, 0x8d, 0xc9, 0xf2, 0x89, 0xf9, 0x96, 0xb8, 0x6d, 0xda, 0xd3, 0x2d,
0x22, 0x27, 0x65, 0xdc, 0x7c, 0x73, 0xf6, 0x8d, 0x87, 0xcc, 0xed, 0x94, 0x0f, 0xca, 0x45, 0xdc,
0x78, 0xee, 0xfc, 0x8a, 0xf9, 0xce, 0xdd, 0xa0, 0xad, 0xd5, 0xc3, 0x9b, 0x54, 0xe1, 0x15, 0x53,
0xe1, 0x8b, 0xf2, 0x24, 0xe0, 0x6e, 0x96, 0x81, 0x2a, 0xca, 0x79, 0x79, 0x72, 0xd8, 0x37, 0x86,
0x71, 0xf7, 0x5e, 0xd9, 0xff, 0x5c, 0xc4, 0xb5, 0x96, 0xf7, 0xb7, 0x1a, 0x6c, 0xf8, 0x93, 0x59,
0x9c, 0xa4, 0x46, 0x17, 0xf1, 0xa7, 0x63, 0x71, 0xa5, 0xba, 0x08, 0x11, 0xd5, 0x0f, 0x2d, 0x75,
0x73, 0xec, 0x26, 0xd4, 0x3d, 0x1c, 0x2e, 0x09, 0xa3, 0x82, 0x9c, 0x42, 0x05, 0x6d, 0x43, 0x4b,
0x5e, 0x17, 0x14, 0xd5, 0x49, 0xa4, 0x19, 0xf2, 0x1b, 0x63, 0x49, 0xb3, 0x66, 0x83, 0xa6, 0x57,
0x45, 0x62, 0xe7, 0x94, 0x6a, 0x24, 0x6c, 0x92, 0xd0, 0xe0, 0xa0, 0xfc, 0x2c, 0x9c, 0x88, 0x79,
0x1a, 0x4c, 0x66, 0xd8, 0x8a, 0xec, 0xbe, 0xcd, 0x0d, 0x0e, 0x76, 0x21, 0x0a, 0xe2, 0x65, 0x22,
0x82, 0x54, 0x8c, 0x0f, 0x52, 0xaa, 0x40, 0x9b, 0x97, 0xb8, 0xa8, 0x47, 0x61, 0x69, 0x3d, 0x90,
0x7a, 0x45, 0x2e, 0xbd, 0xa4, 0x91, 0x08, 0x12, 0xaa, 0xab, 0x26, 0x97, 0x84, 0xf7, 0xcf, 0x1a,
0x30, 0x89, 0xa4, 0x9c, 0x15, 0xbf, 0x35, 0x38, 0x6f, 0x87, 0xad, 0x08, 0x4e, 0x63, 0x05, 0x9c,
0xaf, 0xf2, 0x09, 0x57, 0x02, 0x93, 0x51, 0xd8, 0xfe, 0xf5, 0xe3, 0x23, 0x51, 0xb5, 0xb8, 0xc9,
0x62, 0x1e, 0x74, 0x8c, 0x97, 0x0f, 0xaf, 0x2d, 0xda, 0x2e, 0xf0, 0x2a, 0xa0, 0x85, 0x3b, 0x42,
0xdb, 0xbe, 0x1d, 0xda, 0x8e, 0x09, 0xed, 0x07, 0x0b, 0x3a, 0x07, 0x69, 0x3c, 0x09, 0x47, 0x5c,
0x8c, 0xe2, 0x64, 0x7c, 0x33, 0xa8, 0x12, 0xbe, 0x9a, 0x09, 0xdf, 0x1e, 0xd8, 0xfe, 0xfb, 0x24,
0xeb, 0x9e, 0xdb, 0xc6, 0x6c, 0xb6, 0x92, 0x2b, 0x8e, 0x8a, 0xec, 0x1b, 0xa8, 0xf9, 0x09, 0x55,
0x6e, 0xa1, 0xef, 0x17, 0x2e, 0x09, 0xaf, 0xf9, 0x89, 0xf7, 0x63, 0xe8, 0x4a, 0xa7, 0x94, 0x28,
0x7b, 0x87, 0xba, 0x50, 0x3f, 0x4a, 0x92, 0x58, 0xbd, 0x44, 0x92, 0xf0, 0xae, 0xa0, 0x7b, 0x96,
0x04, 0xd3, 0x79, 0x14, 0xa4, 0x02, 0x13, 0xf3, 0x39, 0xf5, 0x51, 0xf5, 0x01, 0xdf, 0x83, 0xf6,
0x69, 0x9c, 0xbe, 0x4d, 0xc2, 0x94, 0x5a, 0x86, 0x6c, 0xfe, 0x26, 0xcb, 0xfb, 0x21, 0x7c, 0x59,
0x3a, 0x59, 0x3f, 0x98, 0x58, 0x52, 0xb6, 0xfe, 0xf0, 0x1d, 0xc2, 0xfd, 0x5c, 0xd5, 0x1f, 0x7c,
0x96, 0x8f, 0xab, 0x46, 0x7f, 0x64, 0x44, 0x4e, 0x46, 0xb3, 0xe3, 0x2b, 0xa2, 0xf1, 0x0e, 0xc1,
0xcd, 0xd0, 0x94, 0xff, 0x17, 0x32, 0x0f, 0xce, 0x43, 0xb1, 0xbc, 0xe9, 0x93, 0x8a, 0x06, 0x86,
0x1a, 0xfd, 0x95, 0xa0, 0xb5, 0xf7, 0x5f, 0x0b, 0xba, 0x55, 0x46, 0x74, 0x71, 0x59, 0x46, 0x71,
0xb1, 0xe7, 0x50, 0x7f, 0x1f, 0x8a, 0xa5, 0x1a, 0x11, 0xbc, 0x95, 0x94, 0xaf, 0x78, 0xc2, 0xe5,
0x06, 0xbc, 0x5a, 0x07, 0xa3, 0x34, 0x8c, 0xa7, 0xea, 0x7b, 0x40, 0x52, 0x78, 0xce, 0x61, 0x14,
0x8f, 0x7e, 0x27, 0xbf, 0x74, 0xb9, 0x24, 0x2a, 0xae, 0x4a, 0xfd, 0x8e, 0x57, 0x65, 0xbd, 0xea,
0xaa, 0x78, 0x7f, 0xb5, 0x14, 0x56, 0xc6, 0xcc, 0xf6, 0xc9, 0x8c, 0xe9, 0x0b, 0x62, 0xab, 0x0b,
0xe2, 0xca, 0xc1, 0x53, 0xcf, 0xd7, 0x8a, 0xc4, 0x61, 0x17, 0x97, 0xf4, 0x9b, 0xc3, 0xa1, 0x2c,
0xe5, 0xf4, 0x27, 0xba, 0xd2, 0x6a, 0xb0, 0xeb, 0x55, 0xc1, 0x1e, 0x6e, 0xfd, 0xfd, 0xe3, 0x8e,
0xf5, 0x8f, 0x8f, 0x3b, 0xd6, 0xbf, 0x3f, 0xee, 0x58, 0x7f, 0xfa, 0xcf, 0xce, 0xda, 0xc5, 0x3a,
0xfd, 0xd6, 0xfa, 0xc9, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xf4, 0x59, 0xf3, 0x5b, 0xe6, 0x12,
0x00, 0x00,
0xe9, 0x21, 0x36, 0xb0, 0xf4, 0xd9, 0x13, 0x14, 0xcb, 0x82, 0x44, 0x6f, 0x6c, 0x9e, 0x95, 0xcc,
0x02, 0x9a, 0x12, 0xba, 0x78, 0xa9, 0x0d, 0x58, 0x86, 0x01, 0xe4, 0x62, 0x5b, 0x19, 0xa8, 0x38,
0x89, 0xc0, 0x6b, 0xcb, 0xe3, 0xa5, 0x86, 0x24, 0xa3, 0xd8, 0x77, 0xd5, 0x29, 0x0e, 0xc5, 0x7c,
0xcf, 0xb8, 0x4a, 0xe8, 0x85, 0x3a, 0xf6, 0x57, 0x00, 0x3f, 0x4b, 0xe2, 0xc5, 0x8c, 0x40, 0x63,
0x7d, 0xa8, 0x13, 0x95, 0xc5, 0xc7, 0xf4, 0x26, 0xe5, 0x1b, 0x97, 0x0a, 0xd5, 0xa0, 0x63, 0x72,
0x86, 0x8b, 0x89, 0xbc, 0x69, 0x1c, 0x97, 0x58, 0x4a, 0xcd, 0xf3, 0x20, 0xca, 0xc5, 0xe7, 0x41,
0x94, 0xc5, 0x8d, 0xcb, 0xa2, 0x19, 0x5b, 0x99, 0x79, 0x00, 0xcd, 0x57, 0x51, 0x1c, 0xa4, 0xa8,
0x8c, 0xb6, 0x2c, 0x9e, 0xd3, 0x6c, 0x1f, 0x60, 0x20, 0x46, 0xe1, 0x24, 0x88, 0x50, 0xea, 0x94,
0x1b, 0x40, 0x26, 0xe3, 0x86, 0x92, 0xf7, 0x14, 0x1a, 0x19, 0x55, 0x8d, 0x3d, 0x72, 0x87, 0xa3,
0x20, 0x12, 0xca, 0x0b, 0x22, 0xbc, 0xb7, 0xb0, 0x21, 0x8b, 0x11, 0x9f, 0xa6, 0xa1, 0x48, 0xef,
0x50, 0x8a, 0x77, 0x7a, 0xe4, 0xbc, 0x3f, 0x59, 0xe0, 0xe0, 0x4a, 0x19, 0xb0, 0xb4, 0x01, 0xf3,
0x36, 0x3a, 0xf2, 0x36, 0xb2, 0x1e, 0xb4, 0x87, 0x29, 0xbe, 0x81, 0xba, 0x8d, 0xb5, 0xb8, 0xc9,
0x42, 0xbc, 0xfc, 0x69, 0xaa, 0xd3, 0x6d, 0xf3, 0x9c, 0x66, 0xdb, 0xd0, 0xc2, 0xde, 0x24, 0x85,
0xd8, 0xc8, 0x9a, 0x5c, 0x33, 0xd8, 0x0e, 0x80, 0x42, 0x76, 0x21, 0xa8, 0x9b, 0x59, 0xdc, 0xe0,
0x78, 0x8f, 0xa0, 0x81, 0x9e, 0x9e, 0x04, 0x33, 0x1d, 0x9b, 0x75, 0x5b, 0x6c, 0xff, 0xb5, 0xa0,
0xf3, 0xcb, 0x85, 0x48, 0xae, 0xb9, 0xf8, 0xed, 0x42, 0xcc, 0x53, 0xc4, 0x96, 0x68, 0x55, 0xcb,
0x44, 0x60, 0xd5, 0x0e, 0xdf, 0x05, 0xc9, 0x58, 0x22, 0xe5, 0xf0, 0x8c, 0xc2, 0x58, 0x35, 0xe6,
0x73, 0x8a, 0xb5, 0xc9, 0x4d, 0x16, 0xd5, 0xbb, 0x98, 0xc4, 0xa9, 0x0a, 0x26, 0xa3, 0x58, 0x1f,
0xee, 0x1d, 0x5d, 0x8d, 0xa2, 0xc5, 0x58, 0xf0, 0x78, 0x29, 0x77, 0x53, 0x73, 0xe6, 0x65, 0x36,
0xfb, 0x1e, 0x36, 0x37, 0x62, 0xa9, 0xd6, 0xd4, 0x20, 0xc5, 0x12, 0x97, 0xed, 0x43, 0xe7, 0x68,
0x72, 0x21, 0xc6, 0x63, 0x31, 0x1e, 0x04, 0x69, 0xe0, 0x36, 0xab, 0x06, 0x88, 0x82, 0x8a, 0xf7,
0xc1, 0x82, 0x8d, 0x2c, 0xfa, 0xf9, 0x2c, 0x9e, 0xce, 0x05, 0xa6, 0xf8, 0x28, 0x49, 0x54, 0x8a,
0x8f, 0x92, 0x84, 0x3d, 0x82, 0x06, 0x17, 0xf3, 0x45, 0x94, 0xaa, 0x2a, 0xf9, 0x52, 0x5b, 0x54,
0x7b, 0x17, 0x51, 0xca, 0x95, 0x16, 0xfb, 0x29, 0x6c, 0x16, 0xea, 0x50, 0x3d, 0x0b, 0xdf, 0xd2,
0xfb, 0x0a, 0x72, 0x5e, 0x52, 0xf7, 0xfe, 0x5c, 0x87, 0xb6, 0x61, 0x39, 0x2f, 0x32, 0xc4, 0x67,
0x23, 0x2b, 0xb2, 0xaf, 0x69, 0xa6, 0xbb, 0x61, 0xea, 0xc1, 0x9e, 0xd4, 0x01, 0xeb, 0x34, 0x2b,
0x4b, 0xeb, 0x54, 0x37, 0x42, 0xfb, 0xb6, 0x46, 0x88, 0x13, 0xe2, 0xbb, 0x60, 0x7a, 0x29, 0xc6,
0x54, 0x96, 0x4d, 0xae, 0x48, 0xb6, 0xa7, 0xbb, 0x02, 0xe5, 0xb1, 0xd0, 0x6b, 0x94, 0x84, 0xeb,
0xce, 0x21, 0xbb, 0x1c, 0x4e, 0x06, 0x0d, 0x59, 0x2f, 0x92, 0x62, 0xcf, 0xa0, 0xad, 0xdb, 0xd7,
0x3c, 0x4b, 0x51, 0x57, 0x9b, 0xd2, 0x42, 0x6e, 0x2a, 0xb2, 0x17, 0xe5, 0x11, 0xcd, 0x6d, 0x91,
0x17, 0x6e, 0x21, 0x72, 0x43, 0xce, 0xcb, 0x23, 0xdd, 0xbe, 0x31, 0x33, 0xba, 0x40, 0x9b, 0xef,
0xeb, 0xcd, 0xb9, 0x88, 0x1b, 0x93, 0xe5, 0x13, 0xf3, 0x2d, 0x71, 0xdb, 0xb4, 0xa7, 0x5b, 0x44,
0x4e, 0xca, 0xb8, 0xf9, 0xe6, 0xec, 0x1b, 0x0f, 0x99, 0xdb, 0x29, 0x1f, 0x94, 0x8b, 0xb8, 0xf1,
0xdc, 0xf9, 0x15, 0xf3, 0x9d, 0xbb, 0x41, 0x5b, 0xab, 0x87, 0x37, 0xa9, 0xc2, 0x2b, 0xa6, 0xc2,
0x17, 0xe5, 0x49, 0xc0, 0xdd, 0x2c, 0x03, 0x55, 0x94, 0xf3, 0xf2, 0xe4, 0xb0, 0x6f, 0x0c, 0xe3,
0xee, 0xbd, 0xb2, 0xff, 0xb9, 0x88, 0x6b, 0x2d, 0xef, 0xaf, 0x35, 0xd8, 0xf0, 0x27, 0xb3, 0x38,
0x49, 0x8d, 0x2e, 0x22, 0xa7, 0x7f, 0xab, 0x72, 0xfa, 0xaf, 0x95, 0xde, 0x49, 0xea, 0x26, 0xd4,
0x3d, 0x1c, 0x2e, 0x09, 0xa3, 0x82, 0x9c, 0x42, 0x05, 0x6d, 0x43, 0x4b, 0x5e, 0x17, 0x14, 0xd5,
0x49, 0xa4, 0x19, 0xf2, 0x7b, 0x64, 0x49, 0xb3, 0x66, 0x83, 0xa6, 0x57, 0x45, 0x62, 0xe7, 0x94,
0x6a, 0x24, 0x6c, 0x92, 0xd0, 0xe0, 0xa0, 0xfc, 0x2c, 0x9c, 0x88, 0x79, 0x1a, 0x4c, 0x66, 0xd8,
0x8a, 0xec, 0xbe, 0xcd, 0x0d, 0x0e, 0x76, 0x21, 0x0a, 0xe2, 0x65, 0x22, 0x82, 0x54, 0x8c, 0x0f,
0x52, 0xaa, 0x40, 0x9b, 0x97, 0xb8, 0xa8, 0x47, 0x61, 0x69, 0x3d, 0x90, 0x7a, 0x45, 0x2e, 0xbd,
0xa4, 0x91, 0x08, 0x12, 0xaa, 0xab, 0x26, 0x97, 0x84, 0xf7, 0x8f, 0x1a, 0x30, 0x89, 0xa4, 0x9c,
0x15, 0xff, 0x6f, 0x70, 0xde, 0x0e, 0x5b, 0x11, 0x9c, 0xc6, 0x0a, 0x38, 0x5f, 0xe5, 0x13, 0xae,
0x04, 0x26, 0xa3, 0xb0, 0xfd, 0xeb, 0xc7, 0x47, 0xa2, 0x6a, 0x71, 0x93, 0xc5, 0x3c, 0xe8, 0x18,
0x2f, 0x1f, 0x5e, 0x5b, 0xb4, 0x5d, 0xe0, 0x55, 0x40, 0x0b, 0x77, 0x84, 0xb6, 0x7d, 0x3b, 0xb4,
0x1d, 0x13, 0xda, 0x0f, 0x16, 0x74, 0x0e, 0xd2, 0x78, 0x12, 0x8e, 0xb8, 0x18, 0xc5, 0xc9, 0xf8,
0x66, 0x50, 0x25, 0x7c, 0x35, 0x13, 0xbe, 0x3d, 0xb0, 0xfd, 0xf7, 0x49, 0xd6, 0x3d, 0xb7, 0x8d,
0xd9, 0x6c, 0x25, 0x57, 0x1c, 0x15, 0xd9, 0x37, 0x50, 0xf3, 0x13, 0xaa, 0xdc, 0x42, 0xdf, 0x2f,
0x5c, 0x12, 0x5e, 0xf3, 0x13, 0xef, 0x87, 0xd0, 0x95, 0x4e, 0x29, 0x51, 0xf6, 0x0e, 0x75, 0xa1,
0x7e, 0x94, 0x24, 0xb1, 0x7a, 0x89, 0x24, 0xe1, 0x5d, 0x41, 0xf7, 0x2c, 0x09, 0xa6, 0xf3, 0x28,
0x48, 0x05, 0x26, 0xe6, 0x73, 0xea, 0xa3, 0xea, 0x63, 0xbf, 0x07, 0xed, 0xd3, 0x38, 0x7d, 0x9b,
0x84, 0x29, 0xb5, 0x0c, 0xd9, 0xfc, 0x4d, 0x96, 0xf7, 0x7d, 0xf8, 0xb2, 0x74, 0xb2, 0x7e, 0x30,
0xb1, 0xa4, 0x6c, 0xfd, 0xe1, 0x3b, 0x84, 0xfb, 0xb9, 0xaa, 0x3f, 0xf8, 0x2c, 0x1f, 0x57, 0x8d,
0xfe, 0xc0, 0x88, 0x9c, 0x8c, 0x66, 0xc7, 0x57, 0x44, 0xe3, 0x1d, 0x82, 0x9b, 0xa1, 0x29, 0xff,
0x45, 0x64, 0x1e, 0x9c, 0x87, 0x62, 0x79, 0xd3, 0x27, 0x15, 0x0d, 0x0c, 0x35, 0xfa, 0x83, 0x41,
0x6b, 0xef, 0x3f, 0x16, 0x74, 0xab, 0x8c, 0xe8, 0xe2, 0xb2, 0x8c, 0xe2, 0x62, 0xcf, 0xa1, 0xfe,
0x3e, 0x14, 0x4b, 0x35, 0x22, 0x78, 0x2b, 0x29, 0x5f, 0xf1, 0x84, 0xcb, 0x0d, 0x78, 0xb5, 0x0e,
0x46, 0x69, 0x18, 0x4f, 0xd5, 0xf7, 0x80, 0xa4, 0xf0, 0x9c, 0xc3, 0x28, 0x1e, 0xfd, 0x46, 0x7e,
0xe9, 0x72, 0x49, 0x54, 0x5c, 0x95, 0xfa, 0x1d, 0xaf, 0xca, 0x7a, 0xd5, 0x55, 0xf1, 0xfe, 0x62,
0x29, 0xac, 0x8c, 0x99, 0xed, 0x93, 0x19, 0xd3, 0x17, 0xc4, 0x56, 0x17, 0xc4, 0x95, 0x83, 0xa7,
0x9e, 0xaf, 0x15, 0x89, 0xc3, 0x2e, 0x2e, 0xe9, 0x37, 0x87, 0x43, 0x59, 0xca, 0xe9, 0x4f, 0x74,
0xa5, 0xd5, 0x60, 0xd7, 0xab, 0x82, 0x3d, 0xdc, 0xfa, 0xdb, 0xc7, 0x1d, 0xeb, 0xef, 0x1f, 0x77,
0xac, 0x7f, 0x7d, 0xdc, 0xb1, 0xfe, 0xf0, 0xef, 0x9d, 0xb5, 0x8b, 0x75, 0xfa, 0x07, 0xf6, 0xa3,
0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x2d, 0xb9, 0x97, 0xfb, 0x13, 0x13, 0x00, 0x00,
}
func (m *Row) Marshal() (dAtA []byte, err error) {
@ -2800,6 +2816,20 @@ func (m *Row) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Field) > 0 {
i -= len(m.Field)
copy(dAtA[i:], m.Field)
i = encodeVarintPublic(dAtA, i, uint64(len(m.Field)))
i--
dAtA[i] = 0x32
}
if len(m.Index) > 0 {
i -= len(m.Index)
copy(dAtA[i:], m.Index)
i = encodeVarintPublic(dAtA, i, uint64(len(m.Index)))
i--
dAtA[i] = 0x2a
}
if len(m.Roaring) > 0 {
i -= len(m.Roaring)
copy(dAtA[i:], m.Roaring)
@ -5183,6 +5213,14 @@ func (m *Row) Size() (n int) {
if l > 0 {
n += 1 + l + sovPublic(uint64(l))
}
l = len(m.Index)
if l > 0 {
n += 1 + l + sovPublic(uint64(l))
}
l = len(m.Field)
if l > 0 {
n += 1 + l + sovPublic(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
@ -6457,6 +6495,70 @@ func (m *Row) Unmarshal(dAtA []byte) error {
m.Roaring = []byte{}
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPublic
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPublic
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Index = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 6:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Field", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPublic
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthPublic
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthPublic
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Field = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipPublic(dAtA[iNdEx:])

View file

@ -7,6 +7,8 @@ message Row {
repeated string Keys = 3;
repeated Attr Attrs = 2;
bytes Roaring = 4;
string Index = 5;
string Field = 6;
}
message RowMatrix {

11
row.go
View file

@ -33,6 +33,15 @@ type Row struct {
// Attributes associated with the row.
Attrs map[string]interface{}
// Index tells what index this row is from - needed for key translation.
Index string
// Field tells what field this row is from if it's a "vertical"
// row. It may be the result of a Distinct query or Rows
// query. Knowing the index and field, we can figure out how to
// interpret the row data.
Field string
}
// NewRow returns a new instance of Row.
@ -322,7 +331,7 @@ func (r *Row) Union(others ...*Row) *Row {
output = append(output, *toProcess[0].Union(toProcess[1:]...))
}
}
return &Row{segments: output}
return &Row{Index: r.Index, Field: r.Field, segments: output}
}
// Difference returns the diff of r and other.