github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/db/test/txn_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 test 16 17 import ( 18 "context" 19 "fmt" 20 "math/rand" 21 "sync" 22 "testing" 23 "time" 24 25 pkgcatalog "github.com/matrixorigin/matrixone/pkg/catalog" 26 "github.com/matrixorigin/matrixone/pkg/common/moerr" 27 "github.com/matrixorigin/matrixone/pkg/container/types" 28 "github.com/matrixorigin/matrixone/pkg/logutil" 29 "github.com/matrixorigin/matrixone/pkg/objectio" 30 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog" 31 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common" 32 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers" 33 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/db/testutil" 34 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle" 35 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 36 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/options" 37 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils" 38 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/txn/txnbase" 39 "github.com/panjf2000/ants/v2" 40 "github.com/stretchr/testify/assert" 41 ) 42 43 var wareHouse *catalog.Schema 44 var district *catalog.Schema 45 46 var app1db = "app1" 47 var goods *catalog.Schema 48 var balance *catalog.Schema 49 var user *catalog.Schema 50 var deal *catalog.Schema 51 var repertory *catalog.Schema 52 var app1Conf *APP1Conf 53 54 var errNotEnoughRepertory = moerr.NewInternalErrorNoCtx("not enough repertory") 55 56 type APP1Conf struct { 57 Users int 58 InitBalance float64 59 GoodKinds int 60 GoodRepertory int 61 } 62 63 type APP1Client struct { 64 ID uint64 65 Name string 66 Txn txnif.AsyncTxn 67 DB handle.Database 68 Rel handle.Relation 69 } 70 71 type APP1Goods struct { 72 ID uint64 73 Name string 74 Price float64 75 } 76 77 type APP1Repertory struct { 78 ID uint64 79 GoodsID uint64 80 Count uint64 81 } 82 83 type APP1 struct { 84 sync.RWMutex 85 Clients []*APP1Client 86 Goods []*APP1Goods 87 DBName string 88 Mgr *txnbase.TxnManager 89 } 90 91 func init() { 92 app1Conf = &APP1Conf{ 93 Users: 100, 94 InitBalance: 1000000, 95 GoodKinds: 2000, 96 GoodRepertory: 100, 97 } 98 99 var err error 100 wareHouse = catalog.NewEmptySchema("WAREHOUSE") 101 wareHouse.BlockMaxRows = 40000 102 wareHouse.ObjectMaxBlocks = 40 103 _ = wareHouse.AppendPKCol("W_ID", types.T_uint8.ToType(), 0) 104 _ = wareHouse.AppendCol("W_NAME", types.T_varchar.ToType()) 105 _ = wareHouse.AppendCol("W_STREET_1", types.T_varchar.ToType()) 106 _ = wareHouse.AppendCol("W_STREET_2", types.T_varchar.ToType()) 107 _ = wareHouse.AppendCol("W_CITY", types.T_varchar.ToType()) 108 _ = wareHouse.AppendCol("W_STATE", types.T_varchar.ToType()) 109 _ = wareHouse.AppendCol("W_ZIP", types.T_varchar.ToType()) 110 _ = wareHouse.AppendCol("W_TAX", types.T_float64.ToType()) 111 _ = wareHouse.AppendCol("W_YTD", types.T_float64.ToType()) 112 if err = wareHouse.Finalize(false); err != nil { 113 panic(err) 114 } 115 116 district = catalog.NewEmptySchema("DISTRICT") 117 district.BlockMaxRows = 40000 118 district.ObjectMaxBlocks = 40 119 _ = district.AppendPKCol("D_ID", types.T_int16.ToType(), 0) 120 _ = district.AppendCol("D_W_ID", types.T_uint8.ToType()) 121 _ = district.AppendCol("D_NAME", types.T_varchar.ToType()) 122 _ = district.AppendCol("D_STREET_1", types.T_varchar.ToType()) 123 _ = district.AppendCol("D_STREET_2", types.T_varchar.ToType()) 124 _ = district.AppendCol("D_CITY", types.T_varchar.ToType()) 125 _ = district.AppendCol("D_STATE", types.T_varchar.ToType()) 126 _ = district.AppendCol("D_ZIP", types.T_varchar.ToType()) 127 _ = district.AppendCol("D_TAX", types.T_float64.ToType()) 128 _ = district.AppendCol("D_YTD", types.T_float64.ToType()) 129 _ = district.AppendCol("D_NEXT_O_ID", types.T_int64.ToType()) 130 if err = district.Finalize(false); err != nil { 131 panic(err) 132 } 133 134 balance = catalog.NewEmptySchema("BALANCE") 135 balance.BlockMaxRows = 40000 136 balance.ObjectMaxBlocks = 40 137 _ = balance.AppendPKCol("ID", types.T_uint64.ToType(), 0) 138 _ = balance.AppendCol("BALANCE", types.T_float64.ToType()) 139 // balance.AppendCol("USERID", types.T_uint64.ToType()) 140 if err = balance.Finalize(false); err != nil { 141 panic(err) 142 } 143 144 user = catalog.NewEmptySchema("USER") 145 user.BlockMaxRows = 40000 146 user.ObjectMaxBlocks = 40 147 _ = user.AppendPKCol("ID", types.T_uint64.ToType(), 0) 148 _ = user.AppendCol("NAME", types.T_varchar.ToType()) 149 _ = user.AppendCol("BIRTH", types.T_date.ToType()) 150 _ = user.AppendCol("ADDR", types.T_varchar.ToType()) 151 _ = user.AppendCol("BALANCEID", types.T_uint64.ToType()) 152 if err = user.Finalize(false); err != nil { 153 panic(err) 154 } 155 156 goods = catalog.NewEmptySchema("GOODS") 157 goods.BlockMaxRows = 40000 158 goods.ObjectMaxBlocks = 40 159 _ = goods.AppendPKCol("ID", types.T_uint64.ToType(), 0) 160 _ = goods.AppendCol("NAME", types.T_varchar.ToType()) 161 _ = goods.AppendCol("PRICE", types.T_float64.ToType()) 162 _ = goods.AppendCol("DESC", types.T_varchar.ToType()) 163 if err = goods.Finalize(false); err != nil { 164 panic(err) 165 } 166 167 repertory = catalog.NewEmptySchema("REPERTORY") 168 repertory.BlockMaxRows = 40000 169 repertory.ObjectMaxBlocks = 40 170 _ = repertory.AppendPKCol("ID", types.T_uint64.ToType(), 0) 171 _ = repertory.AppendCol("GOODID", types.T_uint64.ToType()) 172 _ = repertory.AppendCol("COUNT", types.T_uint64.ToType()) 173 if err = repertory.Finalize(false); err != nil { 174 panic(err) 175 } 176 177 deal = catalog.NewEmptySchema("DEAL") 178 deal.BlockMaxRows = 40000 179 deal.ObjectMaxBlocks = 40 180 _ = deal.AppendPKCol("ID", types.T_uint64.ToType(), 0) 181 _ = deal.AppendCol("USERID", types.T_uint64.ToType()) 182 _ = deal.AppendCol("GOODID", types.T_uint64.ToType()) 183 _ = deal.AppendCol("QUANTITY", types.T_uint32.ToType()) 184 _ = deal.AppendCol("DEALTIME", types.T_datetime.ToType()) 185 if err = deal.Finalize(false); err != nil { 186 panic(err) 187 } 188 } 189 190 func NewApp1(mgr *txnbase.TxnManager, dbName string) *APP1 { 191 return &APP1{ 192 Mgr: mgr, 193 DBName: dbName, 194 Clients: make([]*APP1Client, 0), 195 Goods: make([]*APP1Goods, 0), 196 } 197 } 198 199 func NewAPP1UserClient(id uint64, name string) *APP1Client { 200 return &APP1Client{ 201 ID: id, 202 Name: name, 203 } 204 } 205 206 func (c *APP1Client) Clone() *APP1Client { 207 return &APP1Client{ 208 ID: c.ID, 209 Name: c.Name, 210 } 211 } 212 213 func (c *APP1Client) String() string { 214 s := fmt.Sprintf("User:%d,%s", c.ID, c.Name) 215 return s 216 } 217 func (c *APP1Client) Bind(db handle.Database, txn txnif.AsyncTxn) { 218 if c.Txn != nil { 219 panic("logic error") 220 } 221 c.Txn = txn 222 c.DB = db 223 c.Rel, _ = db.GetRelationByName(c.Name) 224 } 225 226 func (c *APP1Client) Unbind() { 227 if c.Txn == nil { 228 panic("logic error") 229 } 230 c.Txn = nil 231 c.DB = nil 232 c.Rel = nil 233 } 234 235 func (c *APP1Client) CheckBound() { 236 if c.Txn == nil { 237 panic("logic error") 238 } 239 } 240 241 // TODO: rewrite 242 func (c *APP1Client) GetGoodRepetory(goodId uint64) (id *common.ID, offset uint32, count uint64, err error) { 243 rel, _ := c.DB.GetRelationByName(repertory.Name) 244 blockIt := rel.MakeObjectIt() 245 var view *containers.ColumnView 246 found := false 247 for blockIt.Valid() { 248 blk := blockIt.GetObject() 249 for j := 0; j < blk.BlkCnt(); j++ { 250 view, err = blk.GetColumnDataByName(context.Background(), uint16(j), repertory.ColDefs[1].Name, common.DefaultAllocator) 251 if err != nil { 252 return 253 } 254 defer view.Close() 255 _ = view.GetData().Foreach(func(v any, _ bool, row int) (err error) { 256 pk := v.(uint64) 257 if pk != goodId { 258 return 259 } 260 if view.DeleteMask.Contains(uint64(row)) { 261 return 262 } 263 id = blk.Fingerprint() 264 key := *objectio.NewRowid(&id.BlockID, uint32(row)) 265 cntv, _, err := rel.GetValueByPhyAddrKey(key, 2) 266 if err != nil { 267 return 268 } 269 found = true 270 offset = uint32(row) 271 count = cntv.(uint64) 272 return moerr.NewInternalErrorNoCtx("stop iteration") 273 }, nil) 274 if found { 275 return 276 } 277 } 278 blockIt.Next() 279 } 280 err = moerr.NewNotFoundNoCtx() 281 return 282 } 283 284 // TODO: rewrite 285 func (c *APP1Client) GetGoodEntry(goodId uint64) (id *common.ID, offset uint32, entry *APP1Goods, err error) { 286 filter := handle.NewEQFilter(goodId) 287 goodRel, _ := c.DB.GetRelationByName(goods.Name) 288 id, offset, err = goodRel.GetByFilter(context.Background(), filter) 289 if err != nil { 290 return 291 } 292 293 entry = new(APP1Goods) 294 entry.ID = goodId 295 price, _, _ := goodRel.GetValue(id, offset, 2) 296 entry.Price = price.(float64) 297 return 298 } 299 300 func (c *APP1Client) BuyGood(goodId uint64, count uint64) error { 301 c.CheckBound() 302 _, _, entry, err := c.GetGoodEntry(goodId) 303 if err != nil { 304 return err 305 } 306 _, _, left, err := c.GetGoodRepetory(entry.ID) 307 if err != nil { 308 return err 309 } 310 logutil.Debugf("%s, Count=%d", entry.String(), left) 311 if count > left { 312 logutil.Warnf("NotEnough Good %d: Repe %d, Requested %d", goodId, left, count) 313 err = errNotEnoughRepertory 314 return err 315 } 316 newLeft := left - count 317 rel, _ := c.DB.GetRelationByName(repertory.Name) 318 err = rel.UpdateByFilter(context.Background(), handle.NewEQFilter(entry.ID), uint16(2), newLeft, false) 319 return err 320 } 321 322 func (g *APP1Goods) String() string { 323 return fmt.Sprintf("GoodId:%d, GoodName:%s, GoodPrice:%f", g.ID, g.Name, g.Price) 324 } 325 326 func MockWarehouses(dbName string, num uint8, txn txnif.AsyncTxn) (err error) { 327 db, err := txn.GetDatabase(dbName) 328 if moerr.IsMoErrCode(err, moerr.ErrBadDB) { 329 if db, err = txn.CreateDatabase(dbName, "", ""); err != nil { 330 return 331 } 332 } 333 rel, err := db.GetRelationByName(wareHouse.Name) 334 if err == moerr.GetOkExpectedEOB() { 335 if rel, err = db.CreateRelation(wareHouse); err != nil { 336 return 337 } 338 } 339 bat := catalog.MockBatch(wareHouse, int(num)) 340 defer bat.Close() 341 err = rel.Append(context.Background(), bat) 342 return 343 } 344 345 func GetWarehouseRelation(dbName string, txn txnif.AsyncTxn) (rel handle.Relation, err error) { 346 db, _ := txn.GetDatabase(dbName) 347 rel, err = db.GetRelationByName(wareHouse.Name) 348 return 349 } 350 351 func GetOrCreateDatabase(name string, txn txnif.AsyncTxn) handle.Database { 352 db, err := txn.GetDatabase(name) 353 if moerr.IsMoErrCode(err, moerr.ErrBadDB) { 354 if db, err = txn.CreateDatabase(name, "", ""); err != nil { 355 panic(err) 356 } 357 } 358 return db 359 } 360 361 func App1CreateTables(txn txnif.AsyncTxn) (db handle.Database, err error) { 362 db = GetOrCreateDatabase(app1db, txn) 363 if _, err = db.CreateRelation(user); err != nil { 364 return 365 } 366 if _, err = db.CreateRelation(goods); err != nil { 367 return 368 } 369 if _, err = db.CreateRelation(balance); err != nil { 370 return 371 } 372 if _, err = db.CreateRelation(deal); err != nil { 373 return 374 } 375 if _, err = db.CreateRelation(repertory); err != nil { 376 return 377 } 378 return 379 } 380 381 func (app1 *APP1) GetClient() *APP1Client { 382 idx := rand.Intn(len(app1.Clients)) 383 return app1.Clients[idx].Clone() 384 } 385 386 func (app1 *APP1) GetGoods() *APP1Goods { 387 idx := rand.Intn(len(app1.Goods)) 388 return app1.Goods[idx] 389 } 390 391 func (app1 *APP1) Init(factor int) { 392 txn, _ := app1.Mgr.StartTxn(nil) 393 defer func() { 394 err := txn.Commit(context.Background()) 395 if err != nil { 396 panic(err) 397 } 398 }() 399 db, err := App1CreateTables(txn) 400 if err != nil { 401 panic(err) 402 } 403 conf := *app1Conf 404 conf.GoodKinds *= factor 405 conf.GoodRepertory *= factor 406 conf.Users *= factor 407 balanceRel, err := db.GetRelationByName(balance.Name) 408 if err != nil { 409 panic(err) 410 } 411 balanceData := catalog.MockBatch(balance, int(conf.Users)) 412 defer balanceData.Close() 413 if err = balanceRel.Append(context.Background(), balanceData); err != nil { 414 panic(err) 415 } 416 417 userRel, err := db.GetRelationByName(user.Name) 418 if err != nil { 419 panic(err) 420 } 421 provider := containers.NewMockDataProvider() 422 provider.AddColumnProvider(4, balanceData.Vecs[0]) 423 userData := containers.MockBatchWithAttrs(user.Types(), user.Attrs(), conf.Users, user.GetSingleSortKeyIdx(), provider) 424 defer userData.Close() 425 426 for i := 0; i < conf.Users; i++ { 427 uid := userData.Vecs[0].Get(i) 428 uname := userData.Vecs[1].Get(i) 429 client := NewAPP1UserClient(uid.(uint64), string(uname.([]byte))) 430 app1.Clients = append(app1.Clients, client) 431 // logutil.Info(client.String()) 432 } 433 434 if err = userRel.Append(context.Background(), userData); err != nil { 435 panic(err) 436 } 437 price := containers.MakeVector(goods.ColDefs[2].Type, common.DefaultAllocator) 438 defer price.Close() 439 for i := 0; i < conf.GoodKinds; i++ { 440 goodPrice := float64(rand.Intn(1000)+20) / float64(rand.Intn(10)+1) / float64(20) 441 price.Append(goodPrice, false) 442 } 443 goodsRel, err := db.GetRelationByName(goods.Name) 444 if err != nil { 445 panic(err) 446 } 447 provider.Reset() 448 provider.AddColumnProvider(2, price) 449 goodsData := containers.MockBatchWithAttrs(goods.Types(), goods.Attrs(), conf.GoodKinds, goods.GetSingleSortKeyIdx(), provider) 450 defer goodsData.Close() 451 if err = goodsRel.Append(context.Background(), goodsData); err != nil { 452 panic(err) 453 } 454 455 goodIds := goodsData.Vecs[0] 456 count := containers.MakeVector(repertory.ColDefs[2].Type, common.DefaultAllocator) 457 defer count.Close() 458 for i := 0; i < conf.GoodKinds; i++ { 459 goodCount := rand.Intn(1000) + 100 460 count.Append(uint64(goodCount), false) 461 goodsId := goodsData.Vecs[0].Get(i) 462 goodsName := goodsData.Vecs[1].Get(i) 463 goods := new(APP1Goods) 464 goods.ID = goodsId.(uint64) 465 goods.Name = string(goodsName.([]byte)) 466 app1.Goods = append(app1.Goods, goods) 467 } 468 provider.Reset() 469 provider.AddColumnProvider(1, goodIds) 470 provider.AddColumnProvider(2, count) 471 repertoryData := containers.MockBatchWithAttrs(repertory.Types(), repertory.Attrs(), int(conf.GoodKinds), repertory.GetSingleSortKeyIdx(), provider) 472 defer repertoryData.Close() 473 repertoryRel, err := db.GetRelationByName(repertory.Name) 474 if err != nil { 475 panic(err) 476 } 477 if err = repertoryRel.Append(context.Background(), repertoryData); err != nil { 478 panic(err) 479 } 480 } 481 482 func TestApp1(t *testing.T) { 483 defer testutils.AfterTest(t)() 484 testutils.EnsureNoLeak(t) 485 ctx := context.Background() 486 487 opts := new(options.Options) 488 db := testutil.InitTestDB(ctx, ModuleName, t, opts) 489 defer db.Close() 490 mgr := db.TxnMgr 491 c := db.Catalog 492 493 app1 := NewApp1(mgr, "app1") 494 app1.Init(1) 495 496 p, _ := ants.NewPool(100) 497 defer p.Release() 498 499 var wg sync.WaitGroup 500 buyTxn := func() { 501 defer wg.Done() 502 txn, _ := mgr.StartTxn(nil) 503 client := app1.GetClient() 504 db, _ := txn.GetDatabase(app1.DBName) 505 client.Bind(db, txn) 506 goods := app1.GetGoods() 507 err := client.BuyGood(goods.ID, uint64(rand.Intn(2)+10)) 508 if err != nil { 509 // t.Log(err) 510 err := txn.Rollback(context.Background()) 511 assert.Nil(t, err) 512 } else { 513 err := txn.Commit(context.Background()) 514 assert.Nil(t, err) 515 } 516 if txn.GetTxnState(true) == txnif.TxnStateRollbacked { 517 t.Log(txn.String()) 518 } 519 } 520 for i := 0; i < 500; i++ { 521 wg.Add(1) 522 err := p.Submit(buyTxn) 523 assert.Nil(t, err) 524 } 525 wg.Wait() 526 t.Log(c.SimplePPString(common.PPL1)) 527 { 528 // txn := mgr.StartTxn(nil) 529 // db, _ := txn.GetDatabase(app1.DBName) 530 // rel, _ := db.GetRelationByName(repertory.Name) 531 // t.Log(rel.SimplePPString(common.PPL1)) 532 } 533 } 534 535 func TestWarehouse(t *testing.T) { 536 defer testutils.AfterTest(t)() 537 testutils.EnsureNoLeak(t) 538 ctx := context.Background() 539 540 db := testutil.InitTestDB(ctx, ModuleName, t, nil) 541 defer db.Close() 542 543 txn, _ := db.StartTxn(nil) 544 err := MockWarehouses("test", 20, txn) 545 assert.Nil(t, err) 546 assert.Nil(t, txn.Commit(context.Background())) 547 t.Log(db.Catalog.SimplePPString(common.PPL1)) 548 549 { 550 txn, _ = db.StartTxn(nil) 551 rel, err := GetWarehouseRelation("test", txn) 552 assert.Nil(t, err) 553 it := rel.MakeObjectIt() 554 blk := it.GetObject() 555 view, _ := blk.GetColumnDataById(context.Background(), 0, 1, common.DefaultAllocator) 556 t.Log(view.GetData().String()) 557 defer view.Close() 558 testutil.CheckAllColRowsByScan(t, rel, 20, false) 559 _ = txn.Commit(context.Background()) 560 } 561 } 562 563 func TestTxn7(t *testing.T) { 564 defer testutils.AfterTest(t)() 565 testutils.EnsureNoLeak(t) 566 ctx := context.Background() 567 568 tae := testutil.InitTestDB(ctx, ModuleName, t, nil) 569 defer tae.Close() 570 schema := catalog.MockSchemaAll(13, 12) 571 schema.BlockMaxRows = 10 572 schema.ObjectMaxBlocks = 2 573 574 bat := catalog.MockBatch(schema, 20) 575 defer bat.Close() 576 577 txn, _ := tae.StartTxn(nil) 578 db, err := txn.CreateDatabase("db", "", "") 579 assert.NoError(t, err) 580 _, err = db.CreateRelation(schema) 581 assert.NoError(t, err) 582 assert.NoError(t, txn.Commit(context.Background())) 583 584 txn, _ = tae.StartTxn(nil) 585 db, _ = txn.GetDatabase("db") 586 rel, _ := db.GetRelationByName(schema.Name) 587 err = rel.Append(context.Background(), bat) 588 assert.NoError(t, err) 589 { 590 txn, _ := tae.StartTxn(nil) 591 db, _ := txn.GetDatabase("db") 592 rel, _ := db.GetRelationByName(schema.Name) 593 err := rel.Append(context.Background(), bat) 594 assert.NoError(t, err) 595 assert.NoError(t, txn.Commit(context.Background())) 596 } 597 err = txn.Commit(context.Background()) 598 t.Log(err) 599 assert.Error(t, err) 600 t.Log(txn.String()) 601 } 602 603 func TestTxn8(t *testing.T) { 604 defer testutils.AfterTest(t)() 605 testutils.EnsureNoLeak(t) 606 ctx := context.Background() 607 608 tae := testutil.InitTestDB(ctx, ModuleName, t, nil) 609 schema := catalog.MockSchemaAll(13, 2) 610 schema.BlockMaxRows = 10 611 schema.ObjectMaxBlocks = 2 612 613 bat := catalog.MockBatch(schema, int(schema.BlockMaxRows*10)) 614 defer bat.Close() 615 bats := bat.Split(2) 616 617 txn, _ := tae.StartTxn(nil) 618 db, _ := txn.GetDatabase(pkgcatalog.MO_CATALOG) 619 rel, _ := db.CreateRelation(schema) 620 err := rel.Append(context.Background(), bats[0]) 621 assert.NoError(t, err) 622 assert.NoError(t, txn.Commit(context.Background())) 623 624 txn, _ = tae.StartTxn(nil) 625 db, _ = txn.GetDatabase(pkgcatalog.MO_CATALOG) 626 rel, _ = db.GetRelationByName(schema.Name) 627 err = rel.Append(context.Background(), bats[1]) 628 assert.NoError(t, err) 629 pkv := bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(2) 630 filter := handle.NewEQFilter(pkv) 631 err = rel.UpdateByFilter(context.Background(), filter, 3, int64(9999), false) 632 assert.NoError(t, err) 633 634 pkv = bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(3) 635 filter = handle.NewEQFilter(pkv) 636 id, row, err := rel.GetByFilter(context.Background(), filter) 637 assert.NoError(t, err) 638 err = rel.RangeDelete(id, row, row, handle.DT_Normal) 639 assert.NoError(t, err) 640 641 tae.Close() 642 643 _, err = tae.StartTxn(nil) 644 assert.Error(t, err) 645 646 err = txn.Commit(context.Background()) 647 t.Log(err) 648 } 649 650 // Test wait committing 651 func TestTxn9(t *testing.T) { 652 defer testutils.AfterTest(t)() 653 testutils.EnsureNoLeak(t) 654 ctx := context.Background() 655 656 tae := testutil.InitTestDB(ctx, ModuleName, t, nil) 657 defer tae.Close() 658 659 schema := catalog.MockSchemaAll(13, 12) 660 schema.BlockMaxRows = 20 661 schema.ObjectMaxBlocks = 4 662 expectRows := schema.BlockMaxRows * 5 / 2 663 bat := catalog.MockBatch(schema, int(expectRows)) 664 defer bat.Close() 665 bats := bat.Split(5) 666 667 txn, _ := tae.StartTxn(nil) 668 db, _ := txn.CreateDatabase("db", "", "") 669 _, _ = db.CreateRelation(schema) 670 assert.NoError(t, txn.Commit(context.Background())) 671 672 var wg sync.WaitGroup 673 674 scanNames := func(txn txnif.AsyncTxn) { 675 defer wg.Done() 676 txn2, _ := tae.StartTxn(nil) 677 db, _ := txn2.GetDatabase("db") 678 it := db.MakeRelationIt() 679 cnt := 0 680 for it.Valid() { 681 cnt++ 682 it.Next() 683 } 684 startTS := txn2.GetStartTS() 685 prepareTS := txn.GetPrepareTS() 686 if startTS.Greater(&prepareTS) { 687 assert.Equal(t, 2, cnt) 688 } else { 689 assert.Equal(t, 1, cnt) 690 } 691 assert.NoError(t, txn2.Commit(context.Background())) 692 } 693 694 scanCol := func(waitExpect, nowaitExpect int, waitTxn txnif.AsyncTxn) { 695 defer wg.Done() 696 txn, _ := tae.StartTxn(nil) 697 db, _ := txn.GetDatabase("db") 698 rel, _ := db.GetRelationByName(schema.Name) 699 if waitTxn != nil { 700 startTS := txn.GetStartTS() 701 prepareTS := waitTxn.GetPrepareTS() 702 if startTS.Greater(&prepareTS) { 703 testutil.CheckAllColRowsByScan(t, rel, waitExpect, true) 704 } else { 705 testutil.CheckAllColRowsByScan(t, rel, nowaitExpect, true) 706 } 707 } else { 708 testutil.CheckAllColRowsByScan(t, rel, nowaitExpect, true) 709 } 710 assert.NoError(t, txn.Commit(context.Background())) 711 } 712 713 txn, _ = tae.StartTxn(nil) 714 db, _ = txn.GetDatabase("db") 715 txn.SetApplyCommitFn(func(txn txnif.AsyncTxn) error { 716 wg.Add(1) 717 go scanNames(txn) 718 time.Sleep(time.Millisecond * 10) 719 store := txn.GetStore() 720 return store.ApplyCommit() 721 }) 722 schema2 := catalog.MockSchemaAll(13, 12) 723 _, _ = db.CreateRelation(schema2) 724 rel, _ := db.GetRelationByName(schema.Name) 725 err := rel.Append(context.Background(), bats[0]) 726 assert.NoError(t, err) 727 assert.NoError(t, txn.Commit(context.Background())) 728 wg.Wait() 729 730 apply := func(waitExpect, nowaitExpect int, waitTxn txnif.AsyncTxn) func(txnif.AsyncTxn) error { 731 return func(txn txnif.AsyncTxn) error { 732 wg.Add(1) 733 go scanCol(waitExpect, nowaitExpect, waitTxn) 734 time.Sleep(time.Millisecond * 10) 735 store := txn.GetStore() 736 return store.ApplyCommit() 737 } 738 } 739 740 txn, _ = tae.StartTxn(nil) 741 db, _ = txn.GetDatabase("db") 742 txn.SetApplyCommitFn(apply(int(expectRows)/5*2, int(expectRows/5), txn)) 743 rel, _ = db.GetRelationByName(schema.Name) 744 err = rel.Append(context.Background(), bats[1]) 745 assert.NoError(t, err) 746 assert.NoError(t, txn.Commit(context.Background())) 747 wg.Wait() 748 749 txn, _ = tae.StartTxn(nil) 750 db, _ = txn.GetDatabase("db") 751 txn.SetApplyCommitFn(apply(int(expectRows/5*2)-1, int(expectRows/5)*2, txn)) 752 rel, _ = db.GetRelationByName(schema.Name) 753 v := bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(2) 754 filter := handle.NewEQFilter(v) 755 id, row, err := rel.GetByFilter(context.Background(), filter) 756 assert.NoError(t, err) 757 err = rel.RangeDelete(id, row, row, handle.DT_Normal) 758 assert.NoError(t, err) 759 assert.NoError(t, txn.Commit(context.Background())) 760 wg.Wait() 761 762 txn, _ = tae.StartTxn(nil) 763 db, _ = txn.GetDatabase("db") 764 txn.SetApplyCommitFn(apply(0, int(expectRows/5*2)-1, nil)) 765 rel, _ = db.GetRelationByName(schema.Name) 766 v = bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(3) 767 filter = handle.NewEQFilter(v) 768 err = rel.UpdateByFilter(context.Background(), filter, 2, int32(9999), false) 769 assert.NoError(t, err) 770 assert.NoError(t, txn.Commit(context.Background())) 771 wg.Wait() 772 } 773 774 // func TestTxn10(t *testing.T) { 775 // opts := config.WithLongScanAndCKPOpts(nil) 776 // tae := newTestEngine(t, opts) 777 // defer tae.Close() 778 // schema := catalog.MockSchemaAll(18, 2) 779 // tae.bindSchema(schema) 780 // bat := catalog.MockBatch(schema, 5) 781 // defer bat.Close() 782 // tae.createRelAndAppend(bat.Window(0, 2), true) 783 784 // txn1, rel1 := tae.getRelation() 785 // blk := getOneBlock(rel1) 786 // view, err := blk.GetColumnDataById(context.Background(), 2, nil, nil) 787 // assert.NoError(t, err) 788 // defer view.Close() 789 // t.Log(view.String()) 790 // err = rel1.Append(context.Background(), bat.Window(2, 1)) 791 // assert.NoError(t, err) 792 // blk = getOneBlock(rel1) 793 // view, err = blk.GetColumnDataById(context.Background(), 2, nil, nil) 794 // assert.NoError(t, err) 795 // defer view.Close() 796 // t.Log(view.String()) 797 // { 798 // txn, rel := tae.getRelation() 799 // err := rel.Append(context.Background(), bat.Window(2, 1)) 800 // assert.NoError(t, err) 801 // assert.NoError(t, txn.Commit(context.Background())) 802 // txn, rel = tae.getRelation() 803 // blk := getOneBlock(rel) 804 // view, err := blk.GetColumnDataById(context.Background(), 2, nil, nil) 805 // assert.NoError(t, err) 806 // defer view.Close() 807 // t.Log(view.String()) 808 // assert.NoError(t, txn.Commit(context.Background())) 809 // } 810 811 // // filter := handle.NewEQFilter(int32(99)) 812 // // err = rel1.DeleteByFilter(filter) 813 // // assert.NoError(t, err) 814 // win := bat.CloneWindow(2, 1) 815 // win.Vecs[2].Update(0, int32(99)) 816 // err = rel1.Append(context.Background(), win) 817 // { 818 // // filter := handle.NewEQFilter(int32(99)) 819 // // txn, rel := tae.getRelation() 820 // // err = rel1.UpdateByFilter(context.Background(), filter, 2, int32(88)) 821 // // assert.NoError(t, err) 822 // // assert.NoError(t, txn.Commit(context.Background())) 823 // } 824 // return 825 // assert.NoError(t, txn1.Commit(context.Background())) 826 // } 827 828 // func TestTxn11(t *testing.T) { 829 // opts := config.WithLongScanAndCKPOpts(nil) 830 // tae := newTestEngine(t, opts) 831 // defer tae.Close() 832 // schema := catalog.MockSchema(2, 0) 833 // tae.bindSchema(schema) 834 // bat1 := catalog.MockBatch(schema, 0) 835 // defer bat1.Close() 836 // bat1.Vecs[0].AppendMany(int32(1), int32(2)) 837 // bat1.Vecs[1].AppendMany(int32(1), int32(2)) 838 // bat2 := catalog.MockBatch(schema, 0) 839 // defer bat2.Close() 840 // bat2.Vecs[0].Append(context.Background(), int32(3)) 841 // bat2.Vecs[0].Append(context.Background(), int32(4)) 842 // bat2.Vecs[1].Append(context.Background(), int32(1)) 843 // bat2.Vecs[1].Append(context.Background(), int32(2)) 844 845 // tae.createRelAndAppend(bat1, true) 846 847 // buffer := new(bytes.Buffer) 848 849 // txn, rel := tae.getRelation() 850 // blk := getOneBlock(rel) 851 // view, err := blk.GetColumnDataById(context.Background(), 0, nil, buffer) 852 // assert.NoError(t, err) 853 // defer view.Close() 854 // view, err = blk.GetColumnDataById(context.Background(), 1, nil, buffer) 855 // assert.NoError(t, err) 856 // defer view.Close() 857 858 // err = rel.Append(context.Background(), bat2) 859 // assert.NoError(t, err) 860 // it := rel.MakeBlockIt() 861 // for it.Valid() { 862 // blk = it.GetBlock() 863 // t.Log(blk.Fingerprint().String()) 864 // view, err = blk.GetColumnDataById(context.Background(), 0, nil, buffer) 865 // assert.NoError(t, err) 866 // defer view.Close() 867 // t.Log(view.String()) 868 // view, err = blk.GetColumnDataById(context.Background(), 1, nil, buffer) 869 // assert.NoError(t, err) 870 // defer view.Close() 871 // t.Log(view.String()) 872 // it.Next() 873 // } 874 // filter := handle.NewEQFilter(int32(1)) 875 // err = rel.DeleteByFilter(filter) 876 // testutil.CheckAllColRowsByScan(t, rel, 3, true) 877 // assert.NoError(t, err) 878 // { 879 // txn, rel := tae.getRelation() 880 // it := rel.MakeBlockIt() 881 // for it.Valid() { 882 // blk := it.GetBlock() 883 // view, err := blk.GetColumnDataById(context.Background(), 0, nil, buffer) 884 // assert.NoError(t, err) 885 // defer view.Close() 886 // t.Log(view.String()) 887 // it.Next() 888 // } 889 890 // assert.NoError(t, txn.Commit(context.Background())) 891 // } 892 893 // txn.Commit(context.Background()) 894 // }