github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/function/func_binary_test.go (about) 1 // Copyright 2023 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 function 16 17 import ( 18 "fmt" 19 "math" 20 "testing" 21 "time" 22 23 "github.com/matrixorigin/matrixone/pkg/common/mpool" 24 "github.com/matrixorigin/matrixone/pkg/container/types" 25 "github.com/matrixorigin/matrixone/pkg/testutil" 26 "github.com/matrixorigin/matrixone/pkg/vm/process" 27 "github.com/stretchr/testify/require" 28 ) 29 30 func initAddFaultPointTestCase() []tcTemp { 31 return []tcTemp{ 32 { 33 info: "test space", 34 inputs: []testutil.FunctionTestInput{ 35 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{"a"}, []bool{false}), 36 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{":5::"}, []bool{false}), 37 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{"return"}, []bool{false}), 38 testutil.NewFunctionTestConstInput(types.T_int64.ToType(), []int64{0}, []bool{false}), 39 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{""}, []bool{false}), 40 }, 41 expect: testutil.NewFunctionTestResult(types.T_bool.ToType(), true, 42 []bool{true}, 43 []bool{false}), 44 }, 45 } 46 } 47 48 func TestAddFaultPoint(t *testing.T) { 49 testCases := initAddFaultPointTestCase() 50 51 // do the test work. 52 proc := testutil.NewProcess() 53 for _, tc := range testCases { 54 fcTC := testutil.NewFunctionTestCase(proc, 55 tc.inputs, tc.expect, AddFaultPoint) 56 s, info := fcTC.Run() 57 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 58 } 59 } 60 61 func initCeilTestCase() []tcTemp { 62 rfs := []float64{1, -1, -2, math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 1, 63 0, 2, 5, 9, 17, 33, 65, math.MaxInt64, math.MaxFloat64, 0} 64 fs := []float64{math.SmallestNonzeroFloat64, -1.2, -2.3, math.MinInt64 + 1, math.MinInt64 + 2, -100.2, -1.3, 0.9, 0, 65 1.5, 4.4, 8.5, 16.32, 32.345, 64.09, math.MaxInt64, math.MaxFloat64, 0} 66 bs := make([]bool, len(fs)) 67 return []tcTemp{ 68 { 69 info: "test ceil", 70 typ: types.T_uint64, 71 inputs: []testutil.FunctionTestInput{ 72 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 73 []uint64{1, 4, 8, 16, 32, math.MaxUint64, 0}, 74 []bool{false, false, false, false, false, false, false}), 75 }, 76 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 77 []uint64{1, 4, 8, 16, 32, math.MaxUint64, 0}, 78 []bool{false, false, false, false, false, false, false}), 79 }, 80 { 81 info: "test ceil", 82 typ: types.T_int64, 83 inputs: []testutil.FunctionTestInput{ 84 testutil.NewFunctionTestInput(types.T_int64.ToType(), 85 []int64{math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 0, 1, 4, 8, 16, 32, 64, math.MaxInt64, 0}, 86 []bool{false, false, false, false, false, false, false, false, false, false, false, false, false}), 87 }, 88 expect: testutil.NewFunctionTestResult(types.T_int64.ToType(), false, 89 []int64{math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 0, 1, 4, 8, 16, 32, 64, math.MaxInt64, 0}, 90 []bool{false, false, false, false, false, false, false, false, false, false, false, false, false}), 91 }, 92 { 93 info: "test ceil", 94 typ: types.T_float64, 95 inputs: []testutil.FunctionTestInput{ 96 testutil.NewFunctionTestInput(types.T_float64.ToType(), 97 fs, 98 bs), 99 }, 100 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 101 rfs, 102 bs), 103 }, 104 } 105 } 106 107 func TestCeil(t *testing.T) { 108 testCases := initCeilTestCase() 109 110 // do the test work. 111 proc := testutil.NewProcess() 112 for _, tc := range testCases { 113 var fcTC testutil.FunctionTestCase 114 switch tc.typ { 115 case types.T_uint64: 116 fcTC = testutil.NewFunctionTestCase(proc, 117 tc.inputs, tc.expect, CeilUint64) 118 case types.T_int64: 119 fcTC = testutil.NewFunctionTestCase(proc, 120 tc.inputs, tc.expect, CeilInt64) 121 case types.T_float64: 122 fcTC = testutil.NewFunctionTestCase(proc, 123 tc.inputs, tc.expect, CeilFloat64) 124 } 125 s, info := fcTC.Run() 126 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 127 } 128 } 129 130 func initFloorTestCase() []tcTemp { 131 rfs := []float64{0, -2, -3, math.MinInt64 + 1, math.MinInt64 + 2, -101, -2, 0, 132 0, 1, 4, 8, 16, 32, 64, math.MaxInt64, math.MaxFloat64, 0} 133 fs := []float64{math.SmallestNonzeroFloat64, -1.2, -2.3, math.MinInt64 + 1, math.MinInt64 + 2, -100.2, -1.3, 0.9, 0, 134 1.5, 4.4, 8.5, 16.32, 32.345, 64.09, math.MaxInt64, math.MaxFloat64, 0} 135 bs := make([]bool, len(fs)) 136 return []tcTemp{ 137 { 138 info: "test floor uint64", 139 typ: types.T_uint64, 140 inputs: []testutil.FunctionTestInput{ 141 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 142 []uint64{1, 4, 8, 16, 32, math.MaxUint64, 0}, 143 []bool{false, false, false, false, false, false, false}), 144 }, 145 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 146 []uint64{1, 4, 8, 16, 32, math.MaxUint64, 0}, 147 []bool{false, false, false, false, false, false, false}), 148 }, 149 { 150 info: "test floor int64", 151 typ: types.T_int64, 152 inputs: []testutil.FunctionTestInput{ 153 testutil.NewFunctionTestInput(types.T_int64.ToType(), 154 []int64{math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 0, 1, 4, 8, 16, 32, 64, math.MaxInt64, 0}, 155 []bool{false, false, false, false, false, false, false, false, false, false, false, false, false}), 156 }, 157 expect: testutil.NewFunctionTestResult(types.T_int64.ToType(), false, 158 []int64{math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 0, 1, 4, 8, 16, 32, 64, math.MaxInt64, 0}, 159 []bool{false, false, false, false, false, false, false, false, false, false, false, false, false}), 160 }, 161 { 162 info: "test floor floa64", 163 typ: types.T_float64, 164 inputs: []testutil.FunctionTestInput{ 165 testutil.NewFunctionTestInput(types.T_float64.ToType(), 166 fs, 167 bs), 168 }, 169 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 170 rfs, 171 bs), 172 }, 173 } 174 } 175 176 func TestFloor(t *testing.T) { 177 testCases := initFloorTestCase() 178 179 // do the test work. 180 proc := testutil.NewProcess() 181 for _, tc := range testCases { 182 var fcTC testutil.FunctionTestCase 183 switch tc.typ { 184 case types.T_uint64: 185 fcTC = testutil.NewFunctionTestCase(proc, 186 tc.inputs, tc.expect, FloorUInt64) 187 case types.T_int64: 188 fcTC = testutil.NewFunctionTestCase(proc, 189 tc.inputs, tc.expect, FloorInt64) 190 case types.T_float64: 191 fcTC = testutil.NewFunctionTestCase(proc, 192 tc.inputs, tc.expect, FloorFloat64) 193 } 194 s, info := fcTC.Run() 195 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 196 } 197 } 198 199 func initRoundTestCase() []tcTemp { 200 rfs := []float64{0, -1, -2, math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 1, 201 0, 2, 4, 8, 16, 32, 64, math.MaxInt64, math.MaxFloat64, 0} 202 fs := []float64{math.SmallestNonzeroFloat64, -1.2, -2.3, math.MinInt64 + 1, math.MinInt64 + 2, -100.2, -1.3, 0.9, 0, 203 1.5, 4.4, 8.5, 16.32, 32.345, 64.09, math.MaxInt64, math.MaxFloat64, 0} 204 bs := make([]bool, len(fs)) 205 return []tcTemp{ 206 { 207 info: "test round uint64", 208 typ: types.T_uint64, 209 inputs: []testutil.FunctionTestInput{ 210 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 211 []uint64{1, 4, 8, 16, 32, math.MaxUint64, 0}, 212 []bool{false, false, false, false, false, false, false}), 213 }, 214 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 215 []uint64{1, 4, 8, 16, 32, math.MaxUint64, 0}, 216 []bool{false, false, false, false, false, false, false}), 217 }, 218 { 219 info: "test round int64", 220 typ: types.T_int64, 221 inputs: []testutil.FunctionTestInput{ 222 testutil.NewFunctionTestInput(types.T_int64.ToType(), 223 []int64{math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 0, 1, 4, 8, 16, 32, 64, math.MaxInt64, 0}, 224 []bool{false, false, false, false, false, false, false, false, false, false, false, false, false}), 225 }, 226 expect: testutil.NewFunctionTestResult(types.T_int64.ToType(), false, 227 []int64{math.MinInt64 + 1, math.MinInt64 + 2, -100, -1, 0, 1, 4, 8, 16, 32, 64, math.MaxInt64, 0}, 228 []bool{false, false, false, false, false, false, false, false, false, false, false, false, false}), 229 }, 230 { 231 info: "test round floa64", 232 typ: types.T_float64, 233 inputs: []testutil.FunctionTestInput{ 234 testutil.NewFunctionTestInput(types.T_float64.ToType(), 235 fs, 236 bs), 237 }, 238 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 239 rfs, 240 bs), 241 }, 242 } 243 } 244 245 func TestRound(t *testing.T) { 246 testCases := initRoundTestCase() 247 248 // do the test work. 249 proc := testutil.NewProcess() 250 for _, tc := range testCases { 251 var fcTC testutil.FunctionTestCase 252 switch tc.typ { 253 case types.T_uint64: 254 fcTC = testutil.NewFunctionTestCase(proc, 255 tc.inputs, tc.expect, RoundUint64) 256 case types.T_int64: 257 fcTC = testutil.NewFunctionTestCase(proc, 258 tc.inputs, tc.expect, RoundInt64) 259 case types.T_float64: 260 fcTC = testutil.NewFunctionTestCase(proc, 261 tc.inputs, tc.expect, RoundFloat64) 262 } 263 s, info := fcTC.Run() 264 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 265 } 266 } 267 268 func initCoalesceTestCase() []tcTemp { 269 return []tcTemp{ 270 { 271 info: "test Coalesce int64", 272 typ: types.T_int64, 273 inputs: []testutil.FunctionTestInput{ 274 testutil.NewFunctionTestInput(types.T_int64.ToType(), 275 []int64{1, 4, 8, 16, 32, 0}, 276 []bool{true, true, true, true, true, true}), 277 testutil.NewFunctionTestInput(types.T_int64.ToType(), 278 []int64{1, 4, 8, 16, 32, 0}, 279 []bool{false, false, false, false, false, false}), 280 }, 281 expect: testutil.NewFunctionTestResult(types.T_int64.ToType(), false, 282 []int64{1, 4, 8, 16, 32, 0}, 283 []bool{false, false, false, false, false, false}), 284 }, 285 { 286 info: "test Coalesce varchar", 287 typ: types.T_varchar, 288 inputs: []testutil.FunctionTestInput{ 289 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 290 []string{"hello", "", "world"}, 291 []bool{false, true, false}), 292 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 293 []string{"hello", "-", "world"}, 294 []bool{true, false, true}), 295 }, 296 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 297 []string{"hello", "-", "world"}, 298 []bool{false, false, false}), 299 }, 300 { 301 info: "test Coalesce vecf32", 302 typ: types.T_varchar, 303 inputs: []testutil.FunctionTestInput{ 304 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), 305 [][]float32{{1, 2, 3}, {}, {4, 5, 6}}, 306 []bool{false, true, false}), 307 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), 308 [][]float32{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}, 309 []bool{true, false, true}), 310 }, 311 expect: testutil.NewFunctionTestResult(types.T_array_float32.ToType(), false, 312 [][]float32{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}, 313 []bool{false, false, false}), 314 }, 315 { 316 info: "test Coalesce vecf64", 317 typ: types.T_varchar, 318 inputs: []testutil.FunctionTestInput{ 319 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), 320 [][]float64{{1, 2, 3}, {}, {4, 5, 6}}, 321 []bool{false, true, false}), 322 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), 323 [][]float64{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}, 324 []bool{true, false, true}), 325 }, 326 expect: testutil.NewFunctionTestResult(types.T_array_float64.ToType(), false, 327 [][]float64{{1, 2, 3}, {0, 0, 0}, {4, 5, 6}}, 328 []bool{false, false, false}), 329 }, 330 } 331 } 332 333 func TestCoalesce(t *testing.T) { 334 testCases := initCoalesceTestCase() 335 336 // do the test work. 337 proc := testutil.NewProcess() 338 for _, tc := range testCases { 339 var fcTC testutil.FunctionTestCase 340 switch tc.typ { 341 case types.T_varchar: 342 fcTC = testutil.NewFunctionTestCase(proc, 343 tc.inputs, tc.expect, CoalesceStr) 344 case types.T_int64: 345 fcTC = testutil.NewFunctionTestCase(proc, 346 tc.inputs, tc.expect, CoalesceGeneral[int64]) 347 } 348 s, info := fcTC.Run() 349 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 350 } 351 } 352 353 func initConcatWsTestCase() []tcTemp { 354 return []tcTemp{ 355 { 356 info: "test ConcatWs", 357 typ: types.T_varchar, 358 inputs: []testutil.FunctionTestInput{ 359 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 360 []string{"---", "---", "---"}, 361 []bool{false, false, false}), 362 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 363 []string{"a", "b", "c"}, 364 []bool{false, false, false}), 365 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 366 []string{"a", "b", "c"}, 367 []bool{false, false, false}), 368 }, 369 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 370 []string{"a---a", "b---b", "c---c"}, 371 []bool{false, false, false}), 372 }, 373 } 374 } 375 376 func TestConcatWs(t *testing.T) { 377 testCases := initConcatWsTestCase() 378 379 // do the test work. 380 proc := testutil.NewProcess() 381 for _, tc := range testCases { 382 fcTC := testutil.NewFunctionTestCase(proc, 383 tc.inputs, tc.expect, ConcatWs) 384 s, info := fcTC.Run() 385 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 386 } 387 } 388 389 func initDateAddTestCase() []tcTemp { 390 d1, _ := types.ParseDatetime("2022-01-01", 6) 391 r1, _ := types.ParseDatetime("2022-01-02", 6) 392 return []tcTemp{ 393 { 394 info: "test DateAdd", 395 typ: types.T_date, 396 inputs: []testutil.FunctionTestInput{ 397 testutil.NewFunctionTestInput(types.T_date.ToType(), 398 []types.Date{d1.ToDate()}, 399 []bool{false}), 400 testutil.NewFunctionTestInput(types.T_int64.ToType(), 401 []int64{1}, 402 []bool{false}), 403 testutil.NewFunctionTestInput(types.T_int64.ToType(), 404 []int64{int64(types.Day)}, 405 []bool{false}), 406 }, 407 expect: testutil.NewFunctionTestResult(types.T_date.ToType(), false, 408 []types.Date{r1.ToDate()}, 409 []bool{false}), 410 }, 411 { 412 info: "test DatetimeAdd", 413 typ: types.T_datetime, 414 inputs: []testutil.FunctionTestInput{ 415 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 416 []types.Datetime{d1}, 417 []bool{false}), 418 testutil.NewFunctionTestInput(types.T_int64.ToType(), 419 []int64{1}, 420 []bool{false}), 421 testutil.NewFunctionTestInput(types.T_int64.ToType(), 422 []int64{int64(types.Day)}, 423 []bool{false}), 424 }, 425 expect: testutil.NewFunctionTestResult(types.T_datetime.ToType(), false, 426 []types.Datetime{r1}, 427 []bool{false}), 428 }, 429 { 430 info: "test DatetimeAdd", 431 typ: types.T_varchar, 432 inputs: []testutil.FunctionTestInput{ 433 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 434 []string{"2022-01-01"}, 435 []bool{false}), 436 testutil.NewFunctionTestInput(types.T_int64.ToType(), 437 []int64{1}, 438 []bool{false}), 439 testutil.NewFunctionTestInput(types.T_int64.ToType(), 440 []int64{int64(types.Day)}, 441 []bool{false}), 442 }, 443 expect: testutil.NewFunctionTestResult(types.T_datetime.ToType(), false, 444 []types.Datetime{r1}, 445 []bool{false}), 446 }, 447 } 448 } 449 450 func TestDateAdd(t *testing.T) { 451 testCases := initDateAddTestCase() 452 453 // do the test work. 454 proc := testutil.NewProcess() 455 for _, tc := range testCases { 456 var fcTC testutil.FunctionTestCase 457 switch tc.typ { 458 case types.T_date: 459 fcTC = testutil.NewFunctionTestCase(proc, 460 tc.inputs, tc.expect, DateAdd) 461 case types.T_datetime: 462 fcTC = testutil.NewFunctionTestCase(proc, 463 tc.inputs, tc.expect, DatetimeAdd) 464 case types.T_varchar: 465 fcTC = testutil.NewFunctionTestCase(proc, 466 tc.inputs, tc.expect, DateStringAdd) 467 } 468 s, info := fcTC.Run() 469 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 470 } 471 } 472 473 func initConvertTzTestCase() []tcTemp { 474 d1, _ := types.ParseDatetime("2023-01-01 00:00:00", 6) 475 r1 := "2022-12-31 13:07:00" 476 d2, _ := types.ParseDatetime("2022-01-01 00:00:00", 6) 477 r2 := "2021-12-31 16:00:00" 478 d3, _ := types.ParseDatetime("9999-12-31 23:00:00", 6) 479 r3 := "9999-12-31 23:00:00" 480 d4, _ := types.ParseDatetime("9999-12-31 22:00:00", 6) 481 r4 := "9999-12-31 22:00:00" 482 d5, _ := types.ParseDatetime("9999-12-31 10:00:00", 6) 483 r5 := "9999-12-31 18:00:00" 484 return []tcTemp{ 485 { // select convert_tz('2023-01-01 00:00:00', '+08:21', '-02:32'); 486 info: "test ConvertTz correct1", 487 typ: types.T_datetime, 488 inputs: []testutil.FunctionTestInput{ 489 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 490 []types.Datetime{d1}, 491 []bool{false}), 492 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 493 []string{"+08:21"}, 494 []bool{false}), 495 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 496 []string{"-02:32"}, 497 []bool{false}), 498 }, 499 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 500 []string{r1}, 501 []bool{false}), 502 }, 503 { // select convert_tz('2022-01-01 00:00:00', 'Asia/Shanghai', '+00:00'); 504 info: "test ConvertTz correct2", 505 typ: types.T_datetime, 506 inputs: []testutil.FunctionTestInput{ 507 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 508 []types.Datetime{d2}, 509 []bool{false}), 510 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 511 []string{"Asia/Shanghai"}, 512 []bool{false}), 513 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 514 []string{"+00:00"}, 515 []bool{false}), 516 }, 517 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 518 []string{r2}, 519 []bool{false}), 520 }, 521 { // select convert_tz('2022-01-01 00:00:00', 'Europe/London', 'Asia/Shanghai'); 522 info: "test ConvertTz correct3", 523 typ: types.T_datetime, 524 inputs: []testutil.FunctionTestInput{ 525 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 526 []types.Datetime{d2}, 527 []bool{false}), 528 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 529 []string{"Asia/Shanghai"}, 530 []bool{false}), 531 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 532 []string{"Europe/London"}, 533 []bool{false}), 534 }, 535 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 536 []string{r2}, 537 []bool{false}), 538 }, 539 { // select convert_tz('9999-12-31 23:00:00', '-02:00', '+11:00'); 540 info: "test ConvertTz out of range1", 541 typ: types.T_datetime, 542 inputs: []testutil.FunctionTestInput{ 543 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 544 []types.Datetime{d3}, 545 []bool{false}), 546 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 547 []string{"-02:00"}, 548 []bool{false}), 549 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 550 []string{"+11:00"}, 551 []bool{false}), 552 }, 553 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 554 []string{r3}, 555 []bool{false}), 556 }, 557 { // select convert_tz('9999-12-31 22:00:00', 'Europe/London', 'Asia/Shanghai'); 558 info: "test ConvertTz out of range2", 559 typ: types.T_datetime, 560 inputs: []testutil.FunctionTestInput{ 561 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 562 []types.Datetime{d4}, 563 []bool{false}), 564 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 565 []string{"Europe/London"}, 566 []bool{false}), 567 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 568 []string{"Asia/Shanghai"}, 569 []bool{false}), 570 }, 571 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 572 []string{r4}, 573 []bool{false}), 574 }, 575 { // select convert_tz('9999-12-31 10:00:00', 'Europe/London', 'Asia/Shanghai'); 576 info: "test ConvertTz not out of range", 577 typ: types.T_datetime, 578 inputs: []testutil.FunctionTestInput{ 579 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 580 []types.Datetime{d5}, 581 []bool{false}), 582 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 583 []string{"Europe/London"}, 584 []bool{false}), 585 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 586 []string{"Asia/Shanghai"}, 587 []bool{false}), 588 }, 589 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 590 []string{r5}, 591 []bool{false}), 592 }, 593 { 594 info: "test ConvertTz err1", 595 typ: types.T_datetime, 596 inputs: []testutil.FunctionTestInput{ 597 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 598 []types.Datetime{d1}, 599 []bool{false}), 600 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 601 []string{"ABC"}, 602 []bool{false}), 603 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 604 []string{"GMT"}, 605 []bool{false}), 606 }, 607 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 608 []string{""}, 609 []bool{true}), 610 }, 611 { 612 info: "test ConvertTz err2", 613 typ: types.T_datetime, 614 inputs: []testutil.FunctionTestInput{ 615 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 616 []types.Datetime{d1}, 617 []bool{false}), 618 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 619 []string{"+00:00"}, 620 []bool{false}), 621 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 622 []string{"ABC"}, 623 []bool{false}), 624 }, 625 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 626 []string{""}, 627 []bool{true}), 628 }, 629 { 630 info: "test ConvertTz err3", 631 typ: types.T_datetime, 632 inputs: []testutil.FunctionTestInput{ 633 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 634 []types.Datetime{d1}, 635 []bool{false}), 636 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 637 []string{"+00:00:00"}, 638 []bool{false}), 639 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 640 []string{"+08:00"}, 641 []bool{false}), 642 }, 643 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 644 []string{""}, 645 []bool{true}), 646 }, 647 { 648 info: "test ConvertTz err4", 649 typ: types.T_datetime, 650 inputs: []testutil.FunctionTestInput{ 651 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 652 []types.Datetime{d1}, 653 []bool{false}), 654 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 655 []string{"+00:ws"}, 656 []bool{false}), 657 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 658 []string{"+08:00"}, 659 []bool{false}), 660 }, 661 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 662 []string{""}, 663 []bool{true}), 664 }, 665 { 666 info: "test ConvertTz err5", 667 typ: types.T_datetime, 668 inputs: []testutil.FunctionTestInput{ 669 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 670 []types.Datetime{d1}, 671 []bool{false}), 672 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 673 []string{"+00:00"}, 674 []bool{false}), 675 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 676 []string{"+18:00"}, 677 []bool{false}), 678 }, 679 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 680 []string{""}, 681 []bool{true}), 682 }, 683 { 684 info: "test ConvertTz when tz is empty", 685 typ: types.T_datetime, 686 inputs: []testutil.FunctionTestInput{ 687 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 688 []types.Datetime{d3}, 689 []bool{false}), 690 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 691 []string{""}, 692 []bool{false}), 693 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 694 []string{""}, 695 []bool{false}), 696 }, 697 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 698 []string{""}, 699 []bool{true}), 700 }, 701 } 702 } 703 704 func TestConvertTz(t *testing.T) { 705 testCases := initConvertTzTestCase() 706 707 // do the test work. 708 proc := testutil.NewProcess() 709 for _, tc := range testCases { 710 fcTC := testutil.NewFunctionTestCase(proc, 711 tc.inputs, tc.expect, ConvertTz) 712 s, info := fcTC.Run() 713 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 714 } 715 } 716 717 func initFormatTestCase() []tcTemp { 718 format := `%b %M %m %c %D %d %e %j %k %h %i %p %r %T %s %f %U %u %V %v %a %W %w %X %x %Y %y %%` 719 720 d1, _ := types.ParseDatetime("2010-01-07 23:12:34.12345", 6) 721 r1 := `Jan January 01 1 7th 07 7 007 23 11 12 PM 11:12:34 PM 23:12:34 34 123450 01 01 01 01 Thu Thursday 4 2010 2010 2010 10 %` 722 723 d2, _ := types.ParseDatetime("2012-12-21 23:12:34.123456", 6) 724 r2 := "Dec December 12 12 21st 21 21 356 23 11 12 PM 11:12:34 PM 23:12:34 34 123456 51 51 51 51 Fri Friday 5 2012 2012 2012 12 %" 725 726 d3, _ := types.ParseDatetime("0001-01-01 00:00:00.123456", 6) 727 r3 := `Jan January 01 1 1st 01 1 001 0 12 00 AM 12:00:00 AM 00:00:00 00 123456 00 01 53 01 Mon Monday 1 0000 0001 0001 01 %` 728 729 d4, _ := types.ParseDatetime("2016-09-3 00:59:59.123456", 6) 730 r4 := `Sep September 09 9 3rd 03 3 247 0 12 59 AM 12:59:59 AM 00:59:59 59 123456 35 35 35 35 Sat Saturday 6 2016 2016 2016 16 %` 731 732 return []tcTemp{ 733 { 734 info: "test format", 735 typ: types.T_datetime, 736 inputs: []testutil.FunctionTestInput{ 737 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 738 []types.Datetime{d1}, 739 []bool{false}), 740 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), 741 []string{format}, 742 []bool{false}), 743 }, 744 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 745 []string{r1}, 746 []bool{false}), 747 }, 748 { 749 info: "test format", 750 typ: types.T_datetime, 751 inputs: []testutil.FunctionTestInput{ 752 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 753 []types.Datetime{d2}, 754 []bool{false}), 755 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), 756 []string{format}, 757 []bool{false}), 758 }, 759 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 760 []string{r2}, 761 []bool{false}), 762 }, 763 { 764 info: "test format", 765 typ: types.T_datetime, 766 inputs: []testutil.FunctionTestInput{ 767 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 768 []types.Datetime{d3}, 769 []bool{false}), 770 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), 771 []string{format}, 772 []bool{false}), 773 }, 774 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 775 []string{r3}, 776 []bool{false}), 777 }, 778 { 779 info: "test format", 780 typ: types.T_datetime, 781 inputs: []testutil.FunctionTestInput{ 782 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 783 []types.Datetime{d4}, 784 []bool{false}), 785 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), 786 []string{format}, 787 []bool{false}), 788 }, 789 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 790 []string{r4}, 791 []bool{false}), 792 }, 793 } 794 } 795 796 func TestFormat(t *testing.T) { 797 testCases := initFormatTestCase() 798 799 // do the test work. 800 proc := testutil.NewProcess() 801 for _, tc := range testCases { 802 fcTC := testutil.NewFunctionTestCase(proc, 803 tc.inputs, tc.expect, DateFormat) 804 s, info := fcTC.Run() 805 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 806 } 807 } 808 809 func initDateSubTestCase() []tcTemp { 810 d1, _ := types.ParseDatetime("2022-01-01", 6) 811 r1, _ := types.ParseDatetime("2021-12-31", 6) 812 return []tcTemp{ 813 { 814 info: "test DateAdd", 815 typ: types.T_date, 816 inputs: []testutil.FunctionTestInput{ 817 testutil.NewFunctionTestInput(types.T_date.ToType(), 818 []types.Date{d1.ToDate()}, 819 []bool{false}), 820 testutil.NewFunctionTestInput(types.T_int64.ToType(), 821 []int64{1}, 822 []bool{false}), 823 testutil.NewFunctionTestInput(types.T_int64.ToType(), 824 []int64{int64(types.Day)}, 825 []bool{false}), 826 }, 827 expect: testutil.NewFunctionTestResult(types.T_date.ToType(), false, 828 []types.Date{r1.ToDate()}, 829 []bool{false}), 830 }, 831 { 832 info: "test DatetimeAdd", 833 typ: types.T_datetime, 834 inputs: []testutil.FunctionTestInput{ 835 testutil.NewFunctionTestInput(types.T_datetime.ToType(), 836 []types.Datetime{d1}, 837 []bool{false}), 838 testutil.NewFunctionTestInput(types.T_int64.ToType(), 839 []int64{1}, 840 []bool{false}), 841 testutil.NewFunctionTestInput(types.T_int64.ToType(), 842 []int64{int64(types.Day)}, 843 []bool{false}), 844 }, 845 expect: testutil.NewFunctionTestResult(types.T_datetime.ToType(), false, 846 []types.Datetime{r1}, 847 []bool{false}), 848 }, 849 { 850 info: "test DatetimeAdd", 851 typ: types.T_varchar, 852 inputs: []testutil.FunctionTestInput{ 853 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 854 []string{"2022-01-01"}, 855 []bool{false}), 856 testutil.NewFunctionTestInput(types.T_int64.ToType(), 857 []int64{1}, 858 []bool{false}), 859 testutil.NewFunctionTestInput(types.T_int64.ToType(), 860 []int64{int64(types.Day)}, 861 []bool{false}), 862 }, 863 expect: testutil.NewFunctionTestResult(types.T_datetime.ToType(), false, 864 []types.Datetime{r1}, 865 []bool{false}), 866 }, 867 } 868 } 869 870 func TestDateSub(t *testing.T) { 871 testCases := initDateSubTestCase() 872 873 // do the test work. 874 proc := testutil.NewProcess() 875 for _, tc := range testCases { 876 var fcTC testutil.FunctionTestCase 877 switch tc.typ { 878 case types.T_date: 879 fcTC = testutil.NewFunctionTestCase(proc, 880 tc.inputs, tc.expect, DateSub) 881 case types.T_datetime: 882 fcTC = testutil.NewFunctionTestCase(proc, 883 tc.inputs, tc.expect, DatetimeSub) 884 case types.T_varchar: 885 fcTC = testutil.NewFunctionTestCase(proc, 886 tc.inputs, tc.expect, DateStringSub) 887 } 888 s, info := fcTC.Run() 889 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 890 } 891 } 892 893 func initFieldTestCase() []tcTemp { 894 return []tcTemp{ 895 { 896 info: "test Field", 897 typ: types.T_uint64, 898 inputs: []testutil.FunctionTestInput{ 899 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 900 []uint64{0}, 901 []bool{true}), 902 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 903 []uint64{1}, 904 []bool{false}), 905 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 906 []uint64{1}, 907 []bool{false}), 908 }, 909 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 910 []uint64{0}, 911 []bool{false}), 912 }, 913 { 914 info: "test Field", 915 typ: types.T_uint64, 916 inputs: []testutil.FunctionTestInput{ 917 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 918 []uint64{1}, 919 []bool{false}), 920 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 921 []uint64{2}, 922 []bool{false}), 923 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 924 []uint64{1}, 925 []bool{false}), 926 }, 927 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 928 []uint64{2}, 929 []bool{false}), 930 }, 931 { 932 info: "test Field", 933 typ: types.T_uint64, 934 inputs: []testutil.FunctionTestInput{ 935 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 936 []uint64{1}, 937 []bool{false}), 938 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 939 []uint64{2}, 940 []bool{false}), 941 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 942 []uint64{3}, 943 []bool{false}), 944 }, 945 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 946 []uint64{0}, 947 []bool{false}), 948 }, 949 950 { 951 info: "test Field", 952 typ: types.T_varchar, 953 inputs: []testutil.FunctionTestInput{ 954 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 955 []string{"hello"}, 956 []bool{false}), 957 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 958 []string{""}, 959 []bool{true}), 960 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 961 []string{"hello"}, 962 []bool{false}), 963 }, 964 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 965 []uint64{2}, 966 []bool{false}), 967 }, 968 } 969 } 970 971 func TestField(t *testing.T) { 972 testCases := initFieldTestCase() 973 974 // do the test work. 975 proc := testutil.NewProcess() 976 for _, tc := range testCases { 977 var fcTC testutil.FunctionTestCase 978 switch tc.typ { 979 case types.T_uint64: 980 fcTC = testutil.NewFunctionTestCase(proc, 981 tc.inputs, tc.expect, FieldNumber[uint64]) 982 case types.T_varchar: 983 fcTC = testutil.NewFunctionTestCase(proc, 984 tc.inputs, tc.expect, FieldString) 985 } 986 s, info := fcTC.Run() 987 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 988 } 989 } 990 991 func initFormat2Or3TestCase() []tcTemp { 992 return []tcTemp{ 993 { 994 info: "2", 995 typ: types.T_varchar, 996 inputs: []testutil.FunctionTestInput{ 997 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"12332.123456"}, []bool{false}), 998 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"4"}, []bool{false}), 999 }, 1000 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"12,332.1235"}, []bool{false}), 1001 }, 1002 { 1003 info: "2", 1004 typ: types.T_varchar, 1005 inputs: []testutil.FunctionTestInput{ 1006 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"12332.1"}, []bool{false}), 1007 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"4"}, []bool{false}), 1008 }, 1009 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"12,332.1000"}, []bool{false}), 1010 }, 1011 { 1012 info: "2", 1013 typ: types.T_varchar, 1014 inputs: []testutil.FunctionTestInput{ 1015 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"12332.2"}, []bool{false}), 1016 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"0"}, []bool{false}), 1017 }, 1018 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"12,332"}, []bool{false}), 1019 }, 1020 { 1021 info: "2", 1022 typ: types.T_varchar, 1023 inputs: []testutil.FunctionTestInput{ 1024 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"-.12334.2"}, []bool{false}), 1025 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"2"}, []bool{false}), 1026 }, 1027 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"-0.12"}, []bool{false}), 1028 }, 1029 { 1030 info: "3", 1031 typ: types.T_varchar, 1032 inputs: []testutil.FunctionTestInput{ 1033 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"12332.123456"}, []bool{false}), 1034 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"4"}, []bool{false}), 1035 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"ar_SA"}, []bool{false}), 1036 }, 1037 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"12332.1235"}, []bool{false}), 1038 }, 1039 { 1040 info: "3", 1041 typ: types.T_varchar, 1042 inputs: []testutil.FunctionTestInput{ 1043 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"12332.1"}, []bool{false}), 1044 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"4"}, []bool{false}), 1045 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"ar_SA"}, []bool{false}), 1046 }, 1047 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"12332.1000"}, []bool{false}), 1048 }, 1049 { 1050 info: "3", 1051 typ: types.T_varchar, 1052 inputs: []testutil.FunctionTestInput{ 1053 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"12332.2"}, []bool{false}), 1054 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"0"}, []bool{false}), 1055 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"ar_SA"}, []bool{false}), 1056 }, 1057 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"12332"}, []bool{false}), 1058 }, 1059 { 1060 info: "3", 1061 typ: types.T_varchar, 1062 inputs: []testutil.FunctionTestInput{ 1063 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"-.12334.2"}, []bool{false}), 1064 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"2"}, []bool{false}), 1065 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"ar_SA"}, []bool{false}), 1066 }, 1067 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"-0.12"}, []bool{false}), 1068 }, 1069 } 1070 } 1071 1072 func TestFormat2Or3(t *testing.T) { 1073 testCases := initFormat2Or3TestCase() 1074 1075 // do the test work. 1076 proc := testutil.NewProcess() 1077 for _, tc := range testCases { 1078 var fcTC testutil.FunctionTestCase 1079 switch tc.info { 1080 case "2": 1081 fcTC = testutil.NewFunctionTestCase(proc, 1082 tc.inputs, tc.expect, FormatWith2Args) 1083 case "3": 1084 fcTC = testutil.NewFunctionTestCase(proc, 1085 tc.inputs, tc.expect, FormatWith3Args) 1086 } 1087 s, info := fcTC.Run() 1088 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1089 } 1090 } 1091 1092 func initFromUnixTimeTestCase() []tcTemp { 1093 d1, _ := types.ParseDatetime("1970-01-01 00:00:00", 6) 1094 d2, _ := types.ParseDatetime("2016-01-01 00:00:00", 6) 1095 d3, _ := types.ParseDatetime("2016-01-01 00:00:00.999999", 6) 1096 return []tcTemp{ 1097 { 1098 info: "test from unix time int64", 1099 typ: types.T_int64, 1100 inputs: []testutil.FunctionTestInput{ 1101 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1102 []int64{0}, 1103 []bool{false}), 1104 }, 1105 expect: testutil.NewFunctionTestResult(types.T_datetime.ToType(), false, 1106 []types.Datetime{d1}, 1107 []bool{false}), 1108 }, 1109 { 1110 info: "test from unix time uint64", 1111 typ: types.T_uint64, 1112 inputs: []testutil.FunctionTestInput{ 1113 testutil.NewFunctionTestInput(types.T_uint64.ToType(), 1114 []uint64{1451606400}, 1115 []bool{false}), 1116 }, 1117 expect: testutil.NewFunctionTestResult(types.T_datetime.ToType(), false, 1118 []types.Datetime{d2}, 1119 []bool{false}), 1120 }, 1121 { 1122 info: "test from unix time float64", 1123 typ: types.T_float64, 1124 inputs: []testutil.FunctionTestInput{ 1125 testutil.NewFunctionTestInput(types.T_float64.ToType(), 1126 []float64{1451606400.999999}, 1127 []bool{false}), 1128 }, 1129 expect: testutil.NewFunctionTestResult(types.T_datetime.ToType(), false, 1130 []types.Datetime{d3}, 1131 []bool{false}), 1132 }, 1133 { 1134 info: "test from unix time float64", 1135 typ: types.T_varchar, 1136 inputs: []testutil.FunctionTestInput{ 1137 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1138 []int64{0}, 1139 []bool{false}), 1140 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), 1141 []string{"%b %M %m %c %D %d %e %j %k %h %i %p %r %T %s %f %v %x %Y %y"}, 1142 []bool{false}), 1143 }, 1144 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1145 []string{"Jan January 01 1 1st 01 1 001 0 12 00 AM 12:00:00 AM 00:00:00 00 000000 01 1970 1970 70"}, 1146 []bool{false}), 1147 }, 1148 } 1149 } 1150 1151 func newTmpProcess() *process.Process { 1152 return newProcessWithMPool(mpool.MustNewZero()) 1153 } 1154 1155 func newProcessWithMPool(mp *mpool.MPool) *process.Process { 1156 process := testutil.NewProcessWithMPool(mp) 1157 process.SessionInfo.TimeZone = time.FixedZone("UTC0", 0) 1158 return process 1159 } 1160 1161 func TestFromUnixTime(t *testing.T) { 1162 testCases := initFromUnixTimeTestCase() 1163 1164 // do the test work. 1165 proc := newTmpProcess() 1166 for _, tc := range testCases { 1167 var fcTC testutil.FunctionTestCase 1168 switch tc.typ { 1169 case types.T_int64: 1170 fcTC = testutil.NewFunctionTestCase(proc, 1171 tc.inputs, tc.expect, FromUnixTimeInt64) 1172 case types.T_uint64: 1173 fcTC = testutil.NewFunctionTestCase(proc, 1174 tc.inputs, tc.expect, FromUnixTimeUint64) 1175 case types.T_float64: 1176 fcTC = testutil.NewFunctionTestCase(proc, 1177 tc.inputs, tc.expect, FromUnixTimeFloat64) 1178 case types.T_varchar: 1179 fcTC = testutil.NewFunctionTestCase(proc, 1180 tc.inputs, tc.expect, FromUnixTimeInt64Format) 1181 } 1182 s, info := fcTC.Run() 1183 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1184 } 1185 } 1186 1187 func initSubStrTestCase() []tcTemp { 1188 return []tcTemp{ 1189 { 1190 info: "2", 1191 typ: types.T_varchar, 1192 inputs: []testutil.FunctionTestInput{ 1193 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1194 []string{"abcdefghijklmn"}, 1195 []bool{false}), 1196 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1197 []int64{5}, 1198 []bool{false}), 1199 }, 1200 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1201 []string{"efghijklmn"}, 1202 []bool{false}), 1203 }, 1204 { 1205 info: "2", 1206 typ: types.T_blob, 1207 inputs: []testutil.FunctionTestInput{ 1208 testutil.NewFunctionTestInput(types.T_blob.ToType(), 1209 []string{"abcdefghijklmn"}, 1210 []bool{false}), 1211 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1212 []int64{7}, 1213 []bool{false}), 1214 }, 1215 expect: testutil.NewFunctionTestResult(types.T_blob.ToType(), false, 1216 []string{"ghijklmn"}, 1217 []bool{false}), 1218 }, 1219 { 1220 info: "2", 1221 typ: types.T_text, 1222 inputs: []testutil.FunctionTestInput{ 1223 testutil.NewFunctionTestInput(types.T_text.ToType(), 1224 []string{"abcdefghijklmn"}, 1225 []bool{false}), 1226 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1227 []int64{11}, 1228 []bool{false}), 1229 }, 1230 expect: testutil.NewFunctionTestResult(types.T_text.ToType(), false, 1231 []string{"klmn"}, 1232 []bool{false}), 1233 }, 1234 1235 { 1236 info: "2", 1237 typ: types.T_varchar, 1238 inputs: []testutil.FunctionTestInput{ 1239 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1240 []string{"abcdefghijklmn"}, 1241 []bool{false}), 1242 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1243 []int64{16}, 1244 []bool{false}), 1245 }, 1246 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1247 []string{""}, 1248 []bool{false}), 1249 }, 1250 { 1251 info: "3", 1252 typ: types.T_varchar, 1253 inputs: []testutil.FunctionTestInput{ 1254 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1255 []string{"abcdefghijklmn"}, 1256 []bool{false}), 1257 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1258 []int64{5}, 1259 []bool{false}), 1260 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1261 []int64{6}, 1262 []bool{false}), 1263 }, 1264 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1265 []string{"efghij"}, 1266 []bool{false}), 1267 }, 1268 { 1269 info: "3", 1270 typ: types.T_varchar, 1271 inputs: []testutil.FunctionTestInput{ 1272 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1273 []string{"abcdefghijklmn"}, 1274 []bool{false}), 1275 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1276 []int64{6}, 1277 []bool{false}), 1278 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1279 []int64{-8}, 1280 []bool{false}), 1281 }, 1282 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1283 []string{""}, 1284 []bool{false}), 1285 }, 1286 { 1287 info: "3", 1288 typ: types.T_varchar, 1289 inputs: []testutil.FunctionTestInput{ 1290 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1291 []string{"abcdefghijklmn"}, 1292 []bool{false}), 1293 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1294 []int64{6}, 1295 []bool{false}), 1296 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1297 []int64{-9}, 1298 []bool{false}), 1299 }, 1300 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1301 []string{""}, 1302 []bool{false}), 1303 }, 1304 { 1305 info: "3", 1306 typ: types.T_varchar, 1307 inputs: []testutil.FunctionTestInput{ 1308 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1309 []string{"abcdefghijklmn"}, 1310 []bool{false}), 1311 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1312 []int64{-4}, 1313 []bool{false}), 1314 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1315 []int64{4}, 1316 []bool{false}), 1317 }, 1318 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1319 []string{"klmn"}, 1320 []bool{false}), 1321 }, 1322 { 1323 info: "3", 1324 typ: types.T_varchar, 1325 inputs: []testutil.FunctionTestInput{ 1326 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1327 []string{"abcdefghijklmn"}, 1328 []bool{false}), 1329 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1330 []int64{-14}, 1331 []bool{false}), 1332 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1333 []int64{14}, 1334 []bool{false}), 1335 }, 1336 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1337 []string{"abcdefghijklmn"}, 1338 []bool{false}), 1339 }, 1340 { 1341 info: "3", 1342 typ: types.T_varchar, 1343 inputs: []testutil.FunctionTestInput{ 1344 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1345 []string{"abcdefghijklmn"}, 1346 []bool{false}), 1347 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1348 []int64{-14}, 1349 []bool{false}), 1350 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1351 []int64{10}, 1352 []bool{false}), 1353 }, 1354 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1355 []string{"abcdefghij"}, 1356 []bool{false}), 1357 }, 1358 { 1359 info: "3", 1360 typ: types.T_varchar, 1361 inputs: []testutil.FunctionTestInput{ 1362 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1363 []string{"abcdefghijklmn"}, 1364 []bool{false}), 1365 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1366 []int64{-12}, 1367 []bool{false}), 1368 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1369 []int64{2}, 1370 []bool{false}), 1371 }, 1372 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1373 []string{"cd"}, 1374 []bool{false}), 1375 }, 1376 } 1377 } 1378 1379 func TestSubStr(t *testing.T) { 1380 testCases := initSubStrTestCase() 1381 1382 // do the test work. 1383 proc := testutil.NewProcess() 1384 for _, tc := range testCases { 1385 var fcTC testutil.FunctionTestCase 1386 switch tc.info { 1387 case "2": 1388 fcTC = testutil.NewFunctionTestCase(proc, 1389 tc.inputs, tc.expect, SubStringWith2Args) 1390 case "3": 1391 fcTC = testutil.NewFunctionTestCase(proc, 1392 tc.inputs, tc.expect, SubStringWith3Args) 1393 } 1394 s, info := fcTC.Run() 1395 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1396 } 1397 } 1398 1399 func initSubStrIndexTestCase() []tcTemp { 1400 return []tcTemp{ 1401 { 1402 info: "3", 1403 typ: types.T_varchar, 1404 inputs: []testutil.FunctionTestInput{ 1405 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1406 []string{"www.mysql.com"}, 1407 []bool{false}), 1408 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1409 []string{"."}, 1410 []bool{false}), 1411 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1412 []int64{0}, 1413 []bool{false}), 1414 }, 1415 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1416 []string{""}, 1417 []bool{false}), 1418 }, 1419 { 1420 info: "3", 1421 typ: types.T_varchar, 1422 inputs: []testutil.FunctionTestInput{ 1423 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1424 []string{"www.mysql.com"}, 1425 []bool{false}), 1426 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1427 []string{"."}, 1428 []bool{false}), 1429 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1430 []int64{1}, 1431 []bool{false}), 1432 }, 1433 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1434 []string{"www"}, 1435 []bool{false}), 1436 }, 1437 { 1438 info: "3", 1439 typ: types.T_varchar, 1440 inputs: []testutil.FunctionTestInput{ 1441 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1442 []string{"www.mysql.com"}, 1443 []bool{false}), 1444 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1445 []string{"."}, 1446 []bool{false}), 1447 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1448 []int64{2}, 1449 []bool{false}), 1450 }, 1451 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1452 []string{"www.mysql"}, 1453 []bool{false}), 1454 }, 1455 { 1456 info: "3", 1457 typ: types.T_varchar, 1458 inputs: []testutil.FunctionTestInput{ 1459 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1460 []string{"www.mysql.com"}, 1461 []bool{false}), 1462 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1463 []string{"."}, 1464 []bool{false}), 1465 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1466 []int64{3}, 1467 []bool{false}), 1468 }, 1469 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1470 []string{"www.mysql.com"}, 1471 []bool{false}), 1472 }, 1473 { 1474 info: "3", 1475 typ: types.T_varchar, 1476 inputs: []testutil.FunctionTestInput{ 1477 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1478 []string{"www.mysql.com"}, 1479 []bool{false}), 1480 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1481 []string{"."}, 1482 []bool{false}), 1483 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1484 []int64{-3}, 1485 []bool{false}), 1486 }, 1487 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1488 []string{"www.mysql.com"}, 1489 []bool{false}), 1490 }, 1491 { 1492 info: "3", 1493 typ: types.T_varchar, 1494 inputs: []testutil.FunctionTestInput{ 1495 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1496 []string{"www.mysql.com"}, 1497 []bool{false}), 1498 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1499 []string{"."}, 1500 []bool{false}), 1501 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1502 []int64{-2}, 1503 []bool{false}), 1504 }, 1505 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1506 []string{"mysql.com"}, 1507 []bool{false}), 1508 }, 1509 { 1510 info: "3", 1511 typ: types.T_varchar, 1512 inputs: []testutil.FunctionTestInput{ 1513 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1514 []string{"www.mysql.com"}, 1515 []bool{false}), 1516 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1517 []string{"."}, 1518 []bool{false}), 1519 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1520 []int64{-1}, 1521 []bool{false}), 1522 }, 1523 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1524 []string{"com"}, 1525 []bool{false}), 1526 }, 1527 { 1528 info: "3", 1529 typ: types.T_varchar, 1530 inputs: []testutil.FunctionTestInput{ 1531 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1532 []string{"xyz"}, 1533 []bool{false}), 1534 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1535 []string{"abc"}, 1536 []bool{false}), 1537 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1538 []int64{223372036854775808}, 1539 []bool{false}), 1540 }, 1541 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1542 []string{"xyz"}, 1543 []bool{false}), 1544 }, 1545 { 1546 info: "3", 1547 typ: types.T_varchar, 1548 inputs: []testutil.FunctionTestInput{ 1549 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1550 []string{"aaa.bbb.ccc.ddd.eee"}, 1551 []bool{false}), 1552 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1553 []string{"."}, 1554 []bool{false}), 1555 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1556 []int64{9223372036854775807}, 1557 []bool{false}), 1558 }, 1559 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1560 []string{"aaa.bbb.ccc.ddd.eee"}, 1561 []bool{false}), 1562 }, 1563 { 1564 info: "3", 1565 typ: types.T_varchar, 1566 inputs: []testutil.FunctionTestInput{ 1567 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1568 []string{"aaa.bbb.ccc.ddd.eee"}, 1569 []bool{false}), 1570 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1571 []string{"."}, 1572 []bool{false}), 1573 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1574 []int64{-9223372036854775808}, 1575 []bool{false}), 1576 }, 1577 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1578 []string{"aaa.bbb.ccc.ddd.eee"}, 1579 []bool{false}), 1580 }, 1581 { 1582 info: "3", 1583 typ: types.T_varchar, 1584 inputs: []testutil.FunctionTestInput{ 1585 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1586 []string{"aaa.bbb.ccc.ddd.eee"}, 1587 []bool{false}), 1588 testutil.NewFunctionTestInput(types.T_varchar.ToType(), 1589 []string{"."}, 1590 []bool{false}), 1591 testutil.NewFunctionTestInput(types.T_int64.ToType(), 1592 []int64{int64(922337203685477580)}, 1593 []bool{false}), 1594 }, 1595 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 1596 []string{"aaa.bbb.ccc.ddd.eee"}, 1597 []bool{false}), 1598 }, 1599 } 1600 } 1601 1602 func TestSubStrIndex(t *testing.T) { 1603 testCases := initSubStrIndexTestCase() 1604 1605 // do the test work. 1606 proc := testutil.NewProcess() 1607 for _, tc := range testCases { 1608 fcTC := testutil.NewFunctionTestCase(proc, 1609 tc.inputs, tc.expect, SubStrIndex[int64]) 1610 s, info := fcTC.Run() 1611 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1612 } 1613 } 1614 1615 func initTimeDiffInTimeTestCase() []tcTemp { 1616 //Test Set 1 1617 t11, _ := types.ParseTime("22:22:22", 6) 1618 t12, _ := types.ParseTime("11:11:11", 6) 1619 r1, _ := types.ParseTime("11:11:11", 6) 1620 1621 t21, _ := types.ParseTime("22:22:22", 6) 1622 t22, _ := types.ParseTime("-11:11:11", 6) 1623 r2, _ := types.ParseTime("33:33:33", 6) 1624 1625 t31, _ := types.ParseTime("-22:22:22", 6) 1626 t32, _ := types.ParseTime("11:11:11", 6) 1627 r3, _ := types.ParseTime("-33:33:33", 6) 1628 1629 t41, _ := types.ParseTime("-22:22:22", 6) 1630 t42, _ := types.ParseTime("-11:11:11", 6) 1631 r4, _ := types.ParseTime("-11:11:11", 6) 1632 1633 //Test Set 2 1634 t51, _ := types.ParseTime("11:11:11", 6) 1635 t52, _ := types.ParseTime("22:22:22", 6) 1636 r5, _ := types.ParseTime("-11:11:11", 6) 1637 1638 t61, _ := types.ParseTime("11:11:11", 6) 1639 t62, _ := types.ParseTime("-22:22:22", 6) 1640 r6, _ := types.ParseTime("33:33:33", 6) 1641 1642 t71, _ := types.ParseTime("-11:11:11", 6) 1643 t72, _ := types.ParseTime("22:22:22", 6) 1644 r7, _ := types.ParseTime("-33:33:33", 6) 1645 1646 t81, _ := types.ParseTime("-11:11:11", 6) 1647 t82, _ := types.ParseTime("-22:22:22", 6) 1648 r8, _ := types.ParseTime("11:11:11", 6) 1649 1650 //Test Set 3 1651 t91, _ := types.ParseTime("-2562047787:59:59", 6) 1652 t92, _ := types.ParseTime("-2562047787:59:59", 6) 1653 r9, _ := types.ParseTime("00:00:00", 6) 1654 1655 t101, _ := types.ParseTime("2562047787:59:59", 6) 1656 t102, _ := types.ParseTime("2562047787:59:59", 6) 1657 r10, _ := types.ParseTime("00:00:00", 6) 1658 1659 bb := make([]bool, 10) 1660 return []tcTemp{ 1661 { 1662 info: "test timediff time 1", 1663 inputs: []testutil.FunctionTestInput{ 1664 testutil.NewFunctionTestInput(types.T_time.ToType(), []types.Time{t11, t21, t31, t41, t51, t61, t71, t81, t91, t101}, bb), 1665 testutil.NewFunctionTestInput(types.T_time.ToType(), []types.Time{t12, t22, t32, t42, t52, t62, t72, t82, t92, t102}, bb), 1666 }, 1667 expect: testutil.NewFunctionTestResult(types.T_time.ToType(), false, []types.Time{r1, r2, r3, r4, r5, r6, r7, r8, r9, r10}, bb), 1668 }, 1669 } 1670 } 1671 1672 func TestTimeDiffInTime(t *testing.T) { 1673 testCases := initTimeDiffInTimeTestCase() 1674 1675 proc := testutil.NewProcess() 1676 for _, tc := range testCases { 1677 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, TimeDiff[types.Time]) 1678 s, info := fcTC.Run() 1679 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1680 } 1681 } 1682 1683 func initTimeDiffInDatetimeTestCase() []tcTemp { 1684 // Test case 1 1685 t11, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1686 t12, _ := types.ParseDatetime("2012-12-12 11:11:11", 6) 1687 r1, _ := types.ParseTime("11:11:11", 0) 1688 1689 // Test case 2 1690 t21, _ := types.ParseDatetime("2012-12-12 11:11:11", 6) 1691 t22, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1692 r2, _ := types.ParseTime("-11:11:11", 0) 1693 1694 // Test case 3 1695 t31, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1696 t32, _ := types.ParseDatetime("2000-12-12 11:11:11", 6) 1697 r3, _ := types.ParseTime("105203:11:11", 0) 1698 1699 // Test case 4 1700 t41, _ := types.ParseDatetime("2000-12-12 11:11:11", 6) 1701 t42, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1702 r4, _ := types.ParseTime("-105203:11:11", 0) 1703 1704 // Test case 5 1705 t51, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1706 t52, _ := types.ParseDatetime("2012-10-10 11:11:11", 6) 1707 r5, _ := types.ParseTime("1523:11:11", 0) 1708 1709 // Test case 6 1710 t61, _ := types.ParseDatetime("2012-10-10 11:11:11", 6) 1711 t62, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1712 r6, _ := types.ParseTime("-1523:11:11", 0) 1713 1714 // Test case 7 1715 t71, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1716 t72, _ := types.ParseDatetime("2012-12-10 11:11:11", 6) 1717 r7, _ := types.ParseTime("59:11:11", 0) 1718 1719 // Test case 8 1720 t81, _ := types.ParseDatetime("2012-12-10 11:11:11", 6) 1721 t82, _ := types.ParseDatetime("2012-12-12 22:22:22", 6) 1722 r8, _ := types.ParseTime("-59:11:11", 0) 1723 1724 // Test case 9 1725 t91, _ := types.ParseDatetime("2012-12-10 11:11:11", 6) 1726 t92, _ := types.ParseDatetime("2012-12-10 11:11:11", 6) 1727 r9, _ := types.ParseTime("00:00:00", 0) 1728 1729 return []tcTemp{ 1730 { 1731 info: "test Datetimediff Datetime 1", 1732 inputs: []testutil.FunctionTestInput{ 1733 testutil.NewFunctionTestInput(types.T_datetime.ToType(), []types.Datetime{t11, t21, t31, t41, t51, t61, t71, t81, t91}, []bool{}), 1734 testutil.NewFunctionTestInput(types.T_datetime.ToType(), []types.Datetime{t12, t22, t32, t42, t52, t62, t72, t82, t92}, []bool{}), 1735 }, 1736 expect: testutil.NewFunctionTestResult(types.T_time.ToType(), false, []types.Time{r1, r2, r3, r4, r5, r6, r7, r8, r9}, []bool{}), 1737 }, 1738 } 1739 } 1740 1741 func TestTimeDiffInDateTime(t *testing.T) { 1742 testCases := initTimeDiffInDatetimeTestCase() 1743 1744 proc := testutil.NewProcess() 1745 for _, tc := range testCases { 1746 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, TimeDiff[types.Datetime]) 1747 s, info := fcTC.Run() 1748 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1749 } 1750 } 1751 1752 // TIMESTAMPDIFF 1753 1754 func initTimestampDiffTestCase() []tcTemp { 1755 // FIXME: Migrating the testcases as it was from the original functions code. May refactor it later. Original code: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/multi/timestampdiff_test.go#L35 1756 cases := []struct { 1757 name string 1758 inputs []string 1759 want int64 1760 }{ 1761 { 1762 name: "TEST01", 1763 inputs: []string{"2017-12-01 12:15:12", "2018-01-01 7:18:20", "microsecond"}, 1764 want: 2660588000000, 1765 }, 1766 { 1767 name: "TEST02", 1768 inputs: []string{"2017-12-01 12:15:12", "2018-01-01 7:18:20", "second"}, 1769 want: 2660588, 1770 }, 1771 { 1772 name: "TEST03", 1773 inputs: []string{"2017-12-01 12:15:12", "2018-01-01 7:18:20", "minute"}, 1774 want: 44343, 1775 }, 1776 { 1777 name: "TEST04", 1778 inputs: []string{"2017-12-01 12:15:12", "2018-01-01 7:18:20", "hour"}, 1779 want: 739, 1780 }, 1781 { 1782 name: "TEST05", 1783 inputs: []string{"2017-12-01 12:15:12", "2018-01-01 7:18:20", "day"}, 1784 want: 30, 1785 }, 1786 { 1787 name: "TEST06", 1788 inputs: []string{"2017-12-01 12:15:12", "2018-01-08 12:15:12", "week"}, 1789 want: 5, 1790 }, 1791 { 1792 name: "TEST07", 1793 inputs: []string{"2017-11-01 12:15:12", "2018-01-01 12:15:12", "month"}, 1794 want: 2, 1795 }, 1796 { 1797 name: "TEST08", 1798 inputs: []string{"2017-01-01 12:15:12", "2018-01-01 12:15:12", "quarter"}, 1799 want: 4, 1800 }, 1801 { 1802 name: "TEST09", 1803 inputs: []string{"2017-01-01 12:15:12", "2018-01-01 12:15:12", "year"}, 1804 want: 1, 1805 }, 1806 { 1807 name: "TEST10", 1808 inputs: []string{"2018-01-01 7:18:20", "2017-12-01 12:15:12", "microsecond"}, 1809 want: -2660588000000, 1810 }, 1811 { 1812 name: "TEST11", 1813 inputs: []string{"2018-01-01 7:18:20", "2017-12-01 12:15:12", "second"}, 1814 want: -2660588, 1815 }, 1816 { 1817 name: "TEST12", 1818 inputs: []string{"2018-01-01 7:18:20", "2017-12-01 12:15:12", "minute"}, 1819 1820 want: -44343, 1821 }, 1822 { 1823 name: "TEST13", 1824 inputs: []string{"2018-01-01 7:18:20", "2017-12-01 12:15:12", "hour"}, 1825 1826 want: -739, 1827 }, 1828 { 1829 name: "TEST14", 1830 inputs: []string{"2018-01-01 7:18:20", "2017-12-01 12:15:12", "day"}, 1831 1832 want: -30, 1833 }, 1834 { 1835 name: "TEST15", 1836 inputs: []string{"2018-01-08 12:15:12", "2017-12-01 12:15:12", "week"}, 1837 want: -5, 1838 }, 1839 { 1840 name: "TEST16", 1841 inputs: []string{"2018-01-01 12:15:12", "2017-11-01 12:15:12", "month"}, 1842 want: -2, 1843 }, 1844 { 1845 name: "TEST17", 1846 inputs: []string{"2018-01-01 12:15:12", "2017-01-01 12:15:12", "quarter"}, 1847 want: -4, 1848 }, 1849 { 1850 name: "TEST18", 1851 inputs: []string{"2018-01-01 12:15:12", "2017-01-01 12:15:12", "year"}, 1852 want: -1, 1853 }, 1854 } 1855 1856 var testInputs = make([]tcTemp, 0, len(cases)) 1857 for _, c := range cases { 1858 1859 i1 := c.inputs[2] 1860 i2, _ := types.ParseDatetime(c.inputs[0], 6) 1861 i3, _ := types.ParseDatetime(c.inputs[1], 6) 1862 1863 o := c.want 1864 1865 testInputs = append(testInputs, tcTemp{ 1866 1867 info: "test TimestampDiff " + c.name, 1868 inputs: []testutil.FunctionTestInput{ 1869 // Create a input entry <String, Datetime1, Datetime2> 1870 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{i1}, []bool{}), 1871 testutil.NewFunctionTestInput(types.T_datetime.ToType(), []types.Datetime{i2}, []bool{}), 1872 testutil.NewFunctionTestInput(types.T_datetime.ToType(), []types.Datetime{i3}, []bool{}), 1873 }, 1874 expect: testutil.NewFunctionTestResult(types.T_int64.ToType(), false, []int64{o}, []bool{}), 1875 }) 1876 } 1877 1878 return testInputs 1879 } 1880 1881 func TestTimestampDiff(t *testing.T) { 1882 testCases := initTimestampDiffTestCase() 1883 1884 proc := testutil.NewProcess() 1885 for _, tc := range testCases { 1886 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, TimestampDiff) 1887 s, info := fcTC.Run() 1888 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1889 } 1890 } 1891 1892 // StartsWith 1893 1894 func initStartsWithTestCase() []tcTemp { 1895 // FIXME: Migrating the testcases as it was from the original functions code. May refactor it later. Original code:https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/startswith_test.go#L28 1896 var charVecBase = []string{"-123", "123", "+123", "8", ""} 1897 var charVecBase2 = []string{"-", "+", "1", ""} 1898 var nsp1, nsp2 []uint64 1899 var origVecs = make([]testutil.FunctionTestInput, 2) 1900 n1, n2 := len(charVecBase), len(charVecBase2) 1901 inputVec := make([]string, n1*n2) 1902 inputVec2 := make([]string, len(inputVec)) 1903 for i := 0; i < len(inputVec); i++ { 1904 inputVec[i] = charVecBase[i/n2] 1905 inputVec2[i] = charVecBase2[i%n2] 1906 if (i / n2) == (n1 - 1) { 1907 nsp1 = append(nsp1, uint64(i)) 1908 } 1909 if (i % n2) == (n2 - 1) { 1910 nsp2 = append(nsp2, uint64(i)) 1911 } 1912 } 1913 1914 makeFunctionTestInputEndsWith := func(values []string, nsp []uint64) testutil.FunctionTestInput { 1915 totalCount := len(values) 1916 strs := make([]string, totalCount) 1917 nulls := make([]bool, totalCount) 1918 for i := 0; i < totalCount; i++ { 1919 strs[i] = values[i] 1920 } 1921 for i := 0; i < len(nsp); i++ { 1922 idx := nsp[i] 1923 nulls[idx] = true 1924 } 1925 return testutil.NewFunctionTestInput(types.T_varchar.ToType(), strs, nulls) 1926 } 1927 1928 origVecs[0] = makeFunctionTestInputEndsWith(inputVec, nsp1) 1929 origVecs[1] = makeFunctionTestInputEndsWith(inputVec2, nsp2) 1930 1931 return []tcTemp{ 1932 { 1933 info: "test StartsWith", 1934 inputs: []testutil.FunctionTestInput{ 1935 origVecs[0], 1936 origVecs[1], 1937 }, 1938 expect: testutil.NewFunctionTestResult(types.T_bool.ToType(), false, 1939 []bool{true, false, false, true, false, false, true, true, false, true, false, true, false, false, false, true, false, false, false, true}, 1940 []bool{false, false, false, true, false, false, false, true, false, false, false, true, false, false, false, true, true, true, true, true}), 1941 }, 1942 } 1943 } 1944 1945 func TestStartsWith(t *testing.T) { 1946 testCases := initStartsWithTestCase() 1947 1948 // do the test work. 1949 proc := testutil.NewProcess() 1950 for _, tc := range testCases { 1951 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, StartsWith) 1952 s, info := fcTC.Run() 1953 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 1954 } 1955 } 1956 1957 // EndsWith 1958 1959 func initEndsWithTestCase() []tcTemp { 1960 // FIXME: Migrating the testcases as it was from the original functions code. May refactor it later. Original code:https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/endswith_test.go#L29 1961 var charVecBase = []string{"123-", "321", "123+", "8", ""} 1962 var charVecBase2 = []string{"-", "+", "1", ""} 1963 var nsp1, nsp2 []uint64 1964 var origVecs = make([]testutil.FunctionTestInput, 2) 1965 n1, n2 := len(charVecBase), len(charVecBase2) 1966 inputVec := make([]string, n1*n2) 1967 inputVec2 := make([]string, len(inputVec)) 1968 for i := 0; i < len(inputVec); i++ { 1969 inputVec[i] = charVecBase[i/n2] 1970 inputVec2[i] = charVecBase2[i%n2] 1971 if (i / n2) == (n1 - 1) { 1972 nsp1 = append(nsp1, uint64(i)) 1973 } 1974 if (i % n2) == (n2 - 1) { 1975 nsp2 = append(nsp2, uint64(i)) 1976 } 1977 } 1978 1979 makeFunctionTestInputEndsWith := func(values []string, nsp []uint64) testutil.FunctionTestInput { 1980 totalCount := len(values) 1981 strs := make([]string, totalCount) 1982 nulls := make([]bool, totalCount) 1983 for i := 0; i < totalCount; i++ { 1984 strs[i] = values[i] 1985 } 1986 for i := 0; i < len(nsp); i++ { 1987 idx := nsp[i] 1988 nulls[idx] = true 1989 } 1990 return testutil.NewFunctionTestInput(types.T_varchar.ToType(), strs, nulls) 1991 } 1992 1993 origVecs[0] = makeFunctionTestInputEndsWith(inputVec, nsp1) 1994 origVecs[1] = makeFunctionTestInputEndsWith(inputVec2, nsp2) 1995 1996 return []tcTemp{ 1997 { 1998 info: "test EndsWith", 1999 inputs: []testutil.FunctionTestInput{ 2000 origVecs[0], 2001 origVecs[1], 2002 }, 2003 expect: testutil.NewFunctionTestResult(types.T_bool.ToType(), false, 2004 []bool{true, false, false, true, false, false, true, true, false, true, false, true, false, false, false, true, false, false, false, true}, 2005 []bool{false, false, false, true, false, false, false, true, false, false, false, true, false, false, false, true, true, true, true, true}), 2006 }, 2007 } 2008 } 2009 2010 func TestEndsWith(t *testing.T) { 2011 testCases := initEndsWithTestCase() 2012 2013 // do the test work. 2014 proc := testutil.NewProcess() 2015 for _, tc := range testCases { 2016 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, EndsWith) 2017 s, info := fcTC.Run() 2018 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2019 } 2020 } 2021 2022 // FindInSet 2023 2024 func initFindInSetTestCase() []tcTemp { 2025 2026 return []tcTemp{ 2027 { 2028 info: "test findinset", 2029 inputs: []testutil.FunctionTestInput{ 2030 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{ 2031 "abc", 2032 "xyz", 2033 "z", 2034 "abc", //TODO: Ignoring the scalar checks. Please fix. Original code:https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/findinset_test.go#L67 2035 "abc", 2036 "abc", 2037 "", 2038 "abc", 2039 }, 2040 []bool{ 2041 false, 2042 false, 2043 false, 2044 false, 2045 false, 2046 false, 2047 true, 2048 false, 2049 }), 2050 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{ 2051 "abc,def", 2052 "dec,xyz,abc", 2053 "a,e,c,z", 2054 "abc,def", 2055 "abc,def", 2056 "abc,def", 2057 "abc", 2058 "", 2059 }, 2060 []bool{ 2061 false, 2062 false, 2063 false, 2064 false, 2065 false, 2066 false, 2067 false, 2068 true, 2069 }), 2070 }, 2071 expect: testutil.NewFunctionTestResult(types.T_uint64.ToType(), false, 2072 []uint64{ 2073 1, 2074 2, 2075 4, 2076 1, 2077 1, 2078 1, 2079 0, 2080 0, 2081 }, 2082 []bool{ 2083 false, 2084 false, 2085 false, 2086 false, 2087 false, 2088 false, 2089 true, 2090 true, 2091 }, 2092 ), 2093 }, 2094 } 2095 } 2096 2097 func TestFindInSet(t *testing.T) { 2098 testCases := initFindInSetTestCase() 2099 2100 // do the test work. 2101 proc := testutil.NewProcess() 2102 for _, tc := range testCases { 2103 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, FindInSet) 2104 s, info := fcTC.Run() 2105 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2106 } 2107 } 2108 2109 // INSTR 2110 func initInstrTestCase() []tcTemp { 2111 cases := []struct { 2112 strs []string 2113 substrs []string 2114 wants []int64 2115 }{ 2116 { 2117 strs: []string{"abc", "abc", "abc", "abc", "abc"}, 2118 substrs: []string{"bc", "b", "abc", "a", "dca"}, 2119 wants: []int64{2, 2, 1, 1, 0}, 2120 }, 2121 { 2122 strs: []string{"abc", "abc", "abc", "abc", "abc"}, 2123 substrs: []string{"", "", "a", "b", "c"}, 2124 wants: []int64{1, 1, 1, 2, 3}, 2125 }, 2126 //TODO: @m-schen. Please fix these. Original code: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/instr_test.go#L43 2127 //{ 2128 // strs: []string{"abc", "abc", "abc", "abc", "abc"}, 2129 // substrs: []string{"bc"}, 2130 // wants: []int64{2, 2, 2, 2, 2}, 2131 //}, 2132 //{ 2133 // strs: []string{"abc"}, 2134 // substrs: []string{"bc", "b", "abc", "a", "dca"}, 2135 // wants: []int64{2, 2, 1, 1, 0}, 2136 //}, 2137 } 2138 2139 var testInputs = make([]tcTemp, 0, len(cases)) 2140 for _, c := range cases { 2141 2142 testInputs = append(testInputs, tcTemp{ 2143 2144 info: "test instr ", 2145 inputs: []testutil.FunctionTestInput{ 2146 // Create a input entry <strs, substrs> 2147 testutil.NewFunctionTestInput(types.T_varchar.ToType(), c.strs, []bool{}), 2148 testutil.NewFunctionTestInput(types.T_varchar.ToType(), c.substrs, []bool{}), 2149 }, 2150 expect: testutil.NewFunctionTestResult(types.T_int64.ToType(), false, c.wants, []bool{}), 2151 }) 2152 } 2153 2154 return testInputs 2155 2156 } 2157 2158 func TestInstr(t *testing.T) { 2159 testCases := initInstrTestCase() 2160 2161 proc := testutil.NewProcess() 2162 for _, tc := range testCases { 2163 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, Instr) 2164 s, info := fcTC.Run() 2165 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2166 } 2167 } 2168 2169 // Left 2170 func initLeftTestCase() []tcTemp { 2171 cases := []struct { 2172 s string 2173 len int64 2174 want string 2175 }{ 2176 { 2177 "abcde", 2178 3, 2179 "abc", 2180 }, 2181 { 2182 "abcde", 2183 0, 2184 "", 2185 }, 2186 { 2187 "abcde", 2188 -1, 2189 "", 2190 }, 2191 { 2192 "abcde", 2193 100, 2194 "abcde", 2195 }, 2196 { 2197 "foobarbar", 2198 5, 2199 "fooba", 2200 }, 2201 2202 // TestLeft1 2203 { 2204 "是都方式快递费", 2205 3, 2206 "是都方", 2207 }, 2208 { 2209 "アイウエオ", 2210 3, 2211 "アイウ", 2212 }, 2213 { 2214 "アイウエオ ", 2215 3, 2216 "アイウ", 2217 }, 2218 { 2219 "アイウエオ ", 2220 3, 2221 "アイウ", 2222 }, 2223 { 2224 "アイウエオ ", 2225 3, 2226 "アイウ", 2227 }, 2228 { 2229 "あいうえお", 2230 3, 2231 "あいう", 2232 }, 2233 { 2234 "あいうえお ", 2235 3, 2236 "あいう", 2237 }, 2238 { 2239 "あいうえお ", 2240 3, 2241 "あいう", 2242 }, 2243 { 2244 "あいうえお ", 2245 3, 2246 "あいう", 2247 }, 2248 { 2249 "龔龖龗龞龡", 2250 3, 2251 "龔龖龗", 2252 }, 2253 { 2254 "龔龖龗龞龡 ", 2255 3, 2256 "龔龖龗", 2257 }, 2258 { 2259 "龔龖龗龞龡 ", 2260 3, 2261 "龔龖龗", 2262 }, 2263 { 2264 "龔龖龗龞龡 ", 2265 3, 2266 "龔龖龗", 2267 }, 2268 { 2269 "2017-06-15 ", 2270 8, 2271 "2017-06-", 2272 }, 2273 { 2274 "2019-06-25 ", 2275 8, 2276 "2019-06-", 2277 }, 2278 { 2279 " 2019-06-25 ", 2280 8, 2281 " 2019", 2282 }, 2283 { 2284 " 2019-06-25 ", 2285 8, 2286 " 2019-", 2287 }, 2288 { 2289 " 2012-10-12 ", 2290 8, 2291 " 2012", 2292 }, 2293 { 2294 " 2004-04-24. ", 2295 8, 2296 " 2004-", 2297 }, 2298 { 2299 " 2008-12-04. ", 2300 8, 2301 " 2008-", 2302 }, 2303 { 2304 " 2012-03-23. ", 2305 8, 2306 " 2012", 2307 }, 2308 { 2309 " 2013-04-30 ", 2310 8, 2311 " 2013", 2312 }, 2313 { 2314 " 1994-10-04 ", 2315 8, 2316 " 1994-1", 2317 }, 2318 { 2319 " 2018-06-04 ", 2320 8, 2321 " 2018-", 2322 }, 2323 { 2324 " 2012-10-12 ", 2325 8, 2326 " 2012-10", 2327 }, 2328 { 2329 "1241241^&@%#^*^!@#&*(!& ", 2330 12, 2331 "1241241^&@%#", 2332 }, 2333 { 2334 " 123 ", 2335 2, 2336 " 1", 2337 }, 2338 } 2339 2340 var testInputs = make([]tcTemp, 0, len(cases)) 2341 for _, c := range cases { 2342 2343 testInputs = append(testInputs, tcTemp{ 2344 2345 //TODO: Avoiding TestLeft2. Original code: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/left_test.go#L247 2346 info: "test left ", 2347 inputs: []testutil.FunctionTestInput{ 2348 // Create a input entry <str, int> 2349 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{c.s}, []bool{}), 2350 testutil.NewFunctionTestInput(types.T_int64.ToType(), []int64{c.len}, []bool{}), 2351 }, 2352 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{c.want}, []bool{}), 2353 }) 2354 } 2355 2356 return testInputs 2357 2358 } 2359 2360 func TestLeft(t *testing.T) { 2361 testCases := initLeftTestCase() 2362 2363 proc := testutil.NewProcess() 2364 for _, tc := range testCases { 2365 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, Left) 2366 s, info := fcTC.Run() 2367 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2368 } 2369 } 2370 2371 // POWER 2372 func initPowerTestCase() []tcTemp { 2373 cases := []struct { 2374 left float64 2375 right float64 2376 want float64 2377 }{ 2378 {1, 2, 1}, 2379 {2, 2, 4}, 2380 {3, 2, 9}, 2381 {3, 3, 27}, 2382 {4, 2, 16}, 2383 {4, 3, 64}, 2384 {4, 0.5, 2}, 2385 {5, 2, 25}, 2386 {6, 2, 36}, 2387 {7, 2, 49}, 2388 {8, 2, 64}, 2389 {0.5, 2, 0.25}, 2390 {1.5, 2, 2.25}, 2391 {2.5, 2, 6.25}, 2392 {3.5, 2, 12.25}, 2393 {4.5, 2, 20.25}, 2394 {5.5, 2, 30.25}, 2395 } 2396 2397 var testInputs = make([]tcTemp, 0, len(cases)) 2398 for _, c := range cases { 2399 2400 testInputs = append(testInputs, tcTemp{ 2401 info: "test pow ", 2402 inputs: []testutil.FunctionTestInput{ 2403 // Create a input entry <float64, float64> 2404 testutil.NewFunctionTestInput(types.T_float64.ToType(), []float64{c.left}, []bool{}), 2405 testutil.NewFunctionTestInput(types.T_float64.ToType(), []float64{c.right}, []bool{}), 2406 }, 2407 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, []float64{c.want}, []bool{}), 2408 }) 2409 } 2410 2411 return testInputs 2412 } 2413 2414 func TestPower(t *testing.T) { 2415 testCases := initPowerTestCase() 2416 2417 // do the test work. 2418 proc := testutil.NewProcess() 2419 for _, tc := range testCases { 2420 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, Power) 2421 s, info := fcTC.Run() 2422 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2423 } 2424 } 2425 2426 // SQRT 2427 func initSqrtTestCase() []tcTemp { 2428 return []tcTemp{ 2429 { 2430 info: "test sqrt regular", 2431 inputs: []testutil.FunctionTestInput{ 2432 testutil.NewFunctionTestInput(types.T_float64.ToType(), 2433 []float64{1, 4, 2, 10, 25, 10000, 0, 0, 1.41}, 2434 []bool{false, false, false, false, false, false, true, false, false}), 2435 }, 2436 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2437 []float64{1, 2, 1.4142135623730951, 3.1622776601683795, 5, 100, 0, 0, 1.1874342087037917}, 2438 []bool{false, false, false, false, false, false, true, false, false, true}), 2439 }, 2440 { 2441 info: "test sqrt error", 2442 inputs: []testutil.FunctionTestInput{ 2443 testutil.NewFunctionTestInput(types.T_float64.ToType(), []float64{-2}, nil), 2444 }, 2445 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), true, nil, nil), 2446 }, 2447 } 2448 } 2449 2450 func TestSqrt(t *testing.T) { 2451 testCases := initSqrtTestCase() 2452 2453 proc := testutil.NewProcess() 2454 for _, tc := range testCases { 2455 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, builtInSqrt) 2456 s, info := fcTC.Run() 2457 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2458 } 2459 } 2460 2461 func initSqrtArrayTestCase() []tcTemp { 2462 return []tcTemp{ 2463 { 2464 info: "test sqrt float32 array", 2465 typ: types.T_array_float32, 2466 inputs: []testutil.FunctionTestInput{ 2467 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), 2468 [][]float32{{4, 9, 16}, {0, 25, 49}}, 2469 []bool{false, false}), 2470 }, 2471 expect: testutil.NewFunctionTestResult(types.T_array_float64.ToType(), false, 2472 //NOTE: SQRT(vecf32) --> vecf64 2473 [][]float64{{2, 3, 4}, {0, 5, 7}}, 2474 []bool{false, false}), 2475 }, 2476 { 2477 info: "test sqrt float64 array", 2478 typ: types.T_array_float64, 2479 inputs: []testutil.FunctionTestInput{ 2480 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), 2481 [][]float64{{4, 9, 16}, {0, 25, 49}}, 2482 []bool{false, false}), 2483 }, 2484 expect: testutil.NewFunctionTestResult(types.T_array_float64.ToType(), false, 2485 [][]float64{{2, 3, 4}, {0, 5, 7}}, 2486 []bool{false, false}), 2487 }, 2488 } 2489 } 2490 2491 func TestSqrtArray(t *testing.T) { 2492 testCases := initSqrtArrayTestCase() 2493 2494 proc := testutil.NewProcess() 2495 for _, tc := range testCases { 2496 var fcTC testutil.FunctionTestCase 2497 switch tc.typ { 2498 case types.T_array_float32: 2499 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, builtInSqrtArray[float32]) 2500 case types.T_array_float64: 2501 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, builtInSqrtArray[float64]) 2502 } 2503 s, info := fcTC.Run() 2504 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2505 } 2506 } 2507 2508 // Inner Product 2509 func initInnerProductArrayTestCase() []tcTemp { 2510 return []tcTemp{ 2511 { 2512 info: "test InnerProduct float32 array", 2513 typ: types.T_array_float32, 2514 inputs: []testutil.FunctionTestInput{ 2515 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2516 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2517 }, 2518 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2519 []float64{14, 77}, 2520 []bool{false, false}), 2521 }, 2522 { 2523 info: "test InnerProduct float64 array", 2524 typ: types.T_array_float64, 2525 inputs: []testutil.FunctionTestInput{ 2526 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2527 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2528 }, 2529 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2530 []float64{14, 77}, 2531 []bool{false, false}), 2532 }, 2533 } 2534 } 2535 2536 func TestInnerProductArray(t *testing.T) { 2537 testCases := initInnerProductArrayTestCase() 2538 2539 proc := testutil.NewProcess() 2540 for _, tc := range testCases { 2541 var fcTC testutil.FunctionTestCase 2542 switch tc.typ { 2543 case types.T_array_float32: 2544 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, InnerProductArray[float32]) 2545 case types.T_array_float64: 2546 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, InnerProductArray[float64]) 2547 } 2548 s, info := fcTC.Run() 2549 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2550 } 2551 } 2552 2553 // Cosine Similarity 2554 func initCosineSimilarityArrayTestCase() []tcTemp { 2555 return []tcTemp{ 2556 { 2557 info: "test CosineSimilarity float32 array", 2558 typ: types.T_array_float32, 2559 inputs: []testutil.FunctionTestInput{ 2560 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2561 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2562 }, 2563 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2564 []float64{1, 1}, 2565 []bool{false, false}), 2566 }, 2567 { 2568 info: "test CosineSimilarity float64 array", 2569 typ: types.T_array_float64, 2570 inputs: []testutil.FunctionTestInput{ 2571 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2572 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2573 }, 2574 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2575 []float64{1, 1}, 2576 []bool{false, false}), 2577 }, 2578 } 2579 } 2580 2581 func TestCosineSimilarityArray(t *testing.T) { 2582 testCases := initCosineSimilarityArrayTestCase() 2583 2584 proc := testutil.NewProcess() 2585 for _, tc := range testCases { 2586 var fcTC testutil.FunctionTestCase 2587 switch tc.typ { 2588 case types.T_array_float32: 2589 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, CosineSimilarityArray[float32]) 2590 case types.T_array_float64: 2591 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, CosineSimilarityArray[float64]) 2592 } 2593 s, info := fcTC.Run() 2594 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2595 } 2596 } 2597 2598 // L2 Distance 2599 func initL2DistanceArrayTestCase() []tcTemp { 2600 return []tcTemp{ 2601 { 2602 info: "test L2Distance float32 array", 2603 typ: types.T_array_float32, 2604 inputs: []testutil.FunctionTestInput{ 2605 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2606 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{10, 20, 30}, {40, 50, 60}}, []bool{false, false}), 2607 }, 2608 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2609 []float64{33.67491648096547, 78.9746794865291}, 2610 []bool{false, false}), 2611 }, 2612 { 2613 info: "test L2Distance float64 array", 2614 typ: types.T_array_float64, 2615 inputs: []testutil.FunctionTestInput{ 2616 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2617 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{10, 20, 30}, {40, 50, 60}}, []bool{false, false}), 2618 }, 2619 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2620 []float64{33.67491648096547, 78.9746794865291}, 2621 []bool{false, false}), 2622 }, 2623 } 2624 } 2625 2626 func TestL2DistanceArray(t *testing.T) { 2627 testCases := initL2DistanceArrayTestCase() 2628 2629 proc := testutil.NewProcess() 2630 for _, tc := range testCases { 2631 var fcTC testutil.FunctionTestCase 2632 switch tc.typ { 2633 case types.T_array_float32: 2634 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, L2DistanceArray[float32]) 2635 case types.T_array_float64: 2636 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, L2DistanceArray[float64]) 2637 } 2638 s, info := fcTC.Run() 2639 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2640 } 2641 } 2642 2643 // Cosine Distance 2644 func initCosineDistanceArrayTestCase() []tcTemp { 2645 return []tcTemp{ 2646 { 2647 info: "test CosineDistance float32 array", 2648 typ: types.T_array_float32, 2649 inputs: []testutil.FunctionTestInput{ 2650 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2651 testutil.NewFunctionTestInput(types.T_array_float32.ToType(), [][]float32{{10, 20, 30}, {5, 6, 7}}, []bool{false, false}), 2652 }, 2653 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2654 []float64{0, 0.0003542540112345671}, 2655 []bool{false, false}), 2656 }, 2657 { 2658 info: "test CosineDistance float64 array", 2659 typ: types.T_array_float64, 2660 inputs: []testutil.FunctionTestInput{ 2661 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{1, 2, 3}, {4, 5, 6}}, []bool{false, false}), 2662 testutil.NewFunctionTestInput(types.T_array_float64.ToType(), [][]float64{{10, 20, 30}, {5, 6, 7}}, []bool{false, false}), 2663 }, 2664 expect: testutil.NewFunctionTestResult(types.T_float64.ToType(), false, 2665 []float64{0, 0.0003542540112345671}, 2666 []bool{false, false}), 2667 }, 2668 } 2669 } 2670 2671 func TestCosineDistanceArray(t *testing.T) { 2672 testCases := initCosineDistanceArrayTestCase() 2673 2674 proc := testutil.NewProcess() 2675 for _, tc := range testCases { 2676 var fcTC testutil.FunctionTestCase 2677 switch tc.typ { 2678 case types.T_array_float32: 2679 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, CosineDistanceArray[float32]) 2680 case types.T_array_float64: 2681 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, CosineDistanceArray[float64]) 2682 } 2683 s, info := fcTC.Run() 2684 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2685 } 2686 } 2687 2688 // Extract 2689 func initExtractTestCase() []tcTemp { 2690 MakeDates := func(values ...string) []types.Date { 2691 ds := make([]types.Date, len(values)) 2692 for i, s := range values { 2693 if len(s) == 0 { 2694 ds[i] = types.Date(0) 2695 } else { 2696 d, err := types.ParseDateCast(s) 2697 if err != nil { 2698 panic(err) 2699 } 2700 ds[i] = d 2701 } 2702 } 2703 return ds 2704 } 2705 2706 MakeDateTimes := func(values ...string) []types.Datetime { 2707 ds := make([]types.Datetime, len(values)) 2708 for i, s := range values { 2709 if len(s) == 0 { 2710 ds[i] = types.Datetime(0) 2711 } else { 2712 d, err := types.ParseDatetime(s, 6) 2713 if err != nil { 2714 panic(err) 2715 } 2716 ds[i] = d 2717 } 2718 } 2719 return ds 2720 } 2721 2722 return []tcTemp{ 2723 { 2724 info: "test extractFromDate year", 2725 typ: types.T_date, 2726 inputs: []testutil.FunctionTestInput{ 2727 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{"year", "year", "year", "year"}, []bool{false, false, false, false}), 2728 testutil.NewFunctionTestInput(types.T_date.ToType(), MakeDates("2020-01-01", "2021-02-03", "2024-03-04", ""), []bool{false, false, false, true}), 2729 }, 2730 expect: testutil.NewFunctionTestResult(types.T_uint32.ToType(), false, 2731 []uint32{2020, 2021, 2024, 1}, 2732 []bool{false, false, false, true}), 2733 //TODO: Comments migrated from original code: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/extract_test.go#L39 2734 // XXX why? This seems to be wrong. ExtractFromDate "" should error out, 2735 // but if it does not, we tested the result is 1 in prev check. 2736 // it should not be null. 2737 // require.True(t, nulls.Contains(outputVector.GetNulls(), uint64(3))) 2738 }, 2739 { 2740 info: "test extractFromDate month", 2741 typ: types.T_date, 2742 inputs: []testutil.FunctionTestInput{ 2743 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{"month", "month", "month", "month"}, []bool{false, false, false, false}), 2744 testutil.NewFunctionTestInput(types.T_date.ToType(), MakeDates("2020-01-01", "2021-02-03", "2024-03-04", ""), []bool{false, false, false, true}), 2745 }, 2746 expect: testutil.NewFunctionTestResult(types.T_uint32.ToType(), false, 2747 []uint32{1, 2, 3, 1}, 2748 []bool{false, false, false, true}), 2749 //TODO: Comments migrated from original code: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/extract_test.go#L39 2750 // XXX same as above. 2751 // require.True(t, nulls.Contains(outputVector.GetNulls(), uint64(3))) 2752 }, 2753 { 2754 info: "test extractFromDate day", 2755 typ: types.T_date, 2756 inputs: []testutil.FunctionTestInput{ 2757 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{"day", "day", "day", "day"}, []bool{}), 2758 testutil.NewFunctionTestInput(types.T_date.ToType(), MakeDates("2020-01-01", "2021-02-03", "2024-03-04", ""), []bool{false, false, false, true}), 2759 }, 2760 expect: testutil.NewFunctionTestResult(types.T_uint32.ToType(), false, 2761 []uint32{1, 3, 4, 1}, 2762 []bool{false, false, false, true}), 2763 //TODO: Comments migrated from original code: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/extract_test.go#L39 2764 // XXX Same 2765 // require.True(t, nulls.Contains(outputVector.GetNulls(), uint64(3))) 2766 }, 2767 { 2768 info: "test extractFromDate year_month", 2769 typ: types.T_date, 2770 inputs: []testutil.FunctionTestInput{ 2771 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{"year_month", "year_month", "year_month", "year_month"}, []bool{}), 2772 testutil.NewFunctionTestInput(types.T_date.ToType(), MakeDates("2020-01-01", "2021-02-03", "2024-03-04", ""), []bool{false, false, false, true}), 2773 }, 2774 expect: testutil.NewFunctionTestResult(types.T_uint32.ToType(), false, 2775 []uint32{202001, 202102, 202403, 101}, 2776 []bool{false, false, false, true}), 2777 //TODO: Comments migrated from original code: https://github.com/m-schen/matrixone/blob/0c480ca11b6302de26789f916a3e2faca7f79d47/pkg/sql/plan/function/builtin/binary/extract_test.go#L39 2778 // XXX same 2779 // require.True(t, nulls.Contains(outputVector.GetNulls(), uint64(3))) 2780 }, 2781 { 2782 info: "test extractFromDateTime year", 2783 typ: types.T_datetime, 2784 inputs: []testutil.FunctionTestInput{ 2785 testutil.NewFunctionTestConstInput(types.T_varchar.ToType(), []string{"year", "year", "year", "year"}, []bool{}), 2786 testutil.NewFunctionTestInput(types.T_datetime.ToType(), MakeDateTimes("2020-01-01 11:12:13.0006", "2006-01-02 15:03:04.1234", "2024-03-04 12:13:14", ""), []bool{false, false, false, true}), 2787 }, 2788 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, 2789 []string{"2020", "2006", "2024", ""}, 2790 []bool{false, false, false, true}), 2791 }, 2792 } 2793 } 2794 2795 func TestExtract(t *testing.T) { 2796 testCases := initExtractTestCase() 2797 2798 proc := testutil.NewProcess() 2799 for _, tc := range testCases { 2800 var fcTC testutil.FunctionTestCase 2801 switch tc.typ { 2802 case types.T_date: 2803 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, ExtractFromDate) 2804 case types.T_datetime: 2805 fcTC = testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, ExtractFromDatetime) 2806 } 2807 s, info := fcTC.Run() 2808 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2809 } 2810 } 2811 2812 // REPLACE 2813 2814 func initReplaceTestCase() []tcTemp { 2815 cases := []struct { 2816 info string 2817 input [][]string 2818 expect []string 2819 }{ 2820 { 2821 info: "Single string case1", 2822 input: [][]string{ 2823 {"abc"}, 2824 {"a"}, 2825 {"d"}, 2826 }, 2827 2828 expect: []string{"dbc"}, 2829 }, 2830 2831 { 2832 info: "Single string case2", 2833 input: [][]string{ 2834 {".*.*.*"}, 2835 {".*"}, 2836 {"n"}, 2837 }, 2838 2839 expect: []string{"nnn"}, 2840 }, 2841 2842 { 2843 info: "Single string case3", 2844 input: [][]string{ 2845 {"当时明月 在 当时"}, 2846 {"当时"}, 2847 {"此时"}, 2848 }, 2849 2850 expect: []string{"此时明月 在 此时"}, 2851 }, 2852 2853 { 2854 info: "Single string case4", 2855 input: [][]string{ 2856 {"123"}, 2857 {""}, 2858 {"n"}, 2859 }, 2860 2861 expect: []string{"123"}, 2862 }, 2863 //FIXME: Didn't implement the ReplaceWithArrays. Hence multi string case fails. 2864 2865 //{ 2866 // info: "Multi string case1", 2867 // input: [][]string{ 2868 // []string{"firststring", "secondstring"}, 2869 // []string{"st"}, 2870 // []string{"re"}, 2871 // }, 2872 // 2873 // expect: []string{"firrerering", "secondrering"}, 2874 //}, 2875 //{ 2876 // info: "Multi string case2", 2877 // input: [][]string{ 2878 // []string{"Oneinput"}, 2879 // []string{"n"}, 2880 // []string{"e", "b"}, 2881 // }, 2882 // 2883 // expect: []string{"Oeeieput", "Obeibput"}, 2884 //}, 2885 // 2886 //{ 2887 // info: "Multi string case3", 2888 // input: [][]string{ 2889 // []string{"aaabbb"}, 2890 // []string{"a", "b"}, 2891 // []string{"n"}, 2892 // }, 2893 // 2894 // expect: []string{"nnnbbb", "aaannn"}, 2895 //}, 2896 // 2897 //{ 2898 // info: "Multi string case4", 2899 // input: [][]string{ 2900 // []string{"Matrix", "Origin"}, 2901 // []string{"a", "i"}, 2902 // []string{"b", "d"}, 2903 // }, 2904 // 2905 // expect: []string{"Mbtrix", "Ordgdn"}, 2906 //}, 2907 // 2908 //{ 2909 // info: "Scalar case1", 2910 // input: [][]string{ 2911 // []string{"cool"}, 2912 // []string{"o"}, 2913 // []string{"a"}, 2914 // }, 2915 // 2916 // expect: []string{"caal"}, 2917 //}, 2918 } 2919 2920 var testInputs = make([]tcTemp, 0, len(cases)) 2921 for _, c := range cases { 2922 2923 testInputs = append(testInputs, tcTemp{ 2924 info: "test replace " + c.info, 2925 inputs: []testutil.FunctionTestInput{ 2926 // Create a input entry <[]string, []string, []string> 2927 testutil.NewFunctionTestInput(types.T_varchar.ToType(), c.input[0], []bool{}), 2928 testutil.NewFunctionTestInput(types.T_varchar.ToType(), c.input[1], []bool{}), 2929 testutil.NewFunctionTestInput(types.T_varchar.ToType(), c.input[2], []bool{}), 2930 }, 2931 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, c.expect, []bool{}), 2932 }) 2933 } 2934 2935 return testInputs 2936 } 2937 2938 func TestReplace(t *testing.T) { 2939 testCases := initReplaceTestCase() 2940 2941 proc := testutil.NewProcess() 2942 for _, tc := range testCases { 2943 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, Replace) 2944 s, info := fcTC.Run() 2945 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 2946 } 2947 } 2948 2949 // TRIM 2950 2951 func initTrimTestCase() []tcTemp { 2952 cases := []struct { 2953 mode string 2954 input string 2955 trimWord string 2956 output string 2957 info string 2958 }{ 2959 2960 { 2961 mode: "both", 2962 input: " hello world ", 2963 trimWord: " ", 2964 output: "hello world", 2965 }, 2966 { 2967 mode: "leading", 2968 input: " hello world ", 2969 trimWord: " ", 2970 output: "hello world ", 2971 }, 2972 { 2973 mode: "trailing", 2974 input: " hello world ", 2975 trimWord: " ", 2976 output: " hello world", 2977 }, 2978 { 2979 mode: "both", 2980 input: " hello world ", 2981 trimWord: "h", 2982 output: " hello world ", 2983 }, 2984 { 2985 mode: "trailing", 2986 input: " hello world", 2987 trimWord: "d", 2988 output: " hello worl", 2989 }, 2990 { 2991 mode: "leading", 2992 input: "hello world ", 2993 trimWord: "h", 2994 output: "ello world ", 2995 }, 2996 { 2997 mode: "both", 2998 input: "嗷嗷0k七七", 2999 trimWord: "七", 3000 output: "嗷嗷0k", 3001 }, 3002 { 3003 mode: "leading", 3004 input: "嗷嗷0k七七", 3005 trimWord: "七", 3006 output: "嗷嗷0k七七", 3007 }, 3008 { 3009 mode: "trailing", 3010 input: "嗷嗷0k七七", 3011 trimWord: "七", 3012 output: "嗷嗷0k", 3013 }, 3014 { 3015 mode: "both", 3016 input: "嗷嗷0k七七", 3017 trimWord: "k七七", 3018 output: "嗷嗷0", 3019 }, 3020 { 3021 mode: "leading", 3022 input: "嗷嗷0k七七", 3023 trimWord: "", 3024 output: "嗷嗷0k七七", 3025 }, 3026 { 3027 mode: "trailing", 3028 input: "", 3029 trimWord: "嗷嗷0k七七", 3030 output: "", 3031 }, 3032 } 3033 3034 var testInputs = make([]tcTemp, 0, len(cases)) 3035 for _, c := range cases { 3036 3037 testInputs = append(testInputs, tcTemp{ 3038 3039 info: "test trim ", 3040 inputs: []testutil.FunctionTestInput{ 3041 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{c.mode}, []bool{}), 3042 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{c.trimWord}, []bool{}), 3043 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{c.input}, []bool{}), 3044 }, 3045 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{c.output}, []bool{}), 3046 }) 3047 } 3048 3049 return testInputs 3050 3051 } 3052 3053 func TestTrim(t *testing.T) { 3054 testCases := initTrimTestCase() 3055 3056 proc := testutil.NewProcess() 3057 for _, tc := range testCases { 3058 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, Trim) 3059 s, info := fcTC.Run() 3060 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 3061 } 3062 } 3063 3064 // JSON EXTRACT 3065 3066 func initJsonExtractTestCase() []tcTemp { 3067 3068 var ( 3069 cases = []struct { 3070 index int 3071 json string 3072 path string 3073 want string 3074 pathNullList []bool 3075 }{ 3076 { 3077 index: 0, 3078 json: `{"a":1,"b":2,"c":3}`, 3079 path: `$.a`, 3080 want: `1`, 3081 }, 3082 { 3083 index: 1, 3084 json: `{"a":1,"b":2,"c":3}`, 3085 path: `$.b`, 3086 want: `2`, 3087 }, 3088 { 3089 index: 2, 3090 json: `{"a":{"q":[1,2,3]}}`, 3091 path: `$.a.q[1]`, 3092 want: `2`, 3093 }, 3094 { 3095 index: 3, 3096 json: `[{"a":1,"b":2,"c":3},{"a":4,"b":5,"c":6}]`, 3097 path: `$[1].a`, 3098 want: `4`, 3099 }, 3100 { 3101 index: 4, 3102 json: `{"a":{"q":[{"a":1},{"a":2},{"a":3}]}}`, 3103 path: `$.a.q[1]`, 3104 want: `{"a":2}`, 3105 }, 3106 { 3107 index: 5, 3108 json: `{"a":{"q":[{"a":1},{"a":2},{"a":3}]}}`, 3109 path: `$.a.q`, 3110 want: `[{"a":1},{"a":2},{"a":3}]`, 3111 }, 3112 { 3113 index: 6, 3114 json: `[1,2,3]`, 3115 path: "$[*]", 3116 want: "[1,2,3]", 3117 }, 3118 { 3119 index: 7, 3120 json: `{"a":[1,2,3,{"b":4}]}`, 3121 path: "$.a[3].b", 3122 want: "4", 3123 }, 3124 //{ 3125 // index: 8, 3126 // json: `{"a":[1,2,3,{"b":4}]}`, 3127 // path: "$.a[3].c", 3128 // want: "null", 3129 //}, 3130 { 3131 index: 9, 3132 json: `{"a":[1,2,3,{"b":4}],"c":5}`, 3133 path: "$.*", 3134 want: `[[1,2,3,{"b":4}],5]`, 3135 }, 3136 { 3137 index: 10, 3138 json: `{"a":[1,2,3,{"a":4}]}`, 3139 path: "$**.a", 3140 want: `[[1,2,3,{"a":4}],4]`, 3141 }, 3142 { 3143 index: 11, 3144 json: `{"a":[1,2,3,{"a":4}]}`, 3145 path: "$.a[*].a", 3146 want: `4`, 3147 }, 3148 //{ 3149 // index: 12, 3150 // json: `{"a":[1,2,3,{"a":4}]}`, 3151 // pathNullList: []bool{true}, 3152 // want: "null", 3153 //}, 3154 } 3155 ) 3156 3157 var testInputs = make([]tcTemp, 0, len(cases)) 3158 for _, c := range cases { 3159 3160 want := make([]string, 1) 3161 if c.want != "null" { 3162 bj, _ := types.ParseStringToByteJson(c.want) 3163 dt, _ := bj.Marshal() 3164 want[0] = string(dt) 3165 } 3166 3167 testInputs = append(testInputs, tcTemp{ 3168 3169 info: "test json_extract " + fmt.Sprint(c.index), 3170 inputs: []testutil.FunctionTestInput{ 3171 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{c.json}, []bool{}), 3172 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{c.path}, c.pathNullList), 3173 }, 3174 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, want, []bool{}), 3175 }) 3176 } 3177 3178 return testInputs 3179 } 3180 3181 func TestJsonExtract(t *testing.T) { 3182 testCases := initJsonExtractTestCase() 3183 3184 proc := testutil.NewProcess() 3185 for _, tc := range testCases { 3186 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, JsonExtract) 3187 s, info := fcTC.Run() 3188 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 3189 } 3190 } 3191 3192 // SPLIT PART 3193 3194 func initSplitPart() []tcTemp { 3195 3196 //TODO: Need to validate testcases: https://github.com/m-schen/matrixone/blob/3b58fe39a4c233739a8d3b9cd4fcd562fa2a1568/pkg/sql/plan/function/builtin/multi/split_part_test.go#L50 3197 // I have skipped the scalar testcases. Please add if it is relevant. 3198 return []tcTemp{ 3199 { 3200 info: "test split_part", 3201 inputs: []testutil.FunctionTestInput{ 3202 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"a,b,c"}, []bool{}), 3203 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{","}, []bool{}), 3204 testutil.NewFunctionTestInput(types.T_uint32.ToType(), []uint32{1}, []bool{}), 3205 }, 3206 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), false, []string{"a"}, []bool{}), 3207 }, 3208 { 3209 info: "test split_part Error", 3210 inputs: []testutil.FunctionTestInput{ 3211 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{"a,b,c"}, []bool{}), 3212 testutil.NewFunctionTestInput(types.T_varchar.ToType(), []string{","}, []bool{}), 3213 testutil.NewFunctionTestInput(types.T_uint32.ToType(), []uint32{0}, []bool{}), 3214 }, 3215 expect: testutil.NewFunctionTestResult(types.T_varchar.ToType(), true, []string{"a"}, []bool{}), 3216 }, 3217 } 3218 3219 } 3220 3221 func TestSplitPart(t *testing.T) { 3222 testCases := initSplitPart() 3223 3224 proc := testutil.NewProcess() 3225 for _, tc := range testCases { 3226 fcTC := testutil.NewFunctionTestCase(proc, tc.inputs, tc.expect, SplitPart) 3227 s, info := fcTC.Run() 3228 require.True(t, s, fmt.Sprintf("case is '%s', err info is '%s'", tc.info, info)) 3229 } 3230 }