github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/disttae/util.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  package disttae
    15  
    16  import (
    17  	"bytes"
    18  	"context"
    19  	"encoding/binary"
    20  	"fmt"
    21  	"math"
    22  	"sort"
    23  	"strconv"
    24  	"strings"
    25  	"sync/atomic"
    26  
    27  	"github.com/matrixorigin/matrixone/pkg/vm/engine"
    28  
    29  	"github.com/matrixorigin/matrixone/pkg/catalog"
    30  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    31  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    32  	"github.com/matrixorigin/matrixone/pkg/container/hashtable"
    33  	"github.com/matrixorigin/matrixone/pkg/container/types"
    34  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    35  	"github.com/matrixorigin/matrixone/pkg/fileservice"
    36  	"github.com/matrixorigin/matrixone/pkg/objectio"
    37  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    38  	"github.com/matrixorigin/matrixone/pkg/sql/colexec"
    39  	plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan"
    40  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function"
    41  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/containers"
    42  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/dataio/blockio"
    43  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index"
    44  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    45  )
    46  
    47  const (
    48  	HASH_VALUE_FUN string = "hash_value"
    49  	MAX_RANGE_SIZE int64  = 200
    50  )
    51  
    52  func getIndexDataFromVec(idx uint16, vec *vector.Vector) (objectio.IndexData, objectio.IndexData, error) {
    53  	var bloomFilter, zoneMap objectio.IndexData
    54  
    55  	// get min/max from  vector
    56  	if vec.Length() > 0 {
    57  		cvec := containers.NewVectorWithSharedMemory(vec, true)
    58  
    59  		// create zone map
    60  		zm := index.NewZoneMap(vec.Typ)
    61  		ctx := new(index.KeysCtx)
    62  		ctx.Keys = cvec
    63  		ctx.Count = vec.Length()
    64  		defer ctx.Keys.Close()
    65  		err := zm.BatchUpdate(ctx)
    66  		if err != nil {
    67  			return nil, nil, err
    68  		}
    69  		buf, err := zm.Marshal()
    70  		if err != nil {
    71  			return nil, nil, err
    72  		}
    73  		zoneMap, err = objectio.NewZoneMap(idx, buf)
    74  		if err != nil {
    75  			return nil, nil, err
    76  		}
    77  
    78  		// create bloomfilter
    79  		sf, err := index.NewBinaryFuseFilter(cvec)
    80  		if err != nil {
    81  			return nil, nil, err
    82  		}
    83  		bf, err := sf.Marshal()
    84  		if err != nil {
    85  			return nil, nil, err
    86  		}
    87  		alg := uint8(0)
    88  		bloomFilter = objectio.NewBloomFilter(idx, alg, bf)
    89  	}
    90  
    91  	return bloomFilter, zoneMap, nil
    92  }
    93  
    94  func GetTableMeta(ctx context.Context, tbl *table, expr *plan.Expr) error {
    95  	priKeys := make([]*engine.Attribute, 0, 1)
    96  	if tbl.primaryIdx >= 0 {
    97  		for _, def := range tbl.defs {
    98  			if attr, ok := def.(*engine.AttributeDef); ok {
    99  				if attr.Attr.Primary {
   100  					priKeys = append(priKeys, &attr.Attr)
   101  				}
   102  			}
   103  		}
   104  	}
   105  	dnList := needSyncDnStores(ctx, expr, tbl.tableDef, priKeys,
   106  		tbl.db.txn.dnStores, tbl.db.txn.proc)
   107  	switch {
   108  	case tbl.tableId == catalog.MO_DATABASE_ID:
   109  		tbl.dnList = []int{0}
   110  	case tbl.tableId == catalog.MO_TABLES_ID:
   111  		tbl.dnList = []int{0}
   112  	case tbl.tableId == catalog.MO_COLUMNS_ID:
   113  		tbl.dnList = []int{0}
   114  	default:
   115  		tbl.dnList = dnList
   116  	}
   117  	_, created := tbl.db.txn.createMap.Load(genTableKey(ctx, tbl.tableName, tbl.db.databaseId))
   118  	if !created && !tbl.updated {
   119  		if err := tbl.db.txn.db.Update(ctx, tbl.db.txn.dnStores[:1], tbl, tbl.db.txn.op, tbl.primaryIdx,
   120  			tbl.db.databaseId, tbl.tableId, tbl.db.txn.meta.SnapshotTS); err != nil {
   121  			return err
   122  		}
   123  		columnLength := len(tbl.tableDef.Cols) - 1 //we use this data to fetch zonemap, but row_id has no zonemap
   124  		meta, err := tbl.db.txn.getTableMeta(ctx, tbl.db.databaseId, genMetaTableName(tbl.tableId), true, columnLength, false)
   125  		if err != nil {
   126  			return err
   127  		}
   128  		tbl.meta = meta
   129  		tbl.updated = true
   130  	}
   131  	return nil
   132  }
   133  
   134  func fetchZonemapAndRowsFromBlockInfo(
   135  	ctx context.Context,
   136  	idxs []uint16,
   137  	blockInfo catalog.BlockInfo,
   138  	fs fileservice.FileService,
   139  	m *mpool.MPool) ([][64]byte, uint32, error) {
   140  	name, extent, rows := blockio.DecodeMetaLoc(blockInfo.MetaLoc)
   141  	zonemapList := make([][64]byte, len(idxs))
   142  
   143  	// raed s3
   144  	reader, err := objectio.NewObjectReader(name, fs)
   145  	if err != nil {
   146  		return nil, 0, err
   147  	}
   148  
   149  	obs, err := reader.ReadMeta(ctx, []objectio.Extent{extent}, m)
   150  	if err != nil {
   151  		return nil, 0, err
   152  	}
   153  
   154  	for i, idx := range idxs {
   155  		column, err := obs[0].GetColumn(idx)
   156  		if err != nil {
   157  			return nil, 0, err
   158  		}
   159  		data, err := column.GetIndex(ctx, objectio.ZoneMapType, m)
   160  		if err != nil {
   161  			return nil, 0, err
   162  		}
   163  		bytes := data.(*objectio.ZoneMap).GetData()
   164  		copy(zonemapList[i][:], bytes[:])
   165  	}
   166  
   167  	return zonemapList, rows, nil
   168  }
   169  
   170  func getZonemapDataFromMeta(ctx context.Context, columns []int, meta BlockMeta, tableDef *plan.TableDef) ([][2]any, []uint8, error) {
   171  	dataLength := len(columns)
   172  	datas := make([][2]any, dataLength)
   173  	dataTypes := make([]uint8, dataLength)
   174  
   175  	for i := 0; i < dataLength; i++ {
   176  		idx := columns[i]
   177  		dataTypes[i] = uint8(tableDef.Cols[idx].Typ.Id)
   178  		typ := types.T(dataTypes[i]).ToType()
   179  
   180  		zm := index.NewZoneMap(typ)
   181  		err := zm.Unmarshal(meta.Zonemap[idx][:])
   182  		if err != nil {
   183  			return nil, nil, err
   184  		}
   185  
   186  		min := zm.GetMin()
   187  		max := zm.GetMax()
   188  		if min == nil || max == nil {
   189  			return nil, nil, nil
   190  		}
   191  		datas[i] = [2]any{min, max}
   192  	}
   193  
   194  	return datas, dataTypes, nil
   195  }
   196  
   197  // getNewBlockName Each time a unique name is generated in one CN
   198  func getNewBlockName(accountId uint32) (string, error) {
   199  	uuid, err := types.BuildUuid()
   200  	if err != nil {
   201  		return "", err
   202  	}
   203  	return fmt.Sprintf("%d_%s.blk", accountId, uuid.ToString()), nil
   204  }
   205  
   206  func getConstantExprHashValue(ctx context.Context, constExpr *plan.Expr, proc *process.Process) (bool, uint64) {
   207  	args := []*plan.Expr{constExpr}
   208  	argTypes := []types.Type{types.T(constExpr.Typ.Id).ToType()}
   209  	funId, returnType, _, _ := function.GetFunctionByName(ctx, HASH_VALUE_FUN, argTypes)
   210  	funExpr := &plan.Expr{
   211  		Typ: plan2.MakePlan2Type(&returnType),
   212  		Expr: &plan.Expr_F{
   213  			F: &plan.Function{
   214  				Func: &plan.ObjectRef{
   215  					Obj:     funId,
   216  					ObjName: HASH_VALUE_FUN,
   217  				},
   218  				Args: args,
   219  			},
   220  		},
   221  	}
   222  
   223  	bat := batch.NewWithSize(0)
   224  	bat.Zs = []int64{1}
   225  	ret, err := colexec.EvalExpr(bat, proc, funExpr)
   226  	if err != nil {
   227  		return false, 0
   228  	}
   229  	list := vector.MustTCols[int64](ret)
   230  	return true, uint64(list[0])
   231  }
   232  
   233  func compPkCol(colName string, pkName string) bool {
   234  	dotIdx := strings.Index(colName, ".")
   235  	colName = colName[dotIdx+1:]
   236  	return colName == pkName
   237  }
   238  
   239  func getPkExpr(expr *plan.Expr, pkName string) (bool, *plan.Expr) {
   240  	switch exprImpl := expr.Expr.(type) {
   241  	case *plan.Expr_F:
   242  		funName := exprImpl.F.Func.ObjName
   243  		switch funName {
   244  		case "and":
   245  			canCompute, pkBytes := getPkExpr(exprImpl.F.Args[0], pkName)
   246  			if canCompute {
   247  				return canCompute, pkBytes
   248  			}
   249  			return getPkExpr(exprImpl.F.Args[1], pkName)
   250  
   251  		case "=":
   252  			switch leftExpr := exprImpl.F.Args[0].Expr.(type) {
   253  			case *plan.Expr_C:
   254  				if rightExpr, ok := exprImpl.F.Args[1].Expr.(*plan.Expr_Col); ok {
   255  					if compPkCol(rightExpr.Col.Name, pkName) {
   256  						return true, exprImpl.F.Args[0]
   257  					}
   258  				}
   259  
   260  			case *plan.Expr_Col:
   261  				if compPkCol(leftExpr.Col.Name, pkName) {
   262  					if _, ok := exprImpl.F.Args[1].Expr.(*plan.Expr_C); ok {
   263  						return true, exprImpl.F.Args[1]
   264  					}
   265  				}
   266  			}
   267  
   268  			return false, nil
   269  
   270  		default:
   271  			return false, nil
   272  		}
   273  	}
   274  
   275  	return false, nil
   276  }
   277  
   278  func getPkValueByExpr(expr *plan.Expr, pkName string, oid types.T) (bool, any) {
   279  	canCompute, valExpr := getPkExpr(expr, pkName)
   280  	if !canCompute {
   281  		return canCompute, nil
   282  	}
   283  	switch val := valExpr.Expr.(*plan.Expr_C).C.Value.(type) {
   284  	case *plan.Const_I8Val:
   285  		return transferIval(val.I8Val, oid)
   286  	case *plan.Const_I16Val:
   287  		return transferIval(val.I16Val, oid)
   288  	case *plan.Const_I32Val:
   289  		return transferIval(val.I32Val, oid)
   290  	case *plan.Const_I64Val:
   291  		return transferIval(val.I64Val, oid)
   292  	case *plan.Const_Dval:
   293  		return transferDval(val.Dval, oid)
   294  	case *plan.Const_Sval:
   295  		return transferSval(val.Sval, oid)
   296  	case *plan.Const_Bval:
   297  		return transferBval(val.Bval, oid)
   298  	case *plan.Const_U8Val:
   299  		return transferUval(val.U8Val, oid)
   300  	case *plan.Const_U16Val:
   301  		return transferUval(val.U16Val, oid)
   302  	case *plan.Const_U32Val:
   303  		return transferUval(val.U32Val, oid)
   304  	case *plan.Const_U64Val:
   305  		return transferUval(val.U64Val, oid)
   306  	case *plan.Const_Fval:
   307  		return transferFval(val.Fval, oid)
   308  	case *plan.Const_Dateval:
   309  		return transferDateval(val.Dateval, oid)
   310  	case *plan.Const_Timeval:
   311  		return transferTimeval(val.Timeval, oid)
   312  	case *plan.Const_Datetimeval:
   313  		return transferDatetimeval(val.Datetimeval, oid)
   314  	case *plan.Const_Decimal64Val:
   315  		return transferDecimal64val(val.Decimal64Val.A, oid)
   316  	case *plan.Const_Decimal128Val:
   317  		return transferDecimal128val(val.Decimal128Val.A, val.Decimal128Val.B, oid)
   318  	case *plan.Const_Timestampval:
   319  		return transferTimestampval(val.Timestampval, oid)
   320  	case *plan.Const_Jsonval:
   321  		return transferSval(val.Jsonval, oid)
   322  	}
   323  	return false, nil
   324  }
   325  
   326  // computeRangeByNonIntPk compute NonIntPk range Expr
   327  // only support function :["and", "="]
   328  // support eg: pk="a",  pk="a" and noPk > 200
   329  // unsupport eg: pk>"a", pk=otherFun("a"),  pk="a" or noPk > 200,
   330  func computeRangeByNonIntPk(ctx context.Context, expr *plan.Expr, pkName string, proc *process.Process) (bool, uint64) {
   331  	canCompute, valExpr := getPkExpr(expr, pkName)
   332  	if !canCompute {
   333  		return canCompute, 0
   334  	}
   335  	ok, pkHashValue := getConstantExprHashValue(ctx, valExpr, proc)
   336  	if !ok {
   337  		return false, 0
   338  	}
   339  	return true, pkHashValue
   340  }
   341  
   342  // computeRangeByIntPk compute primaryKey range by Expr
   343  // only under the following conditions:
   344  // 1、function named ["and", "or", ">", "<", ">=", "<=", "="]
   345  // 2、if function name is not "and", "or".  then one arg is column, the other is constant
   346  func computeRangeByIntPk(expr *plan.Expr, pkName string, parentFun string) (bool, *pkRange) {
   347  	type argType int
   348  	var typeConstant argType = 0
   349  	var typeColumn argType = 1
   350  	var leftArg argType
   351  	var leftConstant, rightConstat int64
   352  	var ok bool
   353  
   354  	getConstant := func(e *plan.Expr_C) (bool, int64) {
   355  		switch val := e.C.Value.(type) {
   356  		case *plan.Const_I8Val:
   357  			return true, int64(val.I8Val)
   358  		case *plan.Const_I16Val:
   359  			return true, int64(val.I16Val)
   360  		case *plan.Const_I32Val:
   361  			return true, int64(val.I32Val)
   362  		case *plan.Const_I64Val:
   363  			return true, val.I64Val
   364  		case *plan.Const_U8Val:
   365  			return true, int64(val.U8Val)
   366  		case *plan.Const_U16Val:
   367  			return true, int64(val.U16Val)
   368  		case *plan.Const_U32Val:
   369  			return true, int64(val.U32Val)
   370  		case *plan.Const_U64Val:
   371  			if val.U64Val > uint64(math.MaxInt64) {
   372  				return false, 0
   373  			}
   374  			return true, int64(val.U64Val)
   375  		}
   376  		return false, 0
   377  	}
   378  
   379  	switch exprImpl := expr.Expr.(type) {
   380  	case *plan.Expr_F:
   381  		funName := exprImpl.F.Func.ObjName
   382  		switch funName {
   383  		case "and", "or":
   384  			canCompute, leftRange := computeRangeByIntPk(exprImpl.F.Args[0], pkName, funName)
   385  			if !canCompute {
   386  				return canCompute, nil
   387  			}
   388  
   389  			canCompute, rightRange := computeRangeByIntPk(exprImpl.F.Args[1], pkName, funName)
   390  			if !canCompute {
   391  				return canCompute, nil
   392  			}
   393  
   394  			if funName == "and" {
   395  				return _computeAnd(leftRange, rightRange)
   396  			} else {
   397  				return _computeOr(leftRange, rightRange)
   398  			}
   399  
   400  		case ">", "<", ">=", "<=", "=":
   401  			switch subExpr := exprImpl.F.Args[0].Expr.(type) {
   402  			case *plan.Expr_C:
   403  				ok, leftConstant = getConstant(subExpr)
   404  				if !ok {
   405  					return false, nil
   406  				}
   407  				leftArg = typeConstant
   408  
   409  			case *plan.Expr_Col:
   410  				if !compPkCol(subExpr.Col.Name, pkName) {
   411  					// if  pk > 10 and noPk < 10.  we just use pk > 10
   412  					if parentFun == "and" {
   413  						return true, &pkRange{
   414  							isRange: false,
   415  						}
   416  					}
   417  					// if pk > 10 or noPk < 10,   we use all list
   418  					return false, nil
   419  				}
   420  				leftArg = typeColumn
   421  
   422  			default:
   423  				return false, nil
   424  			}
   425  
   426  			switch subExpr := exprImpl.F.Args[1].Expr.(type) {
   427  			case *plan.Expr_C:
   428  				if leftArg == typeColumn {
   429  					ok, rightConstat = getConstant(subExpr)
   430  					if !ok {
   431  						return false, nil
   432  					}
   433  					switch funName {
   434  					case ">":
   435  						return true, &pkRange{
   436  							isRange: true,
   437  							ranges:  []int64{rightConstat + 1, math.MaxInt64},
   438  						}
   439  					case ">=":
   440  						return true, &pkRange{
   441  							isRange: true,
   442  							ranges:  []int64{rightConstat, math.MaxInt64},
   443  						}
   444  					case "<":
   445  						return true, &pkRange{
   446  							isRange: true,
   447  							ranges:  []int64{math.MinInt64, rightConstat - 1},
   448  						}
   449  					case "<=":
   450  						return true, &pkRange{
   451  							isRange: true,
   452  							ranges:  []int64{math.MinInt64, rightConstat},
   453  						}
   454  					case "=":
   455  						return true, &pkRange{
   456  							isRange: false,
   457  							items:   []int64{rightConstat},
   458  						}
   459  					}
   460  					return false, nil
   461  				}
   462  			case *plan.Expr_Col:
   463  				if !compPkCol(subExpr.Col.Name, pkName) {
   464  					// if  pk > 10 and noPk < 10.  we just use pk > 10
   465  					if parentFun == "and" {
   466  						return true, &pkRange{
   467  							isRange: false,
   468  						}
   469  					}
   470  					// if pk > 10 or noPk < 10,   we use all list
   471  					return false, nil
   472  				}
   473  
   474  				if leftArg == typeConstant {
   475  					switch funName {
   476  					case ">":
   477  						return true, &pkRange{
   478  							isRange: true,
   479  							ranges:  []int64{math.MinInt64, leftConstant - 1},
   480  						}
   481  					case ">=":
   482  						return true, &pkRange{
   483  							isRange: true,
   484  							ranges:  []int64{math.MinInt64, leftConstant},
   485  						}
   486  					case "<":
   487  						return true, &pkRange{
   488  							isRange: true,
   489  							ranges:  []int64{leftConstant + 1, math.MaxInt64},
   490  						}
   491  					case "<=":
   492  						return true, &pkRange{
   493  							isRange: true,
   494  							ranges:  []int64{leftConstant, math.MaxInt64},
   495  						}
   496  					case "=":
   497  						return true, &pkRange{
   498  							isRange: false,
   499  							items:   []int64{leftConstant},
   500  						}
   501  					}
   502  					return false, nil
   503  				}
   504  			}
   505  		}
   506  	}
   507  
   508  	return false, nil
   509  }
   510  
   511  func _computeOr(left *pkRange, right *pkRange) (bool, *pkRange) {
   512  	result := &pkRange{
   513  		isRange: false,
   514  		items:   []int64{},
   515  	}
   516  
   517  	compute := func(left []int64, right []int64) [][]int64 {
   518  		min := left[0]
   519  		max := left[1]
   520  		if min > right[1] {
   521  			// eg: a > 10 or a < 2
   522  			return [][]int64{left, right}
   523  		} else if max < right[0] {
   524  			// eg: a < 2 or a > 10
   525  			return [][]int64{left, right}
   526  		} else {
   527  			// eg: a > 2 or a < 10
   528  			// a > 2 or a > 10
   529  			// a > 2 or a = -2
   530  			if right[0] < min {
   531  				min = right[0]
   532  			}
   533  			if right[1] > max {
   534  				max = right[1]
   535  			}
   536  			return [][]int64{{min, max}}
   537  		}
   538  	}
   539  
   540  	if !left.isRange {
   541  		if !right.isRange {
   542  			result.items = append(left.items, right.items...)
   543  			return len(result.items) < int(MAX_RANGE_SIZE), result
   544  		} else {
   545  			r := right.ranges
   546  			if r[0] == math.MinInt64 || r[1] == math.MaxInt64 || r[1]-r[0] > MAX_RANGE_SIZE {
   547  				return false, nil
   548  			}
   549  			result.items = append(result.items, left.items...)
   550  			for i := right.ranges[0]; i <= right.ranges[1]; i++ {
   551  				result.items = append(result.items, i)
   552  			}
   553  			return len(result.items) < int(MAX_RANGE_SIZE), result
   554  		}
   555  	} else {
   556  		if !right.isRange {
   557  			r := left.ranges
   558  			if r[0] == math.MinInt64 || r[1] == math.MaxInt64 || r[1]-r[0] > MAX_RANGE_SIZE {
   559  				return false, nil
   560  			}
   561  			result.items = append(result.items, right.items...)
   562  			for i := left.ranges[0]; i <= left.ranges[1]; i++ {
   563  				result.items = append(result.items, i)
   564  			}
   565  			return len(result.items) < int(MAX_RANGE_SIZE), result
   566  		} else {
   567  			newRange := compute(left.ranges, right.ranges)
   568  			for _, r := range newRange {
   569  				if r[0] == math.MinInt64 || r[1] == math.MaxInt64 || r[1]-r[0] > MAX_RANGE_SIZE {
   570  					return false, nil
   571  				}
   572  				for i := r[0]; i <= r[1]; i++ {
   573  					result.items = append(result.items, i)
   574  				}
   575  			}
   576  			return len(result.items) < int(MAX_RANGE_SIZE), result
   577  		}
   578  	}
   579  }
   580  
   581  func _computeAnd(left *pkRange, right *pkRange) (bool, *pkRange) {
   582  	result := &pkRange{
   583  		isRange: false,
   584  		items:   []int64{},
   585  	}
   586  
   587  	compute := func(left []int64, right []int64) (bool, []int64) {
   588  		min := left[0]
   589  		max := left[1]
   590  
   591  		if min > right[1] {
   592  			// eg: a > 10 and a < 2
   593  			return false, left
   594  		} else if max < right[0] {
   595  			// eg: a < 2 and a > 10
   596  			return false, left
   597  		} else {
   598  			// eg: a > 2 and a < 10
   599  			// a > 2 and a > 10
   600  			// a > 2 and a = -2
   601  			if right[0] > min {
   602  				min = right[0]
   603  			}
   604  			if right[1] < max {
   605  				max = right[1]
   606  			}
   607  			return true, []int64{min, max}
   608  		}
   609  	}
   610  
   611  	if !left.isRange {
   612  		if !right.isRange {
   613  			result.items = append(left.items, right.items...)
   614  			return len(result.items) < int(MAX_RANGE_SIZE), result
   615  		} else {
   616  			r := right.ranges
   617  			if r[0] == math.MinInt64 || r[1] == math.MaxInt64 || r[1]-r[0] > MAX_RANGE_SIZE {
   618  				return false, nil
   619  			}
   620  			result.items = append(result.items, left.items...)
   621  			for i := right.ranges[0]; i <= right.ranges[1]; i++ {
   622  				result.items = append(result.items, i)
   623  			}
   624  			return len(result.items) < int(MAX_RANGE_SIZE), result
   625  		}
   626  	} else {
   627  		if !right.isRange {
   628  			r := left.ranges
   629  			if r[0] == math.MinInt64 || r[1] == math.MaxInt64 || r[1]-r[0] > MAX_RANGE_SIZE {
   630  				return false, nil
   631  			}
   632  			result.items = append(result.items, right.items...)
   633  			for i := left.ranges[0]; i <= left.ranges[1]; i++ {
   634  				result.items = append(result.items, i)
   635  			}
   636  			return len(result.items) < int(MAX_RANGE_SIZE), result
   637  		} else {
   638  			ok, r := compute(left.ranges, right.ranges)
   639  			if !ok {
   640  				return false, nil
   641  			}
   642  			if r[0] == math.MinInt64 || r[1] == math.MaxInt64 || r[1]-r[0] > MAX_RANGE_SIZE {
   643  				return false, nil
   644  			}
   645  			for i := r[0]; i <= r[1]; i++ {
   646  				result.items = append(result.items, i)
   647  			}
   648  			return len(result.items) < int(MAX_RANGE_SIZE), result
   649  		}
   650  	}
   651  }
   652  
   653  func getHashValue(buf []byte) uint64 {
   654  	buf = append([]byte{0}, buf...)
   655  	var states [3]uint64
   656  	if l := len(buf); l < 16 {
   657  		buf = append(buf, hashtable.StrKeyPadding[l:]...)
   658  	}
   659  	hashtable.BytesBatchGenHashStates(&buf, &states, 1)
   660  	return states[0]
   661  }
   662  
   663  func getListByItems[T DNStore](list []T, items []int64) []int {
   664  	fullList := func() []int {
   665  		dnList := make([]int, len(list))
   666  		for i := range list {
   667  			dnList[i] = i
   668  		}
   669  		return dnList
   670  	}
   671  
   672  	listLen := uint64(len(list))
   673  	if listLen == 1 {
   674  		return []int{0}
   675  	}
   676  
   677  	if len(items) == 0 || int64(len(items)) > MAX_RANGE_SIZE {
   678  		return fullList()
   679  	}
   680  
   681  	listMap := make(map[uint64]struct{})
   682  	for _, item := range items {
   683  		keys := make([]byte, 8)
   684  		binary.LittleEndian.PutUint64(keys, uint64(item))
   685  		val := getHashValue(keys)
   686  		modVal := val % listLen
   687  		listMap[modVal] = struct{}{}
   688  		if len(listMap) == int(listLen) {
   689  			return fullList()
   690  		}
   691  	}
   692  	dnList := make([]int, len(listMap))
   693  	i := 0
   694  	for idx := range listMap {
   695  		dnList[i] = int(idx)
   696  		i++
   697  	}
   698  	return dnList
   699  }
   700  
   701  // func getListByRange[T DNStore](list []T, pkRange [][2]int64) []int {
   702  // 	fullList := func() []int {
   703  // 		dnList := make([]int, len(list))
   704  // 		for i := range list {
   705  // 			dnList[i] = i
   706  // 		}
   707  // 		return dnList
   708  // 	}
   709  // 	listLen := uint64(len(list))
   710  // 	if listLen == 1 || len(pkRange) == 0 {
   711  // 		return []int{0}
   712  // 	}
   713  
   714  // 	listMap := make(map[uint64]struct{})
   715  // 	for _, r := range pkRange {
   716  // 		if r[1]-r[0] > MAX_RANGE_SIZE {
   717  // 			return fullList()
   718  // 		}
   719  // 		for i := r[0]; i <= r[1]; i++ {
   720  // 			keys := make([]byte, 8)
   721  // 			binary.LittleEndian.PutUint64(keys, uint64(i))
   722  // 			val := getHashValue(keys)
   723  // 			modVal := val % listLen
   724  // 			listMap[modVal] = struct{}{}
   725  // 			if len(listMap) == int(listLen) {
   726  // 				return fullList()
   727  // 			}
   728  // 		}
   729  // 	}
   730  // 	dnList := make([]int, len(listMap))
   731  // 	i := 0
   732  // 	for idx := range listMap {
   733  // 		dnList[i] = int(idx)
   734  // 		i++
   735  // 	}
   736  // 	return dnList
   737  // }
   738  
   739  func checkIfDataInBlock(data any, meta BlockMeta, colIdx int, typ types.Type) (bool, error) {
   740  	zm := index.NewZoneMap(typ)
   741  	err := zm.Unmarshal(meta.Zonemap[colIdx][:])
   742  	if err != nil {
   743  		return false, err
   744  	}
   745  	return zm.Contains(data), nil
   746  }
   747  
   748  func findRowByPkValue(vec *vector.Vector, v any) int {
   749  	switch vec.Typ.Oid {
   750  	case types.T_int8:
   751  		rows := vector.MustTCols[int8](vec)
   752  		val := v.(int8)
   753  		return sort.Search(vec.Length(), func(idx int) bool {
   754  			return rows[idx] >= val
   755  		})
   756  	case types.T_int16:
   757  		rows := vector.MustTCols[int16](vec)
   758  		val := v.(int16)
   759  		return sort.Search(vec.Length(), func(idx int) bool {
   760  			return rows[idx] >= val
   761  		})
   762  	case types.T_int32:
   763  		rows := vector.MustTCols[int32](vec)
   764  		val := v.(int32)
   765  		return sort.Search(vec.Length(), func(idx int) bool {
   766  			return rows[idx] >= val
   767  		})
   768  	case types.T_int64:
   769  		rows := vector.MustTCols[int64](vec)
   770  		val := v.(int64)
   771  		return sort.Search(vec.Length(), func(idx int) bool {
   772  			return rows[idx] >= val
   773  		})
   774  	case types.T_uint8:
   775  		rows := vector.MustTCols[uint8](vec)
   776  		val := v.(uint8)
   777  		return sort.Search(vec.Length(), func(idx int) bool {
   778  			return rows[idx] >= val
   779  		})
   780  	case types.T_uint16:
   781  		rows := vector.MustTCols[uint16](vec)
   782  		val := v.(uint16)
   783  		return sort.Search(vec.Length(), func(idx int) bool {
   784  			return rows[idx] >= val
   785  		})
   786  	case types.T_uint32:
   787  		rows := vector.MustTCols[uint32](vec)
   788  		val := v.(uint32)
   789  		return sort.Search(vec.Length(), func(idx int) bool {
   790  			return rows[idx] >= val
   791  		})
   792  	case types.T_uint64:
   793  		rows := vector.MustTCols[uint64](vec)
   794  		val := v.(uint64)
   795  		return sort.Search(vec.Length(), func(idx int) bool {
   796  			return rows[idx] >= val
   797  		})
   798  	case types.T_float32:
   799  		rows := vector.MustTCols[float32](vec)
   800  		val := v.(float32)
   801  		return sort.Search(vec.Length(), func(idx int) bool {
   802  			return rows[idx] >= val
   803  		})
   804  	case types.T_float64:
   805  		rows := vector.MustTCols[float64](vec)
   806  		val := v.(float64)
   807  		return sort.Search(vec.Length(), func(idx int) bool {
   808  			return rows[idx] >= val
   809  		})
   810  	case types.T_date:
   811  		rows := vector.MustTCols[types.Date](vec)
   812  		val := v.(types.Date)
   813  		return sort.Search(vec.Length(), func(idx int) bool {
   814  			return rows[idx] >= val
   815  		})
   816  	case types.T_time:
   817  		rows := vector.MustTCols[types.Time](vec)
   818  		val := v.(types.Time)
   819  		return sort.Search(vec.Length(), func(idx int) bool {
   820  			return rows[idx] >= val
   821  		})
   822  	case types.T_datetime:
   823  		rows := vector.MustTCols[types.Datetime](vec)
   824  		val := v.(types.Datetime)
   825  		return sort.Search(vec.Length(), func(idx int) bool {
   826  			return rows[idx] >= val
   827  		})
   828  	case types.T_timestamp:
   829  		rows := vector.MustTCols[types.Timestamp](vec)
   830  		val := v.(types.Timestamp)
   831  		return sort.Search(vec.Length(), func(idx int) bool {
   832  			return rows[idx] >= val
   833  		})
   834  	case types.T_uuid:
   835  		rows := vector.MustTCols[types.Uuid](vec)
   836  		val := v.(types.Uuid)
   837  		return sort.Search(vec.Length(), func(idx int) bool {
   838  			return rows[idx].Ge(val)
   839  		})
   840  	case types.T_decimal64:
   841  		rows := vector.MustTCols[types.Decimal64](vec)
   842  		val := v.(types.Decimal64)
   843  		return sort.Search(vec.Length(), func(idx int) bool {
   844  			return rows[idx].Ge(val)
   845  		})
   846  	case types.T_decimal128:
   847  		rows := vector.MustTCols[types.Decimal128](vec)
   848  		val := v.(types.Decimal128)
   849  		return sort.Search(vec.Length(), func(idx int) bool {
   850  			return rows[idx].Ge(val)
   851  		})
   852  	case types.T_char, types.T_text, types.T_varchar, types.T_json, types.T_blob:
   853  		// rows := vector.MustStrCols(vec)
   854  		// val := string(v.([]byte))
   855  		// return sort.SearchStrings(rows, val)
   856  		val := v.([]byte)
   857  		area := vec.GetArea()
   858  		varlenas := vector.MustTCols[types.Varlena](vec)
   859  		return sort.Search(vec.Length(), func(idx int) bool {
   860  			colVal := varlenas[idx].GetByteSlice(area)
   861  			return bytes.Compare(colVal, val) >= 0
   862  		})
   863  	}
   864  
   865  	return -1
   866  }
   867  
   868  var nextMemTableTransactionID = int64(1024)
   869  
   870  func newMemTableTransactionID() string {
   871  	return strconv.FormatInt(
   872  		atomic.AddInt64(&nextMemTableTransactionID, 1),
   873  		32,
   874  	)
   875  }