diff --git a/Gopkg.lock b/Gopkg.lock index a867d1e49f50..478d4e9b0458 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -143,11 +143,11 @@ [[projects]] branch = "master" - digest = "1:dfe2c5eadcbaf622a726116baf37582aa82fa8d364f05e168b58fbe96551832d" + digest = "1:caed868e37c6cda382a217d8ad4f55da579e1a1d046836de57f11a569e383443" name = "github.com/andy-kimball/arenaskl" packages = ["."] pruneopts = "UT" - revision = "224761e552afe64db9d93004f8d5d3a686b89771" + revision = "6bf06cf57626e536063e9398a57dfe1417ed0799" [[projects]] digest = "1:66b3310cf22cdc96c35ef84ede4f7b9b370971c4025f394c89a2638729653b11" diff --git a/pkg/jobs/jobspb/jobs.pb.go b/pkg/jobs/jobspb/jobs.pb.go index f6d31e425e7f..e20e9aefadc9 100644 --- a/pkg/jobs/jobspb/jobs.pb.go +++ b/pkg/jobs/jobspb/jobs.pb.go @@ -55,19 +55,20 @@ func (x Status) String() string { return proto.EnumName(Status_name, int32(x)) } func (Status) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{0} + return fileDescriptor_jobs_672575a1a0b382a2, []int{0} } type Type int32 const ( - TypeUnspecified Type = 0 - TypeBackup Type = 1 - TypeRestore Type = 2 - TypeSchemaChange Type = 3 - TypeImport Type = 4 - TypeChangefeed Type = 5 - TypeCreateStats Type = 6 + TypeUnspecified Type = 0 + TypeBackup Type = 1 + TypeRestore Type = 2 + TypeSchemaChange Type = 3 + TypeImport Type = 4 + TypeChangefeed Type = 5 + TypeCreateStats Type = 6 + TypeAutoCreateStats Type = 7 ) var Type_name = map[int32]string{ @@ -78,19 +79,21 @@ var Type_name = map[int32]string{ 4: "IMPORT", 5: "CHANGEFEED", 6: "CREATE_STATS", + 7: "AUTO_CREATE_STATS", } var Type_value = map[string]int32{ - "UNSPECIFIED": 0, - "BACKUP": 1, - "RESTORE": 2, - "SCHEMA_CHANGE": 3, - "IMPORT": 4, - "CHANGEFEED": 5, - "CREATE_STATS": 6, + "UNSPECIFIED": 0, + "BACKUP": 1, + "RESTORE": 2, + "SCHEMA_CHANGE": 3, + "IMPORT": 4, + "CHANGEFEED": 5, + "CREATE_STATS": 6, + "AUTO_CREATE_STATS": 7, } func (Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{1} + return fileDescriptor_jobs_672575a1a0b382a2, []int{1} } type Lease struct { @@ -106,7 +109,7 @@ func (m *Lease) Reset() { *m = Lease{} } func (m *Lease) String() string { return proto.CompactTextString(m) } func (*Lease) ProtoMessage() {} func (*Lease) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{0} + return fileDescriptor_jobs_672575a1a0b382a2, []int{0} } func (m *Lease) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -144,7 +147,7 @@ func (m *BackupDetails) Reset() { *m = BackupDetails{} } func (m *BackupDetails) String() string { return proto.CompactTextString(m) } func (*BackupDetails) ProtoMessage() {} func (*BackupDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{1} + return fileDescriptor_jobs_672575a1a0b382a2, []int{1} } func (m *BackupDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -178,7 +181,7 @@ func (m *BackupProgress) Reset() { *m = BackupProgress{} } func (m *BackupProgress) String() string { return proto.CompactTextString(m) } func (*BackupProgress) ProtoMessage() {} func (*BackupProgress) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{2} + return fileDescriptor_jobs_672575a1a0b382a2, []int{2} } func (m *BackupProgress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -217,7 +220,7 @@ func (m *RestoreDetails) Reset() { *m = RestoreDetails{} } func (m *RestoreDetails) String() string { return proto.CompactTextString(m) } func (*RestoreDetails) ProtoMessage() {} func (*RestoreDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{3} + return fileDescriptor_jobs_672575a1a0b382a2, []int{3} } func (m *RestoreDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -253,7 +256,7 @@ func (m *RestoreDetails_TableRewrite) Reset() { *m = RestoreDetails_Tabl func (m *RestoreDetails_TableRewrite) String() string { return proto.CompactTextString(m) } func (*RestoreDetails_TableRewrite) ProtoMessage() {} func (*RestoreDetails_TableRewrite) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{3, 0} + return fileDescriptor_jobs_672575a1a0b382a2, []int{3, 0} } func (m *RestoreDetails_TableRewrite) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -288,7 +291,7 @@ func (m *RestoreProgress) Reset() { *m = RestoreProgress{} } func (m *RestoreProgress) String() string { return proto.CompactTextString(m) } func (*RestoreProgress) ProtoMessage() {} func (*RestoreProgress) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{4} + return fileDescriptor_jobs_672575a1a0b382a2, []int{4} } func (m *RestoreProgress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -341,7 +344,7 @@ func (m *ImportDetails) Reset() { *m = ImportDetails{} } func (m *ImportDetails) String() string { return proto.CompactTextString(m) } func (*ImportDetails) ProtoMessage() {} func (*ImportDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{5} + return fileDescriptor_jobs_672575a1a0b382a2, []int{5} } func (m *ImportDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -378,7 +381,7 @@ func (m *ImportDetails_Table) Reset() { *m = ImportDetails_Table{} } func (m *ImportDetails_Table) String() string { return proto.CompactTextString(m) } func (*ImportDetails_Table) ProtoMessage() {} func (*ImportDetails_Table) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{5, 0} + return fileDescriptor_jobs_672575a1a0b382a2, []int{5, 0} } func (m *ImportDetails_Table) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -419,7 +422,7 @@ func (m *ImportProgress) Reset() { *m = ImportProgress{} } func (m *ImportProgress) String() string { return proto.CompactTextString(m) } func (*ImportProgress) ProtoMessage() {} func (*ImportProgress) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{6} + return fileDescriptor_jobs_672575a1a0b382a2, []int{6} } func (m *ImportProgress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -454,7 +457,7 @@ func (m *ResumeSpanList) Reset() { *m = ResumeSpanList{} } func (m *ResumeSpanList) String() string { return proto.CompactTextString(m) } func (*ResumeSpanList) ProtoMessage() {} func (*ResumeSpanList) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{7} + return fileDescriptor_jobs_672575a1a0b382a2, []int{7} } func (m *ResumeSpanList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -491,7 +494,7 @@ func (m *DroppedTableDetails) Reset() { *m = DroppedTableDetails{} } func (m *DroppedTableDetails) String() string { return proto.CompactTextString(m) } func (*DroppedTableDetails) ProtoMessage() {} func (*DroppedTableDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{8} + return fileDescriptor_jobs_672575a1a0b382a2, []int{8} } func (m *DroppedTableDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -535,7 +538,7 @@ func (m *SchemaChangeDetails) Reset() { *m = SchemaChangeDetails{} } func (m *SchemaChangeDetails) String() string { return proto.CompactTextString(m) } func (*SchemaChangeDetails) ProtoMessage() {} func (*SchemaChangeDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{9} + return fileDescriptor_jobs_672575a1a0b382a2, []int{9} } func (m *SchemaChangeDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -569,7 +572,7 @@ func (m *SchemaChangeProgress) Reset() { *m = SchemaChangeProgress{} } func (m *SchemaChangeProgress) String() string { return proto.CompactTextString(m) } func (*SchemaChangeProgress) ProtoMessage() {} func (*SchemaChangeProgress) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{10} + return fileDescriptor_jobs_672575a1a0b382a2, []int{10} } func (m *SchemaChangeProgress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -604,7 +607,7 @@ func (m *ChangefeedTarget) Reset() { *m = ChangefeedTarget{} } func (m *ChangefeedTarget) String() string { return proto.CompactTextString(m) } func (*ChangefeedTarget) ProtoMessage() {} func (*ChangefeedTarget) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{11} + return fileDescriptor_jobs_672575a1a0b382a2, []int{11} } func (m *ChangefeedTarget) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -659,7 +662,7 @@ func (m *ChangefeedDetails) Reset() { *m = ChangefeedDetails{} } func (m *ChangefeedDetails) String() string { return proto.CompactTextString(m) } func (*ChangefeedDetails) ProtoMessage() {} func (*ChangefeedDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{12} + return fileDescriptor_jobs_672575a1a0b382a2, []int{12} } func (m *ChangefeedDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -695,7 +698,7 @@ func (m *ResolvedSpan) Reset() { *m = ResolvedSpan{} } func (m *ResolvedSpan) String() string { return proto.CompactTextString(m) } func (*ResolvedSpan) ProtoMessage() {} func (*ResolvedSpan) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{13} + return fileDescriptor_jobs_672575a1a0b382a2, []int{13} } func (m *ResolvedSpan) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -730,7 +733,7 @@ func (m *ChangefeedProgress) Reset() { *m = ChangefeedProgress{} } func (m *ChangefeedProgress) String() string { return proto.CompactTextString(m) } func (*ChangefeedProgress) ProtoMessage() {} func (*ChangefeedProgress) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{14} + return fileDescriptor_jobs_672575a1a0b382a2, []int{14} } func (m *ChangefeedProgress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -775,7 +778,7 @@ func (m *CreateStatsDetails) Reset() { *m = CreateStatsDetails{} } func (m *CreateStatsDetails) String() string { return proto.CompactTextString(m) } func (*CreateStatsDetails) ProtoMessage() {} func (*CreateStatsDetails) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{15} + return fileDescriptor_jobs_672575a1a0b382a2, []int{15} } func (m *CreateStatsDetails) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -810,7 +813,7 @@ func (m *CreateStatsDetails_ColList) Reset() { *m = CreateStatsDetails_C func (m *CreateStatsDetails_ColList) String() string { return proto.CompactTextString(m) } func (*CreateStatsDetails_ColList) ProtoMessage() {} func (*CreateStatsDetails_ColList) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{15, 0} + return fileDescriptor_jobs_672575a1a0b382a2, []int{15, 0} } func (m *CreateStatsDetails_ColList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -844,7 +847,7 @@ func (m *CreateStatsProgress) Reset() { *m = CreateStatsProgress{} } func (m *CreateStatsProgress) String() string { return proto.CompactTextString(m) } func (*CreateStatsProgress) ProtoMessage() {} func (*CreateStatsProgress) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{16} + return fileDescriptor_jobs_672575a1a0b382a2, []int{16} } func (m *CreateStatsProgress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -899,7 +902,7 @@ func (m *Payload) Reset() { *m = Payload{} } func (m *Payload) String() string { return proto.CompactTextString(m) } func (*Payload) ProtoMessage() {} func (*Payload) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{17} + return fileDescriptor_jobs_672575a1a0b382a2, []int{17} } func (m *Payload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1178,7 +1181,7 @@ func (m *Progress) Reset() { *m = Progress{} } func (m *Progress) String() string { return proto.CompactTextString(m) } func (*Progress) ProtoMessage() {} func (*Progress) Descriptor() ([]byte, []int) { - return fileDescriptor_jobs_8f4fceb1a78d438f, []int{18} + return fileDescriptor_jobs_672575a1a0b382a2, []int{18} } func (m *Progress) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -7184,157 +7187,159 @@ var ( ErrIntOverflowJobs = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("jobs/jobspb/jobs.proto", fileDescriptor_jobs_8f4fceb1a78d438f) } - -var fileDescriptor_jobs_8f4fceb1a78d438f = []byte{ - // 2381 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, 0xed, 0x77, 0xd7, 0x1b, 0xed, 0x36, 0xf9, - 0x06, 0x76, 0xb7, 0x3b, 0xc3, 0x24, 0xd0, 0x11, 0x3b, 0xcc, 0x08, 0x56, 0xe4, 0x57, 0xa7, 0xc9, - 0x74, 0x9a, 0xae, 0x93, 0xce, 0xc2, 0x22, 0x30, 0x4e, 0x7c, 0xdb, 0x98, 0x26, 0xb1, 0xeb, 0xeb, - 0xcc, 0x30, 0x2b, 0x24, 0x10, 0xe2, 0x01, 0xcd, 0x13, 0x7f, 0x00, 0x23, 0x21, 0x01, 0x12, 0x2f, - 0x08, 0x9e, 0xf8, 0x1b, 0xe6, 0x05, 0xb1, 0x88, 0x17, 0x10, 0x52, 0x16, 0xc2, 0x0b, 0x7f, 0xc3, - 0x3c, 0xa1, 0x7b, 0xaf, 0xed, 0x38, 0x9d, 0xd2, 0x5f, 0x12, 0x2f, 0x6d, 0x7c, 0xee, 0x39, 0xc7, - 0xf7, 0x9c, 0xf3, 0x39, 0x9f, 0x7b, 0xae, 0xe1, 0xb5, 0xef, 0x59, 0x7d, 0x52, 0xa1, 0x7f, 0xec, - 0x3e, 0xfb, 0x57, 0xb6, 0x1d, 0xcb, 0xb5, 0xd0, 0x1b, 0x03, 0x6b, 0x70, 0xec, 0x58, 0xfa, 0x60, +func init() { proto.RegisterFile("jobs/jobspb/jobs.proto", fileDescriptor_jobs_672575a1a0b382a2) } + +var fileDescriptor_jobs_672575a1a0b382a2 = []byte{ + // 2404 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xdf, 0x6f, 0x23, 0x57, + 0xf5, 0xf7, 0xd8, 0x63, 0x7b, 0x7c, 0xfc, 0x23, 0x93, 0x9b, 0x7c, 0xdb, 0xa9, 0xd5, 0xc6, 0xfe, + 0x1a, 0xda, 0xa6, 0x2d, 0xb5, 0x21, 0x15, 0x5d, 0x76, 0x05, 0x15, 0xfe, 0x95, 0x8d, 0xbd, 0xd9, + 0x38, 0x1d, 0x3b, 0x5b, 0x28, 0x82, 0x61, 0xec, 0xb9, 0x89, 0x87, 0xd8, 0x9e, 0xc9, 0xdc, 0xf1, + 0x2e, 0x5b, 0x21, 0x21, 0x21, 0x1e, 0x50, 0x9e, 0xf8, 0x03, 0x88, 0x84, 0x04, 0x48, 0xbc, 0x20, + 0xfa, 0xc4, 0xdf, 0xb0, 0x2f, 0x88, 0x22, 0x5e, 0x40, 0x48, 0x2e, 0x98, 0x17, 0xfe, 0x86, 0x7d, + 0x42, 0xf7, 0xde, 0x99, 0xf1, 0x38, 0x1b, 0xf2, 0x4b, 0xe2, 0x25, 0xf1, 0x9c, 0x7b, 0xce, 0x99, + 0x7b, 0xce, 0xf9, 0x9c, 0xcf, 0x3d, 0x77, 0xe0, 0xa5, 0x1f, 0x58, 0x7d, 0x52, 0xa1, 0x7f, 0xec, + 0x3e, 0xfb, 0x57, 0xb6, 0x1d, 0xcb, 0xb5, 0xd0, 0x2b, 0x03, 0x6b, 0x70, 0xec, 0x58, 0xfa, 0x60, 0x58, 0x26, 0x27, 0xa3, 0x32, 0x5b, 0xe1, 0x5a, 0xf9, 0xf5, 0x23, 0xeb, 0xc8, 0x62, 0x5a, 0x15, 0xfa, 0x8b, 0x1b, 0xe4, 0x11, 0x53, 0xb6, 0xfb, 0x15, 0x43, 0x77, 0x75, 0x4f, 0xa6, 0xf8, 0x32, - 0xd3, 0xba, 0x75, 0x68, 0x39, 0x63, 0xdd, 0xf5, 0xdc, 0xe7, 0xdf, 0x24, 0x27, 0xa3, 0x0a, 0x39, - 0x19, 0xf5, 0x75, 0x82, 0x2b, 0xc4, 0x75, 0xa6, 0x03, 0x77, 0xea, 0x60, 0xc3, 0xb7, 0x9b, 0xba, - 0xe6, 0xa8, 0x32, 0x1c, 0x0d, 0x2a, 0xae, 0x39, 0xc6, 0xc4, 0xd5, 0xc7, 0x36, 0x5f, 0x29, 0xfd, - 0x10, 0xe2, 0xbb, 0x58, 0x27, 0x18, 0x7d, 0x0c, 0xc9, 0x89, 0x65, 0x60, 0xcd, 0x34, 0x14, 0xa1, - 0x28, 0x6c, 0x66, 0x6b, 0xd5, 0xf9, 0xac, 0x90, 0xd8, 0xb3, 0x0c, 0xdc, 0x6a, 0xbc, 0x9c, 0x15, - 0x6e, 0x1f, 0x99, 0xee, 0x70, 0xda, 0x2f, 0x0f, 0xac, 0x71, 0x25, 0x88, 0xc4, 0xe8, 0x2f, 0x7e, - 0x57, 0xec, 0xe3, 0xa3, 0x8a, 0xb7, 0xbd, 0x32, 0x37, 0x53, 0x13, 0xd4, 0x63, 0xcb, 0x40, 0xeb, - 0x10, 0xc7, 0xb6, 0x35, 0x18, 0x2a, 0xd1, 0xa2, 0xb0, 0x19, 0x53, 0xf9, 0xc3, 0x3d, 0xf1, 0xdf, - 0xbf, 0x28, 0x08, 0xa5, 0xbf, 0x0b, 0x90, 0xad, 0xe9, 0x83, 0xe3, 0xa9, 0xdd, 0xc0, 0xae, 0x6e, - 0x8e, 0x08, 0xaa, 0x01, 0x10, 0x57, 0x77, 0x5c, 0x8d, 0xee, 0x95, 0x6d, 0x26, 0xbd, 0xf5, 0x56, - 0x79, 0x91, 0x3e, 0x1a, 0x4b, 0x79, 0x38, 0x1a, 0x94, 0x7b, 0x7e, 0x2c, 0x35, 0xf1, 0xc5, 0xac, - 0x10, 0x51, 0x53, 0xcc, 0x8c, 0x4a, 0xd1, 0x07, 0x20, 0xe1, 0x89, 0xc1, 0x3d, 0x44, 0x2f, 0xef, - 0x21, 0x89, 0x27, 0x06, 0xb3, 0x7f, 0x03, 0x62, 0x53, 0xc7, 0x54, 0x62, 0x45, 0x61, 0x33, 0x55, - 0x4b, 0xce, 0x67, 0x85, 0xd8, 0x81, 0xda, 0x52, 0xa9, 0x0c, 0xdd, 0x84, 0xd5, 0x3e, 0xdb, 0xaf, - 0x66, 0x60, 0x32, 0x70, 0x4c, 0xdb, 0xb5, 0x1c, 0x45, 0x2c, 0x0a, 0x9b, 0x19, 0x55, 0xee, 0x7b, - 0x81, 0xf8, 0xf2, 0x92, 0x0c, 0x39, 0x1e, 0xdc, 0xbe, 0x63, 0x1d, 0x39, 0x98, 0x90, 0xd2, 0xdf, - 0xe2, 0x90, 0x53, 0x31, 0x71, 0x2d, 0x07, 0xfb, 0x01, 0xff, 0x5c, 0x80, 0x9c, 0xab, 0xf7, 0x47, - 0x58, 0x73, 0xf0, 0x13, 0xc7, 0x74, 0x31, 0x51, 0xa2, 0xc5, 0xd8, 0x66, 0x7a, 0xeb, 0xab, 0xe5, - 0xff, 0x0a, 0x9a, 0xf2, 0xb2, 0x8f, 0x72, 0x8f, 0xda, 0xab, 0x9e, 0x79, 0x73, 0xe2, 0x3a, 0x4f, - 0x6b, 0x77, 0x7e, 0xfc, 0xd9, 0x25, 0xcb, 0x16, 0xc2, 0x4e, 0xb9, 0xd5, 0x50, 0xb3, 0x6e, 0xd8, - 0x19, 0x7a, 0x13, 0xc4, 0xa9, 0x63, 0x12, 0x25, 0x56, 0x8c, 0x6d, 0xa6, 0x6a, 0xd2, 0x7c, 0x56, - 0x10, 0x0f, 0xd4, 0x16, 0x51, 0x99, 0x74, 0x29, 0xd3, 0xe2, 0x35, 0x32, 0x7d, 0x1f, 0xd2, 0x3c, - 0x76, 0x9a, 0x4d, 0xa2, 0xc4, 0x59, 0xe0, 0xef, 0x9c, 0x0a, 0xdc, 0xdf, 0x1c, 0x8b, 0x72, 0x91, - 0x5e, 0x15, 0x5c, 0x5f, 0x40, 0x50, 0x05, 0xd2, 0xd6, 0x63, 0xec, 0x38, 0xa6, 0x81, 0x35, 0xa3, - 0xaf, 0x24, 0x58, 0xe9, 0x72, 0xf3, 0x59, 0x01, 0x3a, 0x9e, 0xb8, 0x51, 0x53, 0xc1, 0x57, 0x69, - 0xf4, 0xf3, 0x7f, 0x12, 0x20, 0x13, 0x4e, 0x1b, 0xfa, 0x36, 0x48, 0x7c, 0x2b, 0x41, 0x0f, 0xd4, - 0xe6, 0xb3, 0x42, 0x92, 0xe9, 0x5c, 0xa1, 0x09, 0x4e, 0x65, 0x33, 0xc9, 0x7c, 0xb6, 0x0c, 0xf4, - 0x5d, 0x48, 0xd9, 0xba, 0x83, 0x27, 0x2e, 0xf5, 0x1f, 0x65, 0xfe, 0xeb, 0xf3, 0x59, 0x41, 0xda, - 0x67, 0xc2, 0xeb, 0xbf, 0x40, 0xe2, 0x5e, 0x5b, 0x46, 0xfe, 0xfb, 0x80, 0x5e, 0xc5, 0x01, 0x92, - 0x21, 0x76, 0x8c, 0x9f, 0xf2, 0x88, 0x54, 0xfa, 0x13, 0xed, 0x42, 0xfc, 0xb1, 0x3e, 0x9a, 0xfa, - 0xad, 0xf1, 0xfe, 0xf5, 0x60, 0xa6, 0x72, 0x27, 0xf7, 0xa2, 0x5f, 0x11, 0xda, 0xa2, 0x24, 0xc8, - 0xd1, 0xd2, 0x17, 0x61, 0xc5, 0xd3, 0xf7, 0xe1, 0x8e, 0xde, 0x02, 0x18, 0x9a, 0x47, 0x43, 0xed, - 0x89, 0xee, 0x62, 0x87, 0xed, 0x21, 0xa3, 0xa6, 0xa8, 0xe4, 0x23, 0x2a, 0x28, 0x7d, 0x16, 0x87, - 0x6c, 0x6b, 0x6c, 0x5b, 0x8e, 0xeb, 0x37, 0xc3, 0x2e, 0x24, 0x58, 0xc2, 0x88, 0x22, 0x30, 0x28, - 0x94, 0xcf, 0xd9, 0xdc, 0x92, 0x25, 0xdf, 0x9b, 0x07, 0x2f, 0xcf, 0x47, 0x80, 0xdd, 0xe8, 0x99, - 0xd8, 0xfd, 0x1a, 0x24, 0x38, 0x8b, 0xb2, 0x46, 0x4f, 0x6f, 0x15, 0x42, 0xef, 0xf2, 0xa9, 0xac, - 0xd5, 0xd9, 0x36, 0x47, 0x78, 0x9b, 0xa9, 0xf9, 0xce, 0xb9, 0x11, 0x7a, 0x07, 0x24, 0x42, 0x5c, - 0x8d, 0x98, 0x9f, 0x70, 0xe8, 0xc7, 0x6a, 0x69, 0x8a, 0x97, 0x6e, 0xb7, 0xd7, 0x35, 0x3f, 0xc1, - 0x6a, 0x92, 0x10, 0x97, 0xfe, 0x40, 0x79, 0x90, 0x9e, 0xe8, 0xa3, 0x11, 0x6b, 0x91, 0x38, 0x63, - 0xc0, 0xe0, 0x79, 0x19, 0x14, 0x89, 0xff, 0x01, 0x28, 0x50, 0x01, 0xd2, 0x1e, 0x5f, 0xd9, 0xba, - 0x3b, 0x54, 0x92, 0xb4, 0x2f, 0x54, 0xe0, 0xa2, 0x7d, 0xdd, 0x1d, 0x22, 0x05, 0x92, 0x44, 0x1f, - 0xdb, 0x34, 0xe5, 0x52, 0x31, 0xb6, 0x99, 0x51, 0xfd, 0x47, 0xb4, 0x01, 0xac, 0x5f, 0xf8, 0xa3, - 0x92, 0x62, 0x5b, 0x0f, 0x49, 0x58, 0x02, 0x8e, 0x4d, 0x5b, 0x3b, 0x3c, 0x26, 0x0a, 0x14, 0x85, - 0x4d, 0xc9, 0x4b, 0xc0, 0xb1, 0x69, 0x6f, 0x3f, 0x20, 0x6a, 0x92, 0x2e, 0x6e, 0x1f, 0x13, 0xf4, - 0x2e, 0xac, 0x98, 0x93, 0x23, 0x4c, 0x5c, 0xcd, 0x30, 0x1d, 0x3c, 0x70, 0x47, 0x4f, 0x95, 0x34, - 0x55, 0x57, 0x73, 0x5c, 0xdc, 0xf0, 0xa4, 0xf9, 0x4f, 0x05, 0x88, 0xb3, 0x32, 0xa2, 0x7b, 0x20, - 0x52, 0x42, 0xf0, 0xe8, 0xff, 0xb2, 0x7c, 0xc0, 0x6c, 0x10, 0x02, 0x71, 0xa2, 0x8f, 0xb1, 0x82, - 0x58, 0xa8, 0xec, 0x37, 0x7a, 0x1d, 0x92, 0x04, 0x9f, 0x68, 0x8f, 0xf5, 0x91, 0xb2, 0xc6, 0xe2, - 0x48, 0x10, 0x7c, 0xf2, 0x48, 0x1f, 0xb5, 0x45, 0x29, 0x2a, 0xc7, 0xda, 0xa2, 0x14, 0x93, 0xc5, - 0xb6, 0x28, 0x89, 0x72, 0xbc, 0x2d, 0x4a, 0x71, 0x39, 0xd1, 0x16, 0xa5, 0x84, 0x9c, 0x6c, 0x8b, - 0x52, 0x52, 0x96, 0xda, 0xa2, 0x24, 0xc9, 0xa9, 0xb6, 0x28, 0xa5, 0x64, 0x68, 0x8b, 0x12, 0xc8, - 0xe9, 0xb6, 0x28, 0xa5, 0xe5, 0x4c, 0x5b, 0x94, 0x32, 0x72, 0xb6, 0x2d, 0x4a, 0x59, 0x39, 0xd7, - 0x16, 0xa5, 0x9c, 0xbc, 0xd2, 0x16, 0xa5, 0x15, 0x59, 0x6e, 0x8b, 0x92, 0x2c, 0xaf, 0xb6, 0x45, - 0x69, 0x55, 0x46, 0xa5, 0x3f, 0x0a, 0x90, 0xe3, 0x38, 0x0d, 0x7a, 0xe2, 0x26, 0xac, 0xb2, 0x04, - 0x9a, 0x93, 0x23, 0xcd, 0xf6, 0x84, 0x0c, 0xed, 0x51, 0x55, 0xf6, 0x17, 0x02, 0xe5, 0xcf, 0x41, - 0xd6, 0xc1, 0xba, 0xb1, 0x50, 0x8c, 0x32, 0xc5, 0x0c, 0x15, 0x06, 0x4a, 0x6f, 0x43, 0x8e, 0xb5, - 0xe4, 0x42, 0x2b, 0xc6, 0xb4, 0xb2, 0x4c, 0x1a, 0xa8, 0xd5, 0x20, 0x4b, 0x6c, 0x7d, 0xb2, 0xd0, - 0x12, 0x59, 0x8b, 0xbd, 0x7e, 0x06, 0xec, 0xbb, 0xb6, 0x3e, 0xf1, 0xe0, 0x9e, 0xa1, 0x36, 0xc1, - 0xf9, 0xa5, 0xb2, 0xe3, 0x6b, 0x3a, 0xc6, 0x54, 0x63, 0xd7, 0x24, 0x2e, 0xfa, 0x3a, 0x64, 0x1c, - 0x26, 0xd1, 0xa8, 0xa2, 0xdf, 0xb7, 0x17, 0x38, 0x4d, 0x3b, 0x81, 0x13, 0x52, 0xfa, 0xad, 0x00, - 0x6b, 0x0d, 0xc7, 0xb2, 0x6d, 0x6c, 0x78, 0x15, 0xe5, 0x5c, 0xe0, 0x17, 0x52, 0x08, 0x15, 0xf2, - 0x3e, 0x44, 0x5b, 0x0d, 0x8f, 0x3e, 0xef, 0x5c, 0xb7, 0x3b, 0xa2, 0xad, 0x06, 0xba, 0x0b, 0x09, - 0xe2, 0xea, 0xee, 0x94, 0xb0, 0xe6, 0xcf, 0x6d, 0xfd, 0xff, 0x39, 0x44, 0xd3, 0x65, 0x8a, 0xaa, - 0x67, 0x50, 0xfa, 0x73, 0x14, 0xd6, 0xba, 0x83, 0x21, 0x1e, 0xeb, 0xf5, 0xa1, 0x3e, 0x39, 0x0a, - 0xf6, 0xfb, 0x4d, 0x90, 0x43, 0x99, 0xd0, 0x46, 0x26, 0x71, 0xbd, 0x93, 0xfc, 0xbd, 0xf3, 0x29, - 0x36, 0x94, 0x4e, 0x2f, 0x3f, 0x39, 0x67, 0x39, 0xc9, 0xdf, 0x82, 0x9c, 0xc1, 0x33, 0xa4, 0x79, - 0xf4, 0x18, 0xbb, 0x90, 0x1e, 0xcf, 0x48, 0xa9, 0xe7, 0x3d, 0x6b, 0x84, 0x96, 0x08, 0xfa, 0x01, - 0xac, 0xf9, 0xce, 0xe9, 0xb0, 0x49, 0xb3, 0x44, 0xe9, 0x48, 0x64, 0x49, 0xde, 0x9d, 0xcf, 0x0a, - 0xab, 0x9e, 0xab, 0x86, 0xb7, 0x7a, 0x7d, 0x5e, 0x5a, 0x35, 0x4e, 0x79, 0x32, 0xbc, 0xb3, 0xe3, - 0x35, 0x58, 0x0f, 0xa7, 0x34, 0xc0, 0x5b, 0x0d, 0x64, 0x2e, 0x39, 0xc4, 0x74, 0xbf, 0xce, 0x11, - 0x76, 0x51, 0x19, 0xd6, 0x68, 0x25, 0xf0, 0x98, 0xf2, 0x26, 0xa5, 0x51, 0x2d, 0x04, 0x93, 0xd5, - 0x60, 0x89, 0xce, 0x17, 0x7b, 0xfa, 0x18, 0x97, 0x7e, 0x27, 0xc2, 0xea, 0xc2, 0x89, 0x5f, 0x2d, - 0xca, 0x5e, 0xe6, 0xe4, 0x58, 0x5b, 0x0c, 0x7a, 0x9c, 0xbd, 0xcc, 0xc9, 0x31, 0x1d, 0xf6, 0x92, - 0x74, 0xf1, 0xc0, 0x31, 0x51, 0x1b, 0x44, 0xcb, 0x76, 0xfd, 0x66, 0x39, 0xef, 0xb0, 0x7c, 0xe5, - 0x1d, 0xe5, 0x8e, 0xed, 0xf2, 0x53, 0x58, 0x65, 0x3e, 0xd0, 0xaf, 0x05, 0x48, 0xba, 0x2c, 0x08, - 0xa2, 0x24, 0x98, 0xbf, 0xbb, 0x57, 0xf2, 0xc7, 0x13, 0xe0, 0x0d, 0x78, 0xfb, 0xb4, 0x96, 0x2f, - 0x67, 0x85, 0xd5, 0xd3, 0x09, 0x22, 0xd7, 0x9d, 0xfc, 0xfc, 0xbd, 0xa1, 0x36, 0xe4, 0x96, 0x33, - 0xcc, 0xce, 0x8d, 0x4b, 0xce, 0x76, 0xd9, 0xa5, 0x0a, 0xe4, 0x8f, 0xe8, 0x98, 0xb5, 0xd8, 0xf6, - 0x19, 0xf3, 0x48, 0x75, 0x79, 0x1e, 0xb9, 0x79, 0xa9, 0x94, 0x70, 0x9f, 0xa1, 0x21, 0x24, 0x7f, - 0x07, 0x52, 0x41, 0xbe, 0xc3, 0x6f, 0x49, 0xf1, 0xb7, 0xac, 0x87, 0xdf, 0x92, 0x7a, 0x65, 0x7a, - 0x09, 0x4e, 0x82, 0xb8, 0x9c, 0x28, 0xfd, 0x44, 0x80, 0x8c, 0x8a, 0x89, 0x35, 0x7a, 0x8c, 0x0d, - 0xda, 0x83, 0xe8, 0x4b, 0x20, 0xd2, 0x9e, 0xf6, 0xce, 0xa3, 0x0b, 0xc8, 0x8d, 0xa9, 0xa2, 0x2a, - 0xa4, 0x82, 0xdb, 0xd6, 0x55, 0x2e, 0x21, 0x0b, 0xab, 0x92, 0x0d, 0x68, 0x11, 0x70, 0x40, 0xe3, - 0x3d, 0xa0, 0xec, 0xc0, 0xf6, 0xe6, 0x51, 0x2e, 0x27, 0x99, 0x77, 0xcf, 0x27, 0x99, 0x20, 0x18, - 0xbf, 0x4c, 0x4e, 0x48, 0x46, 0xbc, 0x36, 0xfc, 0x43, 0x0c, 0x50, 0xdd, 0xc1, 0xba, 0x8b, 0x29, - 0xe7, 0x91, 0xf3, 0x98, 0xb8, 0x06, 0x71, 0x46, 0x45, 0x5e, 0x6c, 0x97, 0x3c, 0xa3, 0xbd, 0x97, - 0x73, 0x53, 0xf4, 0x1d, 0xc8, 0x0c, 0xac, 0xd1, 0x74, 0xcc, 0xc9, 0xd2, 0x27, 0xb5, 0x2f, 0x9f, - 0x07, 0x80, 0x57, 0x36, 0x57, 0xae, 0x5b, 0xa3, 0x10, 0x73, 0xa6, 0xb9, 0x43, 0x2a, 0xa1, 0xf3, - 0x5f, 0x2a, 0x00, 0x23, 0xe3, 0xb3, 0x94, 0xba, 0x10, 0xa0, 0x2d, 0x88, 0xeb, 0x44, 0xb3, 0x0e, - 0xd9, 0x54, 0x76, 0x51, 0x75, 0x54, 0x51, 0x27, 0x9d, 0x43, 0x74, 0x1b, 0xb2, 0x87, 0x27, 0x9c, - 0x83, 0x39, 0xeb, 0xf0, 0x8b, 0xc6, 0xca, 0x7c, 0x56, 0x48, 0x6f, 0x7f, 0xc8, 0x82, 0xa5, 0x9c, - 0xa3, 0xa6, 0x0f, 0x4f, 0x82, 0x87, 0xbc, 0x0e, 0x49, 0x6f, 0x93, 0xe8, 0x11, 0xc4, 0x4c, 0x83, - 0x1f, 0x92, 0xd9, 0x5a, 0x83, 0xde, 0x2c, 0x5b, 0x0d, 0xf2, 0x72, 0x56, 0xb8, 0x7b, 0xe5, 0x7e, - 0xad, 0xb3, 0x38, 0x5b, 0x0d, 0x95, 0x3a, 0x2c, 0xfd, 0x1f, 0xac, 0x85, 0x52, 0x13, 0xd0, 0xe7, - 0x5f, 0x12, 0x90, 0xdc, 0xd7, 0x9f, 0x8e, 0x2c, 0xdd, 0x40, 0x45, 0x48, 0xfb, 0x57, 0x56, 0xd3, - 0x9a, 0x78, 0xb5, 0x0c, 0x8b, 0xe8, 0xa4, 0x3a, 0x25, 0xd8, 0x61, 0x71, 0xf1, 0x2e, 0x09, 0x9e, - 0xe9, 0x8c, 0xc1, 0xee, 0xd7, 0xd8, 0xd0, 0xc6, 0xe6, 0xc0, 0xb1, 0xf8, 0xb9, 0x19, 0x63, 0xdd, - 0x4e, 0xa5, 0x0f, 0x99, 0x90, 0xce, 0x7a, 0x87, 0xe6, 0xc4, 0x24, 0xc3, 0x85, 0x1e, 0x9b, 0x8d, - 0xd5, 0x9c, 0x2f, 0xf6, 0x14, 0x2d, 0xc8, 0x2d, 0x2e, 0xd0, 0x1a, 0xcd, 0x49, 0x82, 0xe5, 0x64, - 0x67, 0x3e, 0x2b, 0x64, 0x17, 0x78, 0xe1, 0xd9, 0xb9, 0xde, 0x3d, 0x76, 0xe1, 0xbf, 0x65, 0x10, - 0xf6, 0x15, 0xc2, 0x71, 0x2c, 0x47, 0x91, 0x78, 0xff, 0xb3, 0x07, 0xf4, 0x3e, 0xc4, 0x47, 0x58, - 0x27, 0x7c, 0xbc, 0x4d, 0x6f, 0x15, 0xcf, 0x81, 0x1e, 0xfb, 0x50, 0xa2, 0x72, 0x75, 0x54, 0x83, - 0x04, 0x9f, 0xa1, 0xd9, 0xe4, 0x9b, 0xde, 0xda, 0x3c, 0xc7, 0x70, 0xe9, 0xfb, 0xc6, 0x4e, 0x44, - 0xf5, 0x2c, 0x51, 0x13, 0x92, 0x0e, 0xbf, 0x2f, 0xb1, 0x79, 0xf8, 0xc2, 0x31, 0x21, 0x74, 0x13, - 0xdb, 0x89, 0xa8, 0xbe, 0x2d, 0xea, 0x41, 0x86, 0x84, 0x8e, 0x4e, 0x25, 0xc3, 0x7c, 0x9d, 0x37, - 0x19, 0x9c, 0x31, 0xbc, 0xec, 0xd0, 0x41, 0x2f, 0x24, 0xa6, 0x01, 0x9a, 0x6c, 0x6e, 0x55, 0xb2, - 0x17, 0x06, 0xb8, 0x74, 0x11, 0xa3, 0x01, 0x72, 0x4b, 0xb4, 0x07, 0x30, 0x08, 0xf8, 0x4b, 0xc9, - 0x31, 0x3f, 0x5f, 0xb8, 0xca, 0x81, 0xb7, 0x13, 0x51, 0x43, 0x1e, 0xd0, 0x87, 0x90, 0x1e, 0x2c, - 0x40, 0xae, 0xac, 0x30, 0x87, 0xb7, 0xae, 0xc4, 0x16, 0x3b, 0x94, 0x21, 0x16, 0xd2, 0x65, 0x86, - 0x90, 0x4f, 0x31, 0x44, 0x2d, 0x05, 0x49, 0x83, 0xdb, 0x05, 0xd7, 0x82, 0xa4, 0x2c, 0x95, 0x7e, - 0x1f, 0x07, 0x29, 0xa0, 0xe3, 0x0a, 0xa0, 0x43, 0x47, 0x1f, 0xd0, 0x06, 0xd2, 0x06, 0x16, 0xbd, - 0x18, 0xb9, 0x98, 0x7f, 0x40, 0x88, 0xee, 0x44, 0xd4, 0x55, 0x7f, 0xad, 0xee, 0x2f, 0xd1, 0x16, - 0x19, 0x5b, 0x86, 0x79, 0x68, 0x2e, 0x5a, 0x84, 0x7f, 0x18, 0xcb, 0xf9, 0x62, 0xaf, 0x45, 0x3e, - 0x58, 0xba, 0x3c, 0xc7, 0x2e, 0x41, 0x52, 0x3b, 0x91, 0xd0, 0xed, 0x9a, 0xb6, 0xac, 0x33, 0x9d, - 0x4c, 0xe8, 0x3d, 0xc3, 0x1b, 0x75, 0x39, 0x05, 0x66, 0x3d, 0x29, 0x1f, 0x6b, 0x51, 0xfd, 0x14, - 0x94, 0xdf, 0xbb, 0x10, 0xca, 0x7e, 0xec, 0x3b, 0x42, 0x80, 0xe5, 0xed, 0xd3, 0x58, 0xbe, 0x71, - 0x31, 0x96, 0x43, 0x6e, 0x02, 0x30, 0x1f, 0x9c, 0x09, 0xe6, 0xca, 0x25, 0xc1, 0x1c, 0xf2, 0xb8, - 0x8c, 0xe6, 0xfa, 0x29, 0x34, 0xbf, 0x77, 0x21, 0x9a, 0xc3, 0x31, 0x7a, 0x70, 0xee, 0x9c, 0x01, - 0xe7, 0x5b, 0x97, 0x82, 0x73, 0xc8, 0x59, 0x18, 0xcf, 0xea, 0x59, 0x78, 0x2e, 0x5f, 0x0e, 0xcf, - 0x21, 0x97, 0x61, 0x27, 0x35, 0x00, 0xc9, 0xbf, 0xdf, 0x85, 0xe0, 0x7b, 0xe3, 0x1b, 0x90, 0xf0, - 0xca, 0x8d, 0x20, 0xd7, 0x50, 0xab, 0xad, 0xbd, 0xd6, 0xde, 0x7d, 0x6d, 0xaf, 0xfa, 0xb0, 0xd9, - 0x95, 0x23, 0x48, 0x81, 0xf5, 0x8f, 0xaa, 0xad, 0x9e, 0xb6, 0xdd, 0x51, 0xb5, 0xfb, 0x75, 0xad, - 0xb5, 0xd7, 0x6b, 0xaa, 0x8f, 0xaa, 0xbb, 0xb2, 0x80, 0x5e, 0x03, 0xa4, 0x76, 0xea, 0x0f, 0xba, - 0x8d, 0x9a, 0x56, 0xef, 0x3c, 0xdc, 0xaf, 0xd6, 0x7b, 0xad, 0xce, 0x9e, 0x1c, 0x45, 0x12, 0x88, - 0x8d, 0xce, 0x5e, 0x53, 0x86, 0x1b, 0x3f, 0x8a, 0x82, 0xd8, 0x7b, 0x6a, 0x63, 0xf4, 0x79, 0x48, - 0x1f, 0xec, 0x75, 0xf7, 0x9b, 0xf5, 0xd6, 0x76, 0xab, 0xd9, 0x90, 0x23, 0xf9, 0xb5, 0x67, 0xcf, - 0x8b, 0x2b, 0x74, 0xe9, 0x60, 0x42, 0x6c, 0x3c, 0x60, 0xd0, 0x46, 0x79, 0x48, 0xd4, 0xaa, 0xf5, - 0x07, 0x07, 0xfb, 0xb2, 0x90, 0xcf, 0x3d, 0x7b, 0x5e, 0x04, 0xaa, 0xc0, 0x61, 0x85, 0xde, 0x84, - 0xa4, 0xda, 0xec, 0xf6, 0x3a, 0x6a, 0x53, 0x8e, 0xe6, 0x57, 0x9e, 0x3d, 0x2f, 0xa6, 0xe9, 0xa2, - 0x87, 0x16, 0xf4, 0x2e, 0x64, 0xbb, 0xf5, 0x9d, 0xe6, 0xc3, 0xaa, 0x56, 0xdf, 0xa9, 0xee, 0xdd, - 0x6f, 0xca, 0xb1, 0xfc, 0xfa, 0xb3, 0xe7, 0x45, 0x99, 0xea, 0x84, 0x41, 0x40, 0x5f, 0xd1, 0x7a, - 0xb8, 0xdf, 0x51, 0x7b, 0xb2, 0xb8, 0x78, 0x05, 0xaf, 0x2a, 0x2a, 0x01, 0x70, 0xeb, 0xed, 0x66, - 0xb3, 0x21, 0xc7, 0xf3, 0xe8, 0xd9, 0xf3, 0x62, 0x8e, 0xae, 0x2f, 0x8a, 0x85, 0xde, 0x86, 0x4c, - 0x5d, 0x6d, 0x56, 0x7b, 0x4d, 0xad, 0xdb, 0xab, 0xf6, 0xba, 0x72, 0x62, 0x11, 0x49, 0xa8, 0x00, - 0x79, 0xe9, 0xa7, 0xbf, 0xdc, 0x88, 0xfc, 0xe6, 0x57, 0x1b, 0x91, 0x5a, 0xf1, 0xc5, 0x3f, 0x37, - 0x22, 0x2f, 0xe6, 0x1b, 0xc2, 0xa7, 0xf3, 0x0d, 0xe1, 0xaf, 0xf3, 0x0d, 0xe1, 0x1f, 0xf3, 0x0d, - 0xe1, 0x67, 0xff, 0xda, 0x88, 0x7c, 0x9c, 0xe0, 0x85, 0xeb, 0x27, 0xd8, 0xe7, 0xf6, 0xdb, 0xff, - 0x09, 0x00, 0x00, 0xff, 0xff, 0xcd, 0xe9, 0x69, 0xab, 0x1f, 0x18, 0x00, 0x00, + 0xd3, 0x7a, 0xf7, 0xd0, 0x72, 0xc6, 0xba, 0xeb, 0xb9, 0xcf, 0xbf, 0x4a, 0x4e, 0x46, 0x15, 0x72, + 0x32, 0xea, 0xeb, 0x04, 0x57, 0x88, 0xeb, 0x4c, 0x07, 0xee, 0xd4, 0xc1, 0x86, 0x6f, 0x37, 0x75, + 0xcd, 0x51, 0x65, 0x38, 0x1a, 0x54, 0x5c, 0x73, 0x8c, 0x89, 0xab, 0x8f, 0x6d, 0xbe, 0x52, 0xfa, + 0x31, 0xc4, 0x77, 0xb1, 0x4e, 0x30, 0xfa, 0x18, 0x92, 0x13, 0xcb, 0xc0, 0x9a, 0x69, 0x28, 0x42, + 0x51, 0xd8, 0xcc, 0xd6, 0xaa, 0xf3, 0x59, 0x21, 0xb1, 0x67, 0x19, 0xb8, 0xd5, 0x78, 0x3e, 0x2b, + 0xbc, 0x77, 0x64, 0xba, 0xc3, 0x69, 0xbf, 0x3c, 0xb0, 0xc6, 0x95, 0x20, 0x12, 0xa3, 0xbf, 0xf8, + 0x5d, 0xb1, 0x8f, 0x8f, 0x2a, 0xde, 0xf6, 0xca, 0xdc, 0x4c, 0x4d, 0x50, 0x8f, 0x2d, 0x03, 0xad, + 0x43, 0x1c, 0xdb, 0xd6, 0x60, 0xa8, 0x44, 0x8b, 0xc2, 0x66, 0x4c, 0xe5, 0x0f, 0xf7, 0xc4, 0x7f, + 0xff, 0xb2, 0x20, 0x94, 0xfe, 0x2e, 0x40, 0xb6, 0xa6, 0x0f, 0x8e, 0xa7, 0x76, 0x03, 0xbb, 0xba, + 0x39, 0x22, 0xa8, 0x06, 0x40, 0x5c, 0xdd, 0x71, 0x35, 0xba, 0x57, 0xb6, 0x99, 0xf4, 0xd6, 0x6b, + 0xe5, 0x45, 0xfa, 0x68, 0x2c, 0xe5, 0xe1, 0x68, 0x50, 0xee, 0xf9, 0xb1, 0xd4, 0xc4, 0x67, 0xb3, + 0x42, 0x44, 0x4d, 0x31, 0x33, 0x2a, 0x45, 0x1f, 0x80, 0x84, 0x27, 0x06, 0xf7, 0x10, 0xbd, 0xbe, + 0x87, 0x24, 0x9e, 0x18, 0xcc, 0xfe, 0x15, 0x88, 0x4d, 0x1d, 0x53, 0x89, 0x15, 0x85, 0xcd, 0x54, + 0x2d, 0x39, 0x9f, 0x15, 0x62, 0x07, 0x6a, 0x4b, 0xa5, 0x32, 0xf4, 0x0e, 0xac, 0xf6, 0xd9, 0x7e, + 0x35, 0x03, 0x93, 0x81, 0x63, 0xda, 0xae, 0xe5, 0x28, 0x62, 0x51, 0xd8, 0xcc, 0xa8, 0x72, 0xdf, + 0x0b, 0xc4, 0x97, 0x97, 0x64, 0xc8, 0xf1, 0xe0, 0xf6, 0x1d, 0xeb, 0xc8, 0xc1, 0x84, 0x94, 0xfe, + 0x16, 0x87, 0x9c, 0x8a, 0x89, 0x6b, 0x39, 0xd8, 0x0f, 0xf8, 0x17, 0x02, 0xe4, 0x5c, 0xbd, 0x3f, + 0xc2, 0x9a, 0x83, 0x9f, 0x38, 0xa6, 0x8b, 0x89, 0x12, 0x2d, 0xc6, 0x36, 0xd3, 0x5b, 0x5f, 0x2f, + 0xff, 0x57, 0xd0, 0x94, 0x97, 0x7d, 0x94, 0x7b, 0xd4, 0x5e, 0xf5, 0xcc, 0x9b, 0x13, 0xd7, 0x79, + 0x5a, 0xbb, 0xf3, 0x93, 0xcf, 0xaf, 0x59, 0xb6, 0x10, 0x76, 0xca, 0xad, 0x86, 0x9a, 0x75, 0xc3, + 0xce, 0xd0, 0xab, 0x20, 0x4e, 0x1d, 0x93, 0x28, 0xb1, 0x62, 0x6c, 0x33, 0x55, 0x93, 0xe6, 0xb3, + 0x82, 0x78, 0xa0, 0xb6, 0x88, 0xca, 0xa4, 0x4b, 0x99, 0x16, 0x6f, 0x91, 0xe9, 0xfb, 0x90, 0xe6, + 0xb1, 0xd3, 0x6c, 0x12, 0x25, 0xce, 0x02, 0x7f, 0xe3, 0x5c, 0xe0, 0xfe, 0xe6, 0x58, 0x94, 0x8b, + 0xf4, 0xaa, 0xe0, 0xfa, 0x02, 0x82, 0x2a, 0x90, 0xb6, 0x1e, 0x63, 0xc7, 0x31, 0x0d, 0xac, 0x19, + 0x7d, 0x25, 0xc1, 0x4a, 0x97, 0x9b, 0xcf, 0x0a, 0xd0, 0xf1, 0xc4, 0x8d, 0x9a, 0x0a, 0xbe, 0x4a, + 0xa3, 0x9f, 0xff, 0x93, 0x00, 0x99, 0x70, 0xda, 0xd0, 0x77, 0x41, 0xe2, 0x5b, 0x09, 0x7a, 0xa0, + 0x36, 0x9f, 0x15, 0x92, 0x4c, 0xe7, 0x06, 0x4d, 0x70, 0x2e, 0x9b, 0x49, 0xe6, 0xb3, 0x65, 0xa0, + 0xef, 0x43, 0xca, 0xd6, 0x1d, 0x3c, 0x71, 0xa9, 0xff, 0x28, 0xf3, 0x5f, 0x9f, 0xcf, 0x0a, 0xd2, + 0x3e, 0x13, 0xde, 0xfe, 0x05, 0x12, 0xf7, 0xda, 0x32, 0xf2, 0x3f, 0x04, 0xf4, 0x22, 0x0e, 0x90, + 0x0c, 0xb1, 0x63, 0xfc, 0x94, 0x47, 0xa4, 0xd2, 0x9f, 0x68, 0x17, 0xe2, 0x8f, 0xf5, 0xd1, 0xd4, + 0x6f, 0x8d, 0xf7, 0x6f, 0x07, 0x33, 0x95, 0x3b, 0xb9, 0x17, 0xfd, 0x9a, 0xd0, 0x16, 0x25, 0x41, + 0x8e, 0x96, 0xbe, 0x0c, 0x2b, 0x9e, 0xbe, 0x0f, 0x77, 0xf4, 0x1a, 0xc0, 0xd0, 0x3c, 0x1a, 0x6a, + 0x4f, 0x74, 0x17, 0x3b, 0x6c, 0x0f, 0x19, 0x35, 0x45, 0x25, 0x1f, 0x51, 0x41, 0xe9, 0xf3, 0x38, + 0x64, 0x5b, 0x63, 0xdb, 0x72, 0x5c, 0xbf, 0x19, 0x76, 0x21, 0xc1, 0x12, 0x46, 0x14, 0x81, 0x41, + 0xa1, 0x7c, 0xc9, 0xe6, 0x96, 0x2c, 0xf9, 0xde, 0x3c, 0x78, 0x79, 0x3e, 0x02, 0xec, 0x46, 0x2f, + 0xc4, 0xee, 0x37, 0x20, 0xc1, 0x59, 0x94, 0x35, 0x7a, 0x7a, 0xab, 0x10, 0x7a, 0x97, 0x4f, 0x65, + 0xad, 0xce, 0xb6, 0x39, 0xc2, 0xdb, 0x4c, 0xcd, 0x77, 0xce, 0x8d, 0xd0, 0x1b, 0x20, 0x11, 0xe2, + 0x6a, 0xc4, 0xfc, 0x84, 0x43, 0x3f, 0x56, 0x4b, 0x53, 0xbc, 0x74, 0xbb, 0xbd, 0xae, 0xf9, 0x09, + 0x56, 0x93, 0x84, 0xb8, 0xf4, 0x07, 0xca, 0x83, 0xf4, 0x44, 0x1f, 0x8d, 0x58, 0x8b, 0xc4, 0x19, + 0x03, 0x06, 0xcf, 0xcb, 0xa0, 0x48, 0xfc, 0x0f, 0x40, 0x81, 0x0a, 0x90, 0xf6, 0xf8, 0xca, 0xd6, + 0xdd, 0xa1, 0x92, 0xa4, 0x7d, 0xa1, 0x02, 0x17, 0xed, 0xeb, 0xee, 0x10, 0x29, 0x90, 0x24, 0xfa, + 0xd8, 0xa6, 0x29, 0x97, 0x8a, 0xb1, 0xcd, 0x8c, 0xea, 0x3f, 0xa2, 0x0d, 0x60, 0xfd, 0xc2, 0x1f, + 0x95, 0x14, 0xdb, 0x7a, 0x48, 0xc2, 0x12, 0x70, 0x6c, 0xda, 0xda, 0xe1, 0x31, 0x51, 0xa0, 0x28, + 0x6c, 0x4a, 0x5e, 0x02, 0x8e, 0x4d, 0x7b, 0xfb, 0x01, 0x51, 0x93, 0x74, 0x71, 0xfb, 0x98, 0xa0, + 0x37, 0x61, 0xc5, 0x9c, 0x1c, 0x61, 0xe2, 0x6a, 0x86, 0xe9, 0xe0, 0x81, 0x3b, 0x7a, 0xaa, 0xa4, + 0xa9, 0xba, 0x9a, 0xe3, 0xe2, 0x86, 0x27, 0xcd, 0x7f, 0x26, 0x40, 0x9c, 0x95, 0x11, 0xdd, 0x03, + 0x91, 0x12, 0x82, 0x47, 0xff, 0xd7, 0xe5, 0x03, 0x66, 0x83, 0x10, 0x88, 0x13, 0x7d, 0x8c, 0x15, + 0xc4, 0x42, 0x65, 0xbf, 0xd1, 0xcb, 0x90, 0x24, 0xf8, 0x44, 0x7b, 0xac, 0x8f, 0x94, 0x35, 0x16, + 0x47, 0x82, 0xe0, 0x93, 0x47, 0xfa, 0xa8, 0x2d, 0x4a, 0x51, 0x39, 0xd6, 0x16, 0xa5, 0x98, 0x2c, + 0xb6, 0x45, 0x49, 0x94, 0xe3, 0x6d, 0x51, 0x8a, 0xcb, 0x89, 0xb6, 0x28, 0x25, 0xe4, 0x64, 0x5b, + 0x94, 0x92, 0xb2, 0xd4, 0x16, 0x25, 0x49, 0x4e, 0xb5, 0x45, 0x29, 0x25, 0x43, 0x5b, 0x94, 0x40, + 0x4e, 0xb7, 0x45, 0x29, 0x2d, 0x67, 0xda, 0xa2, 0x94, 0x91, 0xb3, 0x6d, 0x51, 0xca, 0xca, 0xb9, + 0xb6, 0x28, 0xe5, 0xe4, 0x95, 0xb6, 0x28, 0xad, 0xc8, 0x72, 0x5b, 0x94, 0x64, 0x79, 0xb5, 0x2d, + 0x4a, 0xab, 0x32, 0x2a, 0xfd, 0x51, 0x80, 0x1c, 0xc7, 0x69, 0xd0, 0x13, 0xef, 0xc0, 0x2a, 0x4b, + 0xa0, 0x39, 0x39, 0xd2, 0x6c, 0x4f, 0xc8, 0xd0, 0x1e, 0x55, 0x65, 0x7f, 0x21, 0x50, 0xfe, 0x02, + 0x64, 0x1d, 0xac, 0x1b, 0x0b, 0xc5, 0x28, 0x53, 0xcc, 0x50, 0x61, 0xa0, 0xf4, 0x3a, 0xe4, 0x58, + 0x4b, 0x2e, 0xb4, 0x62, 0x4c, 0x2b, 0xcb, 0xa4, 0x81, 0x5a, 0x0d, 0xb2, 0xc4, 0xd6, 0x27, 0x0b, + 0x2d, 0x91, 0xb5, 0xd8, 0xcb, 0x17, 0xc0, 0xbe, 0x6b, 0xeb, 0x13, 0x0f, 0xee, 0x19, 0x6a, 0x13, + 0x9c, 0x5f, 0x2a, 0x3b, 0xbe, 0xa6, 0x63, 0x4c, 0x35, 0x76, 0x4d, 0xe2, 0xa2, 0x6f, 0x42, 0xc6, + 0x61, 0x12, 0x8d, 0x2a, 0xfa, 0x7d, 0x7b, 0x85, 0xd3, 0xb4, 0x13, 0x38, 0x21, 0xa5, 0xdf, 0x09, + 0xb0, 0xd6, 0x70, 0x2c, 0xdb, 0xc6, 0x86, 0x57, 0x51, 0xce, 0x05, 0x7e, 0x21, 0x85, 0x50, 0x21, + 0xef, 0x43, 0xb4, 0xd5, 0xf0, 0xe8, 0xf3, 0xce, 0x6d, 0xbb, 0x23, 0xda, 0x6a, 0xa0, 0xbb, 0x90, + 0x20, 0xae, 0xee, 0x4e, 0x09, 0x6b, 0xfe, 0xdc, 0xd6, 0xff, 0x5f, 0x42, 0x34, 0x5d, 0xa6, 0xa8, + 0x7a, 0x06, 0xa5, 0x3f, 0x47, 0x61, 0xad, 0x3b, 0x18, 0xe2, 0xb1, 0x5e, 0x1f, 0xea, 0x93, 0xa3, + 0x60, 0xbf, 0xdf, 0x06, 0x39, 0x94, 0x09, 0x6d, 0x64, 0x12, 0xd7, 0x3b, 0xc9, 0xdf, 0xba, 0x9c, + 0x62, 0x43, 0xe9, 0xf4, 0xf2, 0x93, 0x73, 0x96, 0x93, 0xfc, 0x1d, 0xc8, 0x19, 0x3c, 0x43, 0x9a, + 0x47, 0x8f, 0xb1, 0x2b, 0xe9, 0xf1, 0x82, 0x94, 0x7a, 0xde, 0xb3, 0x46, 0x68, 0x89, 0xa0, 0x1f, + 0xc1, 0x9a, 0xef, 0x9c, 0x0e, 0x9b, 0x34, 0x4b, 0x94, 0x8e, 0x44, 0x96, 0xe4, 0xdd, 0xf9, 0xac, + 0xb0, 0xea, 0xb9, 0x6a, 0x78, 0xab, 0xb7, 0xe7, 0xa5, 0x55, 0xe3, 0x9c, 0x27, 0xc3, 0x3b, 0x3b, + 0x5e, 0x82, 0xf5, 0x70, 0x4a, 0x03, 0xbc, 0xd5, 0x40, 0xe6, 0x92, 0x43, 0x4c, 0xf7, 0xeb, 0x1c, + 0x61, 0x17, 0x95, 0x61, 0x8d, 0x56, 0x02, 0x8f, 0x29, 0x6f, 0x52, 0x1a, 0xd5, 0x42, 0x30, 0x59, + 0x0d, 0x96, 0xe8, 0x7c, 0xb1, 0xa7, 0x8f, 0x71, 0xe9, 0xf7, 0x22, 0xac, 0x2e, 0x9c, 0xf8, 0xd5, + 0xa2, 0xec, 0x65, 0x4e, 0x8e, 0xb5, 0xc5, 0xa0, 0xc7, 0xd9, 0xcb, 0x9c, 0x1c, 0xd3, 0x61, 0x2f, + 0x49, 0x17, 0x0f, 0x1c, 0x13, 0xb5, 0x41, 0xb4, 0x6c, 0xd7, 0x6f, 0x96, 0xcb, 0x0e, 0xcb, 0x17, + 0xde, 0x51, 0xee, 0xd8, 0x2e, 0x3f, 0x85, 0x55, 0xe6, 0x03, 0xfd, 0x46, 0x80, 0xa4, 0xcb, 0x82, + 0x20, 0x4a, 0x82, 0xf9, 0xbb, 0x7b, 0x23, 0x7f, 0x3c, 0x01, 0xde, 0x80, 0xb7, 0x4f, 0x6b, 0xf9, + 0x7c, 0x56, 0x58, 0x3d, 0x9f, 0x20, 0x72, 0xdb, 0xc9, 0xcf, 0xdf, 0x1b, 0x6a, 0x43, 0x6e, 0x39, + 0xc3, 0xec, 0xdc, 0xb8, 0xe6, 0x6c, 0x97, 0x5d, 0xaa, 0x40, 0xfe, 0x88, 0x8e, 0x59, 0x8b, 0x6d, + 0x5f, 0x30, 0x8f, 0x54, 0x97, 0xe7, 0x91, 0x77, 0xae, 0x95, 0x12, 0xee, 0x33, 0x34, 0x84, 0xe4, + 0xef, 0x40, 0x2a, 0xc8, 0x77, 0xf8, 0x2d, 0x29, 0xfe, 0x96, 0xf5, 0xf0, 0x5b, 0x52, 0x2f, 0x4c, + 0x2f, 0xc1, 0x49, 0x10, 0x97, 0x13, 0xa5, 0x9f, 0x0a, 0x90, 0x51, 0x31, 0xb1, 0x46, 0x8f, 0xb1, + 0x41, 0x7b, 0x10, 0x7d, 0x05, 0x44, 0xda, 0xd3, 0xde, 0x79, 0x74, 0x05, 0xb9, 0x31, 0x55, 0x54, + 0x85, 0x54, 0x70, 0xdb, 0xba, 0xc9, 0x25, 0x64, 0x61, 0x55, 0xb2, 0x01, 0x2d, 0x02, 0x0e, 0x68, + 0xbc, 0x07, 0x94, 0x1d, 0xd8, 0xde, 0x3c, 0xca, 0xe5, 0x24, 0xf3, 0xe6, 0xe5, 0x24, 0x13, 0x04, + 0xe3, 0x97, 0xc9, 0x09, 0xc9, 0x88, 0xd7, 0x86, 0x7f, 0x88, 0x01, 0xaa, 0x3b, 0x58, 0x77, 0x31, + 0xe5, 0x3c, 0x72, 0x19, 0x13, 0xd7, 0x20, 0xce, 0xa8, 0xc8, 0x8b, 0xed, 0x9a, 0x67, 0xb4, 0xf7, + 0x72, 0x6e, 0x8a, 0xbe, 0x07, 0x99, 0x81, 0x35, 0x9a, 0x8e, 0x39, 0x59, 0xfa, 0xa4, 0xf6, 0xd5, + 0xcb, 0x00, 0xf0, 0xc2, 0xe6, 0xca, 0x75, 0x6b, 0x14, 0x62, 0xce, 0x34, 0x77, 0x48, 0x25, 0x74, + 0xfe, 0x4b, 0x05, 0x60, 0x64, 0x7c, 0x96, 0x52, 0x17, 0x02, 0xb4, 0x05, 0x71, 0x9d, 0x68, 0xd6, + 0x21, 0x9b, 0xca, 0xae, 0xaa, 0x8e, 0x2a, 0xea, 0xa4, 0x73, 0x88, 0xde, 0x83, 0xec, 0xe1, 0x09, + 0xe7, 0x60, 0xce, 0x3a, 0xfc, 0xa2, 0xb1, 0x32, 0x9f, 0x15, 0xd2, 0xdb, 0x1f, 0xb2, 0x60, 0x29, + 0xe7, 0xa8, 0xe9, 0xc3, 0x93, 0xe0, 0x21, 0xaf, 0x43, 0xd2, 0xdb, 0x24, 0x7a, 0x04, 0x31, 0xd3, + 0xe0, 0x87, 0x64, 0xb6, 0xd6, 0xa0, 0x37, 0xcb, 0x56, 0x83, 0x3c, 0x9f, 0x15, 0xee, 0xde, 0xb8, + 0x5f, 0xeb, 0x2c, 0xce, 0x56, 0x43, 0xa5, 0x0e, 0x4b, 0xff, 0x07, 0x6b, 0xa1, 0xd4, 0x04, 0xf4, + 0xf9, 0x97, 0x04, 0x24, 0xf7, 0xf5, 0xa7, 0x23, 0x4b, 0x37, 0x50, 0x11, 0xd2, 0xfe, 0x95, 0xd5, + 0xb4, 0x26, 0x5e, 0x2d, 0xc3, 0x22, 0x3a, 0xa9, 0x4e, 0x09, 0x76, 0x58, 0x5c, 0xbc, 0x4b, 0x82, + 0x67, 0x3a, 0x63, 0xb0, 0xfb, 0x35, 0x36, 0xb4, 0xb1, 0x39, 0x70, 0x2c, 0x7e, 0x6e, 0xc6, 0x58, + 0xb7, 0x53, 0xe9, 0x43, 0x26, 0xa4, 0xb3, 0xde, 0xa1, 0x39, 0x31, 0xc9, 0x70, 0xa1, 0xc7, 0x66, + 0x63, 0x35, 0xe7, 0x8b, 0x3d, 0x45, 0x0b, 0x72, 0x8b, 0x0b, 0xb4, 0x46, 0x73, 0x92, 0x60, 0x39, + 0xd9, 0x99, 0xcf, 0x0a, 0xd9, 0x05, 0x5e, 0x78, 0x76, 0x6e, 0x77, 0x8f, 0x5d, 0xf8, 0x6f, 0x19, + 0x84, 0x7d, 0x85, 0x70, 0x1c, 0xcb, 0x51, 0x24, 0xde, 0xff, 0xec, 0x01, 0xbd, 0x0f, 0xf1, 0x11, + 0xd6, 0x09, 0x1f, 0x6f, 0xd3, 0x5b, 0xc5, 0x4b, 0xa0, 0xc7, 0x3e, 0x94, 0xa8, 0x5c, 0x1d, 0xd5, + 0x20, 0xc1, 0x67, 0x68, 0x36, 0xf9, 0xa6, 0xb7, 0x36, 0x2f, 0x31, 0x5c, 0xfa, 0xbe, 0xb1, 0x13, + 0x51, 0x3d, 0x4b, 0xd4, 0x84, 0xa4, 0xc3, 0xef, 0x4b, 0x6c, 0x1e, 0xbe, 0x72, 0x4c, 0x08, 0xdd, + 0xc4, 0x76, 0x22, 0xaa, 0x6f, 0x8b, 0x7a, 0x90, 0x21, 0xa1, 0xa3, 0x53, 0xc9, 0x30, 0x5f, 0x97, + 0x4d, 0x06, 0x17, 0x0c, 0x2f, 0x3b, 0x74, 0xd0, 0x0b, 0x89, 0x69, 0x80, 0x26, 0x9b, 0x5b, 0x95, + 0xec, 0x95, 0x01, 0x2e, 0x5d, 0xc4, 0x68, 0x80, 0xdc, 0x12, 0xed, 0x01, 0x0c, 0x02, 0xfe, 0x52, + 0x72, 0xcc, 0xcf, 0x97, 0x6e, 0x72, 0xe0, 0xed, 0x44, 0xd4, 0x90, 0x07, 0xf4, 0x21, 0xa4, 0x07, + 0x0b, 0x90, 0x2b, 0x2b, 0xcc, 0xe1, 0xbb, 0x37, 0x62, 0x8b, 0x1d, 0xca, 0x10, 0x0b, 0xe9, 0x32, + 0x43, 0xc8, 0xe7, 0x18, 0xa2, 0x96, 0x82, 0xa4, 0xc1, 0xed, 0x82, 0x6b, 0x41, 0x52, 0x96, 0x4a, + 0x9f, 0xc6, 0x41, 0x0a, 0xe8, 0xb8, 0x02, 0xe8, 0xd0, 0xd1, 0x07, 0xb4, 0x81, 0xb4, 0x81, 0x45, + 0x2f, 0x46, 0x2e, 0xe6, 0x1f, 0x10, 0xa2, 0x3b, 0x11, 0x75, 0xd5, 0x5f, 0xab, 0xfb, 0x4b, 0xb4, + 0x45, 0xc6, 0x96, 0x61, 0x1e, 0x9a, 0x8b, 0x16, 0xe1, 0x1f, 0xc6, 0x72, 0xbe, 0xd8, 0x6b, 0x91, + 0x0f, 0x96, 0x2e, 0xcf, 0xb1, 0x6b, 0x90, 0xd4, 0x4e, 0x24, 0x74, 0xbb, 0xa6, 0x2d, 0xeb, 0x4c, + 0x27, 0x13, 0x7a, 0xcf, 0xf0, 0x46, 0x5d, 0x4e, 0x81, 0x59, 0x4f, 0xca, 0xc7, 0x5a, 0x54, 0x3f, + 0x07, 0xe5, 0xb7, 0xae, 0x84, 0xb2, 0x1f, 0xfb, 0x8e, 0x10, 0x60, 0x79, 0xfb, 0x3c, 0x96, 0xdf, + 0xbe, 0x1a, 0xcb, 0x21, 0x37, 0x01, 0x98, 0x0f, 0x2e, 0x04, 0x73, 0xe5, 0x9a, 0x60, 0x0e, 0x79, + 0x5c, 0x46, 0x73, 0xfd, 0x1c, 0x9a, 0xdf, 0xba, 0x12, 0xcd, 0xe1, 0x18, 0x3d, 0x38, 0x77, 0x2e, + 0x80, 0xf3, 0xbb, 0xd7, 0x82, 0x73, 0xc8, 0x59, 0x18, 0xcf, 0xea, 0x45, 0x78, 0x2e, 0x5f, 0x0f, + 0xcf, 0x21, 0x97, 0x61, 0x27, 0x35, 0x00, 0xc9, 0xbf, 0xdf, 0x85, 0xe0, 0xfb, 0xf6, 0xb7, 0x20, + 0xe1, 0x95, 0x1b, 0x41, 0xae, 0xa1, 0x56, 0x5b, 0x7b, 0xad, 0xbd, 0xfb, 0xda, 0x5e, 0xf5, 0x61, + 0xb3, 0x2b, 0x47, 0x90, 0x02, 0xeb, 0x1f, 0x55, 0x5b, 0x3d, 0x6d, 0xbb, 0xa3, 0x6a, 0xf7, 0xeb, + 0x5a, 0x6b, 0xaf, 0xd7, 0x54, 0x1f, 0x55, 0x77, 0x65, 0x01, 0xbd, 0x04, 0x48, 0xed, 0xd4, 0x1f, + 0x74, 0x1b, 0x35, 0xad, 0xde, 0x79, 0xb8, 0x5f, 0xad, 0xf7, 0x5a, 0x9d, 0x3d, 0x39, 0x8a, 0x24, + 0x10, 0x1b, 0x9d, 0xbd, 0xa6, 0x0c, 0x6f, 0x7f, 0x1a, 0x05, 0xb1, 0xf7, 0xd4, 0xc6, 0xe8, 0x8b, + 0x90, 0x3e, 0xd8, 0xeb, 0xee, 0x37, 0xeb, 0xad, 0xed, 0x56, 0xb3, 0x21, 0x47, 0xf2, 0x6b, 0xa7, + 0x67, 0xc5, 0x15, 0xba, 0x74, 0x30, 0x21, 0x36, 0x1e, 0x30, 0x68, 0xa3, 0x3c, 0x24, 0x6a, 0xd5, + 0xfa, 0x83, 0x83, 0x7d, 0x59, 0xc8, 0xe7, 0x4e, 0xcf, 0x8a, 0x40, 0x15, 0x38, 0xac, 0xd0, 0xab, + 0x90, 0x54, 0x9b, 0xdd, 0x5e, 0x47, 0x6d, 0xca, 0xd1, 0xfc, 0xca, 0xe9, 0x59, 0x31, 0x4d, 0x17, + 0x3d, 0xb4, 0xa0, 0x37, 0x21, 0xdb, 0xad, 0xef, 0x34, 0x1f, 0x56, 0xb5, 0xfa, 0x4e, 0x75, 0xef, + 0x7e, 0x53, 0x8e, 0xe5, 0xd7, 0x4f, 0xcf, 0x8a, 0x32, 0xd5, 0x09, 0x83, 0x80, 0xbe, 0xa2, 0xf5, + 0x70, 0xbf, 0xa3, 0xf6, 0x64, 0x71, 0xf1, 0x0a, 0x5e, 0x55, 0x54, 0x02, 0xe0, 0xd6, 0xdb, 0xcd, + 0x66, 0x43, 0x8e, 0xe7, 0xd1, 0xe9, 0x59, 0x31, 0x47, 0xd7, 0x17, 0xc5, 0x42, 0xaf, 0x43, 0xa6, + 0xae, 0x36, 0xab, 0xbd, 0xa6, 0xd6, 0xed, 0x55, 0x7b, 0x5d, 0x39, 0xb1, 0x88, 0x24, 0x54, 0x00, + 0x54, 0x86, 0xd5, 0xea, 0x41, 0xaf, 0xa3, 0x2d, 0xe9, 0x26, 0xf3, 0x2f, 0x9f, 0x9e, 0x15, 0xd7, + 0xa8, 0x6e, 0x75, 0xea, 0x5a, 0x21, 0xfd, 0xbc, 0xf4, 0xb3, 0x5f, 0x6d, 0x44, 0x7e, 0xfb, 0xeb, + 0x8d, 0x48, 0xad, 0xf8, 0xec, 0x9f, 0x1b, 0x91, 0x67, 0xf3, 0x0d, 0xe1, 0xb3, 0xf9, 0x86, 0xf0, + 0xd7, 0xf9, 0x86, 0xf0, 0x8f, 0xf9, 0x86, 0xf0, 0xf3, 0x7f, 0x6d, 0x44, 0x3e, 0x4e, 0xf0, 0x42, + 0xf7, 0x13, 0xec, 0xf3, 0xfc, 0x7b, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x45, 0xc5, 0x65, 0xa2, + 0x4f, 0x18, 0x00, 0x00, } diff --git a/pkg/jobs/jobspb/jobs.proto b/pkg/jobs/jobspb/jobs.proto index aeec8d1c2de1..0b48be0ded99 100644 --- a/pkg/jobs/jobspb/jobs.proto +++ b/pkg/jobs/jobspb/jobs.proto @@ -281,4 +281,5 @@ enum Type { IMPORT = 4 [(gogoproto.enumvalue_customname) = "TypeImport"]; CHANGEFEED = 5 [(gogoproto.enumvalue_customname) = "TypeChangefeed"]; CREATE_STATS = 6 [(gogoproto.enumvalue_customname) = "TypeCreateStats"]; + AUTO_CREATE_STATS = 7 [(gogoproto.enumvalue_customname) = "TypeAutoCreateStats"]; } diff --git a/pkg/jobs/jobspb/wrap.go b/pkg/jobs/jobspb/wrap.go index ca69434cfd37..c895f79e91ff 100644 --- a/pkg/jobs/jobspb/wrap.go +++ b/pkg/jobs/jobspb/wrap.go @@ -19,6 +19,7 @@ import ( "strings" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" + "github.com/cockroachdb/cockroach/pkg/sql/stats" ) // Details is a marker interface for job details proto structs. @@ -58,6 +59,10 @@ func DetailsType(d isPayload_Details) Type { case *Payload_Changefeed: return TypeChangefeed case *Payload_CreateStats: + createStatsName := d.(*Payload_CreateStats).CreateStats.Name + if createStatsName == stats.AutoStatsName { + return TypeAutoCreateStats + } return TypeCreateStats default: panic(fmt.Sprintf("Payload.Type called on a payload with an unknown details type: %T", d)) diff --git a/pkg/sql/create_stats.go b/pkg/sql/create_stats.go index fedc5947990d..4edc0056e91b 100644 --- a/pkg/sql/create_stats.go +++ b/pkg/sql/create_stats.go @@ -383,7 +383,7 @@ func checkRunningJobs(ctx context.Context, job *jobs.Job, p *planner) error { return err } - if payload.Type() == jobspb.TypeCreateStats { + if payload.Type() == jobspb.TypeCreateStats || payload.Type() == jobspb.TypeAutoCreateStats { id := (*int64)(row[0].(*tree.DInt)) if *id == jobID { break @@ -443,7 +443,7 @@ func (r *createStatsResumer) OnTerminal( func init() { jobs.AddResumeHook(func(typ jobspb.Type, settings *cluster.Settings) jobs.Resumer { - if typ != jobspb.TypeCreateStats { + if typ != jobspb.TypeCreateStats && typ != jobspb.TypeAutoCreateStats { return nil } return &createStatsResumer{} diff --git a/pkg/sql/opt/exec/execbuilder/relational_builder.go b/pkg/sql/opt/exec/execbuilder/relational_builder.go index 3cc4ef9bddf9..a310ab5cea06 100644 --- a/pkg/sql/opt/exec/execbuilder/relational_builder.go +++ b/pkg/sql/opt/exec/execbuilder/relational_builder.go @@ -1297,7 +1297,7 @@ func (b *Builder) buildInsert(ins *memo.InsertExpr) (execPlan, error) { colList := make(opt.ColList, 0, len(ins.InsertCols)+len(ins.CheckCols)) colList = appendColsWhenPresent(colList, ins.InsertCols) colList = appendColsWhenPresent(colList, ins.CheckCols) - input, err = b.ensureColumns(input, colList, nil, ins.ProvidedPhysical().Ordering) + input, err = b.ensureColumns(input, colList, nil, ins.Input.ProvidedPhysical().Ordering) if err != nil { return execPlan{}, err } @@ -1348,7 +1348,7 @@ func (b *Builder) buildUpdate(upd *memo.UpdateExpr) (execPlan, error) { colList = appendColsWhenPresent(colList, upd.FetchCols) colList = appendColsWhenPresent(colList, upd.UpdateCols) colList = appendColsWhenPresent(colList, upd.CheckCols) - input, err = b.ensureColumns(input, colList, nil, upd.ProvidedPhysical().Ordering) + input, err = b.ensureColumns(input, colList, nil, upd.Input.ProvidedPhysical().Ordering) if err != nil { return execPlan{}, err } @@ -1414,7 +1414,7 @@ func (b *Builder) buildUpsert(ups *memo.UpsertExpr) (execPlan, error) { colList = append(colList, ups.CanaryCol) } colList = appendColsWhenPresent(colList, ups.CheckCols) - input, err = b.ensureColumns(input, colList, nil, ups.ProvidedPhysical().Ordering) + input, err = b.ensureColumns(input, colList, nil, ups.Input.ProvidedPhysical().Ordering) if err != nil { return execPlan{}, err } @@ -1473,7 +1473,7 @@ func (b *Builder) buildDelete(del *memo.DeleteExpr) (execPlan, error) { // Upgrade execution engine to not require this. colList := make(opt.ColList, 0, len(del.FetchCols)) colList = appendColsWhenPresent(colList, del.FetchCols) - input, err = b.ensureColumns(input, colList, nil, del.ProvidedPhysical().Ordering) + input, err = b.ensureColumns(input, colList, nil, del.Input.ProvidedPhysical().Ordering) if err != nil { return execPlan{}, err } diff --git a/pkg/sql/opt/exec/execbuilder/testdata/insert b/pkg/sql/opt/exec/execbuilder/testdata/insert index 927f4f416b21..f455d2e2cc95 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/insert +++ b/pkg/sql/opt/exec/execbuilder/testdata/insert @@ -467,3 +467,30 @@ count · · () statement ok ROLLBACK + +# Regression test for #35564: make sure we use the Insert's input required +# ordering for the internal projection. + +statement ok +CREATE TABLE abc (a INT, b INT, c INT, INDEX(c) STORING(a,b)) + +statement ok +CREATE TABLE xyz (x INT, y INT, z INT) + +query TTTTT +EXPLAIN (VERBOSE) SELECT * FROM [INSERT INTO xyz SELECT a, b, c FROM abc RETURNING z] ORDER BY z +---- +render · · (z) +z + │ render 0 z · · + └── run · · (x, y, z, rowid[hidden]) · + └── insert · · (x, y, z, rowid[hidden]) · + │ into xyz(x, y, z, rowid) · · + │ strategy inserter · · + └── render · · (a, b, c, column9) +c + │ render 0 a · · + │ render 1 b · · + │ render 2 c · · + │ render 3 unique_rowid() · · + └── scan · · (a, b, c) +c +· table abc@abc_c_idx · · +· spans ALL · · diff --git a/pkg/sql/opt/exec/execbuilder/testdata/union b/pkg/sql/opt/exec/execbuilder/testdata/union index c0b956ebda19..71edebee0619 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/union +++ b/pkg/sql/opt/exec/execbuilder/testdata/union @@ -1,4 +1,4 @@ -# LogicTest: local-opt +# LogicTest: local-opt fakedist-opt statement ok CREATE TABLE uniontest ( @@ -101,3 +101,12 @@ render · · ("?column?", "?column? · row 0, expr 0 '' · · · row 0, expr 1 '' · · · row 0, expr 2 'x' · · + +statement ok +CREATE TABLE a (a INT PRIMARY KEY) + +# Regression test for #34524. This test is here because the issue still exists +# in the heuristic planner. +query I +(SELECT NULL FROM a) EXCEPT (VALUES((SELECT 1 FROM a LIMIT 1)), (1)) +---- diff --git a/pkg/sql/opt/exec/execbuilder/testdata/update b/pkg/sql/opt/exec/execbuilder/testdata/update index f2b6db8ca2c9..02ee30a15baf 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/update +++ b/pkg/sql/opt/exec/execbuilder/testdata/update @@ -296,3 +296,29 @@ Del /Table/57/1/1/1/1 Del /Table/57/1/1/2/1 fast path completed rows affected: 1 + +# Regression test for #35564: make sure we use the Update's input required +# ordering for the internal projection. + +statement ok +CREATE TABLE abc (a INT, b INT, c INT, INDEX(c) STORING(a,b)) + +query TTTTT +EXPLAIN (VERBOSE) SELECT * FROM [ UPDATE abc SET a=c RETURNING a ] ORDER BY a +---- +render · · (a) +a + │ render 0 a · · + └── run · · (a, b, c, rowid[hidden]) · + └── update · · (a, b, c, rowid[hidden]) · + │ table abc · · + │ set a · · + │ strategy updater · · + └── render · · (a, b, c, rowid, c) +c + │ render 0 a · · + │ render 1 b · · + │ render 2 c · · + │ render 3 rowid · · + │ render 4 c · · + └── scan · · (a, b, c, rowid[hidden]) +c +· table abc@abc_c_idx · · +· spans ALL · · diff --git a/pkg/sql/opt/exec/execbuilder/testdata/upsert b/pkg/sql/opt/exec/execbuilder/testdata/upsert index 1b6b5e2bc3d1..49ee92abe999 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/upsert +++ b/pkg/sql/opt/exec/execbuilder/testdata/upsert @@ -307,3 +307,38 @@ INSERT INTO t5 VALUES (1, 10, 9) ON CONFLICT (k) DO NOTHING statement ok INSERT INTO t5 VALUES (1, 10, 20) ON CONFLICT (k) DO NOTHING + +# Regression test for #35564: make sure we use the Upsert's input required +# ordering for the internal projection. + +statement ok +CREATE TABLE abc (a INT, b INT, c INT, INDEX(c) STORING(a,b)) + +statement ok +CREATE TABLE xyz (x INT, y INT, z INT) + +query TTTTT +EXPLAIN (VERBOSE) SELECT * FROM [UPSERT INTO xyz SELECT a, b, c FROM abc RETURNING z] ORDER BY z +---- +render · · (z) +z + │ render 0 z · · + └── run · · (x, y, z, rowid[hidden]) · + └── upsert · · (x, y, z, rowid[hidden]) · + │ into xyz(x, y, z, rowid) · · + │ strategy opt upserter · · + └── render · · (a, b, c, column9, a, b, c) +c + │ render 0 a · · + │ render 1 b · · + │ render 2 c · · + │ render 3 column9 · · + │ render 4 a · · + │ render 5 b · · + │ render 6 c · · + └── render · · (column9, a, b, c) +c + │ render 0 unique_rowid() · · + │ render 1 a · · + │ render 2 b · · + │ render 3 c · · + └── scan · · (a, b, c) +c +· table abc@abc_c_idx · · +· spans ALL · · diff --git a/pkg/sql/opt/norm/custom_funcs.go b/pkg/sql/opt/norm/custom_funcs.go index 967c2b04eb34..e518bf5c8443 100644 --- a/pkg/sql/opt/norm/custom_funcs.go +++ b/pkg/sql/opt/norm/custom_funcs.go @@ -658,32 +658,6 @@ func (c *CustomFuncs) AreProjectionsCorrelated( return false } -// ProjectColMapLeft returns a Projections operator that maps the left side -// columns in a SetPrivate to the output columns in it. Useful for replacing set -// operations with simpler constructs. -func (c *CustomFuncs) ProjectColMapLeft(set *memo.SetPrivate) memo.ProjectionsExpr { - return c.projectColMapSide(set.OutCols, set.LeftCols) -} - -// ProjectColMapRight returns a Project operator that maps the right side -// columns in a SetPrivate to the output columns in it. Useful for replacing set -// operations with simpler constructs. -func (c *CustomFuncs) ProjectColMapRight(set *memo.SetPrivate) memo.ProjectionsExpr { - return c.projectColMapSide(set.OutCols, set.RightCols) -} - -// projectColMapSide implements the side-agnostic logic from ProjectColMapLeft -// and ProjectColMapRight. -func (c *CustomFuncs) projectColMapSide(toList, fromList opt.ColList) memo.ProjectionsExpr { - items := make(memo.ProjectionsExpr, len(toList)) - for idx, fromCol := range fromList { - toCol := toList[idx] - items[idx].Element = c.f.ConstructVariable(fromCol) - items[idx].Col = toCol - } - return items -} - // MakeEmptyColSet returns a column set with no columns in it. func (c *CustomFuncs) MakeEmptyColSet() opt.ColSet { return opt.ColSet{} @@ -885,6 +859,39 @@ func (c *CustomFuncs) ZipOuterCols(zip memo.ZipExpr) opt.ColSet { return colSet } +// ---------------------------------------------------------------------- +// +// Set Rules +// Custom match and replace functions used with set.opt rules. +// +// ---------------------------------------------------------------------- + +// ProjectColMapLeft returns a Projections operator that maps the left side +// columns in a SetPrivate to the output columns in it. Useful for replacing set +// operations with simpler constructs. +func (c *CustomFuncs) ProjectColMapLeft(set *memo.SetPrivate) memo.ProjectionsExpr { + return c.projectColMapSide(set.OutCols, set.LeftCols) +} + +// ProjectColMapRight returns a Project operator that maps the right side +// columns in a SetPrivate to the output columns in it. Useful for replacing set +// operations with simpler constructs. +func (c *CustomFuncs) ProjectColMapRight(set *memo.SetPrivate) memo.ProjectionsExpr { + return c.projectColMapSide(set.OutCols, set.RightCols) +} + +// projectColMapSide implements the side-agnostic logic from ProjectColMapLeft +// and ProjectColMapRight. +func (c *CustomFuncs) projectColMapSide(toList, fromList opt.ColList) memo.ProjectionsExpr { + items := make(memo.ProjectionsExpr, len(toList)) + for idx, fromCol := range fromList { + toCol := toList[idx] + items[idx].Element = c.f.ConstructVariable(fromCol) + items[idx].Col = toCol + } + return items +} + // ---------------------------------------------------------------------- // // Boolean Rules diff --git a/pkg/sql/opt/norm/rules/select.opt b/pkg/sql/opt/norm/rules/select.opt index 868693c87706..a7f36d05c048 100644 --- a/pkg/sql/opt/norm/rules/select.opt +++ b/pkg/sql/opt/norm/rules/select.opt @@ -344,33 +344,3 @@ $input (RemoveFiltersItem $filters $item) ) - -# EliminateUnionAllLeft replaces a union all with a right side having a -# cardinality of zero, with just the left side operand. -[EliminateUnionAllLeft, Normalize] -(UnionAll - $left:* - $right:* & (HasZeroRows $right) - $colmap:* -) -=> -(Project - $left - (ProjectColMapLeft $colmap) - (MakeEmptyColSet) -) - -# EliminateUnionAllRight replaces a union all with a left side having a -# cardinality of zero, with just the right side operand. -[EliminateUnionAllRight, Normalize] -(UnionAll - $left:* & (HasZeroRows $left) - $right:* - $colmap:* -) -=> -(Project - $right - (ProjectColMapRight $colmap) - (MakeEmptyColSet) -) diff --git a/pkg/sql/opt/norm/rules/set.opt b/pkg/sql/opt/norm/rules/set.opt new file mode 100644 index 000000000000..465d5aaf69a0 --- /dev/null +++ b/pkg/sql/opt/norm/rules/set.opt @@ -0,0 +1,33 @@ +# ============================================================================= +# set.opt contains normalization rules for set operators. +# ============================================================================= + +# EliminateUnionAllLeft replaces a union all with a right side having a +# cardinality of zero, with just the left side operand. +[EliminateUnionAllLeft, Normalize] +(UnionAll + $left:* + $right:* & (HasZeroRows $right) + $colmap:* +) +=> +(Project + $left + (ProjectColMapLeft $colmap) + (MakeEmptyColSet) +) + +# EliminateUnionAllRight replaces a union all with a left side having a +# cardinality of zero, with just the right side operand. +[EliminateUnionAllRight, Normalize] +(UnionAll + $left:* & (HasZeroRows $left) + $right:* + $colmap:* +) +=> +(Project + $right + (ProjectColMapRight $colmap) + (MakeEmptyColSet) +) diff --git a/pkg/sql/opt/norm/testdata/rules/select b/pkg/sql/opt/norm/testdata/rules/select index 09e5193352ee..7bb59784b516 100644 --- a/pkg/sql/opt/norm/testdata/rules/select +++ b/pkg/sql/opt/norm/testdata/rules/select @@ -1133,51 +1133,3 @@ values ├── cardinality: [0 - 0] ├── key: () └── fd: ()-->(1) - -# -------------------------------------------------- -# EliminateUnionAllLeft -# -------------------------------------------------- - -opt expect=EliminateUnionAllLeft -SELECT k FROM - (SELECT k FROM b) - UNION ALL - (SELECT k FROM b WHERE k IN ()) ----- -project - ├── columns: k:11(int) - ├── scan b - │ ├── columns: b.k:1(int!null) - │ └── key: (1) - └── projections - └── variable: b.k [type=int, outer=(1)] - -# -------------------------------------------------- -# EliminateUnionAllRight -# -------------------------------------------------- - -opt expect=EliminateUnionAllRight -SELECT k FROM - (SELECT k FROM b WHERE Null) - UNION ALL - (SELECT k FROM b) ----- -project - ├── columns: k:11(int) - ├── scan b - │ ├── columns: b.k:6(int!null) - │ └── key: (6) - └── projections - └── variable: b.k [type=int, outer=(6)] - -opt -SELECT k FROM - (SELECT k FROM b WHERE False) - UNION ALL - (SELECT k FROM b WHERE i IN ()) ----- -values - ├── columns: k:11(int) - ├── cardinality: [0 - 0] - ├── key: () - └── fd: ()-->(11) diff --git a/pkg/sql/opt/norm/testdata/rules/set b/pkg/sql/opt/norm/testdata/rules/set new file mode 100644 index 000000000000..660ea2b5f0e2 --- /dev/null +++ b/pkg/sql/opt/norm/testdata/rules/set @@ -0,0 +1,59 @@ +exec-ddl +CREATE TABLE b (k INT PRIMARY KEY, i INT, f FLOAT, s STRING NOT NULL, j JSON) +---- +TABLE b + ├── k int not null + ├── i int + ├── f float + ├── s string not null + ├── j jsonb + └── INDEX primary + └── k int not null + +# -------------------------------------------------- +# EliminateUnionAllLeft +# -------------------------------------------------- + +opt expect=EliminateUnionAllLeft +SELECT k FROM + (SELECT k FROM b) + UNION ALL + (SELECT k FROM b WHERE k IN ()) +---- +project + ├── columns: k:11(int) + ├── scan b + │ ├── columns: b.k:1(int!null) + │ └── key: (1) + └── projections + └── variable: b.k [type=int, outer=(1)] + +# -------------------------------------------------- +# EliminateUnionAllRight +# -------------------------------------------------- + +opt expect=EliminateUnionAllRight +SELECT k FROM + (SELECT k FROM b WHERE Null) + UNION ALL + (SELECT k FROM b) +---- +project + ├── columns: k:11(int) + ├── scan b + │ ├── columns: b.k:6(int!null) + │ └── key: (6) + └── projections + └── variable: b.k [type=int, outer=(6)] + +opt +SELECT k FROM + (SELECT k FROM b WHERE False) + UNION ALL + (SELECT k FROM b WHERE i IN ()) +---- +values + ├── columns: k:11(int) + ├── cardinality: [0 - 0] + ├── key: () + └── fd: ()-->(11) diff --git a/pkg/sql/opt/ops/relational.opt b/pkg/sql/opt/ops/relational.opt index 783a461bba06..f9a8e91c736f 100644 --- a/pkg/sql/opt/ops/relational.opt +++ b/pkg/sql/opt/ops/relational.opt @@ -605,6 +605,9 @@ define Union { # Left: [2, 1] # Right: [4, 3] # Out: [5, 6] <-- synthesized output columns +# +# To make normalization rules and execution simpler, both inputs to the set op +# must have matching types. [Private] define SetPrivate { LeftCols ColList diff --git a/pkg/sql/opt/optbuilder/scope.go b/pkg/sql/opt/optbuilder/scope.go index 59fe77cf33b3..45adb69f20ba 100644 --- a/pkg/sql/opt/optbuilder/scope.go +++ b/pkg/sql/opt/optbuilder/scope.go @@ -135,29 +135,38 @@ func (s *scope) replace() *scope { } // appendColumnsFromScope adds newly bound variables to this scope. -// The groups in the new columns are reset to 0. +// The expressions in the new columns are reset to nil. func (s *scope) appendColumnsFromScope(src *scope) { l := len(s.cols) s.cols = append(s.cols, src.cols...) - // We want to reset the groups, as these become pass-through columns in the - // new scope. + // We want to reset the expressions, as these become pass-through columns in + // the new scope. for i := l; i < len(s.cols); i++ { s.cols[i].scalar = nil } } // appendColumns adds newly bound variables to this scope. -// The groups in the new columns are reset to 0. +// The expressions in the new columns are reset to nil. func (s *scope) appendColumns(cols []scopeColumn) { l := len(s.cols) s.cols = append(s.cols, cols...) - // We want to reset the groups, as these become pass-through columns in the - // new scope. + // We want to reset the expressions, as these become pass-through columns in + // the new scope. for i := l; i < len(s.cols); i++ { s.cols[i].scalar = nil } } +// appendColumn adds a newly bound variable to this scope. +// The expression in the new column is reset to nil. +func (s *scope) appendColumn(col *scopeColumn) { + s.cols = append(s.cols, *col) + // We want to reset the expression, as this becomes a pass-through column in + // the new scope. + s.cols[len(s.cols)-1].scalar = nil +} + // addExtraColumns adds the given columns as extra columns, ignoring any // duplicate columns that are already in the scope. func (s *scope) addExtraColumns(cols []scopeColumn) { diff --git a/pkg/sql/opt/optbuilder/testdata/union b/pkg/sql/opt/optbuilder/testdata/union index 8c186fa0e8e3..dd95d4dfa02c 100644 --- a/pkg/sql/opt/optbuilder/testdata/union +++ b/pkg/sql/opt/optbuilder/testdata/union @@ -286,12 +286,17 @@ sort ├── ordering: +3 └── union-all ├── columns: column1:3(int) - ├── left columns: column1:1(unknown) + ├── left columns: column1:4(int) ├── right columns: column1:2(int) - ├── values - │ ├── columns: column1:1(unknown) - │ └── tuple [type=tuple{unknown}] - │ └── null [type=unknown] + ├── project + │ ├── columns: column1:4(int) + │ ├── values + │ │ ├── columns: column1:1(unknown) + │ │ └── tuple [type=tuple{unknown}] + │ │ └── null [type=unknown] + │ └── projections + │ └── cast: INT8 [type=int] + │ └── variable: column1 [type=unknown] └── values ├── columns: column1:2(int) └── tuple [type=tuple{int}] @@ -317,18 +322,23 @@ build SELECT x, pg_typeof(y) FROM (SELECT 1 AS a, NULL AS b UNION ALL SELECT 2 AS a, 4 AS b) AS t(x, y) ---- project - ├── columns: x:5(int!null) pg_typeof:7(string) + ├── columns: x:5(int!null) pg_typeof:8(string) ├── union-all │ ├── columns: a:5(int!null) b:6(int) - │ ├── left columns: a:1(int) b:2(unknown) + │ ├── left columns: a:1(int) b:7(int) │ ├── right columns: a:3(int) b:4(int) │ ├── project - │ │ ├── columns: a:1(int!null) b:2(unknown) - │ │ ├── values - │ │ │ └── tuple [type=tuple] + │ │ ├── columns: b:7(int) a:1(int!null) + │ │ ├── project + │ │ │ ├── columns: a:1(int!null) b:2(unknown) + │ │ │ ├── values + │ │ │ │ └── tuple [type=tuple] + │ │ │ └── projections + │ │ │ ├── const: 1 [type=int] + │ │ │ └── null [type=unknown] │ │ └── projections - │ │ ├── const: 1 [type=int] - │ │ └── null [type=unknown] + │ │ └── cast: INT8 [type=int] + │ │ └── variable: b [type=unknown] │ └── project │ ├── columns: a:3(int!null) b:4(int!null) │ ├── values @@ -344,11 +354,11 @@ build SELECT x, pg_typeof(y) FROM (SELECT 1 AS a, 3 AS b UNION ALL SELECT 2 AS a, NULL AS b) AS t(x, y) ---- project - ├── columns: x:5(int!null) pg_typeof:7(string) + ├── columns: x:5(int!null) pg_typeof:8(string) ├── union-all │ ├── columns: a:5(int!null) b:6(int) │ ├── left columns: a:1(int) b:2(int) - │ ├── right columns: a:3(int) b:4(unknown) + │ ├── right columns: a:3(int) b:7(int) │ ├── project │ │ ├── columns: a:1(int!null) b:2(int!null) │ │ ├── values @@ -357,12 +367,17 @@ project │ │ ├── const: 1 [type=int] │ │ └── const: 3 [type=int] │ └── project - │ ├── columns: a:3(int!null) b:4(unknown) - │ ├── values - │ │ └── tuple [type=tuple] + │ ├── columns: b:7(int) a:3(int!null) + │ ├── project + │ │ ├── columns: a:3(int!null) b:4(unknown) + │ │ ├── values + │ │ │ └── tuple [type=tuple] + │ │ └── projections + │ │ ├── const: 2 [type=int] + │ │ └── null [type=unknown] │ └── projections - │ ├── const: 2 [type=int] - │ └── null [type=unknown] + │ └── cast: INT8 [type=int] + │ └── variable: b [type=unknown] └── projections └── function: pg_typeof [type=string] └── variable: b [type=int] @@ -839,3 +854,166 @@ except ├── columns: a:5(string) b:6(string!null) c:7(string!null) └── scan abc └── columns: a:5(string) b:6(string!null) c:7(string!null) rowid:8(int!null) + +# Tests for type propagation. + +build +VALUES (NULL, NULL), (NULL, 'x') UNION VALUES (1, 'a'), (2, 'b') +---- +union + ├── columns: column1:5(int) column2:6(string) + ├── left columns: column1:7(int) column2:2(string) + ├── right columns: column1:3(int) column2:4(string) + ├── project + │ ├── columns: column1:7(int) column2:2(string) + │ ├── values + │ │ ├── columns: column1:1(unknown) column2:2(string) + │ │ ├── tuple [type=tuple{unknown, string}] + │ │ │ ├── null [type=unknown] + │ │ │ └── null [type=unknown] + │ │ └── tuple [type=tuple{unknown, string}] + │ │ ├── null [type=unknown] + │ │ └── const: 'x' [type=string] + │ └── projections + │ └── cast: INT8 [type=int] + │ └── variable: column1 [type=unknown] + └── values + ├── columns: column1:3(int) column2:4(string) + ├── tuple [type=tuple{int, string}] + │ ├── const: 1 [type=int] + │ └── const: 'a' [type=string] + └── tuple [type=tuple{int, string}] + ├── const: 2 [type=int] + └── const: 'b' [type=string] + +build +VALUES (3, NULL), (NULL, 'x') INTERSECT VALUES (1, NULL), (2, NULL) +---- +intersect + ├── columns: column1:1(int) column2:2(string) + ├── left columns: column1:1(int) column2:2(string) + ├── right columns: column1:3(int) column2:5(string) + ├── values + │ ├── columns: column1:1(int) column2:2(string) + │ ├── tuple [type=tuple{int, string}] + │ │ ├── const: 3 [type=int] + │ │ └── null [type=unknown] + │ └── tuple [type=tuple{int, string}] + │ ├── null [type=unknown] + │ └── const: 'x' [type=string] + └── project + ├── columns: column2:5(string) column1:3(int) + ├── values + │ ├── columns: column1:3(int) column2:4(unknown) + │ ├── tuple [type=tuple{int, unknown}] + │ │ ├── const: 1 [type=int] + │ │ └── null [type=unknown] + │ └── tuple [type=tuple{int, unknown}] + │ ├── const: 2 [type=int] + │ └── null [type=unknown] + └── projections + └── cast: STRING [type=string] + └── variable: column2 [type=unknown] + +build +VALUES (NULL, NULL), (NULL, 'x') UNION ALL VALUES (1, NULL), (2, NULL) +---- +union-all + ├── columns: column1:5(int) column2:6(string) + ├── left columns: column1:7(int) column2:2(string) + ├── right columns: column1:3(int) column2:8(string) + ├── project + │ ├── columns: column1:7(int) column2:2(string) + │ ├── values + │ │ ├── columns: column1:1(unknown) column2:2(string) + │ │ ├── tuple [type=tuple{unknown, string}] + │ │ │ ├── null [type=unknown] + │ │ │ └── null [type=unknown] + │ │ └── tuple [type=tuple{unknown, string}] + │ │ ├── null [type=unknown] + │ │ └── const: 'x' [type=string] + │ └── projections + │ └── cast: INT8 [type=int] + │ └── variable: column1 [type=unknown] + └── project + ├── columns: column2:8(string) column1:3(int) + ├── values + │ ├── columns: column1:3(int) column2:4(unknown) + │ ├── tuple [type=tuple{int, unknown}] + │ │ ├── const: 1 [type=int] + │ │ └── null [type=unknown] + │ └── tuple [type=tuple{int, unknown}] + │ ├── const: 2 [type=int] + │ └── null [type=unknown] + └── projections + └── cast: STRING [type=string] + └── variable: column2 [type=unknown] + +build +VALUES (NULL, NULL), (NULL, NULL) UNION ALL VALUES (NULL, NULL), (NULL, NULL) +---- +union-all + ├── columns: column1:5(unknown) column2:6(unknown) + ├── left columns: column1:1(unknown) column2:2(unknown) + ├── right columns: column1:3(unknown) column2:4(unknown) + ├── values + │ ├── columns: column1:1(unknown) column2:2(unknown) + │ ├── tuple [type=tuple{unknown, unknown}] + │ │ ├── null [type=unknown] + │ │ └── null [type=unknown] + │ └── tuple [type=tuple{unknown, unknown}] + │ ├── null [type=unknown] + │ └── null [type=unknown] + └── values + ├── columns: column1:3(unknown) column2:4(unknown) + ├── tuple [type=tuple{unknown, unknown}] + │ ├── null [type=unknown] + │ └── null [type=unknown] + └── tuple [type=tuple{unknown, unknown}] + ├── null [type=unknown] + └── null [type=unknown] + +exec-ddl +CREATE TABLE a (a INT PRIMARY KEY) +---- +TABLE a + ├── a int not null + └── INDEX primary + └── a int not null + +# Regression test for #34524. +build +(SELECT NULL FROM a) EXCEPT (VALUES((SELECT 1 FROM a LIMIT 1)), (1)) +---- +except + ├── columns: "?column?":6(int) + ├── left columns: "?column?":6(int) + ├── right columns: column1:5(int) + ├── project + │ ├── columns: "?column?":6(int) + │ ├── project + │ │ ├── columns: "?column?":2(unknown) + │ │ ├── scan a + │ │ │ └── columns: a:1(int!null) + │ │ └── projections + │ │ └── null [type=unknown] + │ └── projections + │ └── cast: INT8 [type=int] + │ └── variable: ?column? [type=unknown] + └── values + ├── columns: column1:5(int) + ├── tuple [type=tuple{int}] + │ └── subquery [type=int] + │ └── max1-row + │ ├── columns: "?column?":4(int!null) + │ └── limit + │ ├── columns: "?column?":4(int!null) + │ ├── project + │ │ ├── columns: "?column?":4(int!null) + │ │ ├── scan a + │ │ │ └── columns: a:3(int!null) + │ │ └── projections + │ │ └── const: 1 [type=int] + │ └── const: 1 [type=int] + └── tuple [type=tuple{int}] + └── const: 1 [type=int] diff --git a/pkg/sql/opt/optbuilder/union.go b/pkg/sql/opt/optbuilder/union.go index 9f117ad83537..a27d1ed9cf01 100644 --- a/pkg/sql/opt/optbuilder/union.go +++ b/pkg/sql/opt/optbuilder/union.go @@ -17,6 +17,7 @@ package optbuilder import ( "fmt" + "github.com/cockroachdb/cockroach/pkg/sql/coltypes" "github.com/cockroachdb/cockroach/pkg/sql/opt" "github.com/cockroachdb/cockroach/pkg/sql/opt/memo" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" @@ -49,7 +50,6 @@ func (b *Builder) buildUnion( } outScope = inScope.push() - outScope.appendColumnsFromScope(leftScope) // newColsNeeded indicates whether or not we need to synthesize output // columns. This is always required for a UNION, because the output columns @@ -57,21 +57,21 @@ func (b *Builder) buildUnion( // synthesize new columns to contain these values. This is not necessary for // INTERSECT or EXCEPT, since these operations are basically filters on the // left relation. - // - // Another benefit to synthesizing new columns is to handle the case - // when the type of one of the columns in the left relation is unknown, but - // the type of the matching column in the right relation is known. - // For example: - // SELECT NULL UNION SELECT 1 - // The type of NULL is unknown, and the type of 1 is int. We need to - // synthesize a new column so the output column will have the correct type. newColsNeeded := clause.Type == tree.UnionOp if newColsNeeded { - // Create a new scope to hold the new synthesized columns. - outScope = outScope.push() outScope.cols = make([]scopeColumn, 0, len(leftScope.cols)) } + // propagateTypesLeft/propagateTypesRight indicate whether we need to wrap + // the left/right side in a projection to cast some of the columns to the + // correct type. + // For example: + // SELECT NULL UNION SELECT 1 + // The type of NULL is unknown, and the type of 1 is int. We need to + // wrap the left side in a project operation with a Cast expression so the + // output column will have the correct type. + var propagateTypesLeft, propagateTypesRight bool + // Build map from left columns to right columns. for i := range leftScope.cols { l := &leftScope.cols[i] @@ -88,18 +88,31 @@ func (b *Builder) buildUnion( panic(fmt.Errorf("%v types cannot be matched", clause.Type)) } - if newColsNeeded { - var typ types.T - if l.typ != types.Unknown { - typ = l.typ - } else { - typ = r.typ + var typ types.T + if l.typ != types.Unknown { + typ = l.typ + if r.typ == types.Unknown { + propagateTypesRight = true } + } else { + typ = r.typ + if r.typ != types.Unknown { + propagateTypesLeft = true + } + } + if newColsNeeded { b.synthesizeColumn(outScope, string(l.name), typ, nil, nil /* scalar */) } } + if propagateTypesLeft { + leftScope = b.propagateTypes(leftScope, rightScope) + } + if propagateTypesRight { + rightScope = b.propagateTypes(rightScope, leftScope) + } + // Create the mapping between the left-side columns, right-side columns and // new columns (if needed). leftCols := colsToColList(leftScope.cols) @@ -108,6 +121,7 @@ func (b *Builder) buildUnion( if newColsNeeded { newCols = colsToColList(outScope.cols) } else { + outScope.appendColumnsFromScope(leftScope) newCols = leftCols } @@ -137,3 +151,32 @@ func (b *Builder) buildUnion( return outScope } + +// propagateTypes propagates the types of the source columns to the destination +// columns by wrapping the destination in a Project operation. The Project +// operation passes through columns that already have the correct type, and +// creates cast expressions for those that don't. +func (b *Builder) propagateTypes(dst, src *scope) *scope { + expr := dst.expr.(memo.RelExpr) + dstCols := dst.cols + + dst = dst.push() + dst.cols = make([]scopeColumn, 0, len(dstCols)) + + for i := 0; i < len(dstCols); i++ { + dstType := dstCols[i].typ + srcType := src.cols[i].typ + if dstType == types.Unknown && srcType != types.Unknown { + // Create a new column which casts the old column to the correct type. + colType, _ := coltypes.DatumTypeToColumnType(srcType) + castExpr := b.factory.ConstructCast(b.factory.ConstructVariable(dstCols[i].id), colType) + b.synthesizeColumn(dst, string(dstCols[i].name), srcType, nil /* expr */, castExpr) + } else { + // The column is already the correct type, so add it as a passthrough + // column. + dst.appendColumn(&dstCols[i]) + } + } + dst.expr = b.constructProject(expr, dst.cols) + return dst +} diff --git a/pkg/sql/opt/optgen/exprgen/testdata/join b/pkg/sql/opt/optgen/exprgen/testdata/join index 72a44b63f45c..94d66d22cac6 100644 --- a/pkg/sql/opt/optgen/exprgen/testdata/join +++ b/pkg/sql/opt/optgen/exprgen/testdata/join @@ -66,7 +66,7 @@ left-join (lookup abc@ab) ├── columns: t.public.abc.a:5(int) t.public.abc.b:6(int) ├── key columns: [5] = [5] ├── stats: [rows=333333.333] - ├── cost: 355060.02 + ├── cost: 358393.353 ├── scan t.public.def │ ├── columns: t.public.def.d:1(int) t.public.def.e:2(int) │ ├── stats: [rows=1000] diff --git a/pkg/sql/opt/xform/coster.go b/pkg/sql/opt/xform/coster.go index 95a316922567..ebf5e9722ec1 100644 --- a/pkg/sql/opt/xform/coster.go +++ b/pkg/sql/opt/xform/coster.go @@ -363,6 +363,33 @@ func (c *coster) computeLookupJoinCost(join *memo.LookupJoinExpr) memo.Cost { // cost of emitting the rows. numLookupCols := join.Cols.Difference(join.Input.Relational().OutputCols).Len() perRowCost := seqIOCostFactor + c.rowScanCost(join.Table, join.Index, numLookupCols) + + // Add a cost if we have to evaluate an ON condition on every row. The more + // leftover conditions, the more expensive it should be. We want to + // differentiate between two lookup joins where one uses only a subset of the + // columns. For example: + // abc JOIN xyz ON a=x AND b=y + // We could have a lookup join using an index on y (and left-over condition + // a=x), and another lookup join on an index on x,y. The latter is definitely + // preferable (the former could generate a lot of internal results that are + // then discarded). + // + // TODO(radu): we should take into account that the "internal" row count is + // higher, according to the selectivities of the conditions. Unfortunately + // this is very tricky, in particular because of left-over conditions that are + // not selective. + // For example: + // ab JOIN xy ON a=x AND x=10 + // becomes (during normalization): + // ab JOIN xy ON a=x AND a=10 AND x=10 + // which can become a lookup join with left-over condition x=10 which doesn't + // actually filter anything. + // + // TODO(radu): this should be extended to all join types. It's tricky for hash + // joins where we don't have the equality and leftover filters readily + // available. + perRowCost += cpuCostFactor * memo.Cost(len(join.On)) + cost += memo.Cost(join.Relational().Stats.RowCount) * perRowCost return cost } diff --git a/pkg/sql/opt/xform/testdata/coster/join b/pkg/sql/opt/xform/testdata/coster/join index 09417b25aa97..7e47f37927eb 100644 --- a/pkg/sql/opt/xform/testdata/coster/join +++ b/pkg/sql/opt/xform/testdata/coster/join @@ -166,3 +166,158 @@ index-join abc ├── cost: 10.306 ├── key: (1) └── fd: ()-->(3) + +# Regression test for #34810: make sure we pick the lookup join that uses +# all equality columns. + +exec-ddl +CREATE TABLE abcde ( + a TEXT NOT NULL, + b UUID NOT NULL, + c UUID NOT NULL, + d VARCHAR(255) NOT NULL, + e TEXT NOT NULL, + CONSTRAINT "primary" PRIMARY KEY (a, b, c), + UNIQUE INDEX idx_abd (a, b, d), + UNIQUE INDEX idx_abcd (a, b, c, d) +) +---- +TABLE abcde + ├── a string not null + ├── b uuid not null + ├── c uuid not null + ├── d string not null + ├── e string not null + ├── INDEX primary + │ ├── a string not null + │ ├── b uuid not null + │ └── c uuid not null + ├── INDEX idx_abd + │ ├── a string not null + │ ├── b uuid not null + │ ├── d string not null + │ └── c uuid not null (storing) + └── INDEX idx_abcd + ├── a string not null + ├── b uuid not null + ├── c uuid not null + └── d string not null + +exec-ddl +ALTER TABLE abcde INJECT STATISTICS '[ + { + "columns": ["a"], + "created_at": "2019-02-08 04:10:40.001179+00:00", + "row_count": 250000, + "distinct_count": 1 + }, + { + "columns": ["b"], + "created_at": "2019-02-08 04:10:40.119954+00:00", + "row_count": 250000, + "distinct_count": 2 + }, + { + "columns": ["d"], + "created_at": "2019-02-08 04:10:40.119954+00:00", + "row_count": 250000, + "distinct_count": 125000 + } +]' +---- + +exec-ddl +CREATE TABLE wxyz ( + w TEXT NOT NULL, + x UUID NOT NULL, + y UUID NOT NULL, + z TEXT NOT NULL, + CONSTRAINT "primary" PRIMARY KEY (w, x, y), + CONSTRAINT "foreign" FOREIGN KEY (w, x, y) REFERENCES abcde (a, b, c) +) +---- +TABLE wxyz + ├── w string not null + ├── x uuid not null + ├── y uuid not null + ├── z string not null + ├── INDEX primary + │ ├── w string not null + │ ├── x uuid not null + │ └── y uuid not null + └── FOREIGN KEY (w, x, y) REFERENCES t.public.abcde (a, b, c) + +exec-ddl +ALTER TABLE wxyz INJECT STATISTICS '[ + { + "columns": ["w"], + "created_at": "2019-02-08 04:10:40.001179+00:00", + "row_count": 10000, + "distinct_count": 1 + }, + { + "columns": ["x"], + "created_at": "2019-02-08 04:10:40.119954+00:00", + "row_count": 10000, + "distinct_count": 1 + }, + { + "columns": ["y"], + "created_at": "2019-02-08 04:10:40.119954+00:00", + "row_count": 10000, + "distinct_count": 2500 + } +]' +---- + +opt +SELECT w, x, y, z +FROM wxyz +INNER JOIN abcde +ON w = a AND x = b AND y = c +WHERE w = 'foo' AND x = '2AB23800-06B1-4E19-A3BB-DF3768B808D2' +ORDER BY d +LIMIT 10 +---- +project + ├── columns: w:1(string!null) x:2(uuid!null) y:3(uuid!null) z:4(string!null) [hidden: d:8(string!null)] + ├── cardinality: [0 - 10] + ├── stats: [rows=10] + ├── cost: 122481.301 + ├── key: (8) + ├── fd: ()-->(1,2), (3)-->(4,8), (8)-->(3,4) + ├── ordering: +8 opt(1,2) [actual: +8] + └── limit + ├── columns: w:1(string!null) x:2(uuid!null) y:3(uuid!null) z:4(string!null) a:5(string!null) b:6(uuid!null) c:7(uuid!null) d:8(string!null) + ├── internal-ordering: +8 opt(1,2,5,6) + ├── cardinality: [0 - 10] + ├── stats: [rows=10] + ├── cost: 122481.191 + ├── key: (7) + ├── fd: ()-->(1,2,5,6), (3)-->(4), (7)-->(8), (8)-->(7), (1)==(5), (5)==(1), (2)==(6), (6)==(2), (3)==(7), (7)==(3) + ├── ordering: +8 opt(1,2,5,6) [actual: +8] + ├── sort + │ ├── columns: w:1(string!null) x:2(uuid!null) y:3(uuid!null) z:4(string!null) a:5(string!null) b:6(uuid!null) c:7(uuid!null) d:8(string!null) + │ ├── stats: [rows=50048.8759, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=2500, null(3)=0, distinct(4)=1000, null(4)=0, distinct(5)=1, null(5)=0, distinct(6)=1, null(6)=0, distinct(7)=2500, null(7)=0, distinct(8)=38781.1698, null(8)=0] + │ ├── cost: 122481.081 + │ ├── key: (7) + │ ├── fd: ()-->(1,2,5,6), (3)-->(4), (7)-->(8), (8)-->(7), (1)==(5), (5)==(1), (2)==(6), (6)==(2), (3)==(7), (7)==(3) + │ ├── ordering: +8 opt(1,2,5,6) [actual: +8] + │ └── inner-join (lookup abcde@idx_abcd) + │ ├── columns: w:1(string!null) x:2(uuid!null) y:3(uuid!null) z:4(string!null) a:5(string!null) b:6(uuid!null) c:7(uuid!null) d:8(string!null) + │ ├── key columns: [1 2 3] = [5 6 7] + │ ├── stats: [rows=50048.8759, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=2500, null(3)=0, distinct(4)=1000, null(4)=0, distinct(5)=1, null(5)=0, distinct(6)=1, null(6)=0, distinct(7)=2500, null(7)=0, distinct(8)=38781.1698, null(8)=0] + │ ├── cost: 105853.783 + │ ├── key: (7) + │ ├── fd: ()-->(1,2,5,6), (3)-->(4), (7)-->(8), (8)-->(7), (1)==(5), (5)==(1), (2)==(6), (6)==(2), (3)==(7), (7)==(3) + │ ├── scan wxyz + │ │ ├── columns: w:1(string!null) x:2(uuid!null) y:3(uuid!null) z:4(string!null) + │ │ ├── constraint: /1/2/3: [/'foo'/'2ab23800-06b1-4e19-a3bb-df3768b808d2' - /'foo'/'2ab23800-06b1-4e19-a3bb-df3768b808d2'] + │ │ ├── stats: [rows=10000, distinct(1)=1, null(1)=0, distinct(2)=1, null(2)=0, distinct(3)=2500, null(3)=0, distinct(4)=1000, null(4)=0] + │ │ ├── cost: 10800.01 + │ │ ├── key: (3) + │ │ └── fd: ()-->(1,2), (3)-->(4) + │ └── filters + │ ├── a = 'foo' [type=bool, outer=(5), constraints=(/5: [/'foo' - /'foo']; tight), fd=()-->(5)] + │ └── b = '2ab23800-06b1-4e19-a3bb-df3768b808d2' [type=bool, outer=(6), constraints=(/6: [/'2ab23800-06b1-4e19-a3bb-df3768b808d2' - /'2ab23800-06b1-4e19-a3bb-df3768b808d2']; tight), fd=()-->(6)] + └── const: 10 [type=int] diff --git a/pkg/sql/opt/xform/testdata/coster/zone b/pkg/sql/opt/xform/testdata/coster/zone index 26432a72067a..3eb9e44ce7bc 100644 --- a/pkg/sql/opt/xform/testdata/coster/zone +++ b/pkg/sql/opt/xform/testdata/coster/zone @@ -317,7 +317,7 @@ inner-join (lookup xy@y2) ├── flags: no-merge-join;no-hash-join ├── key columns: [2] = [5] ├── stats: [rows=98.01, distinct(1)=9.9, null(1)=0, distinct(2)=1, null(2)=0, distinct(4)=9.9, null(4)=0, distinct(5)=1, null(5)=0] - ├── cost: 152.0444 + ├── cost: 153.0245 ├── key: (1,4) ├── fd: ()-->(2,5), (1)-->(3), (2,3)~~>(1), (2)==(5), (5)==(2) ├── prune: (1,3,4) @@ -359,7 +359,7 @@ inner-join (lookup xy@y1) ├── flags: no-merge-join;no-hash-join ├── key columns: [2] = [5] ├── stats: [rows=98.01, distinct(1)=9.9, null(1)=0, distinct(2)=1, null(2)=0, distinct(4)=9.9, null(4)=0, distinct(5)=1, null(5)=0] - ├── cost: 152.0444 + ├── cost: 153.0245 ├── key: (1,4) ├── fd: ()-->(2,5), (1)-->(3), (2,3)~~>(1), (2)==(5), (5)==(2) ├── prune: (1,3,4) diff --git a/pkg/sql/opt/xform/testdata/external/tpcc b/pkg/sql/opt/xform/testdata/external/tpcc index 00feeb0304c9..a58eb257b0ed 100644 --- a/pkg/sql/opt/xform/testdata/external/tpcc +++ b/pkg/sql/opt/xform/testdata/external/tpcc @@ -904,7 +904,7 @@ scalar-group-by ├── columns: count:28(int) ├── cardinality: [1 - 1] ├── stats: [rows=1] - ├── cost: 1.82111111 + ├── cost: 1.84111111 ├── key: () ├── fd: ()-->(28) ├── prune: (28) @@ -912,7 +912,7 @@ scalar-group-by │ ├── columns: ol_o_id:1(int!null) ol_d_id:2(int!null) ol_w_id:3(int!null) ol_i_id:5(int!null) s_i_id:11(int!null) s_w_id:12(int!null) s_quantity:13(int!null) │ ├── key columns: [3 5] = [12 11] │ ├── stats: [rows=1, distinct(1)=0.11109736, null(1)=0, distinct(2)=0.111097416, null(2)=0, distinct(3)=0.111111111, null(3)=0, distinct(5)=0.111111056, null(5)=0, distinct(11)=0.111111056, null(11)=0, distinct(12)=0.111111111, null(12)=0, distinct(13)=1, null(13)=0] - │ ├── cost: 1.79111111 + │ ├── cost: 1.81111111 │ ├── fd: ()-->(2,3,12), (11)-->(13), (5)==(11), (11)==(5), (3)==(12), (12)==(3) │ ├── interesting orderings: (+3,+2,-1) │ ├── scan order_line diff --git a/pkg/sql/opt/xform/testdata/external/tpcc-no-stats b/pkg/sql/opt/xform/testdata/external/tpcc-no-stats index 636cd49d3b7a..e9a6331c7d78 100644 --- a/pkg/sql/opt/xform/testdata/external/tpcc-no-stats +++ b/pkg/sql/opt/xform/testdata/external/tpcc-no-stats @@ -709,7 +709,7 @@ scalar-group-by ├── columns: count:28(int) ├── cardinality: [1 - 1] ├── stats: [rows=1] - ├── cost: 0.141477778 + ├── cost: 0.142211111 ├── key: () ├── fd: ()-->(28) ├── prune: (28) @@ -717,7 +717,7 @@ scalar-group-by │ ├── columns: ol_o_id:1(int!null) ol_d_id:2(int!null) ol_w_id:3(int!null) ol_i_id:5(int!null) s_i_id:11(int!null) s_w_id:12(int!null) s_quantity:13(int!null) │ ├── key columns: [3 5] = [12 11] │ ├── stats: [rows=0.0366666667, distinct(1)=0.0111105556, null(1)=0, distinct(2)=0.0111111111, null(2)=0, distinct(3)=0.0111111111, null(3)=0, distinct(5)=0.0111105556, null(5)=0, distinct(11)=0.0111105556, null(11)=0, distinct(12)=0.0111111111, null(12)=0, distinct(13)=0.0366666667, null(13)=0] - │ ├── cost: 0.121111111 + │ ├── cost: 0.121844444 │ ├── fd: ()-->(2,3,12), (11)-->(13), (5)==(11), (11)==(5), (3)==(12), (12)==(3) │ ├── interesting orderings: (+3,+2,-1) │ ├── scan order_line @@ -762,7 +762,7 @@ scalar-group-by ├── columns: count:22(int) ├── cardinality: [1 - 1] ├── stats: [rows=1] - ├── cost: 1588.01 + ├── cost: 1588.34 ├── key: () ├── fd: ()-->(22) ├── prune: (22) @@ -770,7 +770,7 @@ scalar-group-by │ ├── columns: w_id:1(int!null) w_ytd:9(decimal!null) d_w_id:11(int!null) sum:21(decimal!null) │ ├── key columns: [11] = [1] │ ├── stats: [rows=33, distinct(1)=33, null(1)=0, distinct(9)=28.3508504, null(9)=0, distinct(11)=33, null(11)=0, distinct(21)=28.3508504, null(21)=0] - │ ├── cost: 1587.66 + │ ├── cost: 1587.99 │ ├── key: (11) │ ├── fd: (1)-->(9), (11)-->(21), (1)==(11), (11)==(1) │ ├── interesting orderings: (+11) diff --git a/pkg/sql/opt/xform/testdata/rules/join b/pkg/sql/opt/xform/testdata/rules/join index dae0ca231323..00d22c265e4e 100644 --- a/pkg/sql/opt/xform/testdata/rules/join +++ b/pkg/sql/opt/xform/testdata/rules/join @@ -1879,11 +1879,11 @@ memo (optimized, ~11KB, required=[presentation: a:1]) ├── G1: (project G2 G3 a) │ └── [presentation: a:1] │ ├── best: (project G2 G3 a) - │ └── cost: 87.93 + │ └── cost: 88.05 ├── G2: (select G4 G5) (lookup-join G6 G5 t5,keyCols=[1],outCols=(1,2)) (select G7 G5) │ └── [] │ ├── best: (lookup-join G6 G5 t5,keyCols=[1],outCols=(1,2)) - │ └── cost: 87.80 + │ └── cost: 87.92 ├── G3: (projections) ├── G4: (scan t5,cols=(1,2)) │ └── [] diff --git a/pkg/storage/tscache/interval_skl.go b/pkg/storage/tscache/interval_skl.go index 80194d4bbced..6fe843edd865 100644 --- a/pkg/storage/tscache/interval_skl.go +++ b/pkg/storage/tscache/interval_skl.go @@ -374,7 +374,7 @@ func (s *intervalSkl) frontPage() *sklPage { // pushNewPage prepends a new empty page to the front of the pages list. It // accepts an optional arena argument to facilitate re-use. func (s *intervalSkl) pushNewPage(maxWallTime int64, arena *arenaskl.Arena) { - if arena != nil && arena.Size() == s.pageSize { + if arena != nil { // Re-use the provided arena, if possible. arena.Reset() } else { @@ -837,26 +837,25 @@ func (p *sklPage) ratchetValueSet( // attempt then we must have raced with node initialization before. return nil } - - var keyValUpdate, gapValUpdate bool - oldKeyVal, oldGapVal := decodeValueSet(it.Value(), meta) - keyVal, keyValUpdate = ratchetValue(oldKeyVal, keyVal) - gapVal, gapValUpdate = ratchetValue(oldGapVal, gapVal) - updateVals := keyValUpdate || gapValUpdate - - newMeta := meta - updateInit := setInit && !inited - if updateInit { + if (meta & cantInit) != 0 { // If the meta has the cantInit flag set to true, we fail with an // ErrArenaFull error to force the current goroutine to retry on a // new page. - if (meta & cantInit) != 0 { - return arenaskl.ErrArenaFull - } + return arenaskl.ErrArenaFull + } + newMeta := meta + updateInit := setInit && !inited + if updateInit { newMeta |= initialized } + var keyValUpdate, gapValUpdate bool + oldKeyVal, oldGapVal := decodeValueSet(it.Value(), meta) + keyVal, keyValUpdate = ratchetValue(oldKeyVal, keyVal) + gapVal, gapValUpdate = ratchetValue(oldGapVal, gapVal) + updateVals := keyValUpdate || gapValUpdate + if updateVals { // If we're updating the values (and maybe the init flag) then we // need to call it.Set. This can return an ErrArenaFull, which we diff --git a/pkg/storage/tscache/interval_skl_test.go b/pkg/storage/tscache/interval_skl_test.go index 713e70584cd6..13639f6eefcf 100644 --- a/pkg/storage/tscache/interval_skl_test.go +++ b/pkg/storage/tscache/interval_skl_test.go @@ -1218,10 +1218,10 @@ func BenchmarkIntervalSklAddAndLookup(b *testing.B) { rng := rand.New(rand.NewSource(timeutil.Now().UnixNano())) for n := 0; n < b.N/parallel; n++ { - readFrac := rng.Int31() + readFrac := rng.Int31n(10) keyNum := rng.Int31n(max) - if (readFrac % 10) < int32(i) { + if readFrac < int32(i) { key := []byte(fmt.Sprintf("%020d", keyNum)) s.LookupTimestamp(key) } else { diff --git a/pkg/ui/src/views/jobs/index.tsx b/pkg/ui/src/views/jobs/index.tsx index feda599c8f29..be1ff51b61a2 100644 --- a/pkg/ui/src/views/jobs/index.tsx +++ b/pkg/ui/src/views/jobs/index.tsx @@ -64,6 +64,7 @@ const typeOptions = [ { value: JobType.SCHEMA_CHANGE.toString(), label: "Schema Changes" }, { value: JobType.CHANGEFEED.toString(), label: "Changefeed"}, { value: JobType.CREATE_STATS.toString(), label: "Statistics Creation"}, + { value: JobType.AUTO_CREATE_STATS.toString(), label: "Auto-Statistics Creation"}, ]; const typeSetting = new LocalSetting( diff --git a/vendor b/vendor index 33eeb37f6f67..2b619c3efb04 160000 --- a/vendor +++ b/vendor @@ -1 +1 @@ -Subproject commit 33eeb37f6f67ba330d5343ca2da83c8c25d6b974 +Subproject commit 2b619c3efb048f876d9ab26e45872bafb7099e5c