github.com/matrixorigin/matrixone@v0.7.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  	"fmt"
    20  	catalog2 "github.com/matrixorigin/matrixone/pkg/catalog"
    21  	"github.com/matrixorigin/matrixone/pkg/container/types"
    22  	"github.com/matrixorigin/matrixone/pkg/defines"
    23  	"github.com/matrixorigin/matrixone/pkg/fileservice"
    24  	"github.com/matrixorigin/matrixone/pkg/objectio"
    25  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/dataio/blockio"
    26  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/mergesort"
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/tables/jobs"
    28  	"os"
    29  	"path"
    30  	"strconv"
    31  	"sync"
    32  	"testing"
    33  	"time"
    34  
    35  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    36  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    37  	"github.com/matrixorigin/matrixone/pkg/pb/api"
    38  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    39  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    40  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/catalog"
    41  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    42  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/moengine"
    43  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils"
    44  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/testutils/config"
    45  	"github.com/stretchr/testify/assert"
    46  )
    47  
    48  func TestHandle_HandlePreCommitWriteS3(t *testing.T) {
    49  	defer testutils.AfterTest(t)()
    50  	opts := config.WithLongScanAndCKPOpts(nil)
    51  
    52  	//create  file service;
    53  	//dir := testutils.GetDefaultTestPath(ModuleName, t)
    54  	dir := "/tmp/s3"
    55  	dir = path.Join(dir, "/local")
    56  	//if dir exists, remove it.
    57  	os.RemoveAll(dir)
    58  	c := fileservice.Config{
    59  		Name:    defines.LocalFileServiceName,
    60  		Backend: "DISK",
    61  		DataDir: dir,
    62  	}
    63  	//create dir;
    64  	fs, err := fileservice.NewFileService(c)
    65  	assert.Nil(t, err)
    66  	opts.Fs = fs
    67  	handle := mockTAEHandle(t, opts)
    68  	defer handle.HandleClose(context.TODO())
    69  	IDAlloc := catalog.NewIDAllocator()
    70  	txnEngine := handle.GetTxnEngine()
    71  
    72  	schema := catalog.MockSchema(2, 1)
    73  	schema.Name = "tbtest"
    74  	schema.BlockMaxRows = 10
    75  	schema.SegmentMaxBlocks = 2
    76  	taeBat := catalog.MockBatch(schema, 40)
    77  	defer taeBat.Close()
    78  	taeBats := taeBat.Split(4)
    79  	taeBats[0] = taeBats[0].CloneWindow(0, 10)
    80  	taeBats[1] = taeBats[1].CloneWindow(0, 10)
    81  	taeBats[2] = taeBats[2].CloneWindow(0, 10)
    82  	taeBats[3] = taeBats[3].CloneWindow(0, 10)
    83  
    84  	//sort by primary key
    85  	_, err = mergesort.SortBlockColumns(taeBats[0].Vecs, 1)
    86  	assert.Nil(t, err)
    87  	_, err = mergesort.SortBlockColumns(taeBats[1].Vecs, 1)
    88  	assert.Nil(t, err)
    89  	_, err = mergesort.SortBlockColumns(taeBats[2].Vecs, 1)
    90  	assert.Nil(t, err)
    91  
    92  	moBats := make([]*batch.Batch, 4)
    93  	moBats[0] = containers.CopyToMoBatch(taeBats[0])
    94  	moBats[1] = containers.CopyToMoBatch(taeBats[1])
    95  	moBats[2] = containers.CopyToMoBatch(taeBats[2])
    96  	moBats[3] = containers.CopyToMoBatch(taeBats[3])
    97  
    98  	//write taeBats[0], taeBats[1] two blocks into file service
    99  	id := 1
   100  	objName1 := fmt.Sprintf("%d.seg", id)
   101  	writer := blockio.NewWriter(context.Background(),
   102  		objectio.NewObjectFS(fs, "data"), objName1)
   103  	for i, bat := range taeBats {
   104  		if i == 2 {
   105  			break
   106  		}
   107  		block, err := writer.WriteBlock(bat)
   108  		assert.Nil(t, err)
   109  		err = jobs.BuildBlockIndex(writer.GetWriter(), block,
   110  			schema, bat, true)
   111  		assert.Nil(t, err)
   112  	}
   113  	blocks, err := writer.Sync()
   114  	assert.Nil(t, err)
   115  	assert.Equal(t, 2, len(blocks))
   116  	metaLoc1, err := blockio.EncodeMetaLocWithObject(
   117  		blocks[0].GetExtent(),
   118  		uint32(taeBats[0].Vecs[0].Length()),
   119  		blocks,
   120  	)
   121  	assert.Nil(t, err)
   122  	metaLoc2, err := blockio.EncodeMetaLocWithObject(
   123  		blocks[1].GetExtent(),
   124  		uint32(taeBats[1].Vecs[0].Length()),
   125  		blocks,
   126  	)
   127  	assert.Nil(t, err)
   128  
   129  	//write taeBats[3] into file service
   130  	id += 1
   131  	objName2 := fmt.Sprintf("%d.seg", id)
   132  	writer = blockio.NewWriter(context.Background(),
   133  		objectio.NewObjectFS(fs, "data"), objName2)
   134  	block, err := writer.WriteBlock(taeBats[3])
   135  	assert.Nil(t, err)
   136  	err = jobs.BuildBlockIndex(writer.GetWriter(),
   137  		block, schema, taeBats[3], true)
   138  	assert.Nil(t, err)
   139  	blocks, err = writer.Sync()
   140  	assert.Equal(t, 1, len(blocks))
   141  	assert.Nil(t, err)
   142  	metaLoc3, err := blockio.EncodeMetaLocWithObject(
   143  		blocks[0].GetExtent(),
   144  		uint32(taeBats[3].Vecs[0].Length()),
   145  		blocks,
   146  	)
   147  	assert.Nil(t, err)
   148  
   149  	//create db;
   150  	dbName := "dbtest"
   151  	ac := AccessInfo{
   152  		accountId: 0,
   153  		userId:    0,
   154  		roleId:    0,
   155  	}
   156  	var entries []*api.Entry
   157  	txn := mock1PCTxn(txnEngine)
   158  	dbTestID := IDAlloc.NextDB()
   159  	createDbEntries, err := makeCreateDatabaseEntries(
   160  		"",
   161  		ac,
   162  		dbName,
   163  		dbTestID,
   164  		handle.m)
   165  	assert.Nil(t, err)
   166  	entries = append(entries, createDbEntries...)
   167  	//create table from "dbtest"
   168  	defs, err := moengine.SchemaToDefs(schema)
   169  	for i := 0; i < len(defs); i++ {
   170  		if attrdef, ok := defs[i].(*engine.AttributeDef); ok {
   171  			attrdef.Attr.Default = &plan.Default{
   172  				NullAbility: true,
   173  				Expr: &plan.Expr{
   174  					Expr: &plan.Expr_C{
   175  						C: &plan.Const{
   176  							Isnull: false,
   177  							Value: &plan.Const_Sval{
   178  								Sval: "expr" + strconv.Itoa(i),
   179  							},
   180  						},
   181  					},
   182  				},
   183  				OriginString: "expr" + strconv.Itoa(i),
   184  			}
   185  		}
   186  	}
   187  
   188  	assert.Nil(t, err)
   189  	tbTestID := IDAlloc.NextTable()
   190  	createTbEntries, err := makeCreateTableEntries(
   191  		"",
   192  		ac,
   193  		schema.Name,
   194  		tbTestID,
   195  		dbTestID,
   196  		dbName,
   197  		handle.m,
   198  		defs,
   199  	)
   200  	assert.Nil(t, err)
   201  	entries = append(entries, createTbEntries...)
   202  	//append data into "tbtest" table
   203  	insertEntry, err := makePBEntry(INSERT, dbTestID,
   204  		tbTestID, dbName, schema.Name, "", moBats[2])
   205  	assert.NoError(t, err)
   206  	entries = append(entries, insertEntry)
   207  
   208  	//add two non-appendable blocks from S3 into "tbtest" table
   209  	attrs := []string{catalog2.BlockMeta_MetaLoc}
   210  	vecTypes := []types.Type{types.New(types.T_varchar,
   211  		types.MaxVarcharLen, 0, 0)}
   212  	nullable := []bool{false}
   213  	vecOpts := containers.Options{}
   214  	vecOpts.Capacity = 0
   215  	metaLocBat1 := containers.BuildBatch(attrs, vecTypes, nullable, vecOpts)
   216  	metaLocBat1.Vecs[0].Append([]byte(metaLoc1))
   217  	metaLocBat1.Vecs[0].Append([]byte(metaLoc2))
   218  	metaLocMoBat1 := containers.CopyToMoBatch(metaLocBat1)
   219  	addS3BlkEntry1, err := makePBEntry(INSERT, dbTestID,
   220  		tbTestID, dbName, schema.Name, objName1, metaLocMoBat1)
   221  	assert.NoError(t, err)
   222  	loc1 := vector.GetStrVectorValues(metaLocMoBat1.GetVector(0))[0]
   223  	loc2 := vector.GetStrVectorValues(metaLocMoBat1.GetVector(0))[1]
   224  	assert.Equal(t, metaLoc1, loc1)
   225  	assert.Equal(t, metaLoc2, loc2)
   226  	entries = append(entries, addS3BlkEntry1)
   227  
   228  	//add one non-appendable block from S3 into "tbtest" table
   229  	metaLocBat2 := containers.BuildBatch(attrs, vecTypes, nullable, vecOpts)
   230  	metaLocBat2.Vecs[0].Append([]byte(metaLoc3))
   231  	metaLocMoBat2 := containers.CopyToMoBatch(metaLocBat2)
   232  	addS3BlkEntry2, err := makePBEntry(INSERT, dbTestID,
   233  		tbTestID, dbName, schema.Name, objName2, metaLocMoBat2)
   234  	assert.NoError(t, err)
   235  	entries = append(entries, addS3BlkEntry2)
   236  
   237  	err = handle.HandlePreCommit(
   238  		context.TODO(),
   239  		txn,
   240  		api.PrecommitWriteCmd{
   241  			UserId:    ac.userId,
   242  			AccountId: ac.accountId,
   243  			RoleId:    ac.roleId,
   244  			EntryList: entries,
   245  		},
   246  		new(api.SyncLogTailResp),
   247  	)
   248  	assert.Nil(t, err)
   249  	//t.FailNow()
   250  	err = handle.HandleCommit(context.TODO(), txn)
   251  	assert.Nil(t, err)
   252  	//check rows of "tbtest" which should has three blocks.
   253  	txnR, err := txnEngine.StartTxn(nil)
   254  	assert.NoError(t, err)
   255  	dbHandle, err := txnEngine.GetDatabase(context.TODO(), dbName, txnR)
   256  	assert.NoError(t, err)
   257  	tbHandle, err := dbHandle.GetRelation(context.TODO(), schema.Name)
   258  	assert.NoError(t, err)
   259  	hideDef, err := tbHandle.GetHideKeys(context.TODO())
   260  	assert.NoError(t, err)
   261  	blkReaders, _ := tbHandle.NewReader(context.TODO(), 1, nil, nil)
   262  	rows := 0
   263  	var hideBats []*batch.Batch
   264  	for i := 0; i < len(taeBats); i++ {
   265  		//read primary key column
   266  		bat, err := blkReaders[0].Read(
   267  			context.TODO(),
   268  			[]string{schema.ColDefs[1].Name},
   269  			nil,
   270  			handle.m)
   271  		assert.Nil(t, err)
   272  		if bat != nil {
   273  			rows += vector.Length(bat.Vecs[0])
   274  		}
   275  	}
   276  	assert.Equal(t, taeBat.Length(), rows)
   277  
   278  	//read physical addr column
   279  	blkReaders, _ = tbHandle.NewReader(context.TODO(), 1, nil, nil)
   280  	for i := 0; i < len(taeBats); i++ {
   281  		hideBat, err := blkReaders[0].Read(
   282  			context.TODO(),
   283  			[]string{hideDef[0].Name},
   284  			nil,
   285  			handle.m,
   286  		)
   287  		assert.Nil(t, err)
   288  		if hideBat != nil {
   289  			batch.SetLength(hideBat, 5)
   290  			hideBats = append(hideBats, hideBat)
   291  		}
   292  	}
   293  	assert.Equal(t, len(taeBats), len(hideBats))
   294  	err = txnR.Commit()
   295  	assert.Nil(t, err)
   296  
   297  	//write deleted row ids into FS
   298  	id += 1
   299  	objName3 := fmt.Sprintf("%d.del", id)
   300  	writer = blockio.NewWriter(context.Background(),
   301  		objectio.NewObjectFS(fs, "data"), objName3)
   302  	for _, bat := range hideBats {
   303  		taeBat := toTAEBatchWithSharedMemory(schema, bat)
   304  		//defer taeBat.Close()
   305  		_, err := writer.WriteBlock(taeBat)
   306  		assert.Nil(t, err)
   307  	}
   308  	blocks, err = writer.Sync()
   309  	assert.Nil(t, err)
   310  	assert.Equal(t, len(hideBats), len(blocks))
   311  	delLoc1, err := blockio.EncodeMetaLocWithObject(
   312  		blocks[0].GetExtent(),
   313  		uint32(hideBats[0].Vecs[0].Length()),
   314  		blocks,
   315  	)
   316  	assert.Nil(t, err)
   317  	delLoc2, err := blockio.EncodeMetaLocWithObject(
   318  		blocks[1].GetExtent(),
   319  		uint32(hideBats[1].Vecs[0].Length()),
   320  		blocks,
   321  	)
   322  	assert.Nil(t, err)
   323  	delLoc3, err := blockio.EncodeMetaLocWithObject(
   324  		blocks[2].GetExtent(),
   325  		uint32(hideBats[2].Vecs[0].Length()),
   326  		blocks,
   327  	)
   328  	assert.Nil(t, err)
   329  	delLoc4, err := blockio.EncodeMetaLocWithObject(
   330  		blocks[3].GetExtent(),
   331  		uint32(hideBats[3].Vecs[0].Length()),
   332  		blocks,
   333  	)
   334  	assert.Nil(t, err)
   335  
   336  	//prepare delete locations.
   337  	attrs = []string{catalog2.BlockMeta_DeltaLoc}
   338  	vecTypes = []types.Type{types.New(types.T_varchar,
   339  		types.MaxVarcharLen, 0, 0)}
   340  	nullable = []bool{false}
   341  	vecOpts = containers.Options{}
   342  	vecOpts.Capacity = 0
   343  	delLocBat := containers.BuildBatch(attrs, vecTypes, nullable, vecOpts)
   344  	delLocBat.Vecs[0].Append([]byte(delLoc1))
   345  	delLocBat.Vecs[0].Append([]byte(delLoc2))
   346  	delLocBat.Vecs[0].Append([]byte(delLoc3))
   347  	delLocBat.Vecs[0].Append([]byte(delLoc4))
   348  
   349  	delLocMoBat := containers.CopyToMoBatch(delLocBat)
   350  	var delApiEntries []*api.Entry
   351  	deleteS3BlkEntry, err := makePBEntry(DELETE, dbTestID,
   352  		tbTestID, dbName, schema.Name, objName3, delLocMoBat)
   353  	assert.NoError(t, err)
   354  	delApiEntries = append(delApiEntries, deleteS3BlkEntry)
   355  
   356  	txn = mock1PCTxn(txnEngine)
   357  	err = handle.HandlePreCommit(
   358  		context.TODO(),
   359  		txn,
   360  		api.PrecommitWriteCmd{
   361  			UserId:    ac.userId,
   362  			AccountId: ac.accountId,
   363  			RoleId:    ac.roleId,
   364  			EntryList: delApiEntries,
   365  		},
   366  		new(api.SyncLogTailResp),
   367  	)
   368  	assert.Nil(t, err)
   369  	err = handle.HandleCommit(context.TODO(), txn)
   370  	assert.Nil(t, err)
   371  	//Now, the "tbtest" table has 20 rows left.
   372  	txnR, err = txnEngine.StartTxn(nil)
   373  	assert.NoError(t, err)
   374  	dbHandle, err = txnEngine.GetDatabase(context.TODO(), dbName, txnR)
   375  	assert.NoError(t, err)
   376  	tbHandle, err = dbHandle.GetRelation(context.TODO(), schema.Name)
   377  	assert.NoError(t, err)
   378  	blkReaders, _ = tbHandle.NewReader(context.TODO(), 1, nil, nil)
   379  	rows = 0
   380  	for i := 0; i < len(taeBats); i++ {
   381  		//read primary key column
   382  		bat, err := blkReaders[0].Read(
   383  			context.TODO(),
   384  			[]string{schema.ColDefs[1].Name},
   385  			nil,
   386  			handle.m)
   387  		assert.Nil(t, err)
   388  		if bat != nil {
   389  			rows += vector.Length(bat.Vecs[0])
   390  		}
   391  	}
   392  	assert.Equal(t, len(taeBats)*taeBats[0].Length()-5*len(taeBats), rows)
   393  	err = txnR.Commit()
   394  	assert.Nil(t, err)
   395  }
   396  
   397  func TestHandle_HandlePreCommit1PC(t *testing.T) {
   398  	defer testutils.AfterTest(t)()
   399  	opts := config.WithLongScanAndCKPOpts(nil)
   400  	handle := mockTAEHandle(t, opts)
   401  	defer handle.HandleClose(context.TODO())
   402  	IDAlloc := catalog.NewIDAllocator()
   403  	txnEngine := handle.GetTxnEngine()
   404  	schema := catalog.MockSchema(2, 1)
   405  	schema.Name = "tbtest"
   406  	schema.BlockMaxRows = 10
   407  	schema.SegmentMaxBlocks = 2
   408  	//DDL
   409  	//create db;
   410  	dbName := "dbtest"
   411  	ac := AccessInfo{
   412  		accountId: 0,
   413  		userId:    0,
   414  		roleId:    0,
   415  	}
   416  	createDbEntries, err := makeCreateDatabaseEntries(
   417  		"",
   418  		ac,
   419  		dbName,
   420  		IDAlloc.NextDB(),
   421  		handle.m)
   422  	assert.Nil(t, err)
   423  	createDbTxn := mock1PCTxn(txnEngine)
   424  	err = handle.HandlePreCommit(
   425  		context.TODO(),
   426  		createDbTxn,
   427  		api.PrecommitWriteCmd{
   428  			UserId:    ac.userId,
   429  			AccountId: ac.accountId,
   430  			RoleId:    ac.roleId,
   431  			EntryList: createDbEntries,
   432  		},
   433  		new(api.SyncLogTailResp),
   434  	)
   435  	assert.Nil(t, err)
   436  	err = handle.HandleCommit(context.TODO(), createDbTxn)
   437  	assert.Nil(t, err)
   438  
   439  	//start txn ,read "dbtest"'s ID
   440  	ctx := context.TODO()
   441  	txn, err := txnEngine.StartTxn(nil)
   442  	assert.Nil(t, err)
   443  	names, _ := txnEngine.DatabaseNames(ctx, txn)
   444  	assert.Equal(t, 2, len(names))
   445  	dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
   446  	assert.Nil(t, err)
   447  	dbTestId := dbHandle.GetDatabaseID(ctx)
   448  	err = txn.Commit()
   449  	assert.Nil(t, err)
   450  
   451  	//create table from "dbtest"
   452  	defs, err := moengine.SchemaToDefs(schema)
   453  	for i := 0; i < len(defs); i++ {
   454  		if attrdef, ok := defs[i].(*engine.AttributeDef); ok {
   455  			attrdef.Attr.Default = &plan.Default{
   456  				NullAbility: true,
   457  				Expr: &plan.Expr{
   458  					Expr: &plan.Expr_C{
   459  						C: &plan.Const{
   460  							Isnull: false,
   461  							Value: &plan.Const_Sval{
   462  								Sval: "expr" + strconv.Itoa(i),
   463  							},
   464  						},
   465  					},
   466  				},
   467  				OriginString: "expr" + strconv.Itoa(i),
   468  			}
   469  		}
   470  	}
   471  	assert.Nil(t, err)
   472  
   473  	createTbTxn := mock1PCTxn(txnEngine)
   474  
   475  	createTbEntries, err := makeCreateTableEntries(
   476  		"",
   477  		ac,
   478  		schema.Name,
   479  		IDAlloc.NextTable(),
   480  		dbTestId,
   481  		dbName,
   482  		handle.m,
   483  		defs,
   484  	)
   485  	assert.Nil(t, err)
   486  
   487  	createTbEntries1, err := makeCreateTableEntries(
   488  		"",
   489  		ac,
   490  		"tbtest1",
   491  		IDAlloc.NextTable(),
   492  		dbTestId,
   493  		dbName,
   494  		handle.m,
   495  		defs,
   496  	)
   497  	assert.Nil(t, err)
   498  	createTbEntries = append(createTbEntries, createTbEntries1...)
   499  	err = handle.HandlePreCommit(
   500  		context.TODO(),
   501  		createTbTxn,
   502  		api.PrecommitWriteCmd{
   503  			UserId:    ac.userId,
   504  			AccountId: ac.accountId,
   505  			RoleId:    ac.roleId,
   506  			EntryList: createTbEntries,
   507  		},
   508  		new(api.SyncLogTailResp))
   509  	assert.Nil(t, err)
   510  	err = handle.HandleCommit(context.TODO(), createTbTxn)
   511  	assert.Nil(t, err)
   512  	//start txn ,read table ID
   513  	txn, err = txnEngine.StartTxn(nil)
   514  	assert.Nil(t, err)
   515  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
   516  	assert.NoError(t, err)
   517  	dbId := dbHandle.GetDatabaseID(ctx)
   518  	assert.True(t, dbTestId == dbId)
   519  	names, _ = dbHandle.RelationNames(ctx)
   520  	assert.Equal(t, 2, len(names))
   521  	tbHandle, err := dbHandle.GetRelation(ctx, schema.Name)
   522  	assert.NoError(t, err)
   523  	tbTestId := tbHandle.GetRelationID(ctx)
   524  	rDefs, _ := tbHandle.TableDefs(ctx)
   525  	//assert.Equal(t, 3, len(rDefs))
   526  	rAttr := rDefs[0].(*engine.AttributeDef).Attr
   527  	assert.Equal(t, true, rAttr.Default.NullAbility)
   528  	rAttr = rDefs[1].(*engine.AttributeDef).Attr
   529  	assert.Equal(t, "expr2", rAttr.Default.OriginString)
   530  
   531  	err = txn.Commit()
   532  	assert.NoError(t, err)
   533  
   534  	//DML: insert batch into table
   535  	insertTxn := mock1PCTxn(txnEngine)
   536  	moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100))
   537  	insertEntry, err := makePBEntry(INSERT, dbTestId,
   538  		tbTestId, dbName, schema.Name, "", moBat)
   539  	assert.NoError(t, err)
   540  	err = handle.HandlePreCommit(
   541  		context.TODO(),
   542  		insertTxn,
   543  		api.PrecommitWriteCmd{
   544  			UserId:    ac.userId,
   545  			AccountId: ac.accountId,
   546  			RoleId:    ac.roleId,
   547  			EntryList: []*api.Entry{insertEntry},
   548  		},
   549  		new(api.SyncLogTailResp),
   550  	)
   551  	assert.NoError(t, err)
   552  	// TODO:: Dml delete
   553  	//bat := batch.NewWithSize(1)
   554  	err = handle.HandleCommit(context.TODO(), insertTxn)
   555  	assert.NoError(t, err)
   556  	//TODO::DML:delete by primary key.
   557  	// physcial addr + primary key
   558  	//bat = batch.NewWithSize(2)
   559  
   560  	//start txn ,read table ID
   561  	txn, err = txnEngine.StartTxn(nil)
   562  	assert.NoError(t, err)
   563  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
   564  	assert.NoError(t, err)
   565  	tbHandle, err = dbHandle.GetRelation(ctx, schema.Name)
   566  	assert.NoError(t, err)
   567  	tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil)
   568  	for _, reader := range tbReaders {
   569  		bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
   570  		assert.Nil(t, err)
   571  		if bat != nil {
   572  			len := vector.Length(bat.Vecs[0])
   573  			assert.Equal(t, 100, len)
   574  		}
   575  	}
   576  	// read row ids
   577  	hideCol, err := tbHandle.GetHideKeys(ctx)
   578  	assert.NoError(t, err)
   579  	reader, _ := tbHandle.NewReader(ctx, 1, nil, nil)
   580  	hideBat, err := reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m)
   581  	assert.Nil(t, err)
   582  	err = txn.Commit()
   583  	assert.Nil(t, err)
   584  
   585  	//delete 20 rows
   586  	deleteTxn := mock1PCTxn(handle.GetTxnEngine())
   587  	batch.SetLength(hideBat, 20)
   588  	deleteEntry, _ := makePBEntry(
   589  		DELETE,
   590  		dbId,
   591  		tbTestId,
   592  		dbName,
   593  		schema.Name,
   594  		"",
   595  		hideBat,
   596  	)
   597  	err = handle.HandlePreCommit(
   598  		context.TODO(),
   599  		deleteTxn,
   600  		api.PrecommitWriteCmd{
   601  			UserId:    ac.userId,
   602  			AccountId: ac.accountId,
   603  			RoleId:    ac.roleId,
   604  			EntryList: append([]*api.Entry{}, deleteEntry),
   605  		},
   606  		new(api.SyncLogTailResp),
   607  	)
   608  	assert.Nil(t, err)
   609  	err = handle.HandleCommit(context.TODO(), deleteTxn)
   610  	assert.Nil(t, err)
   611  	//read, there should be 80 rows left.
   612  	txn, err = txnEngine.StartTxn(nil)
   613  	assert.NoError(t, err)
   614  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
   615  	assert.NoError(t, err)
   616  	tbHandle, err = dbHandle.GetRelation(ctx, schema.Name)
   617  	assert.NoError(t, err)
   618  	tbReaders, _ = tbHandle.NewReader(ctx, 2, nil, nil)
   619  	for _, reader := range tbReaders {
   620  		bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
   621  		assert.Nil(t, err)
   622  		if bat != nil {
   623  			len := vector.Length(bat.Vecs[0])
   624  			assert.Equal(t, 80, len)
   625  		}
   626  	}
   627  	err = txn.Commit()
   628  	assert.Nil(t, err)
   629  }
   630  
   631  func TestHandle_HandlePreCommit2PCForCoordinator(t *testing.T) {
   632  	defer testutils.AfterTest(t)()
   633  	opts := config.WithLongScanAndCKPOpts(nil)
   634  	handle := mockTAEHandle(t, opts)
   635  	defer handle.HandleClose(context.TODO())
   636  	IDAlloc := catalog.NewIDAllocator()
   637  	txnEngine := handle.GetTxnEngine()
   638  	schema := catalog.MockSchema(2, -1)
   639  	schema.Name = "tbtest"
   640  	schema.BlockMaxRows = 10
   641  	schema.SegmentMaxBlocks = 2
   642  	dbName := "dbtest"
   643  	ac := AccessInfo{
   644  		accountId: 0,
   645  		userId:    0,
   646  		roleId:    0,
   647  	}
   648  	//make create db cmd;
   649  	createDbEntries, err := makeCreateDatabaseEntries(
   650  		"",
   651  		ac,
   652  		dbName,
   653  		IDAlloc.NextDB(),
   654  		handle.m)
   655  	assert.Nil(t, err)
   656  	txnCmds := []txnCommand{
   657  		{
   658  			typ: CmdPreCommitWrite,
   659  			cmd: api.PrecommitWriteCmd{
   660  				UserId:    ac.userId,
   661  				AccountId: ac.accountId,
   662  				RoleId:    ac.roleId,
   663  				EntryList: createDbEntries},
   664  		},
   665  		{typ: CmdPrepare},
   666  		{typ: CmdCommitting},
   667  		{typ: CmdCommit},
   668  	}
   669  	txnMeta := mock2PCTxn(txnEngine)
   670  	ctx := context.TODO()
   671  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
   672  	assert.Nil(t, err)
   673  
   674  	//start 1pc txn ,read "dbtest"'s ID
   675  	ctx = context.TODO()
   676  	txn, err := txnEngine.StartTxn(nil)
   677  	assert.Nil(t, err)
   678  	names, _ := txnEngine.DatabaseNames(ctx, txn)
   679  	assert.Equal(t, 2, len(names))
   680  	dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
   681  	assert.Nil(t, err)
   682  	dbTestId := dbHandle.GetDatabaseID(ctx)
   683  	err = txn.Commit()
   684  	assert.Nil(t, err)
   685  
   686  	//create table from "dbtest"
   687  	defs, err := moengine.SchemaToDefs(schema)
   688  	defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{
   689  		NullAbility: true,
   690  		Expr: &plan.Expr{
   691  			Expr: &plan.Expr_C{
   692  				C: &plan.Const{
   693  					Isnull: false,
   694  					Value: &plan.Const_Sval{
   695  						Sval: "expr1",
   696  					},
   697  				},
   698  			},
   699  		},
   700  		OriginString: "expr1",
   701  	}
   702  	defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{
   703  		NullAbility: false,
   704  		Expr: &plan.Expr{
   705  			Expr: &plan.Expr_C{
   706  				C: &plan.Const{
   707  					Isnull: false,
   708  					Value: &plan.Const_Sval{
   709  						Sval: "expr2",
   710  					},
   711  				},
   712  			},
   713  		},
   714  		OriginString: "expr2",
   715  	}
   716  	assert.Nil(t, err)
   717  	createTbEntries, err := makeCreateTableEntries(
   718  		"",
   719  		ac,
   720  		schema.Name,
   721  		IDAlloc.NextTable(),
   722  		dbTestId,
   723  		dbName,
   724  		handle.m,
   725  		defs,
   726  	)
   727  	assert.Nil(t, err)
   728  	txnCmds = []txnCommand{
   729  		{
   730  			typ: CmdPreCommitWrite,
   731  			cmd: api.PrecommitWriteCmd{
   732  				UserId:    ac.userId,
   733  				AccountId: ac.accountId,
   734  				RoleId:    ac.roleId,
   735  				EntryList: createTbEntries},
   736  		},
   737  		{typ: CmdPrepare},
   738  		{typ: CmdCommitting},
   739  		{typ: CmdCommit},
   740  	}
   741  	txnMeta = mock2PCTxn(txnEngine)
   742  	ctx = context.TODO()
   743  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
   744  	assert.Nil(t, err)
   745  
   746  	//start 1pc txn ,read table ID
   747  	txn, err = txnEngine.StartTxn(nil)
   748  	assert.Nil(t, err)
   749  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
   750  	assert.NoError(t, err)
   751  	dbId := dbHandle.GetDatabaseID(ctx)
   752  	assert.True(t, dbTestId == dbId)
   753  	names, _ = dbHandle.RelationNames(ctx)
   754  	assert.Equal(t, 1, len(names))
   755  	tbHandle, err := dbHandle.GetRelation(ctx, schema.Name)
   756  	assert.NoError(t, err)
   757  	tbTestId := tbHandle.GetRelationID(ctx)
   758  	rDefs, _ := tbHandle.TableDefs(ctx)
   759  	assert.Equal(t, 3, len(rDefs))
   760  	rAttr := rDefs[0].(*engine.AttributeDef).Attr
   761  	assert.Equal(t, true, rAttr.Default.NullAbility)
   762  	rAttr = rDefs[1].(*engine.AttributeDef).Attr
   763  	assert.Equal(t, "expr2", rAttr.Default.OriginString)
   764  	err = txn.Commit()
   765  	assert.NoError(t, err)
   766  
   767  	//DML::insert batch into table
   768  	moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100))
   769  	insertEntry, err := makePBEntry(INSERT, dbTestId,
   770  		tbTestId, dbName, schema.Name, "", moBat)
   771  	assert.NoError(t, err)
   772  	txnCmds = []txnCommand{
   773  		{
   774  			typ: CmdPreCommitWrite,
   775  			cmd: api.PrecommitWriteCmd{
   776  				UserId:    ac.userId,
   777  				AccountId: ac.accountId,
   778  				RoleId:    ac.roleId,
   779  				EntryList: []*api.Entry{insertEntry}},
   780  		},
   781  		{typ: CmdPrepare},
   782  		{typ: CmdCommitting},
   783  		{typ: CmdCommit},
   784  	}
   785  	insertTxn := mock2PCTxn(txnEngine)
   786  	ctx = context.TODO()
   787  	err = handle.handleCmds(ctx, insertTxn, txnCmds)
   788  	assert.Nil(t, err)
   789  
   790  	//start 2PC txn ,rollback it after prepared
   791  	rollbackTxn := mock2PCTxn(txnEngine)
   792  	//insert 20 rows, then rollback the txn
   793  	//FIXME::??
   794  	//batch.SetLength(moBat, 20)
   795  	moBat = containers.CopyToMoBatch(catalog.MockBatch(schema, 20))
   796  	insertEntry, err = makePBEntry(INSERT, dbTestId,
   797  		tbTestId, dbName, schema.Name, "", moBat)
   798  	assert.NoError(t, err)
   799  	txnCmds = []txnCommand{
   800  		{
   801  			typ: CmdPreCommitWrite,
   802  			cmd: api.PrecommitWriteCmd{
   803  				UserId:    ac.userId,
   804  				AccountId: ac.accountId,
   805  				RoleId:    ac.roleId,
   806  				EntryList: []*api.Entry{insertEntry}},
   807  		},
   808  		{typ: CmdPrepare},
   809  		{typ: CmdRollback},
   810  	}
   811  	ctx = context.TODO()
   812  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
   813  	assert.Nil(t, err)
   814  
   815  	//start 1PC txn , read table
   816  	txn, err = txnEngine.StartTxn(nil)
   817  	assert.NoError(t, err)
   818  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
   819  	assert.NoError(t, err)
   820  	tbHandle, err = dbHandle.GetRelation(ctx, schema.Name)
   821  	assert.NoError(t, err)
   822  	tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil)
   823  	for _, reader := range tbReaders {
   824  		bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
   825  		assert.Nil(t, err)
   826  		if bat != nil {
   827  			len := vector.Length(bat.Vecs[0])
   828  			assert.Equal(t, 100, len)
   829  		}
   830  	}
   831  	// read row ids
   832  	hideCol, err := tbHandle.GetHideKeys(ctx)
   833  	assert.NoError(t, err)
   834  	reader, _ := tbHandle.NewReader(ctx, 1, nil, nil)
   835  	hideBat, err := reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m)
   836  	assert.Nil(t, err)
   837  	err = txn.Commit()
   838  	assert.Nil(t, err)
   839  
   840  	hideBats := containers.SplitBatch(hideBat, 5)
   841  	//delete 20 rows by 2PC txn
   842  	//batch.SetLength(hideBats[0], 20)
   843  	deleteEntry, err := makePBEntry(
   844  		DELETE,
   845  		dbId,
   846  		tbTestId,
   847  		dbName,
   848  		schema.Name,
   849  		"",
   850  		hideBats[0],
   851  	)
   852  	assert.Nil(t, err)
   853  	txnCmds = []txnCommand{
   854  		{
   855  			typ: CmdPreCommitWrite,
   856  			cmd: api.PrecommitWriteCmd{
   857  				UserId:    ac.userId,
   858  				AccountId: ac.accountId,
   859  				RoleId:    ac.roleId,
   860  				EntryList: []*api.Entry{deleteEntry}},
   861  		},
   862  		{typ: CmdPrepare},
   863  		{typ: CmdCommitting},
   864  		{typ: CmdCommit},
   865  	}
   866  	deleteTxn := mock2PCTxn(txnEngine)
   867  	ctx = context.TODO()
   868  	err = handle.handleCmds(ctx, deleteTxn, txnCmds)
   869  	assert.Nil(t, err)
   870  
   871  	//start a 2PC txn ,rollback it after prepared.
   872  	rollbackTxn = mock2PCTxn(txnEngine)
   873  	deleteEntry, _ = makePBEntry(
   874  		DELETE,
   875  		dbId,
   876  		tbTestId,
   877  		dbName,
   878  		schema.Name,
   879  		"",
   880  		hideBats[1],
   881  	)
   882  	txnCmds = []txnCommand{
   883  		{
   884  			typ: CmdPreCommitWrite,
   885  			cmd: api.PrecommitWriteCmd{
   886  				UserId:    ac.userId,
   887  				AccountId: ac.accountId,
   888  				RoleId:    ac.roleId,
   889  				EntryList: []*api.Entry{deleteEntry}},
   890  		},
   891  		{typ: CmdPrepare},
   892  		{typ: CmdRollback},
   893  	}
   894  	ctx = context.TODO()
   895  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
   896  	assert.Nil(t, err)
   897  
   898  	//read, there should be 80 rows left.
   899  	txn, err = txnEngine.StartTxn(nil)
   900  	assert.NoError(t, err)
   901  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
   902  	assert.NoError(t, err)
   903  	tbHandle, err = dbHandle.GetRelation(ctx, schema.Name)
   904  	assert.NoError(t, err)
   905  	tbReaders, _ = tbHandle.NewReader(ctx, 2, nil, nil)
   906  	for _, reader := range tbReaders {
   907  		bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
   908  		assert.Nil(t, err)
   909  		if bat != nil {
   910  			len := vector.Length(bat.Vecs[0])
   911  			assert.Equal(t, 80, len)
   912  		}
   913  	}
   914  	err = txn.Commit()
   915  	assert.Nil(t, err)
   916  }
   917  
   918  func TestHandle_HandlePreCommit2PCForParticipant(t *testing.T) {
   919  	defer testutils.AfterTest(t)()
   920  	opts := config.WithLongScanAndCKPOpts(nil)
   921  	handle := mockTAEHandle(t, opts)
   922  	defer handle.HandleClose(context.TODO())
   923  	IDAlloc := catalog.NewIDAllocator()
   924  	txnEngine := handle.GetTxnEngine()
   925  	schema := catalog.MockSchema(2, -1)
   926  	schema.Name = "tbtest"
   927  	schema.BlockMaxRows = 10
   928  	schema.SegmentMaxBlocks = 2
   929  	dbName := "dbtest"
   930  	ac := AccessInfo{
   931  		accountId: 0,
   932  		userId:    0,
   933  		roleId:    0,
   934  	}
   935  	//make create db cmd;
   936  	createDbEntries, err := makeCreateDatabaseEntries(
   937  		"",
   938  		ac,
   939  		dbName,
   940  		IDAlloc.NextDB(),
   941  		handle.m)
   942  	assert.Nil(t, err)
   943  	txnCmds := []txnCommand{
   944  		{
   945  			typ: CmdPreCommitWrite,
   946  			cmd: api.PrecommitWriteCmd{
   947  				UserId:    ac.userId,
   948  				AccountId: ac.accountId,
   949  				RoleId:    ac.roleId,
   950  				EntryList: createDbEntries},
   951  		},
   952  		{typ: CmdPrepare},
   953  		{typ: CmdCommit},
   954  	}
   955  	txnMeta := mock2PCTxn(txnEngine)
   956  	ctx := context.TODO()
   957  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
   958  	assert.Nil(t, err)
   959  
   960  	//start 1pc txn ,read "dbtest"'s ID
   961  	ctx = context.TODO()
   962  	txn, err := txnEngine.StartTxn(nil)
   963  	assert.Nil(t, err)
   964  	names, _ := txnEngine.DatabaseNames(ctx, txn)
   965  	assert.Equal(t, 2, len(names))
   966  	dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
   967  	assert.Nil(t, err)
   968  	dbTestId := dbHandle.GetDatabaseID(ctx)
   969  	err = txn.Commit()
   970  	assert.Nil(t, err)
   971  
   972  	//create table from "dbtest"
   973  	defs, err := moengine.SchemaToDefs(schema)
   974  	defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{
   975  		NullAbility: true,
   976  		Expr: &plan.Expr{
   977  			Expr: &plan.Expr_C{
   978  				C: &plan.Const{
   979  					Isnull: false,
   980  					Value: &plan.Const_Sval{
   981  						Sval: "expr1",
   982  					},
   983  				},
   984  			},
   985  		},
   986  		OriginString: "expr1",
   987  	}
   988  	defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{
   989  		NullAbility: false,
   990  		Expr: &plan.Expr{
   991  			Expr: &plan.Expr_C{
   992  				C: &plan.Const{
   993  					Isnull: false,
   994  					Value: &plan.Const_Sval{
   995  						Sval: "expr2",
   996  					},
   997  				},
   998  			},
   999  		},
  1000  		OriginString: "expr2",
  1001  	}
  1002  	assert.Nil(t, err)
  1003  	createTbEntries, err := makeCreateTableEntries(
  1004  		"",
  1005  		ac,
  1006  		schema.Name,
  1007  		IDAlloc.NextTable(),
  1008  		dbTestId,
  1009  		dbName,
  1010  		handle.m,
  1011  		defs,
  1012  	)
  1013  	assert.Nil(t, err)
  1014  	txnCmds = []txnCommand{
  1015  		{
  1016  			typ: CmdPreCommitWrite,
  1017  			cmd: api.PrecommitWriteCmd{
  1018  				UserId:    ac.userId,
  1019  				AccountId: ac.accountId,
  1020  				RoleId:    ac.roleId,
  1021  				EntryList: createTbEntries},
  1022  		},
  1023  		{typ: CmdPrepare},
  1024  		{typ: CmdCommit},
  1025  	}
  1026  	txnMeta = mock2PCTxn(txnEngine)
  1027  	ctx = context.TODO()
  1028  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
  1029  	assert.Nil(t, err)
  1030  
  1031  	//start 1pc txn ,read table ID
  1032  	txn, err = txnEngine.StartTxn(nil)
  1033  	assert.Nil(t, err)
  1034  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
  1035  	assert.NoError(t, err)
  1036  	dbId := dbHandle.GetDatabaseID(ctx)
  1037  	assert.True(t, dbTestId == dbId)
  1038  	names, _ = dbHandle.RelationNames(ctx)
  1039  	assert.Equal(t, 1, len(names))
  1040  	tbHandle, err := dbHandle.GetRelation(ctx, schema.Name)
  1041  	assert.NoError(t, err)
  1042  	tbTestId := tbHandle.GetRelationID(ctx)
  1043  	rDefs, _ := tbHandle.TableDefs(ctx)
  1044  	assert.Equal(t, 3, len(rDefs))
  1045  	rAttr := rDefs[0].(*engine.AttributeDef).Attr
  1046  	assert.Equal(t, true, rAttr.Default.NullAbility)
  1047  	rAttr = rDefs[1].(*engine.AttributeDef).Attr
  1048  	assert.Equal(t, "expr2", rAttr.Default.OriginString)
  1049  	err = txn.Commit()
  1050  	assert.NoError(t, err)
  1051  
  1052  	//DML::insert batch into table
  1053  	moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100))
  1054  	insertEntry, err := makePBEntry(INSERT, dbTestId,
  1055  		tbTestId, dbName, schema.Name, "", moBat)
  1056  	assert.NoError(t, err)
  1057  	txnCmds = []txnCommand{
  1058  		{
  1059  			typ: CmdPreCommitWrite,
  1060  			cmd: api.PrecommitWriteCmd{
  1061  				UserId:    ac.userId,
  1062  				AccountId: ac.accountId,
  1063  				RoleId:    ac.roleId,
  1064  				EntryList: []*api.Entry{insertEntry}},
  1065  		},
  1066  		{typ: CmdPrepare},
  1067  		{typ: CmdCommit},
  1068  	}
  1069  	insertTxn := mock2PCTxn(txnEngine)
  1070  	ctx = context.TODO()
  1071  	err = handle.handleCmds(ctx, insertTxn, txnCmds)
  1072  	assert.Nil(t, err)
  1073  
  1074  	//start 2PC txn ,rollback it after prepared
  1075  	rollbackTxn := mock2PCTxn(txnEngine)
  1076  	//insert 20 rows ,then rollback
  1077  	//FIXME::??
  1078  	//batch.SetLength(moBat, 20)
  1079  	moBat = containers.CopyToMoBatch(catalog.MockBatch(schema, 20))
  1080  	insertEntry, err = makePBEntry(INSERT, dbTestId,
  1081  		tbTestId, dbName, schema.Name, "", moBat)
  1082  	assert.NoError(t, err)
  1083  	txnCmds = []txnCommand{
  1084  		{
  1085  			typ: CmdPreCommitWrite,
  1086  			cmd: api.PrecommitWriteCmd{
  1087  				UserId:    ac.userId,
  1088  				AccountId: ac.accountId,
  1089  				RoleId:    ac.roleId,
  1090  				EntryList: []*api.Entry{insertEntry}},
  1091  		},
  1092  		{typ: CmdPrepare},
  1093  		{typ: CmdRollback},
  1094  	}
  1095  	ctx = context.TODO()
  1096  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1097  	assert.Nil(t, err)
  1098  
  1099  	//start 2PC txn , rollback it when it is ACTIVE.
  1100  	rollbackTxn = mock2PCTxn(txnEngine)
  1101  	//insert 10 rows ,then rollback
  1102  	//batch.SetLength(moBat, 10)
  1103  	moBat = containers.CopyToMoBatch(catalog.MockBatch(schema, 10))
  1104  	insertEntry, err = makePBEntry(INSERT, dbTestId,
  1105  		tbTestId, dbName, schema.Name, "", moBat)
  1106  	assert.NoError(t, err)
  1107  	txnCmds = []txnCommand{
  1108  		{
  1109  			typ: CmdPreCommitWrite,
  1110  			cmd: api.PrecommitWriteCmd{
  1111  				UserId:    ac.userId,
  1112  				AccountId: ac.accountId,
  1113  				RoleId:    ac.roleId,
  1114  				EntryList: []*api.Entry{insertEntry}},
  1115  		},
  1116  		{typ: CmdRollback},
  1117  	}
  1118  	ctx = context.TODO()
  1119  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1120  	assert.Nil(t, err)
  1121  
  1122  	//start 1PC txn , read table
  1123  	txn, err = txnEngine.StartTxn(nil)
  1124  	assert.NoError(t, err)
  1125  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
  1126  	assert.NoError(t, err)
  1127  	tbHandle, err = dbHandle.GetRelation(ctx, schema.Name)
  1128  	assert.NoError(t, err)
  1129  	tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil)
  1130  	for _, reader := range tbReaders {
  1131  		bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
  1132  		assert.Nil(t, err)
  1133  		if bat != nil {
  1134  			len := vector.Length(bat.Vecs[0])
  1135  			assert.Equal(t, 100, len)
  1136  		}
  1137  	}
  1138  	// read row ids
  1139  	hideCol, err := tbHandle.GetHideKeys(ctx)
  1140  	assert.NoError(t, err)
  1141  	reader, _ := tbHandle.NewReader(ctx, 1, nil, nil)
  1142  	hideBat, err := reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m)
  1143  	assert.Nil(t, err)
  1144  	err = txn.Commit()
  1145  	assert.Nil(t, err)
  1146  
  1147  	hideBats := containers.SplitBatch(hideBat, 5)
  1148  	//delete 20 rows by 2PC txn
  1149  	//batch.SetLength(hideBat, 20)
  1150  	deleteEntry, err := makePBEntry(
  1151  		DELETE,
  1152  		dbId,
  1153  		tbTestId,
  1154  		dbName,
  1155  		schema.Name,
  1156  		"",
  1157  		hideBats[0],
  1158  	)
  1159  	assert.Nil(t, err)
  1160  	txnCmds = []txnCommand{
  1161  		{
  1162  			typ: CmdPreCommitWrite,
  1163  			cmd: api.PrecommitWriteCmd{
  1164  				UserId:    ac.userId,
  1165  				AccountId: ac.accountId,
  1166  				RoleId:    ac.roleId,
  1167  				EntryList: []*api.Entry{deleteEntry}},
  1168  		},
  1169  		{typ: CmdPrepare},
  1170  		{typ: CmdCommitting},
  1171  		{typ: CmdCommit},
  1172  	}
  1173  	deleteTxn := mock2PCTxn(txnEngine)
  1174  	ctx = context.TODO()
  1175  	err = handle.handleCmds(ctx, deleteTxn, txnCmds)
  1176  	assert.Nil(t, err)
  1177  
  1178  	//start a 2PC txn ,rollback it after prepared.
  1179  	// delete 20 rows ,then rollback
  1180  	rollbackTxn = mock2PCTxn(txnEngine)
  1181  	deleteEntry, _ = makePBEntry(
  1182  		DELETE,
  1183  		dbId,
  1184  		tbTestId,
  1185  		dbName,
  1186  		schema.Name,
  1187  		"",
  1188  		hideBats[1],
  1189  	)
  1190  	txnCmds = []txnCommand{
  1191  		{
  1192  			typ: CmdPreCommitWrite,
  1193  			cmd: api.PrecommitWriteCmd{
  1194  				UserId:    ac.userId,
  1195  				AccountId: ac.accountId,
  1196  				RoleId:    ac.roleId,
  1197  				EntryList: []*api.Entry{deleteEntry}},
  1198  		},
  1199  		{typ: CmdPrepare},
  1200  		{typ: CmdRollback},
  1201  	}
  1202  	ctx = context.TODO()
  1203  	err = handle.handleCmds(ctx, rollbackTxn, txnCmds)
  1204  	assert.Nil(t, err)
  1205  
  1206  	//read, there should be 80 rows left.
  1207  	txn, err = txnEngine.StartTxn(nil)
  1208  	assert.NoError(t, err)
  1209  	dbHandle, err = txnEngine.GetDatabase(ctx, dbName, txn)
  1210  	assert.NoError(t, err)
  1211  	tbHandle, err = dbHandle.GetRelation(ctx, schema.Name)
  1212  	assert.NoError(t, err)
  1213  	tbReaders, _ = tbHandle.NewReader(ctx, 2, nil, nil)
  1214  	for _, reader := range tbReaders {
  1215  		bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
  1216  		assert.Nil(t, err)
  1217  		if bat != nil {
  1218  			len := vector.Length(bat.Vecs[0])
  1219  			assert.Equal(t, 80, len)
  1220  		}
  1221  	}
  1222  	err = txn.Commit()
  1223  	assert.Nil(t, err)
  1224  }
  1225  
  1226  func TestHandle_MVCCVisibility(t *testing.T) {
  1227  	defer testutils.AfterTest(t)()
  1228  	opts := config.WithLongScanAndCKPOpts(nil)
  1229  	handle := mockTAEHandle(t, opts)
  1230  	defer handle.HandleClose(context.TODO())
  1231  	IDAlloc := catalog.NewIDAllocator()
  1232  	txnEngine := handle.GetTxnEngine()
  1233  	schema := catalog.MockSchema(2, -1)
  1234  	schema.Name = "tbtest"
  1235  	schema.BlockMaxRows = 10
  1236  	schema.SegmentMaxBlocks = 2
  1237  	dbName := "dbtest"
  1238  	ac := AccessInfo{
  1239  		accountId: 0,
  1240  		userId:    0,
  1241  		roleId:    0,
  1242  	}
  1243  	//make create db cmd;
  1244  	createDbEntries, err := makeCreateDatabaseEntries(
  1245  		"",
  1246  		ac,
  1247  		dbName,
  1248  		IDAlloc.NextDB(),
  1249  		handle.m)
  1250  	assert.Nil(t, err)
  1251  	txnCmds := []txnCommand{
  1252  		{
  1253  			typ: CmdPreCommitWrite,
  1254  			cmd: api.PrecommitWriteCmd{
  1255  				UserId:    ac.userId,
  1256  				AccountId: ac.accountId,
  1257  				RoleId:    ac.roleId,
  1258  				EntryList: createDbEntries},
  1259  		},
  1260  	}
  1261  	txnMeta := mock2PCTxn(txnEngine)
  1262  	ctx := context.TODO()
  1263  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
  1264  	assert.Nil(t, err)
  1265  	var dbTestId uint64
  1266  	var dbNames []string
  1267  	wg := new(sync.WaitGroup)
  1268  	wg.Add(1)
  1269  	//start a db reader.
  1270  	go func() {
  1271  		//start 1pc txn ,read "dbtest"'s ID
  1272  		ctx := context.TODO()
  1273  		txn, err := txnEngine.StartTxn(nil)
  1274  		assert.Nil(t, err)
  1275  		dbNames, _ = txnEngine.DatabaseNames(ctx, txn)
  1276  		err = txn.Commit()
  1277  		assert.Nil(t, err)
  1278  		wg.Done()
  1279  
  1280  	}()
  1281  	wg.Wait()
  1282  	assert.Equal(t, 1, len(dbNames))
  1283  
  1284  	err = handle.HandlePrepare(ctx, txnMeta)
  1285  	assert.Nil(t, err)
  1286  	//start reader after preparing success.
  1287  	startTime := time.Now()
  1288  	wg.Add(1)
  1289  	go func() {
  1290  		//start 1pc txn ,read "dbtest"'s ID
  1291  		ctx := context.TODO()
  1292  		txn, err := txnEngine.StartTxn(nil)
  1293  		assert.Nil(t, err)
  1294  		//reader should wait until the writer committed.
  1295  		dbNames, _ = txnEngine.DatabaseNames(ctx, txn)
  1296  		assert.Equal(t, 2, len(dbNames))
  1297  		dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
  1298  		assert.Nil(t, err)
  1299  		dbTestId = dbHandle.GetDatabaseID(ctx)
  1300  		err = txn.Commit()
  1301  		assert.Nil(t, err)
  1302  		//wg.Done()
  1303  		//To check whether reader had waited.
  1304  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1305  		wg.Done()
  1306  
  1307  	}()
  1308  	//sleep 1 second
  1309  	time.Sleep(1 * time.Second)
  1310  	//CommitTS = PreparedTS + 1
  1311  	err = handle.handleCmds(ctx, txnMeta, []txnCommand{
  1312  		{typ: CmdCommitting}, {typ: CmdCommit},
  1313  	})
  1314  	assert.Nil(t, err)
  1315  	wg.Wait()
  1316  
  1317  	//create table from "dbtest"
  1318  	defs, err := moengine.SchemaToDefs(schema)
  1319  	defs[0].(*engine.AttributeDef).Attr.Default = &plan.Default{
  1320  		NullAbility: true,
  1321  		Expr: &plan.Expr{
  1322  			Expr: &plan.Expr_C{
  1323  				C: &plan.Const{
  1324  					Isnull: false,
  1325  					Value: &plan.Const_Sval{
  1326  						Sval: "expr1",
  1327  					},
  1328  				},
  1329  			},
  1330  		},
  1331  		OriginString: "expr1",
  1332  	}
  1333  	defs[1].(*engine.AttributeDef).Attr.Default = &plan.Default{
  1334  		NullAbility: false,
  1335  		Expr: &plan.Expr{
  1336  			Expr: &plan.Expr_C{
  1337  				C: &plan.Const{
  1338  					Isnull: false,
  1339  					Value: &plan.Const_Sval{
  1340  						Sval: "expr2",
  1341  					},
  1342  				},
  1343  			},
  1344  		},
  1345  		OriginString: "expr2",
  1346  	}
  1347  	assert.Nil(t, err)
  1348  	createTbEntries, err := makeCreateTableEntries(
  1349  		"",
  1350  		ac,
  1351  		schema.Name,
  1352  		IDAlloc.NextTable(),
  1353  		dbTestId,
  1354  		dbName,
  1355  		handle.m,
  1356  		defs,
  1357  	)
  1358  	assert.Nil(t, err)
  1359  	txnCmds = []txnCommand{
  1360  		{
  1361  			typ: CmdPreCommitWrite,
  1362  			cmd: api.PrecommitWriteCmd{
  1363  				UserId:    ac.userId,
  1364  				AccountId: ac.accountId,
  1365  				RoleId:    ac.roleId,
  1366  				EntryList: createTbEntries},
  1367  		},
  1368  		{typ: CmdPrepare},
  1369  	}
  1370  	txnMeta = mock2PCTxn(txnEngine)
  1371  	ctx = context.TODO()
  1372  	err = handle.handleCmds(ctx, txnMeta, txnCmds)
  1373  	assert.Nil(t, err)
  1374  	var tbTestId uint64
  1375  	startTime = time.Now()
  1376  	wg.Add(1)
  1377  	go func() {
  1378  		//start 1pc txn ,read table ID
  1379  		txn, err := txnEngine.StartTxn(nil)
  1380  		assert.Nil(t, err)
  1381  		ctx := context.TODO()
  1382  		dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
  1383  		assert.NoError(t, err)
  1384  		dbId := dbHandle.GetDatabaseID(ctx)
  1385  		assert.True(t, dbTestId == dbId)
  1386  		//txn should wait here.
  1387  		names, _ := dbHandle.RelationNames(ctx)
  1388  		assert.Equal(t, 1, len(names))
  1389  		tbHandle, err := dbHandle.GetRelation(ctx, schema.Name)
  1390  		assert.NoError(t, err)
  1391  		tbTestId = tbHandle.GetRelationID(ctx)
  1392  		rDefs, _ := tbHandle.TableDefs(ctx)
  1393  		assert.Equal(t, 3, len(rDefs))
  1394  		rAttr := rDefs[0].(*engine.AttributeDef).Attr
  1395  		assert.Equal(t, true, rAttr.Default.NullAbility)
  1396  		rAttr = rDefs[1].(*engine.AttributeDef).Attr
  1397  		assert.Equal(t, "expr2", rAttr.Default.OriginString)
  1398  		err = txn.Commit()
  1399  		assert.NoError(t, err)
  1400  		//wg.Done()
  1401  		//To check whether reader had waited.
  1402  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1403  		wg.Done()
  1404  	}()
  1405  	time.Sleep(1 * time.Second)
  1406  	err = handle.handleCmds(ctx, txnMeta, []txnCommand{
  1407  		{typ: CmdCommitting}, {typ: CmdCommit},
  1408  	})
  1409  	assert.Nil(t, err)
  1410  	wg.Wait()
  1411  
  1412  	//DML::insert batch into table
  1413  	moBat := containers.CopyToMoBatch(catalog.MockBatch(schema, 100))
  1414  	insertEntry, err := makePBEntry(INSERT, dbTestId,
  1415  		tbTestId, dbName, schema.Name, "", moBat)
  1416  	assert.NoError(t, err)
  1417  	txnCmds = []txnCommand{
  1418  		{
  1419  			typ: CmdPreCommitWrite,
  1420  			cmd: api.PrecommitWriteCmd{
  1421  				UserId:    ac.userId,
  1422  				AccountId: ac.accountId,
  1423  				RoleId:    ac.roleId,
  1424  				EntryList: []*api.Entry{insertEntry}},
  1425  		},
  1426  		{typ: CmdPrepare},
  1427  	}
  1428  	insertTxn := mock2PCTxn(txnEngine)
  1429  	ctx = context.TODO()
  1430  	err = handle.handleCmds(ctx, insertTxn, txnCmds)
  1431  	assert.Nil(t, err)
  1432  	startTime = time.Now()
  1433  	wg.Add(1)
  1434  	go func() {
  1435  		//start 1PC txn , read table
  1436  		txn, err := txnEngine.StartTxn(nil)
  1437  		assert.NoError(t, err)
  1438  		ctx := context.TODO()
  1439  		dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
  1440  		assert.NoError(t, err)
  1441  		tbHandle, err := dbHandle.GetRelation(ctx, schema.Name)
  1442  		assert.NoError(t, err)
  1443  		tbReaders, _ := tbHandle.NewReader(ctx, 1, nil, nil)
  1444  		for _, reader := range tbReaders {
  1445  			bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
  1446  			assert.Nil(t, err)
  1447  			if bat != nil {
  1448  				len := vector.Length(bat.Vecs[0])
  1449  				assert.Equal(t, 100, len)
  1450  			}
  1451  		}
  1452  		txn.Commit()
  1453  		//To check whether reader had waited.
  1454  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1455  		wg.Done()
  1456  	}()
  1457  	time.Sleep(1 * time.Second)
  1458  	//insertTxn 's CommitTS = PreparedTS + 1.
  1459  	err = handle.handleCmds(ctx, insertTxn, []txnCommand{
  1460  		{typ: CmdCommitting}, {typ: CmdCommit},
  1461  	})
  1462  	assert.Nil(t, err)
  1463  	wg.Wait()
  1464  
  1465  	//DML:delete rows
  1466  	//read row ids
  1467  	var hideBat *batch.Batch
  1468  	{
  1469  		txn, err := txnEngine.StartTxn(nil)
  1470  		assert.NoError(t, err)
  1471  		ctx = context.TODO()
  1472  		dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
  1473  		assert.NoError(t, err)
  1474  		tbHandle, err := dbHandle.GetRelation(ctx, schema.Name)
  1475  		assert.NoError(t, err)
  1476  		hideCol, err := tbHandle.GetHideKeys(ctx)
  1477  		assert.NoError(t, err)
  1478  		reader, _ := tbHandle.NewReader(ctx, 1, nil, nil)
  1479  		hideBat, err = reader[0].Read(ctx, []string{hideCol[0].Name}, nil, handle.m)
  1480  		assert.Nil(t, err)
  1481  		err = txn.Commit()
  1482  		assert.Nil(t, err)
  1483  	}
  1484  
  1485  	hideBats := containers.SplitBatch(hideBat, 5)
  1486  	//delete 20 rows by 2PC txn
  1487  	deleteTxn := mock2PCTxn(txnEngine)
  1488  	//batch.SetLength(hideBat, 20)
  1489  	deleteEntry, err := makePBEntry(
  1490  		DELETE,
  1491  		dbTestId,
  1492  		tbTestId,
  1493  		dbName,
  1494  		schema.Name,
  1495  		"",
  1496  		hideBats[0],
  1497  	)
  1498  	assert.Nil(t, err)
  1499  	txnCmds = []txnCommand{
  1500  		{
  1501  			typ: CmdPreCommitWrite,
  1502  			cmd: api.PrecommitWriteCmd{
  1503  				UserId:    ac.userId,
  1504  				AccountId: ac.accountId,
  1505  				RoleId:    ac.roleId,
  1506  				EntryList: []*api.Entry{deleteEntry}},
  1507  		},
  1508  		{typ: CmdPrepare},
  1509  	}
  1510  	ctx = context.TODO()
  1511  	err = handle.handleCmds(ctx, deleteTxn, txnCmds)
  1512  	assert.Nil(t, err)
  1513  	startTime = time.Now()
  1514  	wg.Add(1)
  1515  	go func() {
  1516  		//read, there should be 80 rows left.
  1517  		txn, err := txnEngine.StartTxn(nil)
  1518  		assert.NoError(t, err)
  1519  		ctx := context.TODO()
  1520  		dbHandle, err := txnEngine.GetDatabase(ctx, dbName, txn)
  1521  		assert.NoError(t, err)
  1522  		tbHandle, err := dbHandle.GetRelation(ctx, schema.Name)
  1523  		assert.NoError(t, err)
  1524  		tbReaders, _ := tbHandle.NewReader(ctx, 2, nil, nil)
  1525  		for _, reader := range tbReaders {
  1526  			bat, err := reader.Read(ctx, []string{schema.ColDefs[1].Name}, nil, handle.m)
  1527  			assert.Nil(t, err)
  1528  			if bat != nil {
  1529  				len := vector.Length(bat.Vecs[0])
  1530  				assert.Equal(t, 80, len)
  1531  			}
  1532  		}
  1533  		err = txn.Commit()
  1534  		assert.Nil(t, err)
  1535  		//To check whether reader had waited.
  1536  		assert.True(t, time.Since(startTime) > 1*time.Second)
  1537  		wg.Done()
  1538  
  1539  	}()
  1540  	time.Sleep(1 * time.Second)
  1541  	//deleteTxn 's CommitTS = PreparedTS + 1
  1542  	err = handle.handleCmds(ctx, deleteTxn, []txnCommand{
  1543  		{typ: CmdCommitting}, {typ: CmdCommit},
  1544  	})
  1545  	assert.Nil(t, err)
  1546  	wg.Wait()
  1547  }