From 9ee5f52a11b77359e4cc0db1e4239727556837e4 Mon Sep 17 00:00:00 2001 From: Matt Jaffee Date: Wed, 23 Dec 2020 14:14:51 -0600 Subject: [PATCH] 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. --- encoding/proto/proto.go | 4 + executor.go | 184 +++++++++++++++++++---- executor_test.go | 43 ++++-- internal/public.pb.go | 314 ++++++++++++++++++++++++++-------------- internal/public.proto | 2 + row.go | 11 +- 6 files changed, 408 insertions(+), 150 deletions(-) diff --git a/encoding/proto/proto.go b/encoding/proto/proto.go index 1631e47dd..ec3e3c950 100644 --- a/encoding/proto/proto.go +++ b/encoding/proto/proto.go @@ -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() diff --git a/executor.go b/executor.go index 1668fa218..4a0fa5d27 100644 --- a/executor.go +++ b/executor.go @@ -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<=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) }) } diff --git a/internal/public.pb.go b/internal/public.pb.go index b3038896d..b334a48e3 100644 --- a/internal/public.pb.go +++ b/internal/public.pb.go @@ -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:]) diff --git a/internal/public.proto b/internal/public.proto index 6d6a56d70..9e3b4241e 100644 --- a/internal/public.proto +++ b/internal/public.proto @@ -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 { diff --git a/row.go b/row.go index 9170926a7..5e2256841 100644 --- a/row.go +++ b/row.go @@ -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.