diff --git a/pkg/sql/distsql_physical_planner.go b/pkg/sql/distsql_physical_planner.go index 81fe10e03570..a0395ff32aba 100644 --- a/pkg/sql/distsql_physical_planner.go +++ b/pkg/sql/distsql_physical_planner.go @@ -33,7 +33,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/sql/distsqlplan" "github.com/cockroachdb/cockroach/pkg/sql/distsqlrun" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" - "github.com/cockroachdb/cockroach/pkg/sql/sem/types" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/cockroachdb/cockroach/pkg/storage" "github.com/cockroachdb/cockroach/pkg/util" @@ -280,15 +279,6 @@ func newQueryNotSupportedErrorf(format string, args ...interface{}) error { var mutationsNotSupportedError = newQueryNotSupportedError("mutations not supported") var setNotSupportedError = newQueryNotSupportedError("SET / SET CLUSTER SETTING should never distribute") -// leafType returns the element type if the given type is an array, and the type -// itself otherwise. -func leafType(t types.T) types.T { - if a, ok := t.(types.TArray); ok { - return leafType(a.Typ) - } - return t -} - // checkSupportForNode returns a distRecommendation (as described above) or an // error if the plan subtree is not supported by DistSQL. // TODO(radu): add tests for this. @@ -301,11 +291,7 @@ func (dsp *DistSQLPlanner) checkSupportForNode(node planNode) (distRecommendatio return dsp.checkSupportForNode(n.source.plan) case *renderNode: - for i, e := range n.render { - typ := n.columns[i].Typ - if leafType(typ).FamilyEqual(types.FamTuple) { - return 0, newQueryNotSupportedErrorf("unsupported render type %s", typ) - } + for _, e := range n.render { if err := dsp.checkExpr(e); err != nil { return 0, err } diff --git a/pkg/sql/distsqlrun/hash_row_container.go b/pkg/sql/distsqlrun/hash_row_container.go index 0b51f7242f42..bcbcbe278bb8 100644 --- a/pkg/sql/distsqlrun/hash_row_container.go +++ b/pkg/sql/distsqlrun/hash_row_container.go @@ -417,7 +417,7 @@ func (h *hashDiskRowContainer) Init( h.columnEncoder.init(types, storedEqCols) // Provide the diskRowContainer with an ordering on the equality columns of // the rows that we will store. This will result in rows with the - // same equality columns ocurring contiguously in the keyspace. + // same equality columns occurring contiguously in the keyspace. ordering := make(sqlbase.ColumnOrdering, len(storedEqCols)) for i := range ordering { ordering[i] = sqlbase.ColumnOrderInfo{ diff --git a/pkg/sql/distsqlrun/processors.go b/pkg/sql/distsqlrun/processors.go index 78fb26049b6b..31385263b564 100644 --- a/pkg/sql/distsqlrun/processors.go +++ b/pkg/sql/distsqlrun/processors.go @@ -67,7 +67,7 @@ type ProcOutputHelper struct { // // If renderExprs is set, these types correspond to the types of those // expressions. - // If outpuCols is set, these types correspond to the types of + // If outputCols is set, these types correspond to the types of // those columns. // If neither is set, this is the internal schema of the processor. outputTypes []sqlbase.ColumnType diff --git a/pkg/sql/distsqlrun/version_history.txt b/pkg/sql/distsqlrun/version_history.txt index 435df5b60bb6..f99bacdd59a3 100644 --- a/pkg/sql/distsqlrun/version_history.txt +++ b/pkg/sql/distsqlrun/version_history.txt @@ -62,3 +62,6 @@ - Enhancements to lookup joins. They now support joining against secondary indexes as well as left outer joins. Left join support required two additional fields on JoinReaderSpec: index_filter_expr and type. +- Version: 15 (MinAcceptedVersion: 6) + - Add support for processing queries with tuples in DistSQL. Old versions + would not recognize the new tuple field in the proto. diff --git a/pkg/sql/logictest/testdata/logic_test/select b/pkg/sql/logictest/testdata/logic_test/select index a9ef31502f6b..a0936021e637 100644 --- a/pkg/sql/logictest/testdata/logic_test/select +++ b/pkg/sql/logictest/testdata/logic_test/select @@ -249,7 +249,7 @@ SELECT * FROM xyzw ORDER BY x OFFSET 1 + 0.0 ---- 4 5 6 7 -query T +query T rowsort SELECT (x,y) FROM xyzw ---- (1,2) diff --git a/pkg/sql/sem/tree/datum.go b/pkg/sql/sem/tree/datum.go index 201661e56a7f..db1e30e1c934 100644 --- a/pkg/sql/sem/tree/datum.go +++ b/pkg/sql/sem/tree/datum.go @@ -2609,6 +2609,10 @@ func (*DTuple) AmbiguousFormat() bool { return false } // Format implements the NodeFormatter interface. // TODO(bram): We don't format tuples in the same way as postgres. See #25522. func (d *DTuple) Format(ctx *FmtCtx) { + if ctx.HasFlags(FmtParsable) && (len(d.D) == 0) { + ctx.WriteString("ROW()") + return + } ctx.FormatNode(&d.D) } diff --git a/pkg/sql/sem/tree/format_test.go b/pkg/sql/sem/tree/format_test.go index 60d1f3f13713..10040ae8b7b6 100644 --- a/pkg/sql/sem/tree/format_test.go +++ b/pkg/sql/sem/tree/format_test.go @@ -194,6 +194,8 @@ func TestFormatExpr(t *testing.T) { `unique_rowid() + 123:::INT`}, {`sqrt(123.0) + 456`, tree.FmtParsable, `sqrt(123.0:::DECIMAL) + 456:::DECIMAL`}, + {`ROW()`, tree.FmtParsable, `ROW()`}, + {`ROW()`, tree.FmtSimple, `()`}, {`now() + interval '3s'`, tree.FmtSimple, `now() + '3s'`}, {`now() + interval '3s'`, tree.FmtParsable, diff --git a/pkg/sql/sqlbase/encoded_datum.go b/pkg/sql/sqlbase/encoded_datum.go index a7c62138dd7b..f63c08dc8bd1 100644 --- a/pkg/sql/sqlbase/encoded_datum.go +++ b/pkg/sql/sqlbase/encoded_datum.go @@ -203,7 +203,7 @@ func (ed *EncDatum) EnsureDecoded(typ *ColumnType, a *DatumAlloc) error { panic(fmt.Sprintf("unknown encoding %s", ed.encoding)) } if err != nil { - return err + return errors.Wrapf(err, "error decoding %d bytes", len(ed.encoded)) } if len(rem) != 0 { ed.Datum = nil diff --git a/pkg/sql/sqlbase/encoded_datum_test.go b/pkg/sql/sqlbase/encoded_datum_test.go index cc0bfe4acd9f..5165a213e22f 100644 --- a/pkg/sql/sqlbase/encoded_datum_test.go +++ b/pkg/sql/sqlbase/encoded_datum_test.go @@ -20,6 +20,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/sql/sem/types" "github.com/cockroachdb/cockroach/pkg/util/encoding" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/randutil" @@ -481,3 +482,40 @@ func TestEncDatumRowAlloc(t *testing.T) { } } } + +func TestValueEncodeDecodeTuple(t *testing.T) { + rng, seed := randutil.NewPseudoRand() + tests := make([]tree.Datum, 1000) + colTypes := make([]ColumnType, 1000) + + for i := range tests { + colTypes[i] = ColumnType{SemanticType: ColumnType_TUPLE} + + len := rng.Intn(5) + colTypes[i].TupleContents = make([]ColumnType, len) + for j := range colTypes[i].TupleContents { + colTypes[i].TupleContents[j] = RandColumnType(rng) + } + tests[i] = RandDatum(rng, colTypes[i], true) + } + + for i, test := range tests { + + buf, err := encodeTuple(test.(*tree.DTuple), nil, encoding.NoColumnID, nil) + if err != nil { + t.Fatalf("seed %d: encoding tuple %v with types %v failed with error: %v", + seed, test, colTypes[i], err) + } + var decodedTuple tree.Datum + decodedTuple, buf, err = decodeTuple(&DatumAlloc{}, test.ResolvedType().(types.TTuple), buf) + if err != nil { + t.Fatalf("seed %d: decoding tuple %v with types %v failed with error: %v", + seed, test, colTypes[i], err) + } + + if cmp := decodedTuple.Compare(&tree.EvalContext{}, test); cmp != 0 { + t.Fatalf("seed %d: encoded %+v, decoded %+v, expected equal, received comparison: %d", seed, test, decodedTuple, cmp) + } + } + +} diff --git a/pkg/sql/sqlbase/structured.go b/pkg/sql/sqlbase/structured.go index 867a5ccc83a1..7406c9b7e7cb 100644 --- a/pkg/sql/sqlbase/structured.go +++ b/pkg/sql/sqlbase/structured.go @@ -652,7 +652,7 @@ func DatumTypeHasCompositeKeyEncoding(typ types.T) bool { // MustBeValueEncoded returns true if columns of the given kind can only be value // encoded. func MustBeValueEncoded(semanticType ColumnType_SemanticType) bool { - return semanticType == ColumnType_ARRAY || semanticType == ColumnType_JSON + return semanticType == ColumnType_ARRAY || semanticType == ColumnType_JSON || semanticType == ColumnType_TUPLE } // HasOldStoredColumns returns whether the index has stored columns in the old @@ -2305,6 +2305,9 @@ func DatumTypeToColumnSemanticType(ptyp types.T) (ColumnType_SemanticType, error if ptyp.FamilyEqual(types.FamCollatedString) { return ColumnType_COLLATEDSTRING, nil } + if ptyp.FamilyEqual(types.FamTuple) { + return ColumnType_TUPLE, nil + } if wrapper, ok := ptyp.(types.TOidWrapper); ok { return DatumTypeToColumnSemanticType(wrapper.T) } @@ -2330,6 +2333,17 @@ func DatumTypeToColumnType(ptyp types.T) (ColumnType, error) { cs := t.Typ.(types.TCollatedString) ctyp.Locale = &cs.Locale } + case types.TTuple: + ctyp.SemanticType = ColumnType_TUPLE + ctyp.TupleContents = make([]ColumnType, len(t.Types)) + for i, tc := range t.Types { + var err error + ctyp.TupleContents[i], err = DatumTypeToColumnType(tc) + if err != nil { + return ColumnType{}, err + } + } + return ctyp, nil default: semanticType, err := DatumTypeToColumnSemanticType(ptyp) if err != nil { @@ -2372,6 +2386,8 @@ func columnSemanticTypeToDatumType(c *ColumnType, k ColumnType_SemanticType) typ return types.INet case ColumnType_JSON: return types.JSON + case ColumnType_TUPLE: + return types.FamTuple case ColumnType_COLLATEDSTRING: if c.Locale == nil { panic("locale is required for COLLATEDSTRING") @@ -2397,6 +2413,14 @@ func (c *ColumnType) ToDatumType() types.T { switch c.SemanticType { case ColumnType_ARRAY: return types.TArray{Typ: columnSemanticTypeToDatumType(c, *c.ArrayContents)} + case ColumnType_TUPLE: + datums := types.TTuple{ + Types: make([]types.T, len(c.TupleContents)), + } + for i := range c.TupleContents { + datums.Types[i] = c.TupleContents[i].ToDatumType() + } + return datums default: return columnSemanticTypeToDatumType(c, c.SemanticType) } diff --git a/pkg/sql/sqlbase/structured.pb.go b/pkg/sql/sqlbase/structured.pb.go index d645c8dce4f2..59e226ba8b2d 100644 --- a/pkg/sql/sqlbase/structured.pb.go +++ b/pkg/sql/sqlbase/structured.pb.go @@ -78,6 +78,7 @@ const ( ColumnType_TIME ColumnType_SemanticType = 17 ColumnType_JSON ColumnType_SemanticType = 18 ColumnType_TIMETZ ColumnType_SemanticType = 19 + ColumnType_TUPLE ColumnType_SemanticType = 20 ColumnType_INT2VECTOR ColumnType_SemanticType = 200 ColumnType_OIDVECTOR ColumnType_SemanticType = 201 ) @@ -103,6 +104,7 @@ var ColumnType_SemanticType_name = map[int32]string{ 17: "TIME", 18: "JSON", 19: "TIMETZ", + 20: "TUPLE", 200: "INT2VECTOR", 201: "OIDVECTOR", } @@ -127,6 +129,7 @@ var ColumnType_SemanticType_value = map[string]int32{ "TIME": 17, "JSON": 18, "TIMETZ": 19, + "TUPLE": 20, "INT2VECTOR": 200, "OIDVECTOR": 201, } @@ -530,6 +533,8 @@ type ColumnType struct { VisibleType ColumnType_VisibleType `protobuf:"varint,6,opt,name=visible_type,json=visibleType,enum=cockroach.sql.sqlbase.ColumnType_VisibleType" json:"visible_type"` // Only used if the kind is ARRAY. ArrayContents *ColumnType_SemanticType `protobuf:"varint,7,opt,name=array_contents,json=arrayContents,enum=cockroach.sql.sqlbase.ColumnType_SemanticType" json:"array_contents,omitempty"` + // Only used if the kind is TUPLE + TupleContents []ColumnType `protobuf:"bytes,8,rep,name=tuple_contents,json=tupleContents" json:"tuple_contents"` } func (m *ColumnType) Reset() { *m = ColumnType{} } @@ -1715,6 +1720,14 @@ func (this *ColumnType) Equal(that interface{}) bool { } else if that1.ArrayContents != nil { return false } + if len(this.TupleContents) != len(that1.TupleContents) { + return false + } + for i := range this.TupleContents { + if !this.TupleContents[i].Equal(&that1.TupleContents[i]) { + return false + } + } return true } func (m *ColumnType) Marshal() (dAtA []byte, err error) { @@ -1762,6 +1775,18 @@ func (m *ColumnType) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintStructured(dAtA, i, uint64(*m.ArrayContents)) } + if len(m.TupleContents) > 0 { + for _, msg := range m.TupleContents { + dAtA[i] = 0x42 + i++ + i = encodeVarintStructured(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -2887,6 +2912,12 @@ func (m *ColumnType) Size() (n int) { if m.ArrayContents != nil { n += 1 + sovStructured(uint64(*m.ArrayContents)) } + if len(m.TupleContents) > 0 { + for _, e := range m.TupleContents { + l = e.Size() + n += 1 + l + sovStructured(uint64(l)) + } + } return n } @@ -3557,6 +3588,37 @@ func (m *ColumnType) Unmarshal(dAtA []byte) error { } } m.ArrayContents = &v + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TupleContents", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructured + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStructured + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TupleContents = append(m.TupleContents, ColumnType{}) + if err := m.TupleContents[len(m.TupleContents)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipStructured(dAtA[iNdEx:]) @@ -7742,191 +7804,192 @@ var ( func init() { proto.RegisterFile("sql/sqlbase/structured.proto", fileDescriptorStructured) } var fileDescriptorStructured = []byte{ - // 2967 bytes of a gzipped FileDescriptorProto + // 2986 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x59, 0x5b, 0x6f, 0xe3, 0xc6, - 0x15, 0x36, 0x75, 0xd7, 0xd1, 0x8d, 0x9e, 0xbd, 0x84, 0xab, 0x6c, 0x6c, 0xaf, 0x92, 0x4d, 0x9d, + 0x15, 0x36, 0x75, 0xd7, 0xd1, 0x8d, 0x9e, 0xbd, 0x44, 0xab, 0x6c, 0x6c, 0xaf, 0x92, 0x4d, 0x9d, 0x9b, 0xbc, 0xf1, 0xa6, 0x6d, 0x90, 0x16, 0x41, 0x25, 0x91, 0xde, 0xa5, 0x57, 0x96, 0xbc, 0x94, 0xec, 0xcd, 0x06, 0x69, 0x09, 0x5a, 0x1c, 0xdb, 0xcc, 0x52, 0xa4, 0x96, 0xa4, 0x1c, 0xeb, 0x1f, - 0xe4, 0xb1, 0x0f, 0x05, 0x8a, 0xbe, 0x04, 0x41, 0xd0, 0xb7, 0xfe, 0x81, 0xfe, 0x84, 0x2d, 0xd0, - 0x87, 0xa2, 0x4f, 0x7d, 0xe9, 0xa2, 0x75, 0x51, 0xa0, 0xbf, 0xa0, 0x0f, 0x01, 0x0a, 0x14, 0x33, - 0x9c, 0xa1, 0x28, 0xdf, 0xa2, 0xdd, 0x7d, 0x13, 0xcf, 0x9c, 0xf3, 0xcd, 0x9c, 0x33, 0xe7, 0x7c, - 0x73, 0x66, 0x04, 0x37, 0xfd, 0xa7, 0xf6, 0x9a, 0xff, 0xd4, 0xde, 0x33, 0x7c, 0xbc, 0xe6, 0x07, - 0xde, 0x78, 0x10, 0x8c, 0x3d, 0x6c, 0xd6, 0x47, 0x9e, 0x1b, 0xb8, 0xe8, 0xda, 0xc0, 0x1d, 0x3c, - 0xf1, 0x5c, 0x63, 0x70, 0x58, 0xf7, 0x9f, 0xda, 0x75, 0xa6, 0x57, 0x95, 0xc6, 0x81, 0x65, 0xaf, - 0x1d, 0xda, 0x83, 0xb5, 0xc0, 0x1a, 0x62, 0x3f, 0x30, 0x86, 0xa3, 0xd0, 0xa0, 0xfa, 0x7a, 0x1c, - 0x6e, 0xe4, 0x59, 0x47, 0x96, 0x8d, 0x0f, 0x30, 0x1b, 0xbc, 0x7a, 0xe0, 0x1e, 0xb8, 0xf4, 0xe7, - 0x1a, 0xf9, 0x15, 0x4a, 0x6b, 0xbf, 0xcf, 0x00, 0xb4, 0x5c, 0x7b, 0x3c, 0x74, 0xfa, 0x93, 0x11, - 0x46, 0x8f, 0xa1, 0xe4, 0xe3, 0xa1, 0xe1, 0x04, 0xd6, 0x40, 0x0f, 0x26, 0x23, 0x2c, 0x09, 0x2b, - 0xc2, 0x6a, 0x79, 0xbd, 0x5e, 0x3f, 0x77, 0x29, 0xf5, 0xa9, 0x65, 0xbd, 0xc7, 0xcc, 0xc8, 0x47, - 0x33, 0xf5, 0xec, 0xf9, 0xf2, 0x82, 0x56, 0xf4, 0x63, 0x32, 0x54, 0x85, 0xf4, 0x57, 0x96, 0x19, - 0x1c, 0x4a, 0x89, 0x15, 0x61, 0x35, 0xcd, 0x54, 0x42, 0x11, 0xaa, 0x41, 0x7e, 0xe4, 0xe1, 0x81, - 0xe5, 0x5b, 0xae, 0x23, 0x25, 0x63, 0xe3, 0x53, 0x31, 0x7a, 0x07, 0x44, 0xc3, 0xf3, 0x8c, 0x89, - 0x6e, 0x5a, 0x43, 0xec, 0x10, 0x91, 0x2f, 0xa5, 0x56, 0x92, 0xab, 0x69, 0xad, 0x42, 0xe5, 0x72, - 0x24, 0x46, 0xd7, 0x21, 0x63, 0xbb, 0x03, 0xc3, 0xc6, 0x52, 0x7a, 0x45, 0x58, 0xcd, 0x6b, 0xec, - 0x0b, 0xed, 0x42, 0xf1, 0xc8, 0xf2, 0xad, 0x3d, 0x1b, 0x87, 0xce, 0x65, 0xa8, 0x73, 0x1f, 0xfc, - 0xb0, 0x73, 0xbb, 0xa1, 0x55, 0xcc, 0xb7, 0xc2, 0xd1, 0x54, 0x84, 0x76, 0xa0, 0x1c, 0x2e, 0x6d, - 0xe0, 0x3a, 0x01, 0x76, 0x02, 0x5f, 0xca, 0xbe, 0x4c, 0xd8, 0xb4, 0x12, 0x45, 0x69, 0x31, 0x90, - 0xda, 0xef, 0x12, 0x50, 0x8c, 0x8f, 0xa3, 0x1c, 0xa4, 0x9a, 0xdd, 0x6e, 0x5b, 0x5c, 0x40, 0x59, - 0x48, 0xaa, 0x9d, 0xbe, 0x28, 0xa0, 0x3c, 0xa4, 0x37, 0xda, 0xdd, 0x46, 0x5f, 0x4c, 0xa0, 0x02, - 0x64, 0x65, 0xa5, 0xa5, 0x6e, 0x35, 0xda, 0x62, 0x92, 0xa8, 0xca, 0x8d, 0xbe, 0x22, 0xa6, 0x50, - 0x09, 0xf2, 0x7d, 0x75, 0x4b, 0xe9, 0xf5, 0x1b, 0x5b, 0xdb, 0x62, 0x1a, 0x15, 0x21, 0xa7, 0x76, - 0xfa, 0x8a, 0xb6, 0xdb, 0x68, 0x8b, 0x19, 0x04, 0x90, 0xe9, 0xf5, 0x35, 0xb5, 0x73, 0x4f, 0xcc, - 0x12, 0xa8, 0xe6, 0xe3, 0xbe, 0xd2, 0x13, 0x73, 0xa8, 0x02, 0x85, 0xc8, 0xa6, 0xff, 0xb9, 0x98, - 0x47, 0x08, 0xca, 0xad, 0x6e, 0xbb, 0xdd, 0xe8, 0x2b, 0x32, 0xd3, 0x07, 0x32, 0x45, 0xa7, 0xb1, - 0xa5, 0x88, 0x05, 0xb2, 0x9a, 0xae, 0x2a, 0x8b, 0x45, 0x2a, 0xda, 0x69, 0xb7, 0xc5, 0x12, 0xf9, - 0xb5, 0xb3, 0xa3, 0xca, 0x62, 0x99, 0xc0, 0x36, 0x34, 0xad, 0xf1, 0x58, 0xac, 0x10, 0xa1, 0xda, - 0x51, 0xfa, 0xa2, 0x48, 0x7e, 0x91, 0x09, 0xc4, 0x45, 0xf2, 0x6b, 0xb3, 0xd7, 0xed, 0x88, 0x88, - 0xac, 0x85, 0xc8, 0xfa, 0x9f, 0x8b, 0x57, 0x50, 0x05, 0x40, 0xed, 0xf4, 0xd7, 0x77, 0x95, 0x56, - 0xbf, 0xab, 0x89, 0xcf, 0x04, 0x54, 0x86, 0x7c, 0x57, 0x95, 0xd9, 0xf7, 0x9f, 0x84, 0xda, 0x01, - 0x14, 0x62, 0x9b, 0x42, 0x27, 0xee, 0x76, 0x14, 0x71, 0x81, 0x44, 0x81, 0xf8, 0x77, 0x4f, 0xd1, - 0x44, 0x81, 0x38, 0xdb, 0xdb, 0x6a, 0xb4, 0xdb, 0x24, 0x56, 0x09, 0x32, 0x41, 0x53, 0xbd, 0x47, - 0x7e, 0x27, 0xc9, 0x92, 0x9b, 0x6a, 0x5f, 0x4c, 0x11, 0x4b, 0x4d, 0x69, 0xb4, 0xc5, 0x34, 0xba, - 0x0a, 0xa2, 0xdc, 0xdd, 0x69, 0xb6, 0x15, 0x7d, 0x5b, 0x53, 0x5a, 0x6a, 0x4f, 0xed, 0x76, 0xc4, - 0xcc, 0x27, 0xa9, 0xff, 0x7c, 0xbb, 0x2c, 0xd4, 0xfe, 0x9b, 0x84, 0x2b, 0x1b, 0xae, 0x87, 0xad, - 0x03, 0xe7, 0x01, 0x9e, 0x68, 0x78, 0x1f, 0x7b, 0xd8, 0x19, 0x60, 0xb4, 0x02, 0xe9, 0xc0, 0xd8, - 0xb3, 0xc3, 0x3a, 0x29, 0x35, 0x81, 0xe4, 0xc6, 0xf7, 0xcf, 0x97, 0x13, 0xaa, 0xac, 0x85, 0x03, - 0xe8, 0x36, 0xa4, 0x2d, 0xc7, 0xc4, 0xc7, 0x34, 0xed, 0x4b, 0xcd, 0x0a, 0xd3, 0xc8, 0xaa, 0x44, - 0x48, 0xd4, 0xe8, 0x28, 0x92, 0x20, 0xe5, 0x18, 0x43, 0x4c, 0x93, 0x3f, 0xcf, 0x72, 0x8c, 0x4a, - 0xd0, 0x03, 0xc8, 0x1d, 0x19, 0xb6, 0x65, 0x5a, 0xc1, 0x44, 0x4a, 0xd1, 0xb4, 0x7a, 0xe7, 0xc2, - 0xb4, 0x72, 0xfc, 0xc0, 0x33, 0x2c, 0x27, 0xd8, 0x65, 0x06, 0x0c, 0x28, 0x02, 0x40, 0x77, 0x60, - 0xd1, 0x3f, 0x34, 0x3c, 0x6c, 0xea, 0x23, 0x0f, 0xef, 0x5b, 0xc7, 0xba, 0x8d, 0x1d, 0x5a, 0x24, - 0xbc, 0xe0, 0x2a, 0xe1, 0xf0, 0x36, 0x1d, 0x6d, 0x63, 0x07, 0xf5, 0x21, 0xef, 0x3a, 0xba, 0x89, - 0x6d, 0x1c, 0xf0, 0x82, 0xf9, 0xf0, 0x82, 0xf9, 0xcf, 0x09, 0x50, 0xbd, 0x31, 0x08, 0x2c, 0xd7, - 0xe1, 0xeb, 0x70, 0x1d, 0x99, 0x02, 0x31, 0xd4, 0xf1, 0xc8, 0x34, 0x02, 0xcc, 0x8a, 0xe5, 0x55, - 0x50, 0x77, 0x28, 0x50, 0xed, 0x21, 0x64, 0xc2, 0x11, 0x92, 0xf4, 0x9d, 0xae, 0xde, 0x68, 0xf5, - 0xc9, 0x26, 0x2e, 0x90, 0x3c, 0xd0, 0x14, 0x92, 0xb8, 0xad, 0x3e, 0xcb, 0x0a, 0xa5, 0xaf, 0xd3, - 0x4c, 0x4d, 0x90, 0x5c, 0x27, 0x5f, 0xb2, 0xb2, 0xd1, 0xd8, 0x69, 0x93, 0xd4, 0x28, 0x40, 0xb6, - 0xd5, 0xe8, 0xb5, 0x1a, 0xb2, 0x22, 0xa6, 0x6a, 0x7f, 0x4f, 0x80, 0x18, 0x96, 0xab, 0x8c, 0xfd, - 0x81, 0x67, 0x8d, 0x02, 0xd7, 0x8b, 0x36, 0x4b, 0x38, 0xb3, 0x59, 0x6f, 0x43, 0xc2, 0x32, 0xd9, - 0x56, 0x5f, 0x27, 0xf2, 0x13, 0x9a, 0x0c, 0xdf, 0x3f, 0x5f, 0xce, 0x85, 0x28, 0xaa, 0xac, 0x25, - 0x2c, 0x13, 0xfd, 0x0c, 0x52, 0x94, 0x81, 0xc8, 0x76, 0x17, 0xd6, 0x6f, 0xfd, 0x20, 0x4f, 0xf0, - 0x49, 0x88, 0x11, 0x5a, 0x81, 0x9c, 0x33, 0xb6, 0x6d, 0x9a, 0x77, 0x24, 0x23, 0x72, 0x3c, 0x10, - 0x5c, 0x8a, 0x6e, 0x41, 0xd1, 0xc4, 0xfb, 0xc6, 0xd8, 0x0e, 0x74, 0x7c, 0x3c, 0xf2, 0x18, 0x0d, - 0x16, 0x98, 0x4c, 0x39, 0x1e, 0x79, 0xe8, 0x26, 0x64, 0x0e, 0x2d, 0xd3, 0xc4, 0x0e, 0xdd, 0x54, - 0x0e, 0xc1, 0x64, 0x68, 0x1d, 0x16, 0xc7, 0x3e, 0xf6, 0x75, 0x1f, 0x3f, 0x1d, 0x93, 0x88, 0xeb, - 0x96, 0xe9, 0x4b, 0xb0, 0x92, 0x5c, 0x2d, 0x35, 0x33, 0x2c, 0xbf, 0x2b, 0x44, 0xa1, 0xc7, 0xc6, - 0x55, 0xd3, 0x27, 0x93, 0x0e, 0xdc, 0xe1, 0x68, 0x1c, 0xe0, 0x70, 0xd2, 0x42, 0x38, 0x29, 0x93, - 0x91, 0x49, 0x37, 0x53, 0xb9, 0x9c, 0x98, 0xdf, 0x4c, 0xe5, 0xf2, 0x22, 0x6c, 0xa6, 0x72, 0x59, - 0x31, 0x57, 0xfb, 0x3a, 0x01, 0xd7, 0x43, 0x37, 0x37, 0x8c, 0xa1, 0x65, 0x4f, 0x5e, 0x35, 0xca, - 0x21, 0x0a, 0x8b, 0x32, 0x5d, 0x11, 0xc1, 0xd6, 0x89, 0x99, 0x2f, 0x25, 0x57, 0x92, 0xe1, 0x8a, - 0x88, 0xac, 0x43, 0x44, 0xe8, 0x63, 0x00, 0xa6, 0x42, 0x3c, 0x4c, 0x51, 0x0f, 0x6f, 0x9c, 0x3c, - 0x5f, 0xce, 0xf3, 0xed, 0xf2, 0x67, 0xf6, 0x2e, 0x1f, 0x2a, 0x13, 0x77, 0xbb, 0xb0, 0xc8, 0x63, - 0x1c, 0x21, 0xd0, 0x40, 0x97, 0x9a, 0x6f, 0xb2, 0x35, 0x55, 0xe4, 0x50, 0x81, 0x9b, 0xcf, 0x40, - 0x55, 0xcc, 0x99, 0x41, 0xb3, 0xf6, 0x87, 0x04, 0x5c, 0x55, 0x9d, 0x00, 0x7b, 0x36, 0x36, 0x8e, - 0x70, 0x2c, 0x10, 0x9f, 0x41, 0xde, 0x70, 0x06, 0xd8, 0x0f, 0x5c, 0xcf, 0x97, 0x84, 0x95, 0xe4, - 0x6a, 0x61, 0xfd, 0xa3, 0x0b, 0x32, 0xe6, 0x3c, 0xfb, 0x7a, 0x83, 0x19, 0xf3, 0x33, 0x35, 0x02, - 0xab, 0xfe, 0x51, 0x80, 0x1c, 0x1f, 0x45, 0x77, 0x20, 0x47, 0x29, 0x8b, 0xf8, 0x11, 0xd2, 0xd9, - 0x35, 0xe6, 0x47, 0xb6, 0x4f, 0xe4, 0x74, 0xfd, 0x64, 0xe7, 0xb3, 0x54, 0x4d, 0x35, 0xd1, 0x8f, - 0x21, 0x47, 0xd9, 0x4b, 0x8f, 0x76, 0xa3, 0xca, 0x2d, 0x18, 0xbd, 0xc5, 0x99, 0x2e, 0x4b, 0x75, - 0x55, 0x13, 0xb5, 0xce, 0x23, 0xa1, 0x24, 0xb5, 0x7f, 0x8d, 0x47, 0xae, 0x37, 0x4b, 0x43, 0x67, - 0x78, 0xa9, 0xf6, 0xef, 0x24, 0x5c, 0xdf, 0x36, 0xbc, 0xc0, 0x22, 0xf5, 0x6e, 0x39, 0x07, 0xb1, - 0x78, 0xdd, 0x86, 0x82, 0x33, 0x1e, 0xb2, 0x5d, 0xf1, 0x99, 0x2f, 0xa1, 0xef, 0xe0, 0x8c, 0x87, - 0x61, 0xc0, 0x7d, 0xd4, 0x86, 0x94, 0x6d, 0xf9, 0x81, 0x94, 0xa0, 0x11, 0x5d, 0xbf, 0x20, 0xa2, - 0xe7, 0xcf, 0x51, 0x6f, 0x5b, 0x7e, 0xc0, 0x73, 0x92, 0xa0, 0xa0, 0x2e, 0xa4, 0x3d, 0xc3, 0x39, - 0xc0, 0x34, 0xc9, 0x0a, 0xeb, 0x77, 0x5f, 0x0c, 0x4e, 0x23, 0xa6, 0xbc, 0x27, 0xa2, 0x38, 0xd5, - 0xdf, 0x0a, 0x90, 0x22, 0xb3, 0x5c, 0x52, 0x07, 0xd7, 0x21, 0x73, 0x64, 0xd8, 0x63, 0xec, 0x53, - 0x1f, 0x8a, 0x1a, 0xfb, 0x42, 0xbf, 0x84, 0x8a, 0x3f, 0xde, 0x1b, 0xc5, 0xa6, 0x62, 0x44, 0xf3, - 0xc1, 0x0b, 0xad, 0x2a, 0x3a, 0x12, 0x66, 0xb1, 0xaa, 0x4f, 0x20, 0x4d, 0xd7, 0x7b, 0xc9, 0xca, - 0x6e, 0x41, 0x31, 0x70, 0x75, 0x7c, 0x3c, 0xb0, 0xc7, 0xbe, 0x75, 0x84, 0x69, 0x76, 0x14, 0xb5, - 0x42, 0xe0, 0x2a, 0x5c, 0x84, 0x6e, 0x43, 0x79, 0xdf, 0x73, 0x87, 0xba, 0xe5, 0x70, 0xa5, 0x24, - 0x55, 0x2a, 0x11, 0xa9, 0xca, 0x85, 0xb5, 0xff, 0xe5, 0xa0, 0x42, 0x33, 0x68, 0x2e, 0x66, 0xb8, - 0x1d, 0x63, 0x86, 0x6b, 0x33, 0xcc, 0x10, 0xa5, 0x21, 0x21, 0x86, 0x9b, 0x90, 0x19, 0x3b, 0xd6, - 0xd3, 0x71, 0x38, 0x67, 0x44, 0x7e, 0xa1, 0xec, 0x0c, 0x6d, 0xa4, 0xce, 0xd2, 0xc6, 0xfb, 0x80, - 0x48, 0xcd, 0x60, 0x7d, 0x46, 0x31, 0x4d, 0x15, 0x45, 0x3a, 0xd2, 0xba, 0x90, 0x64, 0x32, 0x2f, - 0x40, 0x32, 0xf7, 0x41, 0xc4, 0xc7, 0x81, 0x67, 0xe8, 0x31, 0xfb, 0x2c, 0xb5, 0x5f, 0x3a, 0x79, - 0xbe, 0x5c, 0x56, 0xc8, 0xd8, 0xf9, 0x20, 0x65, 0x1c, 0x1b, 0x33, 0x49, 0x4e, 0x2c, 0x32, 0x0c, - 0xd3, 0xf2, 0x30, 0x3d, 0x25, 0x7d, 0x29, 0xb7, 0x92, 0x5c, 0x2d, 0xaf, 0xdf, 0xb9, 0x90, 0x4c, - 0x66, 0xc2, 0x5e, 0x97, 0xb9, 0xa1, 0x26, 0x86, 0x50, 0x91, 0xc0, 0x47, 0x0f, 0xa1, 0xb0, 0x1f, - 0x1e, 0xd4, 0xfa, 0x13, 0x3c, 0x91, 0xf2, 0x34, 0xdd, 0xde, 0x9d, 0xff, 0x48, 0xe7, 0xf5, 0xb9, - 0x1f, 0x0d, 0xa1, 0x1d, 0x28, 0x79, 0x7c, 0xd8, 0xd4, 0xf7, 0x26, 0xf4, 0xfc, 0x79, 0x19, 0xd0, - 0xe2, 0x14, 0xa6, 0x39, 0x41, 0x0f, 0x01, 0xac, 0x88, 0x25, 0xe9, 0x21, 0x55, 0x58, 0x7f, 0xef, - 0x05, 0xe8, 0x94, 0xaf, 0x74, 0x0a, 0x82, 0x1e, 0x41, 0x79, 0xfa, 0x45, 0x97, 0x5a, 0x7c, 0xc9, - 0xa5, 0x96, 0x62, 0x38, 0xcd, 0x09, 0xea, 0xc3, 0x55, 0x72, 0x7c, 0xba, 0xbe, 0x15, 0xe0, 0x78, - 0x0a, 0x94, 0x68, 0x0a, 0xd4, 0x4e, 0x9e, 0x2f, 0xa3, 0x16, 0x1f, 0x3f, 0x3f, 0x0d, 0xd0, 0xe0, - 0xd4, 0x78, 0x98, 0x54, 0x33, 0xc9, 0x4b, 0x10, 0xcb, 0xd3, 0xa4, 0xea, 0x4d, 0xd3, 0xf7, 0x4c, - 0x52, 0xc5, 0x52, 0x9b, 0x20, 0x3d, 0x82, 0xe2, 0x0c, 0xcb, 0x54, 0x5e, 0x9e, 0x65, 0x66, 0x80, - 0x90, 0xc2, 0xfa, 0x23, 0x91, 0xb6, 0x86, 0xef, 0xcd, 0x99, 0xa0, 0xa7, 0x3b, 0xa5, 0xda, 0x12, - 0xe4, 0xa3, 0x1c, 0x25, 0x2d, 0x7f, 0xa3, 0xd7, 0x12, 0x17, 0xe8, 0xdd, 0x48, 0xe9, 0xb5, 0x44, - 0xa1, 0x76, 0x0b, 0x52, 0xf4, 0xfa, 0x50, 0x80, 0xec, 0x46, 0x57, 0x7b, 0xd4, 0xd0, 0xe4, 0xb0, - 0x59, 0x54, 0x3b, 0xbb, 0x8a, 0xd6, 0x57, 0x64, 0x51, 0xa8, 0x7d, 0x97, 0x02, 0x34, 0x9d, 0x62, - 0x6b, 0x1c, 0x18, 0x14, 0xac, 0x01, 0x99, 0x30, 0x7a, 0x94, 0x84, 0x0a, 0xeb, 0x3f, 0xba, 0xb4, - 0x85, 0x9b, 0x02, 0xdc, 0x5f, 0xd0, 0x98, 0x21, 0xfa, 0x34, 0x7e, 0x33, 0x28, 0xac, 0xbf, 0x3d, - 0x9f, 0x93, 0xf7, 0x17, 0xf8, 0x95, 0xe1, 0x01, 0xa4, 0xfd, 0x80, 0xf4, 0xcf, 0x49, 0x1a, 0xa4, - 0xb5, 0x0b, 0xec, 0xcf, 0x2e, 0xbe, 0xde, 0x23, 0x66, 0xfc, 0xb4, 0xa1, 0x18, 0xe8, 0x11, 0xe4, - 0x23, 0x5e, 0x60, 0xd7, 0x8c, 0xbb, 0xf3, 0x03, 0x46, 0x41, 0xe6, 0x2d, 0x46, 0x84, 0x85, 0x1a, - 0x50, 0x18, 0x32, 0xb5, 0x69, 0x83, 0xb4, 0xc2, 0xa8, 0x19, 0x38, 0x02, 0xa5, 0xe8, 0xd8, 0x97, - 0x06, 0xdc, 0x48, 0x35, 0x49, 0xbf, 0xeb, 0xb9, 0xb6, 0xbd, 0x67, 0x0c, 0x9e, 0xd0, 0xbb, 0x42, - 0xd4, 0xef, 0x72, 0x69, 0xed, 0x17, 0x90, 0xa6, 0x3e, 0x91, 0x8d, 0xdc, 0xe9, 0x3c, 0xe8, 0x74, - 0x1f, 0x91, 0xae, 0xbf, 0x02, 0x05, 0x59, 0x69, 0x2b, 0x7d, 0x45, 0xef, 0x76, 0xda, 0x8f, 0x45, - 0x01, 0xdd, 0x80, 0x6b, 0x4c, 0xd0, 0xe8, 0xc8, 0xfa, 0x23, 0x4d, 0xe5, 0x43, 0x89, 0xda, 0x6a, - 0x3c, 0x53, 0xa6, 0xb7, 0x49, 0x92, 0x33, 0xb2, 0x2c, 0x0a, 0x34, 0x67, 0xb4, 0xee, 0xb6, 0x98, - 0x68, 0x16, 0x01, 0xcc, 0x28, 0x02, 0x9b, 0xa9, 0x5c, 0x46, 0xcc, 0xd6, 0xfe, 0x2c, 0x41, 0x85, - 0xf6, 0x48, 0x73, 0x1d, 0x52, 0x2b, 0xf4, 0x90, 0x0a, 0x1b, 0x1e, 0x71, 0xe6, 0x90, 0x4a, 0xb0, - 0xf3, 0xe9, 0x2e, 0xe4, 0x47, 0x86, 0x87, 0x9d, 0x80, 0x84, 0x2c, 0x35, 0xd3, 0xe7, 0xe6, 0xb6, - 0xe9, 0x40, 0xa4, 0x9e, 0x0b, 0x15, 0x55, 0x62, 0x94, 0x3d, 0xc2, 0x1e, 0x7d, 0x42, 0x09, 0xa3, - 0x7c, 0x83, 0xdd, 0x35, 0x17, 0xa7, 0xab, 0xda, 0x0d, 0x15, 0x34, 0xae, 0x89, 0xde, 0x04, 0x18, - 0x8f, 0x74, 0x6e, 0x17, 0xbf, 0x0a, 0xe4, 0xc7, 0x23, 0xa6, 0x8d, 0xb6, 0x61, 0x71, 0xe8, 0x9a, - 0xd6, 0xbe, 0x35, 0x08, 0xf7, 0x31, 0xb0, 0x86, 0xe1, 0xad, 0xad, 0xb0, 0xfe, 0x46, 0x2c, 0x49, - 0xc6, 0x81, 0x65, 0xd7, 0x0f, 0xed, 0x41, 0xbd, 0xcf, 0xdf, 0xa5, 0x18, 0x94, 0x18, 0xb7, 0x26, - 0x83, 0xe8, 0x1e, 0x64, 0x79, 0x7b, 0x96, 0xa3, 0x54, 0x39, 0x6f, 0xfd, 0x30, 0x44, 0x6e, 0x8d, - 0x36, 0xa0, 0xec, 0xe0, 0xe3, 0x78, 0x0b, 0x9e, 0x9f, 0xc9, 0xb0, 0x62, 0x07, 0x1f, 0x9f, 0xdf, - 0x7f, 0x17, 0x9d, 0xe9, 0x88, 0x89, 0x1e, 0x42, 0x69, 0xe4, 0x59, 0x43, 0xc3, 0x9b, 0xe8, 0x61, - 0x51, 0xc2, 0x8b, 0x14, 0x65, 0xc4, 0x61, 0x21, 0x04, 0x1d, 0x45, 0x1b, 0x10, 0x76, 0xbc, 0xd8, - 0x97, 0x0a, 0xd4, 0xc7, 0x17, 0x03, 0xe3, 0xc6, 0xa8, 0x09, 0x25, 0xea, 0x62, 0xd4, 0x6a, 0x17, - 0xa9, 0x87, 0x4b, 0xcc, 0xc3, 0x02, 0xf1, 0xf0, 0x9c, 0x76, 0xbb, 0xe0, 0x44, 0x72, 0x13, 0x6d, - 0x02, 0x44, 0xef, 0x81, 0xe4, 0xf8, 0xb8, 0xec, 0x74, 0xde, 0xe6, 0x8a, 0xd3, 0x25, 0x69, 0x31, - 0x6b, 0xb4, 0x05, 0x79, 0x5e, 0x9c, 0xe1, 0xb9, 0x51, 0xb8, 0xf0, 0x45, 0xe2, 0x2c, 0x55, 0xf0, - 0xe4, 0x8a, 0x10, 0x50, 0x07, 0xd2, 0x36, 0x36, 0x7c, 0xcc, 0x0e, 0x8f, 0x8f, 0x2f, 0x80, 0x3a, - 0x55, 0x5e, 0xf5, 0xde, 0xe0, 0x10, 0x0f, 0x8d, 0xd6, 0x21, 0x69, 0x44, 0xdb, 0xc4, 0x5e, 0x0b, - 0x61, 0x50, 0x07, 0x44, 0x1a, 0xae, 0x38, 0xeb, 0x88, 0x34, 0x62, 0x6f, 0xb1, 0x88, 0x95, 0x49, - 0xc4, 0x2e, 0x64, 0x1e, 0x9a, 0x4f, 0x5b, 0x53, 0xf6, 0xf9, 0x39, 0x94, 0xf7, 0x5d, 0x6f, 0x68, - 0x04, 0x51, 0x95, 0x2c, 0x4e, 0xdb, 0xcb, 0xef, 0x9f, 0x2f, 0x97, 0x36, 0xe8, 0x28, 0xaf, 0xac, - 0xd2, 0x7e, 0xfc, 0x13, 0xdd, 0xe7, 0x24, 0x7d, 0x85, 0x72, 0xea, 0xfb, 0xf3, 0x7a, 0x77, 0x96, - 0xa1, 0x3b, 0x90, 0x19, 0x1c, 0xe2, 0xc1, 0x13, 0x5f, 0xba, 0x4a, 0x63, 0xfe, 0x93, 0x39, 0xa1, - 0x5a, 0xc4, 0x68, 0xfa, 0x34, 0xa4, 0x31, 0x14, 0xf4, 0x05, 0x94, 0x4d, 0x22, 0xb1, 0x9c, 0x03, - 0xd6, 0xbe, 0x5e, 0xa3, 0xb8, 0x6b, 0x73, 0xe2, 0x92, 0xd6, 0x56, 0x75, 0xf6, 0x5d, 0xde, 0xb9, - 0x70, 0xb0, 0xb0, 0xe5, 0xed, 0x42, 0x6e, 0x9f, 0x5c, 0xc5, 0x2d, 0xec, 0x4b, 0xd7, 0x29, 0xee, - 0xe5, 0xcf, 0xac, 0xa7, 0x6f, 0xff, 0x9c, 0xe2, 0x39, 0x48, 0x54, 0xe8, 0x54, 0x30, 0x21, 0x9b, - 0xfa, 0xda, 0xd9, 0x42, 0xe7, 0xb7, 0xff, 0x99, 0x97, 0x00, 0x5a, 0xe8, 0xec, 0xcb, 0x24, 0x84, - 0x77, 0x64, 0xe1, 0xaf, 0xf4, 0xa7, 0x63, 0xec, 0x4d, 0x24, 0x29, 0x46, 0xce, 0x79, 0x22, 0x7f, - 0x48, 0xc4, 0xe8, 0x43, 0xc8, 0x9b, 0x78, 0x84, 0x1d, 0xd3, 0xef, 0x3a, 0xd2, 0x0d, 0xda, 0x1a, - 0x5d, 0x21, 0xfd, 0xba, 0xcc, 0x85, 0x8c, 0x7c, 0xa7, 0x5a, 0xe8, 0x4b, 0x28, 0x86, 0x1f, 0xd8, - 0xec, 0x3a, 0xcd, 0x89, 0x54, 0xa5, 0x4e, 0xdf, 0x99, 0x33, 0x98, 0xd3, 0x3e, 0xf0, 0x2a, 0xf7, - 0x47, 0x8e, 0xa1, 0x69, 0x33, 0xd8, 0xe8, 0x0b, 0x28, 0xf2, 0xec, 0xde, 0x74, 0xf7, 0x7c, 0xe9, - 0xf5, 0x4b, 0x6f, 0xb0, 0xa7, 0xe7, 0xda, 0x9a, 0x9a, 0x72, 0xde, 0x8a, 0xa3, 0xa1, 0xcf, 0xa0, - 0x14, 0x3d, 0xfb, 0xb8, 0xa3, 0xc0, 0x97, 0x6e, 0xd2, 0xc2, 0xbc, 0x3b, 0x6f, 0xea, 0x32, 0xdb, - 0xee, 0x28, 0xf0, 0xb5, 0xa2, 0x1f, 0xfb, 0x42, 0xb7, 0x20, 0x6f, 0x7a, 0xee, 0x28, 0x3c, 0x3f, - 0xde, 0x58, 0x11, 0x56, 0x93, 0x7c, 0x9b, 0x89, 0x98, 0x1e, 0x0c, 0x3a, 0x94, 0x3d, 0x3c, 0xb2, - 0x8d, 0x01, 0x1e, 0x92, 0xe3, 0xcf, 0xdd, 0x97, 0x96, 0xe8, 0xec, 0xeb, 0x73, 0x07, 0x32, 0x32, - 0xe6, 0x89, 0x19, 0xc3, 0xeb, 0xee, 0xa3, 0x1d, 0x00, 0x63, 0x6c, 0x5a, 0x81, 0x3e, 0x74, 0x4d, - 0x2c, 0x2d, 0xd3, 0xaa, 0x9c, 0x77, 0x97, 0x1a, 0xc4, 0x70, 0xcb, 0x35, 0x71, 0xf4, 0x92, 0xc2, - 0x05, 0xd5, 0xef, 0x04, 0x58, 0x3c, 0x43, 0x49, 0xe8, 0x57, 0x90, 0x75, 0x5c, 0x33, 0xf6, 0xa2, - 0xa2, 0xb0, 0xdd, 0xcd, 0x74, 0x5c, 0x33, 0x7c, 0x50, 0xb9, 0x7b, 0x60, 0x05, 0x87, 0xe3, 0xbd, - 0xfa, 0xc0, 0x1d, 0xae, 0x45, 0xab, 0x30, 0xf7, 0xa6, 0xbf, 0xd7, 0x46, 0x4f, 0x0e, 0xd6, 0xe8, - 0xaf, 0xd1, 0x5e, 0x3d, 0x34, 0xd3, 0x32, 0x04, 0x55, 0x35, 0xd1, 0x07, 0x50, 0xc1, 0xc7, 0x23, - 0xcb, 0x8b, 0x1d, 0xcb, 0x89, 0x58, 0x58, 0xcb, 0xd3, 0x41, 0x12, 0xdc, 0xea, 0x5f, 0x05, 0xa8, - 0x9c, 0xa2, 0x03, 0xd2, 0xa6, 0xd0, 0xd7, 0xba, 0x99, 0x36, 0x85, 0x48, 0xa2, 0x06, 0x26, 0x71, - 0xe9, 0x93, 0x74, 0xf2, 0x55, 0x9f, 0xa4, 0x67, 0x2f, 0xc7, 0xe9, 0xf9, 0x2f, 0xc7, 0x9b, 0xa9, - 0x5c, 0x4a, 0x4c, 0x57, 0x1f, 0x43, 0x8e, 0x53, 0xd1, 0x6c, 0xdf, 0x24, 0xcc, 0xd9, 0x37, 0x5d, - 0xe8, 0x67, 0xf5, 0x1b, 0x01, 0xf2, 0xf1, 0xb7, 0xfe, 0x44, 0x84, 0x7a, 0x7e, 0xdb, 0xf6, 0x92, - 0xef, 0x61, 0xb3, 0x11, 0x48, 0xce, 0x1f, 0x81, 0xea, 0x11, 0x14, 0x62, 0xd5, 0x7c, 0xba, 0xd7, - 0x16, 0x5e, 0xa2, 0xd7, 0x7e, 0x0b, 0x32, 0x5f, 0xba, 0x7b, 0xdc, 0x81, 0x64, 0xb3, 0xc4, 0xac, - 0xd3, 0x9b, 0xee, 0x9e, 0x2a, 0x6b, 0xe9, 0x2f, 0xdd, 0x3d, 0xd5, 0xac, 0xfe, 0x46, 0x80, 0x62, - 0xbc, 0xce, 0x51, 0x0d, 0xf2, 0x96, 0x33, 0xf0, 0x68, 0x91, 0xd1, 0x79, 0x79, 0x0a, 0x4e, 0xc5, - 0xa4, 0xfa, 0x87, 0x96, 0xa3, 0xd3, 0x37, 0xaa, 0x99, 0x34, 0xcd, 0x0d, 0x2d, 0x67, 0x97, 0x48, - 0xa9, 0x8a, 0x71, 0xcc, 0x54, 0x92, 0x33, 0x2a, 0xc6, 0x71, 0xa8, 0x52, 0xa5, 0x07, 0xaa, 0x17, - 0xd0, 0xb6, 0x38, 0x19, 0x3b, 0x22, 0xbd, 0xa0, 0x7a, 0x08, 0x85, 0x58, 0xfd, 0xcf, 0xb1, 0x61, - 0x3f, 0x85, 0x54, 0x54, 0x34, 0x73, 0xf6, 0xb2, 0xd4, 0xa0, 0xf6, 0x36, 0xbf, 0x70, 0x00, 0x64, - 0xb6, 0x77, 0x9a, 0x6d, 0xb5, 0x75, 0xee, 0x65, 0x81, 0x5c, 0x2b, 0x22, 0xd2, 0x20, 0x17, 0x4b, - 0x59, 0xed, 0x35, 0x9a, 0x6d, 0x85, 0x5c, 0x33, 0x4b, 0x90, 0xd7, 0x94, 0x86, 0x4c, 0x6f, 0x21, - 0xa2, 0xf0, 0x49, 0xea, 0xeb, 0x6f, 0x97, 0x85, 0xcd, 0x54, 0x0e, 0x89, 0x57, 0x6a, 0xdf, 0x09, - 0x80, 0x64, 0x23, 0x30, 0x48, 0x09, 0xbd, 0xc0, 0x8d, 0x22, 0x71, 0x89, 0xa7, 0xb3, 0x0d, 0x60, - 0xf2, 0x55, 0x1a, 0xc0, 0x70, 0xa9, 0xb5, 0x6f, 0x04, 0x80, 0xd8, 0xe2, 0x3e, 0x8d, 0xff, 0x13, - 0x76, 0x71, 0xaf, 0x7b, 0x8a, 0x52, 0xc9, 0x6d, 0x36, 0xfc, 0x9f, 0xec, 0x1e, 0xe4, 0x4c, 0xe6, - 0x32, 0xdb, 0x8e, 0x0b, 0x9b, 0xca, 0x33, 0x91, 0xb9, 0x4f, 0x4e, 0x10, 0x26, 0x6d, 0x66, 0x21, - 0x3d, 0x76, 0x2c, 0xd7, 0x79, 0xf7, 0x23, 0x40, 0x67, 0xe9, 0x87, 0x84, 0x9d, 0xfe, 0x36, 0x02, - 0x6c, 0x86, 0x77, 0xc4, 0x1d, 0xe7, 0x28, 0x12, 0x08, 0xcd, 0x5b, 0xcf, 0xfe, 0xb9, 0xb4, 0xf0, - 0xec, 0x64, 0x49, 0xf8, 0xcb, 0xc9, 0x92, 0xf0, 0xb7, 0x93, 0x25, 0xe1, 0x1f, 0x27, 0x4b, 0xc2, - 0xaf, 0xff, 0xb5, 0xb4, 0xf0, 0x79, 0x96, 0x2d, 0xe0, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x24, - 0xd0, 0xcb, 0x1e, 0xb6, 0x1f, 0x00, 0x00, + 0xe4, 0xb1, 0x0f, 0x05, 0xfa, 0x16, 0x04, 0x41, 0xdf, 0xfa, 0x07, 0xfa, 0x13, 0xb6, 0x40, 0x1f, + 0x8a, 0x3e, 0xf5, 0xa5, 0x46, 0xeb, 0xa2, 0x40, 0x7f, 0x41, 0x1f, 0x02, 0x14, 0x2d, 0x66, 0x38, + 0x43, 0x51, 0xb6, 0xe5, 0xc8, 0xbb, 0x6f, 0xe2, 0x99, 0x73, 0xbe, 0x99, 0x73, 0xe6, 0x5c, 0x47, + 0x70, 0xdb, 0x7b, 0x6e, 0xad, 0x79, 0xcf, 0xad, 0x3d, 0xdd, 0xc3, 0x6b, 0x9e, 0xef, 0x8e, 0xfa, + 0xfe, 0xc8, 0xc5, 0x46, 0x6d, 0xe8, 0x3a, 0xbe, 0x83, 0x6e, 0xf4, 0x9d, 0xfe, 0x33, 0xd7, 0xd1, + 0xfb, 0x87, 0x35, 0xef, 0xb9, 0x55, 0x63, 0x7c, 0x95, 0xf2, 0xc8, 0x37, 0xad, 0xb5, 0x43, 0xab, + 0xbf, 0xe6, 0x9b, 0x03, 0xec, 0xf9, 0xfa, 0x60, 0x18, 0x08, 0x54, 0x5e, 0x8f, 0xc2, 0x0d, 0x5d, + 0xf3, 0xc8, 0xb4, 0xf0, 0x01, 0x66, 0x8b, 0xd7, 0x0f, 0x9c, 0x03, 0x87, 0xfe, 0x5c, 0x23, 0xbf, + 0x02, 0x6a, 0xf5, 0x7f, 0x29, 0x80, 0xa6, 0x63, 0x8d, 0x06, 0x76, 0x6f, 0x3c, 0xc4, 0xe8, 0x29, + 0x14, 0x3c, 0x3c, 0xd0, 0x6d, 0xdf, 0xec, 0x6b, 0xfe, 0x78, 0x88, 0xcb, 0xc2, 0x8a, 0xb0, 0x5a, + 0x5c, 0xaf, 0xd5, 0x2e, 0x3c, 0x4a, 0x6d, 0x22, 0x59, 0xeb, 0x32, 0x31, 0xf2, 0xd1, 0x48, 0xbc, + 0x38, 0x59, 0x5e, 0x50, 0xf3, 0x5e, 0x84, 0x86, 0x2a, 0x90, 0xfc, 0xca, 0x34, 0xfc, 0xc3, 0x72, + 0x6c, 0x45, 0x58, 0x4d, 0x32, 0x96, 0x80, 0x84, 0xaa, 0x90, 0x1d, 0xba, 0xb8, 0x6f, 0x7a, 0xa6, + 0x63, 0x97, 0xe3, 0x91, 0xf5, 0x09, 0x19, 0xbd, 0x03, 0xa2, 0xee, 0xba, 0xfa, 0x58, 0x33, 0xcc, + 0x01, 0xb6, 0x09, 0xc9, 0x2b, 0x27, 0x56, 0xe2, 0xab, 0x49, 0xb5, 0x44, 0xe9, 0x52, 0x48, 0x46, + 0x37, 0x21, 0x65, 0x39, 0x7d, 0xdd, 0xc2, 0xe5, 0xe4, 0x8a, 0xb0, 0x9a, 0x55, 0xd9, 0x17, 0xda, + 0x85, 0xfc, 0x91, 0xe9, 0x99, 0x7b, 0x16, 0x0e, 0x94, 0x4b, 0x51, 0xe5, 0x3e, 0xf8, 0x61, 0xe5, + 0x76, 0x03, 0xa9, 0x88, 0x6e, 0xb9, 0xa3, 0x09, 0x09, 0xed, 0x40, 0x31, 0x38, 0x5a, 0xdf, 0xb1, + 0x7d, 0x6c, 0xfb, 0x5e, 0x39, 0xfd, 0x32, 0x66, 0x53, 0x0b, 0x14, 0xa5, 0xc9, 0x40, 0x50, 0x1b, + 0x8a, 0xfe, 0x68, 0x68, 0xe1, 0x09, 0x6c, 0x66, 0x25, 0xbe, 0x9a, 0x5b, 0xbf, 0xf3, 0x83, 0xb0, + 0xec, 0x90, 0x05, 0x2a, 0xce, 0xf1, 0xaa, 0xbf, 0x8b, 0x41, 0x3e, 0xba, 0x1f, 0xca, 0x40, 0xa2, + 0xd1, 0xe9, 0xb4, 0xc4, 0x05, 0x94, 0x86, 0xb8, 0xd2, 0xee, 0x89, 0x02, 0xca, 0x42, 0x72, 0xa3, + 0xd5, 0xa9, 0xf7, 0xc4, 0x18, 0xca, 0x41, 0x5a, 0x92, 0x9b, 0xca, 0x56, 0xbd, 0x25, 0xc6, 0x09, + 0xab, 0x54, 0xef, 0xc9, 0x62, 0x02, 0x15, 0x20, 0xdb, 0x53, 0xb6, 0xe4, 0x6e, 0xaf, 0xbe, 0xb5, + 0x2d, 0x26, 0x51, 0x1e, 0x32, 0x4a, 0xbb, 0x27, 0xab, 0xbb, 0xf5, 0x96, 0x98, 0x42, 0x00, 0xa9, + 0x6e, 0x4f, 0x55, 0xda, 0x0f, 0xc4, 0x34, 0x81, 0x6a, 0x3c, 0xed, 0xc9, 0x5d, 0x31, 0x83, 0x4a, + 0x90, 0x0b, 0x65, 0x7a, 0x9f, 0x8b, 0x59, 0x84, 0xa0, 0xd8, 0xec, 0xb4, 0x5a, 0xf5, 0x9e, 0x2c, + 0x31, 0x7e, 0x20, 0x5b, 0xb4, 0xeb, 0x5b, 0xb2, 0x98, 0x23, 0xa7, 0xe9, 0x28, 0x92, 0x98, 0xa7, + 0xa4, 0x9d, 0x56, 0x4b, 0x2c, 0x90, 0x5f, 0x3b, 0x3b, 0x8a, 0x24, 0x16, 0x09, 0x6c, 0x5d, 0x55, + 0xeb, 0x4f, 0xc5, 0x12, 0x21, 0x2a, 0x6d, 0xb9, 0x27, 0x8a, 0xe4, 0x17, 0xd9, 0x40, 0x5c, 0x24, + 0xbf, 0x36, 0xbb, 0x9d, 0xb6, 0x88, 0xc8, 0x59, 0x08, 0xad, 0xf7, 0xb9, 0x78, 0x8d, 0x08, 0xf5, + 0x76, 0xb6, 0x5b, 0xb2, 0x78, 0x1d, 0x95, 0x00, 0x94, 0x76, 0x6f, 0x7d, 0x57, 0x6e, 0xf6, 0x3a, + 0xaa, 0xf8, 0x42, 0x40, 0x45, 0xc8, 0x76, 0x14, 0x89, 0x7d, 0xff, 0x51, 0xa8, 0x1e, 0x40, 0x2e, + 0x72, 0xdf, 0xf4, 0x0c, 0x9d, 0xb6, 0x2c, 0x2e, 0x10, 0x83, 0x10, 0x55, 0x1f, 0xc8, 0xaa, 0x28, + 0x10, 0xbd, 0xbb, 0x5b, 0xf5, 0x56, 0x8b, 0x98, 0x2d, 0x46, 0xf6, 0x6a, 0x28, 0x0f, 0xc8, 0xef, + 0x38, 0x39, 0x7d, 0x43, 0xe9, 0x89, 0x09, 0x22, 0xa9, 0xca, 0xf5, 0x96, 0x98, 0x44, 0xd7, 0x41, + 0x94, 0x3a, 0x3b, 0x8d, 0x96, 0xac, 0x6d, 0xab, 0x72, 0x53, 0xe9, 0x2a, 0x9d, 0xb6, 0x98, 0xfa, + 0x24, 0xf1, 0xef, 0x6f, 0x97, 0x85, 0xea, 0x7f, 0xe2, 0x70, 0x6d, 0xc3, 0x71, 0xb1, 0x79, 0x60, + 0x3f, 0xc2, 0x63, 0x15, 0xef, 0x63, 0x17, 0xdb, 0x7d, 0x8c, 0x56, 0x20, 0xe9, 0xeb, 0x7b, 0x56, + 0x10, 0x82, 0x85, 0x06, 0x90, 0x1b, 0xfd, 0xfe, 0x64, 0x39, 0xa6, 0x48, 0x6a, 0xb0, 0x80, 0xee, + 0x42, 0xd2, 0xb4, 0x0d, 0x7c, 0x4c, 0x23, 0xaa, 0xd0, 0x28, 0x31, 0x8e, 0xb4, 0x42, 0x88, 0x84, + 0x8d, 0xae, 0xa2, 0x32, 0x24, 0x6c, 0x7d, 0x80, 0x69, 0x5c, 0x65, 0x99, 0x67, 0x50, 0x0a, 0x7a, + 0x04, 0x99, 0x23, 0xdd, 0x32, 0x0d, 0xd3, 0x1f, 0x97, 0x13, 0xd4, 0x63, 0xdf, 0x99, 0xe9, 0x5a, + 0xb6, 0xe7, 0xbb, 0xba, 0x69, 0xfb, 0xbb, 0x4c, 0x80, 0x01, 0x85, 0x00, 0xe8, 0x1e, 0x2c, 0x7a, + 0x87, 0xba, 0x8b, 0x0d, 0x6d, 0xe8, 0xe2, 0x7d, 0xf3, 0x58, 0xb3, 0xb0, 0x4d, 0xe3, 0x8f, 0xc7, + 0x72, 0x29, 0x58, 0xde, 0xa6, 0xab, 0x2d, 0x6c, 0xa3, 0x1e, 0x64, 0x1d, 0x5b, 0x33, 0xb0, 0x85, + 0x7d, 0x1e, 0x8b, 0x1f, 0xce, 0xd8, 0xff, 0x02, 0x03, 0xd5, 0xea, 0x7d, 0xdf, 0x74, 0x6c, 0x7e, + 0x0e, 0xc7, 0x96, 0x28, 0x10, 0x43, 0x1d, 0x0d, 0x0d, 0xdd, 0xc7, 0x2c, 0x0e, 0x5f, 0x05, 0x75, + 0x87, 0x02, 0x55, 0x1f, 0x43, 0x2a, 0x58, 0x21, 0xfe, 0xdf, 0xee, 0x68, 0xf5, 0x66, 0x8f, 0x5c, + 0xe2, 0x02, 0xf1, 0x03, 0x55, 0x26, 0x3e, 0xdc, 0xec, 0x31, 0xaf, 0x90, 0x7b, 0x1a, 0x75, 0xda, + 0x18, 0x71, 0x7b, 0xf2, 0x25, 0xc9, 0x1b, 0xf5, 0x9d, 0x16, 0x71, 0x8d, 0x1c, 0xa4, 0x9b, 0xf5, + 0x6e, 0xb3, 0x2e, 0xc9, 0x62, 0xa2, 0xfa, 0xb7, 0x18, 0x88, 0x41, 0xc8, 0x4a, 0xd8, 0xeb, 0xbb, + 0xe6, 0xd0, 0x77, 0xdc, 0xf0, 0xb2, 0x84, 0x73, 0x97, 0xf5, 0x36, 0xc4, 0x4c, 0x83, 0x5d, 0xf5, + 0x4d, 0x42, 0x3f, 0xa5, 0xce, 0xf0, 0xfd, 0xc9, 0x72, 0x26, 0x40, 0x51, 0x24, 0x35, 0x66, 0x1a, + 0xe8, 0x67, 0x90, 0xa0, 0xc9, 0x8d, 0x5c, 0xf7, 0x15, 0x72, 0x05, 0x15, 0x42, 0x2b, 0x90, 0xb1, + 0x47, 0x96, 0x45, 0xfd, 0x8e, 0x78, 0x44, 0x86, 0x1b, 0x82, 0x53, 0xd1, 0x1d, 0xc8, 0x1b, 0x78, + 0x5f, 0x1f, 0x59, 0xbe, 0x86, 0x8f, 0x87, 0x2e, 0xcb, 0xb0, 0x39, 0x46, 0x93, 0x8f, 0x87, 0x2e, + 0xba, 0x0d, 0xa9, 0x43, 0xd3, 0x30, 0xb0, 0x4d, 0x2f, 0x95, 0x43, 0x30, 0x1a, 0x5a, 0x87, 0xc5, + 0x91, 0x87, 0x3d, 0xcd, 0xc3, 0xcf, 0x47, 0xc4, 0xe2, 0x9a, 0x69, 0x78, 0x65, 0x58, 0x89, 0xaf, + 0x16, 0x1a, 0x29, 0xe6, 0xdf, 0x25, 0xc2, 0xd0, 0x65, 0xeb, 0x8a, 0xe1, 0x91, 0x4d, 0xfb, 0xce, + 0x60, 0x38, 0xf2, 0x71, 0xb0, 0x69, 0x2e, 0xd8, 0x94, 0xd1, 0xc8, 0xa6, 0x9b, 0x89, 0x4c, 0x46, + 0xcc, 0x6e, 0x26, 0x32, 0x59, 0x11, 0x36, 0x13, 0x99, 0xb4, 0x98, 0xa9, 0x7e, 0x1d, 0x83, 0x9b, + 0x81, 0x9a, 0x1b, 0xfa, 0xc0, 0xb4, 0xc6, 0xaf, 0x6a, 0xe5, 0x00, 0x85, 0x59, 0x99, 0x9e, 0x88, + 0x60, 0x6b, 0x44, 0xcc, 0x2b, 0xc7, 0x57, 0xe2, 0xc1, 0x89, 0x08, 0xad, 0x4d, 0x48, 0xe8, 0x63, + 0x00, 0xc6, 0x42, 0x34, 0x4c, 0x50, 0x0d, 0x6f, 0x9d, 0x9e, 0x2c, 0x67, 0xf9, 0x75, 0x79, 0x53, + 0x77, 0x97, 0x0d, 0x98, 0x89, 0xba, 0x1d, 0x58, 0xe4, 0x36, 0x0e, 0x11, 0xa8, 0xa1, 0x0b, 0x8d, + 0x37, 0xd9, 0x99, 0x4a, 0x52, 0xc0, 0xc0, 0xc5, 0xa7, 0xa0, 0x4a, 0xc6, 0xd4, 0xa2, 0x51, 0xfd, + 0x7d, 0x0c, 0xae, 0x2b, 0xb6, 0x8f, 0x5d, 0x0b, 0xeb, 0x47, 0x38, 0x62, 0x88, 0xcf, 0x20, 0xab, + 0xdb, 0x7d, 0xec, 0xf9, 0x8e, 0xeb, 0x95, 0x05, 0x5a, 0x5d, 0x3e, 0x9a, 0xe1, 0x31, 0x17, 0xc9, + 0xd7, 0xea, 0x4c, 0x98, 0x97, 0xeb, 0x10, 0xac, 0xf2, 0x07, 0x01, 0x32, 0x7c, 0x15, 0xdd, 0x83, + 0x0c, 0x4d, 0x59, 0x44, 0x8f, 0x20, 0x9d, 0xdd, 0x60, 0x7a, 0xa4, 0x7b, 0x84, 0x4e, 0xcf, 0x4f, + 0x6e, 0x3e, 0x4d, 0xd9, 0x14, 0x03, 0xfd, 0x18, 0x32, 0x34, 0x7b, 0x69, 0xe1, 0x6d, 0x54, 0xb8, + 0x04, 0x4b, 0x6f, 0xd1, 0x4c, 0x97, 0xa6, 0xbc, 0x8a, 0x81, 0x9a, 0x17, 0x25, 0xa1, 0x38, 0x95, + 0x7f, 0x8d, 0x5b, 0xae, 0x3b, 0x9d, 0x86, 0xce, 0xe5, 0xa5, 0xea, 0xbf, 0xe2, 0x70, 0x73, 0x5b, + 0x77, 0x7d, 0x93, 0xc4, 0xbb, 0x69, 0x1f, 0x44, 0xec, 0x75, 0x17, 0x72, 0xf6, 0x68, 0xc0, 0x6e, + 0xc5, 0x63, 0xba, 0x04, 0xba, 0x83, 0x3d, 0x1a, 0x04, 0x06, 0xf7, 0x50, 0x0b, 0x12, 0x96, 0xe9, + 0xf9, 0xe5, 0x18, 0xb5, 0xe8, 0xfa, 0x0c, 0x8b, 0x5e, 0xbc, 0x47, 0xad, 0x65, 0x7a, 0x3e, 0xf7, + 0x49, 0x82, 0x82, 0x3a, 0x90, 0x74, 0x75, 0xfb, 0x00, 0x53, 0x27, 0xcb, 0xad, 0xdf, 0xbf, 0x1a, + 0x9c, 0x4a, 0x44, 0x79, 0xbb, 0x45, 0x71, 0x2a, 0xbf, 0x15, 0x20, 0x41, 0x76, 0xb9, 0x24, 0x0e, + 0x6e, 0x42, 0xea, 0x48, 0xb7, 0x46, 0xd8, 0xa3, 0x3a, 0xe4, 0x55, 0xf6, 0x85, 0x7e, 0x09, 0x25, + 0x6f, 0xb4, 0x37, 0x8c, 0x6c, 0xc5, 0x12, 0xcd, 0x07, 0x57, 0x3a, 0x55, 0x58, 0x12, 0xa6, 0xb1, + 0x2a, 0xcf, 0x20, 0x49, 0xcf, 0x7b, 0xc9, 0xc9, 0xee, 0x40, 0xde, 0x77, 0x34, 0x7c, 0xdc, 0xb7, + 0x46, 0x9e, 0x79, 0x84, 0xa9, 0x77, 0xe4, 0xd5, 0x9c, 0xef, 0xc8, 0x9c, 0x84, 0xee, 0x42, 0x71, + 0xdf, 0x75, 0x06, 0x9a, 0x69, 0x73, 0xa6, 0x38, 0x65, 0x2a, 0x10, 0xaa, 0xc2, 0x89, 0xd5, 0xff, + 0x66, 0xa0, 0x44, 0x3d, 0x68, 0xae, 0xcc, 0x70, 0x37, 0x92, 0x19, 0x6e, 0x4c, 0x65, 0x86, 0xd0, + 0x0d, 0x49, 0x62, 0xb8, 0x0d, 0xa9, 0x91, 0x6d, 0x3e, 0x1f, 0x05, 0x7b, 0x86, 0xc9, 0x2f, 0xa0, + 0x9d, 0x4b, 0x1b, 0x89, 0xf3, 0x69, 0xe3, 0x7d, 0x40, 0x24, 0x66, 0xb0, 0x36, 0xc5, 0x98, 0xa4, + 0x8c, 0x22, 0x5d, 0x69, 0xce, 0x4c, 0x32, 0xa9, 0x2b, 0x24, 0x99, 0x87, 0x20, 0xe2, 0x63, 0xdf, + 0xd5, 0xb5, 0x88, 0x7c, 0x9a, 0xca, 0x2f, 0x9d, 0x9e, 0x2c, 0x17, 0x65, 0xb2, 0x76, 0x31, 0x48, + 0x11, 0x47, 0xd6, 0x0c, 0xe2, 0x13, 0x8b, 0x0c, 0xc3, 0x30, 0x5d, 0x4c, 0xab, 0x64, 0xd0, 0xaa, + 0x16, 0xd7, 0xef, 0xcd, 0x4c, 0x26, 0x53, 0x66, 0xaf, 0x49, 0x5c, 0x50, 0x15, 0x03, 0xa8, 0x90, + 0xe0, 0xa1, 0xc7, 0x90, 0xdb, 0x0f, 0x0a, 0xb5, 0xf6, 0x0c, 0x8f, 0xcb, 0x59, 0xea, 0x6e, 0xef, + 0xce, 0x5f, 0xd2, 0x79, 0x7c, 0xee, 0x87, 0x4b, 0x68, 0x07, 0x0a, 0x2e, 0x5f, 0x36, 0xb4, 0xbd, + 0x31, 0xad, 0x3f, 0x2f, 0x03, 0x9a, 0x9f, 0xc0, 0x34, 0xc6, 0xe8, 0x31, 0x80, 0x19, 0x66, 0x49, + 0x5a, 0xa4, 0x72, 0xeb, 0xef, 0x5d, 0x21, 0x9d, 0xf2, 0x93, 0x4e, 0x40, 0xd0, 0x13, 0x28, 0x4e, + 0xbe, 0xe8, 0x51, 0xf3, 0x2f, 0x79, 0xd4, 0x42, 0x04, 0xa7, 0x31, 0x46, 0x3d, 0xb8, 0x4e, 0xca, + 0xa7, 0xe3, 0x99, 0x3e, 0x8e, 0xba, 0x40, 0x81, 0xba, 0x40, 0xf5, 0xf4, 0x64, 0x19, 0x35, 0xf9, + 0xfa, 0xc5, 0x6e, 0x80, 0xfa, 0x67, 0xd6, 0x03, 0xa7, 0x9a, 0x72, 0x5e, 0x82, 0x58, 0x9c, 0x38, + 0x55, 0x77, 0xe2, 0xbe, 0xe7, 0x9c, 0x2a, 0xe2, 0xda, 0x04, 0xe9, 0x09, 0xe4, 0xa7, 0xb2, 0x4c, + 0xe9, 0xe5, 0xb3, 0xcc, 0x14, 0x10, 0x92, 0x59, 0x7f, 0x24, 0xd2, 0xd6, 0xf0, 0xbd, 0x39, 0x1d, + 0xf4, 0x6c, 0xa7, 0x54, 0x5d, 0x82, 0x6c, 0xe8, 0xa3, 0xa4, 0xe5, 0xaf, 0x77, 0x9b, 0xe2, 0x02, + 0x1d, 0x93, 0xe4, 0x6e, 0x53, 0x14, 0xaa, 0x77, 0x20, 0x41, 0xc7, 0x87, 0x1c, 0xa4, 0x37, 0x3a, + 0xea, 0x93, 0xba, 0x2a, 0x05, 0xcd, 0xa2, 0xd2, 0xde, 0x95, 0xd5, 0x9e, 0x2c, 0x89, 0x42, 0xf5, + 0xbb, 0x04, 0xa0, 0xc9, 0x16, 0x5b, 0x23, 0x5f, 0xa7, 0x60, 0x75, 0x48, 0x05, 0xd6, 0xa3, 0x49, + 0x28, 0xb7, 0xfe, 0xa3, 0x4b, 0x5b, 0xb8, 0x09, 0xc0, 0xc3, 0x05, 0x95, 0x09, 0xa2, 0x4f, 0xa3, + 0x93, 0x41, 0x6e, 0xfd, 0xed, 0xf9, 0x94, 0x7c, 0xb8, 0xc0, 0x47, 0x86, 0x47, 0x90, 0xf4, 0x7c, + 0xd2, 0x3f, 0xc7, 0xa9, 0x91, 0xd6, 0x66, 0xc8, 0x9f, 0x3f, 0x7c, 0xad, 0x4b, 0xc4, 0x78, 0xb5, + 0xa1, 0x18, 0xe8, 0x09, 0x64, 0xc3, 0xbc, 0xc0, 0xc6, 0x8c, 0xfb, 0xf3, 0x03, 0x86, 0x46, 0xe6, + 0x2d, 0x46, 0x88, 0x85, 0xea, 0x90, 0x1b, 0x30, 0xb6, 0x49, 0x83, 0xb4, 0xc2, 0x52, 0x33, 0x70, + 0x04, 0x9a, 0xa2, 0x23, 0x5f, 0x2a, 0x70, 0x21, 0xc5, 0x20, 0xfd, 0xae, 0xeb, 0x58, 0xd6, 0x9e, + 0xde, 0x7f, 0x46, 0x67, 0x85, 0xb0, 0xdf, 0xe5, 0xd4, 0xea, 0x2f, 0x20, 0x49, 0x75, 0x22, 0x17, + 0xb9, 0xd3, 0x7e, 0xd4, 0xee, 0x3c, 0x21, 0x5d, 0x7f, 0x09, 0x72, 0x92, 0xdc, 0x92, 0x7b, 0xb2, + 0xd6, 0x69, 0xb7, 0x9e, 0x8a, 0x02, 0xba, 0x05, 0x37, 0x18, 0xa1, 0xde, 0x96, 0xb4, 0x27, 0xaa, + 0xc2, 0x97, 0x62, 0xd5, 0xd5, 0xa8, 0xa7, 0x4c, 0xa6, 0x49, 0xe2, 0x33, 0x92, 0x24, 0x0a, 0xd4, + 0x67, 0xd4, 0xce, 0xb6, 0x18, 0x6b, 0xe4, 0x01, 0x8c, 0xd0, 0x02, 0x9b, 0x89, 0x4c, 0x4a, 0x4c, + 0x57, 0xff, 0x54, 0x86, 0x12, 0xed, 0x91, 0xe6, 0x2a, 0x52, 0x2b, 0xb4, 0x48, 0x05, 0x0d, 0x8f, + 0x38, 0x55, 0xa4, 0x62, 0xac, 0x3e, 0xdd, 0x87, 0xec, 0x50, 0x77, 0xb1, 0xed, 0x13, 0x93, 0x25, + 0xa6, 0xfa, 0xdc, 0xcc, 0x36, 0x5d, 0x08, 0xd9, 0x33, 0x01, 0xa3, 0x42, 0x84, 0xd2, 0x47, 0xd8, + 0xa5, 0xaf, 0x33, 0x81, 0x95, 0x6f, 0xb1, 0x59, 0x73, 0x71, 0x72, 0xaa, 0xdd, 0x80, 0x41, 0xe5, + 0x9c, 0xe8, 0x4d, 0x80, 0xd1, 0x50, 0xe3, 0x72, 0xd1, 0x51, 0x20, 0x3b, 0x1a, 0x32, 0x6e, 0xb4, + 0x0d, 0x8b, 0x03, 0xc7, 0x30, 0xf7, 0xcd, 0x7e, 0x70, 0x8f, 0xbe, 0x39, 0x08, 0xa6, 0xb6, 0xdc, + 0xfa, 0x1b, 0x11, 0x27, 0x19, 0xf9, 0xa6, 0x55, 0x3b, 0xb4, 0xfa, 0xb5, 0x1e, 0x7f, 0xf2, 0x62, + 0x50, 0x62, 0x54, 0x9a, 0x2c, 0xa2, 0x07, 0x90, 0xe6, 0xed, 0x59, 0xf0, 0x5c, 0x32, 0x6f, 0xfc, + 0x30, 0x44, 0x2e, 0x8d, 0x36, 0xa0, 0x68, 0xe3, 0xe3, 0x68, 0x0b, 0x9e, 0x9d, 0xf2, 0xb0, 0x7c, + 0x1b, 0x1f, 0x5f, 0xdc, 0x7f, 0xe7, 0xed, 0xc9, 0x8a, 0x81, 0x1e, 0x43, 0x61, 0xe8, 0x9a, 0x03, + 0xdd, 0x1d, 0x6b, 0x41, 0x50, 0xc2, 0x55, 0x82, 0x32, 0xcc, 0x61, 0x01, 0x04, 0x5d, 0x45, 0x1b, + 0x10, 0x74, 0xbc, 0xd8, 0x2b, 0xe7, 0xa8, 0x8e, 0x57, 0x03, 0xe3, 0xc2, 0xa8, 0x01, 0x05, 0xaa, + 0x62, 0xd8, 0x6a, 0xe7, 0xa9, 0x86, 0x4b, 0x4c, 0xc3, 0x1c, 0xd1, 0xf0, 0x82, 0x76, 0x3b, 0x67, + 0x87, 0x74, 0x03, 0x6d, 0x02, 0x84, 0x4f, 0x8d, 0xa4, 0x7c, 0x5c, 0x56, 0x9d, 0xb7, 0x39, 0xe3, + 0xe4, 0x48, 0x6a, 0x44, 0x1a, 0x6d, 0x41, 0x96, 0x07, 0x67, 0x50, 0x37, 0x72, 0x33, 0x5f, 0x24, + 0xce, 0xa7, 0x0a, 0xee, 0x5c, 0x21, 0x02, 0x6a, 0x43, 0xd2, 0xc2, 0xba, 0x87, 0x59, 0xf1, 0xf8, + 0x78, 0x06, 0xd4, 0x99, 0xf0, 0xaa, 0x75, 0xfb, 0x87, 0x78, 0xa0, 0x37, 0x0f, 0x49, 0x23, 0xda, + 0x22, 0xf2, 0x6a, 0x00, 0x83, 0xda, 0x20, 0x52, 0x73, 0x45, 0xb3, 0x8e, 0x48, 0x2d, 0xf6, 0x16, + 0xb3, 0x58, 0x91, 0x58, 0x6c, 0x66, 0xe6, 0xa1, 0xfe, 0xb4, 0x35, 0xc9, 0x3e, 0x3f, 0x87, 0xe2, + 0xbe, 0xe3, 0x0e, 0x74, 0x3f, 0x8c, 0x92, 0xc5, 0x49, 0x7b, 0xf9, 0xfd, 0xc9, 0x72, 0x61, 0x83, + 0xae, 0xf2, 0xc8, 0x2a, 0xec, 0x47, 0x3f, 0xd1, 0x43, 0x9e, 0xa4, 0xaf, 0xd1, 0x9c, 0xfa, 0xfe, + 0xbc, 0xda, 0x9d, 0xcf, 0xd0, 0x6d, 0x48, 0xf5, 0x0f, 0x71, 0xff, 0x99, 0x57, 0xbe, 0x4e, 0x6d, + 0xfe, 0x93, 0x39, 0xa1, 0x9a, 0x44, 0x68, 0xf2, 0x34, 0xa4, 0x32, 0x14, 0xf4, 0x05, 0x14, 0x0d, + 0x42, 0x31, 0xed, 0x03, 0xd6, 0xbe, 0xde, 0xa0, 0xb8, 0x6b, 0x73, 0xe2, 0x92, 0xd6, 0x56, 0xb1, + 0xf7, 0x1d, 0xde, 0xb9, 0x70, 0xb0, 0xa0, 0xe5, 0xed, 0x40, 0x66, 0x9f, 0x8c, 0xe2, 0x26, 0xf6, + 0xca, 0x37, 0x29, 0xee, 0xe5, 0x2f, 0xb8, 0x67, 0xa7, 0x7f, 0x9e, 0xe2, 0x39, 0x48, 0x18, 0xe8, + 0x94, 0x30, 0x26, 0x97, 0xfa, 0xda, 0xf9, 0x40, 0xe7, 0xd3, 0xff, 0xd4, 0x4b, 0x00, 0x0d, 0x74, + 0xf6, 0x65, 0x90, 0x84, 0x77, 0x64, 0xe2, 0xaf, 0xb4, 0xe7, 0x23, 0xec, 0x8e, 0xcb, 0xe5, 0x48, + 0x72, 0xce, 0x12, 0xfa, 0x63, 0x42, 0x46, 0x1f, 0x42, 0xd6, 0xc0, 0x43, 0x6c, 0x1b, 0x5e, 0xc7, + 0x2e, 0xdf, 0xa2, 0xad, 0xd1, 0x35, 0xd2, 0xaf, 0x4b, 0x9c, 0xc8, 0x92, 0xef, 0x84, 0x0b, 0x7d, + 0x09, 0xf9, 0xe0, 0x03, 0x1b, 0x1d, 0xbb, 0x31, 0x2e, 0x57, 0xa8, 0xd2, 0xf7, 0xe6, 0x34, 0xe6, + 0xa4, 0x0f, 0xbc, 0xce, 0xf5, 0x91, 0x22, 0x68, 0xea, 0x14, 0x36, 0xfa, 0x02, 0xf2, 0xdc, 0xbb, + 0x37, 0x9d, 0x3d, 0xaf, 0xfc, 0xfa, 0xa5, 0x13, 0xec, 0xd9, 0xbd, 0xb6, 0x26, 0xa2, 0x3c, 0x6f, + 0x45, 0xd1, 0xd0, 0x67, 0x50, 0x08, 0x9f, 0x7d, 0x9c, 0xa1, 0xef, 0x95, 0x6f, 0xd3, 0xc0, 0xbc, + 0x3f, 0xaf, 0xeb, 0x32, 0xd9, 0xce, 0xd0, 0xf7, 0xd4, 0xbc, 0x17, 0xf9, 0x42, 0x77, 0x20, 0x6b, + 0xb8, 0xce, 0x30, 0xa8, 0x1f, 0x6f, 0xac, 0x08, 0xab, 0x71, 0x7e, 0xcd, 0x84, 0x4c, 0x0b, 0x83, + 0x06, 0x45, 0x17, 0x0f, 0x2d, 0xbd, 0x8f, 0x07, 0xa4, 0xfc, 0x39, 0xfb, 0xe5, 0x25, 0xba, 0xfb, + 0xfa, 0xdc, 0x86, 0x0c, 0x85, 0xb9, 0x63, 0x46, 0xf0, 0x3a, 0xfb, 0x68, 0x07, 0x40, 0x1f, 0x19, + 0xa6, 0xaf, 0x0d, 0x1c, 0x03, 0x97, 0x97, 0x69, 0x54, 0xce, 0x7b, 0x4b, 0x75, 0x22, 0xb8, 0xe5, + 0x18, 0x38, 0x7c, 0x49, 0xe1, 0x84, 0xca, 0x77, 0x02, 0x2c, 0x9e, 0x4b, 0x49, 0xe8, 0x57, 0x90, + 0xb6, 0x1d, 0x23, 0xf2, 0xa2, 0x22, 0xb3, 0xdb, 0x4d, 0xb5, 0x1d, 0x23, 0x78, 0x50, 0xb9, 0x7f, + 0x60, 0xfa, 0x87, 0xa3, 0xbd, 0x5a, 0xdf, 0x19, 0xac, 0x85, 0xa7, 0x30, 0xf6, 0x26, 0xbf, 0xd7, + 0x86, 0xcf, 0x0e, 0xd6, 0xe8, 0xaf, 0xe1, 0x5e, 0x2d, 0x10, 0x53, 0x53, 0x04, 0x55, 0x31, 0xd0, + 0x07, 0x50, 0xc2, 0xc7, 0x43, 0xd3, 0x8d, 0x94, 0xe5, 0x58, 0xc4, 0xac, 0xc5, 0xc9, 0x22, 0x31, + 0x6e, 0xe5, 0x2f, 0x02, 0x94, 0xce, 0xa4, 0x03, 0xd2, 0xa6, 0xd0, 0xd7, 0xba, 0xa9, 0x36, 0x85, + 0x50, 0xc2, 0x06, 0x26, 0x76, 0xe9, 0x93, 0x74, 0xfc, 0x55, 0x9f, 0xa4, 0xa7, 0x87, 0xe3, 0xe4, + 0xfc, 0xc3, 0xf1, 0x66, 0x22, 0x93, 0x10, 0x93, 0x95, 0xa7, 0x90, 0xe1, 0xa9, 0x68, 0xba, 0x6f, + 0x12, 0xe6, 0xec, 0x9b, 0x66, 0xea, 0x59, 0xf9, 0x46, 0x80, 0x6c, 0xf4, 0xad, 0x3f, 0x16, 0xa2, + 0x5e, 0xdc, 0xb6, 0xbd, 0xe4, 0x7b, 0xd8, 0xb4, 0x05, 0xe2, 0xf3, 0x5b, 0xa0, 0x72, 0x04, 0xb9, + 0x48, 0x34, 0x9f, 0xed, 0xb5, 0x85, 0x97, 0xe8, 0xb5, 0xdf, 0x82, 0xd4, 0x97, 0xce, 0x1e, 0x57, + 0x20, 0xde, 0x28, 0x30, 0xe9, 0xe4, 0xa6, 0xb3, 0xa7, 0x48, 0x6a, 0xf2, 0x4b, 0x67, 0x4f, 0x31, + 0x2a, 0xbf, 0x11, 0x20, 0x1f, 0x8d, 0x73, 0x54, 0x85, 0xac, 0x69, 0xf7, 0x5d, 0x1a, 0x64, 0x74, + 0x5f, 0xee, 0x82, 0x13, 0x32, 0x89, 0xfe, 0x81, 0x69, 0x6b, 0xf4, 0x8d, 0x6a, 0xca, 0x4d, 0x33, + 0x03, 0xd3, 0xde, 0x25, 0x54, 0xca, 0xa2, 0x1f, 0x33, 0x96, 0xf8, 0x14, 0x8b, 0x7e, 0x1c, 0xb0, + 0x54, 0x68, 0x41, 0x75, 0x7d, 0xda, 0x16, 0xc7, 0x23, 0x25, 0xd2, 0xf5, 0x2b, 0x87, 0x90, 0x8b, + 0xc4, 0xff, 0x1c, 0x17, 0xf6, 0x53, 0x48, 0x84, 0x41, 0x33, 0x67, 0x2f, 0x4b, 0x05, 0xaa, 0x6f, + 0xf3, 0x81, 0x03, 0x20, 0xb5, 0xbd, 0xd3, 0x68, 0x29, 0xcd, 0x0b, 0x87, 0x05, 0x32, 0x56, 0x84, + 0x49, 0x83, 0x0c, 0x96, 0x92, 0xd2, 0xad, 0x37, 0x5a, 0x32, 0x19, 0x33, 0x0b, 0x90, 0x55, 0xe5, + 0xba, 0x44, 0xa7, 0x10, 0x51, 0xf8, 0x24, 0xf1, 0xf5, 0xb7, 0xcb, 0xc2, 0x66, 0x22, 0x83, 0xc4, + 0x6b, 0xd5, 0xef, 0x04, 0x40, 0x92, 0xee, 0xeb, 0x24, 0x84, 0xae, 0x30, 0x51, 0xc4, 0x2e, 0xd1, + 0x74, 0xba, 0x01, 0x8c, 0xbf, 0x4a, 0x03, 0x18, 0x1c, 0xb5, 0xfa, 0x8d, 0x00, 0x10, 0x39, 0xdc, + 0xa7, 0xd1, 0x7f, 0xc2, 0x66, 0xf7, 0xba, 0x67, 0x52, 0x2a, 0x99, 0x66, 0x83, 0xff, 0xc9, 0x1e, + 0x40, 0xc6, 0x60, 0x2a, 0xb3, 0xeb, 0x98, 0xd9, 0x54, 0x9e, 0xb3, 0xcc, 0x43, 0x52, 0x41, 0x18, + 0xb5, 0x91, 0x86, 0xe4, 0xc8, 0x36, 0x1d, 0xfb, 0xdd, 0x8f, 0x00, 0x9d, 0x4f, 0x3f, 0xc4, 0xec, + 0xf4, 0xb7, 0xee, 0x63, 0x23, 0x98, 0x11, 0x77, 0xec, 0xa3, 0x90, 0x20, 0x34, 0xee, 0xbc, 0xf8, + 0xc7, 0xd2, 0xc2, 0x8b, 0xd3, 0x25, 0xe1, 0xcf, 0xa7, 0x4b, 0xc2, 0x5f, 0x4f, 0x97, 0x84, 0xbf, + 0x9f, 0x2e, 0x09, 0xbf, 0xfe, 0xe7, 0xd2, 0xc2, 0xe7, 0x69, 0x76, 0x80, 0xff, 0x07, 0x00, 0x00, + 0xff, 0xff, 0x0b, 0xf2, 0xfd, 0xfe, 0x11, 0x20, 0x00, 0x00, } diff --git a/pkg/sql/sqlbase/structured.proto b/pkg/sql/sqlbase/structured.proto index 24a56065bc5f..4332b2e26c13 100644 --- a/pkg/sql/sqlbase/structured.proto +++ b/pkg/sql/sqlbase/structured.proto @@ -57,6 +57,7 @@ message ColumnType { TIME = 17; JSON = 18; TIMETZ = 19; + TUPLE = 20; INT2VECTOR = 200; OIDVECTOR = 201; @@ -88,6 +89,8 @@ message ColumnType { optional VisibleType visible_type = 6 [(gogoproto.nullable) = false]; // Only used if the kind is ARRAY. optional SemanticType array_contents = 7; + // Only used if the kind is TUPLE + repeated ColumnType tuple_contents = 8 [(gogoproto.nullable) = false]; } enum ConstraintValidity { diff --git a/pkg/sql/sqlbase/table.go b/pkg/sql/sqlbase/table.go index eca1146f40ac..62f172249309 100644 --- a/pkg/sql/sqlbase/table.go +++ b/pkg/sql/sqlbase/table.go @@ -726,6 +726,8 @@ func EncodeTableValue( return nil, err } return encoding.EncodeArrayValue(appendTo, uint32(colID), a), nil + case *tree.DTuple: + return encodeTuple(t, appendTo, uint32(colID), scratch) case *tree.DCollatedString: return encoding.EncodeBytesValue(appendTo, uint32(colID), []byte(t.Contents)), nil case *tree.DOid: @@ -734,6 +736,21 @@ func EncodeTableValue( return nil, errors.Errorf("unable to encode table value: %T", val) } +func encodeTuple(t *tree.DTuple, appendTo []byte, colID uint32, scratch []byte) ([]byte, error) { + appendTo = encoding.EncodeValueTag(appendTo, uint32(colID), encoding.Tuple) + appendTo = encoding.EncodeNonsortingUvarint(appendTo, uint64(len(t.D))) + + var err error + for _, dd := range t.D { + appendTo, err = EncodeTableValue(appendTo, ColumnID(encoding.NoColumnID), dd, scratch) + if err != nil { + return nil, err + } + } + return appendTo, nil + +} + // GetColumnTypes returns the types of the columns with the given IDs. func GetColumnTypes(desc *TableDescriptor, columnIDs []ColumnID) ([]ColumnType, error) { types := make([]ColumnType, len(columnIDs)) @@ -1046,11 +1063,13 @@ func ExtractIndexKey( return indexKey, err } -const datumAllocSize = 16 // Arbitrary, could be tuned. +const datumAllocSize = 16 // Arbitrary, could be tuned. +const datumAllocMultiplier = 4 // Arbitrary, could be tuned. // DatumAlloc provides batch allocation of datum pointers, amortizing the cost // of the allocations. type DatumAlloc struct { + datumAlloc []tree.Datum dintAlloc []tree.DInt dfloatAlloc []tree.DFloat dstringAlloc []tree.DString @@ -1065,11 +1084,26 @@ type DatumAlloc struct { duuidAlloc []tree.DUuid dipnetAlloc []tree.DIPAddr djsonAlloc []tree.DJSON + dtupleAlloc []tree.DTuple doidAlloc []tree.DOid scratch []byte env tree.CollationEnvironment } +func (a *DatumAlloc) NewDatums(num int) tree.Datums { + buf := &a.datumAlloc + if len(*buf) < num { + extensionSize := datumAllocSize + if extensionSize < num*datumAllocMultiplier { + extensionSize = num * datumAllocMultiplier + } + *buf = make(tree.Datums, extensionSize) + } + r := (*buf)[0:num] + *buf = (*buf)[num:] + return r +} + // NewDInt allocates a DInt. func (a *DatumAlloc) NewDInt(v tree.DInt) *tree.DInt { buf := &a.dintAlloc @@ -1243,6 +1277,18 @@ func (a *DatumAlloc) NewDJSON(v tree.DJSON) *tree.DJSON { return r } +// NewDTuple allocates a DTuple. +func (a *DatumAlloc) NewDTuple(v tree.DTuple) *tree.DTuple { + buf := &a.dtupleAlloc + if len(*buf) == 0 { + *buf = make([]tree.DTuple, datumAllocSize) + } + r := &(*buf)[0] + *r = v + *buf = (*buf)[1:] + return r +} + // NewDOid allocates a DOid. func (a *DatumAlloc) NewDOid(v tree.DOid) tree.Datum { buf := &a.doidAlloc @@ -1412,7 +1458,8 @@ func DecodeTableKey( } return a.NewDOid(tree.MakeDOid(tree.DInt(i))), rkey, err default: - if t, ok := valType.(types.TCollatedString); ok { + switch t := valType.(type) { + case types.TCollatedString: var r string rkey, r, err = encoding.DecodeUnsafeStringAscending(key, nil) if err != nil { @@ -1519,6 +1566,27 @@ func decodeArray(a *DatumAlloc, elementType types.T, b []byte) (tree.Datum, []by return &result, b, nil } +func decodeTuple(a *DatumAlloc, elementTypes types.TTuple, b []byte) (tree.Datum, []byte, error) { + b, _, l, err := encoding.DecodeNonsortingUvarint(b) + if int(l) != len(elementTypes.Types) { + return nil, nil, errors.Errorf("encoded Tuple has %d values, but expected %d values from type information", l, len(elementTypes.Types)) + } + + result := tree.DTuple{ + D: a.NewDatums(len(elementTypes.Types)), + } + + var datum tree.Datum + for i, typ := range elementTypes.Types { + datum, b, err = DecodeTableValue(a, typ, b) + if err != nil { + return nil, b, err + } + result.D[i] = datum + } + return a.NewDTuple(result), b, nil +} + // decodeUntaggedDatum is used to decode a Datum whose type is known, and which // doesn't have a value tag (either due to it having been consumed already or // not having one in the first place). @@ -1624,6 +1692,8 @@ func decodeUntaggedDatum(a *DatumAlloc, t types.T, buf []byte) (tree.Datum, []by return tree.NewDCollatedString(string(data), typ.Locale, &a.env), b, err case types.TArray: return decodeArray(a, typ.Typ, buf) + case types.TTuple: + return decodeTuple(a, typ, buf) } return nil, buf, errors.Errorf("couldn't decode type %s", t) } diff --git a/pkg/sql/sqlbase/testutils.go b/pkg/sql/sqlbase/testutils.go index 436b9a7c5a63..6fb4edd0258f 100644 --- a/pkg/sql/sqlbase/testutils.go +++ b/pkg/sql/sqlbase/testutils.go @@ -114,6 +114,12 @@ func RandDatum(rng *rand.Rand, typ ColumnType, nullOk bool) tree.Datum { return nil } return &tree.DJSON{JSON: j} + case ColumnType_TUPLE: + tuple := tree.DTuple{D: make(tree.Datums, len(typ.TupleContents))} + for i, internalType := range typ.TupleContents { + tuple.D[i] = RandDatum(rng, internalType, true) + } + return &tuple case ColumnType_STRING: // Generate a random ASCII string. p := make([]byte, rng.Intn(10)) @@ -199,6 +205,14 @@ func RandColumnType(rng *rand.Rand) ColumnType { typ.ArrayContents = &s } } + if typ.SemanticType == ColumnType_TUPLE { + // Generate tuples between 0 and 4 datums in length + len := rng.Intn(5) + typ.TupleContents = make([]ColumnType, len) + for i := range typ.TupleContents { + typ.TupleContents[i] = RandColumnType(rng) + } + } return typ } diff --git a/pkg/util/encoding/encoding.go b/pkg/util/encoding/encoding.go index c9cd1c631b57..d032fa67cf23 100644 --- a/pkg/util/encoding/encoding.go +++ b/pkg/util/encoding/encoding.go @@ -1057,7 +1057,8 @@ const ( // Do not change SentinelType from 15. This value is specifically used for bit // manipulation in EncodeValueTag. SentinelType Type = 15 // Used in the Value encoding. - JSON + JSON Type = iota + Tuple ) // PeekType peeks at the type of the value encoded at the start of b. @@ -1969,7 +1970,7 @@ func PeekValueLengthWithOffsetsAndType(b []byte, dataOffset int, typ Type) (leng return dataOffset + n, err case Float: return dataOffset + floatValueEncodedLength, nil - case Bytes, Array, JSON: + case Bytes, Array, JSON, Tuple: _, n, i, err := DecodeNonsortingUvarint(b) return dataOffset + n + int(i), err case Decimal: