github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/substring/substrutil_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 substring 16 17 import ( 18 "testing" 19 20 "github.com/matrixorigin/matrixone/pkg/container/types" 21 "github.com/stretchr/testify/require" 22 ) 23 24 func TestSubstringFromLeftConstOffsetUnbounded(t *testing.T) { 25 cases := []struct { 26 name string 27 args1 []string 28 start int64 29 want []string 30 }{ 31 { 32 name: "Test01", 33 args1: []string{"abcdefghijklmn"}, 34 start: 5, 35 want: []string{"efghijklmn"}, 36 }, 37 { 38 name: "Test02", 39 args1: []string{"abcdefghijklmn"}, 40 start: 12, 41 want: []string{"lmn"}, 42 }, 43 { 44 name: "Test03", 45 args1: []string{"abcdefghijklmn"}, 46 start: 15, 47 want: []string{""}, 48 }, 49 } 50 51 for _, c := range cases { 52 t.Run(c.name, func(t *testing.T) { 53 out := make([]string, len(c.args1)) 54 got := SubstringFromLeftConstOffsetUnbounded(c.args1, out, c.start-1) 55 require.Equal(t, c.want, got) 56 }) 57 } 58 } 59 60 func TestSubstringFromRightConstOffsetUnbounded(t *testing.T) { 61 cases := []struct { 62 name string 63 args1 []string 64 start int64 65 want []string 66 }{ 67 { 68 name: "Test01", 69 args1: []string{"abcdefghijklmn"}, 70 start: -5, 71 want: []string{"jklmn"}, 72 }, 73 { 74 name: "Test02", 75 args1: []string{"abcdefghijklmn"}, 76 start: -14, 77 want: []string{"abcdefghijklmn"}, 78 }, 79 { 80 name: "Test03", 81 args1: []string{"abcdefghijklmn"}, 82 start: -16, 83 want: []string{""}, 84 }, 85 } 86 87 for _, c := range cases { 88 t.Run(c.name, func(t *testing.T) { 89 out := make([]string, len(c.args1)) 90 got := SubstringFromRightConstOffsetUnbounded(c.args1, out, -c.start) 91 require.Equal(t, c.want, got) 92 }) 93 } 94 } 95 96 func TestSubstringFromZeroConstOffsetUnbounded(t *testing.T) { 97 cases := []struct { 98 name string 99 args1 []string 100 start int64 101 want []string 102 }{ 103 { 104 name: "Test01", 105 args1: []string{"abcdefghijklmn"}, 106 start: 0, 107 want: []string{""}, 108 }, 109 { 110 name: "Test02", 111 args1: []string{"abcd132456"}, 112 start: 0, 113 want: []string{""}, 114 }, 115 } 116 117 for _, c := range cases { 118 t.Run(c.name, func(t *testing.T) { 119 out := make([]string, len(c.args1)) 120 got := SubstringFromZeroConstOffsetUnbounded(c.args1, out) 121 require.Equal(t, c.want, got) 122 }) 123 } 124 } 125 126 func tTestSubstringDynamicOffsetUnbounded[T types.BuiltinNumber](t *testing.T, name string, arg []string, startArgs []T, want []string) { 127 t.Run(name, func(t *testing.T) { 128 out := make([]string, len(arg)) 129 got := SubstringDynamicOffsetUnbounded(arg, out, startArgs, []bool{false, false}) 130 require.Equal(t, want, got) 131 }) 132 } 133 134 func TestSubstringDynamicOffsetUnbounded(t *testing.T) { 135 tTestSubstringDynamicOffsetUnbounded(t, "Testu1", []string{"abcdefghijklmn"}, []uint8{5}, []string{"efghijklmn"}) 136 tTestSubstringDynamicOffsetUnbounded(t, "Testu2", []string{"abcdefghijklmn"}, []uint16{5}, []string{"efghijklmn"}) 137 tTestSubstringDynamicOffsetUnbounded(t, "Testu3", []string{"abcdefghijklmn"}, []uint32{5}, []string{"efghijklmn"}) 138 tTestSubstringDynamicOffsetUnbounded(t, "Testu4", []string{"abcdefghijklmn"}, []uint64{5}, []string{"efghijklmn"}) 139 tTestSubstringDynamicOffsetUnbounded(t, "Testi1", []string{"abcdefghijklmn"}, []int8{5}, []string{"efghijklmn"}) 140 tTestSubstringDynamicOffsetUnbounded(t, "Testi2", []string{"abcdefghijklmn"}, []int16{5}, []string{"efghijklmn"}) 141 tTestSubstringDynamicOffsetUnbounded(t, "Testi3", []string{"abcdefghijklmn"}, []int32{5}, []string{"efghijklmn"}) 142 tTestSubstringDynamicOffsetUnbounded(t, "Testi4", []string{"abcdefghijklmn"}, []int64{5}, []string{"efghijklmn"}) 143 tTestSubstringDynamicOffsetUnbounded(t, "Testf3", []string{"abcdefghijklmn"}, []float32{5}, []string{"efghijklmn"}) 144 tTestSubstringDynamicOffsetUnbounded(t, "Testf4", []string{"abcdefghijklmn"}, []float64{5}, []string{"efghijklmn"}) 145 } 146 147 //------------------------------------------------------------- 148 149 func TestSubstringFromLeftConstOffsetBounded(t *testing.T) { 150 cases := []struct { 151 name string 152 args []string 153 start int64 154 length int64 155 want []string 156 }{ 157 { 158 name: "Test01", 159 args: []string{"abcdefghijklmn"}, 160 start: 5, 161 length: 6, 162 want: []string{"efghij"}, 163 }, 164 { 165 name: "Test02", 166 args: []string{"abcdefghijklmn"}, 167 start: 5, 168 length: 10, 169 want: []string{"efghijklmn"}, 170 }, 171 { 172 name: "Test03", 173 args: []string{"abcdefghijklmn"}, 174 start: 5, 175 length: 0, 176 want: []string{""}, 177 }, 178 { 179 name: "Test04", 180 args: []string{"abcdefghijklmn"}, 181 start: 5, 182 length: -3, 183 want: []string{""}, 184 }, 185 { 186 name: "Test05", 187 args: []string{"abcdefghijklmn"}, 188 start: 5, 189 length: -8, 190 want: []string{""}, 191 }, 192 { 193 name: "Test06", 194 args: []string{"abcdefghijklmn"}, 195 start: 5, 196 length: -10, 197 want: []string{""}, 198 }, 199 } 200 201 for _, c := range cases { 202 t.Run(c.name, func(t *testing.T) { 203 out := make([]string, len(c.args)) 204 got := SubstringFromLeftConstOffsetBounded(c.args, out, c.start-1, c.length) 205 require.Equal(t, c.want, got) 206 }) 207 } 208 } 209 210 func TestSubstringFromRightConstOffsetBounded(t *testing.T) { 211 cases := []struct { 212 name string 213 args []string 214 start int64 215 length int64 216 want []string 217 }{ 218 { 219 name: "Test03", 220 args: []string{"abcdefghijklmn"}, 221 start: -10, 222 length: 5, 223 want: []string{"efghi"}, 224 }, 225 { 226 name: "Test04", 227 args: []string{"abcdefghijklmn"}, 228 start: -10, 229 length: 0, 230 want: []string{""}, 231 }, 232 { 233 name: "Test05", 234 args: []string{"abcdefghijklmn"}, 235 start: -10, 236 length: 12, 237 want: []string{"efghijklmn"}, 238 }, 239 { 240 name: "Test06", 241 args: []string{"abcdefghijklmn"}, 242 start: -14, 243 length: 12, 244 want: []string{"abcdefghijkl"}, 245 }, 246 { 247 name: "Test07", 248 args: []string{"abcdefghijklmn"}, 249 start: -20, 250 length: 4, 251 want: []string{""}, 252 }, 253 { 254 name: "Test08", 255 args: []string{"abcdefghijklmn"}, 256 start: -16, 257 length: 10, 258 want: []string{""}, 259 }, 260 { 261 name: "Test09", 262 args: []string{"abcdefghijklmn"}, 263 start: -16, 264 length: 20, 265 want: []string{""}, 266 }, 267 { 268 name: "Test10", 269 args: []string{"abcdefghijklmn"}, 270 start: -8, 271 length: -4, 272 want: []string{""}, 273 }, 274 { 275 name: "Test11", 276 args: []string{"abcdefghijklmn"}, 277 start: -8, 278 length: -6, 279 want: []string{""}, 280 }, 281 { 282 name: "Test11", 283 args: []string{"abcdefghijklmn"}, 284 start: -14, 285 length: -6, 286 want: []string{""}, 287 }, 288 } 289 290 for _, c := range cases { 291 t.Run(c.name, func(t *testing.T) { 292 out := make([]string, len(c.args)) 293 got := SubstringFromRightConstOffsetBounded(c.args, out, -c.start, c.length) 294 require.Equal(t, c.want, got) 295 }) 296 } 297 } 298 299 func TestSubstringFromZeroConstOffsetBounded(t *testing.T) { 300 cases := []struct { 301 name string 302 args1 []string 303 start int64 304 length int64 305 want []string 306 }{ 307 { 308 name: "Test01", 309 args1: []string{"abcdefghijklmn"}, 310 start: 0, 311 length: 20, 312 want: []string{""}, 313 }, 314 { 315 name: "Test02", 316 args1: []string{"abcd132456"}, 317 start: 0, 318 length: -5, 319 want: []string{""}}, 320 } 321 322 for _, c := range cases { 323 t.Run(c.name, func(t *testing.T) { 324 out := make([]string, len(c.args1)) 325 got := SubstringFromZeroConstOffsetBounded(c.args1, out) 326 require.Equal(t, c.want, got) 327 }) 328 } 329 } 330 331 func tTestSubstringDynamicOffsetBounded[T1, T2 types.BuiltinNumber]( 332 t *testing.T, name string, srcArgs []string, startArgs []T1, lengthArgs []T2, cs []bool, want []string) { 333 t.Run(name, func(t *testing.T) { 334 out := make([]string, len(srcArgs)) 335 got := SubstringDynamicOffsetBounded(srcArgs, out, startArgs, lengthArgs, cs) 336 require.Equal(t, want, got) 337 }) 338 } 339 340 func TestSubstringDynamicOffsetBounded(t *testing.T) { 341 tTestSubstringDynamicOffsetBounded(t, "Test01", []string{"abcdefghijklmn"}, 342 []uint8{5}, []uint8{6}, []bool{false, false, false}, 343 []string{"efghij"}) 344 345 tTestSubstringDynamicOffsetBounded(t, "Test02", []string{"abcdefghijklmn"}, 346 []uint16{5}, []uint16{6}, []bool{false, false, false}, 347 []string{"efghij"}) 348 349 tTestSubstringDynamicOffsetBounded(t, "Test03", []string{"abcdefghijklmn"}, 350 []uint32{5}, []uint32{6}, []bool{false, false, false}, 351 []string{"efghij"}) 352 353 tTestSubstringDynamicOffsetBounded(t, "Test04", []string{"abcdefghijklmn"}, 354 []uint64{5}, []uint64{6}, []bool{false, false, false}, 355 []string{"efghij"}) 356 357 tTestSubstringDynamicOffsetBounded(t, "Test04", []string{"abcdefghijklmn"}, 358 []uint64{5}, []uint64{6}, []bool{false, false, false}, 359 []string{"efghij"}) 360 361 tTestSubstringDynamicOffsetBounded(t, "Test05", []string{"abcdefghijklmn"}, 362 []uint32{5}, []int64{6}, []bool{false, false, false}, 363 []string{"efghij"}) 364 365 tTestSubstringDynamicOffsetBounded(t, "Test06", []string{"abcdefghijklmn"}, 366 []uint32{5}, []int64{-6}, []bool{false, false, false}, 367 []string{""}) 368 369 tTestSubstringDynamicOffsetBounded(t, "Test07", []string{"abcdefghijklmn"}, 370 []uint32{5}, []int8{-6}, []bool{false, false, false}, 371 []string{""}) 372 373 tTestSubstringDynamicOffsetBounded(t, "Test08", []string{"abcdefghijklmn"}, 374 []uint32{5}, []int8{0}, []bool{false, false, false}, 375 []string{""}) 376 377 tTestSubstringDynamicOffsetBounded(t, "Test09", []string{"abcdefghijklmn"}, 378 []uint32{5}, []int16{-10}, []bool{false, false, false}, 379 []string{""}) 380 381 tTestSubstringDynamicOffsetBounded(t, "Test10", []string{"abcdefghijklmn"}, 382 []uint32{0}, []int16{-10}, []bool{false, false, false}, 383 []string{""}) 384 385 tTestSubstringDynamicOffsetBounded(t, "Test11", []string{"abcdefghijklmn"}, 386 []int32{-10}, []int16{-2}, []bool{false, false, false}, 387 []string{""}) 388 389 tTestSubstringDynamicOffsetBounded(t, "Test12", []string{"abcdefghijklmn"}, 390 []int32{-10}, []int64{-6}, []bool{false, false, false}, 391 []string{""}) 392 393 tTestSubstringDynamicOffsetBounded(t, "Test13", []string{"abcdefghijklmn"}, 394 []int32{-10}, []int64{-12}, []bool{false, false, false}, 395 []string{""}) 396 397 tTestSubstringDynamicOffsetBounded(t, "Test14", []string{"abcdefghijklmn"}, 398 []int32{-10}, []int64{0}, []bool{false, false, false}, 399 []string{""}) 400 401 tTestSubstringDynamicOffsetBounded(t, "Test15", []string{"abcdefghijklmn"}, 402 []int32{-10}, []int64{-9}, []bool{false, false, false}, 403 []string{""}) 404 405 tTestSubstringDynamicOffsetBounded(t, "Test16", []string{"abcdefghijklmn"}, 406 []int32{-10}, []int64{-10}, []bool{false, false, false}, 407 []string{""}) 408 }