github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/function/builtin/multi/substr_test.go (about)

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