github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/multi/substr_test.go (about) 1 // Copyright 2022 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 multi 16 17 import ( 18 "testing" 19 20 "github.com/matrixorigin/matrixone/pkg/container/types" 21 "github.com/matrixorigin/matrixone/pkg/container/vector" 22 "github.com/matrixorigin/matrixone/pkg/testutil" 23 "github.com/matrixorigin/matrixone/pkg/vm/process" 24 "github.com/stretchr/testify/require" 25 ) 26 27 func TestSubStr(t *testing.T) { 28 procs := testutil.NewProc() 29 cases := []struct { 30 name string 31 vecs []*vector.Vector 32 proc *process.Process 33 wantBytes []byte 34 wantScalar bool 35 }{ 36 { 37 name: "TEST01", 38 vecs: makeSubStrVectors("abcdefghijklmn", 5, 0, false), 39 proc: procs, 40 wantBytes: []byte("efghijklmn"), 41 wantScalar: true, 42 }, 43 { 44 name: "TEST02", 45 vecs: makeSubStrVectors("abcdefghijklmn", 7, 0, false), 46 proc: procs, 47 wantBytes: []byte("ghijklmn"), 48 wantScalar: true, 49 }, 50 { 51 name: "TEST03", 52 vecs: makeSubStrVectors("abcdefghijklmn", 11, 0, false), 53 proc: procs, 54 wantBytes: []byte("klmn"), 55 wantScalar: true, 56 }, 57 { 58 name: "TEST04", 59 vecs: makeSubStrVectors("abcdefghijklmn", 16, 0, false), 60 proc: procs, 61 wantBytes: []byte(""), 62 wantScalar: true, 63 }, 64 { 65 name: "TEST05", 66 vecs: makeSubStrVectors("abcdefghijklmn", 5, 6, true), 67 proc: procs, 68 wantBytes: []byte("efghij"), 69 wantScalar: true, 70 }, 71 { 72 name: "TEST06", 73 vecs: makeSubStrVectors("abcdefghijklmn", 5, 10, true), 74 proc: procs, 75 wantBytes: []byte("efghijklmn"), 76 wantScalar: true, 77 }, 78 { 79 name: "TEST07", 80 vecs: makeSubStrVectors("abcdefghijklmn", 5, 0, true), 81 proc: procs, 82 wantBytes: []byte(""), 83 wantScalar: true, 84 }, 85 { 86 name: "TEST08", 87 vecs: makeSubStrVectors("abcdefghijklmn", 6, -8, true), 88 proc: procs, 89 wantBytes: []byte(""), 90 wantScalar: true, 91 }, 92 { 93 name: "TEST09", 94 vecs: makeSubStrVectors("abcdefghijklmn", 6, -9, true), 95 proc: procs, 96 wantBytes: []byte(""), 97 wantScalar: true, 98 }, 99 { 100 name: "TEST09", 101 vecs: makeSubStrVectors("abcdefghijklmn", 6, -4, true), 102 proc: procs, 103 wantBytes: []byte(""), 104 wantScalar: true, 105 }, 106 { 107 name: "TEST10", 108 vecs: makeSubStrVectors("abcdefghijklmn", 6, -1, true), 109 proc: procs, 110 wantBytes: []byte(""), 111 wantScalar: true, 112 }, 113 { 114 name: "Test11", 115 vecs: makeSubStrVectors("abcdefghijklmn", -4, 0, false), 116 proc: procs, 117 wantBytes: []byte("klmn"), 118 wantScalar: true, 119 }, 120 { 121 name: "Test12", 122 vecs: makeSubStrVectors("abcdefghijklmn", -14, 0, false), 123 proc: procs, 124 wantBytes: []byte("abcdefghijklmn"), 125 wantScalar: true, 126 }, 127 { 128 name: "Test13", 129 vecs: makeSubStrVectors("abcdefghijklmn", -16, 0, false), 130 proc: procs, 131 wantBytes: []byte(""), 132 wantScalar: true, 133 }, 134 { 135 name: "Test14", 136 vecs: makeSubStrVectors("abcdefghijklmn", -4, 3, true), 137 proc: procs, 138 wantBytes: []byte("klm"), 139 wantScalar: true, 140 }, 141 { 142 name: "Test15", 143 vecs: makeSubStrVectors("abcdefghijklmn", -14, 10, true), 144 proc: procs, 145 wantBytes: []byte("abcdefghij"), 146 wantScalar: true, 147 }, 148 { 149 name: "Test16", 150 vecs: makeSubStrVectors("abcdefghijklmn", -14, 15, true), 151 proc: procs, 152 wantBytes: []byte("abcdefghijklmn"), 153 wantScalar: true, 154 }, 155 { 156 name: "Test17", 157 vecs: makeSubStrVectors("abcdefghijklmn", -16, 10, true), 158 proc: procs, 159 wantBytes: []byte(""), 160 wantScalar: true, 161 }, 162 { 163 name: "Test18", 164 vecs: makeSubStrVectors("abcdefghijklmn", -16, 20, true), 165 proc: procs, 166 wantBytes: []byte(""), 167 wantScalar: true, 168 }, 169 { 170 name: "Test19", 171 vecs: makeSubStrVectors("abcdefghijklmn", -16, 2, true), 172 proc: procs, 173 wantBytes: []byte(""), 174 wantScalar: true, 175 }, 176 { 177 name: "Test20", 178 vecs: makeSubStrVectors("abcdefghijklmn", -12, 2, true), 179 proc: procs, 180 wantBytes: []byte("cd"), 181 wantScalar: true, 182 }, 183 { 184 name: "Test21", 185 vecs: makeSubStrVectors("abcdefghijklmn", -12, 14, true), 186 proc: procs, 187 wantBytes: []byte("cdefghijklmn"), 188 wantScalar: true, 189 }, 190 { 191 name: "Test22", 192 vecs: makeSubStrVectors("abcdefghijklmn", -12, 0, true), 193 proc: procs, 194 wantBytes: []byte(""), 195 wantScalar: true, 196 }, 197 { 198 name: "Test23", 199 vecs: makeSubStrVectors("abcdefghijklmn", -6, -5, true), 200 proc: procs, 201 wantBytes: []byte(""), 202 wantScalar: true, 203 }, 204 { 205 name: "Test24", 206 vecs: makeSubStrVectors("abcdefghijklmn", -6, -10, true), 207 proc: procs, 208 wantBytes: []byte(""), 209 wantScalar: true, 210 }, 211 { 212 name: "Test25", 213 vecs: makeSubStrVectors("abcdefghijklmn", -6, -1, true), 214 proc: procs, 215 wantBytes: []byte(""), 216 wantScalar: true, 217 }, 218 } 219 220 for _, c := range cases { 221 t.Run(c.name, func(t *testing.T) { 222 substr, err := Substring(c.vecs, c.proc) 223 if err != nil { 224 t.Fatal(err) 225 } 226 require.Equal(t, c.wantBytes, substr.GetBytes(0)) 227 require.Equal(t, c.wantScalar, substr.IsScalar()) 228 }) 229 } 230 } 231 232 func TestSubStrUTF(t *testing.T) { 233 procs := testutil.NewProc() 234 cases := []struct { 235 name string 236 vecs []*vector.Vector 237 proc *process.Process 238 wantBytes []byte 239 wantScalar bool 240 }{ 241 { 242 name: "TEST01", 243 vecs: makeSubStrVectors("明天abcdef我爱你中国", 5, 0, false), 244 proc: procs, 245 wantBytes: []byte("cdef我爱你中国"), 246 wantScalar: true, 247 }, 248 { 249 name: "TEST02", 250 vecs: makeSubStrVectors("明天abcdef我爱你中国", 7, 0, false), 251 proc: procs, 252 wantBytes: []byte("ef我爱你中国"), 253 wantScalar: true, 254 }, 255 { 256 name: "TEST03", 257 vecs: makeSubStrVectors("明天abcdef我爱你中国", 11, 0, false), 258 proc: procs, 259 wantBytes: []byte("你中国"), 260 wantScalar: true, 261 }, 262 { 263 name: "TEST04", 264 vecs: makeSubStrVectors("明天abcdef我爱你中国", 16, 0, false), 265 proc: procs, 266 wantBytes: []byte(""), 267 wantScalar: true, 268 }, 269 { 270 name: "TEST05", 271 vecs: makeSubStrVectors("明天abcdef我爱你中国", 5, 6, true), 272 proc: procs, 273 wantBytes: []byte("cdef我爱"), 274 wantScalar: true, 275 }, 276 { 277 name: "TEST06", 278 vecs: makeSubStrVectors("明天abcdef我爱你中国", 5, 10, true), 279 proc: procs, 280 wantBytes: []byte("cdef我爱你中国"), 281 wantScalar: true, 282 }, 283 { 284 name: "TEST07", 285 vecs: makeSubStrVectors("明天abcdef我爱你中国", 5, 0, true), 286 proc: procs, 287 wantBytes: []byte(""), 288 wantScalar: true, 289 }, 290 { 291 name: "TEST08", 292 vecs: makeSubStrVectors("明天abcdef我爱你中国", 6, -8, true), 293 proc: procs, 294 wantBytes: []byte(""), 295 wantScalar: true, 296 }, 297 { 298 name: "TEST09", 299 vecs: makeSubStrVectors("明天abcdef我爱你中国", 6, -9, true), 300 proc: procs, 301 wantBytes: []byte(""), 302 wantScalar: true, 303 }, 304 { 305 name: "TEST09", 306 vecs: makeSubStrVectors("明天abcdef我爱你中国", 6, -4, true), 307 proc: procs, 308 wantBytes: []byte(""), 309 wantScalar: true, 310 }, 311 { 312 name: "TEST10", 313 vecs: makeSubStrVectors("明天abcdef我爱你中国", 6, -1, true), 314 proc: procs, 315 wantBytes: []byte(""), 316 wantScalar: true, 317 }, 318 { 319 name: "Test11", 320 vecs: makeSubStrVectors("明天abcdef我爱你中国", -4, 0, false), 321 proc: procs, 322 wantBytes: []byte("爱你中国"), 323 wantScalar: true, 324 }, 325 { 326 name: "Test12", 327 vecs: makeSubStrVectors("明天abcdef我爱你中国", -13, 0, false), 328 proc: procs, 329 wantBytes: []byte("明天abcdef我爱你中国"), 330 wantScalar: true, 331 }, 332 { 333 name: "Test13", 334 vecs: makeSubStrVectors("明天abcdef我爱你中国", -16, 0, false), 335 proc: procs, 336 wantBytes: []byte(""), 337 wantScalar: true, 338 }, 339 { 340 name: "Test14", 341 vecs: makeSubStrVectors("明天abcdef我爱你中国", -4, 3, true), 342 proc: procs, 343 wantBytes: []byte("爱你中"), 344 wantScalar: true, 345 }, 346 { 347 name: "Test15", 348 vecs: makeSubStrVectors("明天abcdef我爱你中国", -13, 10, true), 349 proc: procs, 350 wantBytes: []byte("明天abcdef我爱"), 351 wantScalar: true, 352 }, 353 { 354 name: "Test16", 355 vecs: makeSubStrVectors("明天abcdef我爱你中国", -13, 15, true), 356 proc: procs, 357 wantBytes: []byte("明天abcdef我爱你中国"), 358 wantScalar: true, 359 }, 360 { 361 name: "Test17", 362 vecs: makeSubStrVectors("明天abcdef我爱你中国", -16, 10, true), 363 proc: procs, 364 wantBytes: []byte(""), 365 wantScalar: true, 366 }, 367 { 368 name: "Test18", 369 vecs: makeSubStrVectors("明天abcdef我爱你中国", -16, 20, true), 370 proc: procs, 371 wantBytes: []byte(""), 372 wantScalar: true, 373 }, 374 { 375 name: "Test19", 376 vecs: makeSubStrVectors("明天abcdef我爱你中国", -16, 2, true), 377 proc: procs, 378 wantBytes: []byte(""), 379 wantScalar: true, 380 }, 381 { 382 name: "Test20", 383 vecs: makeSubStrVectors("明天abcdef我爱你中国", -12, 2, true), 384 proc: procs, 385 wantBytes: []byte("天a"), 386 wantScalar: true, 387 }, 388 { 389 name: "Test21", 390 vecs: makeSubStrVectors("明天abcdef我爱你中国", -12, 14, true), 391 proc: procs, 392 wantBytes: []byte("天abcdef我爱你中国"), 393 wantScalar: true, 394 }, 395 { 396 name: "Test22", 397 vecs: makeSubStrVectors("明天abcdef我爱你中国", -12, 0, true), 398 proc: procs, 399 wantBytes: []byte(""), 400 wantScalar: true, 401 }, 402 { 403 name: "Test23", 404 vecs: makeSubStrVectors("明天abcdef我爱你中国", -6, -5, true), 405 proc: procs, 406 wantBytes: []byte(""), 407 wantScalar: true, 408 }, 409 { 410 name: "Test24", 411 vecs: makeSubStrVectors("明天abcdef我爱你中国", -6, -10, true), 412 proc: procs, 413 wantBytes: []byte(""), 414 wantScalar: true, 415 }, 416 { 417 name: "Test25", 418 vecs: makeSubStrVectors("明天abcdef我爱你中国", -6, -1, true), 419 proc: procs, 420 wantBytes: []byte(""), 421 wantScalar: true, 422 }, 423 } 424 425 for _, c := range cases { 426 t.Run(c.name, func(t *testing.T) { 427 substr, err := Substring(c.vecs, c.proc) 428 if err != nil { 429 t.Fatal(err) 430 } 431 require.Equal(t, c.wantBytes, substr.GetBytes(0)) 432 require.Equal(t, c.wantScalar, substr.IsScalar()) 433 }) 434 } 435 } 436 437 func TestSubStrBlob(t *testing.T) { 438 procs := testutil.NewProc() 439 cases := []struct { 440 name string 441 vecs []*vector.Vector 442 proc *process.Process 443 wantBytes []byte 444 wantScalar bool 445 }{ 446 { 447 name: "TEST01", 448 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 5, 0, false, procs), 449 proc: procs, 450 wantBytes: []byte("efghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 451 wantScalar: true, 452 }, 453 { 454 name: "TEST02", 455 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 27, 0, false, procs), 456 proc: procs, 457 wantBytes: []byte("qwertyuiopasdfghjklzxcvbnm"), 458 wantScalar: true, 459 }, 460 { 461 name: "TEST03", 462 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 50, 0, false, procs), 463 proc: procs, 464 wantBytes: []byte("bnm"), 465 wantScalar: true, 466 }, 467 { 468 name: "TEST04", 469 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 53, 0, false, procs), 470 proc: procs, 471 wantBytes: []byte(""), 472 wantScalar: true, 473 }, 474 { 475 name: "TEST05", 476 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 5, 6, true, procs), 477 proc: procs, 478 wantBytes: []byte("efghij"), 479 wantScalar: true, 480 }, 481 { 482 name: "TEST06", 483 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 5, 10, true, procs), 484 proc: procs, 485 wantBytes: []byte("efghijklmn"), 486 wantScalar: true, 487 }, 488 { 489 name: "TEST07", 490 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 5, 0, true, procs), 491 proc: procs, 492 wantBytes: []byte(""), 493 wantScalar: true, 494 }, 495 { 496 name: "TEST08", 497 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 6, -8, true, procs), 498 proc: procs, 499 wantBytes: []byte(""), 500 wantScalar: true, 501 }, 502 { 503 name: "TEST09", 504 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 6, -9, true, procs), 505 proc: procs, 506 wantBytes: []byte(""), 507 wantScalar: true, 508 }, 509 { 510 name: "TEST09", 511 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 6, -4, true, procs), 512 proc: procs, 513 wantBytes: []byte(""), 514 wantScalar: true, 515 }, 516 { 517 name: "TEST10", 518 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 6, -1, true, procs), 519 proc: procs, 520 wantBytes: []byte(""), 521 wantScalar: true, 522 }, 523 { 524 name: "Test11", 525 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -4, 0, false, procs), 526 proc: procs, 527 wantBytes: []byte("vbnm"), 528 wantScalar: true, 529 }, 530 { 531 name: "Test12", 532 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -14, 0, false, procs), 533 proc: procs, 534 wantBytes: []byte("dfghjklzxcvbnm"), 535 wantScalar: true, 536 }, 537 { 538 name: "Test13", 539 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -50, 0, false, procs), 540 proc: procs, 541 wantBytes: []byte("cdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), 542 wantScalar: true, 543 }, 544 { 545 name: "Test14", 546 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -4, 3, true, procs), 547 proc: procs, 548 wantBytes: []byte("vbn"), 549 wantScalar: true, 550 }, 551 { 552 name: "Test15", 553 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -26, 10, true, procs), 554 proc: procs, 555 wantBytes: []byte("qwertyuiop"), 556 wantScalar: true, 557 }, 558 { 559 name: "Test16", 560 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -14, 15, true, procs), 561 proc: procs, 562 wantBytes: []byte("dfghjklzxcvbnm"), 563 wantScalar: true, 564 }, 565 { 566 name: "Test17", 567 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -53, 10, true, procs), 568 proc: procs, 569 wantBytes: []byte(""), 570 wantScalar: true, 571 }, 572 { 573 name: "Test18", 574 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -53, 20, true, procs), 575 proc: procs, 576 wantBytes: []byte(""), 577 wantScalar: true, 578 }, 579 { 580 name: "Test19", 581 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -53, 2, true, procs), 582 proc: procs, 583 wantBytes: []byte(""), 584 wantScalar: true, 585 }, 586 { 587 name: "Test20", 588 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -50, 2, true, procs), 589 proc: procs, 590 wantBytes: []byte("cd"), 591 wantScalar: true, 592 }, 593 { 594 name: "Test21", 595 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -12, 14, true, procs), 596 proc: procs, 597 wantBytes: []byte("ghjklzxcvbnm"), 598 wantScalar: true, 599 }, 600 { 601 name: "Test22", 602 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -12, 0, true, procs), 603 proc: procs, 604 wantBytes: []byte(""), 605 wantScalar: true, 606 }, 607 { 608 name: "Test23", 609 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -6, -5, true, procs), 610 proc: procs, 611 wantBytes: []byte(""), 612 wantScalar: true, 613 }, 614 { 615 name: "Test24", 616 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -6, -10, true, procs), 617 proc: procs, 618 wantBytes: []byte(""), 619 wantScalar: true, 620 }, 621 { 622 name: "Test25", 623 vecs: makeSubStrBlobVectors([]byte("abcdefghijklmnopqrstuvwxyzqwertyuiopasdfghjklzxcvbnm"), -6, 0, true, procs), 624 proc: procs, 625 wantBytes: []byte(""), 626 wantScalar: true, 627 }, 628 } 629 630 for _, c := range cases { 631 t.Run(c.name, func(t *testing.T) { 632 substr, err := Substring(c.vecs, c.proc) 633 if err != nil { 634 t.Fatal(err) 635 } 636 require.Equal(t, c.wantBytes, substr.GetBytes(0)) 637 require.Equal(t, c.wantScalar, substr.IsScalar()) 638 }) 639 } 640 } 641 642 // Construct vector parameter of substring function 643 func makeSubStrVectors(src string, start int64, length int64, withLength bool) []*vector.Vector { 644 vec := make([]*vector.Vector, 2) 645 vec[0] = vector.NewConstString(types.T_varchar.ToType(), 10, src, testutil.TestUtilMp) 646 vec[1] = vector.NewConstFixed(types.T_int64.ToType(), 10, start, testutil.TestUtilMp) 647 if withLength { 648 lvec := vector.NewConstFixed(types.T_int64.ToType(), 10, length, testutil.TestUtilMp) 649 vec = append(vec, lvec) 650 } 651 return vec 652 } 653 654 func makeSubStrBlobVectors(src []byte, start int64, length int64, withLength bool, procs *process.Process) []*vector.Vector { 655 inputVector := make([]*vector.Vector, 2) 656 inputType := types.New(types.T_blob, 0, 0, 0) 657 inputVector[0] = vector.NewConst(inputType, 1) 658 inputVector[0].Append(src, false, procs.Mp()) 659 inputVector[1] = vector.NewConstFixed(types.T_int64.ToType(), 10, start, testutil.TestUtilMp) 660 if withLength { 661 lvec := vector.NewConstFixed(types.T_int64.ToType(), 10, length, testutil.TestUtilMp) 662 inputVector = append(inputVector, lvec) 663 } 664 return inputVector 665 }