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  }