github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/db/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 db 16 17 import ( 18 "bytes" 19 "fmt" 20 "math/rand" 21 "sync" 22 "sync/atomic" 23 "testing" 24 "time" 25 26 pkgcatalog "github.com/matrixorigin/matrixone/pkg/catalog" 27 "github.com/matrixorigin/matrixone/pkg/common/moerr" 28 "github.com/matrixorigin/matrixone/pkg/container/types" 29 "github.com/matrixorigin/matrixone/pkg/logutil" 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/iface/handle" 34 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/txnif" 35 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/model" 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.SegmentMaxBlocks = 40 103 _ = wareHouse.AppendPKCol("W_ID", types.Type{Oid: types.T_uint8, Size: 1, Width: 8}, 0) 104 _ = wareHouse.AppendCol("W_NAME", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 105 _ = wareHouse.AppendCol("W_STREET_1", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 106 _ = wareHouse.AppendCol("W_STREET_2", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 107 _ = wareHouse.AppendCol("W_CITY", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 108 _ = wareHouse.AppendCol("W_STATE", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 109 _ = wareHouse.AppendCol("W_ZIP", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 110 _ = wareHouse.AppendCol("W_TAX", types.Type{Oid: types.T_float64, Size: 8, Width: 64}) 111 _ = wareHouse.AppendCol("W_YTD", types.Type{Oid: types.T_float64, Size: 8, Width: 64}) 112 if err = wareHouse.Finalize(false); err != nil { 113 panic(err) 114 } 115 116 district = catalog.NewEmptySchema("DISTRICT") 117 district.BlockMaxRows = 40000 118 district.SegmentMaxBlocks = 40 119 _ = district.AppendPKCol("D_ID", types.Type{Oid: types.T_int16, Size: 2, Width: 16}, 0) 120 _ = district.AppendCol("D_W_ID", types.Type{Oid: types.T_uint8, Size: 1, Width: 8}) 121 _ = district.AppendCol("D_NAME", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 122 _ = district.AppendCol("D_STREET_1", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 123 _ = district.AppendCol("D_STREET_2", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 124 _ = district.AppendCol("D_CITY", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 125 _ = district.AppendCol("D_STATE", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 126 _ = district.AppendCol("D_ZIP", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 127 _ = district.AppendCol("D_TAX", types.Type{Oid: types.T_float64, Size: 8, Width: 64}) 128 _ = district.AppendCol("D_YTD", types.Type{Oid: types.T_float64, Size: 8, Width: 64}) 129 _ = district.AppendCol("D_NEXT_O_ID", types.Type{Oid: types.T_int64, Size: 8, Width: 64}) 130 if err = district.Finalize(false); err != nil { 131 panic(err) 132 } 133 134 balance = catalog.NewEmptySchema("BALANCE") 135 balance.BlockMaxRows = 40000 136 balance.SegmentMaxBlocks = 40 137 _ = balance.AppendPKCol("ID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}, 0) 138 _ = balance.AppendCol("BALANCE", types.Type{Oid: types.T_float64, Size: 8, Width: 64}) 139 // balance.AppendCol("USERID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}) 140 if err = balance.Finalize(false); err != nil { 141 panic(err) 142 } 143 144 user = catalog.NewEmptySchema("USER") 145 user.BlockMaxRows = 40000 146 user.SegmentMaxBlocks = 40 147 _ = user.AppendPKCol("ID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}, 0) 148 _ = user.AppendCol("NAME", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 149 _ = user.AppendCol("BIRTH", types.Type{Oid: types.T_date, Size: 4, Width: 32}) 150 _ = user.AppendCol("ADDR", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 151 _ = user.AppendCol("BALANCEID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}) 152 if err = user.Finalize(false); err != nil { 153 panic(err) 154 } 155 156 goods = catalog.NewEmptySchema("GOODS") 157 goods.BlockMaxRows = 40000 158 goods.SegmentMaxBlocks = 40 159 _ = goods.AppendPKCol("ID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}, 0) 160 _ = goods.AppendCol("NAME", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 161 _ = goods.AppendCol("PRICE", types.Type{Oid: types.T_float64, Size: 8, Width: 64}) 162 _ = goods.AppendCol("DESC", types.Type{Oid: types.T_varchar, Size: 24, Width: 100}) 163 if err = goods.Finalize(false); err != nil { 164 panic(err) 165 } 166 167 repertory = catalog.NewEmptySchema("REPERTORY") 168 repertory.BlockMaxRows = 40000 169 repertory.SegmentMaxBlocks = 40 170 _ = repertory.AppendPKCol("ID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}, 0) 171 _ = repertory.AppendCol("GOODID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}) 172 _ = repertory.AppendCol("COUNT", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}) 173 if err = repertory.Finalize(false); err != nil { 174 panic(err) 175 } 176 177 deal = catalog.NewEmptySchema("DEAL") 178 deal.BlockMaxRows = 40000 179 deal.SegmentMaxBlocks = 40 180 _ = deal.AppendPKCol("ID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}, 0) 181 _ = deal.AppendCol("USERID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}) 182 _ = deal.AppendCol("GOODID", types.Type{Oid: types.T_uint64, Size: 8, Width: 64}) 183 _ = deal.AppendCol("QUANTITY", types.Type{Oid: types.T_uint32, Size: 4, Width: 32}) 184 _ = deal.AppendCol("DEALTIME", types.Type{Oid: types.T_datetime, Size: 8, Width: 64}) 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.MakeBlockIt() 245 var buffer bytes.Buffer 246 var view *model.ColumnView 247 found := false 248 for blockIt.Valid() { 249 buffer.Reset() 250 blk := blockIt.GetBlock() 251 view, err = blk.GetColumnDataByName(repertory.ColDefs[1].Name, &buffer) 252 if err != nil { 253 return 254 } 255 defer view.Close() 256 _ = view.GetData().Foreach(func(v any, row int) (err error) { 257 pk := v.(uint64) 258 if pk != goodId { 259 return 260 } 261 if view.DeleteMask != nil && view.DeleteMask.Contains(uint32(row)) { 262 return 263 } 264 id = blk.Fingerprint() 265 key := model.EncodePhyAddrKey(id.SegmentID, id.BlockID, uint32(row)) 266 cntv, err := rel.GetValueByPhyAddrKey(key, 2) 267 if err != nil { 268 return 269 } 270 found = true 271 offset = uint32(row) 272 count = cntv.(uint64) 273 return moerr.NewInternalErrorNoCtx("stop iteration") 274 }, nil) 275 if found { 276 return 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(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(handle.NewEQFilter(entry.ID), uint16(2), newLeft) 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(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() 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(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( 424 user.Types(), 425 user.Attrs(), 426 user.Nullables(), 427 conf.Users, 428 user.GetSingleSortKeyIdx(), 429 provider) 430 defer userData.Close() 431 432 for i := 0; i < conf.Users; i++ { 433 uid := userData.Vecs[0].Get(i) 434 uname := userData.Vecs[1].Get(i) 435 client := NewAPP1UserClient(uid.(uint64), string(uname.([]byte))) 436 app1.Clients = append(app1.Clients, client) 437 // logutil.Info(client.String()) 438 } 439 440 if err = userRel.Append(userData); err != nil { 441 panic(err) 442 } 443 price := containers.MakeVector(goods.ColDefs[2].Type, goods.ColDefs[2].Nullable()) 444 defer price.Close() 445 for i := 0; i < conf.GoodKinds; i++ { 446 goodPrice := float64(rand.Intn(1000)+20) / float64(rand.Intn(10)+1) / float64(20) 447 price.Append(goodPrice) 448 } 449 goodsRel, err := db.GetRelationByName(goods.Name) 450 if err != nil { 451 panic(err) 452 } 453 provider.Reset() 454 provider.AddColumnProvider(2, price) 455 goodsData := containers.MockBatchWithAttrs( 456 goods.Types(), 457 goods.Attrs(), 458 goods.Nullables(), 459 conf.GoodKinds, 460 goods.GetSingleSortKeyIdx(), 461 provider) 462 defer goodsData.Close() 463 if err = goodsRel.Append(goodsData); err != nil { 464 panic(err) 465 } 466 467 goodIds := goodsData.Vecs[0] 468 count := containers.MakeVector(repertory.ColDefs[2].Type, repertory.ColDefs[2].Nullable()) 469 defer count.Close() 470 for i := 0; i < conf.GoodKinds; i++ { 471 goodCount := rand.Intn(1000) + 100 472 count.Append(uint64(goodCount)) 473 goodsId := goodsData.Vecs[0].Get(i) 474 goodsName := goodsData.Vecs[1].Get(i) 475 goods := new(APP1Goods) 476 goods.ID = goodsId.(uint64) 477 goods.Name = string(goodsName.([]byte)) 478 app1.Goods = append(app1.Goods, goods) 479 } 480 provider.Reset() 481 provider.AddColumnProvider(1, goodIds) 482 provider.AddColumnProvider(2, count) 483 repertoryData := containers.MockBatchWithAttrs( 484 repertory.Types(), 485 repertory.Attrs(), 486 repertory.Nullables(), 487 int(conf.GoodKinds), 488 repertory.GetSingleSortKeyIdx(), 489 provider) 490 defer repertoryData.Close() 491 repertoryRel, err := db.GetRelationByName(repertory.Name) 492 if err != nil { 493 panic(err) 494 } 495 if err = repertoryRel.Append(repertoryData); err != nil { 496 panic(err) 497 } 498 } 499 500 func TestApp1(t *testing.T) { 501 defer testutils.AfterTest(t)() 502 testutils.EnsureNoLeak(t) 503 option := new(options.Options) 504 option.CacheCfg = new(options.CacheCfg) 505 option.CacheCfg.IndexCapacity = common.G 506 option.CacheCfg.InsertCapacity = common.G 507 option.CacheCfg.TxnCapacity = common.G 508 db := initDB(t, option) 509 defer db.Close() 510 mgr := db.TxnMgr 511 c := db.Opts.Catalog 512 513 app1 := NewApp1(mgr, "app1") 514 app1.Init(1) 515 516 p, _ := ants.NewPool(100) 517 defer p.Release() 518 519 var wg sync.WaitGroup 520 buyTxn := func() { 521 defer wg.Done() 522 txn, _ := mgr.StartTxn(nil) 523 client := app1.GetClient() 524 db, _ := txn.GetDatabase(app1.DBName) 525 client.Bind(db, txn) 526 goods := app1.GetGoods() 527 err := client.BuyGood(goods.ID, uint64(rand.Intn(2)+10)) 528 if err != nil { 529 // t.Log(err) 530 err := txn.Rollback() 531 assert.Nil(t, err) 532 } else { 533 err := txn.Commit() 534 assert.Nil(t, err) 535 } 536 if txn.GetTxnState(true) == txnif.TxnStateRollbacked { 537 t.Log(txn.String()) 538 } 539 } 540 for i := 0; i < 500; i++ { 541 wg.Add(1) 542 err := p.Submit(buyTxn) 543 assert.Nil(t, err) 544 } 545 wg.Wait() 546 t.Log(c.SimplePPString(common.PPL1)) 547 { 548 // txn := mgr.StartTxn(nil) 549 // db, _ := txn.GetDatabase(app1.DBName) 550 // rel, _ := db.GetRelationByName(repertory.Name) 551 // t.Log(rel.SimplePPString(common.PPL1)) 552 } 553 } 554 555 func TestWarehouse(t *testing.T) { 556 defer testutils.AfterTest(t)() 557 testutils.EnsureNoLeak(t) 558 db := initDB(t, nil) 559 defer db.Close() 560 561 txn, _ := db.StartTxn(nil) 562 err := MockWarehouses("test", 20, txn) 563 assert.Nil(t, err) 564 assert.Nil(t, txn.Commit()) 565 t.Log(db.Opts.Catalog.SimplePPString(common.PPL1)) 566 567 { 568 txn, _ = db.StartTxn(nil) 569 rel, err := GetWarehouseRelation("test", txn) 570 assert.Nil(t, err) 571 it := rel.MakeBlockIt() 572 blk := it.GetBlock() 573 var buffer bytes.Buffer 574 view, _ := blk.GetColumnDataById(1, &buffer) 575 t.Log(view.GetData().String()) 576 defer view.Close() 577 checkAllColRowsByScan(t, rel, 20, false) 578 _ = txn.Commit() 579 } 580 } 581 582 func TestTxn7(t *testing.T) { 583 defer testutils.AfterTest(t)() 584 testutils.EnsureNoLeak(t) 585 tae := initDB(t, nil) 586 defer tae.Close() 587 schema := catalog.MockSchemaAll(13, 12) 588 schema.BlockMaxRows = 10 589 schema.SegmentMaxBlocks = 2 590 591 bat := catalog.MockBatch(schema, 20) 592 defer bat.Close() 593 594 txn, _ := tae.StartTxn(nil) 595 db, err := txn.CreateDatabase("db", "") 596 assert.NoError(t, err) 597 _, err = db.CreateRelation(schema) 598 assert.NoError(t, err) 599 assert.NoError(t, txn.Commit()) 600 601 txn, _ = tae.StartTxn(nil) 602 db, _ = txn.GetDatabase("db") 603 rel, _ := db.GetRelationByName(schema.Name) 604 err = rel.Append(bat) 605 assert.NoError(t, err) 606 { 607 txn, _ := tae.StartTxn(nil) 608 db, _ := txn.GetDatabase("db") 609 rel, _ := db.GetRelationByName(schema.Name) 610 err := rel.Append(bat) 611 assert.NoError(t, err) 612 assert.NoError(t, txn.Commit()) 613 } 614 err = txn.Commit() 615 t.Log(err) 616 assert.Error(t, err) 617 t.Log(txn.String()) 618 } 619 620 func TestTxn8(t *testing.T) { 621 defer testutils.AfterTest(t)() 622 testutils.EnsureNoLeak(t) 623 tae := initDB(t, nil) 624 schema := catalog.MockSchemaAll(13, 2) 625 schema.BlockMaxRows = 10 626 schema.SegmentMaxBlocks = 2 627 628 bat := catalog.MockBatch(schema, int(schema.BlockMaxRows*10)) 629 defer bat.Close() 630 bats := bat.Split(2) 631 632 txn, _ := tae.StartTxn(nil) 633 db, _ := txn.GetDatabase(pkgcatalog.MO_CATALOG) 634 rel, _ := db.CreateRelation(schema) 635 err := rel.Append(bats[0]) 636 assert.NoError(t, err) 637 assert.NoError(t, txn.Commit()) 638 639 txn, _ = tae.StartTxn(nil) 640 db, _ = txn.GetDatabase(pkgcatalog.MO_CATALOG) 641 rel, _ = db.GetRelationByName(schema.Name) 642 err = rel.Append(bats[1]) 643 assert.NoError(t, err) 644 pkv := bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(2) 645 filter := handle.NewEQFilter(pkv) 646 err = rel.UpdateByFilter(filter, 3, int64(9999)) 647 assert.NoError(t, err) 648 649 pkv = bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(3) 650 filter = handle.NewEQFilter(pkv) 651 id, row, err := rel.GetByFilter(filter) 652 assert.NoError(t, err) 653 err = rel.RangeDelete(id, row, row, handle.DT_Normal) 654 assert.NoError(t, err) 655 656 tae.Close() 657 658 _, err = tae.StartTxn(nil) 659 assert.Error(t, err) 660 661 err = txn.Commit() 662 t.Log(err) 663 } 664 665 // Test wait committing 666 func TestTxn9(t *testing.T) { 667 defer testutils.AfterTest(t)() 668 testutils.EnsureNoLeak(t) 669 tae := initDB(t, nil) 670 defer tae.Close() 671 672 schema := catalog.MockSchemaAll(13, 12) 673 schema.BlockMaxRows = 20 674 schema.SegmentMaxBlocks = 4 675 expectRows := schema.BlockMaxRows * 5 / 2 676 bat := catalog.MockBatch(schema, int(expectRows)) 677 defer bat.Close() 678 bats := bat.Split(5) 679 680 txn, _ := tae.StartTxn(nil) 681 db, _ := txn.CreateDatabase("db", "") 682 _, _ = db.CreateRelation(schema) 683 assert.NoError(t, txn.Commit()) 684 685 var wg sync.WaitGroup 686 687 var val atomic.Uint32 688 689 scanNames := func() { 690 defer wg.Done() 691 txn, _ := tae.StartTxn(nil) 692 db, _ := txn.GetDatabase("db") 693 it := db.MakeRelationIt() 694 cnt := 0 695 for it.Valid() { 696 cnt++ 697 it.Next() 698 } 699 val.Store(2) 700 assert.Equal(t, 2, cnt) 701 assert.NoError(t, txn.Commit()) 702 } 703 704 scanCol := func() { 705 defer wg.Done() 706 txn, _ := tae.StartTxn(nil) 707 db, _ := txn.GetDatabase("db") 708 rel, _ := db.GetRelationByName(schema.Name) 709 rows := 0 710 it := rel.MakeBlockIt() 711 for it.Valid() { 712 blk := it.GetBlock() 713 view, err := blk.GetColumnDataById(2, nil) 714 assert.NoError(t, err) 715 defer view.Close() 716 t.Log(view.GetData().String()) 717 rows += blk.Rows() 718 it.Next() 719 } 720 val.Store(2) 721 // assert.Equal(t, int(expectRows/5*2), rows) 722 assert.NoError(t, txn.Commit()) 723 } 724 725 txn, _ = tae.StartTxn(nil) 726 db, _ = txn.GetDatabase("db") 727 txn.SetApplyCommitFn(func(txn txnif.AsyncTxn) error { 728 wg.Add(1) 729 go scanNames() 730 time.Sleep(time.Millisecond * 10) 731 val.Store(1) 732 store := txn.GetStore() 733 return store.ApplyCommit() 734 }) 735 schema2 := catalog.MockSchemaAll(13, 12) 736 _, _ = db.CreateRelation(schema2) 737 rel, _ := db.GetRelationByName(schema.Name) 738 err := rel.Append(bats[0]) 739 assert.NoError(t, err) 740 assert.NoError(t, txn.Commit()) 741 wg.Wait() 742 assert.Equal(t, uint32(2), val.Load()) 743 744 apply := func(_ txnif.AsyncTxn) error { 745 wg.Add(1) 746 go scanCol() 747 time.Sleep(time.Millisecond * 10) 748 val.Store(1) 749 store := txn.GetStore() 750 return store.ApplyCommit() 751 } 752 753 txn, _ = tae.StartTxn(nil) 754 db, _ = txn.GetDatabase("db") 755 txn.SetApplyCommitFn(apply) 756 rel, _ = db.GetRelationByName(schema.Name) 757 err = rel.Append(bats[1]) 758 assert.NoError(t, err) 759 assert.NoError(t, txn.Commit()) 760 wg.Wait() 761 762 txn, _ = tae.StartTxn(nil) 763 db, _ = txn.GetDatabase("db") 764 txn.SetApplyCommitFn(apply) 765 rel, _ = db.GetRelationByName(schema.Name) 766 v := bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(2) 767 filter := handle.NewEQFilter(v) 768 id, row, err := rel.GetByFilter(filter) 769 assert.NoError(t, err) 770 err = rel.RangeDelete(id, row, row, handle.DT_Normal) 771 assert.NoError(t, err) 772 assert.NoError(t, txn.Commit()) 773 wg.Wait() 774 775 txn, _ = tae.StartTxn(nil) 776 db, _ = txn.GetDatabase("db") 777 txn.SetApplyCommitFn(apply) 778 rel, _ = db.GetRelationByName(schema.Name) 779 v = bats[0].Vecs[schema.GetSingleSortKeyIdx()].Get(3) 780 filter = handle.NewEQFilter(v) 781 err = rel.UpdateByFilter(filter, 2, int32(9999)) 782 assert.NoError(t, err) 783 assert.NoError(t, txn.Commit()) 784 wg.Wait() 785 } 786 787 // func TestTxn10(t *testing.T) { 788 // opts := config.WithLongScanAndCKPOpts(nil) 789 // tae := newTestEngine(t, opts) 790 // defer tae.Close() 791 // schema := catalog.MockSchemaAll(18, 2) 792 // tae.bindSchema(schema) 793 // bat := catalog.MockBatch(schema, 5) 794 // defer bat.Close() 795 // tae.createRelAndAppend(bat.Window(0, 2), true) 796 797 // txn1, rel1 := tae.getRelation() 798 // blk := getOneBlock(rel1) 799 // view, err := blk.GetColumnDataById(2, nil, nil) 800 // assert.NoError(t, err) 801 // defer view.Close() 802 // t.Log(view.String()) 803 // err = rel1.Append(bat.Window(2, 1)) 804 // assert.NoError(t, err) 805 // blk = getOneBlock(rel1) 806 // view, err = blk.GetColumnDataById(2, nil, nil) 807 // assert.NoError(t, err) 808 // defer view.Close() 809 // t.Log(view.String()) 810 // { 811 // txn, rel := tae.getRelation() 812 // err := rel.Append(bat.Window(2, 1)) 813 // assert.NoError(t, err) 814 // assert.NoError(t, txn.Commit()) 815 // txn, rel = tae.getRelation() 816 // blk := getOneBlock(rel) 817 // view, err := blk.GetColumnDataById(2, nil, nil) 818 // assert.NoError(t, err) 819 // defer view.Close() 820 // t.Log(view.String()) 821 // assert.NoError(t, txn.Commit()) 822 // } 823 824 // // filter := handle.NewEQFilter(int32(99)) 825 // // err = rel1.DeleteByFilter(filter) 826 // // assert.NoError(t, err) 827 // win := bat.CloneWindow(2, 1) 828 // win.Vecs[2].Update(0, int32(99)) 829 // err = rel1.Append(win) 830 // { 831 // // filter := handle.NewEQFilter(int32(99)) 832 // // txn, rel := tae.getRelation() 833 // // err = rel1.UpdateByFilter(filter, 2, int32(88)) 834 // // assert.NoError(t, err) 835 // // assert.NoError(t, txn.Commit()) 836 // } 837 // return 838 // assert.NoError(t, txn1.Commit()) 839 // } 840 841 // func TestTxn11(t *testing.T) { 842 // opts := config.WithLongScanAndCKPOpts(nil) 843 // tae := newTestEngine(t, opts) 844 // defer tae.Close() 845 // schema := catalog.MockSchema(2, 0) 846 // tae.bindSchema(schema) 847 // bat1 := catalog.MockBatch(schema, 0) 848 // defer bat1.Close() 849 // bat1.Vecs[0].AppendMany(int32(1), int32(2)) 850 // bat1.Vecs[1].AppendMany(int32(1), int32(2)) 851 // bat2 := catalog.MockBatch(schema, 0) 852 // defer bat2.Close() 853 // bat2.Vecs[0].Append(int32(3)) 854 // bat2.Vecs[0].Append(int32(4)) 855 // bat2.Vecs[1].Append(int32(1)) 856 // bat2.Vecs[1].Append(int32(2)) 857 858 // tae.createRelAndAppend(bat1, true) 859 860 // buffer := new(bytes.Buffer) 861 862 // txn, rel := tae.getRelation() 863 // blk := getOneBlock(rel) 864 // view, err := blk.GetColumnDataById(0, nil, buffer) 865 // assert.NoError(t, err) 866 // defer view.Close() 867 // view, err = blk.GetColumnDataById(1, nil, buffer) 868 // assert.NoError(t, err) 869 // defer view.Close() 870 871 // err = rel.Append(bat2) 872 // assert.NoError(t, err) 873 // it := rel.MakeBlockIt() 874 // for it.Valid() { 875 // blk = it.GetBlock() 876 // t.Log(blk.Fingerprint().String()) 877 // view, err = blk.GetColumnDataById(0, nil, buffer) 878 // assert.NoError(t, err) 879 // defer view.Close() 880 // t.Log(view.String()) 881 // view, err = blk.GetColumnDataById(1, nil, buffer) 882 // assert.NoError(t, err) 883 // defer view.Close() 884 // t.Log(view.String()) 885 // it.Next() 886 // } 887 // filter := handle.NewEQFilter(int32(1)) 888 // err = rel.DeleteByFilter(filter) 889 // checkAllColRowsByScan(t, rel, 3, true) 890 // assert.NoError(t, err) 891 // { 892 // txn, rel := tae.getRelation() 893 // it := rel.MakeBlockIt() 894 // for it.Valid() { 895 // blk := it.GetBlock() 896 // view, err := blk.GetColumnDataById(0, nil, buffer) 897 // assert.NoError(t, err) 898 // defer view.Close() 899 // t.Log(view.String()) 900 // it.Next() 901 // } 902 903 // assert.NoError(t, txn.Commit()) 904 // } 905 906 // txn.Commit() 907 // }