github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/colexec/auto_incr.go (about)

     1  // Copyright 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 colexec
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"math"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/catalog"
    23  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    24  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    25  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    26  	"github.com/matrixorigin/matrixone/pkg/container/nulls"
    27  	"github.com/matrixorigin/matrixone/pkg/container/types"
    28  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    29  	"github.com/matrixorigin/matrixone/pkg/defines"
    30  	"github.com/matrixorigin/matrixone/pkg/logutil"
    31  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    32  	"github.com/matrixorigin/matrixone/pkg/txn/client"
    33  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    34  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    35  	"golang.org/x/exp/constraints"
    36  )
    37  
    38  var AUTO_INCR_TABLE = "%!%mo_increment_columns"
    39  var AUTO_INCR_TABLE_COLNAME []string = []string{catalog.Row_ID, "name", "offset", "step"}
    40  
    41  type AutoIncrParam struct {
    42  	eg engine.Engine
    43  	//	rel     engine.Relation
    44  	ctx     context.Context
    45  	proc    *process.Process
    46  	dbName  string
    47  	tblName string
    48  	colDefs []*plan.ColDef
    49  }
    50  
    51  func (aip *AutoIncrParam) SetLastInsertID(id uint64) {
    52  	aip.proc.SetLastInsertID(id)
    53  }
    54  
    55  func getNextAutoIncrNum(proc *process.Process, colDefs []*plan.ColDef, ctx context.Context, incrParam *AutoIncrParam, bat *batch.Batch, tableID uint64) ([]uint64, []uint64, error) {
    56  	autoIncrCaches := proc.SessionInfo.AutoIncrCaches
    57  	autoIncrCaches.Mu.Lock()
    58  	defer autoIncrCaches.Mu.Unlock()
    59  	offset, step := make([]uint64, 0), make([]uint64, 0)
    60  	for i, col := range colDefs {
    61  		if !col.Typ.AutoIncr {
    62  			continue
    63  		}
    64  		name := fmt.Sprintf("%d_%s", tableID, col.Name)
    65  		autoincrcache, ok := autoIncrCaches.AutoIncrCaches[name]
    66  		// Not cached yet or the cache is ran out.
    67  		// Need new txn for read from the table.
    68  		if !ok || autoincrcache.CurNum >= autoincrcache.MaxNum {
    69  			// Need return maxNum for correction.
    70  			cur := uint64(0)
    71  			if ok {
    72  				cur = autoincrcache.CurNum
    73  			}
    74  			curNum, maxNum, stp, err := getNextOneCache(ctx, incrParam, bat, tableID, i, name, proc.SessionInfo.AutoIncrCacheSize, cur)
    75  			if err != nil {
    76  				return nil, nil, err
    77  			}
    78  			autoIncrCaches.AutoIncrCaches[name] = defines.AutoIncrCache{CurNum: curNum, MaxNum: maxNum, Step: stp}
    79  		}
    80  
    81  		offset = append(offset, autoIncrCaches.AutoIncrCaches[name].CurNum)
    82  		step = append(step, autoIncrCaches.AutoIncrCaches[name].Step)
    83  
    84  		// Here got the most recent id in the cache.
    85  		// Need compare witch vec and get the maxNum.
    86  		maxNum, err := getMax(incrParam, bat, i, autoIncrCaches.AutoIncrCaches[name].Step, 1, autoIncrCaches.AutoIncrCaches[name].CurNum)
    87  		if err != nil {
    88  			return nil, nil, err
    89  		}
    90  
    91  		incrParam.SetLastInsertID(maxNum)
    92  
    93  		// Update the caches.
    94  		autoIncrCaches.AutoIncrCaches[name] = defines.AutoIncrCache{CurNum: maxNum,
    95  			MaxNum: autoIncrCaches.AutoIncrCaches[name].MaxNum, Step: autoIncrCaches.AutoIncrCaches[name].Step}
    96  	}
    97  
    98  	return offset, step, nil
    99  }
   100  
   101  func deleteAutoIncrCache(name string, proc *process.Process) {
   102  	autoIncrCaches := proc.SessionInfo.AutoIncrCaches
   103  	autoIncrCaches.Mu.Lock()
   104  	defer autoIncrCaches.Mu.Unlock()
   105  	_, ok := autoIncrCaches.AutoIncrCaches[name]
   106  	if ok {
   107  		delete(autoIncrCaches.AutoIncrCaches, name)
   108  	}
   109  }
   110  
   111  func renameAutoIncrCache(newname, oldname string, proc *process.Process) {
   112  	autoIncrCaches := proc.SessionInfo.AutoIncrCaches
   113  	autoIncrCaches.Mu.Lock()
   114  	defer autoIncrCaches.Mu.Unlock()
   115  	_, ok := autoIncrCaches.AutoIncrCaches[oldname]
   116  	if ok {
   117  		autoIncrCaches.AutoIncrCaches[newname] = defines.AutoIncrCache{CurNum: autoIncrCaches.AutoIncrCaches[oldname].CurNum,
   118  			MaxNum: autoIncrCaches.AutoIncrCaches[oldname].MaxNum, Step: autoIncrCaches.AutoIncrCaches[oldname].Step}
   119  		delete(autoIncrCaches.AutoIncrCaches, oldname)
   120  	}
   121  }
   122  
   123  func getNextOneCache(ctx context.Context, param *AutoIncrParam, bat *batch.Batch, tableID uint64, i int, name string, cachesize, curNum uint64) (uint64, uint64, uint64, error) {
   124  	var err error
   125  	loopCnt := 0
   126  loop:
   127  	loopCnt += 1
   128  	if loopCnt >= 100 {
   129  		return 0, 0, 0, err
   130  	}
   131  
   132  	txn, err := NewTxn(param.eg, param.proc, param.ctx)
   133  	if err != nil {
   134  		goto loop
   135  	}
   136  	var d, m, s uint64
   137  	if d, m, s, err = getOneColRangeFromAutoIncrTable(param, bat, name, i, txn, cachesize, curNum); err != nil { // Get next 1000.
   138  		RolllbackTxn(param.eg, txn, param.ctx)
   139  		goto loop
   140  	}
   141  
   142  	if err = CommitTxn(param.eg, txn, param.ctx); err != nil {
   143  		goto loop
   144  	}
   145  
   146  	return d, m, s, nil
   147  }
   148  
   149  func UpdateInsertBatch(e engine.Engine, ctx context.Context, proc *process.Process, ColDefs []*plan.ColDef, bat *batch.Batch, tableID uint64, dbName, tblName string) error {
   150  	incrParam := &AutoIncrParam{
   151  		eg:      e,
   152  		ctx:     ctx,
   153  		proc:    proc,
   154  		colDefs: ColDefs,
   155  		dbName:  dbName,
   156  		tblName: tblName,
   157  	}
   158  
   159  	offset, step, err := getNextAutoIncrNum(proc, ColDefs, ctx, incrParam, bat, tableID)
   160  	if err != nil {
   161  		return err
   162  	}
   163  
   164  	if err = updateBatchImpl(ctx, ColDefs, bat, offset, step); err != nil {
   165  		return err
   166  	}
   167  	return nil
   168  }
   169  
   170  // func UpdateInsertValueBatch(e engine.Engine, ctx context.Context, proc *process.Process, p *plan.InsertValues, bat *batch.Batch, dbName, tblName string) error {
   171  // 	ColDefs := p.ExplicitCols
   172  // 	orderColDefs(p.OrderAttrs, ColDefs, p.Columns)
   173  // 	db, err := e.Database(ctx, p.DbName, proc.TxnOperator)
   174  // 	if err != nil {
   175  // 		return err
   176  // 	}
   177  // 	rel, err := db.Relation(ctx, p.TblName)
   178  // 	if err != nil {
   179  // 		return err
   180  // 	}
   181  
   182  // 	return UpdateInsertBatch(e, ctx, proc, ColDefs, bat, rel.GetTableID(ctx), dbName, tblName)
   183  // }
   184  
   185  // get autoincr columns values.  This function updates the auto incr table.
   186  // multiple txn may cause a conflicts, but we retry off band transactions.
   187  // func getRangeFromAutoIncrTable(param *AutoIncrParam, bat *batch.Batch, tableID uint64) ([]uint64, []uint64, error) {
   188  // 	var err error
   189  // 	loopCnt := 0
   190  // loop:
   191  // 	// if fail 100 times, too bad, really unlucky one get aborted anyway.
   192  // 	loopCnt += 1
   193  // 	if loopCnt >= 100 {
   194  // 		return nil, nil, err
   195  // 	}
   196  // 	txn, err := NewTxn(param.eg, param.proc, param.ctx)
   197  // 	if err != nil {
   198  // 		goto loop
   199  // 	}
   200  // 	offset, step := make([]uint64, 0), make([]uint64, 0)
   201  // 	for i, col := range param.colDefs {
   202  // 		if !col.Typ.AutoIncr {
   203  // 			continue
   204  // 		}
   205  // 		var d, s uint64
   206  // 		name := fmt.Sprintf("%d_%s", tableID, col.Name)
   207  // 		if d, _, s, err = getOneColRangeFromAutoIncrTable(param, bat, name, i, txn, 1, 0); err != nil {
   208  // 			RolllbackTxn(param.eg, txn, param.ctx)
   209  // 			goto loop
   210  // 		}
   211  // 		offset = append(offset, d)
   212  // 		step = append(step, s)
   213  // 	}
   214  // 	if err = CommitTxn(param.eg, txn, param.ctx); err != nil {
   215  // 		goto loop
   216  // 	}
   217  // 	return offset, step, nil
   218  // }
   219  
   220  func getMaxnum[T constraints.Integer](vec *vector.Vector, length, maxNum, step, cacheSize uint64) uint64 {
   221  	vs := vector.MustTCols[T](vec)
   222  	rowIndex := uint64(0)
   223  	storeNum := maxNum
   224  	for rowIndex = 0; rowIndex < length; rowIndex++ {
   225  		if nulls.Contains(vec.Nsp, rowIndex) {
   226  			maxNum += step
   227  		} else {
   228  			if vs[rowIndex] < 0 {
   229  				continue
   230  			}
   231  			if uint64(vs[rowIndex]) > maxNum {
   232  				maxNum = uint64(vs[rowIndex])
   233  			}
   234  		}
   235  	}
   236  	if cacheSize != 1 {
   237  		storeNum += step * cacheSize
   238  		if storeNum > maxNum {
   239  			maxNum = storeNum
   240  		}
   241  	}
   242  	return maxNum
   243  }
   244  
   245  func updateVector[T constraints.Integer](vec *vector.Vector, length, curNum, stepNum uint64) {
   246  	vs := vector.MustTCols[T](vec)
   247  	rowIndex := uint64(0)
   248  	for rowIndex = 0; rowIndex < length; rowIndex++ {
   249  		if nulls.Contains(vec.Nsp, uint64(rowIndex)) {
   250  			nulls.Del(vec.Nsp, rowIndex)
   251  			curNum += stepNum
   252  			vs[rowIndex] = T(curNum)
   253  		} else {
   254  			if vs[rowIndex] < 0 {
   255  				continue
   256  			}
   257  			if uint64(vs[rowIndex]) > curNum {
   258  				curNum = uint64(vs[rowIndex])
   259  			}
   260  		}
   261  	}
   262  }
   263  
   264  // Get max get the max number of next ids and the vec number.
   265  func getMax(param *AutoIncrParam, bat *batch.Batch, pos int, step, cachesize, oriNum uint64) (uint64, error) {
   266  	vec := bat.Vecs[pos]
   267  	maxNum := oriNum
   268  	maxNumStore := oriNum
   269  
   270  	switch vec.Typ.Oid {
   271  	case types.T_int8:
   272  		maxNum = getMaxnum[int8](vec, uint64(bat.Length()), maxNum, step, 1)
   273  		maxNumStore = getMaxnum[int8](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   274  		if maxNum > math.MaxInt8 {
   275  			return 0, moerr.NewOutOfRange(param.ctx, "tinyint", "value %v", maxNum)
   276  		}
   277  		if maxNumStore > math.MaxInt8 {
   278  			maxNumStore = math.MaxInt8
   279  		}
   280  	case types.T_int16:
   281  		maxNum = getMaxnum[int16](vec, uint64(bat.Length()), maxNum, step, 1)
   282  		maxNumStore = getMaxnum[int16](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   283  		if maxNum > math.MaxInt16 {
   284  			return 0, moerr.NewOutOfRange(param.ctx, "smallint", "value %v", maxNum)
   285  		}
   286  		if maxNumStore > math.MaxInt16 {
   287  			maxNumStore = math.MaxInt16
   288  		}
   289  	case types.T_int32:
   290  		maxNum = getMaxnum[int32](vec, uint64(bat.Length()), maxNum, step, 1)
   291  		maxNumStore = getMaxnum[int32](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   292  		if maxNum > math.MaxInt32 {
   293  			return 0, moerr.NewOutOfRange(param.ctx, "int", "value %v", maxNum)
   294  		}
   295  		if maxNumStore > math.MaxInt32 {
   296  			maxNumStore = math.MaxInt32
   297  		}
   298  	case types.T_int64:
   299  		maxNum = getMaxnum[int64](vec, uint64(bat.Length()), maxNum, step, 1)
   300  		maxNumStore = getMaxnum[int64](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   301  		if maxNum > math.MaxInt64 {
   302  			return 0, moerr.NewOutOfRange(param.ctx, "bigint", "value %v", maxNum)
   303  		}
   304  		if maxNumStore > math.MaxInt64 {
   305  			maxNumStore = math.MaxInt64
   306  		}
   307  	case types.T_uint8:
   308  		maxNum = getMaxnum[uint8](vec, uint64(bat.Length()), maxNum, step, 1)
   309  		maxNumStore = getMaxnum[uint8](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   310  		if maxNum > math.MaxUint8 {
   311  			return 0, moerr.NewOutOfRange(param.ctx, "tinyint unsigned", "value %v", maxNum)
   312  		}
   313  		if maxNumStore > math.MaxUint8 {
   314  			maxNumStore = math.MaxUint8
   315  		}
   316  	case types.T_uint16:
   317  		maxNum = getMaxnum[uint16](vec, uint64(bat.Length()), maxNum, step, 1)
   318  		maxNumStore = getMaxnum[uint16](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   319  		if maxNum > math.MaxUint16 {
   320  			return 0, moerr.NewOutOfRange(param.ctx, "smallint unsigned", "value %v", maxNum)
   321  		}
   322  		if maxNumStore > math.MaxUint16 {
   323  			maxNumStore = math.MaxUint16
   324  		}
   325  	case types.T_uint32:
   326  		maxNum = getMaxnum[uint32](vec, uint64(bat.Length()), maxNum, step, 1)
   327  		maxNumStore = getMaxnum[uint32](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   328  		if maxNum > math.MaxUint32 {
   329  			return 0, moerr.NewOutOfRange(param.ctx, "int unsigned", "value %v", maxNum)
   330  		}
   331  		if maxNumStore > math.MaxUint32 {
   332  			maxNumStore = math.MaxUint32
   333  		}
   334  	case types.T_uint64:
   335  		maxNum = getMaxnum[uint64](vec, uint64(bat.Length()), maxNum, step, 1)
   336  		maxNumStore = getMaxnum[uint64](vec, uint64(bat.Length()), maxNumStore, step, cachesize)
   337  		if maxNum < oriNum {
   338  			return 0, moerr.NewOutOfRange(param.ctx, "bigint unsigned", "auto_incrment column constant value overflows bigint unsigned")
   339  		}
   340  		if maxNumStore < oriNum {
   341  			maxNumStore = math.MaxUint64
   342  		}
   343  	default:
   344  		return 0, moerr.NewInvalidInput(param.ctx, "the auto_incr col is not integer type")
   345  	}
   346  
   347  	return maxNumStore, nil
   348  }
   349  
   350  func getOneColRangeFromAutoIncrTable(param *AutoIncrParam, bat *batch.Batch, name string, pos int, txn client.TxnOperator, cachesize, curNum uint64) (uint64, uint64, uint64, error) {
   351  	oriNum, step, delBat, err := getCurrentIndex(param, name, txn, param.proc.Mp())
   352  	if err != nil {
   353  		return 0, 0, 0, err
   354  	}
   355  
   356  	if curNum > oriNum {
   357  		oriNum = curNum
   358  	}
   359  
   360  	maxNum, err := getMax(param, bat, pos, step, cachesize, oriNum)
   361  	if err != nil {
   362  		return 0, 0, 0, err
   363  	}
   364  
   365  	if err := updateAutoIncrTable(param, delBat, maxNum, name, txn, param.proc.Mp()); err != nil {
   366  		return 0, 0, 0, err
   367  	}
   368  	return oriNum, maxNum, step, nil
   369  }
   370  
   371  func updateBatchImpl(ctx context.Context, ColDefs []*plan.ColDef, bat *batch.Batch, offset, step []uint64) error {
   372  	pos := 0
   373  	for i, col := range ColDefs {
   374  		if !col.Typ.AutoIncr {
   375  			continue
   376  		}
   377  		vec := bat.Vecs[i]
   378  		curNum := offset[pos]
   379  		stepNum := step[pos]
   380  		pos++
   381  		switch vec.Typ.Oid {
   382  		case types.T_int8:
   383  			updateVector[int8](vec, uint64(bat.Length()), curNum, stepNum)
   384  		case types.T_int16:
   385  			updateVector[int16](vec, uint64(bat.Length()), curNum, stepNum)
   386  		case types.T_int32:
   387  			updateVector[int32](vec, uint64(bat.Length()), curNum, stepNum)
   388  		case types.T_int64:
   389  			updateVector[int64](vec, uint64(bat.Length()), curNum, stepNum)
   390  		case types.T_uint8:
   391  			updateVector[uint8](vec, uint64(bat.Length()), curNum, stepNum)
   392  		case types.T_uint16:
   393  			updateVector[uint16](vec, uint64(bat.Length()), curNum, stepNum)
   394  		case types.T_uint32:
   395  			updateVector[uint32](vec, uint64(bat.Length()), curNum, stepNum)
   396  		case types.T_uint64:
   397  			updateVector[uint64](vec, uint64(bat.Length()), curNum, stepNum)
   398  		default:
   399  			return moerr.NewInvalidInput(ctx, "invalid auto_increment type '%v'", vec.Typ.Oid)
   400  		}
   401  	}
   402  	return nil
   403  }
   404  
   405  func getRangeExpr(colName string) *plan.Expr {
   406  	return &plan.Expr{
   407  		Expr: &plan.Expr_F{
   408  			F: &plan.Function{
   409  				Func: &plan.ObjectRef{
   410  					Obj:     10,
   411  					ObjName: "=",
   412  				},
   413  				Args: []*plan.Expr{
   414  					{
   415  						Expr: &plan.Expr_Col{
   416  							Col: &plan.ColRef{
   417  								Name: AUTO_INCR_TABLE_COLNAME[1],
   418  							},
   419  						},
   420  					},
   421  					{
   422  						Expr: &plan.Expr_C{
   423  							C: &plan.Const{
   424  								Value: &plan.Const_Sval{
   425  									Sval: colName,
   426  								},
   427  							},
   428  						},
   429  					},
   430  				},
   431  			},
   432  		},
   433  	}
   434  }
   435  
   436  func getCurrentIndex(param *AutoIncrParam, colName string, txn client.TxnOperator, mp *mpool.MPool) (uint64, uint64, *batch.Batch, error) {
   437  	var rds []engine.Reader
   438  	retbat := batch.NewWithSize(1)
   439  
   440  	rel, err := GetNewRelation(param.eg, param.dbName, AUTO_INCR_TABLE, txn, param.ctx)
   441  	if err != nil {
   442  		return 0, 0, nil, err
   443  	}
   444  
   445  	expr := getRangeExpr(colName)
   446  	// use expression to get ranges
   447  	ret, err := rel.Ranges(param.ctx, expr)
   448  	if err != nil {
   449  		return 0, 0, nil, err
   450  	}
   451  	switch {
   452  	case len(ret) == 0:
   453  		if rds, err = rel.NewReader(param.ctx, 1, expr, nil); err != nil {
   454  			return 0, 0, nil, err
   455  		}
   456  	case len(ret) == 1 && len(ret[0]) == 0:
   457  		if rds, err = rel.NewReader(param.ctx, 1, expr, nil); err != nil {
   458  			return 0, 0, nil, err
   459  		}
   460  	case len(ret[0]) == 0:
   461  		rds0, err := rel.NewReader(param.ctx, 1, expr, nil)
   462  		if err != nil {
   463  			return 0, 0, nil, err
   464  		}
   465  		rds1, err := rel.NewReader(param.ctx, 1, expr, ret[1:])
   466  		if err != nil {
   467  			return 0, 0, nil, err
   468  		}
   469  		rds = append(rds, rds0...)
   470  		rds = append(rds, rds1...)
   471  	default:
   472  		rds, _ = rel.NewReader(param.ctx, 1, expr, ret)
   473  	}
   474  
   475  	for len(rds) > 0 {
   476  		bat, err := rds[0].Read(param.ctx, AUTO_INCR_TABLE_COLNAME, expr, param.proc.Mp())
   477  		if err != nil {
   478  			return 0, 0, nil, moerr.NewInvalidInput(param.ctx, "can not find the auto col")
   479  		}
   480  		if bat == nil {
   481  			rds[0].Close()
   482  			rds = rds[1:]
   483  			continue
   484  		}
   485  		if len(bat.Vecs) < 2 {
   486  			return 0, 0, nil, moerr.NewInternalError(param.ctx, "the mo_increment_columns col num is not two")
   487  		}
   488  
   489  		vs2 := vector.MustTCols[uint64](bat.Vecs[2])
   490  		vs3 := vector.MustTCols[uint64](bat.Vecs[3])
   491  		var rowIndex int64
   492  		for rowIndex = 0; rowIndex < int64(bat.Length()); rowIndex++ {
   493  			str := bat.Vecs[1].GetString(rowIndex)
   494  			if str == colName {
   495  				break
   496  			}
   497  		}
   498  		if rowIndex < int64(bat.Length()) {
   499  			vec := vector.New(bat.GetVector(0).Typ)
   500  			rowid := vector.MustTCols[types.Rowid](bat.GetVector(0))[rowIndex]
   501  			if err := vec.Append(rowid, false, mp); err != nil {
   502  				panic(err)
   503  			}
   504  			retbat.SetVector(0, vec)
   505  			retbat.SetZs(1, mp)
   506  			bat.Clean(mp)
   507  			return vs2[rowIndex], vs3[rowIndex], retbat, nil
   508  		}
   509  		bat.Clean(mp)
   510  	}
   511  	return 0, 0, nil, nil
   512  }
   513  
   514  func updateAutoIncrTable(param *AutoIncrParam, delBat *batch.Batch, curNum uint64, name string, txn client.TxnOperator, mp *mpool.MPool) error {
   515  	rel, err := GetNewRelation(param.eg, param.dbName, AUTO_INCR_TABLE, txn, param.ctx)
   516  	if err != nil {
   517  		return err
   518  	}
   519  
   520  	err = rel.Delete(param.ctx, delBat, AUTO_INCR_TABLE_COLNAME[0])
   521  	if err != nil {
   522  		delBat.Clean(mp)
   523  		return err
   524  	}
   525  	bat := makeAutoIncrBatch(name, curNum, 1, mp)
   526  	if err = rel.Write(param.ctx, bat); err != nil {
   527  		bat.Clean(mp)
   528  		return err
   529  	}
   530  	param.proc.SetLastInsertID(curNum)
   531  	return nil
   532  }
   533  
   534  func makeAutoIncrBatch(name string, num, step uint64, mp *mpool.MPool) *batch.Batch {
   535  	vec := vector.NewWithStrings(types.T_varchar.ToType(), []string{name}, nil, mp)
   536  	vec2 := vector.NewWithFixed(types.T_uint64.ToType(), []uint64{num}, nil, mp)
   537  	vec3 := vector.NewWithFixed(types.T_uint64.ToType(), []uint64{step}, nil, mp)
   538  	bat := batch.NewWithSize(3)
   539  	bat.SetAttributes(AUTO_INCR_TABLE_COLNAME[1:])
   540  	bat.SetVector(0, vec)
   541  	bat.SetVector(1, vec2)
   542  	bat.SetVector(2, vec3)
   543  	bat.SetZs(1, mp)
   544  	return bat
   545  }
   546  
   547  func GetDeleteBatch(rel engine.Relation, ctx context.Context, colName string, mp *mpool.MPool) (*batch.Batch, uint64) {
   548  	var rds []engine.Reader
   549  
   550  	ret, err := rel.Ranges(ctx, nil)
   551  	if err != nil {
   552  		panic(err)
   553  	}
   554  	switch {
   555  	case len(ret) == 0:
   556  		rds, _ = rel.NewReader(ctx, 1, nil, nil)
   557  	case len(ret) == 1 && len(ret[0]) == 0:
   558  		rds, _ = rel.NewReader(ctx, 1, nil, nil)
   559  	case len(ret[0]) == 0:
   560  		rds0, _ := rel.NewReader(ctx, 1, nil, nil)
   561  		rds1, _ := rel.NewReader(ctx, 1, nil, ret[1:])
   562  		rds = append(rds, rds0...)
   563  		rds = append(rds, rds1...)
   564  	default:
   565  		rds, _ = rel.NewReader(ctx, 1, nil, ret)
   566  	}
   567  
   568  	retbat := batch.NewWithSize(1)
   569  	for len(rds) > 0 {
   570  		bat, err := rds[0].Read(ctx, AUTO_INCR_TABLE_COLNAME, nil, mp)
   571  		if err != nil {
   572  			bat.Clean(mp)
   573  			return nil, 0
   574  		}
   575  		if bat == nil {
   576  			rds[0].Close()
   577  			rds = rds[1:]
   578  			continue
   579  		}
   580  		if len(bat.Vecs) < 2 {
   581  			panic(moerr.NewInternalError(ctx, "the mo_increment_columns col num is not two"))
   582  		}
   583  		var rowIndex int64
   584  		for rowIndex = 0; rowIndex < int64(bat.Length()); rowIndex++ {
   585  			str := bat.Vecs[1].GetString(rowIndex)
   586  			if str == colName {
   587  				currentNum := vector.MustTCols[uint64](bat.Vecs[2])[rowIndex : rowIndex+1]
   588  				vec := vector.New(bat.GetVector(0).Typ)
   589  				rowid := vector.MustTCols[types.Rowid](bat.GetVector(0))[rowIndex]
   590  				if err := vec.Append(rowid, false, mp); err != nil {
   591  					panic(err)
   592  				}
   593  				retbat.SetVector(0, vec)
   594  				retbat.SetZs(1, mp)
   595  				bat.Clean(mp)
   596  				return retbat, currentNum[0]
   597  			}
   598  		}
   599  		bat.Clean(mp)
   600  	}
   601  	return nil, 0
   602  }
   603  
   604  // for create database operation, add col in mo_increment_columns table
   605  func CreateAutoIncrTable(e engine.Engine, ctx context.Context, proc *process.Process, dbName string) error {
   606  	dbSource, err := e.Database(ctx, dbName, proc.TxnOperator)
   607  	if err != nil {
   608  		return err
   609  	}
   610  	if err = dbSource.Create(ctx, AUTO_INCR_TABLE, getAutoIncrTableDef()); err != nil {
   611  		return err
   612  	}
   613  	return nil
   614  }
   615  
   616  // for create table operation, add col in mo_increment_columns table
   617  func CreateAutoIncrCol(eg engine.Engine, ctx context.Context, db engine.Database, proc *process.Process, cols []*plan.ColDef, dbName, tblName string) error {
   618  	rel, err := db.Relation(ctx, tblName)
   619  	if err != nil {
   620  		return err
   621  	}
   622  	name := fmt.Sprintf("%d_", rel.GetTableID(ctx))
   623  
   624  	txn, err := NewTxn(eg, proc, ctx)
   625  	if err != nil {
   626  		return err
   627  	}
   628  
   629  	for _, attr := range cols {
   630  		if !attr.Typ.AutoIncr {
   631  			continue
   632  		}
   633  		var rel2 engine.Relation
   634  		// Essentially, temporary table is not an operation of a transaction.
   635  		// Therefore, it is not possible to fetch the temporary table through the function GetNewRelation
   636  		if dbName == defines.TEMPORARY_DBNAME {
   637  			rel2, err = db.Relation(ctx, AUTO_INCR_TABLE)
   638  		} else {
   639  			rel2, err = GetNewRelation(eg, dbName, AUTO_INCR_TABLE, txn, ctx)
   640  		}
   641  		if err != nil {
   642  			return err
   643  		}
   644  		bat := makeAutoIncrBatch(name+attr.Name, 0, 1, proc.Mp())
   645  		if err = rel2.Write(ctx, bat); err != nil {
   646  			if err2 := RolllbackTxn(eg, txn, ctx); err2 != nil {
   647  				return err2
   648  			}
   649  			return err
   650  		}
   651  	}
   652  	if err = CommitTxn(eg, txn, ctx); err != nil {
   653  		return err
   654  	}
   655  	return nil
   656  }
   657  
   658  // for delete table operation, delete col in mo_increment_columns table
   659  func DeleteAutoIncrCol(eg engine.Engine, ctx context.Context, db engine.Database, rel engine.Relation, proc *process.Process, dbName string, tableID uint64) error {
   660  	txn, err := NewTxn(eg, proc, ctx)
   661  	if err != nil {
   662  		return err
   663  	}
   664  
   665  	var rel2 engine.Relation
   666  	// Essentially, temporary table is not an operation of a transaction.
   667  	// Therefore, it is not possible to fetch the temporary table through the function GetNewRelation
   668  	if dbName == defines.TEMPORARY_DBNAME {
   669  		rel2, err = db.Relation(ctx, AUTO_INCR_TABLE)
   670  	} else {
   671  		rel2, err = GetNewRelation(eg, dbName, AUTO_INCR_TABLE, txn, ctx)
   672  	}
   673  
   674  	if err != nil {
   675  		return err
   676  	}
   677  
   678  	defs, err := rel.TableDefs(ctx)
   679  	if err != nil {
   680  		return err
   681  	}
   682  
   683  	for _, def := range defs {
   684  		switch d := def.(type) {
   685  		case *engine.AttributeDef:
   686  			if !d.Attr.AutoIncrement {
   687  				continue
   688  			}
   689  			name := fmt.Sprintf("%d_%s", tableID, d.Attr.Name)
   690  			bat, _ := GetDeleteBatch(rel2, ctx, name, proc.Mp())
   691  			if bat == nil {
   692  				return moerr.NewInternalError(ctx, "the deleted batch is nil")
   693  			}
   694  			if err = rel2.Delete(ctx, bat, AUTO_INCR_TABLE_COLNAME[0]); err != nil {
   695  				bat.Clean(proc.Mp())
   696  				if err2 := RolllbackTxn(eg, txn, ctx); err2 != nil {
   697  					return err2
   698  				}
   699  				return err
   700  			}
   701  			bat.Clean(proc.Mp())
   702  
   703  			// Delete the cache.
   704  			deleteAutoIncrCache(name, proc)
   705  		}
   706  	}
   707  	if err = CommitTxn(eg, txn, ctx); err != nil {
   708  		return err
   709  	}
   710  	return nil
   711  }
   712  
   713  // for delete table operation, move old col as new col in mo_increment_columns table
   714  func MoveAutoIncrCol(eg engine.Engine, ctx context.Context, tblName string, db engine.Database, proc *process.Process, oldTableID, newId uint64, dbName string) error {
   715  	var err error
   716  	newRel, err := db.Relation(ctx, tblName)
   717  	if err != nil {
   718  		return err
   719  	}
   720  	defs, err := newRel.TableDefs(ctx)
   721  	if err != nil {
   722  		return err
   723  	}
   724  
   725  	txn, err := NewTxn(eg, proc, ctx)
   726  	if err != nil {
   727  		return err
   728  	}
   729  
   730  	var autoRel engine.Relation
   731  	// Essentially, temporary table is not an operation of a transaction.
   732  	// Therefore, it is not possible to fetch the temporary table through the function GetNewRelation
   733  	if dbName == defines.TEMPORARY_DBNAME {
   734  		autoRel, err = db.Relation(ctx, AUTO_INCR_TABLE)
   735  	} else {
   736  		autoRel, err = GetNewRelation(eg, dbName, AUTO_INCR_TABLE, txn, ctx)
   737  	}
   738  
   739  	if err != nil {
   740  		return err
   741  	}
   742  
   743  	newName := fmt.Sprintf("%d_", newId)
   744  	for _, def := range defs {
   745  		switch d := def.(type) {
   746  		case *engine.AttributeDef:
   747  			if !d.Attr.AutoIncrement {
   748  				continue
   749  			}
   750  
   751  			delName := fmt.Sprintf("%d_%s", oldTableID, d.Attr.Name)
   752  			bat, currentNum := GetDeleteBatch(autoRel, ctx, delName, proc.Mp())
   753  			if bat == nil {
   754  				return moerr.NewInternalError(ctx, "the deleted batch is nil")
   755  			}
   756  			if err = autoRel.Delete(ctx, bat, AUTO_INCR_TABLE_COLNAME[0]); err != nil {
   757  				if err2 := RolllbackTxn(eg, txn, ctx); err2 != nil {
   758  					return err2
   759  				}
   760  				return err
   761  			}
   762  
   763  			// Rename the old cache.
   764  			renameAutoIncrCache(delName, newName+d.Attr.Name, proc)
   765  
   766  			// In cache implementation no update needed.
   767  			currentNum = currentNum - 1
   768  
   769  			bat2 := makeAutoIncrBatch(newName+d.Attr.Name, currentNum-1, 1, proc.Mp())
   770  			if err = autoRel.Write(ctx, bat2); err != nil {
   771  				if err2 := RolllbackTxn(eg, txn, ctx); err2 != nil {
   772  					return err2
   773  				}
   774  				return err
   775  			}
   776  		}
   777  	}
   778  	if err = CommitTxn(eg, txn, ctx); err != nil {
   779  		return err
   780  	}
   781  	return nil
   782  }
   783  
   784  // for truncate table operation, reset col in mo_increment_columns table
   785  func ResetAutoInsrCol(eg engine.Engine, ctx context.Context, tblName string, db engine.Database, proc *process.Process, tableID, newId uint64, dbName string) error {
   786  	rel, err := db.Relation(ctx, tblName)
   787  	if err != nil {
   788  		return err
   789  	}
   790  	defs, err := rel.TableDefs(ctx)
   791  	if err != nil {
   792  		return err
   793  	}
   794  
   795  	txn, err := NewTxn(eg, proc, ctx)
   796  	if err != nil {
   797  		return err
   798  	}
   799  
   800  	var autoRel engine.Relation
   801  	// Essentially, temporary table is not an operation of a transaction.
   802  	// Therefore, it is not possible to fetch the temporary table through the function GetNewRelation
   803  	if dbName == defines.TEMPORARY_DBNAME {
   804  		autoRel, err = db.Relation(ctx, AUTO_INCR_TABLE)
   805  	} else {
   806  		autoRel, err = GetNewRelation(eg, dbName, AUTO_INCR_TABLE, txn, ctx)
   807  	}
   808  
   809  	if err != nil {
   810  		return err
   811  	}
   812  	name := fmt.Sprintf("%d_", newId)
   813  	for _, def := range defs {
   814  		switch d := def.(type) {
   815  		case *engine.AttributeDef:
   816  			if !d.Attr.AutoIncrement {
   817  				continue
   818  			}
   819  			delName := fmt.Sprintf("%d_%s", tableID, d.Attr.Name)
   820  			bat, _ := GetDeleteBatch(autoRel, ctx, delName, proc.Mp())
   821  			if bat == nil {
   822  				return moerr.NewInternalError(ctx, "the deleted batch is nil")
   823  			}
   824  			if err = autoRel.Delete(ctx, bat, AUTO_INCR_TABLE_COLNAME[0]); err != nil {
   825  				if err2 := RolllbackTxn(eg, txn, ctx); err2 != nil {
   826  					return err2
   827  				}
   828  				return err
   829  			}
   830  
   831  			// Delete the cache.
   832  			deleteAutoIncrCache(delName, proc)
   833  
   834  			bat2 := makeAutoIncrBatch(name+d.Attr.Name, 0, 1, proc.Mp())
   835  			if err = autoRel.Write(ctx, bat2); err != nil {
   836  				if err2 := RolllbackTxn(eg, txn, ctx); err2 != nil {
   837  					return err2
   838  				}
   839  				return err
   840  			}
   841  		}
   842  	}
   843  	if err = CommitTxn(eg, txn, ctx); err != nil {
   844  		return err
   845  	}
   846  	return nil
   847  }
   848  
   849  // func orderColDefs(attrs []string, ColDefs []*plan.ColDef, cols []*plan.Column) {
   850  // 	for i, name := range attrs {
   851  // 		for j, def := range ColDefs {
   852  // 			if name == def.Name {
   853  // 				ColDefs[i], ColDefs[j] = ColDefs[j], ColDefs[i]
   854  // 				cols[i], cols[j] = cols[j], cols[i]
   855  // 			}
   856  // 		}
   857  // 	}
   858  // }
   859  
   860  func NewTxn(eg engine.Engine, proc *process.Process, ctx context.Context) (txn client.TxnOperator, err error) {
   861  	if proc.TxnClient == nil {
   862  		return nil, moerr.NewInternalError(ctx, "must set txn client")
   863  	}
   864  	txn, err = proc.TxnClient.New()
   865  	if err != nil {
   866  		return nil, err
   867  	}
   868  	if ctx == nil {
   869  		return nil, moerr.NewInternalError(ctx, "context should not be nil")
   870  	}
   871  	if err = eg.New(ctx, txn); err != nil {
   872  		return nil, err
   873  	}
   874  	return txn, nil
   875  }
   876  
   877  func CommitTxn(eg engine.Engine, txn client.TxnOperator, ctx context.Context) error {
   878  	if txn == nil {
   879  		return nil
   880  	}
   881  	if ctx == nil {
   882  		return moerr.NewInternalError(ctx, "context should not be nil")
   883  	}
   884  	ctx, cancel := context.WithTimeout(
   885  		ctx,
   886  		eg.Hints().CommitOrRollbackTimeout,
   887  	)
   888  	defer cancel()
   889  	if err := eg.Commit(ctx, txn); err != nil {
   890  		if err2 := RolllbackTxn(eg, txn, ctx); err2 != nil {
   891  			logutil.Errorf("CommitTxn: txn operator rollback failed. error:%v", err2)
   892  		}
   893  		return err
   894  	}
   895  	err := txn.Commit(ctx)
   896  	txn = nil
   897  	return err
   898  }
   899  
   900  func RolllbackTxn(eg engine.Engine, txn client.TxnOperator, ctx context.Context) error {
   901  	if txn == nil {
   902  		return nil
   903  	}
   904  	if ctx == nil {
   905  		return moerr.NewInternalError(ctx, "context should not be nil")
   906  	}
   907  	ctx, cancel := context.WithTimeout(
   908  		ctx,
   909  		eg.Hints().CommitOrRollbackTimeout,
   910  	)
   911  	defer cancel()
   912  	if err := eg.Rollback(ctx, txn); err != nil {
   913  		return err
   914  	}
   915  	err := txn.Rollback(ctx)
   916  	txn = nil
   917  	return err
   918  }
   919  
   920  func GetNewRelation(eg engine.Engine, dbName, tbleName string, txn client.TxnOperator, ctx context.Context) (engine.Relation, error) {
   921  	dbHandler, err := eg.Database(ctx, dbName, txn)
   922  	if err != nil {
   923  		return nil, err
   924  	}
   925  	tableHandler, err := dbHandler.Relation(ctx, tbleName)
   926  	if err != nil {
   927  		return nil, err
   928  	}
   929  	return tableHandler, nil
   930  }
   931  
   932  func getAutoIncrTableDef() []engine.TableDef {
   933  	/*
   934  		mo_increment_columns schema
   935  		| Attribute |     Type     | Primary Key |             Note         |
   936  		| -------   | ------------ | ----------- | ------------------------ |
   937  		|   name    | varchar(770) |             | Name of the db_table_col |
   938  		|  offset   |    uint64     |             |   current index number   |
   939  		|   step    |    uint64     |             |   every increase step    |
   940  	*/
   941  
   942  	nameAttr := &engine.AttributeDef{Attr: engine.Attribute{
   943  		Name:    AUTO_INCR_TABLE_COLNAME[1],
   944  		Alg:     0,
   945  		Type:    types.T_varchar.ToType(),
   946  		Default: &plan.Default{},
   947  		Primary: true,
   948  	}}
   949  
   950  	numAttr := &engine.AttributeDef{Attr: engine.Attribute{
   951  		Name:    AUTO_INCR_TABLE_COLNAME[2],
   952  		Alg:     0,
   953  		Type:    types.T_uint64.ToType(),
   954  		Default: &plan.Default{},
   955  		Primary: false,
   956  	}}
   957  
   958  	stepAttr := &engine.AttributeDef{Attr: engine.Attribute{
   959  		Name:    AUTO_INCR_TABLE_COLNAME[3],
   960  		Alg:     0,
   961  		Type:    types.T_uint64.ToType(),
   962  		Default: &plan.Default{},
   963  		Primary: false,
   964  	}}
   965  
   966  	defs := make([]engine.TableDef, 0, 3)
   967  	defs = append(defs, nameAttr)
   968  	defs = append(defs, numAttr)
   969  	defs = append(defs, stepAttr)
   970  
   971  	constrains := &engine.ConstraintDef{Cts: make([]engine.Constraint, 0)}
   972  	constrains.Cts = append(constrains.Cts, &engine.PrimaryKeyDef{
   973  		Pkey: &plan.PrimaryKeyDef{
   974  			Names:       []string{AUTO_INCR_TABLE_COLNAME[1]},
   975  			PkeyColName: AUTO_INCR_TABLE_COLNAME[1],
   976  		},
   977  	})
   978  	defs = append(defs, constrains)
   979  
   980  	return defs
   981  }