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  // }