github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/util/composite_primary_key_util_test.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package util 16 17 import ( 18 crand "crypto/rand" 19 "math" 20 "math/rand" 21 "reflect" 22 "strconv" 23 "testing" 24 25 "github.com/matrixorigin/matrixone/pkg/catalog" 26 27 "github.com/matrixorigin/matrixone/pkg/common/mpool" 28 "github.com/matrixorigin/matrixone/pkg/container/batch" 29 "github.com/matrixorigin/matrixone/pkg/container/types" 30 "github.com/matrixorigin/matrixone/pkg/container/vector" 31 "github.com/matrixorigin/matrixone/pkg/pb/plan" 32 "github.com/matrixorigin/matrixone/pkg/testutil" 33 "github.com/stretchr/testify/require" 34 ) 35 36 func TestJudgeIsCompositeClusterByColumn(t *testing.T) { 37 tests := []struct { 38 name string 39 args string 40 want bool 41 }{ 42 { 43 name: "test01", 44 args: "__mo_cbkey_005empno005ename", 45 want: true, 46 }, 47 { 48 name: "test02", 49 args: "__mo_cbkey_005ename003sal", 50 want: true, 51 }, 52 { 53 name: "test03", 54 args: "__mo_cpkey_005ename003sal", 55 want: false, 56 }, 57 } 58 for _, tt := range tests { 59 t.Run(tt.name, func(t *testing.T) { 60 if got := JudgeIsCompositeClusterByColumn(tt.args); got != tt.want { 61 t.Errorf("JudgeIsCompositeClusterByColumn() = %v, want %v", got, tt.want) 62 } 63 }) 64 } 65 } 66 67 func TestBuildCompositeClusterByColumnName(t *testing.T) { 68 tests := []struct { 69 name string 70 args []string 71 want string 72 }{ 73 { 74 name: "test01", 75 args: []string{"empno", "ename"}, 76 want: "__mo_cbkey_005empno005ename", 77 }, 78 { 79 name: "test02", 80 args: []string{"empno", "sal"}, 81 want: "__mo_cbkey_005empno003sal", 82 }, 83 { 84 name: "test03", 85 args: []string{"ename", "sal"}, 86 want: "__mo_cbkey_005ename003sal", 87 }, 88 } 89 for _, tt := range tests { 90 t.Run(tt.name, func(t *testing.T) { 91 if got := BuildCompositeClusterByColumnName(tt.args); got != tt.want { 92 t.Errorf("BuildCompositeClusterByColumnName() = %v, want %v", got, tt.want) 93 } 94 }) 95 } 96 } 97 98 func TestSplitCompositeClusterByColumnName(t *testing.T) { 99 tests := []struct { 100 name string 101 args string 102 want []string 103 }{ 104 { 105 name: "test01", 106 args: "__mo_cbkey_005empno005ename", 107 want: []string{"empno", "ename"}, 108 }, 109 { 110 name: "test02", 111 args: "__mo_cbkey_005empno003sal", 112 want: []string{"empno", "sal"}, 113 }, 114 { 115 name: "test03", 116 args: "__mo_cbkey_005ename003sal", 117 want: []string{"ename", "sal"}, 118 }, 119 } 120 for _, tt := range tests { 121 t.Run(tt.name, func(t *testing.T) { 122 if got := SplitCompositeClusterByColumnName(tt.args); !reflect.DeepEqual(got, tt.want) { 123 t.Errorf("SplitCompositeClusterByColumnName() = %v, want %v", got, tt.want) 124 } 125 }) 126 } 127 } 128 129 func TestGetClusterByColumnOrder(t *testing.T) { 130 tests := []struct { 131 name string 132 cbName string 133 colName string 134 want int 135 }{ 136 { 137 name: "test01", 138 cbName: "sal", 139 colName: "ename", 140 want: -1, 141 }, 142 { 143 name: "test02", 144 cbName: "sal", 145 colName: "__mo_cbkey_003sal005empno", 146 want: -1, 147 }, 148 { 149 name: "test03", 150 cbName: "sal", 151 colName: "sal", 152 want: 0, 153 }, 154 } 155 for _, tt := range tests { 156 t.Run(tt.name, func(t *testing.T) { 157 if got := GetClusterByColumnOrder(tt.cbName, tt.colName); got != tt.want { 158 t.Errorf("GetClusterByColumnOrder() = %v, want %v", got, tt.want) 159 } 160 }) 161 } 162 } 163 164 func TestFillCompositePKeyBatch(t *testing.T) { 165 var proc = testutil.NewProc() 166 columnSize := 10 167 rowCount := 10 168 bat, pkeyDef, valueCount := MakeBatch(columnSize, rowCount, proc.Mp()) 169 err := FillCompositeKeyBatch(bat, catalog.CPrimaryKeyColName, pkeyDef.Names, proc) 170 require.Equal(t, err, nil) 171 bs := vector.MustBytesCol(bat.Vecs[len(bat.Vecs)-1]) 172 tuples := make([]types.Tuple, 0) 173 for i := 0; i < len(bs); i++ { 174 tuple, err := types.Unpack(bs[i]) 175 require.Equal(t, err, nil) 176 tuples = append(tuples, tuple) 177 } 178 179 for i := 0; i < rowCount; i++ { 180 for j, name := range pkeyDef.Names { 181 element := tuples[i][j] 182 idx, _ := strconv.Atoi(name) 183 value := valueCount[[2]int{i, idx}] 184 require.Equal(t, element, value) 185 } 186 } 187 } 188 189 func MakeBatch(columnSize int, rowCount int, mp *mpool.MPool) (*batch.Batch, *plan.PrimaryKeyDef, map[[2]int]interface{}) { 190 attrs := make([]string, 0, columnSize) 191 192 for i := 0; i < columnSize; i++ { 193 attrs = append(attrs, strconv.Itoa(i)) 194 } 195 196 var keys []string 197 for i := 0; i < columnSize; i++ { 198 x := rand.Intn(2) 199 if x == 0 { 200 keys = append(keys, strconv.Itoa(i)) 201 } 202 } 203 bat := batch.New(true, attrs) 204 valueCount := make(map[[2]int]interface{}) 205 for i := 0; i < columnSize; i++ { 206 bat.Vecs[i] = vector.NewVec(randType().ToType()) 207 randInsertValues(bat.Vecs[i], bat.Vecs[i].GetType().Oid, rowCount, valueCount, i, mp) 208 } 209 210 primaryKeyDef := &plan.PrimaryKeyDef{ 211 PkeyColName: catalog.CPrimaryKeyColName, 212 Names: keys, 213 } 214 bat.SetRowCount(rowCount) 215 return bat, primaryKeyDef, valueCount 216 } 217 218 func randType() types.T { 219 t := rand.Intn(17) 220 var vt types.T 221 switch t { 222 case 0: 223 vt = types.T_bool 224 case 1: 225 vt = types.T_int8 226 case 2: 227 vt = types.T_int16 228 case 3: 229 vt = types.T_int32 230 case 4: 231 vt = types.T_int64 232 case 5: 233 vt = types.T_uint8 234 case 6: 235 vt = types.T_uint16 236 case 7: 237 vt = types.T_uint32 238 case 8: 239 vt = types.T_uint64 240 case 9: 241 vt = types.T_date 242 case 10: 243 vt = types.T_datetime 244 case 11: 245 vt = types.T_timestamp 246 case 12: 247 vt = types.T_float32 248 case 13: 249 vt = types.T_float64 250 case 14: 251 vt = types.T_decimal64 252 case 15: 253 vt = types.T_decimal128 254 case 16: 255 vt = types.T_varchar 256 } 257 return vt 258 } 259 260 func randInsertValues(v *vector.Vector, t types.T, rowCount int, valueCount map[[2]int]interface{}, columnIndex int, mp *mpool.MPool) { 261 switch t { 262 case types.T_bool: 263 vs := make([]bool, rowCount) 264 for i := 0; i < rowCount; i++ { 265 if i < rowCount/2 { 266 vs[i] = true 267 valueCount[[2]int{i, columnIndex}] = true 268 } else { 269 vs[i] = false 270 valueCount[[2]int{i, columnIndex}] = false 271 } 272 } 273 vector.AppendFixedList(v, vs, nil, mp) 274 case types.T_int8: 275 vs := make([]int8, rowCount) 276 for i := 0; i < rowCount; i++ { 277 vs[i] = randPositiveInt8() 278 valueCount[[2]int{i, columnIndex}] = vs[i] 279 } 280 vector.AppendFixedList(v, vs, nil, mp) 281 case types.T_int16: 282 vs := make([]int16, rowCount) 283 for i := 0; i < rowCount; i++ { 284 vs[i] = randPositiveInt16() 285 valueCount[[2]int{i, columnIndex}] = vs[i] 286 } 287 vector.AppendFixedList(v, vs, nil, mp) 288 case types.T_int32: 289 vs := make([]int32, rowCount) 290 for i := 0; i < rowCount; i++ { 291 vs[i] = randPositiveInt32() 292 valueCount[[2]int{i, columnIndex}] = vs[i] 293 } 294 vector.AppendFixedList(v, vs, nil, mp) 295 case types.T_int64: 296 vs := make([]int64, rowCount) 297 for i := 0; i < rowCount; i++ { 298 vs[i] = randPositiveInt64() 299 valueCount[[2]int{i, columnIndex}] = vs[i] 300 } 301 vector.AppendFixedList(v, vs, nil, mp) 302 case types.T_uint8: 303 vs := make([]uint8, rowCount) 304 for i := 0; i < rowCount; i++ { 305 vs[i] = randUint8() 306 valueCount[[2]int{i, columnIndex}] = vs[i] 307 } 308 vector.AppendFixedList(v, vs, nil, mp) 309 case types.T_uint16: 310 vs := make([]uint16, rowCount) 311 for i := 0; i < rowCount; i++ { 312 vs[i] = randUint16() 313 valueCount[[2]int{i, columnIndex}] = vs[i] 314 } 315 vector.AppendFixedList(v, vs, nil, mp) 316 case types.T_uint32: 317 vs := make([]uint32, rowCount) 318 for i := 0; i < rowCount; i++ { 319 vs[i] = randUint32() 320 valueCount[[2]int{i, columnIndex}] = vs[i] 321 } 322 vector.AppendFixedList(v, vs, nil, mp) 323 case types.T_uint64: 324 vs := make([]uint64, rowCount) 325 for i := 0; i < rowCount; i++ { 326 vs[i] = randUint64() 327 valueCount[[2]int{i, columnIndex}] = vs[i] 328 } 329 vector.AppendFixedList(v, vs, nil, mp) 330 case types.T_date: 331 vs := make([]types.Date, rowCount) 332 for i := 0; i < rowCount; i++ { 333 vs[i] = randDate() 334 valueCount[[2]int{i, columnIndex}] = vs[i] 335 } 336 vector.AppendFixedList(v, vs, nil, mp) 337 case types.T_time: 338 vs := make([]types.Time, rowCount) 339 for i := 0; i < rowCount; i++ { 340 vs[i] = randTime() 341 valueCount[[2]int{i, columnIndex}] = vs[i] 342 } 343 vector.AppendFixedList(v, vs, nil, mp) 344 case types.T_datetime: 345 vs := make([]types.Datetime, rowCount) 346 for i := 0; i < rowCount; i++ { 347 vs[i] = randDatetime() 348 valueCount[[2]int{i, columnIndex}] = vs[i] 349 } 350 vector.AppendFixedList(v, vs, nil, mp) 351 case types.T_timestamp: 352 vs := make([]types.Timestamp, rowCount) 353 for i := 0; i < rowCount; i++ { 354 vs[i] = randTimestamp() 355 valueCount[[2]int{i, columnIndex}] = vs[i] 356 } 357 vector.AppendFixedList(v, vs, nil, mp) 358 case types.T_float32: 359 vs := make([]float32, rowCount) 360 for i := 0; i < rowCount; i++ { 361 vs[i] = rand.Float32() 362 valueCount[[2]int{i, columnIndex}] = vs[i] 363 } 364 vector.AppendFixedList(v, vs, nil, mp) 365 case types.T_float64: 366 vs := make([]float64, rowCount) 367 for i := 0; i < rowCount; i++ { 368 vs[i] = rand.Float64() 369 valueCount[[2]int{i, columnIndex}] = vs[i] 370 } 371 vector.AppendFixedList(v, vs, nil, mp) 372 case types.T_decimal64: 373 vs := make([]types.Decimal64, rowCount) 374 for i := 0; i < rowCount; i++ { 375 vs[i] = randDecimal64() 376 valueCount[[2]int{i, columnIndex}] = vs[i] 377 } 378 vector.AppendFixedList(v, vs, nil, mp) 379 case types.T_decimal128: 380 vs := make([]types.Decimal128, rowCount) 381 for i := 0; i < rowCount; i++ { 382 vs[i] = randDecimal128() 383 valueCount[[2]int{i, columnIndex}] = vs[i] 384 } 385 vector.AppendFixedList(v, vs, nil, mp) 386 case types.T_varchar: 387 vs := make([][]byte, rowCount) 388 for i := 0; i < rowCount; i++ { 389 vs[i] = randStringType() 390 valueCount[[2]int{i, columnIndex}] = vs[i] 391 } 392 vector.AppendBytesList(v, vs, nil, mp) 393 } 394 395 } 396 397 func randPositiveInt8() int8 { 398 return int8(rand.Int31n(math.MaxInt8 + 1)) 399 } 400 401 func randPositiveInt16() int16 { 402 return int16(rand.Int31n(math.MaxInt16 + 1)) 403 } 404 405 func randPositiveInt32() int32 { 406 return rand.Int31() 407 } 408 409 func randPositiveInt64() int64 { 410 return rand.Int63() 411 } 412 413 func randUint8() uint8 { 414 return uint8(rand.Int31n(math.MaxUint8 + 1)) 415 } 416 417 func randUint16() uint16 { 418 return uint16(rand.Int31n(math.MaxUint16 + 1)) 419 } 420 421 func randUint32() uint32 { 422 return rand.Uint32() 423 } 424 425 func randUint64() uint64 { 426 return rand.Uint64() 427 } 428 429 func randDate() types.Date { 430 year := rand.Intn(types.MaxDateYear) + types.MinDateYear 431 month := rand.Intn(12) + 1 432 day := rand.Intn(int(types.LastDay(int32(year), uint8(month)))) + 1 433 return types.DateFromCalendar(int32(year), uint8(month), uint8(day)) 434 } 435 436 func randTime() types.Time { 437 isNeg := false 438 if tmp := rand.Intn(2); tmp == 0 { 439 isNeg = true 440 } 441 hour := rand.Intn(2562047788) 442 minute := rand.Intn(60) 443 second := rand.Intn(60) 444 microSecond := rand.Intn(1e6) 445 return types.TimeFromClock(isNeg, uint64(hour), uint8(minute), uint8(second), uint32(microSecond)) 446 } 447 448 func randDatetime() types.Datetime { 449 year := rand.Intn(types.MaxDatetimeYear) + types.MinDatetimeYear 450 month := rand.Intn(12) + 1 451 day := rand.Intn(int(types.LastDay(int32(year), uint8(month)))) + 1 452 hour := rand.Intn(24) 453 minute := rand.Intn(60) 454 second := rand.Intn(60) 455 microSecond := rand.Intn(1e6) 456 return types.DatetimeFromClock(int32(year), uint8(month), uint8(day), uint8(hour), uint8(minute), uint8(second), uint32(microSecond)) 457 } 458 459 func randTimestamp() types.Timestamp { 460 year := rand.Intn(types.MaxDatetimeYear) + types.MinDatetimeYear 461 month := rand.Intn(12) + 1 462 day := rand.Intn(int(types.LastDay(int32(year), uint8(month)))) + 1 463 hour := rand.Intn(24) 464 minute := rand.Intn(60) 465 second := rand.Intn(60) 466 microSecond := rand.Intn(1e6) 467 return types.FromClockUTC(int32(year), uint8(month), uint8(day), uint8(hour), uint8(minute), uint8(second), uint32(microSecond)) 468 } 469 470 func randDecimal64() types.Decimal64 { 471 return types.Decimal64(rand.Int() % 10000000000) 472 } 473 474 func randDecimal128() types.Decimal128 { 475 return types.Decimal128{B0_63: uint64(rand.Int() % 10000000000), B64_127: 0} 476 } 477 478 func randStringType() []byte { 479 b := make([]byte, 1024) 480 crand.Read(b) 481 return b 482 }