github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/like/like_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 like 16 17 import ( 18 "reflect" 19 "testing" 20 21 "github.com/matrixorigin/matrixone/pkg/container/nulls" 22 ) 23 24 func Test_sliceLikePure(t *testing.T) { 25 type args struct { 26 s []string 27 expr []byte 28 } 29 tests := []struct { 30 name string 31 args args 32 want []int64 33 wantErr bool 34 }{ 35 // 1. % 36 { 37 name: "%", 38 args: args{ 39 s: []string{"a", "bc"}, 40 expr: []byte("%"), 41 }, 42 want: []int64{0, 1}, 43 wantErr: false, 44 }, 45 // 2. _ 46 { 47 name: "_", 48 args: args{ 49 s: []string{"a", "bc"}, 50 expr: []byte("_"), 51 }, 52 want: []int64{0}, 53 wantErr: false, 54 }, 55 // 3. nil 56 { 57 name: "nil", 58 args: args{ 59 s: []string{"a", "bc"}, 60 expr: []byte(""), 61 }, 62 want: []int64{}, 63 wantErr: false, 64 }, 65 // 4. no _ and % 66 { 67 name: "bc", 68 args: args{ 69 s: []string{"a", "bc"}, 70 expr: []byte("bc"), 71 }, 72 want: []int64{1}, 73 wantErr: false, 74 }, 75 // 5. _XXX 76 { 77 name: "_XXX", 78 args: args{ 79 s: []string{"a", "bc"}, 80 expr: []byte("_c"), 81 }, 82 want: []int64{1}, 83 wantErr: false, 84 }, 85 // 6. %XXX 86 { 87 name: "%XXX", 88 args: args{ 89 s: []string{"a", "bc"}, 90 expr: []byte("%c"), 91 }, 92 want: []int64{1}, 93 wantErr: false, 94 }, 95 // 7. _XXX% 96 { 97 name: "_XXX%", 98 args: args{ 99 s: []string{"a", "bc", "aca"}, 100 expr: []byte("_c%"), 101 }, 102 want: []int64{1, 2}, 103 wantErr: false, 104 }, 105 // 8. %XXX_ 106 { 107 name: "%XXX_", 108 args: args{ 109 s: []string{"a", "bc", "aca"}, 110 expr: []byte("%c_"), 111 }, 112 want: []int64{2}, 113 wantErr: false, 114 }, 115 // 9. _XXX_ 116 { 117 name: "_XXX_", 118 args: args{ 119 s: []string{"a", "bc", "aca"}, 120 expr: []byte("_c_"), 121 }, 122 want: []int64{2}, 123 wantErr: false, 124 }, 125 // 10. %XXX% 126 { 127 name: "%XXX%", 128 args: args{ 129 s: []string{"a", "bc", "aca"}, 130 expr: []byte("%c%"), 131 }, 132 want: []int64{1, 2}, 133 wantErr: false, 134 }, 135 // 11. XXX%YYY 136 { 137 name: "XXX%YYY", 138 args: args{ 139 s: []string{"abc", "ac", "aca"}, 140 expr: []byte("a%c"), 141 }, 142 want: []int64{0, 1}, 143 wantErr: false, 144 }, 145 // 12. XXX_YYY 146 { 147 name: "XXX_YYY", 148 args: args{ 149 s: []string{"abc", "ac", "aca"}, 150 expr: []byte("a_c"), 151 }, 152 want: []int64{0}, 153 wantErr: false, 154 }, 155 // 13. single char none wild card 156 { 157 name: "*", 158 args: args{ 159 s: []string{"abc", "*", "aca"}, 160 expr: []byte("*"), 161 }, 162 want: []int64{1}, 163 wantErr: false, 164 }, 165 } 166 for _, tt := range tests { 167 t.Run(tt.name, func(t *testing.T) { 168 rs := make([]bool, len(tt.args.s)) 169 _, err := BtSliceAndConst(tt.args.s, tt.args.expr, rs) 170 if (err != nil) != tt.wantErr { 171 t.Errorf("sliceLikeScalar() error = %v, wantErr %v", err, tt.wantErr) 172 return 173 } 174 175 got := []int64{} 176 for i, b := range rs { 177 if b { 178 got = append(got, int64(i)) 179 } 180 } 181 182 if !reflect.DeepEqual(got, tt.want) { 183 t.Errorf("sliceLikeScalar() got = %v, want %v", got, tt.want) 184 } 185 }) 186 } 187 } 188 189 func Test_pureLikePure(t *testing.T) { 190 type args struct { 191 p []byte 192 expr []byte 193 rs []int64 194 } 195 tests := []struct { 196 name string 197 args args 198 want []int64 199 wantErr bool 200 }{ 201 // 1. % 202 { 203 name: "%", 204 args: args{ 205 p: []byte("123"), 206 expr: []byte("%"), 207 rs: make([]int64, 1), 208 }, 209 want: []int64{0}, 210 wantErr: false, 211 }, 212 // 2. _ 213 { 214 name: "_", 215 args: args{ 216 p: []byte("123"), 217 expr: []byte("_"), 218 rs: make([]int64, 1), 219 }, 220 want: nil, 221 wantErr: false, 222 }, 223 // 3. nil 224 { 225 name: "", 226 args: args{ 227 p: []byte("123"), 228 expr: []byte(""), 229 rs: make([]int64, 1), 230 }, 231 want: nil, 232 wantErr: false, 233 }, 234 // 4. %X% 235 { 236 name: "%X%", 237 args: args{ 238 p: []byte("123"), 239 expr: []byte("%23%"), 240 rs: make([]int64, 1), 241 }, 242 want: []int64{0}, 243 wantErr: false, 244 }, 245 // 5. %X_ 246 { 247 name: "%X_", 248 args: args{ 249 p: []byte("123"), 250 expr: []byte("%12_"), 251 rs: make([]int64, 1), 252 }, 253 want: []int64{0}, 254 wantErr: false, 255 }, 256 // 6. _X_ 257 { 258 name: "_X_", 259 args: args{ 260 p: []byte("323"), 261 expr: []byte("_2_"), 262 rs: make([]int64, 1), 263 }, 264 want: []int64{0}, 265 wantErr: false, 266 }, 267 // 7. _X% 268 { 269 name: "_X%", 270 args: args{ 271 p: []byte("12323"), 272 expr: []byte("_1%"), 273 rs: make([]int64, 1), 274 }, 275 want: nil, 276 wantErr: false, 277 }, 278 // 8. _XX 279 { 280 name: "_XX", 281 args: args{ 282 p: []byte("k123"), 283 expr: []byte("_123"), 284 rs: make([]int64, 1), 285 }, 286 want: []int64{0}, 287 wantErr: false, 288 }, 289 // 9. %XX 290 { 291 name: "%XX", 292 args: args{ 293 p: []byte("k123"), 294 expr: []byte("%23"), 295 rs: make([]int64, 1), 296 }, 297 want: []int64{0}, 298 wantErr: false, 299 }, 300 // 10. XX_ 301 { 302 name: "XX_", 303 args: args{ 304 p: []byte("k123"), 305 expr: []byte("k123_"), 306 rs: make([]int64, 1), 307 }, 308 want: nil, 309 wantErr: false, 310 }, 311 // 11. XX% 312 { 313 name: "XX%", 314 args: args{ 315 p: []byte("wop23"), 316 expr: []byte("w%"), 317 rs: make([]int64, 1), 318 }, 319 want: []int64{0}, 320 wantErr: false, 321 }, 322 // 12. XX_XX 323 { 324 name: "XX_XX", 325 args: args{ 326 p: []byte("wop23"), 327 expr: []byte("wo_23"), 328 rs: make([]int64, 1), 329 }, 330 want: []int64{0}, 331 wantErr: false, 332 }, 333 // 13. XX%XX 334 { 335 name: "XX%XX", 336 args: args{ 337 p: []byte("wop23"), 338 expr: []byte("wop%23"), 339 rs: make([]int64, 1), 340 }, 341 want: []int64{0}, 342 wantErr: false, 343 }, 344 // 14. single char none wild card 345 { 346 name: "*", 347 args: args{ 348 p: []byte("*"), 349 expr: []byte("*"), 350 rs: make([]int64, 1), 351 }, 352 want: []int64{0}, 353 wantErr: false, 354 }, 355 } 356 for _, tt := range tests { 357 t.Run(tt.name, func(t *testing.T) { 358 ok, err := BtConstAndConst(string(tt.args.p), tt.args.expr) 359 if (err != nil) != tt.wantErr { 360 t.Errorf("scalarLikeScalar() error = %v, wantErr %v", err, tt.wantErr) 361 return 362 } 363 364 if ok != (len(tt.want) == 1) { 365 t.Errorf("scalarLikeScalar() got = %v, want %v", ok, tt.want) 366 } 367 }) 368 } 369 } 370 371 func Test_sliceNullLikePure(t *testing.T) { 372 type args struct { 373 s []string 374 expr []byte 375 ns *nulls.Nulls 376 } 377 tests := []struct { 378 name string 379 args args 380 want []int64 381 wantErr bool 382 }{ 383 // 1. % 384 { 385 name: "%", 386 args: args{ 387 s: []string{"a", "bc"}, 388 expr: []byte("%"), 389 ns: nulls.NewWithSize(0), 390 }, 391 want: []int64{0, 1}, 392 wantErr: false, 393 }, 394 // 2. _ 395 { 396 name: "_", 397 args: args{ 398 s: []string{"a", "bc"}, 399 expr: []byte("_"), 400 ns: nulls.NewWithSize(0), 401 }, 402 want: []int64{0}, 403 wantErr: false, 404 }, 405 // 3. nil 406 { 407 name: "nil", 408 args: args{ 409 s: []string{"a", "bc"}, 410 expr: []byte(""), 411 ns: nulls.NewWithSize(0), 412 }, 413 want: []int64{}, 414 wantErr: false, 415 }, 416 // 4. no _ and % 417 { 418 name: "bc", 419 args: args{ 420 s: []string{"a", "bc"}, 421 expr: []byte("bc"), 422 ns: nulls.NewWithSize(0), 423 }, 424 want: []int64{1}, 425 wantErr: false, 426 }, 427 // 5. _XXX 428 { 429 name: "_XXX", 430 args: args{ 431 s: []string{"a", "bc"}, 432 expr: []byte("_c"), 433 ns: nulls.NewWithSize(0), 434 }, 435 want: []int64{1}, 436 wantErr: false, 437 }, 438 // 6. %XXX 439 { 440 name: "%XXX", 441 args: args{ 442 s: []string{"a", "bc"}, 443 expr: []byte("%c"), 444 ns: nulls.NewWithSize(0), 445 }, 446 want: []int64{1}, 447 wantErr: false, 448 }, 449 // 7. _XXX% 450 { 451 name: "_XXX%", 452 args: args{ 453 s: []string{"a", "bc", "aca"}, 454 expr: []byte("_c%"), 455 ns: nulls.NewWithSize(0), 456 }, 457 want: []int64{1, 2}, 458 wantErr: false, 459 }, 460 // 8. %XXX_ 461 { 462 name: "%XXX_", 463 args: args{ 464 s: []string{"a", "bc", "aca"}, 465 expr: []byte("%c_"), 466 ns: nulls.NewWithSize(0), 467 }, 468 want: []int64{2}, 469 wantErr: false, 470 }, 471 // 9. _XXX_ 472 { 473 name: "_XXX_", 474 args: args{ 475 s: []string{"a", "bc", "aca"}, 476 expr: []byte("_c_"), 477 ns: nulls.NewWithSize(0), 478 }, 479 want: []int64{2}, 480 wantErr: false, 481 }, 482 // 10. %XXX% 483 { 484 name: "%XXX%", 485 args: args{ 486 s: []string{"a", "bc", "aca"}, 487 expr: []byte("%c%"), 488 ns: nulls.NewWithSize(0), 489 }, 490 want: []int64{1, 2}, 491 wantErr: false, 492 }, 493 // 11. XXX%YYY 494 { 495 name: "XXX%YYY", 496 args: args{ 497 s: []string{"abc", "ac", "aca"}, 498 expr: []byte("a%c"), 499 ns: nulls.NewWithSize(0), 500 }, 501 want: []int64{0, 1}, 502 wantErr: false, 503 }, 504 // 12. XXX_YYY 505 { 506 name: "XXX_YYY", 507 args: args{ 508 s: []string{"abc", "ac", "aca"}, 509 expr: []byte("a_c"), 510 ns: nulls.NewWithSize(0), 511 }, 512 want: []int64{0}, 513 wantErr: false, 514 }, 515 // 13. XXX_ 516 { 517 name: "XXX_", 518 args: args{ 519 s: []string{"abc", "ac", "aca"}, 520 expr: []byte("a_"), 521 ns: nulls.NewWithSize(0), 522 }, 523 want: []int64{1}, 524 wantErr: false, 525 }, 526 // 14. XXX% 527 { 528 name: "XXX%", 529 args: args{ 530 s: []string{"abc", "ac", "aca"}, 531 expr: []byte("a%"), 532 ns: nulls.NewWithSize(0), 533 }, 534 want: []int64{0, 1, 2}, 535 wantErr: false, 536 }, 537 // 15. single char none wild card 538 { 539 name: "*", 540 args: args{ 541 s: []string{"abc", "*", "*a"}, 542 expr: []byte("*"), 543 ns: nulls.NewWithSize(0), 544 }, 545 want: []int64{1}, 546 wantErr: false, 547 }, 548 } 549 for _, tt := range tests { 550 t.Run(tt.name, func(t *testing.T) { 551 rs := make([]bool, len(tt.args.s)) 552 _, err := BtSliceNullAndConst(tt.args.s, tt.args.expr, tt.args.ns, rs) 553 if (err != nil) != tt.wantErr { 554 t.Errorf("sliceContainsNullLikeScalar() error = %v, wantErr %v", err, tt.wantErr) 555 return 556 } 557 got := []int64{} 558 for i, b := range rs { 559 if b { 560 got = append(got, int64(i)) 561 } 562 } 563 if !reflect.DeepEqual(got, tt.want) { 564 t.Errorf("sliceContainsNullLikeScalar() got = %v, want %v", got, tt.want) 565 } 566 }) 567 } 568 }