github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/util/composite_primary_key_util_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 util
    16  
    17  import (
    18  	crand "crypto/rand"
    19  	"math"
    20  	"math/rand"
    21  	"reflect"
    22  	"strconv"
    23  	"testing"
    24  
    25  	"github.com/matrixorigin/matrixone/pkg/catalog"
    26  
    27  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    28  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    29  	"github.com/matrixorigin/matrixone/pkg/container/types"
    30  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    31  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    32  	"github.com/matrixorigin/matrixone/pkg/testutil"
    33  	"github.com/stretchr/testify/require"
    34  )
    35  
    36  func TestJudgeIsCompositeClusterByColumn(t *testing.T) {
    37  	tests := []struct {
    38  		name string
    39  		args string
    40  		want bool
    41  	}{
    42  		{
    43  			name: "test01",
    44  			args: "__mo_cbkey_005empno005ename",
    45  			want: true,
    46  		},
    47  		{
    48  			name: "test02",
    49  			args: "__mo_cbkey_005ename003sal",
    50  			want: true,
    51  		},
    52  		{
    53  			name: "test03",
    54  			args: "__mo_cpkey_005ename003sal",
    55  			want: false,
    56  		},
    57  	}
    58  	for _, tt := range tests {
    59  		t.Run(tt.name, func(t *testing.T) {
    60  			if got := JudgeIsCompositeClusterByColumn(tt.args); got != tt.want {
    61  				t.Errorf("JudgeIsCompositeClusterByColumn() = %v, want %v", got, tt.want)
    62  			}
    63  		})
    64  	}
    65  }
    66  
    67  func TestBuildCompositeClusterByColumnName(t *testing.T) {
    68  	tests := []struct {
    69  		name string
    70  		args []string
    71  		want string
    72  	}{
    73  		{
    74  			name: "test01",
    75  			args: []string{"empno", "ename"},
    76  			want: "__mo_cbkey_005empno005ename",
    77  		},
    78  		{
    79  			name: "test02",
    80  			args: []string{"empno", "sal"},
    81  			want: "__mo_cbkey_005empno003sal",
    82  		},
    83  		{
    84  			name: "test03",
    85  			args: []string{"ename", "sal"},
    86  			want: "__mo_cbkey_005ename003sal",
    87  		},
    88  	}
    89  	for _, tt := range tests {
    90  		t.Run(tt.name, func(t *testing.T) {
    91  			if got := BuildCompositeClusterByColumnName(tt.args); got != tt.want {
    92  				t.Errorf("BuildCompositeClusterByColumnName() = %v, want %v", got, tt.want)
    93  			}
    94  		})
    95  	}
    96  }
    97  
    98  func TestSplitCompositeClusterByColumnName(t *testing.T) {
    99  	tests := []struct {
   100  		name string
   101  		args string
   102  		want []string
   103  	}{
   104  		{
   105  			name: "test01",
   106  			args: "__mo_cbkey_005empno005ename",
   107  			want: []string{"empno", "ename"},
   108  		},
   109  		{
   110  			name: "test02",
   111  			args: "__mo_cbkey_005empno003sal",
   112  			want: []string{"empno", "sal"},
   113  		},
   114  		{
   115  			name: "test03",
   116  			args: "__mo_cbkey_005ename003sal",
   117  			want: []string{"ename", "sal"},
   118  		},
   119  	}
   120  	for _, tt := range tests {
   121  		t.Run(tt.name, func(t *testing.T) {
   122  			if got := SplitCompositeClusterByColumnName(tt.args); !reflect.DeepEqual(got, tt.want) {
   123  				t.Errorf("SplitCompositeClusterByColumnName() = %v, want %v", got, tt.want)
   124  			}
   125  		})
   126  	}
   127  }
   128  
   129  func TestGetClusterByColumnOrder(t *testing.T) {
   130  	tests := []struct {
   131  		name    string
   132  		cbName  string
   133  		colName string
   134  		want    int
   135  	}{
   136  		{
   137  			name:    "test01",
   138  			cbName:  "sal",
   139  			colName: "ename",
   140  			want:    -1,
   141  		},
   142  		{
   143  			name:    "test02",
   144  			cbName:  "sal",
   145  			colName: "__mo_cbkey_003sal005empno",
   146  			want:    -1,
   147  		},
   148  		{
   149  			name:    "test03",
   150  			cbName:  "sal",
   151  			colName: "sal",
   152  			want:    0,
   153  		},
   154  	}
   155  	for _, tt := range tests {
   156  		t.Run(tt.name, func(t *testing.T) {
   157  			if got := GetClusterByColumnOrder(tt.cbName, tt.colName); got != tt.want {
   158  				t.Errorf("GetClusterByColumnOrder() = %v, want %v", got, tt.want)
   159  			}
   160  		})
   161  	}
   162  }
   163  
   164  func TestFillCompositePKeyBatch(t *testing.T) {
   165  	var proc = testutil.NewProc()
   166  	columnSize := 10
   167  	rowCount := 10
   168  	bat, pkeyDef, valueCount := MakeBatch(columnSize, rowCount, proc.Mp())
   169  	err := FillCompositeKeyBatch(bat, catalog.CPrimaryKeyColName, pkeyDef.Names, proc)
   170  	require.Equal(t, err, nil)
   171  	bs := vector.MustBytesCol(bat.Vecs[len(bat.Vecs)-1])
   172  	tuples := make([]types.Tuple, 0)
   173  	for i := 0; i < len(bs); i++ {
   174  		tuple, err := types.Unpack(bs[i])
   175  		require.Equal(t, err, nil)
   176  		tuples = append(tuples, tuple)
   177  	}
   178  
   179  	for i := 0; i < rowCount; i++ {
   180  		for j, name := range pkeyDef.Names {
   181  			element := tuples[i][j]
   182  			idx, _ := strconv.Atoi(name)
   183  			value := valueCount[[2]int{i, idx}]
   184  			require.Equal(t, element, value)
   185  		}
   186  	}
   187  }
   188  
   189  func MakeBatch(columnSize int, rowCount int, mp *mpool.MPool) (*batch.Batch, *plan.PrimaryKeyDef, map[[2]int]interface{}) {
   190  	attrs := make([]string, 0, columnSize)
   191  
   192  	for i := 0; i < columnSize; i++ {
   193  		attrs = append(attrs, strconv.Itoa(i))
   194  	}
   195  
   196  	var keys []string
   197  	for i := 0; i < columnSize; i++ {
   198  		x := rand.Intn(2)
   199  		if x == 0 {
   200  			keys = append(keys, strconv.Itoa(i))
   201  		}
   202  	}
   203  	bat := batch.New(true, attrs)
   204  	valueCount := make(map[[2]int]interface{})
   205  	for i := 0; i < columnSize; i++ {
   206  		bat.Vecs[i] = vector.NewVec(randType().ToType())
   207  		randInsertValues(bat.Vecs[i], bat.Vecs[i].GetType().Oid, rowCount, valueCount, i, mp)
   208  	}
   209  
   210  	primaryKeyDef := &plan.PrimaryKeyDef{
   211  		PkeyColName: catalog.CPrimaryKeyColName,
   212  		Names:       keys,
   213  	}
   214  	bat.SetRowCount(rowCount)
   215  	return bat, primaryKeyDef, valueCount
   216  }
   217  
   218  func randType() types.T {
   219  	t := rand.Intn(17)
   220  	var vt types.T
   221  	switch t {
   222  	case 0:
   223  		vt = types.T_bool
   224  	case 1:
   225  		vt = types.T_int8
   226  	case 2:
   227  		vt = types.T_int16
   228  	case 3:
   229  		vt = types.T_int32
   230  	case 4:
   231  		vt = types.T_int64
   232  	case 5:
   233  		vt = types.T_uint8
   234  	case 6:
   235  		vt = types.T_uint16
   236  	case 7:
   237  		vt = types.T_uint32
   238  	case 8:
   239  		vt = types.T_uint64
   240  	case 9:
   241  		vt = types.T_date
   242  	case 10:
   243  		vt = types.T_datetime
   244  	case 11:
   245  		vt = types.T_timestamp
   246  	case 12:
   247  		vt = types.T_float32
   248  	case 13:
   249  		vt = types.T_float64
   250  	case 14:
   251  		vt = types.T_decimal64
   252  	case 15:
   253  		vt = types.T_decimal128
   254  	case 16:
   255  		vt = types.T_varchar
   256  	}
   257  	return vt
   258  }
   259  
   260  func randInsertValues(v *vector.Vector, t types.T, rowCount int, valueCount map[[2]int]interface{}, columnIndex int, mp *mpool.MPool) {
   261  	switch t {
   262  	case types.T_bool:
   263  		vs := make([]bool, rowCount)
   264  		for i := 0; i < rowCount; i++ {
   265  			if i < rowCount/2 {
   266  				vs[i] = true
   267  				valueCount[[2]int{i, columnIndex}] = true
   268  			} else {
   269  				vs[i] = false
   270  				valueCount[[2]int{i, columnIndex}] = false
   271  			}
   272  		}
   273  		vector.AppendFixedList(v, vs, nil, mp)
   274  	case types.T_int8:
   275  		vs := make([]int8, rowCount)
   276  		for i := 0; i < rowCount; i++ {
   277  			vs[i] = randPositiveInt8()
   278  			valueCount[[2]int{i, columnIndex}] = vs[i]
   279  		}
   280  		vector.AppendFixedList(v, vs, nil, mp)
   281  	case types.T_int16:
   282  		vs := make([]int16, rowCount)
   283  		for i := 0; i < rowCount; i++ {
   284  			vs[i] = randPositiveInt16()
   285  			valueCount[[2]int{i, columnIndex}] = vs[i]
   286  		}
   287  		vector.AppendFixedList(v, vs, nil, mp)
   288  	case types.T_int32:
   289  		vs := make([]int32, rowCount)
   290  		for i := 0; i < rowCount; i++ {
   291  			vs[i] = randPositiveInt32()
   292  			valueCount[[2]int{i, columnIndex}] = vs[i]
   293  		}
   294  		vector.AppendFixedList(v, vs, nil, mp)
   295  	case types.T_int64:
   296  		vs := make([]int64, rowCount)
   297  		for i := 0; i < rowCount; i++ {
   298  			vs[i] = randPositiveInt64()
   299  			valueCount[[2]int{i, columnIndex}] = vs[i]
   300  		}
   301  		vector.AppendFixedList(v, vs, nil, mp)
   302  	case types.T_uint8:
   303  		vs := make([]uint8, rowCount)
   304  		for i := 0; i < rowCount; i++ {
   305  			vs[i] = randUint8()
   306  			valueCount[[2]int{i, columnIndex}] = vs[i]
   307  		}
   308  		vector.AppendFixedList(v, vs, nil, mp)
   309  	case types.T_uint16:
   310  		vs := make([]uint16, rowCount)
   311  		for i := 0; i < rowCount; i++ {
   312  			vs[i] = randUint16()
   313  			valueCount[[2]int{i, columnIndex}] = vs[i]
   314  		}
   315  		vector.AppendFixedList(v, vs, nil, mp)
   316  	case types.T_uint32:
   317  		vs := make([]uint32, rowCount)
   318  		for i := 0; i < rowCount; i++ {
   319  			vs[i] = randUint32()
   320  			valueCount[[2]int{i, columnIndex}] = vs[i]
   321  		}
   322  		vector.AppendFixedList(v, vs, nil, mp)
   323  	case types.T_uint64:
   324  		vs := make([]uint64, rowCount)
   325  		for i := 0; i < rowCount; i++ {
   326  			vs[i] = randUint64()
   327  			valueCount[[2]int{i, columnIndex}] = vs[i]
   328  		}
   329  		vector.AppendFixedList(v, vs, nil, mp)
   330  	case types.T_date:
   331  		vs := make([]types.Date, rowCount)
   332  		for i := 0; i < rowCount; i++ {
   333  			vs[i] = randDate()
   334  			valueCount[[2]int{i, columnIndex}] = vs[i]
   335  		}
   336  		vector.AppendFixedList(v, vs, nil, mp)
   337  	case types.T_time:
   338  		vs := make([]types.Time, rowCount)
   339  		for i := 0; i < rowCount; i++ {
   340  			vs[i] = randTime()
   341  			valueCount[[2]int{i, columnIndex}] = vs[i]
   342  		}
   343  		vector.AppendFixedList(v, vs, nil, mp)
   344  	case types.T_datetime:
   345  		vs := make([]types.Datetime, rowCount)
   346  		for i := 0; i < rowCount; i++ {
   347  			vs[i] = randDatetime()
   348  			valueCount[[2]int{i, columnIndex}] = vs[i]
   349  		}
   350  		vector.AppendFixedList(v, vs, nil, mp)
   351  	case types.T_timestamp:
   352  		vs := make([]types.Timestamp, rowCount)
   353  		for i := 0; i < rowCount; i++ {
   354  			vs[i] = randTimestamp()
   355  			valueCount[[2]int{i, columnIndex}] = vs[i]
   356  		}
   357  		vector.AppendFixedList(v, vs, nil, mp)
   358  	case types.T_float32:
   359  		vs := make([]float32, rowCount)
   360  		for i := 0; i < rowCount; i++ {
   361  			vs[i] = rand.Float32()
   362  			valueCount[[2]int{i, columnIndex}] = vs[i]
   363  		}
   364  		vector.AppendFixedList(v, vs, nil, mp)
   365  	case types.T_float64:
   366  		vs := make([]float64, rowCount)
   367  		for i := 0; i < rowCount; i++ {
   368  			vs[i] = rand.Float64()
   369  			valueCount[[2]int{i, columnIndex}] = vs[i]
   370  		}
   371  		vector.AppendFixedList(v, vs, nil, mp)
   372  	case types.T_decimal64:
   373  		vs := make([]types.Decimal64, rowCount)
   374  		for i := 0; i < rowCount; i++ {
   375  			vs[i] = randDecimal64()
   376  			valueCount[[2]int{i, columnIndex}] = vs[i]
   377  		}
   378  		vector.AppendFixedList(v, vs, nil, mp)
   379  	case types.T_decimal128:
   380  		vs := make([]types.Decimal128, rowCount)
   381  		for i := 0; i < rowCount; i++ {
   382  			vs[i] = randDecimal128()
   383  			valueCount[[2]int{i, columnIndex}] = vs[i]
   384  		}
   385  		vector.AppendFixedList(v, vs, nil, mp)
   386  	case types.T_varchar:
   387  		vs := make([][]byte, rowCount)
   388  		for i := 0; i < rowCount; i++ {
   389  			vs[i] = randStringType()
   390  			valueCount[[2]int{i, columnIndex}] = vs[i]
   391  		}
   392  		vector.AppendBytesList(v, vs, nil, mp)
   393  	}
   394  
   395  }
   396  
   397  func randPositiveInt8() int8 {
   398  	return int8(rand.Int31n(math.MaxInt8 + 1))
   399  }
   400  
   401  func randPositiveInt16() int16 {
   402  	return int16(rand.Int31n(math.MaxInt16 + 1))
   403  }
   404  
   405  func randPositiveInt32() int32 {
   406  	return rand.Int31()
   407  }
   408  
   409  func randPositiveInt64() int64 {
   410  	return rand.Int63()
   411  }
   412  
   413  func randUint8() uint8 {
   414  	return uint8(rand.Int31n(math.MaxUint8 + 1))
   415  }
   416  
   417  func randUint16() uint16 {
   418  	return uint16(rand.Int31n(math.MaxUint16 + 1))
   419  }
   420  
   421  func randUint32() uint32 {
   422  	return rand.Uint32()
   423  }
   424  
   425  func randUint64() uint64 {
   426  	return rand.Uint64()
   427  }
   428  
   429  func randDate() types.Date {
   430  	year := rand.Intn(types.MaxDateYear) + types.MinDateYear
   431  	month := rand.Intn(12) + 1
   432  	day := rand.Intn(int(types.LastDay(int32(year), uint8(month)))) + 1
   433  	return types.DateFromCalendar(int32(year), uint8(month), uint8(day))
   434  }
   435  
   436  func randTime() types.Time {
   437  	isNeg := false
   438  	if tmp := rand.Intn(2); tmp == 0 {
   439  		isNeg = true
   440  	}
   441  	hour := rand.Intn(2562047788)
   442  	minute := rand.Intn(60)
   443  	second := rand.Intn(60)
   444  	microSecond := rand.Intn(1e6)
   445  	return types.TimeFromClock(isNeg, uint64(hour), uint8(minute), uint8(second), uint32(microSecond))
   446  }
   447  
   448  func randDatetime() types.Datetime {
   449  	year := rand.Intn(types.MaxDatetimeYear) + types.MinDatetimeYear
   450  	month := rand.Intn(12) + 1
   451  	day := rand.Intn(int(types.LastDay(int32(year), uint8(month)))) + 1
   452  	hour := rand.Intn(24)
   453  	minute := rand.Intn(60)
   454  	second := rand.Intn(60)
   455  	microSecond := rand.Intn(1e6)
   456  	return types.DatetimeFromClock(int32(year), uint8(month), uint8(day), uint8(hour), uint8(minute), uint8(second), uint32(microSecond))
   457  }
   458  
   459  func randTimestamp() types.Timestamp {
   460  	year := rand.Intn(types.MaxDatetimeYear) + types.MinDatetimeYear
   461  	month := rand.Intn(12) + 1
   462  	day := rand.Intn(int(types.LastDay(int32(year), uint8(month)))) + 1
   463  	hour := rand.Intn(24)
   464  	minute := rand.Intn(60)
   465  	second := rand.Intn(60)
   466  	microSecond := rand.Intn(1e6)
   467  	return types.FromClockUTC(int32(year), uint8(month), uint8(day), uint8(hour), uint8(minute), uint8(second), uint32(microSecond))
   468  }
   469  
   470  func randDecimal64() types.Decimal64 {
   471  	return types.Decimal64(rand.Int() % 10000000000)
   472  }
   473  
   474  func randDecimal128() types.Decimal128 {
   475  	return types.Decimal128{B0_63: uint64(rand.Int() % 10000000000), B64_127: 0}
   476  }
   477  
   478  func randStringType() []byte {
   479  	b := make([]byte, 1024)
   480  	crand.Read(b)
   481  	return b
   482  }