From 02d7b642669e590f810d4115e4913d7c9d598642 Mon Sep 17 00:00:00 2001 From: Erik Trinh Date: Mon, 10 Sep 2018 10:21:40 -0400 Subject: [PATCH] sql: create jobs for truncated and dropped tables Creates a job for statements involving dropping or truncated tables, including DROP DATABASE. The job is completed when the GC TTL expires and both table data and ID is deleted for each of the tables involved. Fixes #19004 Release note: None --- pkg/jobs/jobspb/jobs.pb.go | 539 +++++++++++++----- pkg/jobs/jobspb/jobs.proto | 13 + pkg/sql/drop_database.go | 21 + pkg/sql/drop_table.go | 8 + pkg/sql/drop_test.go | 124 +++- pkg/sql/drop_view.go | 1 + .../logictest/testdata/logic_test/show_trace | 28 +- pkg/sql/schema_changer.go | 64 ++- pkg/sql/schema_changer_test.go | 24 + pkg/sql/sqlbase/structured.pb.go | 404 +++++++------ pkg/sql/sqlbase/structured.proto | 4 + pkg/sql/table.go | 48 ++ pkg/sql/truncate.go | 26 +- 13 files changed, 961 insertions(+), 343 deletions(-) diff --git a/pkg/jobs/jobspb/jobs.pb.go b/pkg/jobs/jobspb/jobs.pb.go index a8a0a2d3c492..42bdd4992a96 100644 --- a/pkg/jobs/jobspb/jobs.pb.go +++ b/pkg/jobs/jobspb/jobs.pb.go @@ -16,6 +16,7 @@ ImportDetails ImportProgress ResumeSpanList + DroppedTableDetails SchemaChangeDetails SchemaChangeProgress ChangefeedTarget @@ -84,6 +85,35 @@ var Type_value = map[string]int32{ func (Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorJobs, []int{0} } +type DroppedTableDetails_Status int32 + +const ( + DroppedTableDetails_StatusDrainingName DroppedTableDetails_Status = 0 + DroppedTableDetails_StatusWaitForGCInterval DroppedTableDetails_Status = 1 + DroppedTableDetails_StatusRocksDBCompaction DroppedTableDetails_Status = 2 + DroppedTableDetails_StatusDone DroppedTableDetails_Status = 10 +) + +var DroppedTableDetails_Status_name = map[int32]string{ + 0: "DRAINING_NAME", + 1: "WAIT_FOR_GC_INTERVAL", + 2: "ROCKSDB_COMPACTION", + 10: "DONE", +} +var DroppedTableDetails_Status_value = map[string]int32{ + "DRAINING_NAME": 0, + "WAIT_FOR_GC_INTERVAL": 1, + "ROCKSDB_COMPACTION": 2, + "DONE": 10, +} + +func (x DroppedTableDetails_Status) String() string { + return proto.EnumName(DroppedTableDetails_Status_name, int32(x)) +} +func (DroppedTableDetails_Status) EnumDescriptor() ([]byte, []int) { + return fileDescriptorJobs, []int{8, 0} +} + type Lease struct { // The ID of the node that holds the lease. NodeID github_com_cockroachdb_cockroach_pkg_roachpb.NodeID `protobuf:"varint,1,opt,name=node_id,json=nodeId,proto3,casttype=github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" json:"node_id,omitempty"` @@ -207,6 +237,17 @@ func (m *ResumeSpanList) String() string { return proto.CompactTextSt func (*ResumeSpanList) ProtoMessage() {} func (*ResumeSpanList) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{7} } +type DroppedTableDetails struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + ID github_com_cockroachdb_cockroach_pkg_sql_sqlbase.ID `protobuf:"varint,2,opt,name=ID,proto3,casttype=github.com/cockroachdb/cockroach/pkg/sql/sqlbase.ID" json:"ID,omitempty"` + Status DroppedTableDetails_Status `protobuf:"varint,3,opt,name=status,proto3,enum=cockroach.sql.jobs.jobspb.DroppedTableDetails_Status" json:"status,omitempty"` +} + +func (m *DroppedTableDetails) Reset() { *m = DroppedTableDetails{} } +func (m *DroppedTableDetails) String() string { return proto.CompactTextString(m) } +func (*DroppedTableDetails) ProtoMessage() {} +func (*DroppedTableDetails) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{8} } + type SchemaChangeDetails struct { ReadAsOf cockroach_util_hlc.Timestamp `protobuf:"bytes,1,opt,name=read_as_of,json=readAsOf" json:"read_as_of"` // A schema change can involve running multiple processors backfilling @@ -215,13 +256,14 @@ type SchemaChangeDetails struct { // non-overlapping contiguous areas of the KV space that still need to // be processed. The index represents the index of a mutation in a // mutation list containing mutations for the same mutationID. - ResumeSpanList []ResumeSpanList `protobuf:"bytes,2,rep,name=resume_span_list,json=resumeSpanList" json:"resume_span_list"` + ResumeSpanList []ResumeSpanList `protobuf:"bytes,2,rep,name=resume_span_list,json=resumeSpanList" json:"resume_span_list"` + DroppedTables []DroppedTableDetails `protobuf:"bytes,3,rep,name=dropped_tables,json=droppedTables" json:"dropped_tables"` } func (m *SchemaChangeDetails) Reset() { *m = SchemaChangeDetails{} } func (m *SchemaChangeDetails) String() string { return proto.CompactTextString(m) } func (*SchemaChangeDetails) ProtoMessage() {} -func (*SchemaChangeDetails) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{8} } +func (*SchemaChangeDetails) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{9} } type SchemaChangeProgress struct { } @@ -229,7 +271,7 @@ type SchemaChangeProgress struct { func (m *SchemaChangeProgress) Reset() { *m = SchemaChangeProgress{} } func (m *SchemaChangeProgress) String() string { return proto.CompactTextString(m) } func (*SchemaChangeProgress) ProtoMessage() {} -func (*SchemaChangeProgress) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{9} } +func (*SchemaChangeProgress) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{10} } type ChangefeedTarget struct { StatementTimeName string `protobuf:"bytes,1,opt,name=statement_time_name,json=statementTimeName,proto3" json:"statement_time_name,omitempty"` @@ -238,7 +280,7 @@ type ChangefeedTarget struct { func (m *ChangefeedTarget) Reset() { *m = ChangefeedTarget{} } func (m *ChangefeedTarget) String() string { return proto.CompactTextString(m) } func (*ChangefeedTarget) ProtoMessage() {} -func (*ChangefeedTarget) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{10} } +func (*ChangefeedTarget) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{11} } type ChangefeedDetails struct { // Targets contains the user-specified tables and databases to watch, mapping @@ -267,7 +309,7 @@ type ChangefeedDetails struct { func (m *ChangefeedDetails) Reset() { *m = ChangefeedDetails{} } func (m *ChangefeedDetails) String() string { return proto.CompactTextString(m) } func (*ChangefeedDetails) ProtoMessage() {} -func (*ChangefeedDetails) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{11} } +func (*ChangefeedDetails) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{12} } type ResolvedSpan struct { Span cockroach_roachpb1.Span `protobuf:"bytes,1,opt,name=span" json:"span"` @@ -277,7 +319,7 @@ type ResolvedSpan struct { func (m *ResolvedSpan) Reset() { *m = ResolvedSpan{} } func (m *ResolvedSpan) String() string { return proto.CompactTextString(m) } func (*ResolvedSpan) ProtoMessage() {} -func (*ResolvedSpan) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{12} } +func (*ResolvedSpan) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{13} } type ChangefeedProgress struct { ResolvedSpans []ResolvedSpan `protobuf:"bytes,2,rep,name=resolved_spans,json=resolvedSpans" json:"resolved_spans"` @@ -286,7 +328,7 @@ type ChangefeedProgress struct { func (m *ChangefeedProgress) Reset() { *m = ChangefeedProgress{} } func (m *ChangefeedProgress) String() string { return proto.CompactTextString(m) } func (*ChangefeedProgress) ProtoMessage() {} -func (*ChangefeedProgress) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{13} } +func (*ChangefeedProgress) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{14} } type Payload struct { Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` @@ -312,7 +354,7 @@ type Payload struct { func (m *Payload) Reset() { *m = Payload{} } func (m *Payload) String() string { return proto.CompactTextString(m) } func (*Payload) ProtoMessage() {} -func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{14} } +func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{15} } type isPayload_Details interface { isPayload_Details() @@ -533,7 +575,7 @@ type Progress struct { func (m *Progress) Reset() { *m = Progress{} } func (m *Progress) String() string { return proto.CompactTextString(m) } func (*Progress) ProtoMessage() {} -func (*Progress) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{15} } +func (*Progress) Descriptor() ([]byte, []int) { return fileDescriptorJobs, []int{16} } type isProgress_Progress interface { isProgress_Progress() @@ -825,6 +867,7 @@ func init() { proto.RegisterType((*ImportDetails_Table)(nil), "cockroach.sql.jobs.jobspb.ImportDetails.Table") proto.RegisterType((*ImportProgress)(nil), "cockroach.sql.jobs.jobspb.ImportProgress") proto.RegisterType((*ResumeSpanList)(nil), "cockroach.sql.jobs.jobspb.ResumeSpanList") + proto.RegisterType((*DroppedTableDetails)(nil), "cockroach.sql.jobs.jobspb.DroppedTableDetails") proto.RegisterType((*SchemaChangeDetails)(nil), "cockroach.sql.jobs.jobspb.SchemaChangeDetails") proto.RegisterType((*SchemaChangeProgress)(nil), "cockroach.sql.jobs.jobspb.SchemaChangeProgress") proto.RegisterType((*ChangefeedTarget)(nil), "cockroach.sql.jobs.jobspb.ChangefeedTarget") @@ -834,6 +877,7 @@ func init() { proto.RegisterType((*Payload)(nil), "cockroach.sql.jobs.jobspb.Payload") proto.RegisterType((*Progress)(nil), "cockroach.sql.jobs.jobspb.Progress") proto.RegisterEnum("cockroach.sql.jobs.jobspb.Type", Type_name, Type_value) + proto.RegisterEnum("cockroach.sql.jobs.jobspb.DroppedTableDetails_Status", DroppedTableDetails_Status_name, DroppedTableDetails_Status_value) } func (this *Lease) Equal(that interface{}) bool { if that == nil { @@ -1327,6 +1371,40 @@ func (m *ResumeSpanList) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *DroppedTableDetails) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DroppedTableDetails) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintJobs(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if m.ID != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintJobs(dAtA, i, uint64(m.ID)) + } + if m.Status != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintJobs(dAtA, i, uint64(m.Status)) + } + return i, nil +} + func (m *SchemaChangeDetails) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1362,6 +1440,18 @@ func (m *SchemaChangeDetails) MarshalTo(dAtA []byte) (int, error) { i += n } } + if len(m.DroppedTables) > 0 { + for _, msg := range m.DroppedTables { + dAtA[i] = 0x1a + i++ + i = encodeVarintJobs(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } return i, nil } @@ -2033,6 +2123,22 @@ func (m *ResumeSpanList) Size() (n int) { return n } +func (m *DroppedTableDetails) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovJobs(uint64(l)) + } + if m.ID != 0 { + n += 1 + sovJobs(uint64(m.ID)) + } + if m.Status != 0 { + n += 1 + sovJobs(uint64(m.Status)) + } + return n +} + func (m *SchemaChangeDetails) Size() (n int) { var l int _ = l @@ -2044,6 +2150,12 @@ func (m *SchemaChangeDetails) Size() (n int) { n += 1 + l + sovJobs(uint64(l)) } } + if len(m.DroppedTables) > 0 { + for _, e := range m.DroppedTables { + l = e.Size() + n += 1 + l + sovJobs(uint64(l)) + } + } return n } @@ -3769,6 +3881,123 @@ func (m *ResumeSpanList) Unmarshal(dAtA []byte) error { } return nil } +func (m *DroppedTableDetails) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJobs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DroppedTableDetails: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DroppedTableDetails: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJobs + } + 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 ErrInvalidLengthJobs + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJobs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= (github_com_cockroachdb_cockroach_pkg_sql_sqlbase.ID(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJobs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= (DroppedTableDetails_Status(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipJobs(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthJobs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *SchemaChangeDetails) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -3859,6 +4088,37 @@ func (m *SchemaChangeDetails) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DroppedTables", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowJobs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthJobs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DroppedTables = append(m.DroppedTables, DroppedTableDetails{}) + if err := m.DroppedTables[len(m.DroppedTables)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipJobs(dAtA[iNdEx:]) @@ -5349,128 +5609,141 @@ var ( func init() { proto.RegisterFile("jobs/jobspb/jobs.proto", fileDescriptorJobs) } var fileDescriptorJobs = []byte{ - // 1956 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xdd, 0x6f, 0xe3, 0x58, - 0x15, 0x8f, 0x13, 0x27, 0x76, 0x4e, 0x3e, 0xea, 0xde, 0xa9, 0x76, 0xbd, 0xd1, 0x6c, 0x13, 0x05, - 0xd8, 0xe9, 0xec, 0xb0, 0x09, 0x74, 0xa5, 0x5d, 0x18, 0xc1, 0x8a, 0xa6, 0x4d, 0x37, 0xf1, 0xce, - 0xb4, 0x95, 0xdb, 0x82, 0x58, 0x09, 0x19, 0x27, 0xbe, 0x4d, 0x4c, 0x3e, 0xec, 0xfa, 0x3a, 0x33, - 0xcc, 0xbe, 0x20, 0x21, 0x1e, 0x50, 0x9f, 0xf8, 0x03, 0xa8, 0x84, 0x04, 0x48, 0xbc, 0xf1, 0x80, - 0xe0, 0x6f, 0x98, 0x17, 0xc4, 0x3e, 0xb2, 0x42, 0x0a, 0x10, 0x5e, 0xf8, 0x1b, 0xe6, 0x09, 0xdd, - 0x7b, 0xfd, 0x95, 0x4e, 0xe9, 0x97, 0xb4, 0x2f, 0x33, 0xf1, 0xb9, 0xe7, 0xfc, 0xee, 0x39, 0xc7, - 0xbf, 0xf3, 0xe1, 0xc2, 0x1b, 0x3f, 0x71, 0x7a, 0xa4, 0x49, 0xff, 0x71, 0x7b, 0xec, 0xbf, 0x86, - 0xeb, 0x39, 0xbe, 0x83, 0xde, 0xea, 0x3b, 0xfd, 0x91, 0xe7, 0x98, 0xfd, 0x61, 0x83, 0x9c, 0x8e, - 0x1b, 0xec, 0x84, 0x6b, 0x55, 0xd6, 0x06, 0xce, 0xc0, 0x61, 0x5a, 0x4d, 0xfa, 0x8b, 0x1b, 0x54, - 0x10, 0x53, 0x76, 0x7b, 0x4d, 0xcb, 0xf4, 0xcd, 0x40, 0xa6, 0x86, 0x32, 0xdb, 0x79, 0xef, 0xc4, - 0xf1, 0x26, 0xa6, 0x1f, 0xc0, 0x57, 0xee, 0x93, 0xd3, 0x71, 0x93, 0x9c, 0x8e, 0x7b, 0x26, 0xc1, - 0x4d, 0xe2, 0x7b, 0xb3, 0xbe, 0x3f, 0xf3, 0xb0, 0x15, 0xda, 0xcd, 0x7c, 0x7b, 0xdc, 0x1c, 0x8e, - 0xfb, 0x4d, 0xdf, 0x9e, 0x60, 0xe2, 0x9b, 0x13, 0x97, 0x9f, 0xd4, 0x7f, 0x06, 0xd9, 0x27, 0xd8, - 0x24, 0x18, 0x7d, 0x0a, 0xd2, 0xd4, 0xb1, 0xb0, 0x61, 0x5b, 0xaa, 0x50, 0x13, 0x36, 0x4a, 0xad, - 0xad, 0xc5, 0xbc, 0x9a, 0xdb, 0x73, 0x2c, 0xdc, 0xdd, 0x79, 0x35, 0xaf, 0xbe, 0x3f, 0xb0, 0xfd, - 0xe1, 0xac, 0xd7, 0xe8, 0x3b, 0x93, 0x66, 0x14, 0x89, 0xd5, 0x8b, 0x7f, 0x37, 0xdd, 0xd1, 0xa0, - 0x19, 0xb8, 0xd7, 0xe0, 0x66, 0x7a, 0x8e, 0x22, 0x76, 0x2d, 0xb4, 0x06, 0x59, 0xec, 0x3a, 0xfd, - 0xa1, 0x9a, 0xae, 0x09, 0x1b, 0x19, 0x9d, 0x3f, 0x3c, 0x16, 0xff, 0xfb, 0x9b, 0xaa, 0x50, 0xff, - 0x87, 0x00, 0xa5, 0x96, 0xd9, 0x1f, 0xcd, 0xdc, 0x1d, 0xec, 0x9b, 0xf6, 0x98, 0xa0, 0x16, 0x00, - 0xf1, 0x4d, 0xcf, 0x37, 0xa8, 0xaf, 0xcc, 0x99, 0xc2, 0xe6, 0xdb, 0x8d, 0x38, 0x7d, 0x34, 0x96, - 0xc6, 0x70, 0xdc, 0x6f, 0x1c, 0x85, 0xb1, 0xb4, 0xc4, 0x97, 0xf3, 0x6a, 0x4a, 0xcf, 0x33, 0x33, - 0x2a, 0x45, 0x1f, 0x81, 0x8c, 0xa7, 0x16, 0x47, 0x48, 0xdf, 0x1c, 0x41, 0xc2, 0x53, 0x8b, 0xd9, - 0xbf, 0x05, 0x99, 0x99, 0x67, 0xab, 0x99, 0x9a, 0xb0, 0x91, 0x6f, 0x49, 0x8b, 0x79, 0x35, 0x73, - 0xac, 0x77, 0x75, 0x2a, 0x43, 0x8f, 0x60, 0xb5, 0xc7, 0xfc, 0x35, 0x2c, 0x4c, 0xfa, 0x9e, 0xed, - 0xfa, 0x8e, 0xa7, 0x8a, 0x35, 0x61, 0xa3, 0xa8, 0x2b, 0xbd, 0x20, 0x90, 0x50, 0x5e, 0x57, 0xa0, - 0xcc, 0x83, 0x3b, 0xf0, 0x9c, 0x81, 0x87, 0x09, 0xa9, 0x7f, 0x91, 0x85, 0xb2, 0x8e, 0x89, 0xef, - 0x78, 0x38, 0x0c, 0xf8, 0xd7, 0x02, 0x94, 0x7d, 0xb3, 0x37, 0xc6, 0x86, 0x87, 0x9f, 0x7b, 0xb6, - 0x8f, 0x89, 0x9a, 0xae, 0x65, 0x36, 0x0a, 0x9b, 0xdf, 0x69, 0xfc, 0x5f, 0xd2, 0x34, 0x96, 0x31, - 0x1a, 0x47, 0xd4, 0x5e, 0x0f, 0xcc, 0xdb, 0x53, 0xdf, 0x7b, 0xd1, 0xfa, 0xf0, 0xe7, 0xff, 0xbc, - 0xe1, 0x6b, 0x4b, 0x70, 0xa7, 0xd1, 0xdd, 0xd1, 0x4b, 0x7e, 0x12, 0x0c, 0xdd, 0x07, 0x71, 0xe6, - 0xd9, 0x44, 0xcd, 0xd4, 0x32, 0x1b, 0xf9, 0x96, 0xbc, 0x98, 0x57, 0xc5, 0x63, 0xbd, 0x4b, 0x74, - 0x26, 0x5d, 0xca, 0xb4, 0x78, 0x87, 0x4c, 0x7f, 0x0c, 0x05, 0x1e, 0x3b, 0xcd, 0x26, 0x51, 0xb3, - 0x2c, 0xf0, 0x77, 0x2e, 0x04, 0x1e, 0x3a, 0xc7, 0xa2, 0x8c, 0xd3, 0xab, 0x83, 0x1f, 0x0a, 0x08, - 0x6a, 0x42, 0xc1, 0x79, 0x86, 0x3d, 0xcf, 0xb6, 0xb0, 0x61, 0xf5, 0xd4, 0x1c, 0x7b, 0x75, 0xe5, - 0xc5, 0xbc, 0x0a, 0xfb, 0x81, 0x78, 0xa7, 0xa5, 0x43, 0xa8, 0xb2, 0xd3, 0xab, 0xfc, 0x4d, 0x80, - 0x62, 0x32, 0x6d, 0xe8, 0x47, 0x20, 0x73, 0x57, 0xa2, 0x1a, 0x68, 0x2d, 0xe6, 0x55, 0x89, 0xe9, - 0xdc, 0xa2, 0x08, 0x2e, 0x64, 0x53, 0x62, 0x98, 0x5d, 0x0b, 0xfd, 0x18, 0xf2, 0xae, 0xe9, 0xe1, - 0xa9, 0x4f, 0xf1, 0xd3, 0x0c, 0x7f, 0x7b, 0x31, 0xaf, 0xca, 0x07, 0x4c, 0x78, 0xf7, 0x0b, 0x64, - 0x8e, 0xda, 0xb5, 0x2a, 0x3f, 0x05, 0xf4, 0x3a, 0x0f, 0x90, 0x02, 0x99, 0x11, 0x7e, 0xc1, 0x23, - 0xd2, 0xe9, 0x4f, 0xf4, 0x04, 0xb2, 0xcf, 0xcc, 0xf1, 0x2c, 0x2c, 0x8d, 0x0f, 0xee, 0x46, 0x33, - 0x9d, 0x83, 0x3c, 0x4e, 0x7f, 0x4b, 0xd0, 0x44, 0x59, 0x50, 0xd2, 0xf5, 0x6f, 0xc0, 0x4a, 0xa0, - 0x1f, 0xd2, 0x1d, 0xbd, 0x0d, 0x30, 0xb4, 0x07, 0x43, 0xe3, 0xb9, 0xe9, 0x63, 0x8f, 0xf9, 0x50, - 0xd4, 0xf3, 0x54, 0xf2, 0x03, 0x2a, 0xa8, 0xff, 0x25, 0x0b, 0xa5, 0xee, 0xc4, 0x75, 0x3c, 0x3f, - 0x2c, 0x86, 0x27, 0x90, 0x63, 0x09, 0x23, 0xaa, 0xc0, 0xa8, 0xd0, 0xb8, 0xc2, 0xb9, 0x25, 0x4b, - 0xee, 0x5b, 0x40, 0xaf, 0x00, 0x23, 0xe2, 0x6e, 0xfa, 0x52, 0xee, 0x7e, 0x17, 0x72, 0xbc, 0x8b, - 0xb2, 0x42, 0x2f, 0x6c, 0x56, 0x13, 0x77, 0x85, 0xad, 0xac, 0xbb, 0xbf, 0x6b, 0x8f, 0xf1, 0x2e, - 0x53, 0x0b, 0xc1, 0xb9, 0x11, 0x7a, 0x07, 0x64, 0x42, 0x7c, 0x83, 0xd8, 0x9f, 0x71, 0xea, 0x67, - 0x5a, 0x05, 0xca, 0x97, 0xc3, 0xc3, 0xa3, 0x43, 0xfb, 0x33, 0xac, 0x4b, 0x84, 0xf8, 0xf4, 0x07, - 0xaa, 0x80, 0xfc, 0xdc, 0x1c, 0x8f, 0x59, 0x89, 0x64, 0x59, 0x07, 0x8c, 0x9e, 0x97, 0x49, 0x91, - 0xfb, 0x12, 0x48, 0x81, 0xaa, 0x50, 0x08, 0xfa, 0x95, 0x6b, 0xfa, 0x43, 0x55, 0xa2, 0x75, 0xa1, - 0x03, 0x17, 0x1d, 0x98, 0xfe, 0x10, 0xa9, 0x20, 0x11, 0x73, 0xe2, 0xd2, 0x94, 0xcb, 0xb5, 0xcc, - 0x46, 0x51, 0x0f, 0x1f, 0xd1, 0x3a, 0xb0, 0x7a, 0xe1, 0x8f, 0x6a, 0x9e, 0xb9, 0x9e, 0x90, 0xb0, - 0x04, 0x8c, 0x6c, 0xd7, 0x38, 0x19, 0x11, 0x15, 0x6a, 0xc2, 0x86, 0x1c, 0x24, 0x60, 0x64, 0xbb, - 0xbb, 0x9f, 0x10, 0x5d, 0xa2, 0x87, 0xbb, 0x23, 0x52, 0xf9, 0x5c, 0x80, 0x2c, 0x7b, 0x3b, 0xe8, - 0x31, 0x88, 0xb4, 0xce, 0x83, 0xae, 0x7e, 0xd3, 0x32, 0x67, 0x36, 0x08, 0x81, 0x38, 0x35, 0x27, - 0x58, 0x45, 0x2c, 0x02, 0xf6, 0x1b, 0xbd, 0x09, 0x12, 0xc1, 0xa7, 0xc6, 0x33, 0x73, 0xac, 0xde, - 0x63, 0xee, 0xe5, 0x08, 0x3e, 0xfd, 0xbe, 0x39, 0xd6, 0x44, 0x39, 0xad, 0x64, 0x34, 0x51, 0xce, - 0x28, 0xa2, 0x26, 0xca, 0xa2, 0x92, 0xd5, 0x44, 0x39, 0xab, 0xe4, 0x34, 0x51, 0xce, 0x29, 0x92, - 0x26, 0xca, 0x92, 0x22, 0x6b, 0xa2, 0x2c, 0x2b, 0x79, 0x4d, 0x94, 0xf3, 0x0a, 0x68, 0xa2, 0x0c, - 0x4a, 0x41, 0x13, 0xe5, 0x82, 0x52, 0xd4, 0x44, 0xb9, 0xa8, 0x94, 0x34, 0x51, 0x2e, 0x29, 0x65, - 0x4d, 0x94, 0xcb, 0xca, 0x8a, 0x26, 0xca, 0x2b, 0x8a, 0xa2, 0x89, 0xb2, 0xa2, 0xac, 0x6a, 0xa2, - 0xbc, 0xaa, 0xa0, 0xfa, 0x5f, 0x05, 0x28, 0x73, 0xfa, 0x45, 0x54, 0x7f, 0x04, 0xab, 0x2c, 0x2f, - 0xf6, 0x74, 0x60, 0xb8, 0x81, 0x90, 0x91, 0x38, 0xad, 0x2b, 0xe1, 0x41, 0xa4, 0xfc, 0x15, 0x28, - 0x79, 0xd8, 0xb4, 0x62, 0xc5, 0x34, 0x53, 0x2c, 0x52, 0x61, 0xa4, 0xf4, 0x35, 0x28, 0xb3, 0x4a, - 0x8b, 0xb5, 0x32, 0x4c, 0xab, 0xc4, 0xa4, 0x91, 0x5a, 0x0b, 0x4a, 0xc4, 0x35, 0xa7, 0xb1, 0x96, - 0xc8, 0x2a, 0xe7, 0xcd, 0x4b, 0xd8, 0x7c, 0xe8, 0x9a, 0xd3, 0x80, 0xc5, 0x45, 0x6a, 0x13, 0x8d, - 0x25, 0x9d, 0x4d, 0xa5, 0xd9, 0x04, 0x53, 0x8d, 0x27, 0x36, 0xf1, 0xd1, 0xf7, 0xa0, 0xe8, 0x31, - 0x89, 0x41, 0x15, 0xc3, 0x72, 0xbc, 0x06, 0xb4, 0xe0, 0x45, 0x20, 0xa4, 0xfe, 0x27, 0x01, 0xee, - 0x1d, 0xf6, 0x87, 0x78, 0x62, 0x6e, 0x0f, 0xcd, 0xe9, 0x20, 0x9a, 0x77, 0x5b, 0x00, 0x2c, 0x76, - 0x93, 0x18, 0xce, 0xc9, 0x6d, 0x06, 0xbc, 0x4c, 0xcd, 0xb6, 0xc8, 0xfe, 0x09, 0xfa, 0x21, 0x28, - 0x09, 0xe7, 0x8c, 0xb1, 0x4d, 0xfc, 0x60, 0x66, 0x3e, 0xbc, 0xba, 0x99, 0x25, 0x22, 0x0c, 0x40, - 0xcb, 0xde, 0x92, 0xb4, 0xfe, 0x06, 0xac, 0x25, 0x9d, 0x8e, 0x32, 0xd4, 0x02, 0x85, 0x4b, 0x4e, - 0x30, 0xb6, 0x8e, 0x4c, 0x6f, 0x80, 0x7d, 0xd4, 0x80, 0x7b, 0xc4, 0x37, 0x7d, 0x3c, 0xa1, 0x05, - 0x4c, 0xeb, 0xd9, 0x60, 0x0c, 0x15, 0x18, 0x43, 0x57, 0xa3, 0x23, 0x1a, 0xc7, 0x9e, 0x39, 0xc1, - 0xf5, 0x3f, 0x8a, 0xb0, 0x1a, 0x83, 0x84, 0xf9, 0xa0, 0x65, 0x64, 0x4f, 0x47, 0x46, 0xbc, 0x71, - 0xf0, 0x32, 0xb2, 0xa7, 0x23, 0xba, 0x75, 0x48, 0xf4, 0xf0, 0xd8, 0xb3, 0x91, 0x06, 0xa2, 0xe3, - 0xfa, 0xe1, 0xeb, 0xbd, 0xaa, 0x6b, 0xbf, 0x76, 0x47, 0x63, 0xdf, 0xf5, 0xf9, 0x38, 0xd0, 0x19, - 0x06, 0xfa, 0xbd, 0x00, 0x92, 0xcf, 0x82, 0x20, 0x6a, 0x8e, 0xe1, 0x7d, 0xfb, 0x56, 0x78, 0x3c, - 0x01, 0xc1, 0xa6, 0x71, 0x40, 0x13, 0xf9, 0x6a, 0x5e, 0x5d, 0xbd, 0x98, 0x20, 0x72, 0xd7, 0x15, - 0x24, 0xf4, 0x0d, 0x69, 0x50, 0x5e, 0xce, 0x30, 0x6b, 0x60, 0x37, 0xe4, 0x4b, 0x69, 0xe9, 0x0d, - 0x54, 0x06, 0x74, 0xde, 0xc7, 0x6e, 0x5f, 0x32, 0x18, 0xb7, 0x96, 0x07, 0xe3, 0xa3, 0x1b, 0xa5, - 0x84, 0x63, 0x26, 0xa6, 0x61, 0xe5, 0x43, 0xc8, 0x47, 0xf9, 0x4e, 0xde, 0x92, 0xe7, 0xb7, 0xac, - 0x25, 0x6f, 0xc9, 0xbf, 0x36, 0x46, 0xa3, 0xde, 0x95, 0x55, 0x72, 0xf5, 0x5f, 0x08, 0x50, 0xd4, - 0x31, 0x71, 0xc6, 0xcf, 0xb0, 0x45, 0x29, 0x8a, 0xbe, 0x09, 0x22, 0xa5, 0x7c, 0x50, 0x36, 0xd7, - 0x94, 0x23, 0x53, 0x45, 0x5b, 0x90, 0x8f, 0xd6, 0xfe, 0xdb, 0x6c, 0xc3, 0xb1, 0x55, 0xdd, 0x05, - 0x14, 0x07, 0x1c, 0x35, 0x9e, 0x23, 0xa0, 0xc5, 0xc3, 0x7c, 0x0b, 0x9a, 0x04, 0xaf, 0xc1, 0x07, - 0x57, 0xd7, 0x60, 0x14, 0x4c, 0xf8, 0x9a, 0xbc, 0x84, 0x8c, 0x04, 0xbb, 0xc4, 0x22, 0x0b, 0xd2, - 0x81, 0xf9, 0x62, 0xec, 0x98, 0x16, 0xaa, 0x41, 0x21, 0xdc, 0xb5, 0x6d, 0x67, 0x1a, 0xa4, 0x32, - 0x29, 0xa2, 0x23, 0x76, 0x46, 0xb0, 0xc7, 0xaa, 0x8f, 0x67, 0x35, 0x7a, 0xa6, 0x5d, 0x94, 0x7d, - 0x18, 0x60, 0xcb, 0x98, 0xd8, 0x7d, 0xcf, 0x21, 0xac, 0xc8, 0x32, 0x8c, 0x1d, 0x54, 0xfa, 0x94, - 0x09, 0xd1, 0x03, 0x58, 0x39, 0xb1, 0xa7, 0x36, 0x19, 0xc6, 0x7a, 0x6c, 0xa8, 0xeb, 0xe5, 0x50, - 0x1c, 0x28, 0x3a, 0x50, 0x8e, 0x37, 0x7f, 0xc3, 0xb6, 0x78, 0x01, 0x95, 0x5a, 0x9d, 0xc5, 0xbc, - 0x5a, 0x8a, 0xa7, 0x56, 0x77, 0x87, 0xdc, 0x75, 0x78, 0x97, 0x62, 0xfc, 0xae, 0x45, 0xd8, 0xe7, - 0x93, 0xe7, 0x39, 0x9e, 0x2a, 0x73, 0xbe, 0xb0, 0x07, 0xf4, 0x01, 0x64, 0xc7, 0xf4, 0xcb, 0x8d, - 0xcd, 0xe5, 0xc2, 0x66, 0xed, 0x8a, 0x9c, 0xb3, 0x2f, 0x3c, 0x9d, 0xab, 0xa3, 0x16, 0xe4, 0xf8, - 0xf0, 0x67, 0x23, 0xbb, 0xb0, 0xb9, 0x71, 0x85, 0xe1, 0xd2, 0x87, 0x59, 0x27, 0xa5, 0x07, 0x96, - 0xa8, 0x0d, 0x92, 0xc7, 0x17, 0x3d, 0xb5, 0xc0, 0x40, 0x1e, 0xde, 0x78, 0x85, 0xec, 0xa4, 0xf4, - 0xd0, 0x16, 0x1d, 0x41, 0x91, 0x24, 0x5a, 0xad, 0x5a, 0x64, 0x58, 0x57, 0x6d, 0x7c, 0x97, 0x8c, - 0x93, 0x0e, 0x1d, 0x65, 0x09, 0x31, 0x0d, 0xd0, 0x66, 0x93, 0x59, 0x2d, 0x5d, 0x1b, 0xe0, 0xd2, - 0x06, 0x49, 0x03, 0xe4, 0x96, 0x68, 0x0f, 0xa0, 0x1f, 0xf1, 0x5d, 0x2d, 0x33, 0x9c, 0xaf, 0xdf, - 0xa6, 0x41, 0x76, 0x52, 0x7a, 0x02, 0xa1, 0x95, 0x07, 0xc9, 0xe2, 0x07, 0xd1, 0x1e, 0x22, 0x29, - 0x72, 0xfd, 0xcf, 0x22, 0xc8, 0x51, 0x35, 0x35, 0x01, 0x9d, 0x78, 0x66, 0x9f, 0xf2, 0xd9, 0xe8, - 0x3b, 0x74, 0xc1, 0xf2, 0x31, 0xff, 0x10, 0x49, 0x77, 0x52, 0xfa, 0x6a, 0x78, 0xb6, 0x1d, 0x1e, - 0x51, 0xc6, 0x4e, 0x1c, 0xcb, 0x3e, 0xb1, 0x63, 0xc6, 0xf2, 0x0f, 0xec, 0x72, 0x28, 0x0e, 0x18, - 0xfb, 0xd1, 0xd2, 0x12, 0x9e, 0xb9, 0x41, 0x07, 0xe8, 0xa4, 0x12, 0x5b, 0x3a, 0xda, 0xbe, 0x40, - 0x99, 0x87, 0xd7, 0x52, 0x26, 0x0c, 0xaa, 0x23, 0x44, 0x9c, 0xd9, 0xbd, 0xc8, 0x99, 0x77, 0xaf, - 0xe7, 0x4c, 0x02, 0x26, 0x22, 0xcd, 0xf1, 0xa5, 0xa4, 0x69, 0xde, 0x90, 0x34, 0x09, 0xc4, 0x65, - 0xd6, 0x6c, 0x5f, 0x60, 0xcd, 0xc3, 0x6b, 0x59, 0x93, 0x8c, 0x31, 0xa0, 0xcd, 0xfe, 0x25, 0xb4, - 0x79, 0xef, 0x46, 0xb4, 0x49, 0x80, 0x25, 0x79, 0x03, 0x20, 0x87, 0x5b, 0x5d, 0x82, 0x43, 0xef, - 0x7e, 0x21, 0x80, 0x78, 0xf4, 0xc2, 0xc5, 0xe8, 0xab, 0x50, 0x38, 0xde, 0x3b, 0x3c, 0x68, 0x6f, - 0x77, 0x77, 0xbb, 0xed, 0x1d, 0x25, 0x55, 0xb9, 0x77, 0x76, 0x5e, 0x5b, 0xa1, 0x47, 0xc7, 0x53, - 0xe2, 0xe2, 0x3e, 0x63, 0x01, 0xaa, 0x40, 0xae, 0xb5, 0xb5, 0xfd, 0xc9, 0xf1, 0x81, 0x22, 0x54, - 0xca, 0x67, 0xe7, 0x35, 0xa0, 0x0a, 0xfc, 0x45, 0xa1, 0xfb, 0x20, 0xe9, 0xed, 0xc3, 0xa3, 0x7d, - 0xbd, 0xad, 0xa4, 0x2b, 0x2b, 0x67, 0xe7, 0xb5, 0x02, 0x3d, 0x0c, 0xf2, 0x8f, 0x1e, 0x40, 0xe9, - 0x70, 0xbb, 0xd3, 0x7e, 0xba, 0x65, 0x6c, 0x77, 0xb6, 0xf6, 0x3e, 0x6e, 0x2b, 0x99, 0xca, 0xda, - 0xd9, 0x79, 0x4d, 0xa1, 0x3a, 0xc9, 0xb4, 0xd2, 0x2b, 0xba, 0x4f, 0x0f, 0xf6, 0xf5, 0x23, 0x45, - 0x8c, 0xaf, 0xe0, 0x79, 0x42, 0x75, 0x00, 0x6e, 0xbd, 0xdb, 0x6e, 0xef, 0x28, 0xd9, 0x0a, 0x3a, - 0x3b, 0xaf, 0x95, 0xe9, 0x79, 0x1c, 0x7e, 0x45, 0xfe, 0xe5, 0x6f, 0xd7, 0x53, 0x7f, 0xf8, 0xdd, - 0x7a, 0xaa, 0x55, 0x7b, 0xf9, 0xef, 0xf5, 0xd4, 0xcb, 0xc5, 0xba, 0xf0, 0xf9, 0x62, 0x5d, 0xf8, - 0xfb, 0x62, 0x5d, 0xf8, 0xd7, 0x62, 0x5d, 0xf8, 0xd5, 0x7f, 0xd6, 0x53, 0x9f, 0xe6, 0x78, 0xd6, - 0x7a, 0x39, 0xf6, 0xa7, 0xab, 0xf7, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xfd, 0x1b, 0xc6, - 0x6b, 0x13, 0x00, 0x00, + // 2172 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xdf, 0x6f, 0xe3, 0x58, + 0xf5, 0x8f, 0x13, 0x27, 0x71, 0x4e, 0x7e, 0xd4, 0xbd, 0x53, 0xed, 0x78, 0xf3, 0x9d, 0x6d, 0xa2, + 0x7c, 0x61, 0xa7, 0xb3, 0xc3, 0x26, 0xd0, 0xd1, 0xee, 0xc0, 0x08, 0x56, 0xe4, 0x57, 0x5b, 0x67, + 0xa6, 0x4d, 0xe5, 0xb6, 0x3b, 0x62, 0x11, 0x32, 0x4e, 0x7c, 0x9b, 0x98, 0xfc, 0xb0, 0xc7, 0xd7, + 0x99, 0x61, 0xf6, 0x05, 0x09, 0xf1, 0x80, 0xfa, 0xb4, 0x7f, 0x00, 0x95, 0x90, 0x00, 0x89, 0x37, + 0x9e, 0x40, 0xe2, 0x3f, 0x98, 0x17, 0xc4, 0x3e, 0xb2, 0x42, 0x2a, 0x10, 0x5e, 0xf8, 0x1b, 0x56, + 0x42, 0x42, 0xf7, 0x5e, 0xdb, 0x71, 0x3a, 0xa5, 0xed, 0x54, 0xe2, 0xa5, 0xb5, 0xcf, 0x3d, 0xe7, + 0xe3, 0x73, 0xce, 0xfd, 0x9c, 0x73, 0xcf, 0x0d, 0xbc, 0xf5, 0x23, 0xbb, 0x47, 0x6a, 0xf4, 0x8f, + 0xd3, 0x63, 0xff, 0xaa, 0x8e, 0x6b, 0x7b, 0x36, 0x7a, 0xbb, 0x6f, 0xf7, 0x47, 0xae, 0x6d, 0xf4, + 0x87, 0x55, 0xf2, 0x6c, 0x5c, 0x65, 0x2b, 0x5c, 0xab, 0xb8, 0x36, 0xb0, 0x07, 0x36, 0xd3, 0xaa, + 0xd1, 0x27, 0x6e, 0x50, 0x44, 0x4c, 0xd9, 0xe9, 0xd5, 0x4c, 0xc3, 0x33, 0x7c, 0x99, 0x12, 0xc8, + 0x2c, 0xfb, 0xfd, 0x63, 0xdb, 0x9d, 0x18, 0x9e, 0x0f, 0x5f, 0xbc, 0x43, 0x9e, 0x8d, 0x6b, 0xe4, + 0xd9, 0xb8, 0x67, 0x10, 0x5c, 0x23, 0x9e, 0x3b, 0xeb, 0x7b, 0x33, 0x17, 0x9b, 0x81, 0xdd, 0xcc, + 0xb3, 0xc6, 0xb5, 0xe1, 0xb8, 0x5f, 0xf3, 0xac, 0x09, 0x26, 0x9e, 0x31, 0x71, 0xf8, 0x4a, 0xe5, + 0x27, 0x90, 0x7c, 0x82, 0x0d, 0x82, 0xd1, 0x27, 0x90, 0x9e, 0xda, 0x26, 0xd6, 0x2d, 0x53, 0x11, + 0xca, 0xc2, 0x46, 0xbe, 0x51, 0x9f, 0x9f, 0x95, 0x52, 0x7b, 0xb6, 0x89, 0xd5, 0xd6, 0x97, 0x67, + 0xa5, 0x07, 0x03, 0xcb, 0x1b, 0xce, 0x7a, 0xd5, 0xbe, 0x3d, 0xa9, 0x85, 0x91, 0x98, 0xbd, 0xc5, + 0x73, 0xcd, 0x19, 0x0d, 0x6a, 0xbe, 0x7b, 0x55, 0x6e, 0xa6, 0xa5, 0x28, 0xa2, 0x6a, 0xa2, 0x35, + 0x48, 0x62, 0xc7, 0xee, 0x0f, 0x95, 0x78, 0x59, 0xd8, 0x48, 0x68, 0xfc, 0xe5, 0x91, 0xf8, 0xaf, + 0x5f, 0x96, 0x84, 0xca, 0x5f, 0x05, 0xc8, 0x37, 0x8c, 0xfe, 0x68, 0xe6, 0xb4, 0xb0, 0x67, 0x58, + 0x63, 0x82, 0x1a, 0x00, 0xc4, 0x33, 0x5c, 0x4f, 0xa7, 0xbe, 0x32, 0x67, 0xb2, 0x9b, 0xef, 0x54, + 0x17, 0xe9, 0xa3, 0xb1, 0x54, 0x87, 0xe3, 0x7e, 0xf5, 0x30, 0x88, 0xa5, 0x21, 0xbe, 0x3a, 0x2b, + 0xc5, 0xb4, 0x0c, 0x33, 0xa3, 0x52, 0xf4, 0x11, 0x48, 0x78, 0x6a, 0x72, 0x84, 0xf8, 0xf5, 0x11, + 0xd2, 0x78, 0x6a, 0x32, 0xfb, 0xb7, 0x21, 0x31, 0x73, 0x2d, 0x25, 0x51, 0x16, 0x36, 0x32, 0x8d, + 0xf4, 0xfc, 0xac, 0x94, 0x38, 0xd2, 0x54, 0x8d, 0xca, 0xd0, 0x7d, 0x58, 0xed, 0x31, 0x7f, 0x75, + 0x13, 0x93, 0xbe, 0x6b, 0x39, 0x9e, 0xed, 0x2a, 0x62, 0x59, 0xd8, 0xc8, 0x69, 0x72, 0xcf, 0x0f, + 0x24, 0x90, 0x57, 0x64, 0x28, 0xf0, 0xe0, 0xf6, 0x5d, 0x7b, 0xe0, 0x62, 0x42, 0x2a, 0x5f, 0x24, + 0xa1, 0xa0, 0x61, 0xe2, 0xd9, 0x2e, 0x0e, 0x02, 0xfe, 0x85, 0x00, 0x05, 0xcf, 0xe8, 0x8d, 0xb1, + 0xee, 0xe2, 0x17, 0xae, 0xe5, 0x61, 0xa2, 0xc4, 0xcb, 0x89, 0x8d, 0xec, 0xe6, 0xb7, 0xab, 0xff, + 0x95, 0x34, 0xd5, 0x65, 0x8c, 0xea, 0x21, 0xb5, 0xd7, 0x7c, 0xf3, 0xf6, 0xd4, 0x73, 0x5f, 0x36, + 0x1e, 0xfe, 0xf4, 0x6f, 0xd7, 0xdc, 0xb6, 0x08, 0x77, 0xaa, 0x6a, 0x4b, 0xcb, 0x7b, 0x51, 0x30, + 0x74, 0x07, 0xc4, 0x99, 0x6b, 0x11, 0x25, 0x51, 0x4e, 0x6c, 0x64, 0x1a, 0xd2, 0xfc, 0xac, 0x24, + 0x1e, 0x69, 0x2a, 0xd1, 0x98, 0x74, 0x29, 0xd3, 0xe2, 0x0d, 0x32, 0xbd, 0x0d, 0x59, 0x1e, 0x3b, + 0xcd, 0x26, 0x51, 0x92, 0x2c, 0xf0, 0x77, 0xcf, 0x05, 0x1e, 0x38, 0xc7, 0xa2, 0x5c, 0xa4, 0x57, + 0x03, 0x2f, 0x10, 0x10, 0x54, 0x83, 0xac, 0xfd, 0x1c, 0xbb, 0xae, 0x65, 0x62, 0xdd, 0xec, 0x29, + 0x29, 0xb6, 0x75, 0x85, 0xf9, 0x59, 0x09, 0xba, 0xbe, 0xb8, 0xd5, 0xd0, 0x20, 0x50, 0x69, 0xf5, + 0x8a, 0x7f, 0x16, 0x20, 0x17, 0x4d, 0x1b, 0xfa, 0x01, 0x48, 0xdc, 0x95, 0xb0, 0x06, 0x1a, 0xf3, + 0xb3, 0x52, 0x9a, 0xe9, 0xbc, 0x41, 0x11, 0x9c, 0xcb, 0x66, 0x9a, 0x61, 0xaa, 0x26, 0xfa, 0x21, + 0x64, 0x1c, 0xc3, 0xc5, 0x53, 0x8f, 0xe2, 0xc7, 0x19, 0x7e, 0x73, 0x7e, 0x56, 0x92, 0xf6, 0x99, + 0xf0, 0xe6, 0x1f, 0x90, 0x38, 0xaa, 0x6a, 0x16, 0x7f, 0x0c, 0xe8, 0x75, 0x1e, 0x20, 0x19, 0x12, + 0x23, 0xfc, 0x92, 0x47, 0xa4, 0xd1, 0x47, 0xf4, 0x04, 0x92, 0xcf, 0x8d, 0xf1, 0x2c, 0x28, 0x8d, + 0x0f, 0x6f, 0x46, 0x33, 0x8d, 0x83, 0x3c, 0x8a, 0x7f, 0x53, 0xe8, 0x88, 0x92, 0x20, 0xc7, 0x2b, + 0x5f, 0x87, 0x15, 0x5f, 0x3f, 0xa0, 0x3b, 0x7a, 0x07, 0x60, 0x68, 0x0d, 0x86, 0xfa, 0x0b, 0xc3, + 0xc3, 0x2e, 0xf3, 0x21, 0xa7, 0x65, 0xa8, 0xe4, 0x29, 0x15, 0x54, 0xfe, 0x90, 0x84, 0xbc, 0x3a, + 0x71, 0x6c, 0xd7, 0x0b, 0x8a, 0xe1, 0x09, 0xa4, 0x58, 0xc2, 0x88, 0x22, 0x30, 0x2a, 0x54, 0x2f, + 0x71, 0x6e, 0xc9, 0x92, 0xfb, 0xe6, 0xd3, 0xcb, 0xc7, 0x08, 0xb9, 0x1b, 0xbf, 0x90, 0xbb, 0xdf, + 0x81, 0x14, 0xef, 0xa2, 0xac, 0xd0, 0xb3, 0x9b, 0xa5, 0xc8, 0xb7, 0x82, 0x56, 0xa6, 0x76, 0xb7, + 0xac, 0x31, 0xde, 0x62, 0x6a, 0x01, 0x38, 0x37, 0x42, 0xef, 0x82, 0x44, 0x88, 0xa7, 0x13, 0xeb, + 0x53, 0x4e, 0xfd, 0x44, 0x23, 0x4b, 0xf9, 0x72, 0x70, 0x70, 0x78, 0x60, 0x7d, 0x8a, 0xb5, 0x34, + 0x21, 0x1e, 0x7d, 0x40, 0x45, 0x90, 0x5e, 0x18, 0xe3, 0x31, 0x2b, 0x91, 0x24, 0xeb, 0x80, 0xe1, + 0xfb, 0x32, 0x29, 0x52, 0xff, 0x03, 0x52, 0xa0, 0x12, 0x64, 0xfd, 0x7e, 0xe5, 0x18, 0xde, 0x50, + 0x49, 0xd3, 0xba, 0xd0, 0x80, 0x8b, 0xf6, 0x0d, 0x6f, 0x88, 0x14, 0x48, 0x13, 0x63, 0xe2, 0xd0, + 0x94, 0x4b, 0xe5, 0xc4, 0x46, 0x4e, 0x0b, 0x5e, 0xd1, 0x3a, 0xb0, 0x7a, 0xe1, 0xaf, 0x4a, 0x86, + 0xb9, 0x1e, 0x91, 0xb0, 0x04, 0x8c, 0x2c, 0x47, 0x3f, 0x1e, 0x11, 0x05, 0xca, 0xc2, 0x86, 0xe4, + 0x27, 0x60, 0x64, 0x39, 0x5b, 0x8f, 0x89, 0x96, 0xa6, 0x8b, 0x5b, 0x23, 0x52, 0xfc, 0x5c, 0x80, + 0x24, 0xdb, 0x1d, 0xf4, 0x08, 0x44, 0x5a, 0xe7, 0x7e, 0x57, 0xbf, 0x6e, 0x99, 0x33, 0x1b, 0x84, + 0x40, 0x9c, 0x1a, 0x13, 0xac, 0x20, 0x16, 0x01, 0x7b, 0x46, 0xb7, 0x21, 0x4d, 0xf0, 0x33, 0xfd, + 0xb9, 0x31, 0x56, 0x6e, 0x31, 0xf7, 0x52, 0x04, 0x3f, 0xfb, 0xd8, 0x18, 0x77, 0x44, 0x29, 0x2e, + 0x27, 0x3a, 0xa2, 0x94, 0x90, 0xc5, 0x8e, 0x28, 0x89, 0x72, 0xb2, 0x23, 0x4a, 0x49, 0x39, 0xd5, + 0x11, 0xa5, 0x94, 0x9c, 0xee, 0x88, 0x52, 0x5a, 0x96, 0x3a, 0xa2, 0x24, 0xc9, 0x99, 0x8e, 0x28, + 0x65, 0x64, 0xe8, 0x88, 0x12, 0xc8, 0xd9, 0x8e, 0x28, 0x65, 0xe5, 0x5c, 0x47, 0x94, 0x72, 0x72, + 0xbe, 0x23, 0x4a, 0x79, 0xb9, 0xd0, 0x11, 0xa5, 0x82, 0xbc, 0xd2, 0x11, 0xa5, 0x15, 0x59, 0xee, + 0x88, 0x92, 0x2c, 0xaf, 0x76, 0x44, 0x69, 0x55, 0x46, 0x95, 0x3f, 0x09, 0x50, 0xe0, 0xf4, 0x0b, + 0xa9, 0x7e, 0x1f, 0x56, 0x59, 0x5e, 0xac, 0xe9, 0x40, 0x77, 0x7c, 0x21, 0x23, 0x71, 0x5c, 0x93, + 0x83, 0x85, 0x50, 0xf9, 0xff, 0x21, 0xef, 0x62, 0xc3, 0x5c, 0x28, 0xc6, 0x99, 0x62, 0x8e, 0x0a, + 0x43, 0xa5, 0xaf, 0x42, 0x81, 0x55, 0xda, 0x42, 0x2b, 0xc1, 0xb4, 0xf2, 0x4c, 0x1a, 0xaa, 0x35, + 0x20, 0x4f, 0x1c, 0x63, 0xba, 0xd0, 0x12, 0x59, 0xe5, 0xdc, 0xbe, 0x80, 0xcd, 0x07, 0x8e, 0x31, + 0xf5, 0x59, 0x9c, 0xa3, 0x36, 0xe1, 0xb1, 0xa4, 0xb1, 0x53, 0x69, 0x36, 0xc1, 0x54, 0xe3, 0x89, + 0x45, 0x3c, 0xf4, 0x5d, 0xc8, 0xb9, 0x4c, 0xa2, 0x53, 0xc5, 0xa0, 0x1c, 0xaf, 0x00, 0xcd, 0xba, + 0x21, 0x08, 0xa9, 0xfc, 0x3b, 0x0e, 0xb7, 0x5a, 0xae, 0xed, 0x38, 0xd8, 0xf4, 0x77, 0x94, 0x97, + 0x78, 0xb0, 0x91, 0x42, 0x64, 0x23, 0xb7, 0x21, 0xae, 0xb6, 0xfc, 0xae, 0xf8, 0xf0, 0xa6, 0xa4, + 0x8f, 0xab, 0x2d, 0xb4, 0x0b, 0x29, 0xe2, 0x19, 0xde, 0x8c, 0xb0, 0x9a, 0x2e, 0x6c, 0x7e, 0x70, + 0x49, 0xff, 0xb8, 0xc0, 0xb9, 0xea, 0x01, 0x33, 0xd6, 0x7c, 0x90, 0xca, 0x1f, 0x05, 0x48, 0x71, + 0x11, 0xba, 0x07, 0xf9, 0x96, 0x56, 0x57, 0xf7, 0xd4, 0xbd, 0x6d, 0x7d, 0xaf, 0xbe, 0xdb, 0x96, + 0x63, 0xc5, 0xb7, 0x4e, 0x4e, 0xcb, 0x88, 0x2f, 0xb7, 0x5c, 0xc3, 0x9a, 0x5a, 0xd3, 0xc1, 0x1e, + 0x8d, 0xe6, 0x03, 0x58, 0x7b, 0x5a, 0x57, 0x0f, 0xf5, 0xad, 0xae, 0xa6, 0x6f, 0x37, 0x75, 0x75, + 0xef, 0xb0, 0xad, 0x7d, 0x5c, 0x7f, 0x22, 0x0b, 0xc5, 0xff, 0x3b, 0x39, 0x2d, 0xdf, 0xe6, 0x16, + 0x4f, 0x0d, 0xcb, 0xdb, 0xb2, 0xdd, 0xed, 0xa6, 0x3a, 0xf5, 0xb0, 0xfb, 0xdc, 0x18, 0xa3, 0x07, + 0x80, 0xb4, 0x6e, 0xf3, 0xf1, 0x41, 0xab, 0xa1, 0x37, 0xbb, 0xbb, 0xfb, 0xf5, 0xe6, 0xa1, 0xda, + 0xdd, 0x93, 0xe3, 0x51, 0x23, 0xcd, 0xee, 0x8f, 0x48, 0xab, 0xd1, 0xb4, 0x27, 0x8e, 0xd1, 0xf7, + 0x2c, 0x7b, 0x8a, 0x14, 0x10, 0x5b, 0xdd, 0xbd, 0xb6, 0x0c, 0xc5, 0xc2, 0xc9, 0x69, 0x19, 0x7c, + 0x6f, 0xec, 0x29, 0xae, 0x7c, 0x16, 0x87, 0x5b, 0x07, 0xfd, 0x21, 0x9e, 0x18, 0xcd, 0xa1, 0x31, + 0x1d, 0x84, 0xf9, 0xaf, 0x03, 0x30, 0xee, 0x19, 0x44, 0xb7, 0x8f, 0xdf, 0x64, 0xc0, 0x92, 0xa8, + 0x59, 0x9d, 0x74, 0x8f, 0xd1, 0xf7, 0x40, 0x8e, 0x90, 0x43, 0x1f, 0x5b, 0xc4, 0xf3, 0x67, 0x96, + 0x7b, 0x97, 0x1f, 0x26, 0x11, 0x86, 0xf9, 0xa0, 0x05, 0x77, 0x99, 0x77, 0xdf, 0x87, 0x82, 0xc9, + 0xf7, 0x45, 0xf7, 0x0f, 0x82, 0xc4, 0x95, 0x07, 0xc1, 0x05, 0x1b, 0xe9, 0xa3, 0xe7, 0xcd, 0xc8, + 0x12, 0xa9, 0xbc, 0x05, 0x6b, 0xd1, 0x8c, 0x84, 0xf4, 0x6f, 0x80, 0xcc, 0x25, 0xc7, 0x98, 0xea, + 0xba, 0x03, 0xec, 0xa1, 0x2a, 0xdc, 0xa2, 0x24, 0xc0, 0x13, 0xda, 0x9d, 0x69, 0xb3, 0xd6, 0x23, + 0xac, 0x5d, 0x0d, 0x97, 0x68, 0x92, 0xe8, 0xa6, 0x57, 0x7e, 0x27, 0xc2, 0xea, 0x02, 0x24, 0x48, + 0x36, 0xed, 0x91, 0xd6, 0x74, 0xa4, 0x2f, 0xc6, 0x49, 0xde, 0x23, 0xad, 0xe9, 0x88, 0x8e, 0x94, + 0x69, 0xba, 0x78, 0xe4, 0x5a, 0xa8, 0x03, 0xa2, 0xed, 0x78, 0x41, 0xed, 0x5e, 0x76, 0x24, 0xbf, + 0xf6, 0x8d, 0x6a, 0xd7, 0xf1, 0xf8, 0x59, 0xaf, 0x31, 0x0c, 0xf4, 0x1b, 0x01, 0xd2, 0x1e, 0x0b, + 0x82, 0x28, 0x29, 0x86, 0xf7, 0xad, 0x37, 0xc2, 0xe3, 0x09, 0xf0, 0xc7, 0xc8, 0x7d, 0x9a, 0xc7, + 0x2f, 0xcf, 0x4a, 0xab, 0xe7, 0x13, 0x44, 0x6e, 0x3a, 0x5f, 0x06, 0xbe, 0xa1, 0x0e, 0x14, 0x96, + 0x33, 0xcc, 0x4e, 0xa7, 0x6b, 0x92, 0x31, 0xbf, 0xb4, 0x03, 0xc5, 0x01, 0x1d, 0xe6, 0x16, 0x6e, + 0x5f, 0x30, 0xf5, 0xd4, 0x97, 0xa7, 0x9e, 0xfb, 0xd7, 0x4a, 0x09, 0xc7, 0x8c, 0x8c, 0x3a, 0xc5, + 0x87, 0x90, 0x09, 0xf3, 0x1d, 0xfd, 0x4a, 0x86, 0x7f, 0x65, 0x2d, 0xfa, 0x95, 0xcc, 0x6b, 0x33, + 0x52, 0x78, 0x30, 0x25, 0xe5, 0x54, 0xe5, 0x67, 0x02, 0xe4, 0x34, 0x4c, 0xec, 0xf1, 0x73, 0x6c, + 0x52, 0xfe, 0xa3, 0x6f, 0x80, 0x48, 0xeb, 0xc9, 0xaf, 0xc9, 0x2b, 0x7a, 0x2d, 0x53, 0x45, 0x75, + 0xc8, 0x84, 0x77, 0xba, 0x37, 0xb9, 0xea, 0x2c, 0xac, 0x2a, 0x0e, 0xa0, 0x45, 0xc0, 0xe1, 0xa9, + 0x72, 0x08, 0xb4, 0x32, 0x99, 0x6f, 0xfe, 0x09, 0xc0, 0x0b, 0xfc, 0xee, 0xe5, 0x05, 0x1e, 0x06, + 0x13, 0x6c, 0x93, 0x1b, 0x91, 0x11, 0x7f, 0x50, 0x9c, 0x27, 0x21, 0xbd, 0x6f, 0xbc, 0x1c, 0xdb, + 0x86, 0x89, 0xca, 0x90, 0x0d, 0x2e, 0x52, 0x96, 0x3d, 0xf5, 0x53, 0x19, 0x15, 0xd1, 0xf9, 0x69, + 0x46, 0xb0, 0xcb, 0xaa, 0x8f, 0x67, 0x35, 0x7c, 0xa7, 0x47, 0x24, 0xbb, 0xf5, 0x61, 0x53, 0x9f, + 0x58, 0x7d, 0xd7, 0xe6, 0x6d, 0x3f, 0xc1, 0xd8, 0x41, 0xa5, 0xbb, 0x4c, 0x88, 0xee, 0xc2, 0xca, + 0xb1, 0x35, 0xb5, 0xc8, 0x70, 0xa1, 0xc7, 0x26, 0x36, 0xad, 0x10, 0x88, 0x7d, 0x45, 0x1b, 0x0a, + 0x8b, 0x6b, 0x9d, 0x6e, 0x99, 0xbc, 0x80, 0xf2, 0x8d, 0x9d, 0xf9, 0x59, 0x29, 0xbf, 0x18, 0x49, + 0xd4, 0x16, 0xb9, 0xe9, 0x21, 0x95, 0x5f, 0xe0, 0xab, 0x26, 0x61, 0x77, 0x63, 0xd7, 0xb5, 0x5d, + 0x45, 0xe2, 0x7c, 0x61, 0x2f, 0xe8, 0x43, 0x48, 0x8e, 0xe9, 0xb5, 0x9c, 0x0d, 0x5d, 0xd9, 0xcd, + 0xf2, 0x25, 0x39, 0x67, 0xd7, 0x77, 0x8d, 0xab, 0xa3, 0x06, 0xa4, 0xf8, 0x64, 0xc7, 0xe6, 0xb1, + 0xec, 0xe6, 0xc6, 0x25, 0x86, 0x4b, 0xb7, 0xee, 0x9d, 0x98, 0xe6, 0x5b, 0xa2, 0x36, 0xa4, 0x5d, + 0x3e, 0xc5, 0x2b, 0x59, 0x06, 0x72, 0xef, 0xda, 0xf7, 0x83, 0x9d, 0x98, 0x16, 0xd8, 0xa2, 0x43, + 0xc8, 0x91, 0x48, 0xab, 0x55, 0x72, 0x0c, 0xeb, 0xb2, 0x2e, 0x7e, 0xc1, 0x59, 0xb5, 0x43, 0xe7, + 0x94, 0x88, 0x98, 0x06, 0x68, 0xb1, 0xb1, 0x4b, 0xc9, 0x5f, 0x19, 0xe0, 0xd2, 0xf5, 0x80, 0x06, + 0xc8, 0x2d, 0xd1, 0x1e, 0x40, 0x3f, 0xe4, 0xbb, 0x52, 0x60, 0x38, 0x5f, 0x7b, 0x93, 0x06, 0xb9, + 0x13, 0xd3, 0x22, 0x08, 0x8d, 0x0c, 0xa4, 0x4d, 0xbe, 0x10, 0x0e, 0x99, 0x69, 0x59, 0xaa, 0xfc, + 0x5e, 0x04, 0x29, 0xac, 0xa6, 0x1a, 0xa0, 0x63, 0x97, 0x9f, 0xd8, 0x7a, 0xdf, 0xa6, 0xd3, 0xb3, + 0x87, 0xf9, 0x2d, 0x33, 0xbe, 0x13, 0xd3, 0x56, 0x83, 0xb5, 0x66, 0xb0, 0x44, 0x19, 0x3b, 0xb1, + 0x4d, 0xeb, 0xd8, 0x5a, 0x30, 0x96, 0xff, 0x7a, 0x52, 0x08, 0xc4, 0x3e, 0x63, 0x3f, 0x5a, 0xba, + 0x61, 0x25, 0xae, 0xd1, 0x01, 0x76, 0x62, 0x91, 0x2b, 0x18, 0x6a, 0x9e, 0xa3, 0xcc, 0xbd, 0x2b, + 0x29, 0x13, 0x04, 0xb5, 0x23, 0x84, 0x9c, 0xd9, 0x3a, 0xcf, 0x99, 0xf7, 0xae, 0xe6, 0x4c, 0x04, + 0x26, 0x24, 0xcd, 0xd1, 0x85, 0xa4, 0xa9, 0x5d, 0x93, 0x34, 0x11, 0xc4, 0x65, 0xd6, 0x34, 0xcf, + 0xb1, 0xe6, 0xde, 0x95, 0xac, 0x89, 0xc6, 0xe8, 0xd3, 0xa6, 0x7b, 0x01, 0x6d, 0xde, 0xbf, 0x16, + 0x6d, 0x22, 0x60, 0x51, 0xde, 0x00, 0x48, 0xc1, 0xc8, 0x1e, 0xe1, 0xd0, 0x7b, 0x5f, 0x08, 0x20, + 0x1e, 0xbe, 0x74, 0x30, 0xfa, 0x0a, 0x64, 0x8f, 0xf6, 0x0e, 0xf6, 0xdb, 0x4d, 0x75, 0x4b, 0x6d, + 0xb7, 0xe4, 0x58, 0xf1, 0xd6, 0xc9, 0x69, 0x79, 0x85, 0x2e, 0x1d, 0x4d, 0x89, 0x83, 0xfb, 0x8c, + 0x05, 0xa8, 0x08, 0xa9, 0x46, 0xbd, 0xf9, 0xf8, 0x68, 0x5f, 0x16, 0xf8, 0x04, 0x48, 0x15, 0xf8, + 0x46, 0xa1, 0x3b, 0x90, 0xd6, 0xda, 0x07, 0x87, 0x5d, 0xad, 0x2d, 0xc7, 0x8b, 0x2b, 0x27, 0xa7, + 0xe5, 0x2c, 0x5d, 0xf4, 0xf3, 0x8f, 0xee, 0x42, 0xfe, 0xa0, 0xb9, 0xd3, 0xde, 0xad, 0xeb, 0xcd, + 0x9d, 0xfa, 0xde, 0x76, 0x5b, 0x4e, 0x14, 0xd7, 0x4e, 0x4e, 0xcb, 0x32, 0xd5, 0x89, 0xa6, 0x95, + 0x7e, 0x42, 0xdd, 0xdd, 0xef, 0x6a, 0x87, 0xb2, 0xb8, 0xf8, 0x04, 0xcf, 0x13, 0xaa, 0x00, 0x70, + 0xeb, 0xad, 0x76, 0xbb, 0x25, 0x27, 0x8b, 0xe8, 0xe4, 0xb4, 0x5c, 0xa0, 0xeb, 0x8b, 0xf0, 0x8b, + 0xd2, 0xcf, 0x7f, 0xb5, 0x1e, 0xfb, 0xed, 0xaf, 0xd7, 0x63, 0x8d, 0xf2, 0xab, 0x7f, 0xac, 0xc7, + 0x5e, 0xcd, 0xd7, 0x85, 0xcf, 0xe7, 0xeb, 0xc2, 0x5f, 0xe6, 0xeb, 0xc2, 0xdf, 0xe7, 0xeb, 0xc2, + 0x67, 0xff, 0x5c, 0x8f, 0x7d, 0x92, 0xe2, 0x59, 0xeb, 0xa5, 0xd8, 0xef, 0x92, 0x0f, 0xfe, 0x13, + 0x00, 0x00, 0xff, 0xff, 0x63, 0xb8, 0x2f, 0x3a, 0x48, 0x15, 0x00, 0x00, } diff --git a/pkg/jobs/jobspb/jobs.proto b/pkg/jobs/jobspb/jobs.proto index 1a488d355b25..5d6f3dbcc638 100644 --- a/pkg/jobs/jobspb/jobs.proto +++ b/pkg/jobs/jobspb/jobs.proto @@ -112,6 +112,18 @@ message ResumeSpanList { repeated roachpb.Span resume_spans = 1 [(gogoproto.nullable) = false]; } +message DroppedTableDetails { + enum Status { + DRAINING_NAME = 0 [(gogoproto.enumvalue_customname) = "StatusDrainingName"]; + WAIT_FOR_GC_INTERVAL = 1 [(gogoproto.enumvalue_customname) = "StatusWaitForGCInterval"]; + ROCKSDB_COMPACTION = 2 [(gogoproto.enumvalue_customname) = "StatusRocksDBCompaction"]; + DONE = 10 [(gogoproto.enumvalue_customname) = "StatusDone"]; + } + string name = 1; + uint32 ID = 2 [(gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/sql/sqlbase.ID"]; + Status status = 3; +} + message SchemaChangeDetails { util.hlc.Timestamp read_as_of = 1 [(gogoproto.nullable) = false]; // A schema change can involve running multiple processors backfilling @@ -121,6 +133,7 @@ message SchemaChangeDetails { // be processed. The index represents the index of a mutation in a // mutation list containing mutations for the same mutationID. repeated ResumeSpanList resume_span_list = 2 [(gogoproto.nullable) = false]; + repeated DroppedTableDetails dropped_tables = 3 [(gogoproto.nullable) = false]; } message SchemaChangeProgress { diff --git a/pkg/sql/drop_database.go b/pkg/sql/drop_database.go index 74a2505a452f..65cd819af66d 100644 --- a/pkg/sql/drop_database.go +++ b/pkg/sql/drop_database.go @@ -21,6 +21,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/config" "github.com/cockroachdb/cockroach/pkg/internal/client" + "github.com/cockroachdb/cockroach/pkg/jobs/jobspb" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" @@ -119,6 +120,26 @@ func (n *dropDatabaseNode) startExec(params runParams) error { ctx := params.ctx p := params.p tbNameStrings := make([]string, 0, len(n.td)) + droppedTableDetails := make([]jobspb.DroppedTableDetails, 0, len(n.td)) + tableDescs := make([]*sqlbase.TableDescriptor, 0, len(n.td)) + + for _, toDel := range n.td { + if toDel.desc.IsView() { + continue + } + droppedTableDetails = append(droppedTableDetails, jobspb.DroppedTableDetails{ + Name: toDel.tn.FQString(), + ID: toDel.desc.ID, + }) + tableDescs = append(tableDescs, toDel.desc) + } + + _, err := p.createDropTablesJob(ctx, tableDescs, droppedTableDetails, tree.AsStringWithFlags(n.n, + tree.FmtAlwaysQualifyTableNames)) + if err != nil { + return err + } + for _, toDel := range n.td { tbDesc := toDel.desc if tbDesc.IsView() { diff --git a/pkg/sql/drop_table.go b/pkg/sql/drop_table.go index 0a088807720c..5039c2ab8578 100644 --- a/pkg/sql/drop_table.go +++ b/pkg/sql/drop_table.go @@ -21,6 +21,7 @@ import ( "github.com/pkg/errors" "github.com/cockroachdb/cockroach/pkg/jobs" + "github.com/cockroachdb/cockroach/pkg/jobs/jobspb" "github.com/cockroachdb/cockroach/pkg/settings/cluster" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/privilege" @@ -107,6 +108,13 @@ func (n *dropTableNode) startExec(params runParams) error { if droppedDesc == nil { continue } + + droppedDetails := jobspb.DroppedTableDetails{Name: toDel.tn.FQString(), ID: toDel.desc.ID} + if _, err := params.p.createDropTablesJob(ctx, sqlbase.TableDescriptors{droppedDesc}, []jobspb.DroppedTableDetails{droppedDetails}, tree.AsStringWithFlags(n.n, + tree.FmtAlwaysQualifyTableNames)); err != nil { + return err + } + droppedViews, err := params.p.dropTableImpl(params, droppedDesc) if err != nil { return err diff --git a/pkg/sql/drop_test.go b/pkg/sql/drop_test.go index 009fab05684d..05ff7947e3d0 100644 --- a/pkg/sql/drop_test.go +++ b/pkg/sql/drop_test.go @@ -27,12 +27,16 @@ import ( "github.com/cockroachdb/cockroach/pkg/base" "github.com/cockroachdb/cockroach/pkg/config" "github.com/cockroachdb/cockroach/pkg/internal/client" + "github.com/cockroachdb/cockroach/pkg/jobs" + "github.com/cockroachdb/cockroach/pkg/jobs/jobspb" "github.com/cockroachdb/cockroach/pkg/keys" + "github.com/cockroachdb/cockroach/pkg/security" "github.com/cockroachdb/cockroach/pkg/sql" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/cockroachdb/cockroach/pkg/sql/tests" "github.com/cockroachdb/cockroach/pkg/sqlmigrations" "github.com/cockroachdb/cockroach/pkg/testutils" + "github.com/cockroachdb/cockroach/pkg/testutils/jobutils" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" "github.com/cockroachdb/cockroach/pkg/util/leaktest" @@ -199,6 +203,18 @@ INSERT INTO t.kv VALUES ('c', 'e'), ('a', 'c'), ('b', 'd'); if err := zoneExists(sqlDB, &cfg, tbDesc.ID); err != nil { t.Fatal(err) } + + // Job still running, waiting for GC. + sqlRun := sqlutils.MakeSQLRunner(sqlDB) + if err := jobutils.VerifySystemJob(t, sqlRun, 0, jobspb.TypeSchemaChange, jobs.StatusRunning, jobs.Record{ + Username: security.RootUser, + Description: "DROP DATABASE t CASCADE", + DescriptorIDs: sqlbase.IDs{ + tbDesc.ID, + }, + }); err != nil { + t.Fatal(err) + } } // Test that a dropped database's data gets deleted properly. @@ -220,6 +236,8 @@ func TestDropDatabaseDeleteData(t *testing.T) { CREATE DATABASE t; CREATE TABLE t.kv (k CHAR PRIMARY KEY, v CHAR, FAMILY (k), FAMILY (v)); INSERT INTO t.kv VALUES ('c', 'e'), ('a', 'c'), ('b', 'd'); +CREATE TABLE t.kv2 (k CHAR PRIMARY KEY, v CHAR, FAMILY (k), FAMILY (v)); +INSERT INTO t.kv2 VALUES ('c', 'd'), ('a', 'b'), ('e', 'a'); `); err != nil { t.Fatal(err) } @@ -253,8 +271,24 @@ INSERT INTO t.kv VALUES ('c', 'e'), ('a', 'c'), ('b', 'd'); } tbDesc := desc.GetTable() + tb2NameKey := sqlbase.MakeNameMetadataKey(dbDesc.ID, "kv2") + gr2, err := kvDB.Get(ctx, tb2NameKey) + if err != nil { + t.Fatal(err) + } + if !gr2.Exists() { + t.Fatalf(`table "kv2" does not exist`) + } + tb2DescKey := sqlbase.MakeDescMetadataKey(sqlbase.ID(gr2.ValueInt())) + if err := kvDB.GetProto(ctx, tb2DescKey, desc); err != nil { + t.Fatal(err) + } + tb2Desc := desc.GetTable() + tableSpan := tbDesc.TableSpan() + table2Span := tb2Desc.TableSpan() tests.CheckKeyCount(t, kvDB, tableSpan, 6) + tests.CheckKeyCount(t, kvDB, table2Span, 6) if _, err := sqlDB.Exec(`DROP DATABASE t RESTRICT`); !testutils.IsError(err, `database "t" is not empty`) { @@ -266,6 +300,18 @@ INSERT INTO t.kv VALUES ('c', 'e'), ('a', 'c'), ('b', 'd'); } tests.CheckKeyCount(t, kvDB, tableSpan, 6) + tests.CheckKeyCount(t, kvDB, table2Span, 6) + + sqlRun := sqlutils.MakeSQLRunner(sqlDB) + if err := jobutils.VerifySystemJob(t, sqlRun, 0, jobspb.TypeSchemaChange, jobs.StatusRunning, jobs.Record{ + Username: security.RootUser, + Description: "DROP DATABASE t CASCADE", + DescriptorIDs: sqlbase.IDs{ + tbDesc.ID, tb2Desc.ID, + }, + }); err != nil { + t.Fatal(err) + } // Push a new zone config for both the table and database with TTL=0 // so the data is deleted immediately. @@ -278,9 +324,6 @@ INSERT INTO t.kv VALUES ('c', 'e'), ('a', 'c'), ('b', 'd'); if _, err := sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, tbDesc.ID, buf); err != nil { t.Fatal(err) } - if _, err := sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, dbDesc.ID, buf); err != nil { - t.Fatal(err) - } testutils.SucceedsSoon(t, func() error { if err := descExists(sqlDB, false, tbDesc.ID); err != nil { @@ -290,8 +333,47 @@ INSERT INTO t.kv VALUES ('c', 'e'), ('a', 'c'), ('b', 'd'); return zoneExists(sqlDB, nil, tbDesc.ID) }) - // Data is deleted. + // Table 1 data is deleted. tests.CheckKeyCount(t, kvDB, tableSpan, 0) + tests.CheckKeyCount(t, kvDB, table2Span, 6) + + if err := jobutils.VerifySystemJob(t, sqlRun, 0, jobspb.TypeSchemaChange, jobs.StatusRunning, jobs.Record{ + Username: security.RootUser, + Description: "DROP DATABASE t CASCADE", + DescriptorIDs: sqlbase.IDs{ + tbDesc.ID, tb2Desc.ID, + }, + }); err != nil { + t.Fatal(err) + } + + if _, err := sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, tb2Desc.ID, buf); err != nil { + t.Fatal(err) + } + if _, err := sqlDB.Exec(`INSERT INTO system.zones VALUES ($1, $2)`, dbDesc.ID, buf); err != nil { + t.Fatal(err) + } + + testutils.SucceedsSoon(t, func() error { + if err := descExists(sqlDB, false, tb2Desc.ID); err != nil { + return err + } + + return zoneExists(sqlDB, nil, tb2Desc.ID) + }) + + // Table 2 data is deleted. + tests.CheckKeyCount(t, kvDB, table2Span, 0) + + if err := jobutils.VerifySystemJob(t, sqlRun, 0, jobspb.TypeSchemaChange, jobs.StatusSucceeded, jobs.Record{ + Username: security.RootUser, + Description: "DROP DATABASE t CASCADE", + DescriptorIDs: sqlbase.IDs{ + tbDesc.ID, tb2Desc.ID, + }, + }); err != nil { + t.Fatal(err) + } } // Tests that SHOW TABLES works correctly when a database is recreated @@ -544,6 +626,18 @@ func TestDropTable(t *testing.T) { t.Fatalf("table namekey still exists") } + // Job still running, waiting for GC. + sqlRun := sqlutils.MakeSQLRunner(sqlDB) + if err := jobutils.VerifySystemJob(t, sqlRun, 1, jobspb.TypeSchemaChange, jobs.StatusRunning, jobs.Record{ + Username: security.RootUser, + Description: `DROP TABLE t.public.kv`, + DescriptorIDs: sqlbase.IDs{ + tableDesc.ID, + }, + }); err != nil { + t.Fatal(err) + } + // Can create a table with the same name. if err := tests.CreateKVTable(sqlDB, "kv", numRows); err != nil { t.Fatal(err) @@ -605,12 +699,23 @@ func TestDropTableDeleteData(t *testing.T) { } // Data hasn't been GC-ed. + sqlRun := sqlutils.MakeSQLRunner(sqlDB) for i := 0; i < numTables; i++ { if err := descExists(sqlDB, true, descs[i].ID); err != nil { t.Fatal(err) } tableSpan := descs[i].TableSpan() tests.CheckKeyCount(t, kvDB, tableSpan, numKeys) + + if err := jobutils.VerifySystemJob(t, sqlRun, 2*i+1, jobspb.TypeSchemaChange, jobs.StatusRunning, jobs.Record{ + Username: security.RootUser, + Description: fmt.Sprintf(`DROP TABLE t.public.%s`, descs[i].GetName()), + DescriptorIDs: sqlbase.IDs{ + descs[i].ID, + }, + }); err != nil { + t.Fatal(err) + } } // The closure pushes a zone config reducing the TTL to 0 for descriptor i. @@ -636,6 +741,17 @@ func TestDropTableDeleteData(t *testing.T) { }) tableSpan := descs[i].TableSpan() tests.CheckKeyCount(t, kvDB, tableSpan, 0) + + // Ensure that the job is marked as succeeded. + if err := jobutils.VerifySystemJob(t, sqlRun, 2*i+1, jobspb.TypeSchemaChange, jobs.StatusSucceeded, jobs.Record{ + Username: security.RootUser, + Description: fmt.Sprintf(`DROP TABLE t.public.%s`, descs[i].GetName()), + DescriptorIDs: sqlbase.IDs{ + descs[i].ID, + }, + }); err != nil { + t.Fatal(err) + } } // Push a new zone config for a few tables with TTL=0 so the data diff --git a/pkg/sql/drop_view.go b/pkg/sql/drop_view.go index 824c939f6bb1..398055f637c0 100644 --- a/pkg/sql/drop_view.go +++ b/pkg/sql/drop_view.go @@ -83,6 +83,7 @@ func (n *dropViewNode) startExec(params runParams) error { if droppedDesc == nil { continue } + cascadeDroppedViews, err := params.p.dropViewImpl(ctx, droppedDesc, n.n.DropBehavior) if err != nil { return err diff --git a/pkg/sql/logictest/testdata/logic_test/show_trace b/pkg/sql/logictest/testdata/logic_test/show_trace index 347d47a5bfaf..06810dbe5fa6 100644 --- a/pkg/sql/logictest/testdata/logic_test/show_trace +++ b/pkg/sql/logictest/testdata/logic_test/show_trace @@ -83,7 +83,7 @@ dist sender send r1: sending batch 1 Get to (n1,s1):1 dist sender send querying next range at /System/"desc-idgen" dist sender send r1: sending batch 1 Inc to (n1,s1):1 sql txn CPut /Table/2/1/53/"kv"/3/1 -> 54 -sql txn CPut /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:2 privileges: users: > next_mutation_id:1 format_version:3 state:PUBLIC view_query:"" drop_time:0 replacement_of: > audit_mode:DISABLED > +sql txn CPut /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:2 privileges: users: > next_mutation_id:1 format_version:3 state:PUBLIC view_query:"" drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 > dist sender send querying next range at /Table/SystemConfigSpan/Start dist sender send r1: sending batch 2 CPut, 1 BeginTxn to (n1,s1):1 dist sender send querying next range at /Table/3/1/53/2/1 @@ -120,7 +120,7 @@ dist sender send querying next range at /Table/3/1/54/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 dist sender send querying next range at /Table/3/1/53/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 -sql txn Put /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:3 privileges: users: > mutations: interleave:<> partitioning: type:FORWARD > state:DELETE_ONLY direction:ADD mutation_id:1 rollback:false > next_mutation_id:2 format_version:3 state:PUBLIC view_query:"" mutationJobs:<...> drop_time:0 replacement_of: > audit_mode:DISABLED > +sql txn Put /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:3 privileges: users: > mutations: interleave:<> partitioning: type:FORWARD > state:DELETE_ONLY direction:ADD mutation_id:1 rollback:false > next_mutation_id:2 format_version:3 state:PUBLIC view_query:"" mutationJobs:<...> drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 > dist sender send querying next range at /Table/3/1/54/2/1 dist sender send r1: sending batch 1 Put to (n1,s1):1 sql txn rows affected: 0 @@ -247,7 +247,7 @@ dist sender send r1: sending batch 1 Get to (n1,s1):1 dist sender send querying next range at /System/"desc-idgen" dist sender send r1: sending batch 1 Inc to (n1,s1):1 sql txn CPut /Table/2/1/53/"kv2"/3/1 -> 55 -sql txn CPut /Table/3/1/55/2/1 -> table: columns: nullable:true hidden:false > columns: nullable:true hidden:false > columns: nullable:false default_expr:"unique_rowid()" hidden:true > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:2 privileges: users: > next_mutation_id:1 format_version:3 state:PUBLIC view_query:"" drop_time:0 replacement_of: > audit_mode:DISABLED > +sql txn CPut /Table/3/1/55/2/1 -> table: columns: nullable:true hidden:false > columns: nullable:true hidden:false > columns: nullable:false default_expr:"unique_rowid()" hidden:true > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:2 privileges: users: > next_mutation_id:1 format_version:3 state:PUBLIC view_query:"" drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 > dist sender send querying next range at /Table/SystemConfigSpan/Start dist sender send r1: sending batch 2 CPut, 1 BeginTxn to (n1,s1):1 dist sender send querying next range at /Table/3/1/53/2/1 @@ -312,7 +312,7 @@ SET tracing = on,kv,results; DROP TABLE t.kv2; SET tracing = off query TT SELECT operation, - regexp_replace(regexp_replace(message, 'wall_time:\d+', 'wall_time:...'), 'drop_time:\d+', 'drop_time:...') as message + regexp_replace(regexp_replace(regexp_replace(message, 'drop_job_id:[1-9]\d*', 'drop_job_id:...'), 'wall_time:\d+', 'wall_time:...'), 'drop_time:\d+', 'drop_time:...') as message FROM [SHOW KV TRACE FOR SESSION] WHERE message NOT LIKE '%Z/%' AND tag NOT LIKE '%intExec=%' @@ -339,12 +339,12 @@ dist sender send querying next range at /Table/3/1/53/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 dist sender send querying next range at /Table/5/1/0/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 -sql txn Put /Table/3/1/55/2/1 -> table: columns: nullable:true hidden:false > columns: nullable:true hidden:false > columns: nullable:false default_expr:"unique_rowid()" hidden:true > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:2 privileges: users: > next_mutation_id:1 format_version:3 state:DROP draining_names: view_query:"" drop_time:... replacement_of: > audit_mode:DISABLED > -dist sender send querying next range at /Table/SystemConfigSpan/Start -dist sender send r1: sending batch 1 Put, 1 BeginTxn to (n1,s1):1 +sql txn Put /Table/3/1/55/2/1 -> table: columns: nullable:true hidden:false > columns: nullable:true hidden:false > columns: nullable:false default_expr:"unique_rowid()" hidden:true > next_column_id:4 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:2 privileges: users: > next_mutation_id:1 format_version:3 state:DROP draining_names: view_query:"" drop_time:... replacement_of: > audit_mode:DISABLED drop_job_id:... > +dist sender send querying next range at /Table/3/1/55/2/1 +dist sender send r1: sending batch 1 Put to (n1,s1):1 sql txn rows affected: 0 dist sender send querying next range at /Table/SystemConfigSpan/Start -dist sender send r1: sending batch 1 EndTxn, 6 QueryIntent to (n1,s1):1 +dist sender send r1: sending batch 1 EndTxn, 10 QueryIntent to (n1,s1):1 statement ok SET tracing = on,kv,results; DELETE FROM t.kv; SET tracing = off @@ -400,7 +400,7 @@ dist sender send querying next range at /Table/3/1/53/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 dist sender send querying next range at /Table/3/1/53/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 -sql txn Put /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:3 privileges: users: > mutations: interleave:<> partitioning: type:FORWARD > state:DELETE_AND_WRITE_ONLY direction:DROP mutation_id:2 rollback:false > next_mutation_id:3 format_version:3 state:PUBLIC view_query:"" mutationJobs:<...> drop_time:0 replacement_of: > audit_mode:DISABLED > +sql txn Put /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:3 privileges: users: > mutations: interleave:<> partitioning: type:FORWARD > state:DELETE_AND_WRITE_ONLY direction:DROP mutation_id:2 rollback:false > next_mutation_id:3 format_version:3 state:PUBLIC view_query:"" mutationJobs:<...> drop_time:0 replacement_of: > audit_mode:DISABLED drop_job_id:0 > dist sender send querying next range at /Table/3/1/54/2/1 dist sender send r1: sending batch 1 Put to (n1,s1):1 sql txn rows affected: 0 @@ -411,7 +411,7 @@ statement ok SET tracing = on,kv,results; DROP TABLE t.kv; SET tracing = off query TT -SELECT operation, regexp_replace(regexp_replace(regexp_replace(message, 'mutationJobs:<[^>]*>', 'mutationJobs:<...>'), 'wall_time:\d+', 'wall_time:...'), 'drop_time:\d+', 'drop_time:...') as message +SELECT operation, regexp_replace(regexp_replace(regexp_replace(message, 'drop_job_id:[1-9]\d*', 'drop_job_id:...'), 'wall_time:\d+', 'wall_time:...'), 'drop_time:\d+', 'drop_time:...') as message FROM [SHOW KV TRACE FOR SESSION] WHERE message NOT LIKE '%Z/%' AND tag NOT LIKE '%intExec=%' @@ -438,12 +438,12 @@ dist sender send querying next range at /Table/3/1/53/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 dist sender send querying next range at /Table/5/1/0/2/1 dist sender send r1: sending batch 1 Get to (n1,s1):1 -sql txn Put /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:3 privileges: users: > next_mutation_id:3 format_version:3 state:DROP draining_names: view_query:"" drop_time:... replacement_of: > audit_mode:DISABLED > -dist sender send querying next range at /Table/SystemConfigSpan/Start -dist sender send r1: sending batch 1 Put, 1 BeginTxn to (n1,s1):1 +sql txn Put /Table/3/1/54/2/1 -> table: columns: nullable:false hidden:false > columns: nullable:true hidden:false > next_column_id:3 families: next_family_id:1 primary_index: interleave:<> partitioning: type:FORWARD > next_index_id:3 privileges: users: > next_mutation_id:3 format_version:3 state:DROP draining_names: view_query:"" drop_time:... replacement_of: > audit_mode:DISABLED drop_job_id:... > +dist sender send querying next range at /Table/3/1/54/2/1 +dist sender send r1: sending batch 1 Put to (n1,s1):1 sql txn rows affected: 0 dist sender send querying next range at /Table/SystemConfigSpan/Start -dist sender send r1: sending batch 1 EndTxn, 6 QueryIntent to (n1,s1):1 +dist sender send r1: sending batch 1 EndTxn, 10 QueryIntent to (n1,s1):1 # Check that session tracing does not inhibit the fast path for inserts & # friends (the path resulting in 1PC transactions). diff --git a/pkg/sql/schema_changer.go b/pkg/sql/schema_changer.go index 1f9731d54f01..b40d51734979 100644 --- a/pkg/sql/schema_changer.go +++ b/pkg/sql/schema_changer.go @@ -312,14 +312,14 @@ func (sc *SchemaChanger) ExtendLease( } // DropTableDesc removes a descriptor from the KV database. -func DropTableDesc( - ctx context.Context, tableDesc *sqlbase.TableDescriptor, db *client.DB, traceKV bool, +func (sc *SchemaChanger) DropTableDesc( + ctx context.Context, tableDesc *sqlbase.TableDescriptor, traceKV bool, ) error { descKey := sqlbase.MakeDescMetadataKey(tableDesc.ID) zoneKeyPrefix := config.MakeZoneKeyPrefix(uint32(tableDesc.ID)) // Finished deleting all the table data, now delete the table meta data. - return db.Txn(ctx, func(ctx context.Context, txn *client.Txn) error { + return sc.db.Txn(ctx, func(ctx context.Context, txn *client.Txn) error { // Delete table descriptor b := &client.Batch{} if traceKV { @@ -330,8 +330,36 @@ func DropTableDesc( b.Del(descKey) // Delete the zone config entry for this table. b.DelRange(zoneKeyPrefix, zoneKeyPrefix.PrefixEnd(), false /* returnKeys */) - if err := txn.SetSystemConfigTrigger(); err != nil { - return err + + if tableDesc.GetDropJobID() != 0 { + job, err := sc.jobRegistry.LoadJobWithTxn(ctx, tableDesc.GetDropJobID(), txn) + if err != nil { + return err + } + + job.WithTxn(txn) + details, ok := job.Details().(jobspb.SchemaChangeDetails) + if ok { + jobDone := true + for i := 0; i < len(details.DroppedTables); i++ { + droppedTable := &details.DroppedTables[i] + if droppedTable.ID == tableDesc.ID { + droppedTable.Status = jobspb.DroppedTableDetails_StatusDone + } else if droppedTable.Status != jobspb.DroppedTableDetails_StatusDone { + jobDone = false + } + } + + var err error + if jobDone { + err = job.Succeeded(ctx, jobs.NoopFn) + } else { + err = job.SetDetails(ctx, details) + } + if err != nil { + return errors.Wrapf(err, "failed to update job %d", *job.ID()) + } + } } return txn.Run(ctx, b) }) @@ -464,7 +492,7 @@ func (sc *SchemaChanger) maybeAddDrop( return false, err } - return true, DropTableDesc(ctx, table, sc.db, false /* traceKV */) + return true, sc.DropTableDesc(ctx, table, false /* traceKV */) } if table.Adding() { @@ -504,6 +532,7 @@ func (sc *SchemaChanger) drainNames( // has seen the version with the new name. All the draining names // can be reused henceforth. var namesToReclaim []sqlbase.TableDescriptor_NameInfo + var dropJobID int64 _, err := sc.leaseMgr.Publish( ctx, sc.tableID, @@ -523,6 +552,7 @@ func (sc *SchemaChanger) drainNames( // Free up the old name(s) for reuse. namesToReclaim = desc.DrainingNames desc.DrainingNames = nil + dropJobID = desc.GetDropJobID() return nil }, // Reclaim all the old names. @@ -532,6 +562,27 @@ func (sc *SchemaChanger) drainNames( tbKey := tableKey{drain.ParentID, drain.Name}.Key() b.Del(tbKey) } + + if dropJobID != 0 { + job, err := sc.jobRegistry.LoadJobWithTxn(ctx, dropJobID, txn) + if err != nil { + return err + } + + job.WithTxn(txn) + details, ok := job.Details().(jobspb.SchemaChangeDetails) + if ok { + for i, _ := range details.DroppedTables { + details.DroppedTables[i].Status = jobspb.DroppedTableDetails_StatusWaitForGCInterval + break + } + + if err := job.SetDetails(ctx, details); err != nil { + return errors.Wrapf(err, "failed to update job %d", *job.ID()) + } + } + } + return txn.Run(ctx, b) }, ) @@ -625,6 +676,7 @@ func (sc *SchemaChanger) exec( break } } + if !foundJobID { // No job means we've already run and completed this schema change // successfully, so we can just exit. diff --git a/pkg/sql/schema_changer_test.go b/pkg/sql/schema_changer_test.go index 92af5c4e70cf..aa2b8c211904 100644 --- a/pkg/sql/schema_changer_test.go +++ b/pkg/sql/schema_changer_test.go @@ -2836,6 +2836,18 @@ CREATE TABLE t.test (k INT PRIMARY KEY, v INT, pi DECIMAL DEFAULT (DECIMAL '3.14 if !droppedDesc.Dropped() { t.Fatalf("bad state = %s", droppedDesc.State) } + + // Job still running, waiting for GC. + sqlRun := sqlutils.MakeSQLRunner(sqlDB) + if err := jobutils.VerifySystemJob(t, sqlRun, 0, jobspb.TypeSchemaChange, jobs.StatusRunning, jobs.Record{ + Username: security.RootUser, + Description: "TRUNCATE TABLE t.test", + DescriptorIDs: sqlbase.IDs{ + tableDesc.ID, + }, + }); err != nil { + t.Fatal(err) + } } // Test that a table truncation completes properly. @@ -2966,6 +2978,18 @@ CREATE TABLE t.test (k INT PRIMARY KEY, v INT, pi DECIMAL REFERENCES t.pi (d) DE } else if e := 1; len(kvs) != e { t.Fatalf("expected %d key value pairs, but got %d", e, len(kvs)) } + + // Ensure that the job is marked as succeeded. + sqlRun := sqlutils.MakeSQLRunner(sqlDB) + if err := jobutils.VerifySystemJob(t, sqlRun, 0, jobspb.TypeSchemaChange, jobs.StatusSucceeded, jobs.Record{ + Username: security.RootUser, + Description: "TRUNCATE TABLE t.test", + DescriptorIDs: sqlbase.IDs{ + tableDesc.ID, + }, + }); err != nil { + t.Fatal(err) + } } // Test TRUNCATE during a column backfill. diff --git a/pkg/sql/sqlbase/structured.pb.go b/pkg/sql/sqlbase/structured.pb.go index 664efae2f9fb..933f1fe63f08 100644 --- a/pkg/sql/sqlbase/structured.pb.go +++ b/pkg/sql/sqlbase/structured.pb.go @@ -1074,6 +1074,9 @@ type TableDescriptor struct { // can be used when trying to track a table's history across truncatations. ReplacementOf TableDescriptor_Replacement `protobuf:"bytes,30,opt,name=replacement_of,json=replacementOf" json:"replacement_of"` AuditMode TableDescriptor_AuditMode `protobuf:"varint,31,opt,name=audit_mode,json=auditMode,enum=cockroach.sql.sqlbase.TableDescriptor_AuditMode" json:"audit_mode"` + // The job id for a drop job is the id in the system.jobs table of the + // dropping of this table. + DropJobID int64 `protobuf:"varint,32,opt,name=drop_job_id,json=dropJobId" json:"drop_job_id"` } func (m *TableDescriptor) Reset() { *m = TableDescriptor{} } @@ -1284,6 +1287,13 @@ func (m *TableDescriptor) GetAuditMode() TableDescriptor_AuditMode { return TableDescriptor_DISABLED } +func (m *TableDescriptor) GetDropJobID() int64 { + if m != nil { + return m.DropJobID + } + return 0 +} + // The schema update lease. A single goroutine across a cockroach cluster // can own it, and will execute pending schema changes for this table. // Since the execution of a pending schema change is through transactions, @@ -2610,6 +2620,11 @@ func (m *TableDescriptor) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1 i++ i = encodeVarintStructured(dAtA, i, uint64(m.AuditMode)) + dAtA[i] = 0x80 + i++ + dAtA[i] = 0x2 + i++ + i = encodeVarintStructured(dAtA, i, uint64(m.DropJobID)) return i, nil } @@ -3271,6 +3286,7 @@ func (m *TableDescriptor) Size() (n int) { l = m.ReplacementOf.Size() n += 2 + l + sovStructured(uint64(l)) n += 2 + sovStructured(uint64(m.AuditMode)) + n += 2 + sovStructured(uint64(m.DropJobID)) return n } @@ -6652,6 +6668,25 @@ func (m *TableDescriptor) Unmarshal(dAtA []byte) error { break } } + case 32: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DropJobID", wireType) + } + m.DropJobID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStructured + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DropJobID |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipStructured(dAtA[iNdEx:]) @@ -7884,196 +7919,197 @@ var ( func init() { proto.RegisterFile("sql/sqlbase/structured.proto", fileDescriptorStructured) } var fileDescriptorStructured = []byte{ - // 3052 bytes of a gzipped FileDescriptorProto + // 3072 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x59, 0x4b, 0x73, 0xe3, 0xc6, 0xf1, 0x17, 0x48, 0x90, 0x04, 0x9a, 0x2f, 0x68, 0xf6, 0x61, 0x2e, 0xbd, 0x96, 0xb4, 0xb4, 0xd7, 0x7f, 0xf9, 0x45, 0xad, 0xb5, 0xfe, 0x27, 0x2e, 0x27, 0xe5, 0x0a, 0x1f, 0xd0, 0x2e, 0xb4, 0x14, 0xa9, 0x05, 0x29, 0xad, 0xd7, 0xe5, 0x84, 0x05, 0x11, 0x23, 0x09, 0x5e, 0x10, 0xe0, 0x02, 0xa0, - 0x2c, 0x7d, 0x03, 0x1f, 0x53, 0xb9, 0xe4, 0xe6, 0x72, 0xf9, 0x94, 0xaa, 0x5c, 0x73, 0xc8, 0x47, - 0xd8, 0xdc, 0x52, 0x3e, 0xe5, 0x12, 0x55, 0xa2, 0x54, 0xaa, 0x72, 0xc8, 0x39, 0x07, 0x57, 0xa5, - 0x2a, 0x35, 0x83, 0x19, 0x10, 0xd4, 0xcb, 0xd4, 0xee, 0x8d, 0xe8, 0xe9, 0xfe, 0xcd, 0x74, 0x4f, - 0xf7, 0x6f, 0x7a, 0x86, 0x70, 0xdb, 0x7f, 0x6e, 0xaf, 0xf8, 0xcf, 0xed, 0x1d, 0xc3, 0xc7, 0x2b, - 0x7e, 0xe0, 0x8d, 0x07, 0xc1, 0xd8, 0xc3, 0x66, 0x75, 0xe4, 0xb9, 0x81, 0x8b, 0x6e, 0x0c, 0xdc, - 0xc1, 0x33, 0xcf, 0x35, 0x06, 0xfb, 0x55, 0xff, 0xb9, 0x5d, 0x65, 0x7a, 0xe5, 0xd2, 0x38, 0xb0, - 0xec, 0x95, 0x7d, 0x7b, 0xb0, 0x12, 0x58, 0x43, 0xec, 0x07, 0xc6, 0x70, 0x14, 0x1a, 0x94, 0x5f, - 0x8f, 0xc3, 0x8d, 0x3c, 0xeb, 0xc0, 0xb2, 0xf1, 0x1e, 0x66, 0x83, 0xd7, 0xf7, 0xdc, 0x3d, 0x97, - 0xfe, 0x5c, 0x21, 0xbf, 0x42, 0x69, 0xe5, 0xfb, 0x0c, 0x40, 0xc3, 0xb5, 0xc7, 0x43, 0xa7, 0x77, - 0x34, 0xc2, 0xe8, 0x29, 0xe4, 0x7d, 0x3c, 0x34, 0x9c, 0xc0, 0x1a, 0xf4, 0x83, 0xa3, 0x11, 0x2e, - 0x09, 0x4b, 0xc2, 0x72, 0x61, 0xb5, 0x5a, 0x3d, 0x77, 0x29, 0xd5, 0x89, 0x65, 0xb5, 0xcb, 0xcc, - 0xc8, 0x47, 0x5d, 0x7c, 0x71, 0xbc, 0x38, 0xa7, 0xe7, 0xfc, 0x98, 0x0c, 0x95, 0x21, 0xf5, 0x95, - 0x65, 0x06, 0xfb, 0xa5, 0xc4, 0x92, 0xb0, 0x9c, 0x62, 0x2a, 0xa1, 0x08, 0x55, 0x40, 0x1e, 0x79, - 0x78, 0x60, 0xf9, 0x96, 0xeb, 0x94, 0x92, 0xb1, 0xf1, 0x89, 0x18, 0xbd, 0x03, 0x8a, 0xe1, 0x79, - 0xc6, 0x51, 0xdf, 0xb4, 0x86, 0xd8, 0x21, 0x22, 0xbf, 0x24, 0x2e, 0x25, 0x97, 0x53, 0x7a, 0x91, - 0xca, 0x9b, 0x91, 0x18, 0xdd, 0x84, 0xb4, 0xed, 0x0e, 0x0c, 0x1b, 0x97, 0x52, 0x4b, 0xc2, 0xb2, - 0xac, 0xb3, 0x2f, 0xb4, 0x0d, 0xb9, 0x03, 0xcb, 0xb7, 0x76, 0x6c, 0x1c, 0x3a, 0x97, 0xa6, 0xce, - 0x7d, 0xf0, 0xe3, 0xce, 0x6d, 0x87, 0x56, 0x31, 0xdf, 0xb2, 0x07, 0x13, 0x11, 0xda, 0x82, 0x42, - 0xb8, 0xb4, 0x81, 0xeb, 0x04, 0xd8, 0x09, 0xfc, 0x52, 0xe6, 0x65, 0xc2, 0xa6, 0xe7, 0x29, 0x4a, - 0x83, 0x81, 0xa0, 0x36, 0x14, 0x82, 0xf1, 0xc8, 0xc6, 0x13, 0x58, 0x69, 0x29, 0xb9, 0x9c, 0x5d, - 0xbd, 0xf3, 0xa3, 0xb0, 0x6c, 0x91, 0x79, 0x6a, 0x1e, 0xe1, 0xdd, 0x81, 0x5c, 0x88, 0x67, 0x1b, - 0x3b, 0xd8, 0xf6, 0x4b, 0xf2, 0x52, 0x72, 0x59, 0xd6, 0xb3, 0x54, 0xd6, 0xa2, 0xa2, 0xca, 0xef, - 0x12, 0x90, 0x8b, 0x2f, 0x09, 0x49, 0x20, 0xd6, 0x3b, 0x9d, 0x96, 0x32, 0x87, 0x32, 0x90, 0xd4, - 0xda, 0x3d, 0x45, 0x40, 0x32, 0xa4, 0xd6, 0x5a, 0x9d, 0x5a, 0x4f, 0x49, 0xa0, 0x2c, 0x64, 0x9a, - 0x6a, 0x43, 0xdb, 0xa8, 0xb5, 0x94, 0x24, 0x51, 0x6d, 0xd6, 0x7a, 0xaa, 0x22, 0xa2, 0x3c, 0xc8, - 0x3d, 0x6d, 0x43, 0xed, 0xf6, 0x6a, 0x1b, 0x9b, 0x4a, 0x0a, 0xe5, 0x40, 0xd2, 0xda, 0x3d, 0x55, - 0xdf, 0xae, 0xb5, 0x94, 0x34, 0x02, 0x48, 0x77, 0x7b, 0xba, 0xd6, 0x7e, 0xa0, 0x64, 0x08, 0x54, - 0xfd, 0x69, 0x4f, 0xed, 0x2a, 0x12, 0x2a, 0x42, 0x36, 0xb2, 0xe9, 0x7d, 0xae, 0xc8, 0x08, 0x41, - 0xa1, 0xd1, 0x69, 0xb5, 0x6a, 0x3d, 0xb5, 0xc9, 0xf4, 0x81, 0x4c, 0xd1, 0xae, 0x6d, 0xa8, 0x4a, - 0x96, 0xac, 0xa6, 0xa3, 0x35, 0x95, 0x1c, 0x15, 0x6d, 0xb5, 0x5a, 0x4a, 0x9e, 0xfc, 0xda, 0xda, - 0xd2, 0x9a, 0x4a, 0x81, 0xc0, 0xd6, 0x74, 0xbd, 0xf6, 0x54, 0x29, 0x12, 0xa1, 0xd6, 0x56, 0x7b, - 0x8a, 0x42, 0x7e, 0x91, 0x09, 0x94, 0x79, 0x32, 0xbc, 0xde, 0xed, 0xb4, 0xeb, 0x0a, 0x22, 0x3f, - 0x7b, 0x5b, 0x9b, 0x2d, 0x55, 0xb9, 0x4e, 0x10, 0xeb, 0x5a, 0x4f, 0xb9, 0x81, 0x8a, 0x00, 0x5a, - 0xbb, 0xb7, 0xba, 0xad, 0x36, 0x7a, 0x1d, 0x5d, 0x79, 0x21, 0xa0, 0x02, 0xc8, 0x1d, 0xad, 0xc9, - 0xbe, 0xff, 0x24, 0x54, 0x44, 0xe9, 0x9a, 0x72, 0xad, 0xf2, 0x1b, 0x01, 0xb2, 0xb1, 0xbc, 0xa0, - 0x0b, 0xe9, 0xb4, 0x55, 0x65, 0x8e, 0x44, 0x85, 0xf8, 0xfb, 0x40, 0xd5, 0x15, 0x81, 0x38, 0xdf, - 0xdd, 0xa8, 0xb5, 0x5a, 0x24, 0x76, 0x09, 0xe2, 0x7c, 0x5d, 0x7b, 0x40, 0x7e, 0xd3, 0x78, 0xe9, - 0x6a, 0xad, 0xa5, 0xa4, 0xd0, 0x75, 0x50, 0x9a, 0x9d, 0xad, 0x7a, 0x4b, 0xed, 0x6f, 0xea, 0x6a, - 0x43, 0xeb, 0x6a, 0x9d, 0xb6, 0x92, 0x26, 0x30, 0xdb, 0x35, 0xbd, 0xf1, 0xb0, 0xa6, 0x2b, 0x19, - 0xa2, 0x4c, 0x7f, 0x49, 0x64, 0xc9, 0x8f, 0xe9, 0x4f, 0x99, 0xa0, 0x6d, 0xd7, 0x74, 0xb2, 0x6a, - 0xa8, 0x88, 0x92, 0xa8, 0x88, 0x9f, 0x88, 0xff, 0xfa, 0x76, 0x51, 0xa8, 0xfc, 0x27, 0x09, 0xd7, - 0xd6, 0x5c, 0x0f, 0x5b, 0x7b, 0xce, 0x23, 0x7c, 0xa4, 0xe3, 0x5d, 0xec, 0x61, 0x67, 0x80, 0xd1, - 0x12, 0xa4, 0x02, 0x63, 0xc7, 0x0e, 0xab, 0x3a, 0x5f, 0x07, 0x92, 0x24, 0x3f, 0x1c, 0x2f, 0x26, - 0xb4, 0xa6, 0x1e, 0x0e, 0xa0, 0xbb, 0x90, 0xb2, 0x1c, 0x13, 0x1f, 0xd2, 0x22, 0xcd, 0xd7, 0x8b, - 0x4c, 0x23, 0xa3, 0x11, 0x21, 0x51, 0xa3, 0xa3, 0xa8, 0x04, 0xa2, 0x63, 0x0c, 0x31, 0x2d, 0x55, - 0x99, 0x25, 0x1b, 0x95, 0xa0, 0x47, 0x20, 0x1d, 0x18, 0xb6, 0x65, 0x5a, 0xc1, 0x51, 0x49, 0xa4, - 0x45, 0xf0, 0xce, 0x85, 0xd9, 0xea, 0xf8, 0x81, 0x67, 0x58, 0x4e, 0xb0, 0xcd, 0x0c, 0x18, 0x50, - 0x04, 0x80, 0xee, 0xc1, 0xbc, 0xbf, 0x6f, 0x78, 0xd8, 0xec, 0x8f, 0x3c, 0xbc, 0x6b, 0x1d, 0xf6, - 0x6d, 0xec, 0xd0, 0x92, 0xe6, 0xf4, 0x50, 0x0c, 0x87, 0x37, 0xe9, 0x68, 0x0b, 0x3b, 0xa8, 0x07, - 0xb2, 0xeb, 0xf4, 0x4d, 0x6c, 0xe3, 0x80, 0x97, 0xf7, 0x87, 0x17, 0xcc, 0x7f, 0x4e, 0x80, 0xaa, - 0xb5, 0x41, 0x60, 0xb9, 0x0e, 0x5f, 0x87, 0xeb, 0x34, 0x29, 0x10, 0x43, 0x1d, 0x8f, 0x4c, 0x23, - 0xc0, 0xac, 0xb4, 0x5f, 0x05, 0x75, 0x8b, 0x02, 0x55, 0x1e, 0x43, 0x3a, 0x1c, 0x21, 0xf5, 0xd2, - 0xee, 0xf4, 0x6b, 0x8d, 0x1e, 0xd9, 0xf8, 0x39, 0x92, 0x32, 0xba, 0x4a, 0x72, 0xbe, 0xd1, 0x63, - 0x09, 0xa4, 0xf6, 0xfa, 0x34, 0xc9, 0x13, 0xa4, 0x4c, 0xc8, 0x57, 0x53, 0x5d, 0xab, 0x6d, 0xb5, - 0x48, 0x16, 0x65, 0x21, 0xd3, 0xa8, 0x75, 0x1b, 0xb5, 0xa6, 0xaa, 0x88, 0x95, 0xbf, 0x26, 0x40, - 0x09, 0x59, 0xa0, 0x89, 0xfd, 0x81, 0x67, 0x8d, 0x02, 0xd7, 0x8b, 0x36, 0x4b, 0x38, 0xb3, 0x59, - 0x6f, 0x43, 0xc2, 0x32, 0xd9, 0x56, 0xdf, 0x24, 0xf2, 0x13, 0x9a, 0x0c, 0x3f, 0x1c, 0x2f, 0x4a, - 0x21, 0x8a, 0xd6, 0xd4, 0x13, 0x96, 0x89, 0x7e, 0x06, 0x22, 0xe5, 0x4b, 0xb2, 0xdd, 0x57, 0xa0, - 0x1f, 0x6a, 0x84, 0x96, 0x40, 0x72, 0xc6, 0xb6, 0x4d, 0xf3, 0x8e, 0x64, 0x84, 0xc4, 0x03, 0xc1, - 0xa5, 0x84, 0x97, 0x4c, 0xbc, 0x6b, 0x8c, 0xed, 0xa0, 0x8f, 0x0f, 0x47, 0x1e, 0x23, 0xed, 0x2c, - 0x93, 0xa9, 0x87, 0x23, 0x0f, 0xdd, 0x86, 0xf4, 0xbe, 0x65, 0x9a, 0xd8, 0xa1, 0x9b, 0xca, 0x21, - 0x98, 0x0c, 0xad, 0xc2, 0xfc, 0xd8, 0xc7, 0x7e, 0xdf, 0xc7, 0xcf, 0xc7, 0x24, 0xe2, 0x7d, 0xcb, - 0xf4, 0x4b, 0xb0, 0x94, 0x5c, 0xce, 0xd7, 0xd3, 0x2c, 0xbf, 0x8b, 0x44, 0xa1, 0xcb, 0xc6, 0x35, - 0x93, 0x92, 0xe1, 0xc0, 0x1d, 0x8e, 0xc6, 0x01, 0x0e, 0x27, 0xcd, 0x86, 0x93, 0x32, 0x19, 0x99, - 0x74, 0x5d, 0x94, 0x24, 0x45, 0x5e, 0x17, 0x25, 0x59, 0x81, 0x75, 0x51, 0xca, 0x28, 0x52, 0xe5, - 0xeb, 0x04, 0xdc, 0x0c, 0xdd, 0x5c, 0x33, 0x86, 0x96, 0x7d, 0xf4, 0xaa, 0x51, 0x0e, 0x51, 0x58, - 0x94, 0xe9, 0x8a, 0x08, 0x76, 0x9f, 0x98, 0xf9, 0xa5, 0x64, 0x48, 0xcf, 0xa1, 0xac, 0x4d, 0x44, - 0xe8, 0x63, 0x00, 0xa6, 0x42, 0x3c, 0x14, 0xa9, 0x87, 0xb7, 0x4e, 0x8e, 0x17, 0x65, 0xbe, 0x5d, - 0xfe, 0xd4, 0xde, 0xc9, 0xa1, 0x32, 0x71, 0xb7, 0x03, 0xf3, 0x3c, 0xc6, 0x11, 0x02, 0x0d, 0x74, - 0xbe, 0xfe, 0x26, 0x5b, 0x53, 0xb1, 0x19, 0x2a, 0x70, 0xf3, 0x29, 0xa8, 0xa2, 0x39, 0x35, 0x68, - 0x56, 0x7e, 0x9f, 0x80, 0xeb, 0x9a, 0x13, 0x60, 0xcf, 0xc6, 0xc6, 0x01, 0x8e, 0x05, 0xe2, 0x33, - 0x90, 0x0d, 0x67, 0x80, 0xfd, 0xc0, 0xf5, 0xfc, 0x92, 0x40, 0x0f, 0xac, 0x8f, 0x2e, 0xc8, 0x98, - 0xf3, 0xec, 0xab, 0x35, 0x66, 0xcc, 0x3b, 0x80, 0x08, 0xac, 0xfc, 0x47, 0x01, 0x24, 0x3e, 0x8a, - 0xee, 0x81, 0x44, 0x29, 0x8b, 0xf8, 0x11, 0xd2, 0xd9, 0x0d, 0xe6, 0x47, 0xa6, 0x47, 0xe4, 0x74, - 0xfd, 0x64, 0xe7, 0x33, 0x54, 0x4d, 0x33, 0xd1, 0xff, 0x83, 0x44, 0xd9, 0xab, 0x1f, 0xed, 0x46, - 0x99, 0x5b, 0x30, 0x7a, 0x8b, 0x33, 0x5d, 0x86, 0xea, 0x6a, 0x26, 0x6a, 0x9c, 0x47, 0x42, 0x49, - 0x6a, 0xff, 0x1a, 0x8f, 0x5c, 0x77, 0x9a, 0x86, 0xce, 0xf0, 0x52, 0xe5, 0x9f, 0x49, 0xb8, 0xb9, - 0x69, 0x78, 0x81, 0x45, 0xea, 0xdd, 0x72, 0xf6, 0x62, 0xf1, 0xba, 0x0b, 0x59, 0x67, 0x3c, 0x64, - 0xbb, 0xe2, 0x33, 0x5f, 0x42, 0xdf, 0xc1, 0x19, 0x0f, 0xc3, 0x80, 0xfb, 0xa8, 0x05, 0xa2, 0x6d, - 0xf9, 0x41, 0x29, 0x41, 0x23, 0xba, 0x7a, 0x41, 0x44, 0xcf, 0x9f, 0xa3, 0xda, 0xb2, 0xfc, 0x80, - 0xe7, 0x24, 0x41, 0x41, 0x1d, 0x48, 0x79, 0x86, 0xb3, 0x87, 0x69, 0x92, 0x65, 0x57, 0xef, 0x5f, - 0x0d, 0x4e, 0x27, 0xa6, 0xbc, 0x83, 0xa3, 0x38, 0xe5, 0xdf, 0x0a, 0x20, 0x92, 0x59, 0x2e, 0xa9, - 0x83, 0x9b, 0x90, 0x3e, 0x30, 0xec, 0x31, 0xf6, 0xa9, 0x0f, 0x39, 0x9d, 0x7d, 0xa1, 0x5f, 0x42, - 0xd1, 0x1f, 0xef, 0x8c, 0x62, 0x53, 0x31, 0xa2, 0xf9, 0xe0, 0x4a, 0xab, 0x8a, 0x8e, 0x84, 0x69, - 0xac, 0xf2, 0x33, 0x48, 0xd1, 0xf5, 0x5e, 0xb2, 0x32, 0xd2, 0x18, 0xb9, 0x7d, 0x7c, 0x38, 0xb0, - 0xc7, 0xbe, 0x75, 0x80, 0x69, 0x76, 0xe4, 0xf4, 0x6c, 0xe0, 0xaa, 0x5c, 0x84, 0xee, 0x42, 0x61, - 0xd7, 0x73, 0x87, 0x7d, 0xcb, 0xe1, 0x4a, 0x49, 0xaa, 0x94, 0x27, 0x52, 0x8d, 0x0b, 0x2b, 0xff, - 0x95, 0xa0, 0x48, 0x33, 0x68, 0x26, 0x66, 0xb8, 0x1b, 0x63, 0x86, 0x1b, 0x53, 0xcc, 0x10, 0xa5, - 0x21, 0x21, 0x86, 0xdb, 0x90, 0x1e, 0x3b, 0xd6, 0xf3, 0x71, 0x38, 0x67, 0x44, 0x7e, 0xa1, 0xec, - 0x0c, 0x6d, 0x88, 0x67, 0x69, 0xe3, 0x7d, 0x40, 0xa4, 0x66, 0x70, 0x7f, 0x4a, 0x31, 0x45, 0x15, - 0x15, 0x3a, 0xd2, 0xb8, 0x90, 0x64, 0xd2, 0x57, 0x20, 0x99, 0x87, 0xa0, 0xe0, 0xc3, 0xc0, 0x33, - 0xfa, 0x31, 0xfb, 0x0c, 0xb5, 0x5f, 0x38, 0x39, 0x5e, 0x2c, 0xa8, 0x64, 0xec, 0x7c, 0x90, 0x02, - 0x8e, 0x8d, 0x99, 0x24, 0x27, 0xe6, 0x19, 0x86, 0x69, 0x79, 0x98, 0x9e, 0x92, 0x61, 0xf7, 0x5b, - 0x58, 0xbd, 0x77, 0x21, 0x99, 0x4c, 0x85, 0xbd, 0xda, 0xe4, 0x86, 0xba, 0x12, 0x42, 0x45, 0x02, - 0x1f, 0x3d, 0x86, 0xec, 0x6e, 0x78, 0x50, 0xf7, 0x9f, 0xe1, 0xa3, 0x92, 0x4c, 0xd3, 0xed, 0xdd, - 0xd9, 0x8f, 0x74, 0x5e, 0x9f, 0xbb, 0xd1, 0x10, 0xda, 0x82, 0xbc, 0xc7, 0x87, 0xcd, 0xfe, 0xce, - 0x11, 0x3d, 0x7f, 0x5e, 0x06, 0x34, 0x37, 0x81, 0xa9, 0x1f, 0xa1, 0xc7, 0x00, 0x56, 0xc4, 0x92, - 0xf4, 0x90, 0xca, 0xae, 0xbe, 0x77, 0x05, 0x3a, 0xe5, 0x2b, 0x9d, 0x80, 0xa0, 0x27, 0x50, 0x98, - 0x7c, 0xd1, 0xa5, 0xe6, 0x5e, 0x72, 0xa9, 0xf9, 0x18, 0x4e, 0xfd, 0x08, 0xf5, 0xe0, 0x3a, 0x39, - 0x3e, 0x5d, 0xdf, 0x0a, 0x70, 0x3c, 0x05, 0xf2, 0x34, 0x05, 0x2a, 0x27, 0xc7, 0x8b, 0xa8, 0xc1, - 0xc7, 0xcf, 0x4f, 0x03, 0x34, 0x38, 0x35, 0x1e, 0x26, 0xd5, 0x54, 0xf2, 0x12, 0xc4, 0xc2, 0x24, - 0xa9, 0xba, 0x93, 0xf4, 0x3d, 0x93, 0x54, 0xb1, 0xd4, 0x26, 0x48, 0x4f, 0x20, 0x37, 0xc5, 0x32, - 0xc5, 0x97, 0x67, 0x99, 0x29, 0x20, 0xa4, 0xb2, 0xfe, 0x48, 0xa1, 0xad, 0xe1, 0x7b, 0x33, 0x26, - 0xe8, 0xe9, 0x4e, 0xa9, 0xb2, 0x00, 0x72, 0x94, 0xa3, 0xe4, 0x3a, 0x52, 0xeb, 0x36, 0x94, 0x39, - 0x7a, 0xad, 0x52, 0xbb, 0x0d, 0x45, 0xa8, 0xdc, 0x01, 0x91, 0xde, 0x34, 0xb2, 0x90, 0x59, 0xeb, - 0xe8, 0x4f, 0x6a, 0x7a, 0x33, 0x6c, 0x16, 0xb5, 0xf6, 0xb6, 0xaa, 0xf7, 0xd4, 0xa6, 0x22, 0x54, - 0xbe, 0x13, 0x01, 0x4d, 0xa6, 0xd8, 0x18, 0x07, 0x06, 0x05, 0xab, 0x41, 0x3a, 0x8c, 0x1e, 0x25, - 0xa1, 0xec, 0xea, 0xff, 0x5d, 0xda, 0xc2, 0x4d, 0x00, 0x1e, 0xce, 0xe9, 0xcc, 0x10, 0x7d, 0x1a, - 0xbf, 0x19, 0x64, 0x57, 0xdf, 0x9e, 0xcd, 0xc9, 0x87, 0x73, 0xfc, 0xca, 0xf0, 0x08, 0x52, 0x7e, - 0x40, 0xfa, 0xe7, 0x24, 0x0d, 0xd2, 0xca, 0x05, 0xf6, 0x67, 0x17, 0x5f, 0xed, 0x12, 0x33, 0x7e, - 0xda, 0x50, 0x0c, 0xf4, 0x04, 0xe4, 0x88, 0x17, 0xd8, 0x35, 0xe3, 0xfe, 0xec, 0x80, 0x51, 0x90, - 0x79, 0x8b, 0x11, 0x61, 0xa1, 0x1a, 0x64, 0x87, 0x4c, 0x6d, 0xd2, 0x20, 0x2d, 0x31, 0x6a, 0x06, - 0x8e, 0x40, 0x29, 0x3a, 0xf6, 0xa5, 0x03, 0x37, 0xd2, 0x4c, 0xd2, 0xef, 0x7a, 0xae, 0x6d, 0xef, - 0x18, 0x83, 0x67, 0xf4, 0xae, 0x10, 0xf5, 0xbb, 0x5c, 0x5a, 0xf9, 0x05, 0xa4, 0xa8, 0x4f, 0x64, - 0x23, 0xb7, 0xda, 0x8f, 0xda, 0x9d, 0x27, 0xa4, 0xeb, 0x2f, 0x42, 0xb6, 0xa9, 0xb6, 0xd4, 0x9e, - 0xda, 0xef, 0xb4, 0x5b, 0x4f, 0x15, 0x01, 0xdd, 0x82, 0x1b, 0x4c, 0x50, 0x6b, 0x37, 0xfb, 0x4f, - 0x74, 0x8d, 0x0f, 0x25, 0x2a, 0xcb, 0xf1, 0x4c, 0x99, 0x5c, 0x3c, 0x49, 0xce, 0x34, 0x9b, 0x8a, - 0x40, 0x73, 0x46, 0xef, 0x6c, 0x2a, 0x89, 0x7a, 0x0e, 0xc0, 0x8c, 0x22, 0xb0, 0x2e, 0x4a, 0x69, - 0x25, 0x53, 0xf9, 0x77, 0x09, 0x8a, 0xb4, 0x47, 0x9a, 0xe9, 0x90, 0x5a, 0xa2, 0x87, 0x54, 0xd8, - 0xf0, 0x28, 0x53, 0x87, 0x54, 0x82, 0x9d, 0x4f, 0xf7, 0x41, 0x1e, 0x19, 0x1e, 0x76, 0x02, 0x12, - 0x32, 0x71, 0xaa, 0xcf, 0x95, 0x36, 0xe9, 0x40, 0xa4, 0x2e, 0x85, 0x8a, 0x1a, 0x31, 0xca, 0x1c, - 0x60, 0x8f, 0x3e, 0xf8, 0x84, 0x51, 0xbe, 0xc5, 0xee, 0x9a, 0xf3, 0x93, 0x55, 0x6d, 0x87, 0x0a, - 0x3a, 0xd7, 0x44, 0x6f, 0x02, 0x8c, 0x47, 0x7d, 0x6e, 0x17, 0xbf, 0x0a, 0xc8, 0xe3, 0x11, 0xd3, - 0x46, 0x9b, 0x30, 0x3f, 0x74, 0x4d, 0x6b, 0xd7, 0x1a, 0x84, 0xfb, 0x18, 0x58, 0xc3, 0xf0, 0xd6, - 0x96, 0x5d, 0x7d, 0x23, 0x96, 0x24, 0xe3, 0xc0, 0xb2, 0xab, 0xfb, 0xf6, 0xa0, 0xda, 0xe3, 0xaf, - 0x68, 0x0c, 0x4a, 0x89, 0x5b, 0x93, 0x41, 0xf4, 0x00, 0x32, 0xbc, 0x3d, 0x0b, 0x5f, 0x60, 0x66, - 0xad, 0x1f, 0x86, 0xc8, 0xad, 0xd1, 0x1a, 0x14, 0x1c, 0x7c, 0x18, 0x6f, 0xc1, 0xe5, 0xa9, 0x0c, - 0xcb, 0xb5, 0xf1, 0xe1, 0xf9, 0xfd, 0x77, 0xce, 0x99, 0x8c, 0x98, 0xe8, 0x31, 0xe4, 0x47, 0x9e, - 0x35, 0x34, 0xbc, 0xa3, 0x7e, 0x58, 0x94, 0x70, 0x95, 0xa2, 0x8c, 0x38, 0x2c, 0x84, 0xa0, 0xa3, - 0x68, 0x0d, 0xc2, 0x8e, 0x17, 0xfb, 0xa5, 0x2c, 0xf5, 0xf1, 0x6a, 0x60, 0xdc, 0x18, 0xd5, 0x21, - 0x4f, 0x5d, 0x8c, 0x5a, 0xed, 0x1c, 0xf5, 0x70, 0x81, 0x79, 0x98, 0x25, 0x1e, 0x9e, 0xd3, 0x6e, - 0x67, 0x9d, 0x48, 0x6e, 0xa2, 0x75, 0x80, 0xe8, 0xf5, 0x92, 0x1c, 0x1f, 0x97, 0x9d, 0xce, 0x9b, - 0x5c, 0x71, 0xb2, 0x24, 0x3d, 0x66, 0x8d, 0x36, 0x40, 0xe6, 0xc5, 0x19, 0x9e, 0x1b, 0xd9, 0x0b, - 0x5f, 0x24, 0xce, 0x52, 0x05, 0x4f, 0xae, 0x08, 0x01, 0xb5, 0x21, 0x65, 0x63, 0xc3, 0xc7, 0xec, - 0xf0, 0xf8, 0xf8, 0x02, 0xa8, 0x53, 0xe5, 0x55, 0xed, 0x0e, 0xf6, 0xf1, 0xd0, 0x68, 0xec, 0x93, - 0x46, 0xb4, 0x45, 0xec, 0xf5, 0x10, 0x06, 0xb5, 0x41, 0xa1, 0xe1, 0x8a, 0xb3, 0x8e, 0x42, 0x23, - 0xf6, 0x16, 0x8b, 0x58, 0x81, 0x44, 0xec, 0x42, 0xe6, 0xa1, 0xf9, 0xb4, 0x31, 0x61, 0x9f, 0x9f, - 0x43, 0x61, 0xd7, 0xf5, 0x86, 0x46, 0x10, 0x55, 0xc9, 0xfc, 0xa4, 0xbd, 0xfc, 0xe1, 0x78, 0x31, - 0xbf, 0x46, 0x47, 0x79, 0x65, 0xe5, 0x77, 0xe3, 0x9f, 0xe8, 0x21, 0x27, 0xe9, 0x6b, 0x94, 0x53, - 0xdf, 0x9f, 0xd5, 0xbb, 0xb3, 0x0c, 0xdd, 0x86, 0xf4, 0x60, 0x1f, 0x0f, 0x9e, 0xf9, 0xa5, 0xeb, - 0x34, 0xe6, 0x3f, 0x99, 0x11, 0xaa, 0x41, 0x8c, 0x26, 0x4f, 0x43, 0x3a, 0x43, 0x41, 0x5f, 0x40, - 0xc1, 0x24, 0x12, 0xcb, 0xd9, 0x63, 0xed, 0xeb, 0x0d, 0x8a, 0xbb, 0x32, 0x23, 0x2e, 0x69, 0x6d, - 0x35, 0x67, 0xd7, 0xe5, 0x9d, 0x0b, 0x07, 0x0b, 0x5b, 0xde, 0x0e, 0x48, 0xbb, 0xe4, 0x2a, 0x6e, - 0x61, 0xbf, 0x74, 0x93, 0xe2, 0x5e, 0xfe, 0x28, 0x7c, 0xfa, 0xf6, 0xcf, 0x29, 0x9e, 0x83, 0x44, - 0x85, 0x4e, 0x05, 0x47, 0x64, 0x53, 0x5f, 0x3b, 0x5b, 0xe8, 0xfc, 0xf6, 0x3f, 0xf5, 0x12, 0x40, - 0x0b, 0x9d, 0x7d, 0x99, 0x84, 0xf0, 0x0e, 0x2c, 0xfc, 0x55, 0xff, 0xf9, 0x18, 0x7b, 0x47, 0xa5, - 0x52, 0x8c, 0x9c, 0x65, 0x22, 0x7f, 0x4c, 0xc4, 0xe8, 0x43, 0x90, 0x4d, 0x3c, 0xc2, 0x8e, 0xe9, - 0x77, 0x9c, 0xd2, 0x2d, 0xda, 0x1a, 0x5d, 0x23, 0xfd, 0x7a, 0x93, 0x0b, 0x19, 0xf9, 0x4e, 0xb4, - 0xd0, 0x97, 0x90, 0x0b, 0x3f, 0xb0, 0xd9, 0x71, 0xea, 0x47, 0xa5, 0x32, 0x75, 0xfa, 0xde, 0x8c, - 0xc1, 0x9c, 0xf4, 0x81, 0xd7, 0xb9, 0x3f, 0xcd, 0x18, 0x9a, 0x3e, 0x85, 0x8d, 0xbe, 0x80, 0x1c, - 0xcf, 0xee, 0x75, 0x77, 0xc7, 0x2f, 0xbd, 0x7e, 0xe9, 0x0d, 0xf6, 0xf4, 0x5c, 0x1b, 0x13, 0x53, - 0xce, 0x5b, 0x71, 0x34, 0xf4, 0x19, 0xe4, 0xa3, 0x67, 0x1f, 0x77, 0x14, 0xf8, 0xa5, 0xdb, 0xb4, - 0x30, 0xef, 0xcf, 0x9a, 0xba, 0xcc, 0xb6, 0x33, 0x0a, 0x7c, 0x3d, 0xe7, 0xc7, 0xbe, 0xd0, 0x1d, + 0x2c, 0x7d, 0x03, 0x1f, 0x53, 0xb9, 0xe4, 0xe6, 0xb8, 0x7c, 0x4a, 0x55, 0xae, 0x39, 0xe4, 0x23, + 0x6c, 0x6e, 0x29, 0x9f, 0x72, 0x89, 0x2a, 0x51, 0x2a, 0x55, 0xf9, 0x04, 0x39, 0xb8, 0x2a, 0x55, + 0xa9, 0x19, 0xcc, 0x80, 0xa0, 0x5e, 0xa6, 0x76, 0x6f, 0x60, 0x4f, 0xf7, 0x6f, 0xa6, 0x7b, 0xba, + 0x7f, 0xd3, 0x33, 0x84, 0xdb, 0xfe, 0x73, 0x7b, 0xc5, 0x7f, 0x6e, 0xef, 0x18, 0x3e, 0x5e, 0xf1, + 0x03, 0x6f, 0x3c, 0x08, 0xc6, 0x1e, 0x36, 0xab, 0x23, 0xcf, 0x0d, 0x5c, 0x74, 0x63, 0xe0, 0x0e, + 0x9e, 0x79, 0xae, 0x31, 0xd8, 0xaf, 0xfa, 0xcf, 0xed, 0x2a, 0xd3, 0x2b, 0x97, 0xc6, 0x81, 0x65, + 0xaf, 0xec, 0xdb, 0x83, 0x95, 0xc0, 0x1a, 0x62, 0x3f, 0x30, 0x86, 0xa3, 0xd0, 0xa0, 0xfc, 0x7a, + 0x1c, 0x6e, 0xe4, 0x59, 0x07, 0x96, 0x8d, 0xf7, 0x30, 0x1b, 0xbc, 0xbe, 0xe7, 0xee, 0xb9, 0xf4, + 0x73, 0x85, 0x7c, 0x85, 0xd2, 0xca, 0xf7, 0x19, 0x80, 0x86, 0x6b, 0x8f, 0x87, 0x4e, 0xef, 0x68, + 0x84, 0xd1, 0x53, 0xc8, 0xfb, 0x78, 0x68, 0x38, 0x81, 0x35, 0xe8, 0x07, 0x47, 0x23, 0x5c, 0x12, + 0x96, 0x84, 0xe5, 0xc2, 0x6a, 0xb5, 0x7a, 0xee, 0x52, 0xaa, 0x13, 0xcb, 0x6a, 0x97, 0x99, 0x91, + 0x1f, 0x75, 0xf1, 0xc5, 0xf1, 0xe2, 0x9c, 0x9e, 0xf3, 0x63, 0x32, 0x54, 0x86, 0xd4, 0x57, 0x96, + 0x19, 0xec, 0x97, 0x12, 0x4b, 0xc2, 0x72, 0x8a, 0xa9, 0x84, 0x22, 0x54, 0x01, 0x79, 0xe4, 0xe1, + 0x81, 0xe5, 0x5b, 0xae, 0x53, 0x4a, 0xc6, 0xc6, 0x27, 0x62, 0xf4, 0x0e, 0x28, 0x86, 0xe7, 0x19, + 0x47, 0x7d, 0xd3, 0x1a, 0x62, 0x87, 0x88, 0xfc, 0x92, 0xb8, 0x94, 0x5c, 0x4e, 0xe9, 0x45, 0x2a, + 0x6f, 0x46, 0x62, 0x74, 0x13, 0xd2, 0xb6, 0x3b, 0x30, 0x6c, 0x5c, 0x4a, 0x2d, 0x09, 0xcb, 0xb2, + 0xce, 0x7e, 0xa1, 0x6d, 0xc8, 0x1d, 0x58, 0xbe, 0xb5, 0x63, 0xe3, 0xd0, 0xb9, 0x34, 0x75, 0xee, + 0x83, 0x1f, 0x77, 0x6e, 0x3b, 0xb4, 0x8a, 0xf9, 0x96, 0x3d, 0x98, 0x88, 0xd0, 0x16, 0x14, 0xc2, + 0xa5, 0x0d, 0x5c, 0x27, 0xc0, 0x4e, 0xe0, 0x97, 0x32, 0x2f, 0x13, 0x36, 0x3d, 0x4f, 0x51, 0x1a, + 0x0c, 0x04, 0xb5, 0xa1, 0x10, 0x8c, 0x47, 0x36, 0x9e, 0xc0, 0x4a, 0x4b, 0xc9, 0xe5, 0xec, 0xea, + 0x9d, 0x1f, 0x85, 0x65, 0x8b, 0xcc, 0x53, 0xf3, 0x08, 0xef, 0x0e, 0xe4, 0x42, 0x3c, 0xdb, 0xd8, + 0xc1, 0xb6, 0x5f, 0x92, 0x97, 0x92, 0xcb, 0xb2, 0x9e, 0xa5, 0xb2, 0x16, 0x15, 0x55, 0x7e, 0x9f, + 0x80, 0x5c, 0x7c, 0x49, 0x48, 0x02, 0xb1, 0xde, 0xe9, 0xb4, 0x94, 0x39, 0x94, 0x81, 0xa4, 0xd6, + 0xee, 0x29, 0x02, 0x92, 0x21, 0xb5, 0xd6, 0xea, 0xd4, 0x7a, 0x4a, 0x02, 0x65, 0x21, 0xd3, 0x54, + 0x1b, 0xda, 0x46, 0xad, 0xa5, 0x24, 0x89, 0x6a, 0xb3, 0xd6, 0x53, 0x15, 0x11, 0xe5, 0x41, 0xee, + 0x69, 0x1b, 0x6a, 0xb7, 0x57, 0xdb, 0xd8, 0x54, 0x52, 0x28, 0x07, 0x92, 0xd6, 0xee, 0xa9, 0xfa, + 0x76, 0xad, 0xa5, 0xa4, 0x11, 0x40, 0xba, 0xdb, 0xd3, 0xb5, 0xf6, 0x03, 0x25, 0x43, 0xa0, 0xea, + 0x4f, 0x7b, 0x6a, 0x57, 0x91, 0x50, 0x11, 0xb2, 0x91, 0x4d, 0xef, 0x73, 0x45, 0x46, 0x08, 0x0a, + 0x8d, 0x4e, 0xab, 0x55, 0xeb, 0xa9, 0x4d, 0xa6, 0x0f, 0x64, 0x8a, 0x76, 0x6d, 0x43, 0x55, 0xb2, + 0x64, 0x35, 0x1d, 0xad, 0xa9, 0xe4, 0xa8, 0x68, 0xab, 0xd5, 0x52, 0xf2, 0xe4, 0x6b, 0x6b, 0x4b, + 0x6b, 0x2a, 0x05, 0x02, 0x5b, 0xd3, 0xf5, 0xda, 0x53, 0xa5, 0x48, 0x84, 0x5a, 0x5b, 0xed, 0x29, + 0x0a, 0xf9, 0x22, 0x13, 0x28, 0xf3, 0x64, 0x78, 0xbd, 0xdb, 0x69, 0xd7, 0x15, 0x44, 0x3e, 0x7b, + 0x5b, 0x9b, 0x2d, 0x55, 0xb9, 0x4e, 0x10, 0xeb, 0x5a, 0x4f, 0xb9, 0x81, 0x8a, 0x00, 0x5a, 0xbb, + 0xb7, 0xba, 0xad, 0x36, 0x7a, 0x1d, 0x5d, 0x79, 0x21, 0xa0, 0x02, 0xc8, 0x1d, 0xad, 0xc9, 0x7e, + 0xff, 0x59, 0xa8, 0x88, 0xd2, 0x35, 0xe5, 0x5a, 0xe5, 0x37, 0x02, 0x64, 0x63, 0x79, 0x41, 0x17, + 0xd2, 0x69, 0xab, 0xca, 0x1c, 0x89, 0x0a, 0xf1, 0xf7, 0x81, 0xaa, 0x2b, 0x02, 0x71, 0xbe, 0xbb, + 0x51, 0x6b, 0xb5, 0x48, 0xec, 0x12, 0xc4, 0xf9, 0xba, 0xf6, 0x80, 0x7c, 0xd3, 0x78, 0xe9, 0x6a, + 0xad, 0xa5, 0xa4, 0xd0, 0x75, 0x50, 0x9a, 0x9d, 0xad, 0x7a, 0x4b, 0xed, 0x6f, 0xea, 0x6a, 0x43, + 0xeb, 0x6a, 0x9d, 0xb6, 0x92, 0x26, 0x30, 0xdb, 0x35, 0xbd, 0xf1, 0xb0, 0xa6, 0x2b, 0x19, 0xa2, + 0x4c, 0xbf, 0x24, 0xb2, 0xe4, 0xc7, 0xf4, 0x53, 0x26, 0x68, 0xdb, 0x35, 0x9d, 0xac, 0x1a, 0x2a, + 0xa2, 0x24, 0x2a, 0xe2, 0x27, 0xe2, 0xbf, 0xbf, 0x5d, 0x14, 0x2a, 0xff, 0x49, 0xc2, 0xb5, 0x35, + 0xd7, 0xc3, 0xd6, 0x9e, 0xf3, 0x08, 0x1f, 0xe9, 0x78, 0x17, 0x7b, 0xd8, 0x19, 0x60, 0xb4, 0x04, + 0xa9, 0xc0, 0xd8, 0xb1, 0xc3, 0xaa, 0xce, 0xd7, 0x81, 0x24, 0xc9, 0x0f, 0xc7, 0x8b, 0x09, 0xad, + 0xa9, 0x87, 0x03, 0xe8, 0x2e, 0xa4, 0x2c, 0xc7, 0xc4, 0x87, 0xb4, 0x48, 0xf3, 0xf5, 0x22, 0xd3, + 0xc8, 0x68, 0x44, 0x48, 0xd4, 0xe8, 0x28, 0x2a, 0x81, 0xe8, 0x18, 0x43, 0x4c, 0x4b, 0x55, 0x66, + 0xc9, 0x46, 0x25, 0xe8, 0x11, 0x48, 0x07, 0x86, 0x6d, 0x99, 0x56, 0x70, 0x54, 0x12, 0x69, 0x11, + 0xbc, 0x73, 0x61, 0xb6, 0x3a, 0x7e, 0xe0, 0x19, 0x96, 0x13, 0x6c, 0x33, 0x03, 0x06, 0x14, 0x01, + 0xa0, 0x7b, 0x30, 0xef, 0xef, 0x1b, 0x1e, 0x36, 0xfb, 0x23, 0x0f, 0xef, 0x5a, 0x87, 0x7d, 0x1b, + 0x3b, 0xb4, 0xa4, 0x39, 0x3d, 0x14, 0xc3, 0xe1, 0x4d, 0x3a, 0xda, 0xc2, 0x0e, 0xea, 0x81, 0xec, + 0x3a, 0x7d, 0x13, 0xdb, 0x38, 0xe0, 0xe5, 0xfd, 0xe1, 0x05, 0xf3, 0x9f, 0x13, 0xa0, 0x6a, 0x6d, + 0x10, 0x58, 0xae, 0xc3, 0xd7, 0xe1, 0x3a, 0x4d, 0x0a, 0xc4, 0x50, 0xc7, 0x23, 0xd3, 0x08, 0x30, + 0x2b, 0xed, 0x57, 0x41, 0xdd, 0xa2, 0x40, 0x95, 0xc7, 0x90, 0x0e, 0x47, 0x48, 0xbd, 0xb4, 0x3b, + 0xfd, 0x5a, 0xa3, 0x47, 0x36, 0x7e, 0x8e, 0xa4, 0x8c, 0xae, 0x92, 0x9c, 0x6f, 0xf4, 0x58, 0x02, + 0xa9, 0xbd, 0x3e, 0x4d, 0xf2, 0x04, 0x29, 0x13, 0xf2, 0xab, 0xa9, 0xae, 0xd5, 0xb6, 0x5a, 0x24, + 0x8b, 0xb2, 0x90, 0x69, 0xd4, 0xba, 0x8d, 0x5a, 0x53, 0x55, 0xc4, 0xca, 0xdf, 0x12, 0xa0, 0x84, + 0x2c, 0xd0, 0xc4, 0xfe, 0xc0, 0xb3, 0x46, 0x81, 0xeb, 0x45, 0x9b, 0x25, 0x9c, 0xd9, 0xac, 0xb7, + 0x21, 0x61, 0x99, 0x6c, 0xab, 0x6f, 0x12, 0xf9, 0x09, 0x4d, 0x86, 0x1f, 0x8e, 0x17, 0xa5, 0x10, + 0x45, 0x6b, 0xea, 0x09, 0xcb, 0x44, 0x3f, 0x03, 0x91, 0xf2, 0x25, 0xd9, 0xee, 0x2b, 0xd0, 0x0f, + 0x35, 0x42, 0x4b, 0x20, 0x39, 0x63, 0xdb, 0xa6, 0x79, 0x47, 0x32, 0x42, 0xe2, 0x81, 0xe0, 0x52, + 0xc2, 0x4b, 0x26, 0xde, 0x35, 0xc6, 0x76, 0xd0, 0xc7, 0x87, 0x23, 0x8f, 0x91, 0x76, 0x96, 0xc9, + 0xd4, 0xc3, 0x91, 0x87, 0x6e, 0x43, 0x7a, 0xdf, 0x32, 0x4d, 0xec, 0xd0, 0x4d, 0xe5, 0x10, 0x4c, + 0x86, 0x56, 0x61, 0x7e, 0xec, 0x63, 0xbf, 0xef, 0xe3, 0xe7, 0x63, 0x12, 0xf1, 0xbe, 0x65, 0xfa, + 0x25, 0x58, 0x4a, 0x2e, 0xe7, 0xeb, 0x69, 0x96, 0xdf, 0x45, 0xa2, 0xd0, 0x65, 0xe3, 0x9a, 0x49, + 0xc9, 0x70, 0xe0, 0x0e, 0x47, 0xe3, 0x00, 0x87, 0x93, 0x66, 0xc3, 0x49, 0x99, 0x8c, 0x4c, 0xba, + 0x2e, 0x4a, 0x92, 0x22, 0xaf, 0x8b, 0x92, 0xac, 0xc0, 0xba, 0x28, 0x65, 0x14, 0xa9, 0xf2, 0x75, + 0x02, 0x6e, 0x86, 0x6e, 0xae, 0x19, 0x43, 0xcb, 0x3e, 0x7a, 0xd5, 0x28, 0x87, 0x28, 0x2c, 0xca, + 0x74, 0x45, 0x04, 0xbb, 0x4f, 0xcc, 0xfc, 0x52, 0x32, 0xa4, 0xe7, 0x50, 0xd6, 0x26, 0x22, 0xf4, + 0x31, 0x00, 0x53, 0x21, 0x1e, 0x8a, 0xd4, 0xc3, 0x5b, 0x27, 0xc7, 0x8b, 0x32, 0xdf, 0x2e, 0x7f, + 0x6a, 0xef, 0xe4, 0x50, 0x99, 0xb8, 0xdb, 0x81, 0x79, 0x1e, 0xe3, 0x08, 0x81, 0x06, 0x3a, 0x5f, + 0x7f, 0x93, 0xad, 0xa9, 0xd8, 0x0c, 0x15, 0xb8, 0xf9, 0x14, 0x54, 0xd1, 0x9c, 0x1a, 0x34, 0x2b, + 0x7f, 0x48, 0xc0, 0x75, 0xcd, 0x09, 0xb0, 0x67, 0x63, 0xe3, 0x00, 0xc7, 0x02, 0xf1, 0x19, 0xc8, + 0x86, 0x33, 0xc0, 0x7e, 0xe0, 0x7a, 0x7e, 0x49, 0xa0, 0x07, 0xd6, 0x47, 0x17, 0x64, 0xcc, 0x79, + 0xf6, 0xd5, 0x1a, 0x33, 0xe6, 0x1d, 0x40, 0x04, 0x56, 0xfe, 0x93, 0x00, 0x12, 0x1f, 0x45, 0xf7, + 0x40, 0xa2, 0x94, 0x45, 0xfc, 0x08, 0xe9, 0xec, 0x06, 0xf3, 0x23, 0xd3, 0x23, 0x72, 0xba, 0x7e, + 0xb2, 0xf3, 0x19, 0xaa, 0xa6, 0x99, 0xe8, 0xff, 0x41, 0xa2, 0xec, 0xd5, 0x8f, 0x76, 0xa3, 0xcc, + 0x2d, 0x18, 0xbd, 0xc5, 0x99, 0x2e, 0x43, 0x75, 0x35, 0x13, 0x35, 0xce, 0x23, 0xa1, 0x24, 0xb5, + 0x7f, 0x8d, 0x47, 0xae, 0x3b, 0x4d, 0x43, 0x67, 0x78, 0xa9, 0xf2, 0xaf, 0x24, 0xdc, 0xdc, 0x34, + 0xbc, 0xc0, 0x22, 0xf5, 0x6e, 0x39, 0x7b, 0xb1, 0x78, 0xdd, 0x85, 0xac, 0x33, 0x1e, 0xb2, 0x5d, + 0xf1, 0x99, 0x2f, 0xa1, 0xef, 0xe0, 0x8c, 0x87, 0x61, 0xc0, 0x7d, 0xd4, 0x02, 0xd1, 0xb6, 0xfc, + 0xa0, 0x94, 0xa0, 0x11, 0x5d, 0xbd, 0x20, 0xa2, 0xe7, 0xcf, 0x51, 0x6d, 0x59, 0x7e, 0xc0, 0x73, + 0x92, 0xa0, 0xa0, 0x0e, 0xa4, 0x3c, 0xc3, 0xd9, 0xc3, 0x34, 0xc9, 0xb2, 0xab, 0xf7, 0xaf, 0x06, + 0xa7, 0x13, 0x53, 0xde, 0xc1, 0x51, 0x9c, 0xf2, 0x6f, 0x05, 0x10, 0xc9, 0x2c, 0x97, 0xd4, 0xc1, + 0x4d, 0x48, 0x1f, 0x18, 0xf6, 0x18, 0xfb, 0xd4, 0x87, 0x9c, 0xce, 0x7e, 0xa1, 0x5f, 0x42, 0xd1, + 0x1f, 0xef, 0x8c, 0x62, 0x53, 0x31, 0xa2, 0xf9, 0xe0, 0x4a, 0xab, 0x8a, 0x8e, 0x84, 0x69, 0xac, + 0xf2, 0x33, 0x48, 0xd1, 0xf5, 0x5e, 0xb2, 0x32, 0xd2, 0x18, 0xb9, 0x7d, 0x7c, 0x38, 0xb0, 0xc7, + 0xbe, 0x75, 0x80, 0x69, 0x76, 0xe4, 0xf4, 0x6c, 0xe0, 0xaa, 0x5c, 0x84, 0xee, 0x42, 0x61, 0xd7, + 0x73, 0x87, 0x7d, 0xcb, 0xe1, 0x4a, 0x49, 0xaa, 0x94, 0x27, 0x52, 0x8d, 0x0b, 0x2b, 0xff, 0x95, + 0xa0, 0x48, 0x33, 0x68, 0x26, 0x66, 0xb8, 0x1b, 0x63, 0x86, 0x1b, 0x53, 0xcc, 0x10, 0xa5, 0x21, + 0x21, 0x86, 0xdb, 0x90, 0x1e, 0x3b, 0xd6, 0xf3, 0x71, 0x38, 0x67, 0x44, 0x7e, 0xa1, 0xec, 0x0c, + 0x6d, 0x88, 0x67, 0x69, 0xe3, 0x7d, 0x40, 0xa4, 0x66, 0x70, 0x7f, 0x4a, 0x31, 0x45, 0x15, 0x15, + 0x3a, 0xd2, 0xb8, 0x90, 0x64, 0xd2, 0x57, 0x20, 0x99, 0x87, 0xa0, 0xe0, 0xc3, 0xc0, 0x33, 0xfa, + 0x31, 0xfb, 0x0c, 0xb5, 0x5f, 0x38, 0x39, 0x5e, 0x2c, 0xa8, 0x64, 0xec, 0x7c, 0x90, 0x02, 0x8e, + 0x8d, 0x99, 0x24, 0x27, 0xe6, 0x19, 0x86, 0x69, 0x79, 0x98, 0x9e, 0x92, 0x61, 0xf7, 0x5b, 0x58, + 0xbd, 0x77, 0x21, 0x99, 0x4c, 0x85, 0xbd, 0xda, 0xe4, 0x86, 0xba, 0x12, 0x42, 0x45, 0x02, 0x1f, + 0x3d, 0x86, 0xec, 0x6e, 0x78, 0x50, 0xf7, 0x9f, 0xe1, 0xa3, 0x92, 0x4c, 0xd3, 0xed, 0xdd, 0xd9, + 0x8f, 0x74, 0x5e, 0x9f, 0xbb, 0xd1, 0x10, 0xda, 0x82, 0xbc, 0xc7, 0x87, 0xcd, 0xfe, 0xce, 0x11, + 0x3d, 0x7f, 0x5e, 0x06, 0x34, 0x37, 0x81, 0xa9, 0x1f, 0xa1, 0xc7, 0x00, 0x56, 0xc4, 0x92, 0xf4, + 0x90, 0xca, 0xae, 0xbe, 0x77, 0x05, 0x3a, 0xe5, 0x2b, 0x9d, 0x80, 0xa0, 0x27, 0x50, 0x98, 0xfc, + 0xa2, 0x4b, 0xcd, 0xbd, 0xe4, 0x52, 0xf3, 0x31, 0x9c, 0xfa, 0x11, 0xea, 0xc1, 0x75, 0x72, 0x7c, + 0xba, 0xbe, 0x15, 0xe0, 0x78, 0x0a, 0xe4, 0x69, 0x0a, 0x54, 0x4e, 0x8e, 0x17, 0x51, 0x83, 0x8f, + 0x9f, 0x9f, 0x06, 0x68, 0x70, 0x6a, 0x3c, 0x4c, 0xaa, 0xa9, 0xe4, 0x25, 0x88, 0x85, 0x49, 0x52, + 0x75, 0x27, 0xe9, 0x7b, 0x26, 0xa9, 0x62, 0xa9, 0x4d, 0x90, 0x9e, 0x40, 0x6e, 0x8a, 0x65, 0x8a, + 0x2f, 0xcf, 0x32, 0x53, 0x40, 0x48, 0x65, 0xfd, 0x91, 0x42, 0x5b, 0xc3, 0xf7, 0x66, 0x4c, 0xd0, + 0xd3, 0x9d, 0x52, 0x65, 0x01, 0xe4, 0x28, 0x47, 0xc9, 0x75, 0xa4, 0xd6, 0x6d, 0x28, 0x73, 0xf4, + 0x5a, 0xa5, 0x76, 0x1b, 0x8a, 0x50, 0xb9, 0x03, 0x22, 0xbd, 0x69, 0x64, 0x21, 0xb3, 0xd6, 0xd1, + 0x9f, 0xd4, 0xf4, 0x66, 0xd8, 0x2c, 0x6a, 0xed, 0x6d, 0x55, 0xef, 0xa9, 0x4d, 0x45, 0xa8, 0x7c, + 0x27, 0x02, 0x9a, 0x4c, 0xb1, 0x31, 0x0e, 0x0c, 0x0a, 0x56, 0x83, 0x74, 0x18, 0x3d, 0x4a, 0x42, + 0xd9, 0xd5, 0xff, 0xbb, 0xb4, 0x85, 0x9b, 0x00, 0x3c, 0x9c, 0xd3, 0x99, 0x21, 0xfa, 0x34, 0x7e, + 0x33, 0xc8, 0xae, 0xbe, 0x3d, 0x9b, 0x93, 0x0f, 0xe7, 0xf8, 0x95, 0xe1, 0x11, 0xa4, 0xfc, 0x80, + 0xf4, 0xcf, 0x49, 0x1a, 0xa4, 0x95, 0x0b, 0xec, 0xcf, 0x2e, 0xbe, 0xda, 0x25, 0x66, 0xfc, 0xb4, + 0xa1, 0x18, 0xe8, 0x09, 0xc8, 0x11, 0x2f, 0xb0, 0x6b, 0xc6, 0xfd, 0xd9, 0x01, 0xa3, 0x20, 0xf3, + 0x16, 0x23, 0xc2, 0x42, 0x35, 0xc8, 0x0e, 0x99, 0xda, 0xa4, 0x41, 0x5a, 0x62, 0xd4, 0x0c, 0x1c, + 0x81, 0x52, 0x74, 0xec, 0x97, 0x0e, 0xdc, 0x48, 0x33, 0x49, 0xbf, 0xeb, 0xb9, 0xb6, 0xbd, 0x63, + 0x0c, 0x9e, 0xd1, 0xbb, 0x42, 0xd4, 0xef, 0x72, 0x69, 0xe5, 0x17, 0x90, 0xa2, 0x3e, 0x91, 0x8d, + 0xdc, 0x6a, 0x3f, 0x6a, 0x77, 0x9e, 0x90, 0xae, 0xbf, 0x08, 0xd9, 0xa6, 0xda, 0x52, 0x7b, 0x6a, + 0xbf, 0xd3, 0x6e, 0x3d, 0x55, 0x04, 0x74, 0x0b, 0x6e, 0x30, 0x41, 0xad, 0xdd, 0xec, 0x3f, 0xd1, + 0x35, 0x3e, 0x94, 0xa8, 0x2c, 0xc7, 0x33, 0x65, 0x72, 0xf1, 0x24, 0x39, 0xd3, 0x6c, 0x2a, 0x02, + 0xcd, 0x19, 0xbd, 0xb3, 0xa9, 0x24, 0xea, 0x39, 0x00, 0x33, 0x8a, 0xc0, 0xba, 0x28, 0xa5, 0x95, + 0x4c, 0xe5, 0x77, 0xb7, 0xa0, 0x48, 0x7b, 0xa4, 0x99, 0x0e, 0xa9, 0x25, 0x7a, 0x48, 0x85, 0x0d, + 0x8f, 0x32, 0x75, 0x48, 0x25, 0xd8, 0xf9, 0x74, 0x1f, 0xe4, 0x91, 0xe1, 0x61, 0x27, 0x20, 0x21, + 0x13, 0xa7, 0xfa, 0x5c, 0x69, 0x93, 0x0e, 0x44, 0xea, 0x52, 0xa8, 0xa8, 0x11, 0xa3, 0xcc, 0x01, + 0xf6, 0xe8, 0x83, 0x4f, 0x18, 0xe5, 0x5b, 0xec, 0xae, 0x39, 0x3f, 0x59, 0xd5, 0x76, 0xa8, 0xa0, + 0x73, 0x4d, 0xf4, 0x26, 0xc0, 0x78, 0xd4, 0xe7, 0x76, 0xf1, 0xab, 0x80, 0x3c, 0x1e, 0x31, 0x6d, + 0xb4, 0x09, 0xf3, 0x43, 0xd7, 0xb4, 0x76, 0xad, 0x41, 0xb8, 0x8f, 0x81, 0x35, 0x0c, 0x6f, 0x6d, + 0xd9, 0xd5, 0x37, 0x62, 0x49, 0x32, 0x0e, 0x2c, 0xbb, 0xba, 0x6f, 0x0f, 0xaa, 0x3d, 0xfe, 0x8a, + 0xc6, 0xa0, 0x94, 0xb8, 0x35, 0x19, 0x44, 0x0f, 0x20, 0xc3, 0xdb, 0xb3, 0xf0, 0x05, 0x66, 0xd6, + 0xfa, 0x61, 0x88, 0xdc, 0x1a, 0xad, 0x41, 0xc1, 0xc1, 0x87, 0xf1, 0x16, 0x5c, 0x9e, 0xca, 0xb0, + 0x5c, 0x1b, 0x1f, 0x9e, 0xdf, 0x7f, 0xe7, 0x9c, 0xc9, 0x88, 0x89, 0x1e, 0x43, 0x7e, 0xe4, 0x59, + 0x43, 0xc3, 0x3b, 0xea, 0x87, 0x45, 0x09, 0x57, 0x29, 0xca, 0x88, 0xc3, 0x42, 0x08, 0x3a, 0x8a, + 0xd6, 0x20, 0xec, 0x78, 0xb1, 0x5f, 0xca, 0x52, 0x1f, 0xaf, 0x06, 0xc6, 0x8d, 0x51, 0x1d, 0xf2, + 0xd4, 0xc5, 0xa8, 0xd5, 0xce, 0x51, 0x0f, 0x17, 0x98, 0x87, 0x59, 0xe2, 0xe1, 0x39, 0xed, 0x76, + 0xd6, 0x89, 0xe4, 0x26, 0x5a, 0x07, 0x88, 0x5e, 0x2f, 0xc9, 0xf1, 0x71, 0xd9, 0xe9, 0xbc, 0xc9, + 0x15, 0x27, 0x4b, 0xd2, 0x63, 0xd6, 0x68, 0x03, 0x64, 0x5e, 0x9c, 0xe1, 0xb9, 0x91, 0xbd, 0xf0, + 0x45, 0xe2, 0x2c, 0x55, 0xf0, 0xe4, 0x8a, 0x10, 0x50, 0x1b, 0x52, 0x36, 0x36, 0x7c, 0xcc, 0x0e, + 0x8f, 0x8f, 0x2f, 0x80, 0x3a, 0x55, 0x5e, 0xd5, 0xee, 0x60, 0x1f, 0x0f, 0x8d, 0xc6, 0x3e, 0x69, + 0x44, 0x5b, 0xc4, 0x5e, 0x0f, 0x61, 0x50, 0x1b, 0x14, 0x1a, 0xae, 0x38, 0xeb, 0x28, 0x34, 0x62, + 0x6f, 0xb1, 0x88, 0x15, 0x48, 0xc4, 0x2e, 0x64, 0x1e, 0x9a, 0x4f, 0x1b, 0x13, 0xf6, 0xf9, 0x39, + 0x14, 0x76, 0x5d, 0x6f, 0x68, 0x04, 0x51, 0x95, 0xcc, 0x4f, 0xda, 0xcb, 0x1f, 0x8e, 0x17, 0xf3, + 0x6b, 0x74, 0x94, 0x57, 0x56, 0x7e, 0x37, 0xfe, 0x13, 0x3d, 0xe4, 0x24, 0x7d, 0x8d, 0x72, 0xea, + 0xfb, 0xb3, 0x7a, 0x77, 0x96, 0xa1, 0xdb, 0x90, 0x1e, 0xec, 0xe3, 0xc1, 0x33, 0xbf, 0x74, 0x9d, + 0xc6, 0xfc, 0x27, 0x33, 0x42, 0x35, 0x88, 0xd1, 0xe4, 0x69, 0x48, 0x67, 0x28, 0xe8, 0x0b, 0x28, + 0x98, 0x44, 0x62, 0x39, 0x7b, 0xac, 0x7d, 0xbd, 0x41, 0x71, 0x57, 0x66, 0xc4, 0x25, 0xad, 0xad, + 0xe6, 0xec, 0xba, 0xbc, 0x73, 0xe1, 0x60, 0x61, 0xcb, 0xdb, 0x01, 0x69, 0x97, 0x5c, 0xc5, 0x2d, + 0xec, 0x97, 0x6e, 0x52, 0xdc, 0xcb, 0x1f, 0x85, 0x4f, 0xdf, 0xfe, 0x39, 0xc5, 0x73, 0x90, 0xa8, + 0xd0, 0xa9, 0xe0, 0x88, 0x6c, 0xea, 0x6b, 0x67, 0x0b, 0x9d, 0xdf, 0xfe, 0xa7, 0x5e, 0x02, 0x68, + 0xa1, 0xb3, 0x5f, 0x26, 0x21, 0xbc, 0x03, 0x0b, 0x7f, 0xd5, 0x7f, 0x3e, 0xc6, 0xde, 0x51, 0xa9, + 0x14, 0x23, 0x67, 0x99, 0xc8, 0x1f, 0x13, 0x31, 0xfa, 0x10, 0x64, 0x13, 0x8f, 0xb0, 0x63, 0xfa, + 0x1d, 0xa7, 0x74, 0x8b, 0xb6, 0x46, 0xd7, 0x48, 0xbf, 0xde, 0xe4, 0x42, 0x46, 0xbe, 0x13, 0x2d, + 0xf4, 0x25, 0xe4, 0xc2, 0x1f, 0xd8, 0xec, 0x38, 0xf5, 0xa3, 0x52, 0x99, 0x3a, 0x7d, 0x6f, 0xc6, + 0x60, 0x4e, 0xfa, 0xc0, 0xeb, 0xdc, 0x9f, 0x66, 0x0c, 0x4d, 0x9f, 0xc2, 0x46, 0x5f, 0x40, 0x8e, + 0x67, 0xf7, 0xba, 0xbb, 0xe3, 0x97, 0x5e, 0xbf, 0xf4, 0x06, 0x7b, 0x7a, 0xae, 0x8d, 0x89, 0x29, + 0xe7, 0xad, 0x38, 0x1a, 0xfa, 0x0c, 0xf2, 0xd1, 0xb3, 0x8f, 0x3b, 0x0a, 0xfc, 0xd2, 0x6d, 0x5a, + 0x98, 0xf7, 0x67, 0x4d, 0x5d, 0x66, 0xdb, 0x19, 0x05, 0xbe, 0x9e, 0xf3, 0x63, 0xbf, 0xd0, 0x1d, 0x90, 0x4d, 0xcf, 0x1d, 0x85, 0xe7, 0xc7, 0x1b, 0x4b, 0xc2, 0x72, 0x92, 0x6f, 0x33, 0x11, 0xd3, 0x83, 0xa1, 0x0f, 0x05, 0x0f, 0x8f, 0x6c, 0x63, 0x80, 0x87, 0xe4, 0xf8, 0x73, 0x77, 0x4b, 0x0b, 0x74, 0xf6, 0xd5, 0x99, 0x03, 0x19, 0x19, 0xf3, 0xc4, 0x8c, 0xe1, 0x75, 0x76, 0xd1, 0x16, 0x80, 0x31, 0x36, 0xad, 0xa0, 0x3f, 0x74, 0x4d, 0x5c, 0x5a, 0xa4, 0x55, 0x39, 0xeb, 0x2e, 0xd5, 0x88, - 0xe1, 0x86, 0x6b, 0xe2, 0xe8, 0x25, 0x85, 0x0b, 0xca, 0xdf, 0x09, 0x30, 0x7f, 0x86, 0x92, 0xd0, - 0xaf, 0x20, 0xe3, 0xb8, 0x66, 0xec, 0x45, 0x45, 0x65, 0xbb, 0x9b, 0x6e, 0xbb, 0x66, 0xf8, 0xa0, - 0x72, 0x7f, 0xcf, 0x0a, 0xf6, 0xc7, 0x3b, 0xd5, 0x81, 0x3b, 0x5c, 0x89, 0x56, 0x61, 0xee, 0x4c, - 0x7e, 0xaf, 0x8c, 0x9e, 0xed, 0xad, 0xd0, 0x5f, 0xa3, 0x9d, 0x6a, 0x68, 0xa6, 0xa7, 0x09, 0xaa, - 0x66, 0xa2, 0x0f, 0xa0, 0x88, 0x0f, 0x47, 0x96, 0x17, 0x3b, 0x96, 0x13, 0xb1, 0xb0, 0x16, 0x26, - 0x83, 0x24, 0xb8, 0xe5, 0xef, 0x05, 0x28, 0x9e, 0xa2, 0x03, 0xd2, 0xa6, 0xd0, 0xd7, 0xba, 0xa9, - 0x36, 0x85, 0x48, 0xa2, 0x06, 0x26, 0x71, 0xe9, 0x93, 0x74, 0xf2, 0x55, 0x9f, 0xa4, 0xa7, 0x2f, - 0xc7, 0xa9, 0xd9, 0x2f, 0xc7, 0xeb, 0xa2, 0x24, 0x2a, 0xa9, 0xf2, 0x53, 0x90, 0x38, 0x15, 0x4d, - 0xf7, 0x4d, 0xc2, 0x8c, 0x7d, 0xd3, 0x85, 0x7e, 0x96, 0xbf, 0x11, 0x40, 0x8e, 0xbf, 0xf5, 0x27, - 0x22, 0xd4, 0xf3, 0xdb, 0xb6, 0x97, 0x7c, 0x0f, 0x9b, 0x8e, 0x40, 0x72, 0xf6, 0x08, 0x94, 0x0f, - 0x20, 0x1b, 0xab, 0xe6, 0xd3, 0xbd, 0xb6, 0xf0, 0x12, 0xbd, 0xf6, 0x5b, 0x90, 0xfe, 0xd2, 0xdd, - 0xe1, 0x0e, 0x24, 0xeb, 0x79, 0x66, 0x9d, 0x5a, 0x77, 0x77, 0xb4, 0xa6, 0x9e, 0xfa, 0xd2, 0xdd, - 0xd1, 0xcc, 0xf2, 0x1f, 0x04, 0xc8, 0xc5, 0xeb, 0x1c, 0x55, 0x40, 0xb6, 0x9c, 0x81, 0x47, 0x8b, - 0x8c, 0xce, 0xcb, 0x53, 0x70, 0x22, 0x26, 0xd5, 0x3f, 0xb4, 0x9c, 0x3e, 0x7d, 0xa3, 0x9a, 0x4a, - 0x53, 0x69, 0x68, 0x39, 0xdb, 0x44, 0x4a, 0x55, 0x8c, 0x43, 0xa6, 0x92, 0x9c, 0x52, 0x31, 0x0e, - 0x43, 0x95, 0x32, 0x3d, 0x50, 0xbd, 0x80, 0xb6, 0xc5, 0xc9, 0xd8, 0x11, 0xe9, 0x05, 0x68, 0x01, - 0x32, 0x07, 0x96, 0x17, 0x8c, 0x0d, 0x9b, 0x76, 0xc0, 0xbc, 0x93, 0xe5, 0xc2, 0xf2, 0x3e, 0x64, - 0x63, 0xfc, 0x30, 0xc3, 0x86, 0xfe, 0x14, 0xc4, 0xa8, 0xa8, 0x66, 0xec, 0x75, 0xa9, 0x41, 0xe5, - 0x6d, 0x7e, 0x21, 0x01, 0x48, 0x6f, 0x6e, 0xd5, 0x5b, 0x5a, 0xe3, 0xdc, 0xcb, 0x04, 0xb9, 0x76, - 0x44, 0xa4, 0x42, 0x2e, 0x9e, 0x4d, 0xad, 0x5b, 0xab, 0xb7, 0x54, 0x72, 0x0d, 0xcd, 0x83, 0xac, - 0xab, 0xb5, 0x26, 0xbd, 0xa5, 0x28, 0xc2, 0x27, 0xe2, 0xd7, 0xdf, 0x2e, 0x0a, 0xeb, 0xa2, 0x84, - 0x94, 0x6b, 0x95, 0xef, 0x04, 0x40, 0x4d, 0x23, 0x30, 0x48, 0x89, 0x5d, 0xe1, 0xc6, 0x91, 0xb8, - 0xc4, 0xd3, 0xe9, 0x06, 0x31, 0xf9, 0x2a, 0x0d, 0x62, 0xb8, 0xd4, 0xca, 0x37, 0x02, 0x40, 0x6c, - 0x71, 0x9f, 0xc6, 0xff, 0x29, 0xbb, 0xb8, 0x17, 0x3e, 0x45, 0xb9, 0xe4, 0xb6, 0x1b, 0xfe, 0x8f, - 0xf6, 0x00, 0x24, 0x93, 0xb9, 0xcc, 0xb6, 0xe3, 0xc2, 0xa6, 0xf3, 0x4c, 0x64, 0x1e, 0x92, 0x13, - 0x86, 0x49, 0xeb, 0x19, 0x48, 0x8d, 0x1d, 0xcb, 0x75, 0xde, 0xfd, 0x08, 0xd0, 0x59, 0x7a, 0x22, - 0x61, 0xa7, 0xbf, 0x8d, 0x00, 0x9b, 0xe1, 0x1d, 0x72, 0xcb, 0x39, 0x88, 0x04, 0x42, 0xfd, 0xce, - 0x8b, 0xbf, 0x2f, 0xcc, 0xbd, 0x38, 0x59, 0x10, 0xfe, 0x7c, 0xb2, 0x20, 0xfc, 0xe5, 0x64, 0x41, - 0xf8, 0xdb, 0xc9, 0x82, 0xf0, 0xeb, 0x7f, 0x2c, 0xcc, 0x7d, 0x9e, 0x61, 0x0b, 0xf8, 0x5f, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x05, 0x75, 0xa8, 0x15, 0x84, 0x20, 0x00, 0x00, + 0xe1, 0x86, 0x6b, 0xe2, 0xe8, 0x25, 0x85, 0x0b, 0xd0, 0x87, 0x90, 0xa5, 0xae, 0x7d, 0xe9, 0xee, + 0x90, 0xdc, 0x5c, 0xa2, 0xce, 0xcd, 0xb3, 0xbd, 0x94, 0x9b, 0x9e, 0x3b, 0x5a, 0x77, 0x77, 0x68, + 0xc6, 0xb0, 0x4f, 0xb3, 0xfc, 0x9d, 0x00, 0xf3, 0x67, 0x58, 0x0c, 0xfd, 0x0a, 0x32, 0x8e, 0x6b, + 0xc6, 0x1e, 0x61, 0x54, 0x06, 0x92, 0x6e, 0xbb, 0x66, 0xf8, 0x06, 0x73, 0x7f, 0xcf, 0x0a, 0xf6, + 0xc7, 0x3b, 0xd5, 0x81, 0x3b, 0x5c, 0x89, 0x16, 0x6e, 0xee, 0x4c, 0xbe, 0x57, 0x46, 0xcf, 0xf6, + 0x56, 0xe8, 0xd7, 0x68, 0xa7, 0x1a, 0x9a, 0xe9, 0x69, 0x82, 0xaa, 0x99, 0xe8, 0x03, 0x28, 0xe2, + 0xc3, 0x91, 0xe5, 0xc5, 0x4e, 0xf2, 0x44, 0x6c, 0x27, 0x0a, 0x93, 0x41, 0xb2, 0x1f, 0xe5, 0xef, + 0x05, 0x28, 0x9e, 0x62, 0x10, 0xd2, 0xd9, 0xd0, 0x07, 0xbe, 0xa9, 0xce, 0x86, 0x48, 0xa2, 0x9e, + 0x27, 0x71, 0xe9, 0x2b, 0x76, 0xf2, 0x55, 0x5f, 0xb1, 0xa7, 0xef, 0xd3, 0xa9, 0xd9, 0xef, 0xd3, + 0xeb, 0xa2, 0x24, 0x2a, 0xa9, 0xf2, 0x53, 0x90, 0x38, 0x7b, 0x4d, 0xb7, 0x5a, 0xc2, 0x8c, 0xad, + 0xd6, 0x85, 0x7e, 0x96, 0xbf, 0x11, 0x40, 0x8e, 0xff, 0x3d, 0x90, 0x88, 0x50, 0xcf, 0xef, 0xf4, + 0x5e, 0xf2, 0x09, 0x6d, 0x3a, 0x02, 0xc9, 0xd9, 0x23, 0x50, 0x3e, 0x80, 0x6c, 0x8c, 0x00, 0x4e, + 0xb7, 0xe7, 0xc2, 0x4b, 0xb4, 0xe7, 0x6f, 0x41, 0x9a, 0x65, 0x7d, 0x98, 0x48, 0x79, 0x66, 0x9d, + 0x0a, 0x33, 0x3e, 0xf5, 0x25, 0xcd, 0xf6, 0x3f, 0x0a, 0x90, 0x8b, 0x53, 0x03, 0xaa, 0x80, 0x6c, + 0x39, 0x03, 0x8f, 0xd6, 0x25, 0x9d, 0x97, 0xa7, 0xe0, 0x44, 0x4c, 0x08, 0x63, 0x68, 0x39, 0x7d, + 0xfa, 0xac, 0x35, 0x95, 0xa6, 0xd2, 0xd0, 0x72, 0xb6, 0x89, 0x94, 0xaa, 0x18, 0x87, 0x4c, 0x25, + 0x39, 0xa5, 0x62, 0x1c, 0x86, 0x2a, 0x65, 0x7a, 0x06, 0x7b, 0x01, 0xed, 0xa4, 0x93, 0xb1, 0x53, + 0xd5, 0x0b, 0xd0, 0x02, 0x64, 0x0e, 0x2c, 0x2f, 0x18, 0x1b, 0x36, 0x6d, 0x9a, 0x79, 0xf3, 0xcb, + 0x85, 0xe5, 0x7d, 0xc8, 0xc6, 0x28, 0x65, 0x86, 0x0d, 0xfd, 0x29, 0x88, 0x51, 0x51, 0xcd, 0xd8, + 0x1e, 0x53, 0x83, 0xca, 0xdb, 0xfc, 0x0e, 0x03, 0x90, 0xde, 0xdc, 0xaa, 0xb7, 0xb4, 0xc6, 0xb9, + 0xf7, 0x0f, 0x72, 0x53, 0x89, 0x78, 0x88, 0xdc, 0x55, 0x9b, 0x5a, 0xb7, 0x56, 0x6f, 0xa9, 0xe4, + 0xe6, 0x9a, 0x07, 0x59, 0x57, 0x6b, 0x4d, 0x7a, 0xb1, 0x51, 0x84, 0x4f, 0xc4, 0xaf, 0xbf, 0x5d, + 0x14, 0xd6, 0x45, 0x09, 0x29, 0xd7, 0x2a, 0xdf, 0x09, 0x80, 0x9a, 0x46, 0x60, 0x90, 0x12, 0xbb, + 0xc2, 0x25, 0x25, 0x71, 0x89, 0xa7, 0xd3, 0x3d, 0x65, 0xf2, 0x55, 0x7a, 0xca, 0x70, 0xa9, 0x95, + 0x6f, 0x04, 0x80, 0xd8, 0xe2, 0x3e, 0x8d, 0xff, 0xb9, 0x76, 0x71, 0xfb, 0x7c, 0x8a, 0xa5, 0xc9, + 0x05, 0x39, 0xfc, 0xeb, 0xed, 0x01, 0x48, 0x26, 0x73, 0x99, 0x6d, 0xc7, 0x85, 0x7d, 0xea, 0x99, + 0xc8, 0x3c, 0x24, 0x87, 0x12, 0x93, 0xd6, 0x33, 0x90, 0x1a, 0x3b, 0x96, 0xeb, 0xbc, 0xfb, 0x11, + 0xa0, 0xb3, 0xf4, 0x44, 0xc2, 0x4e, 0xbf, 0x8d, 0x00, 0x9b, 0xe1, 0xb5, 0x73, 0xcb, 0x39, 0x88, + 0x04, 0x42, 0xfd, 0xce, 0x8b, 0x7f, 0x2c, 0xcc, 0xbd, 0x38, 0x59, 0x10, 0xfe, 0x72, 0xb2, 0x20, + 0xfc, 0xf5, 0x64, 0x41, 0xf8, 0xfb, 0xc9, 0x82, 0xf0, 0xeb, 0x7f, 0x2e, 0xcc, 0x7d, 0x9e, 0x61, + 0x0b, 0xf8, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xab, 0x04, 0xf2, 0xa5, 0xb7, 0x20, 0x00, 0x00, } diff --git a/pkg/sql/sqlbase/structured.proto b/pkg/sql/sqlbase/structured.proto index fd57dfd79da1..45b3f1809440 100644 --- a/pkg/sql/sqlbase/structured.proto +++ b/pkg/sql/sqlbase/structured.proto @@ -825,6 +825,10 @@ message TableDescriptor { READWRITE = 1; } optional AuditMode audit_mode = 31 [(gogoproto.nullable) = false]; + + // The job id for a drop job is the id in the system.jobs table of the + // dropping of this table. + optional int64 drop_job_id = 32 [(gogoproto.nullable) = false, (gogoproto.customname) = "DropJobID"]; } // DatabaseDescriptor represents a namespace (aka database) and is stored diff --git a/pkg/sql/table.go b/pkg/sql/table.go index 5e06c30efe36..dade680d1589 100644 --- a/pkg/sql/table.go +++ b/pkg/sql/table.go @@ -633,6 +633,54 @@ func (p *planner) createSchemaChangeJob( return mutationID, nil } +// createDropTablesJob creates a schema change job in the system.jobs table. +// The identifiers of the newly-created job are written in the table descriptor. +// +// The job creation is done within the planner's txn. This is important - if the` +// txn ends up rolling back, the job needs to go away. +func (p *planner) createDropTablesJob( + ctx context.Context, + tableDescs []*sqlbase.TableDescriptor, + droppedDetails []jobspb.DroppedTableDetails, + stmt string, +) (int64, error) { + + if len(tableDescs) == 0 { + return 0, nil + } + + descriptorIDs := make([]sqlbase.ID, 0, len(tableDescs)) + + for _, tableDesc := range tableDescs { + descriptorIDs = append(descriptorIDs, tableDesc.ID) + } + + for _, droppedDetail := range droppedDetails { + droppedDetail.Status = jobspb.DroppedTableDetails_StatusDrainingName + } + + jobRecord := jobs.Record{ + Description: stmt, + Username: p.User(), + DescriptorIDs: descriptorIDs, + Details: jobspb.SchemaChangeDetails{DroppedTables: droppedDetails}, + Progress: jobspb.SchemaChangeProgress{}, + } + job := p.ExecCfg().JobRegistry.NewJob(jobRecord) + if err := job.WithTxn(p.txn).Created(ctx); err != nil { + return 0, err + } + + if err := job.WithTxn(p.txn).Started(ctx); err != nil { + return 0, err + } + + for _, tableDesc := range tableDescs { + tableDesc.DropJobID = *job.ID() + } + return *job.ID(), nil +} + // queueSchemaChange queues up a schema changer to process an outstanding // schema change for the table. func (p *planner) queueSchemaChange( diff --git a/pkg/sql/truncate.go b/pkg/sql/truncate.go index 846618a972da..7cc0f765430f 100644 --- a/pkg/sql/truncate.go +++ b/pkg/sql/truncate.go @@ -20,6 +20,7 @@ import ( "github.com/pkg/errors" "github.com/cockroachdb/cockroach/pkg/internal/client" + "github.com/cockroachdb/cockroach/pkg/jobs/jobspb" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/sql/privilege" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" @@ -42,6 +43,12 @@ func (p *planner) Truncate(ctx context.Context, n *tree.Truncate) (planNode, err // toTraverse is the list of tables whose references need to be traversed // while constructing the list of tables that should be truncated. toTraverse := make([]sqlbase.TableDescriptor, 0, len(n.Tables)) + + // This is the list of descriptors of truncated tables in the statement. These tables will have a mutationID and + // MutationJob related to the created job of the TRUNCATE statement. + stmtTableDescs := make([]*sqlbase.TableDescriptor, 0, len(n.Tables)) + droppedTableDetails := make([]jobspb.DroppedTableDetails, 0, len(n.Tables)) + for _, name := range n.Tables { tn, err := name.Normalize() if err != nil { @@ -59,6 +66,18 @@ func (p *planner) Truncate(ctx context.Context, n *tree.Truncate) (planNode, err toTruncate[tableDesc.ID] = tn.FQString() toTraverse = append(toTraverse, *tableDesc) + + stmtTableDescs = append(stmtTableDescs, tableDesc) + droppedTableDetails = append(droppedTableDetails, jobspb.DroppedTableDetails{ + Name: tn.FQString(), + ID: tableDesc.ID, + }) + } + + dropJobID, err := p.createDropTablesJob(ctx, stmtTableDescs, droppedTableDetails, tree.AsStringWithFlags(n, + tree.FmtAlwaysQualifyTableNames)) + if err != nil { + return nil, err } // Check that any referencing tables are contained in the set, or, if CASCADE @@ -122,7 +141,7 @@ func (p *planner) Truncate(ctx context.Context, n *tree.Truncate) (planNode, err } traceKV := p.extendedEvalCtx.Tracing.KVTracingEnabled() for id, name := range toTruncate { - if err := p.truncateTable(ctx, id, traceKV); err != nil { + if err := p.truncateTable(ctx, id, dropJobID, traceKV); err != nil { return nil, err } @@ -149,13 +168,16 @@ func (p *planner) Truncate(ctx context.Context, n *tree.Truncate) (planNode, err // truncateTable truncates the data of a table in a single transaction. It // drops the table and recreates it with a new ID. The dropped table is // GC-ed later through an asynchronous schema change. -func (p *planner) truncateTable(ctx context.Context, id sqlbase.ID, traceKV bool) error { +func (p *planner) truncateTable( + ctx context.Context, id sqlbase.ID, dropJobID int64, traceKV bool, +) error { // Read the table descriptor because it might have changed // while another table in the truncation list was truncated. tableDesc, err := sqlbase.GetTableDescFromID(ctx, p.txn, id) if err != nil { return err } + tableDesc.DropJobID = dropJobID newTableDesc := *tableDesc newTableDesc.ReplacementOf = sqlbase.TableDescriptor_Replacement{ ID: id, Time: p.txn.CommitTimestamp(),