github.com/matrixorigin/matrixone@v0.7.0/pkg/vectorize/like/like_test.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package like
    16  
    17  import (
    18  	"reflect"
    19  	"testing"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/container/nulls"
    22  )
    23  
    24  func Test_sliceLikePure(t *testing.T) {
    25  	type args struct {
    26  		s    []string
    27  		expr []byte
    28  	}
    29  	tests := []struct {
    30  		name    string
    31  		args    args
    32  		want    []int64
    33  		wantErr bool
    34  	}{
    35  		// 1. %
    36  		{
    37  			name: "%",
    38  			args: args{
    39  				s:    []string{"a", "bc"},
    40  				expr: []byte("%"),
    41  			},
    42  			want:    []int64{0, 1},
    43  			wantErr: false,
    44  		},
    45  		// 2. _
    46  		{
    47  			name: "_",
    48  			args: args{
    49  				s:    []string{"a", "bc"},
    50  				expr: []byte("_"),
    51  			},
    52  			want:    []int64{0},
    53  			wantErr: false,
    54  		},
    55  		// 3. nil
    56  		{
    57  			name: "nil",
    58  			args: args{
    59  				s:    []string{"a", "bc"},
    60  				expr: []byte(""),
    61  			},
    62  			want:    []int64{},
    63  			wantErr: false,
    64  		},
    65  		// 4. no _ and %
    66  		{
    67  			name: "bc",
    68  			args: args{
    69  				s:    []string{"a", "bc"},
    70  				expr: []byte("bc"),
    71  			},
    72  			want:    []int64{1},
    73  			wantErr: false,
    74  		},
    75  		// 5. _XXX
    76  		{
    77  			name: "_XXX",
    78  			args: args{
    79  				s:    []string{"a", "bc"},
    80  				expr: []byte("_c"),
    81  			},
    82  			want:    []int64{1},
    83  			wantErr: false,
    84  		},
    85  		// 6. %XXX
    86  		{
    87  			name: "%XXX",
    88  			args: args{
    89  				s:    []string{"a", "bc"},
    90  				expr: []byte("%c"),
    91  			},
    92  			want:    []int64{1},
    93  			wantErr: false,
    94  		},
    95  		// 7. _XXX%
    96  		{
    97  			name: "_XXX%",
    98  			args: args{
    99  				s:    []string{"a", "bc", "aca"},
   100  				expr: []byte("_c%"),
   101  			},
   102  			want:    []int64{1, 2},
   103  			wantErr: false,
   104  		},
   105  		// 8. %XXX_
   106  		{
   107  			name: "%XXX_",
   108  			args: args{
   109  				s:    []string{"a", "bc", "aca"},
   110  				expr: []byte("%c_"),
   111  			},
   112  			want:    []int64{2},
   113  			wantErr: false,
   114  		},
   115  		// 9. _XXX_
   116  		{
   117  			name: "_XXX_",
   118  			args: args{
   119  				s:    []string{"a", "bc", "aca"},
   120  				expr: []byte("_c_"),
   121  			},
   122  			want:    []int64{2},
   123  			wantErr: false,
   124  		},
   125  		// 10. %XXX%
   126  		{
   127  			name: "%XXX%",
   128  			args: args{
   129  				s:    []string{"a", "bc", "aca"},
   130  				expr: []byte("%c%"),
   131  			},
   132  			want:    []int64{1, 2},
   133  			wantErr: false,
   134  		},
   135  		// 11. XXX%YYY
   136  		{
   137  			name: "XXX%YYY",
   138  			args: args{
   139  				s:    []string{"abc", "ac", "aca"},
   140  				expr: []byte("a%c"),
   141  			},
   142  			want:    []int64{0, 1},
   143  			wantErr: false,
   144  		},
   145  		// 12. XXX_YYY
   146  		{
   147  			name: "XXX_YYY",
   148  			args: args{
   149  				s:    []string{"abc", "ac", "aca"},
   150  				expr: []byte("a_c"),
   151  			},
   152  			want:    []int64{0},
   153  			wantErr: false,
   154  		},
   155  		// 13. single char none wild card
   156  		{
   157  			name: "*",
   158  			args: args{
   159  				s:    []string{"abc", "*", "aca"},
   160  				expr: []byte("*"),
   161  			},
   162  			want:    []int64{1},
   163  			wantErr: false,
   164  		},
   165  	}
   166  	for _, tt := range tests {
   167  		t.Run(tt.name, func(t *testing.T) {
   168  			rs := make([]bool, len(tt.args.s))
   169  			_, err := BtSliceAndConst(tt.args.s, tt.args.expr, rs)
   170  			if (err != nil) != tt.wantErr {
   171  				t.Errorf("sliceLikeScalar() error = %v, wantErr %v", err, tt.wantErr)
   172  				return
   173  			}
   174  
   175  			got := []int64{}
   176  			for i, b := range rs {
   177  				if b {
   178  					got = append(got, int64(i))
   179  				}
   180  			}
   181  
   182  			if !reflect.DeepEqual(got, tt.want) {
   183  				t.Errorf("sliceLikeScalar() got = %v, want %v", got, tt.want)
   184  			}
   185  		})
   186  	}
   187  }
   188  
   189  func Test_pureLikePure(t *testing.T) {
   190  	type args struct {
   191  		p    []byte
   192  		expr []byte
   193  		rs   []int64
   194  	}
   195  	tests := []struct {
   196  		name    string
   197  		args    args
   198  		want    []int64
   199  		wantErr bool
   200  	}{
   201  		// 1. %
   202  		{
   203  			name: "%",
   204  			args: args{
   205  				p:    []byte("123"),
   206  				expr: []byte("%"),
   207  				rs:   make([]int64, 1),
   208  			},
   209  			want:    []int64{0},
   210  			wantErr: false,
   211  		},
   212  		// 2. _
   213  		{
   214  			name: "_",
   215  			args: args{
   216  				p:    []byte("123"),
   217  				expr: []byte("_"),
   218  				rs:   make([]int64, 1),
   219  			},
   220  			want:    nil,
   221  			wantErr: false,
   222  		},
   223  		// 3. nil
   224  		{
   225  			name: "",
   226  			args: args{
   227  				p:    []byte("123"),
   228  				expr: []byte(""),
   229  				rs:   make([]int64, 1),
   230  			},
   231  			want:    nil,
   232  			wantErr: false,
   233  		},
   234  		// 4. %X%
   235  		{
   236  			name: "%X%",
   237  			args: args{
   238  				p:    []byte("123"),
   239  				expr: []byte("%23%"),
   240  				rs:   make([]int64, 1),
   241  			},
   242  			want:    []int64{0},
   243  			wantErr: false,
   244  		},
   245  		// 5. %X_
   246  		{
   247  			name: "%X_",
   248  			args: args{
   249  				p:    []byte("123"),
   250  				expr: []byte("%12_"),
   251  				rs:   make([]int64, 1),
   252  			},
   253  			want:    []int64{0},
   254  			wantErr: false,
   255  		},
   256  		// 6. _X_
   257  		{
   258  			name: "_X_",
   259  			args: args{
   260  				p:    []byte("323"),
   261  				expr: []byte("_2_"),
   262  				rs:   make([]int64, 1),
   263  			},
   264  			want:    []int64{0},
   265  			wantErr: false,
   266  		},
   267  		// 7. _X%
   268  		{
   269  			name: "_X%",
   270  			args: args{
   271  				p:    []byte("12323"),
   272  				expr: []byte("_1%"),
   273  				rs:   make([]int64, 1),
   274  			},
   275  			want:    nil,
   276  			wantErr: false,
   277  		},
   278  		// 8. _XX
   279  		{
   280  			name: "_XX",
   281  			args: args{
   282  				p:    []byte("k123"),
   283  				expr: []byte("_123"),
   284  				rs:   make([]int64, 1),
   285  			},
   286  			want:    []int64{0},
   287  			wantErr: false,
   288  		},
   289  		// 9. %XX
   290  		{
   291  			name: "%XX",
   292  			args: args{
   293  				p:    []byte("k123"),
   294  				expr: []byte("%23"),
   295  				rs:   make([]int64, 1),
   296  			},
   297  			want:    []int64{0},
   298  			wantErr: false,
   299  		},
   300  		// 10. XX_
   301  		{
   302  			name: "XX_",
   303  			args: args{
   304  				p:    []byte("k123"),
   305  				expr: []byte("k123_"),
   306  				rs:   make([]int64, 1),
   307  			},
   308  			want:    nil,
   309  			wantErr: false,
   310  		},
   311  		// 11. XX%
   312  		{
   313  			name: "XX%",
   314  			args: args{
   315  				p:    []byte("wop23"),
   316  				expr: []byte("w%"),
   317  				rs:   make([]int64, 1),
   318  			},
   319  			want:    []int64{0},
   320  			wantErr: false,
   321  		},
   322  		// 12. XX_XX
   323  		{
   324  			name: "XX_XX",
   325  			args: args{
   326  				p:    []byte("wop23"),
   327  				expr: []byte("wo_23"),
   328  				rs:   make([]int64, 1),
   329  			},
   330  			want:    []int64{0},
   331  			wantErr: false,
   332  		},
   333  		// 13. XX%XX
   334  		{
   335  			name: "XX%XX",
   336  			args: args{
   337  				p:    []byte("wop23"),
   338  				expr: []byte("wop%23"),
   339  				rs:   make([]int64, 1),
   340  			},
   341  			want:    []int64{0},
   342  			wantErr: false,
   343  		},
   344  		// 14. single char none wild card
   345  		{
   346  			name: "*",
   347  			args: args{
   348  				p:    []byte("*"),
   349  				expr: []byte("*"),
   350  				rs:   make([]int64, 1),
   351  			},
   352  			want:    []int64{0},
   353  			wantErr: false,
   354  		},
   355  	}
   356  	for _, tt := range tests {
   357  		t.Run(tt.name, func(t *testing.T) {
   358  			ok, err := BtConstAndConst(string(tt.args.p), tt.args.expr)
   359  			if (err != nil) != tt.wantErr {
   360  				t.Errorf("scalarLikeScalar() error = %v, wantErr %v", err, tt.wantErr)
   361  				return
   362  			}
   363  
   364  			if ok != (len(tt.want) == 1) {
   365  				t.Errorf("scalarLikeScalar() got = %v, want %v", ok, tt.want)
   366  			}
   367  		})
   368  	}
   369  }
   370  
   371  func Test_sliceNullLikePure(t *testing.T) {
   372  	type args struct {
   373  		s    []string
   374  		expr []byte
   375  		ns   *nulls.Nulls
   376  	}
   377  	tests := []struct {
   378  		name    string
   379  		args    args
   380  		want    []int64
   381  		wantErr bool
   382  	}{
   383  		// 1. %
   384  		{
   385  			name: "%",
   386  			args: args{
   387  				s:    []string{"a", "bc"},
   388  				expr: []byte("%"),
   389  				ns:   nulls.NewWithSize(0),
   390  			},
   391  			want:    []int64{0, 1},
   392  			wantErr: false,
   393  		},
   394  		// 2. _
   395  		{
   396  			name: "_",
   397  			args: args{
   398  				s:    []string{"a", "bc"},
   399  				expr: []byte("_"),
   400  				ns:   nulls.NewWithSize(0),
   401  			},
   402  			want:    []int64{0},
   403  			wantErr: false,
   404  		},
   405  		// 3. nil
   406  		{
   407  			name: "nil",
   408  			args: args{
   409  				s:    []string{"a", "bc"},
   410  				expr: []byte(""),
   411  				ns:   nulls.NewWithSize(0),
   412  			},
   413  			want:    []int64{},
   414  			wantErr: false,
   415  		},
   416  		// 4. no _ and %
   417  		{
   418  			name: "bc",
   419  			args: args{
   420  				s:    []string{"a", "bc"},
   421  				expr: []byte("bc"),
   422  				ns:   nulls.NewWithSize(0),
   423  			},
   424  			want:    []int64{1},
   425  			wantErr: false,
   426  		},
   427  		// 5. _XXX
   428  		{
   429  			name: "_XXX",
   430  			args: args{
   431  				s:    []string{"a", "bc"},
   432  				expr: []byte("_c"),
   433  				ns:   nulls.NewWithSize(0),
   434  			},
   435  			want:    []int64{1},
   436  			wantErr: false,
   437  		},
   438  		// 6. %XXX
   439  		{
   440  			name: "%XXX",
   441  			args: args{
   442  				s:    []string{"a", "bc"},
   443  				expr: []byte("%c"),
   444  				ns:   nulls.NewWithSize(0),
   445  			},
   446  			want:    []int64{1},
   447  			wantErr: false,
   448  		},
   449  		// 7. _XXX%
   450  		{
   451  			name: "_XXX%",
   452  			args: args{
   453  				s:    []string{"a", "bc", "aca"},
   454  				expr: []byte("_c%"),
   455  				ns:   nulls.NewWithSize(0),
   456  			},
   457  			want:    []int64{1, 2},
   458  			wantErr: false,
   459  		},
   460  		// 8. %XXX_
   461  		{
   462  			name: "%XXX_",
   463  			args: args{
   464  				s:    []string{"a", "bc", "aca"},
   465  				expr: []byte("%c_"),
   466  				ns:   nulls.NewWithSize(0),
   467  			},
   468  			want:    []int64{2},
   469  			wantErr: false,
   470  		},
   471  		// 9. _XXX_
   472  		{
   473  			name: "_XXX_",
   474  			args: args{
   475  				s:    []string{"a", "bc", "aca"},
   476  				expr: []byte("_c_"),
   477  				ns:   nulls.NewWithSize(0),
   478  			},
   479  			want:    []int64{2},
   480  			wantErr: false,
   481  		},
   482  		// 10. %XXX%
   483  		{
   484  			name: "%XXX%",
   485  			args: args{
   486  				s:    []string{"a", "bc", "aca"},
   487  				expr: []byte("%c%"),
   488  				ns:   nulls.NewWithSize(0),
   489  			},
   490  			want:    []int64{1, 2},
   491  			wantErr: false,
   492  		},
   493  		// 11. XXX%YYY
   494  		{
   495  			name: "XXX%YYY",
   496  			args: args{
   497  				s:    []string{"abc", "ac", "aca"},
   498  				expr: []byte("a%c"),
   499  				ns:   nulls.NewWithSize(0),
   500  			},
   501  			want:    []int64{0, 1},
   502  			wantErr: false,
   503  		},
   504  		// 12. XXX_YYY
   505  		{
   506  			name: "XXX_YYY",
   507  			args: args{
   508  				s:    []string{"abc", "ac", "aca"},
   509  				expr: []byte("a_c"),
   510  				ns:   nulls.NewWithSize(0),
   511  			},
   512  			want:    []int64{0},
   513  			wantErr: false,
   514  		},
   515  		// 13. XXX_
   516  		{
   517  			name: "XXX_",
   518  			args: args{
   519  				s:    []string{"abc", "ac", "aca"},
   520  				expr: []byte("a_"),
   521  				ns:   nulls.NewWithSize(0),
   522  			},
   523  			want:    []int64{1},
   524  			wantErr: false,
   525  		},
   526  		// 14. XXX%
   527  		{
   528  			name: "XXX%",
   529  			args: args{
   530  				s:    []string{"abc", "ac", "aca"},
   531  				expr: []byte("a%"),
   532  				ns:   nulls.NewWithSize(0),
   533  			},
   534  			want:    []int64{0, 1, 2},
   535  			wantErr: false,
   536  		},
   537  		// 15. single char none wild card
   538  		{
   539  			name: "*",
   540  			args: args{
   541  				s:    []string{"abc", "*", "*a"},
   542  				expr: []byte("*"),
   543  				ns:   nulls.NewWithSize(0),
   544  			},
   545  			want:    []int64{1},
   546  			wantErr: false,
   547  		},
   548  	}
   549  	for _, tt := range tests {
   550  		t.Run(tt.name, func(t *testing.T) {
   551  			rs := make([]bool, len(tt.args.s))
   552  			_, err := BtSliceNullAndConst(tt.args.s, tt.args.expr, tt.args.ns, rs)
   553  			if (err != nil) != tt.wantErr {
   554  				t.Errorf("sliceContainsNullLikeScalar() error = %v, wantErr %v", err, tt.wantErr)
   555  				return
   556  			}
   557  			got := []int64{}
   558  			for i, b := range rs {
   559  				if b {
   560  					got = append(got, int64(i))
   561  				}
   562  			}
   563  			if !reflect.DeepEqual(got, tt.want) {
   564  				t.Errorf("sliceContainsNullLikeScalar() got = %v, want %v", got, tt.want)
   565  			}
   566  		})
   567  	}
   568  }