github.com/matrixorigin/matrixone@v1.2.0/pkg/vm/engine/tae/rpc/rpc_test.go (about)

     1  // Copyright 2021 - 2022 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 rpc
    16  
    17  import (
    18  	"context"
    19  	"strconv"
    20  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	catalog2 "github.com/matrixorigin/matrixone/pkg/catalog"
    25  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    26  	"github.com/matrixorigin/matrixone/pkg/container/types"
    27  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    28  	"github.com/matrixorigin/matrixone/pkg/objectio"
    29  	"github.com/matrixorigin/matrixone/pkg/pb/api"
    30  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    31  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    32  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    33  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/blockio"
    34  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    35  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/common"
    36  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    37  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/db/testutil"
    38  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/iface/handle"
    39  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/mergesort"
    40  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables/jobs"
    41  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils"
    42  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils/config"
    43  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils/mocks"
    44  	"github.com/panjf2000/ants/v2"
    45  	"github.com/stretchr/testify/assert"
    46  )
    47  
    48  func TestHandle_HandleCommitPerformanceForS3Load(t *testing.T) {
    49  	defer testutils.AfterTest(t)()
    50  	opts := config.WithLongScanAndCKPOpts(nil)
    51  	ctx := context.Background()
    52  
    53  	handle := mockTAEHandle(ctx, t, opts)
    54  	defer handle.HandleClose(context.TODO())
    55  	fs := handle.db.Opts.Fs
    56  	IDAlloc := catalog.NewIDAllocator()
    57  
    58  	schema := catalog.MockSchema(2, 1)
    59  	schema.Name = "tbtest"
    60  	schema.BlockMaxRows = 10
    61  	schema.ObjectMaxBlocks = 2
    62  	//100 objs, one obj contains 50 blocks, one block contains 10 rows.
    63  	taeBat := catalog.MockBatch(schema, 100*50*10)
    64  	defer taeBat.Close()
    65  	taeBats := taeBat.Split(100 * 50)
    66  
    67  	//taeBats[0] = taeBats[0].CloneWindow(0, 10)
    68  	//taeBats[1] = taeBats[1].CloneWindow(0, 10)
    69  	//taeBats[2] = taeBats[2].CloneWindow(0, 10)
    70  	//taeBats[3] = taeBats[3].CloneWindow(0, 10)
    71  
    72  	//sort by primary key
    73  	//_, err = mergesort.SortBlockColumns(taeBats[0].Vecs, 1)
    74  	//assert.Nil(t, err)
    75  	//_, err = mergesort.SortBlockColumns(taeBats[1].Vecs, 1)
    76  	//assert.Nil(t, err)
    77  	//_, err = mergesort.SortBlockColumns(taeBats[2].Vecs, 1)
    78  	//assert.Nil(t, err)
    79  
    80  	//moBats := make([]*batch.Batch, 4)
    81  	//moBats[0] = containers.CopyToCNBatch(taeBats[0])
    82  	//moBats[1] = containers.CopyToCNBatch(taeBats[1])
    83  	//moBats[2] = containers.CopyToCNBatch(taeBats[2])
    84  	//moBats[3] = containers.CopyToCNBatch(taeBats[3])
    85  
    86  	var objNames []objectio.ObjectName
    87  	var blkMetas []string
    88  	var stats []objectio.ObjectStats
    89  	offset := 0
    90  	for i := 0; i < 100; i++ {
    91  		name := objectio.BuildObjectNameWithObjectID(objectio.NewObjectid())
    92  		objNames = append(objNames, name)
    93  		writer, err := blockio.NewBlockWriterNew(fs, objNames[i], 0, nil)
    94  		assert.Nil(t, err)
    95  		for i := 0; i < 50; i++ {
    96  			_, err := writer.WriteBatch(containers.ToCNBatch(taeBats[offset+i]))
    97  			assert.Nil(t, err)
    98  			//offset++
    99  		}
   100  		offset += 50
   101  		blocks, _, err := writer.Sync(context.Background())
   102  		assert.Nil(t, err)
   103  		assert.Equal(t, 50, len(blocks))
   104  		for _, blk := range blocks {
   105  			metaLoc := blockio.EncodeLocation(
   106  				writer.GetName(),
   107  				blk.GetExtent(),
   108  				uint32(taeBats[0].Vecs[0].Length()),
   109  				blk.GetID())
   110  			assert.Nil(t, err)
   111  			blkMetas = append(blkMetas, metaLoc.String())
   112  			stats = append(stats, writer.GetObjectStats()[objectio.SchemaData])
   113  		}
   114  	}
   115  
   116  	//create dbtest and tbtest;
   117  	dbName := "dbtest"
   118  	ac := AccessInfo{
   119  		accountId: 0,
   120  		userId:    0,
   121  		roleId:    0,
   122  	}
   123  	//var entries []*api.Entry
   124  	entries := make([]*api.Entry, 0)
   125  	txn := mock1PCTxn(handle.db)
   126  	dbTestID := IDAlloc.NextDB()
   127  	createDbEntries, err := makeCreateDatabaseEntries(
   128  		"",
   129  		ac,
   130  		dbName,
   131  		dbTestID,
   132  		handle.m)
   133  	assert.Nil(t, err)
   134  	entries = append(entries, createDbEntries...)
   135  	//create table from "dbtest"
   136  	defs, err := SchemaToDefs(schema)
   137  	for i := 0; i < len(defs); i++ {
   138  		if attrdef, ok := defs[i].(*engine.AttributeDef); ok {
   139  			attrdef.Attr.Default = &plan.Default{
   140  				NullAbility: true,
   141  				Expr: &plan.Expr{
   142  					Expr: &plan.Expr_Lit{
   143  						Lit: &plan.Literal{
   144  							Isnull: false,
   145  							Value: &plan.Literal_Sval{
   146  								Sval: "expr" + strconv.Itoa(i),
   147  							},
   148  						},
   149  					},
   150  				},
   151  				OriginString: "expr" + strconv.Itoa(i),
   152  			}
   153  		}
   154  	}
   155  
   156  	assert.Nil(t, err)
   157  	tbTestID := IDAlloc.NextTable()
   158  	createTbEntries, err := makeCreateTableEntries(
   159  		"",
   160  		ac,
   161  		schema.Name,
   162  		tbTestID,
   163  		dbTestID,
   164  		dbName,
   165  		schema.Constraint,
   166  		handle.m,
   167  		defs,
   168  	)
   169  	assert.Nil(t, err)
   170  	entries = append(entries, createTbEntries...)
   171  
   172  	//add 100 * 50 blocks from S3 into "tbtest" table
   173  	attrs := []string{catalog2.BlockMeta_MetaLoc, catalog2.ObjectMeta_ObjectStats}
   174  	vecTypes := []types.Type{types.New(types.T_varchar, types.MaxVarcharLen, 0), types.New(types.T_varchar, types.MaxVarcharLen, 0)}
   175  	vecOpts := containers.Options{}
   176  	vecOpts.Capacity = 0
   177  	offset = 0
   178  	for _, obj := range objNames {
   179  		metaLocBat := containers.BuildBatch(attrs, vecTypes, vecOpts)
   180  		for i := 0; i < 50; i++ {
   181  			metaLocBat.Vecs[0].Append([]byte(blkMetas[offset+i]), false)
   182  			metaLocBat.Vecs[1].Append([]byte(stats[offset+i][:]), false)
   183  		}
   184  		offset += 50
   185  		metaLocMoBat := containers.ToCNBatch(metaLocBat)
   186  		addS3BlkEntry, err := makePBEntry(INSERT, dbTestID,
   187  			tbTestID, dbName, schema.Name, obj.String(), metaLocMoBat)
   188  		assert.NoError(t, err)
   189  		entries = append(entries, addS3BlkEntry)
   190  		defer metaLocBat.Close()
   191  	}
   192  	err = handle.HandlePreCommit(
   193  		context.TODO(),
   194  		txn,
   195  		&api.PrecommitWriteCmd{
   196  			//UserId:    ac.userId,
   197  			//AccountId: ac.accountId,
   198  			//RoleId:    ac.roleId,
   199  			EntryList: entries,
   200  		},
   201  		new(api.SyncLogTailResp),
   202  	)
   203  	assert.Nil(t, err)
   204  	//t.FailNow()
   205  	start := time.Now()
   206  	_, err = handle.HandleCommit(context.TODO(), txn)
   207  	assert.Nil(t, err)
   208  	t.Logf("Commit 10w blocks spend: %d", time.Since(start).Microseconds())
   209  }
   210  
   211  func TestHandle_HandlePreCommitWriteS3(t *testing.T) {
   212  	defer testutils.AfterTest(t)()
   213  	opts := config.WithLongScanAndCKPOpts(nil)
   214  	ctx := context.Background()
   215  
   216  	handle := mockTAEHandle(ctx, t, opts)
   217  	defer handle.HandleClose(context.TODO())
   218  	fs := handle.db.Opts.Fs
   219  	defer fs.Close()
   220  	IDAlloc := catalog.NewIDAllocator()
   221  
   222  	schema := catalog.MockSchema(2, 1)
   223  	schema.Name = "tbtest"
   224  	schema.BlockMaxRows = 10
   225  	schema.ObjectMaxBlocks = 2
   226  	taeBat := catalog.MockBatch(schema, 40)
   227  	defer taeBat.Close()
   228  	taeBats := taeBat.Split(4)
   229  	taeBats[0] = taeBats[0].CloneWindow(0, 10)
   230  	taeBats[1] = taeBats[1].CloneWindow(0, 10)
   231  	taeBats[2] = taeBats[2].CloneWindow(0, 10)
   232  	taeBats[3] = taeBats[3].CloneWindow(0, 10)
   233  
   234  	//sort by primary key
   235  	_, err := mergesort.SortBlockColumns(taeBats[0].Vecs, 1, mocks.GetTestVectorPool())
   236  	assert.Nil(t, err)
   237  	_, err = mergesort.SortBlockColumns(taeBats[1].Vecs, 1, mocks.GetTestVectorPool())
   238  	assert.Nil(t, err)
   239  	_, err = mergesort.SortBlockColumns(taeBats[2].Vecs, 1, mocks.GetTestVectorPool())
   240  	assert.Nil(t, err)
   241  
   242  	moBats := make([]*batch.Batch, 4)
   243  	moBats[0] = containers.ToCNBatch(taeBats[0])
   244  	moBats[1] = containers.ToCNBatch(taeBats[1])
   245  	moBats[2] = containers.ToCNBatch(taeBats[2])
   246  	moBats[3] = containers.ToCNBatch(taeBats[3])
   247  
   248  	//write taeBats[0], taeBats[1] two blocks into file service
   249  	objName1 := objectio.BuildObjectNameWithObjectID(objectio.NewObjectid())
   250  	writer, err := blockio.NewBlockWriterNew(fs, objName1, 0, nil)
   251  	assert.Nil(t, err)
   252  	writer.SetPrimaryKey(1)
   253  	for i, bat := range taeBats {
   254  		if i == 2 {
   255  			break
   256  		}
   257  		_, err := writer.WriteBatch(containers.ToCNBatch(bat))
   258  		assert.Nil(t, err)
   259  	}
   260  	blocks, _, err := writer.Sync(context.Background())
   261  	assert.Nil(t, err)
   262  	assert.Equal(t, 2, len(blocks))
   263  	metaLoc1 := blockio.EncodeLocation(
   264  		writer.GetName(),
   265  		blocks[0].GetExtent(),
   266  		uint32(taeBats[0].Vecs[0].Length()),
   267  		blocks[0].GetID(),
   268  	).String()
   269  	assert.Nil(t, err)
   270  	metaLoc2 := blockio.EncodeLocation(
   271  		writer.GetName(),
   272  		blocks[1].GetExtent(),
   273  		uint32(taeBats[1].Vecs[0].Length()),
   274  		blocks[1].GetID(),
   275  	).String()
   276  	assert.Nil(t, err)
   277  	stats1 := writer.GetObjectStats()[objectio.SchemaData]
   278  
   279  	//write taeBats[3] into file service
   280  	objName2 := objectio.BuildObjectNameWithObjectID(objectio.NewObjectid())
   281  	writer, err = blockio.NewBlockWriterNew(fs, objName2, 0, nil)
   282  	assert.Nil(t, err)
   283  	writer.SetPrimaryKey(1)
   284  	_, err = writer.WriteBatch(containers.ToCNBatch(taeBats[3]))
   285  	assert.Nil(t, err)
   286  	blocks, _, err = writer.Sync(context.Background())
   287  	assert.Equal(t, 1, len(blocks))
   288  	assert.Nil(t, err)
   289  	metaLoc3 := blockio.EncodeLocation(
   290  		writer.GetName(),
   291  		blocks[0].GetExtent(),
   292  		uint32(taeBats[3].Vecs[0].Length()),
   293  		blocks[0].GetID(),
   294  	).String()
   295  	stats3 := writer.GetObjectStats()[objectio.SchemaData]
   296  	assert.Nil(t, err)
   297  
   298  	//create db;
   299  	dbName := "dbtest"
   300  	ac := AccessInfo{
   301  		accountId: 0,
   302  		userId:    0,
   303  		roleId:    0,
   304  	}
   305  	var entries []*api.Entry
   306  	txn := mock1PCTxn(handle.db)
   307  	dbTestID := IDAlloc.NextDB()
   308  	createDbEntries, err := makeCreateDatabaseEntries(
   309  		"",
   310  		ac,
   311  		dbName,
   312  		dbTestID,
   313  		handle.m)
   314  	assert.Nil(t, err)
   315  	entries = append(entries, createDbEntries...)
   316  	//create table from "dbtest"
   317  	defs, err := SchemaToDefs(schema)
   318  	for i := 0; i < len(defs); i++ {
   319  		if attrdef, ok := defs[i].(*engine.AttributeDef); ok {
   320  			attrdef.Attr.Default = &plan.Default{
   321  				NullAbility: true,
   322  				Expr: &plan.Expr{
   323  					Expr: &plan.Expr_Lit{
   324  						Lit: &plan.Literal{
   325  							Isnull: false,
   326  							Value: &plan.Literal_Sval{
   327  								Sval: "expr" + strconv.Itoa(i),
   328  							},
   329  						},
   330  					},
   331  				},
   332  				OriginString: "expr" + strconv.Itoa(i),
   333  			}
   334  		}
   335  	}
   336  
   337  	assert.Nil(t, err)
   338  	tbTestID := IDAlloc.NextTable()
   339  	createTbEntries, err := makeCreateTableEntries(
   340  		"",
   341  		ac,
   342  		schema.Name,
   343  		tbTestID,
   344  		dbTestID,
   345  		dbName,
   346  		schema.Constraint,
   347  		handle.m,
   348  		defs,
   349  	)
   350  	assert.Nil(t, err)
   351  	entries = append(entries, createTbEntries...)
   352  	err = handle.HandlePreCommit(
   353  		context.TODO(),
   354  		txn,
   355  		&api.PrecommitWriteCmd{
   356  			//UserId:    ac.userId,
   357  			//AccountId: ac.accountId,
   358  			//RoleId:    ac.roleId,
   359  			EntryList: entries,
   360  		},
   361  		new(api.SyncLogTailResp),
   362  	)
   363  	assert.Nil(t, err)
   364  	//t.FailNow()
   365  	_, err = handle.HandleCommit(context.TODO(), txn)
   366  	assert.Nil(t, err)
   367  	entries = entries[:0]
   368  
   369  	// set blockmaxrow as 10
   370  	p := &catalog.LoopProcessor{}
   371  	p.TableFn = func(te *catalog.TableEntry) error {
   372  		schema := te.GetLastestSchemaLocked()
   373  		if schema.Name == "tbtest" {
   374  			schema.BlockMaxRows = 10
   375  		}
   376  		return nil
   377  	}
   378  	handle.db.Catalog.RecurLoop(p)
   379  	txn = mock1PCTxn(handle.db)
   380  	//append data into "tbtest" table
   381  	insertEntry, err := makePBEntry(INSERT, dbTestID,
   382  		tbTestID, dbName, schema.Name, "", moBats[2])
   383  	assert.NoError(t, err)
   384  	entries = append(entries, insertEntry)
   385  
   386  	//add two non-appendable blocks from S3 into "tbtest" table
   387  	attrs := []string{catalog2.BlockMeta_MetaLoc, catalog2.ObjectMeta_ObjectStats}
   388  	vecTypes := []types.Type{types.New(types.T_varchar, types.MaxVarcharLen, 0), types.New(types.T_varchar, types.MaxVarcharLen, 0)}
   389  	vecOpts := containers.Options{}
   390  	vecOpts.Capacity = 0
   391  	metaLocBat1 := containers.BuildBatch(attrs, vecTypes, vecOpts)
   392  	metaLocBat1.Vecs[0].Append([]byte(metaLoc1), false)
   393  	metaLocBat1.Vecs[0].Append([]byte(metaLoc2), false)
   394  	metaLocBat1.Vecs[1].Append([]byte(stats1[:]), false)
   395  	metaLocBat1.Vecs[1].Append([]byte(stats1[:]), false)
   396  	metaLocMoBat1 := containers.ToCNBatch(metaLocBat1)
   397  	addS3BlkEntry1, err := makePBEntry(INSERT, dbTestID,
   398  		tbTestID, dbName, schema.Name, objName1.String(), metaLocMoBat1)
   399  	assert.NoError(t, err)
   400  	loc1 := vector.MustStrCol(metaLocMoBat1.GetVector(0))[0]
   401  	loc2 := vector.MustStrCol(metaLocMoBat1.GetVector(0))[1]
   402  	assert.Equal(t, metaLoc1, loc1)
   403  	assert.Equal(t, metaLoc2, loc2)
   404  	entries = append(entries, addS3BlkEntry1)
   405  
   406  	//add one non-appendable block from S3 into "tbtest" table
   407  	metaLocBat2 := containers.BuildBatch(attrs, vecTypes, vecOpts)
   408  	metaLocBat2.Vecs[0].Append([]byte(metaLoc3), false)
   409  	metaLocBat2.Vecs[1].Append([]byte(stats3[:]), false)
   410  	metaLocMoBat2 := containers.ToCNBatch(metaLocBat2)
   411  	addS3BlkEntry2, err := makePBEntry(INSERT, dbTestID,
   412  		tbTestID, dbName, schema.Name, objName2.String(), metaLocMoBat2)
   413  	assert.NoError(t, err)
   414  	entries = append(entries, addS3BlkEntry2)
   415  
   416  	err = handle.HandlePreCommit(
   417  		context.TODO(),
   418  		txn,
   419  		&api.PrecommitWriteCmd{
   420  			//UserId:    ac.userId,
   421  			//AccountId: ac.accountId,
   422  			//RoleId:    ac.roleId,
   423  			EntryList: entries,
   424  		},
   425  		new(api.SyncLogTailResp),
   426  	)
   427  	assert.Nil(t, err)
   428  	//t.FailNow()
   429  	_, err = handle.HandleCommit(context.TODO(), txn)
   430  	assert.Nil(t, err)
   431  	t.Log(handle.db.Catalog.SimplePPString(3))
   432  	//check rows of "tbtest" which should has three blocks.
   433  	txnR, err := handle.db.StartTxn(nil)
   434  	assert.NoError(t, err)
   435  	dbH, err := txnR.GetDatabase(dbName)
   436  	assert.NoError(t, err)
   437  	tbH, err := dbH.GetRelationByName(schema.Name)
   438  	assert.NoError(t, err)
   439  	hideDef, err := GetHideKeysOfTable(tbH)
   440  	assert.NoError(t, err)
   441  
   442  	rows := 0
   443  	it := tbH.MakeObjectIt()
   444  	for it.Valid() {
   445  		blk := it.GetObject()
   446  		for j := 0; j < blk.BlkCnt(); j++ {
   447  			cv, err := blk.GetColumnDataByName(context.Background(), uint16(j), schema.ColDefs[1].Name, common.DefaultAllocator)
   448  			assert.NoError(t, err)
   449  			defer cv.Close()
   450  			rows += cv.Length()
   451  		}
   452  		it.Next()
   453  	}
   454  	_ = it.Close()
   455  	assert.Equal(t, taeBat.Length(), rows)
   456  
   457  	var physicals []*containers.BlockView
   458  	it = tbH.MakeObjectIt()
   459  	for it.Valid() {
   460  		blk := it.GetObject()
   461  		for j := 0; j < blk.BlkCnt(); j++ {
   462  			bv, err := blk.GetColumnDataByNames(context.Background(), uint16(j), []string{hideDef[0].Name, schema.GetPrimaryKey().GetName()}, common.DefaultAllocator)
   463  			assert.NoError(t, err)
   464  			physicals = append(physicals, bv)
   465  		}
   466  		it.Next()
   467  	}
   468  	_ = it.Close()
   469  
   470  	//read physical addr column
   471  	assert.Equal(t, len(taeBats), len(physicals))
   472  	err = txnR.Commit(context.Background())
   473  	assert.Nil(t, err)
   474  
   475  	//write deleted row ids into FS
   476  	objName3 := objectio.BuildObjectNameWithObjectID(objectio.NewObjectid())
   477  	writer, err = blockio.NewBlockWriterNew(fs, objName3, 0, nil)
   478  	assert.Nil(t, err)
   479  	for _, view := range physicals {
   480  		bat := batch.New(true, []string{hideDef[0].Name, schema.GetPrimaryKey().GetName()})
   481  		bat.Vecs[0], _ = view.GetColumnData(2).GetDownstreamVector().Window(0, 5)
   482  		bat.Vecs[1], _ = view.GetColumnData(1).GetDownstreamVector().Window(0, 5)
   483  		_, err := writer.WriteTombstoneBatch(bat)
   484  		assert.Nil(t, err)
   485  	}
   486  	blocks, _, err = writer.Sync(context.Background())
   487  	assert.Nil(t, err)
   488  	assert.Equal(t, len(physicals), len(blocks))
   489  	delLoc1 := blockio.EncodeLocation(
   490  		writer.GetName(),
   491  		blocks[0].GetExtent(),
   492  		uint32(physicals[0].GetColumnData(2).Length()),
   493  		blocks[0].GetID(),
   494  	).String()
   495  	assert.Nil(t, err)
   496  	delLoc2 := blockio.EncodeLocation(
   497  		writer.GetName(),
   498  		blocks[1].GetExtent(),
   499  		uint32(physicals[1].GetColumnData(2).Length()),
   500  		blocks[1].GetID(),
   501  	).String()
   502  	assert.Nil(t, err)
   503  	delLoc3 := blockio.EncodeLocation(
   504  		writer.GetName(),
   505  		blocks[2].GetExtent(),
   506  		uint32(physicals[2].GetColumnData(2).Length()),
   507  		blocks[2].GetID(),
   508  	).String()
   509  	assert.Nil(t, err)
   510  	delLoc4 := blockio.EncodeLocation(
   511  		writer.GetName(),
   512  		blocks[3].GetExtent(),
   513  		uint32(physicals[3].GetColumnData(2).Length()),
   514  		blocks[3].GetID(),
   515  	).String()
   516  	assert.Nil(t, err)
   517  
   518  	//prepare delete locations.
   519  	attrs = []string{catalog2.BlockMeta_DeltaLoc}
   520  	vecTypes = []types.Type{types.New(types.T_varchar, types.MaxVarcharLen, 0)}
   521  
   522  	vecOpts = containers.Options{}
   523  	vecOpts.Capacity = 0
   524  	delLocBat := containers.BuildBatch(attrs, vecTypes, vecOpts)
   525  	delLocBat.Vecs[0].Append([]byte(delLoc1), false)
   526  	delLocBat.Vecs[0].Append([]byte(delLoc2), false)
   527  	delLocBat.Vecs[0].Append([]byte(delLoc3), false)
   528  	delLocBat.Vecs[0].Append([]byte(delLoc4), false)
   529  
   530  	delLocMoBat := containers.ToCNBatch(delLocBat)
   531  	var delApiEntries []*api.Entry
   532  	deleteS3BlkEntry, err := makePBEntry(DELETE, dbTestID,
   533  		tbTestID, dbName, schema.Name, objName3.String(), delLocMoBat)
   534  	assert.NoError(t, err)
   535  	delApiEntries = append(delApiEntries, deleteS3BlkEntry)
   536  
   537  	txn = mock1PCTxn(handle.db)
   538  	err = handle.HandlePreCommit(
   539  		context.TODO(),
   540  		txn,
   541  		&api.PrecommitWriteCmd{
   542  			//UserId:    ac.userId,
   543  			//AccountId: ac.accountId,
   544  			//RoleId:    ac.roleId,
   545  			EntryList: delApiEntries,
   546  		},
   547  		new(api.SyncLogTailResp),
   548  	)
   549  	assert.Nil(t, err)
   550  	_, err = handle.HandleCommit(context.TODO(), txn)
   551  	assert.Nil(t, err)
   552  	//Now, the "tbtest" table has 20 rows left.
   553  	txnR, err = handle.db.StartTxn(nil)
   554  	assert.NoError(t, err)
   555  	dbH, err = txnR.GetDatabase(dbName)
   556  	assert.NoError(t, err)
   557  	tbH, err = dbH.GetRelationByName(schema.Name)
   558  	assert.NoError(t, err)
   559  
   560  	rows = 0
   561  	it = tbH.MakeObjectIt()
   562  	for it.Valid() {
   563  		blk := it.GetObject()
   564  		for j := 0; j < blk.BlkCnt(); j++ {
   565  			cv, err := blk.GetColumnDataByName(context.Background(), uint16(j), schema.ColDefs[1].Name, common.DefaultAllocator)
   566  			assert.NoError(t, err)
   567  			defer cv.Close()
   568  			cv.ApplyDeletes()
   569  			rows += cv.Length()
   570  		}
   571  		it.Next()
   572  	}
   573  	assert.Equal(t, len(taeBats)*taeBats[0].Length()-5*len(taeBats), rows)
   574  	err = txnR.Commit(context.Background())
   575  	assert.Nil(t, err)
   576  }
   577  
   578  func TestHandle_HandlePreCommit1PC(t *testing.T) {
   579  	defer testutils.AfterTest(t)()
   580  	ctx := context.Background()
   581  	opts := config.WithLongScanAndCKPOpts(nil)
   582  	handle := mockTAEHandle(ctx, t, opts)
   583  	defer handle.HandleClose(context.TODO())
   584  	IDAlloc := catalog.NewIDAllocator()
   585  	schema := catalog.MockSchema(2, 1)
   586  	schema.Name = "tbtest"
   587  	schema.BlockMaxRows = 10
   588  	schema.ObjectMaxBlocks = 2
   589  	//DDL
   590  	//create db;
   591  	dbName := "dbtest"
   592  	ac := AccessInfo{
   593  		accountId: 0,
   594  		userId:    0,
   595  		roleId:    0,
   596  	}
   597  	createDbEntries, err := makeCreateDatabaseEntries(
   598  		"",
   599  		ac,
   600  		dbName,
   601  		IDAlloc.NextDB(),
   602  		handle.m)
   603  	assert.Nil(t, err)
   604  	createDbTxn := mock1PCTxn(handle.db)
   605  	err = handle.HandlePreCommit(
   606  		context.TODO(),
   607  		createDbTxn,
   608  		&api.PrecommitWriteCmd{
   609  			//UserId:    ac.userId,
   610  			//AccountId: ac.accountId,
   611  			//RoleId:    ac.roleId,
   612  			EntryList: createDbEntries,
   613  		},
   614  		new(api.SyncLogTailResp),
   615  	)
   616  	assert.Nil(t, err)
   617  	_, err = handle.HandleCommit(context.TODO(), createDbTxn)
   618  	assert.Nil(t, err)
   619  
   620  	//start txn ,read "dbtest"'s ID
   621  	txn, err := handle.db.StartTxn(nil)
   622  	assert.Nil(t, err)
   623  	names := txn.DatabaseNames()
   624  	assert.Equal(t, 2, len(names))
   625  	dbH, err := txn.GetDatabase(dbName)
   626  	assert.Nil(t, err)
   627  	dbTestId := dbH.GetID()
   628  	err = txn.Commit(context.Background())
   629  	assert.Nil(t, err)
   630  
   631  	//create table from "dbtest"
   632  	defs, err := SchemaToDefs(schema)
   633  	for i := 0; i < len(defs); i++ {
   634  		if attrdef, ok := defs[i].(*engine.AttributeDef); ok {
   635  			attrdef.Attr.Default = &plan.Default{
   636  				NullAbility: true,
   637  				Expr: &plan.Expr{
   638  					Expr: &plan.Expr_Lit{
   639  						Lit: &plan.Literal{
   640  							Isnull: false,
   641  							Value: &plan.Literal_Sval{
   642  								Sval: "expr" + strconv.Itoa(i),
   643  							},
   644  						},
   645  					},
   646  				},
   647  				OriginString: "expr" + strconv.Itoa(i),
   648  			}
   649  		}
   650  	}
   651  	assert.Nil(t, err)
   652  
   653  	createTbTxn := mock1PCTxn(handle.db)
   654  
   655  	createTbEntries, err := makeCreateTableEntries(
   656  		"",
   657  		ac,
   658  		schema.Name,
   659  		IDAlloc.NextTable(),
   660  		dbTestId,
   661  		dbName,
   662  		schema.Constraint,
   663  		handle.m,
   664  		defs,
   665  	)
   666  	assert.Nil(t, err)
   667  
   668  	createTbEntries1, err := makeCreateTableEntries(
   669  		"",
   670  		ac,
   671  		"tbtest1",
   672  		IDAlloc.NextTable(),
   673  		dbTestId,
   674  		dbName,
   675  		schema.Constraint,
   676  		handle.m,
   677  		defs,
   678  	)
   679  	assert.Nil(t, err)
   680  	createTbEntries = append(createTbEntries, createTbEntries1...)
   681  	err = handle.HandlePreCommit(
   682  		context.TODO(),
   683  		createTbTxn,
   684  		&api.PrecommitWriteCmd{
   685  			//UserId:    ac.userId,
   686  			//AccountId: ac.accountId,
   687  			//RoleId:    ac.roleId,
   688  			EntryList: createTbEntries,
   689  		},
   690  		new(api.SyncLogTailResp))
   691  	assert.Nil(t, err)
   692  	_, err = handle.HandleCommit(context.TODO(), createTbTxn)
   693  	assert.Nil(t, err)
   694  	//start txn ,read table ID
   695  	txn, err = handle.db.StartTxn(nil)
   696  	assert.Nil(t, err)
   697  	dbH, err = txn.GetDatabase(dbName)
   698  	assert.NoError(t, err)
   699  	dbId := dbH.GetID()
   700  	assert.True(t, dbTestId == dbId)
   701  	names, _ = TableNamesOfDB(dbH)
   702  	assert.Equal(t, 2, len(names))
   703  	tbH, err := dbH.GetRelationByName(schema.Name)
   704  	assert.NoError(t, err)
   705  	tbTestId := tbH.ID()
   706  	rDefs, _ := TableDefs(tbH)
   707  	//assert.Equal(t, 3, len(rDefs))
   708  	rAttr := rDefs[1].(*engine.AttributeDef).Attr
   709  	assert.Equal(t, true, rAttr.Default.NullAbility)
   710  	rAttr = rDefs[2].(*engine.AttributeDef).Attr
   711  	assert.Equal(t, "expr2", rAttr.Default.OriginString)
   712  
   713  	err = txn.Commit(context.Background())
   714  	assert.NoError(t, err)
   715  
   716  	//DML: insert batch into table
   717  	insertTxn := mock1PCTxn(handle.db)
   718  	moBat := containers.ToCNBatch(catalog.MockBatch(schema, 100))
   719  	insertEntry, err := makePBEntry(INSERT, dbTestId,
   720  		tbTestId, dbName, schema.Name, "", moBat)
   721  	assert.NoError(t, err)
   722  	err = handle.HandlePreCommit(
   723  		context.TODO(),
   724  		insertTxn,
   725  		&api.PrecommitWriteCmd{
   726  			//UserId:    ac.userId,
   727  			//AccountId: ac.accountId,
   728  			//RoleId:    ac.roleId,
   729  			EntryList: []*api.Entry{insertEntry},
   730  		},
   731  		new(api.SyncLogTailResp),
   732  	)
   733  	assert.NoError(t, err)
   734  	// TODO:: Dml delete
   735  	//bat := batch.NewWithSize(1)
   736  	_, err = handle.HandleCommit(context.TODO(), insertTxn)
   737  	assert.NoError(t, err)
   738  	//TODO::DML:delete by primary key.
   739  	// physcial addr + primary key
   740  	//bat = batch.NewWithSize(2)
   741  
   742  	//start txn ,read table ID
   743  	txn, err = handle.db.StartTxn(nil)
   744  	assert.NoError(t, err)
   745  	dbH, err = txn.GetDatabase(dbName)
   746  	assert.NoError(t, err)
   747  	tbH, err = dbH.GetRelationByName(schema.Name)
   748  	assert.NoError(t, err)
   749  
   750  	it := tbH.MakeObjectIt()
   751  	for it.Valid() {
   752  		blk := it.GetObject()
   753  		for j := 0; j < blk.BlkCnt(); j++ {
   754  			cv, err := blk.GetColumnDataByName(context.Background(), uint16(j), schema.ColDefs[1].Name, common.DefaultAllocator)
   755  			assert.NoError(t, err)
   756  			defer cv.Close()
   757  			assert.Equal(t, 100, cv.Length())
   758  		}
   759  		it.Next()
   760  	}
   761  	_ = it.Close()
   762  
   763  	// read row ids
   764  	hideCol, err := GetHideKeysOfTable(tbH)
   765  	assert.NoError(t, err)
   766  
   767  	it = tbH.MakeObjectIt()
   768  	blk := it.GetObject()
   769  	cv, err := blk.GetColumnDataByName(context.Background(), 0, hideCol[0].Name, common.DefaultAllocator)
   770  	assert.NoError(t, err)
   771  	defer cv.Close()
   772  
   773  	pk, err := blk.GetColumnDataByName(context.Background(), 0, schema.GetPrimaryKey().GetName(), common.DefaultAllocator)
   774  	assert.NoError(t, err)
   775  	defer pk.Close()
   776  
   777  	assert.NoError(t, txn.Commit(context.Background()))
   778  	delBat := batch.New(true, []string{hideCol[0].Name, schema.GetPrimaryKey().GetName()})
   779  	delBat.Vecs[0], _ = cv.GetData().GetDownstreamVector().Window(0, 20)
   780  	delBat.Vecs[1], _ = pk.GetData().GetDownstreamVector().Window(0, 20)
   781  
   782  	//delete 20 rows
   783  	deleteTxn := mock1PCTxn(handle.db)
   784  	deleteEntry, _ := makePBEntry(
   785  		DELETE,
   786  		dbId,
   787  		tbTestId,
   788  		dbName,
   789  		schema.Name,
   790  		"",
   791  		delBat,
   792  	)
   793  	err = handle.HandlePreCommit(
   794  		context.TODO(),
   795  		deleteTxn,
   796  		&api.PrecommitWriteCmd{
   797  			//UserId:    ac.userId,
   798  			//AccountId: ac.accountId,
   799  			//RoleId:    ac.roleId,
   800  			EntryList: append([]*api.Entry{}, deleteEntry),
   801  		},
   802  		new(api.SyncLogTailResp),
   803  	)
   804  	assert.Nil(t, err)
   805  	_, err = handle.HandleCommit(context.TODO(), deleteTxn)
   806  	assert.Nil(t, err)
   807  	//read, there should be 80 rows left.
   808  	txn, err = handle.db.StartTxn(nil)
   809  	assert.NoError(t, err)
   810  	dbH, err = txn.GetDatabase(dbName)
   811  	assert.NoError(t, err)
   812  	tbH, err = dbH.GetRelationByName(schema.Name)
   813  	assert.NoError(t, err)
   814  
   815  	it = tbH.MakeObjectIt()
   816  	for it.Valid() {
   817  		blk := it.GetObject()
   818  		for j := 0; j < blk.BlkCnt(); j++ {
   819  			v, err := blk.GetColumnDataByName(context.Background(), uint16(j), schema.ColDefs[1].Name, common.DefaultAllocator)
   820  			assert.NoError(t, err)
   821  			defer v.Close()
   822  			v.ApplyDeletes()
   823  			assert.Equal(t, 80, v.Length())
   824  		}
   825  		it.Next()
   826  	}
   827  	it.Close()
   828  	assert.NoError(t, txn.Commit(context.Background()))
   829  }
   830  
   831  func TestHandle_HandlePreCommit2PCForCoordinator(t *testing.T) {
   832  	defer testutils.AfterTest(t)()
   833  	ctx := context.Background()
   834  	opts := config.WithLongScanAndCKPOpts(nil)
   835  	handle := mockTAEHandle(ctx, t, opts)
   836  	defer handle.HandleClose(context.TODO())
   837  	IDAlloc := catalog.NewIDAllocator()
   838  	schema := catalog.MockSchemaAll(2, -1)
   839  	schema.Name = "tbtest"
   840  	schema.BlockMaxRows = 10
   841  	schema.ObjectMaxBlocks = 2
   842  	dbName := "dbtest"
   843  	ac := AccessInfo{
   844  		accountId: 0,
   845  		userId:    0,
   846  		roleId:    0,
   847  	}
   848  	//make create db cmd;
   849  	createDbEntries, err := makeCreateDatabaseEntries(
   850  		"",
   851  		ac,
   852  		dbName,
   853  		IDAlloc.NextDB(),
   854  		handle.m)
   855  	assert.Nil(t, err)
   856  	txnCmds := []txnCommand{
   857  		{
   858  			typ: CmdPreCommitWrite,
   859  			cmd: api.PrecommitWriteCmd{
   860  				//UserId:    ac.userId,
   861  				//AccountId: ac.accountId,
   862  				//RoleId:    ac.roleId,
   863  				EntryList: createDbEntries},
   864  		},
   865  		{typ: CmdPrepare},
   866  		{typ: CmdCommitting},
   867  		{typ: CmdCommit},
   868  	}
   869  	txnMeta := mock2PCTxn(handle.db)
   870  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
   871  	assert.Nil(t, err)
   872  
   873  	//start 1pc txn ,read "dbtest"'s ID
   874  	txn, err := handle.db.StartTxn(nil)
   875  	assert.Nil(t, err)
   876  	names := txn.DatabaseNames()
   877  	assert.Equal(t, 2, len(names))
   878  	dbH, err := txn.GetDatabase(dbName)
   879  	assert.Nil(t, err)
   880  	dbTestId := dbH.GetID()
   881  	err = txn.Commit(ctx)
   882  	assert.Nil(t, err)
   883  
   884  	//create table from "dbtest"
   885  	defs, err := SchemaToDefs(schema)
   886  	defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{
   887  		NullAbility: true,
   888  		Expr: &plan.Expr{
   889  			Expr: &plan.Expr_Lit{
   890  				Lit: &plan.Literal{
   891  					Isnull: false,
   892  					Value: &plan.Literal_Sval{
   893  						Sval: "expr1",
   894  					},
   895  				},
   896  			},
   897  		},
   898  		OriginString: "expr1",
   899  	}
   900  	defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{
   901  		NullAbility: false,
   902  		Expr: &plan.Expr{
   903  			Expr: &plan.Expr_Lit{
   904  				Lit: &plan.Literal{
   905  					Isnull: false,
   906  					Value: &plan.Literal_Sval{
   907  						Sval: "expr2",
   908  					},
   909  				},
   910  			},
   911  		},
   912  		OriginString: "expr2",
   913  	}
   914  	assert.Nil(t, err)
   915  	createTbEntries, err := makeCreateTableEntries(
   916  		"",
   917  		ac,
   918  		schema.Name,
   919  		IDAlloc.NextTable(),
   920  		dbTestId,
   921  		dbName,
   922  		schema.Constraint,
   923  		handle.m,
   924  		defs,
   925  	)
   926  	assert.Nil(t, err)
   927  	txnCmds = []txnCommand{
   928  		{
   929  			typ: CmdPreCommitWrite,
   930  			cmd: api.PrecommitWriteCmd{
   931  				//UserId:    ac.userId,
   932  				//AccountId: ac.accountId,
   933  				//RoleId:    ac.roleId,
   934  				EntryList: createTbEntries},
   935  		},
   936  		{typ: CmdPrepare},
   937  		{typ: CmdCommitting},
   938  		{typ: CmdCommit},
   939  	}
   940  	txnMeta = mock2PCTxn(handle.db)
   941  	ctx = context.TODO()
   942  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
   943  	assert.Nil(t, err)
   944  
   945  	//start 1pc txn ,read table ID
   946  	txn, err = handle.db.StartTxn(nil)
   947  	assert.Nil(t, err)
   948  	dbH, err = txn.GetDatabase(dbName)
   949  	assert.NoError(t, err)
   950  	dbId := dbH.GetID()
   951  	assert.True(t, dbTestId == dbId)
   952  	names, _ = TableNamesOfDB(dbH)
   953  	assert.Equal(t, 1, len(names))
   954  	tbH, err := dbH.GetRelationByName(schema.Name)
   955  	assert.NoError(t, err)
   956  	tbTestId := tbH.ID()
   957  	rDefs, _ := TableDefs(tbH)
   958  	assert.Equal(t, 4, len(rDefs))
   959  	rAttr := rDefs[0].(*engine.AttributeDef).Attr
   960  	assert.Equal(t, true, rAttr.Default.NullAbility)
   961  	rAttr = rDefs[1].(*engine.AttributeDef).Attr
   962  	assert.Equal(t, "expr2", rAttr.Default.OriginString)
   963  	err = txn.Commit(ctx)
   964  	assert.NoError(t, err)
   965  
   966  	//DML::insert batch into table
   967  	moBat := containers.ToCNBatch(catalog.MockBatch(schema, 100))
   968  	insertEntry, err := makePBEntry(INSERT, dbTestId,
   969  		tbTestId, dbName, schema.Name, "", moBat)
   970  	assert.NoError(t, err)
   971  	txnCmds = []txnCommand{
   972  		{
   973  			typ: CmdPreCommitWrite,
   974  			cmd: api.PrecommitWriteCmd{
   975  				//UserId:    ac.userId,
   976  				//AccountId: ac.accountId,
   977  				//RoleId:    ac.roleId,
   978  				EntryList: []*api.Entry{insertEntry}},
   979  		},
   980  		{typ: CmdPrepare},
   981  		{typ: CmdCommitting},
   982  		{typ: CmdCommit},
   983  	}
   984  	insertTxn := mock2PCTxn(handle.db)
   985  	ctx = context.TODO()
   986  	err = handle.handleCmds(ctx, insertTxn, txnCmds)
   987  	assert.Nil(t, err)
   988  
   989  	//start 2PC txn ,rollback it after prepared
   990  	rollbackTxn := mock2PCTxn(handle.db)
   991  	//insert 20 rows, then rollback the txn
   992  	//FIXME::??
   993  	//batch.SetLength(moBat, 20)
   994  	moBat = containers.ToCNBatch(catalog.MockBatch(schema, 20))
   995  	insertEntry, err = makePBEntry(INSERT, dbTestId,
   996  		tbTestId, dbName, schema.Name, "", moBat)
   997  	assert.NoError(t, err)
   998  	txnCmds = []txnCommand{
   999  		{
  1000  			typ: CmdPreCommitWrite,
  1001  			cmd: api.PrecommitWriteCmd{
  1002  				//UserId:    ac.userId,
  1003  				//AccountId: ac.accountId,
  1004  				//RoleId:    ac.roleId,
  1005  				EntryList: []*api.Entry{insertEntry}},
  1006  		},
  1007  		{typ: CmdPrepare},
  1008  		{typ: CmdRollback},
  1009  	}
  1010  	ctx = context.TODO()
  1011  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1012  	assert.Nil(t, err)
  1013  
  1014  	//start 1PC txn , read table
  1015  	txn, err = handle.db.StartTxn(nil)
  1016  	assert.NoError(t, err)
  1017  	dbH, err = txn.GetDatabase(dbName)
  1018  	assert.NoError(t, err)
  1019  	tbH, err = dbH.GetRelationByName(schema.Name)
  1020  	assert.NoError(t, err)
  1021  
  1022  	it := tbH.MakeObjectIt()
  1023  	for it.Valid() {
  1024  		blk := it.GetObject()
  1025  		for j := 0; j < blk.BlkCnt(); j++ {
  1026  			v, err := blk.GetColumnDataByName(context.Background(), uint16(j), schema.ColDefs[1].Name, common.DefaultAllocator)
  1027  			assert.NoError(t, err)
  1028  			defer v.Close()
  1029  			assert.Equal(t, 100, v.Length())
  1030  		}
  1031  		it.Next()
  1032  	}
  1033  	_ = it.Close()
  1034  
  1035  	// read row ids
  1036  	hideCol, err := GetHideKeysOfTable(tbH)
  1037  	assert.NoError(t, err)
  1038  	it = tbH.MakeObjectIt()
  1039  	cv, err := it.GetObject().GetColumnDataByName(context.Background(), 0, hideCol[0].Name, common.DefaultAllocator)
  1040  	assert.NoError(t, err)
  1041  	defer cv.Close()
  1042  	pk, err := it.GetObject().GetColumnDataByName(context.Background(), 0, schema.GetPrimaryKey().GetName(), common.DefaultAllocator)
  1043  	assert.NoError(t, err)
  1044  	defer pk.Close()
  1045  
  1046  	_ = it.Close()
  1047  
  1048  	delBat := batch.New(true, []string{hideCol[0].Name, schema.GetPrimaryKey().GetName()})
  1049  	delBat.Vecs[0] = cv.GetData().GetDownstreamVector()
  1050  	delBat.Vecs[1] = pk.GetData().GetDownstreamVector()
  1051  
  1052  	assert.NoError(t, txn.Commit(ctx))
  1053  
  1054  	hideBats := containers.SplitBatch(delBat, 5)
  1055  	//delete 20 rows by 2PC txn
  1056  	//batch.SetLength(hideBats[0], 20)
  1057  	deleteEntry, err := makePBEntry(
  1058  		DELETE,
  1059  		dbId,
  1060  		tbTestId,
  1061  		dbName,
  1062  		schema.Name,
  1063  		"",
  1064  		hideBats[0],
  1065  	)
  1066  	assert.Nil(t, err)
  1067  	txnCmds = []txnCommand{
  1068  		{
  1069  			typ: CmdPreCommitWrite,
  1070  			cmd: api.PrecommitWriteCmd{
  1071  				//UserId:    ac.userId,
  1072  				//AccountId: ac.accountId,
  1073  				//RoleId:    ac.roleId,
  1074  				EntryList: []*api.Entry{deleteEntry}},
  1075  		},
  1076  		{typ: CmdPrepare},
  1077  		{typ: CmdCommitting},
  1078  		{typ: CmdCommit},
  1079  	}
  1080  	deleteTxn := mock2PCTxn(handle.db)
  1081  	ctx = context.TODO()
  1082  	err = handle.handleCmds(ctx, deleteTxn, txnCmds)
  1083  	assert.Nil(t, err)
  1084  
  1085  	//start a 2PC txn ,rollback it after prepared.
  1086  	rollbackTxn = mock2PCTxn(handle.db)
  1087  	deleteEntry, _ = makePBEntry(
  1088  		DELETE,
  1089  		dbId,
  1090  		tbTestId,
  1091  		dbName,
  1092  		schema.Name,
  1093  		"",
  1094  		hideBats[1],
  1095  	)
  1096  	txnCmds = []txnCommand{
  1097  		{
  1098  			typ: CmdPreCommitWrite,
  1099  			cmd: api.PrecommitWriteCmd{
  1100  				//UserId:    ac.userId,
  1101  				//AccountId: ac.accountId,
  1102  				//RoleId:    ac.roleId,
  1103  				EntryList: []*api.Entry{deleteEntry}},
  1104  		},
  1105  		{typ: CmdPrepare},
  1106  		{typ: CmdRollback},
  1107  	}
  1108  	ctx = context.TODO()
  1109  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1110  	assert.Nil(t, err)
  1111  
  1112  	//read, there should be 80 rows left.
  1113  	txn, err = handle.db.StartTxn(nil)
  1114  	assert.NoError(t, err)
  1115  	dbH, err = txn.GetDatabase(dbName)
  1116  	assert.NoError(t, err)
  1117  	tbH, err = dbH.GetRelationByName(schema.Name)
  1118  	assert.NoError(t, err)
  1119  
  1120  	it = tbH.MakeObjectIt()
  1121  	for it.Valid() {
  1122  		obj := it.GetObject()
  1123  		for j := 0; j < obj.BlkCnt(); j++ {
  1124  			v, err := obj.GetColumnDataByName(context.Background(), uint16(0), schema.ColDefs[1].Name, common.DefaultAllocator)
  1125  			assert.NoError(t, err)
  1126  			defer v.Close()
  1127  			v.ApplyDeletes()
  1128  			assert.Equal(t, 80, v.Length())
  1129  		}
  1130  		it.Next()
  1131  	}
  1132  	_ = it.Close()
  1133  	assert.NoError(t, txn.Commit(ctx))
  1134  }
  1135  
  1136  func TestHandle_HandlePreCommit2PCForParticipant(t *testing.T) {
  1137  	defer testutils.AfterTest(t)()
  1138  	ctx := context.Background()
  1139  	opts := config.WithLongScanAndCKPOpts(nil)
  1140  	handle := mockTAEHandle(ctx, t, opts)
  1141  	defer handle.HandleClose(context.TODO())
  1142  	IDAlloc := catalog.NewIDAllocator()
  1143  	schema := catalog.MockSchemaAll(2, -1)
  1144  	schema.Name = "tbtest"
  1145  	schema.BlockMaxRows = 10
  1146  	schema.ObjectMaxBlocks = 2
  1147  	dbName := "dbtest"
  1148  	ac := AccessInfo{
  1149  		accountId: 0,
  1150  		userId:    0,
  1151  		roleId:    0,
  1152  	}
  1153  	//make create db cmd;
  1154  	createDbEntries, err := makeCreateDatabaseEntries(
  1155  		"",
  1156  		ac,
  1157  		dbName,
  1158  		IDAlloc.NextDB(),
  1159  		handle.m)
  1160  	assert.Nil(t, err)
  1161  	txnCmds := []txnCommand{
  1162  		{
  1163  			typ: CmdPreCommitWrite,
  1164  			cmd: api.PrecommitWriteCmd{
  1165  				//UserId:    ac.userId,
  1166  				//AccountId: ac.accountId,
  1167  				//RoleId:    ac.roleId,
  1168  				EntryList: createDbEntries},
  1169  		},
  1170  		{typ: CmdPrepare},
  1171  		{typ: CmdCommit},
  1172  	}
  1173  	txnMeta := mock2PCTxn(handle.db)
  1174  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
  1175  	assert.Nil(t, err)
  1176  
  1177  	//start 1pc txn ,read "dbtest"'s ID
  1178  	txn, err := handle.db.StartTxn(nil)
  1179  	assert.Nil(t, err)
  1180  	names := txn.DatabaseNames()
  1181  	assert.Equal(t, 2, len(names))
  1182  	dbH, err := txn.GetDatabase(dbName)
  1183  	assert.Nil(t, err)
  1184  	dbTestId := dbH.GetID()
  1185  	err = txn.Commit(ctx)
  1186  	assert.Nil(t, err)
  1187  
  1188  	//create table from "dbtest"
  1189  	defs, err := SchemaToDefs(schema)
  1190  	defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{
  1191  		NullAbility: true,
  1192  		Expr: &plan.Expr{
  1193  			Expr: &plan.Expr_Lit{
  1194  				Lit: &plan.Literal{
  1195  					Isnull: false,
  1196  					Value: &plan.Literal_Sval{
  1197  						Sval: "expr1",
  1198  					},
  1199  				},
  1200  			},
  1201  		},
  1202  		OriginString: "expr1",
  1203  	}
  1204  	defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{
  1205  		NullAbility: false,
  1206  		Expr: &plan.Expr{
  1207  			Expr: &plan.Expr_Lit{
  1208  				Lit: &plan.Literal{
  1209  					Isnull: false,
  1210  					Value: &plan.Literal_Sval{
  1211  						Sval: "expr2",
  1212  					},
  1213  				},
  1214  			},
  1215  		},
  1216  		OriginString: "expr2",
  1217  	}
  1218  	assert.Nil(t, err)
  1219  	createTbEntries, err := makeCreateTableEntries(
  1220  		"",
  1221  		ac,
  1222  		schema.Name,
  1223  		IDAlloc.NextTable(),
  1224  		dbTestId,
  1225  		dbName,
  1226  		schema.Constraint,
  1227  		handle.m,
  1228  		defs,
  1229  	)
  1230  	assert.Nil(t, err)
  1231  	txnCmds = []txnCommand{
  1232  		{
  1233  			typ: CmdPreCommitWrite,
  1234  			cmd: api.PrecommitWriteCmd{
  1235  				//UserId:    ac.userId,
  1236  				//AccountId: ac.accountId,
  1237  				//RoleId:    ac.roleId,
  1238  				EntryList: createTbEntries},
  1239  		},
  1240  		{typ: CmdPrepare},
  1241  		{typ: CmdCommit},
  1242  	}
  1243  	txnMeta = mock2PCTxn(handle.db)
  1244  	ctx = context.TODO()
  1245  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
  1246  	assert.Nil(t, err)
  1247  
  1248  	//start 1pc txn ,read table ID
  1249  	txn, err = handle.db.StartTxn(nil)
  1250  	assert.Nil(t, err)
  1251  	dbH, err = txn.GetDatabase(dbName)
  1252  	assert.NoError(t, err)
  1253  	dbId := dbH.GetID()
  1254  	assert.True(t, dbTestId == dbId)
  1255  	names, _ = TableNamesOfDB(dbH)
  1256  	assert.Equal(t, 1, len(names))
  1257  	tbH, err := dbH.GetRelationByName(schema.Name)
  1258  	assert.NoError(t, err)
  1259  	tbTestId := tbH.ID()
  1260  	rDefs, _ := TableDefs(tbH)
  1261  	assert.Equal(t, 4, len(rDefs))
  1262  	rAttr := rDefs[0].(*engine.AttributeDef).Attr
  1263  	assert.Equal(t, true, rAttr.Default.NullAbility)
  1264  	rAttr = rDefs[1].(*engine.AttributeDef).Attr
  1265  	assert.Equal(t, "expr2", rAttr.Default.OriginString)
  1266  	err = txn.Commit(ctx)
  1267  	assert.NoError(t, err)
  1268  
  1269  	//DML::insert batch into table
  1270  	moBat := containers.ToCNBatch(catalog.MockBatch(schema, 100))
  1271  	insertEntry, err := makePBEntry(INSERT, dbTestId,
  1272  		tbTestId, dbName, schema.Name, "", moBat)
  1273  	assert.NoError(t, err)
  1274  	txnCmds = []txnCommand{
  1275  		{
  1276  			typ: CmdPreCommitWrite,
  1277  			cmd: api.PrecommitWriteCmd{
  1278  				//UserId:    ac.userId,
  1279  				//AccountId: ac.accountId,
  1280  				//RoleId:    ac.roleId,
  1281  				EntryList: []*api.Entry{insertEntry}},
  1282  		},
  1283  		{typ: CmdPrepare},
  1284  		{typ: CmdCommit},
  1285  	}
  1286  	insertTxn := mock2PCTxn(handle.db)
  1287  	ctx = context.TODO()
  1288  	err = handle.handleCmds(ctx, insertTxn, txnCmds)
  1289  	assert.Nil(t, err)
  1290  
  1291  	//start 2PC txn ,rollback it after prepared
  1292  	rollbackTxn := mock2PCTxn(handle.db)
  1293  	//insert 20 rows ,then rollback
  1294  	//FIXME::??
  1295  	//batch.SetLength(moBat, 20)
  1296  	moBat = containers.ToCNBatch(catalog.MockBatch(schema, 20))
  1297  	insertEntry, err = makePBEntry(INSERT, dbTestId,
  1298  		tbTestId, dbName, schema.Name, "", moBat)
  1299  	assert.NoError(t, err)
  1300  	txnCmds = []txnCommand{
  1301  		{
  1302  			typ: CmdPreCommitWrite,
  1303  			cmd: api.PrecommitWriteCmd{
  1304  				//UserId:    ac.userId,
  1305  				//AccountId: ac.accountId,
  1306  				//RoleId:    ac.roleId,
  1307  				EntryList: []*api.Entry{insertEntry}},
  1308  		},
  1309  		{typ: CmdPrepare},
  1310  		{typ: CmdRollback},
  1311  	}
  1312  	ctx = context.TODO()
  1313  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1314  	assert.Nil(t, err)
  1315  
  1316  	//start 2PC txn , rollback it when it is ACTIVE.
  1317  	rollbackTxn = mock2PCTxn(handle.db)
  1318  	//insert 10 rows ,then rollback
  1319  	//batch.SetLength(moBat, 10)
  1320  	moBat = containers.ToCNBatch(catalog.MockBatch(schema, 10))
  1321  	insertEntry, err = makePBEntry(INSERT, dbTestId,
  1322  		tbTestId, dbName, schema.Name, "", moBat)
  1323  	assert.NoError(t, err)
  1324  	txnCmds = []txnCommand{
  1325  		{
  1326  			typ: CmdPreCommitWrite,
  1327  			cmd: api.PrecommitWriteCmd{
  1328  				//UserId:    ac.userId,
  1329  				//AccountId: ac.accountId,
  1330  				//RoleId:    ac.roleId,
  1331  				EntryList: []*api.Entry{insertEntry}},
  1332  		},
  1333  		{typ: CmdRollback},
  1334  	}
  1335  	ctx = context.TODO()
  1336  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1337  	assert.Nil(t, err)
  1338  
  1339  	//start 1PC txn , read table
  1340  	txn, err = handle.db.StartTxn(nil)
  1341  	assert.NoError(t, err)
  1342  	dbH, err = txn.GetDatabase(dbName)
  1343  	assert.NoError(t, err)
  1344  	tbH, err = dbH.GetRelationByName(schema.Name)
  1345  	assert.NoError(t, err)
  1346  	it := tbH.MakeObjectIt()
  1347  	for it.Valid() {
  1348  		obj := it.GetObject()
  1349  		for j := 0; j < obj.BlkCnt(); j++ {
  1350  			v, err := it.GetObject().GetColumnDataByName(context.Background(), uint16(0), schema.ColDefs[1].Name, common.DefaultAllocator)
  1351  			assert.NoError(t, err)
  1352  			defer v.Close()
  1353  			assert.Equal(t, 100, v.Length())
  1354  		}
  1355  		it.Next()
  1356  	}
  1357  	_ = it.Close()
  1358  
  1359  	hideCol, err := GetHideKeysOfTable(tbH)
  1360  	assert.NoError(t, err)
  1361  	it = tbH.MakeObjectIt()
  1362  	v, err := it.GetObject().GetColumnDataByName(context.Background(), 0, hideCol[0].Name, common.DefaultAllocator)
  1363  	assert.NoError(t, err)
  1364  	defer v.Close()
  1365  
  1366  	pk, err := it.GetObject().GetColumnDataByName(context.Background(), 0, schema.GetPrimaryKey().GetName(), common.DefaultAllocator)
  1367  	assert.NoError(t, err)
  1368  	defer pk.Close()
  1369  
  1370  	_ = it.Close()
  1371  	delBat := batch.New(true, []string{hideCol[0].Name, schema.GetPrimaryKey().GetName()})
  1372  	delBat.Vecs[0] = v.GetData().GetDownstreamVector()
  1373  	delBat.Vecs[1] = pk.GetData().GetDownstreamVector()
  1374  
  1375  	assert.NoError(t, txn.Commit(ctx))
  1376  
  1377  	hideBats := containers.SplitBatch(delBat, 5)
  1378  	//delete 20 rows by 2PC txn
  1379  	//batch.SetLength(delBat, 20)
  1380  	deleteEntry, err := makePBEntry(
  1381  		DELETE,
  1382  		dbId,
  1383  		tbTestId,
  1384  		dbName,
  1385  		schema.Name,
  1386  		"",
  1387  		hideBats[0],
  1388  	)
  1389  	assert.Nil(t, err)
  1390  	txnCmds = []txnCommand{
  1391  		{
  1392  			typ: CmdPreCommitWrite,
  1393  			cmd: api.PrecommitWriteCmd{
  1394  				//UserId:    ac.userId,
  1395  				//AccountId: ac.accountId,
  1396  				//RoleId:    ac.roleId,
  1397  				EntryList: []*api.Entry{deleteEntry}},
  1398  		},
  1399  		{typ: CmdPrepare},
  1400  		{typ: CmdCommitting},
  1401  		{typ: CmdCommit},
  1402  	}
  1403  	deleteTxn := mock2PCTxn(handle.db)
  1404  	ctx = context.TODO()
  1405  	err = handle.handleCmds(ctx, deleteTxn, txnCmds)
  1406  	assert.Nil(t, err)
  1407  
  1408  	//start a 2PC txn ,rollback it after prepared.
  1409  	// delete 20 rows ,then rollback
  1410  	rollbackTxn = mock2PCTxn(handle.db)
  1411  	deleteEntry, _ = makePBEntry(
  1412  		DELETE,
  1413  		dbId,
  1414  		tbTestId,
  1415  		dbName,
  1416  		schema.Name,
  1417  		"",
  1418  		hideBats[1],
  1419  	)
  1420  	txnCmds = []txnCommand{
  1421  		{
  1422  			typ: CmdPreCommitWrite,
  1423  			cmd: api.PrecommitWriteCmd{
  1424  				//UserId:    ac.userId,
  1425  				//AccountId: ac.accountId,
  1426  				//RoleId:    ac.roleId,
  1427  				EntryList: []*api.Entry{deleteEntry}},
  1428  		},
  1429  		{typ: CmdPrepare},
  1430  		{typ: CmdRollback},
  1431  	}
  1432  	ctx = context.TODO()
  1433  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1434  	assert.Nil(t, err)
  1435  
  1436  	//read, there should be 80 rows left.
  1437  	txn, err = handle.db.StartTxn(nil)
  1438  	assert.NoError(t, err)
  1439  	dbH, err = txn.GetDatabase(dbName)
  1440  	assert.NoError(t, err)
  1441  	tbH, err = dbH.GetRelationByName(schema.Name)
  1442  	assert.NoError(t, err)
  1443  
  1444  	it = tbH.MakeObjectIt()
  1445  	for it.Valid() {
  1446  		obj := it.GetObject()
  1447  		for j := 0; j < obj.BlkCnt(); j++ {
  1448  			v, err := obj.GetColumnDataByName(context.Background(), uint16(j), schema.ColDefs[1].Name, common.DefaultAllocator)
  1449  			assert.NoError(t, err)
  1450  			defer v.Close()
  1451  			v.ApplyDeletes()
  1452  			assert.Equal(t, 80, v.Length())
  1453  		}
  1454  		it.Next()
  1455  	}
  1456  	_ = it.Close()
  1457  
  1458  	assert.NoError(t, txn.Commit(ctx))
  1459  }
  1460  
  1461  func TestHandle_MVCCVisibility(t *testing.T) {
  1462  	t.Skip("debug later")
  1463  	defer testutils.AfterTest(t)()
  1464  	ctx := context.Background()
  1465  	opts := config.WithLongScanAndCKPOpts(nil)
  1466  	handle := mockTAEHandle(ctx, t, opts)
  1467  	defer handle.HandleClose(context.TODO())
  1468  	IDAlloc := catalog.NewIDAllocator()
  1469  	schema := catalog.MockSchemaAll(2, -1)
  1470  	schema.Name = "tbtest"
  1471  	schema.BlockMaxRows = 10
  1472  	schema.ObjectMaxBlocks = 2
  1473  	dbName := "dbtest"
  1474  	ac := AccessInfo{
  1475  		accountId: 0,
  1476  		userId:    0,
  1477  		roleId:    0,
  1478  	}
  1479  	//make create db cmd;
  1480  	createDbEntries, err := makeCreateDatabaseEntries(
  1481  		"",
  1482  		ac,
  1483  		dbName,
  1484  		IDAlloc.NextDB(),
  1485  		handle.m)
  1486  	assert.Nil(t, err)
  1487  	txnCmds := []txnCommand{
  1488  		{
  1489  			typ: CmdPreCommitWrite,
  1490  			cmd: api.PrecommitWriteCmd{
  1491  				//UserId:    ac.userId,
  1492  				//AccountId: ac.accountId,
  1493  				//RoleId:    ac.roleId,
  1494  				EntryList: createDbEntries},
  1495  		},
  1496  	}
  1497  	txnMeta := mock2PCTxn(handle.db)
  1498  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
  1499  	assert.Nil(t, err)
  1500  	var dbTestId uint64
  1501  	var dbNames []string
  1502  	wg := new(sync.WaitGroup)
  1503  	wg.Add(1)
  1504  	//start a db reader.
  1505  	go func() {
  1506  		//start 1pc txn ,read "dbtest"'s ID
  1507  		txn, err := handle.db.StartTxn(nil)
  1508  		assert.Nil(t, err)
  1509  		dbNames = txn.DatabaseNames()
  1510  		err = txn.Commit(ctx)
  1511  		assert.Nil(t, err)
  1512  		wg.Done()
  1513  
  1514  	}()
  1515  	wg.Wait()
  1516  	assert.Equal(t, 1, len(dbNames))
  1517  
  1518  	err = handle.HandlePrepare(ctx, txnMeta)
  1519  	assert.Nil(t, err)
  1520  	//start reader after preparing success.
  1521  	startTime := time.Now()
  1522  	wg.Add(1)
  1523  	go func() {
  1524  		//start 1pc txn ,read "dbtest"'s ID
  1525  		txn, err := handle.db.StartTxn(nil)
  1526  		assert.Nil(t, err)
  1527  		//reader should wait until the writer committed.
  1528  		dbNames = txn.DatabaseNames()
  1529  		assert.Equal(t, 2, len(dbNames))
  1530  		dbH, err := txn.GetDatabase(dbName)
  1531  		assert.Nil(t, err)
  1532  		dbTestId = dbH.GetID()
  1533  		err = txn.Commit(ctx)
  1534  		assert.Nil(t, err)
  1535  		//wg.Done()
  1536  		//To check whether reader had waited.
  1537  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1538  		wg.Done()
  1539  
  1540  	}()
  1541  	//sleep 1 second
  1542  	time.Sleep(1 * time.Second)
  1543  	//CommitTS = PreparedTS + 1
  1544  	err = handle.handleCmds(ctx, txnMeta, []txnCommand{
  1545  		{typ: CmdCommitting}, {typ: CmdCommit},
  1546  	})
  1547  	assert.Nil(t, err)
  1548  	wg.Wait()
  1549  
  1550  	//create table from "dbtest"
  1551  	defs, err := SchemaToDefs(schema)
  1552  	defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{
  1553  		NullAbility: true,
  1554  		Expr: &plan.Expr{
  1555  			Expr: &plan.Expr_Lit{
  1556  				Lit: &plan.Literal{
  1557  					Isnull: false,
  1558  					Value: &plan.Literal_Sval{
  1559  						Sval: "expr1",
  1560  					},
  1561  				},
  1562  			},
  1563  		},
  1564  		OriginString: "expr1",
  1565  	}
  1566  	defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{
  1567  		NullAbility: false,
  1568  		Expr: &plan.Expr{
  1569  			Expr: &plan.Expr_Lit{
  1570  				Lit: &plan.Literal{
  1571  					Isnull: false,
  1572  					Value: &plan.Literal_Sval{
  1573  						Sval: "expr2",
  1574  					},
  1575  				},
  1576  			},
  1577  		},
  1578  		OriginString: "expr2",
  1579  	}
  1580  	assert.Nil(t, err)
  1581  	createTbEntries, err := makeCreateTableEntries(
  1582  		"",
  1583  		ac,
  1584  		schema.Name,
  1585  		IDAlloc.NextTable(),
  1586  		dbTestId,
  1587  		dbName,
  1588  		schema.Constraint,
  1589  		handle.m,
  1590  		defs,
  1591  	)
  1592  	assert.Nil(t, err)
  1593  	txnCmds = []txnCommand{
  1594  		{
  1595  			typ: CmdPreCommitWrite,
  1596  			cmd: api.PrecommitWriteCmd{
  1597  				//UserId:    ac.userId,
  1598  				//AccountId: ac.accountId,
  1599  				//RoleId:    ac.roleId,
  1600  				EntryList: createTbEntries},
  1601  		},
  1602  		{typ: CmdPrepare},
  1603  	}
  1604  	txnMeta = mock2PCTxn(handle.db)
  1605  	ctx = context.TODO()
  1606  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
  1607  	assert.Nil(t, err)
  1608  	var tbTestId uint64
  1609  	startTime = time.Now()
  1610  	wg.Add(1)
  1611  	go func() {
  1612  		//start 1pc txn ,read table ID
  1613  		txn, err := handle.db.StartTxn(nil)
  1614  		assert.Nil(t, err)
  1615  		dbH, err := txn.GetDatabase(dbName)
  1616  		assert.NoError(t, err)
  1617  		dbId := dbH.GetID()
  1618  		assert.True(t, dbTestId == dbId)
  1619  		//txn should wait here.
  1620  		names, _ := TableNamesOfDB(dbH)
  1621  		assert.Equal(t, 1, len(names))
  1622  		tbH, err := dbH.GetRelationByName(schema.Name)
  1623  		assert.NoError(t, err)
  1624  		tbTestId = tbH.ID()
  1625  		rDefs, _ := TableDefs(tbH)
  1626  		assert.Equal(t, 4, len(rDefs))
  1627  		rAttr := rDefs[0].(*engine.AttributeDef).Attr
  1628  		assert.Equal(t, true, rAttr.Default.NullAbility)
  1629  		rAttr = rDefs[1].(*engine.AttributeDef).Attr
  1630  		assert.Equal(t, "expr2", rAttr.Default.OriginString)
  1631  		err = txn.Commit(ctx)
  1632  		assert.NoError(t, err)
  1633  		//wg.Done()
  1634  		//To check whether reader had waited.
  1635  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1636  		wg.Done()
  1637  	}()
  1638  	time.Sleep(1 * time.Second)
  1639  	err = handle.handleCmds(ctx, txnMeta, []txnCommand{
  1640  		{typ: CmdCommitting}, {typ: CmdCommit},
  1641  	})
  1642  	assert.Nil(t, err)
  1643  	wg.Wait()
  1644  
  1645  	//DML::insert batch into table
  1646  	moBat := containers.ToCNBatch(catalog.MockBatch(schema, 100))
  1647  	insertEntry, err := makePBEntry(INSERT, dbTestId,
  1648  		tbTestId, dbName, schema.Name, "", moBat)
  1649  	assert.NoError(t, err)
  1650  	txnCmds = []txnCommand{
  1651  		{
  1652  			typ: CmdPreCommitWrite,
  1653  			cmd: api.PrecommitWriteCmd{
  1654  				//UserId:    ac.userId,
  1655  				//AccountId: ac.accountId,
  1656  				//RoleId:    ac.roleId,
  1657  				EntryList: []*api.Entry{insertEntry}},
  1658  		},
  1659  		{typ: CmdPrepare},
  1660  	}
  1661  	insertTxn := mock2PCTxn(handle.db)
  1662  	ctx = context.TODO()
  1663  	err = handle.handleCmds(ctx, insertTxn, txnCmds)
  1664  	assert.Nil(t, err)
  1665  	startTime = time.Now()
  1666  	wg.Add(1)
  1667  	go func() {
  1668  		//start 1PC txn , read table
  1669  		txn, err := handle.db.StartTxn(nil)
  1670  		assert.NoError(t, err)
  1671  		dbH, err := txn.GetDatabase(dbName)
  1672  		assert.NoError(t, err)
  1673  		tbH, err := dbH.GetRelationByName(schema.Name)
  1674  		assert.NoError(t, err)
  1675  
  1676  		it := tbH.MakeObjectIt()
  1677  		for it.Valid() {
  1678  			obj := it.GetObject()
  1679  			for j := 0; j < obj.BlkCnt(); j++ {
  1680  				v, err := obj.GetColumnDataByName(context.Background(), 0, schema.ColDefs[1].Name, common.DefaultAllocator)
  1681  				assert.NoError(t, err)
  1682  				defer v.Close()
  1683  				assert.Equal(t, 100, v.Length())
  1684  			}
  1685  			it.Next()
  1686  		}
  1687  		_ = it.Close()
  1688  		txn.Commit(ctx)
  1689  		//To check whether reader had waited.
  1690  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1691  		wg.Done()
  1692  	}()
  1693  	time.Sleep(1 * time.Second)
  1694  	//insertTxn 's CommitTS = PreparedTS + 1.
  1695  	err = handle.handleCmds(ctx, insertTxn, []txnCommand{
  1696  		{typ: CmdCommitting}, {typ: CmdCommit},
  1697  	})
  1698  	assert.Nil(t, err)
  1699  	wg.Wait()
  1700  
  1701  	//DML:delete rows
  1702  	//read row ids
  1703  	var delBat *batch.Batch
  1704  	{
  1705  		txn, err := handle.db.StartTxn(nil)
  1706  		assert.NoError(t, err)
  1707  		dbH, err := txn.GetDatabase(dbName)
  1708  		assert.NoError(t, err)
  1709  		tbH, err := dbH.GetRelationByName(schema.Name)
  1710  		assert.NoError(t, err)
  1711  		hideCol, err := GetHideKeysOfTable(tbH)
  1712  		assert.NoError(t, err)
  1713  
  1714  		it := tbH.MakeObjectIt()
  1715  		v, err := it.GetObject().GetColumnDataByName(context.Background(), 0, hideCol[0].Name, common.DefaultAllocator)
  1716  		assert.NoError(t, err)
  1717  		defer v.Close()
  1718  
  1719  		pk, err := it.GetObject().GetColumnDataByName(context.Background(), 0, schema.GetPrimaryKey().GetName(), common.DefaultAllocator)
  1720  		assert.NoError(t, err)
  1721  		defer pk.Close()
  1722  
  1723  		_ = it.Close()
  1724  
  1725  		delBat = batch.New(true, []string{hideCol[0].Name, schema.GetPrimaryKey().GetName()})
  1726  		delBat.Vecs[0] = v.GetData().GetDownstreamVector()
  1727  		delBat.Vecs[1] = pk.GetData().GetDownstreamVector()
  1728  
  1729  		assert.NoError(t, txn.Commit(ctx))
  1730  	}
  1731  
  1732  	hideBats := containers.SplitBatch(delBat, 5)
  1733  	//delete 20 rows by 2PC txn
  1734  	deleteTxn := mock2PCTxn(handle.db)
  1735  	//batch.SetLength(delBat, 20)
  1736  	deleteEntry, err := makePBEntry(
  1737  		DELETE,
  1738  		dbTestId,
  1739  		tbTestId,
  1740  		dbName,
  1741  		schema.Name,
  1742  		"",
  1743  		hideBats[0],
  1744  	)
  1745  	assert.Nil(t, err)
  1746  	txnCmds = []txnCommand{
  1747  		{
  1748  			typ: CmdPreCommitWrite,
  1749  			cmd: api.PrecommitWriteCmd{
  1750  				EntryList: []*api.Entry{deleteEntry}},
  1751  		},
  1752  		{typ: CmdPrepare},
  1753  	}
  1754  	ctx = context.TODO()
  1755  	err = handle.handleCmds(ctx, deleteTxn, txnCmds)
  1756  	assert.Nil(t, err)
  1757  	startTime = time.Now()
  1758  	wg.Add(1)
  1759  	go func() {
  1760  		//read, there should be 80 rows left.
  1761  		txn, err := handle.db.StartTxn(nil)
  1762  		assert.NoError(t, err)
  1763  		dbH, err := txn.GetDatabase(dbName)
  1764  		assert.NoError(t, err)
  1765  		tbH, err := dbH.GetRelationByName(schema.Name)
  1766  		assert.NoError(t, err)
  1767  
  1768  		it := tbH.MakeObjectIt()
  1769  		for it.Valid() {
  1770  			obj := it.GetObject()
  1771  			for j := 0; j < obj.BlkCnt(); j++ {
  1772  				v, err := obj.GetColumnDataByName(context.Background(), uint16(0), schema.ColDefs[1].Name, common.DefaultAllocator)
  1773  				assert.NoError(t, err)
  1774  				defer v.Close()
  1775  				v.ApplyDeletes()
  1776  				assert.Equal(t, 80, v.Length())
  1777  			}
  1778  			it.Next()
  1779  		}
  1780  		_ = it.Close()
  1781  
  1782  		assert.NoError(t, txn.Commit(ctx))
  1783  		//To check whether reader had waited.
  1784  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1785  		wg.Done()
  1786  
  1787  	}()
  1788  	time.Sleep(1 * time.Second)
  1789  	//deleteTxn 's CommitTS = PreparedTS + 1
  1790  	err = handle.handleCmds(ctx, deleteTxn, []txnCommand{
  1791  		{typ: CmdCommitting}, {typ: CmdCommit},
  1792  	})
  1793  	assert.Nil(t, err)
  1794  	wg.Wait()
  1795  }
  1796  
  1797  func TestApplyDeltaloc(t *testing.T) {
  1798  	defer testutils.AfterTest(t)()
  1799  	opts := config.WithLongScanAndCKPOpts(nil)
  1800  	ctx := context.Background()
  1801  
  1802  	h := mockTAEHandle(ctx, t, opts)
  1803  	defer h.HandleClose(context.TODO())
  1804  	defer opts.Fs.Close()
  1805  
  1806  	schema := catalog.MockSchema(2, 1)
  1807  	schema.Name = "tbtest"
  1808  	schema.BlockMaxRows = 5
  1809  	schema.ObjectMaxBlocks = 2
  1810  	//5 objs, one obj contains 2 blocks, one block contains 10 rows.
  1811  	rowCount := 100 * 2 * 5
  1812  	taeBat := catalog.MockBatch(schema, rowCount)
  1813  	defer taeBat.Close()
  1814  	// taeBats := taeBat.Split(rowCount)
  1815  
  1816  	// create relation
  1817  	txn0, err := h.db.StartTxn(nil)
  1818  	assert.NoError(t, err)
  1819  	db, err := txn0.CreateDatabase("db", "create", "typ")
  1820  	assert.NoError(t, err)
  1821  	_, err = db.CreateRelation(schema)
  1822  	assert.NoError(t, err)
  1823  	assert.NoError(t, txn0.Commit(context.Background()))
  1824  
  1825  	// append
  1826  	txn0, err = h.db.StartTxn(nil)
  1827  	assert.NoError(t, err)
  1828  	db, err = txn0.GetDatabase("db")
  1829  	dbID := db.GetID()
  1830  	assert.NoError(t, err)
  1831  	rel, err := db.GetRelationByName(schema.Name)
  1832  	assert.NoError(t, err)
  1833  	tid := rel.GetMeta().(*catalog.TableEntry).GetID()
  1834  	assert.NoError(t, rel.Append(context.Background(), taeBat))
  1835  	assert.NoError(t, txn0.Commit(context.Background()))
  1836  
  1837  	// compact
  1838  	txn0, err = h.db.StartTxn(nil)
  1839  	assert.NoError(t, err)
  1840  	db, err = txn0.GetDatabase("db")
  1841  	assert.NoError(t, err)
  1842  	rel, err = db.GetRelationByName(schema.Name)
  1843  	assert.NoError(t, err)
  1844  	var metas []*catalog.ObjectEntry
  1845  	it := rel.MakeObjectIt()
  1846  	for it.Valid() {
  1847  		blk := it.GetObject()
  1848  		meta := blk.GetMeta().(*catalog.ObjectEntry)
  1849  		metas = append(metas, meta)
  1850  		it.Next()
  1851  	}
  1852  	assert.NoError(t, txn0.Commit(context.Background()))
  1853  
  1854  	txn0, err = h.db.StartTxn(nil)
  1855  	assert.NoError(t, err)
  1856  	task, err := jobs.NewFlushTableTailTask(nil, txn0, metas, h.db.Runtime, txn0.GetStartTS())
  1857  	assert.NoError(t, err)
  1858  	err = task.OnExec(context.Background())
  1859  	assert.NoError(t, err)
  1860  	assert.NoError(t, txn0.Commit(context.Background()))
  1861  
  1862  	txn0, err = h.db.StartTxn(nil)
  1863  	assert.NoError(t, err)
  1864  	db, err = txn0.GetDatabase("db")
  1865  	assert.NoError(t, err)
  1866  	rel, err = db.GetRelationByName(schema.Name)
  1867  	assert.NoError(t, err)
  1868  	inMemoryDeleteTxns := make([]*txn.TxnMeta, 0)
  1869  	blkIDOffsetsMap := make(map[common.ID][]uint32)
  1870  	makeDeleteTxnFn := func(val any) {
  1871  		filter := handle.NewEQFilter(val)
  1872  		id, offset, err := rel.GetByFilter(context.Background(), filter)
  1873  		assert.NoError(t, err)
  1874  		rowIDVec := containers.MakeVector(types.T_Rowid.ToType(), common.DefaultAllocator)
  1875  		rowIDVec.Append(*objectio.NewRowid(&id.BlockID, offset), false)
  1876  		pkVec := containers.MakeVector(schema.GetPrimaryKey().GetType(), common.DefaultAllocator)
  1877  		pkVec.Append(val, false)
  1878  		bat := containers.NewBatch()
  1879  		bat.AddVector(catalog.AttrRowID, rowIDVec)
  1880  		bat.AddVector(schema.GetPrimaryKey().GetName(), pkVec)
  1881  		insertEntry, err := makePBEntry(DELETE, dbID, tid, "db", schema.Name, "", containers.ToCNBatch(bat))
  1882  		assert.NoError(t, err)
  1883  
  1884  		txn := mock1PCTxn(h.db)
  1885  		err = h.HandlePreCommit(context.Background(), txn, &api.PrecommitWriteCmd{EntryList: []*api.Entry{insertEntry}}, new(api.SyncLogTailResp))
  1886  		assert.NoError(t, err)
  1887  		inMemoryDeleteTxns = append(inMemoryDeleteTxns, txn)
  1888  	}
  1889  	assert.NoError(t, txn0.Commit(context.Background()))
  1890  
  1891  	for i := 0; i < rowCount; i++ {
  1892  		val := taeBat.Vecs[schema.GetSingleSortKeyIdx()].Get(i)
  1893  		if i%5 == 0 {
  1894  			// try apply deltaloc
  1895  			filter := handle.NewEQFilter(val)
  1896  			id, offset, err := rel.GetByFilter(context.Background(), filter)
  1897  			assert.NoError(t, err)
  1898  			offsets, ok := blkIDOffsetsMap[*id]
  1899  			if !ok {
  1900  				offsets = make([]uint32, 0)
  1901  			}
  1902  			offsets = append(offsets, offset)
  1903  			blkIDOffsetsMap[*id] = offsets
  1904  		} else {
  1905  			// in memory deletes
  1906  			makeDeleteTxnFn(val)
  1907  		}
  1908  	}
  1909  
  1910  	// make txn for apply deltaloc
  1911  
  1912  	txn0, err = h.db.StartTxn(nil)
  1913  	assert.NoError(t, err)
  1914  	db, err = txn0.GetDatabase("db")
  1915  	assert.NoError(t, err)
  1916  	rel, err = db.GetRelationByName(schema.Name)
  1917  	assert.NoError(t, err)
  1918  	attrs := []string{catalog2.BlockMeta_DeltaLoc}
  1919  	vecTypes := []types.Type{types.New(types.T_varchar, types.MaxVarcharLen, 0)}
  1920  
  1921  	vecOpts := containers.Options{}
  1922  	vecOpts.Capacity = 0
  1923  	delLocBat := containers.BuildBatch(attrs, vecTypes, vecOpts)
  1924  	for id, offsets := range blkIDOffsetsMap {
  1925  		obj, err := rel.GetMeta().(*catalog.TableEntry).GetObjectByID(id.ObjectID())
  1926  		assert.NoError(t, err)
  1927  		_, blkOffset := id.BlockID.Offsets()
  1928  		deltaLoc, err := testutil.MockCNDeleteInS3(h.db.Runtime.Fs, obj.GetObjectData(), blkOffset, schema, txn0, offsets)
  1929  		assert.NoError(t, err)
  1930  		delLocBat.Vecs[0].Append([]byte(deltaLoc.String()), false)
  1931  	}
  1932  	deleteS3Entry, err := makePBEntry(DELETE, dbID, tid, "db", schema.Name, "file", containers.ToCNBatch(delLocBat))
  1933  	assert.NoError(t, err)
  1934  	deleteS3Txn := mock1PCTxn(h.db)
  1935  	err = h.HandlePreCommit(context.Background(), deleteS3Txn, &api.PrecommitWriteCmd{EntryList: []*api.Entry{deleteS3Entry}}, new(api.SyncLogTailResp))
  1936  	assert.NoError(t, err)
  1937  	assert.NoError(t, txn0.Commit(context.Background()))
  1938  
  1939  	var wg sync.WaitGroup
  1940  	pool, _ := ants.NewPool(80)
  1941  	defer pool.Release()
  1942  
  1943  	wg.Add(1)
  1944  	pool.Submit(func() {
  1945  		defer wg.Done()
  1946  		_, err := h.HandleCommit(context.Background(), deleteS3Txn)
  1947  		assert.NoError(t, err)
  1948  	})
  1949  
  1950  	commitMemoryFn := func(txnMeta *txn.TxnMeta) func() {
  1951  		return func() {
  1952  			defer wg.Done()
  1953  			_, err := h.HandleCommit(context.Background(), txnMeta)
  1954  			assert.NoError(t, err)
  1955  		}
  1956  	}
  1957  	for _, deleteTxn := range inMemoryDeleteTxns {
  1958  		wg.Add(1)
  1959  		pool.Submit(commitMemoryFn(deleteTxn))
  1960  	}
  1961  	wg.Wait()
  1962  
  1963  	txn0, err = h.db.StartTxn(nil)
  1964  	assert.NoError(t, err)
  1965  	db, err = txn0.GetDatabase("db")
  1966  	assert.NoError(t, err)
  1967  	rel, err = db.GetRelationByName(schema.Name)
  1968  	assert.NoError(t, err)
  1969  	it = rel.MakeObjectIt()
  1970  	for _, def := range schema.ColDefs {
  1971  		length := 0
  1972  		for it.Valid() {
  1973  			blk := it.GetObject()
  1974  			meta := blk.GetMeta().(*catalog.ObjectEntry)
  1975  			for j := 0; j < blk.BlkCnt(); j++ {
  1976  				view, err := meta.GetObjectData().GetColumnDataById(context.Background(), txn0, schema, uint16(j), def.Idx, common.DefaultAllocator)
  1977  				assert.NoError(t, err)
  1978  				view.ApplyDeletes()
  1979  				length += view.GetData().Length()
  1980  			}
  1981  			it.Next()
  1982  		}
  1983  		assert.Equal(t, 0, length)
  1984  	}
  1985  	assert.NoError(t, txn0.Commit(context.Background()))
  1986  }