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