github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/index_metadata_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 colexec 16 17 import ( 18 "context" 19 "testing" 20 21 "github.com/golang/mock/gomock" 22 "github.com/matrixorigin/matrixone/pkg/catalog" 23 "github.com/matrixorigin/matrixone/pkg/compress" 24 "github.com/matrixorigin/matrixone/pkg/container/batch" 25 "github.com/matrixorigin/matrixone/pkg/container/types" 26 "github.com/matrixorigin/matrixone/pkg/container/vector" 27 mock_frontend "github.com/matrixorigin/matrixone/pkg/frontend/test" 28 "github.com/matrixorigin/matrixone/pkg/pb/plan" 29 "github.com/matrixorigin/matrixone/pkg/testutil" 30 "github.com/matrixorigin/matrixone/pkg/vm/engine" 31 "github.com/matrixorigin/matrixone/pkg/vm/process" 32 "github.com/stretchr/testify/require" 33 ) 34 35 func TestInsertIndexMetadata(t *testing.T) { 36 ctrl := gomock.NewController(t) 37 defer ctrl.Finish() 38 39 txnOperator := mock_frontend.NewMockTxnOperator(ctrl) 40 proc := testutil.NewProc() 41 proc.TxnOperator = txnOperator 42 43 mockEngine := mock_frontend.NewMockEngine(ctrl) 44 mockEngine.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 45 mockEngine.EXPECT().AllocateIDByKey(gomock.Any(), gomock.Any()).Return(uint64(272510), nil).AnyTimes() 46 //-------------------------------------------------mo_catalog + mo_indexes----------------------------------------------------------- 47 catalog_database := mock_frontend.NewMockDatabase(ctrl) 48 mockEngine.EXPECT().Database(gomock.Any(), catalog.MO_CATALOG, txnOperator).Return(catalog_database, nil).AnyTimes() 49 50 indexes_relation := mock_frontend.NewMockRelation(ctrl) 51 indexes_relation.EXPECT().Ranges(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes() 52 indexes_relation.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 53 indexes_relation.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 54 55 reader := mock_frontend.NewMockReader(ctrl) 56 reader.EXPECT().Read(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, attrs []string, b, c interface{}) (*batch.Batch, error) { 57 bat := batch.NewWithSize(3) 58 bat.Vecs[0] = vector.NewVec(types.T_Rowid.ToType()) 59 bat.Vecs[1] = vector.NewVec(types.T_uint64.ToType()) 60 bat.Vecs[2] = vector.NewVec(types.T_varchar.ToType()) 61 62 err := vector.AppendFixed(bat.GetVector(0), types.Rowid([types.RowidSize]byte{}), false, testutil.TestUtilMp) 63 if err != nil { 64 require.Nil(t, err) 65 } 66 67 err = vector.AppendFixed(bat.GetVector(1), uint64(272464), false, testutil.TestUtilMp) 68 if err != nil { 69 require.Nil(t, err) 70 } 71 72 err = vector.AppendBytes(bat.GetVector(2), []byte("empno"), false, testutil.TestUtilMp) 73 if err != nil { 74 require.Nil(t, err) 75 } 76 bat.SetRowCount(bat.GetVector(1).Length()) 77 return bat, nil 78 }).AnyTimes() 79 reader.EXPECT().Close().Return(nil).AnyTimes() 80 81 indexes_relation.EXPECT().NewReader(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]engine.Reader{reader}, nil).AnyTimes() 82 catalog_database.EXPECT().Relation(gomock.Any(), catalog.MO_INDEXES, gomock.Any()).Return(indexes_relation, nil).AnyTimes() 83 //--------------------------------------------------------------------------------------------------------------------------- 84 mock_emp_Relation := mock_frontend.NewMockRelation(ctrl) 85 mock_emp_Relation.EXPECT().TableDefs(gomock.Any()).Return(buildMockTableDefs(mock_emp_table), nil).AnyTimes() 86 mock_emp_Relation.EXPECT().GetTableID(gomock.Any()).Return(uint64(272464)).AnyTimes() 87 88 mock_db1_database := mock_frontend.NewMockDatabase(ctrl) 89 mock_db1_database.EXPECT().Relation(gomock.Any(), gomock.Any(), gomock.Any()).Return(mock_emp_Relation, nil).AnyTimes() 90 mock_db1_database.EXPECT().GetDatabaseId(gomock.Any()).Return("123456").AnyTimes() 91 92 type args struct { 93 eg engine.Engine 94 ctx context.Context 95 db engine.Database 96 proc *process.Process 97 tblName string 98 } 99 tests := []struct { 100 name string 101 args args 102 wantErr bool 103 }{ 104 { 105 name: "test03", 106 args: args{ 107 eg: mockEngine, 108 ctx: proc.Ctx, 109 db: mock_db1_database, 110 tblName: "emp", 111 proc: proc, 112 }, 113 wantErr: false, 114 }, 115 } 116 for _, tt := range tests { 117 t.Run(tt.name, func(t *testing.T) { 118 if err := InsertIndexMetadata(tt.args.eg, tt.args.ctx, tt.args.db, tt.args.proc, tt.args.tblName); (err != nil) != tt.wantErr { 119 t.Errorf("InsertIndexMetadata() error = %v, wantErr %v", err, tt.wantErr) 120 } 121 }) 122 } 123 } 124 125 func TestInsertOneIndexMetadata(t *testing.T) { 126 ctrl := gomock.NewController(t) 127 defer ctrl.Finish() 128 129 txnOperator := mock_frontend.NewMockTxnOperator(ctrl) 130 131 proc := testutil.NewProc() 132 proc.TxnOperator = txnOperator 133 134 mockEngine := mock_frontend.NewMockEngine(ctrl) 135 mockEngine.EXPECT().New(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 136 mockEngine.EXPECT().AllocateIDByKey(gomock.Any(), gomock.Any()).Return(uint64(272510), nil).AnyTimes() 137 //-------------------------------------------------mo_catalog + mo_indexes----------------------------------------------------------- 138 catalog_database := mock_frontend.NewMockDatabase(ctrl) 139 140 mockEngine.EXPECT().Database(gomock.Any(), catalog.MO_CATALOG, txnOperator).Return(catalog_database, nil).AnyTimes() 141 142 indexes_relation := mock_frontend.NewMockRelation(ctrl) 143 indexes_relation.EXPECT().Ranges(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes() 144 indexes_relation.EXPECT().Delete(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 145 indexes_relation.EXPECT().Write(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() 146 147 reader := mock_frontend.NewMockReader(ctrl) 148 reader.EXPECT().Read(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, attrs []string, b, c interface{}) (*batch.Batch, error) { 149 bat := batch.NewWithSize(3) 150 bat.Vecs[0] = vector.NewVec(types.T_Rowid.ToType()) 151 bat.Vecs[1] = vector.NewVec(types.T_uint64.ToType()) 152 bat.Vecs[2] = vector.NewVec(types.T_varchar.ToType()) 153 154 err := vector.AppendFixed(bat.GetVector(0), types.Rowid([types.RowidSize]byte{}), false, testutil.TestUtilMp) 155 if err != nil { 156 require.Nil(t, err) 157 } 158 159 err = vector.AppendFixed(bat.GetVector(1), uint64(272464), false, testutil.TestUtilMp) 160 if err != nil { 161 require.Nil(t, err) 162 } 163 164 err = vector.AppendBytes(bat.GetVector(2), []byte("empno"), false, testutil.TestUtilMp) 165 if err != nil { 166 require.Nil(t, err) 167 } 168 bat.SetRowCount(bat.GetVector(1).Length()) 169 return bat, nil 170 }).AnyTimes() 171 reader.EXPECT().Close().Return(nil).AnyTimes() 172 173 indexes_relation.EXPECT().NewReader(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return([]engine.Reader{reader}, nil).AnyTimes() 174 catalog_database.EXPECT().Relation(gomock.Any(), catalog.MO_INDEXES, gomock.Any()).Return(indexes_relation, nil).AnyTimes() 175 //--------------------------------------------------------------------------------------------------------------------------- 176 177 mock_emp_Relation := mock_frontend.NewMockRelation(ctrl) 178 mock_emp_Relation.EXPECT().TableDefs(gomock.Any()).Return(buildMockTableDefs(mock_emp_table), nil).AnyTimes() 179 mock_emp_Relation.EXPECT().GetTableID(gomock.Any()).Return(uint64(272464)).AnyTimes() 180 181 mock_db1_database := mock_frontend.NewMockDatabase(ctrl) 182 mock_db1_database.EXPECT().Relation(gomock.Any(), gomock.Any(), gomock.Any()).Return(mock_emp_Relation, nil).AnyTimes() 183 mock_db1_database.EXPECT().GetDatabaseId(gomock.Any()).Return("123456").AnyTimes() 184 185 type args struct { 186 eg engine.Engine 187 ctx context.Context 188 db engine.Database 189 proc *process.Process 190 tblName string 191 idxdef *plan.IndexDef 192 } 193 tests := []struct { 194 name string 195 args args 196 wantErr bool 197 }{ 198 { 199 name: "test04", 200 args: args{ 201 eg: mockEngine, 202 ctx: proc.Ctx, 203 db: mock_db1_database, 204 tblName: "emp", 205 proc: proc, 206 idxdef: &plan.IndexDef{ 207 IdxId: "", 208 IndexName: "idx11", 209 Parts: []string{"ename", "sal", "depto"}, 210 Unique: false, 211 IndexTableName: "", 212 TableExist: false, 213 Comment: "this is a index on emp", 214 }, 215 }, 216 wantErr: false, 217 }, 218 } 219 for _, tt := range tests { 220 t.Run(tt.name, func(t *testing.T) { 221 if err := InsertOneIndexMetadata(tt.args.eg, tt.args.ctx, tt.args.db, tt.args.proc, tt.args.tblName, tt.args.idxdef); (err != nil) != tt.wantErr { 222 t.Errorf("InsertOneIndexMetadata() error = %v, wantErr %v", err, tt.wantErr) 223 } 224 }) 225 } 226 } 227 228 // Define an anonymous function to construct the table structure 229 func buildMockTableDefs(table_cols []string) []engine.TableDef { 230 exeCols := make([]engine.TableDef, len(table_cols)) 231 for i := 0; i < len(table_cols); i++ { 232 if i == 0 { 233 exeCols[i] = &engine.ConstraintDef{ 234 Cts: []engine.Constraint{ 235 &engine.IndexDef{ 236 Indexes: []*plan.IndexDef{ 237 { 238 IdxId: "", 239 IndexName: "empno", 240 Parts: []string{"empno,ename"}, 241 Unique: true, 242 IndexTableName: "__mo_index_unique_c1d278ec-bfd6-11ed-9e9d-000c29203f30", 243 TableExist: true, 244 Comment: "", 245 }, 246 }, 247 }, 248 &engine.PrimaryKeyDef{ 249 Pkey: &plan.PrimaryKeyDef{ 250 PkeyColId: 0, 251 PkeyColName: "empno", 252 Names: []string{"empno"}, 253 }, 254 }, 255 }, 256 } 257 } else { 258 exeCols[i] = &engine.AttributeDef{ 259 Attr: engine.Attribute{ 260 Name: table_cols[i], 261 Alg: compress.None, 262 Type: mock_emp_map[table_cols[i]], 263 Default: nil, 264 OnUpdate: nil, 265 Primary: i == 0, 266 Comment: "comment message", 267 ClusterBy: false, 268 AutoIncrement: i == 1, 269 }, 270 } 271 } 272 } 273 return exeCols 274 } 275 276 var mock_emp_table = []string{ 277 "constraint", 278 mock_emp_empno, 279 mock_emp_ename, 280 mock_emp_job, 281 mock_emp_mgr, 282 mock_emp_hiredate, 283 mock_emp_sal, 284 mock_emp_comm, 285 mock_emp_deptno, 286 } 287 288 const ( 289 mock_emp_empno = "empno" 290 mock_emp_ename = "ename" 291 mock_emp_job = "job" 292 mock_emp_mgr = "mgr" 293 mock_emp_hiredate = "hiredate" 294 mock_emp_sal = "sal" 295 mock_emp_comm = "comm" 296 mock_emp_deptno = "deptno" 297 ) 298 299 var mock_emp_map = map[string]types.Type{ 300 mock_emp_empno: { 301 Oid: types.T_uint32, 302 Size: 4, 303 Width: 32, 304 Scale: -1, 305 }, 306 mock_emp_ename: { 307 Oid: types.T_varchar, 308 Size: 24, 309 Width: 15, 310 Scale: 0, 311 }, 312 mock_emp_job: { 313 Oid: types.T_varchar, 314 Size: 24, 315 Width: 10, 316 Scale: 0, 317 }, 318 mock_emp_mgr: { 319 Oid: types.T_uint32, 320 Size: 4, 321 Width: 32, 322 Scale: -1, 323 }, 324 mock_emp_hiredate: { 325 Oid: types.T_date, 326 Size: 4, 327 Width: 0, 328 Scale: 0, 329 }, 330 mock_emp_sal: { 331 Oid: types.T_decimal64, 332 Size: 8, 333 Width: 7, 334 Scale: 2, 335 }, 336 mock_emp_comm: { 337 Oid: types.T_decimal64, 338 Size: 8, 339 Width: 7, 340 Scale: 2, 341 }, 342 mock_emp_deptno: { 343 Oid: types.T_uint32, 344 Size: 4, 345 Width: 32, 346 Scale: -1, 347 }, 348 }