github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/disttae/util_test.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 disttae
    16  
    17  import (
    18  	"bytes"
    19  	"context"
    20  	"testing"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/catalog"
    23  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    26  	plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan"
    27  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function"
    28  	"github.com/matrixorigin/matrixone/pkg/testutil"
    29  	"github.com/matrixorigin/matrixone/pkg/vm/engine/tae/index"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func makeColExprForTest(idx int32, typ types.T) *plan.Expr {
    34  	schema := []string{"a", "b", "c", "d"}
    35  	containerType := typ.ToType()
    36  	exprType := plan2.MakePlan2Type(&containerType)
    37  
    38  	return &plan.Expr{
    39  		Typ: exprType,
    40  		Expr: &plan.Expr_Col{
    41  			Col: &plan.ColRef{
    42  				RelPos: 0,
    43  				ColPos: idx,
    44  				Name:   schema[idx],
    45  			},
    46  		},
    47  	}
    48  }
    49  
    50  func makeFunctionExprForTest(name string, args []*plan.Expr) *plan.Expr {
    51  	argTypes := make([]types.Type, len(args))
    52  	for i, arg := range args {
    53  		argTypes[i] = plan2.MakeTypeByPlan2Expr(arg)
    54  	}
    55  
    56  	funId, returnType, _, _ := function.GetFunctionByName(context.TODO(), name, argTypes)
    57  
    58  	return &plan.Expr{
    59  		Typ: plan2.MakePlan2Type(&returnType),
    60  		Expr: &plan.Expr_F{
    61  			F: &plan.Function{
    62  				Func: &plan.ObjectRef{
    63  					Obj:     funId,
    64  					ObjName: name,
    65  				},
    66  				Args: args,
    67  			},
    68  		},
    69  	}
    70  }
    71  
    72  func makeZonemapForTest(typ types.T, min any, max any) [64]byte {
    73  	zm := index.NewZoneMap(typ.ToType())
    74  	_ = zm.Update(min)
    75  	_ = zm.Update(max)
    76  	buf, _ := zm.Marshal()
    77  
    78  	var zmBuf [64]byte
    79  	copy(zmBuf[:], buf[:])
    80  	return zmBuf
    81  }
    82  
    83  func makeBlockMetaForTest() BlockMeta {
    84  	return BlockMeta{
    85  		Zonemap: [][64]byte{
    86  			makeZonemapForTest(types.T_int64, int64(10), int64(100)),
    87  			makeZonemapForTest(types.T_int64, int64(20), int64(200)),
    88  			makeZonemapForTest(types.T_int64, int64(30), int64(300)),
    89  			makeZonemapForTest(types.T_int64, int64(1), int64(8)),
    90  		},
    91  	}
    92  }
    93  
    94  func getTableDefBySchemaAndType(name string, columns []string, schema []string, types []types.Type) *plan.TableDef {
    95  	columnsMap := make(map[string]struct{})
    96  	for _, col := range columns {
    97  		columnsMap[col] = struct{}{}
    98  	}
    99  
   100  	var cols []*plan.ColDef
   101  	nameToIndex := make(map[string]int32)
   102  
   103  	for i, col := range schema {
   104  		if _, ok := columnsMap[col]; ok {
   105  			cols = append(cols, &plan.ColDef{
   106  				Name: col,
   107  				Typ:  plan2.MakePlan2Type(&types[i]),
   108  			})
   109  		}
   110  		nameToIndex[col] = int32(i)
   111  	}
   112  
   113  	return &plan.TableDef{
   114  		Name:          name,
   115  		Cols:          cols,
   116  		Name2ColIndex: nameToIndex,
   117  	}
   118  }
   119  
   120  func makeTableDefForTest(columns []string) *plan.TableDef {
   121  	schema := []string{"a", "b", "c", "d"}
   122  	types := []types.Type{
   123  		types.T_int64.ToType(),
   124  		types.T_int64.ToType(),
   125  		types.T_int64.ToType(),
   126  		types.T_int64.ToType(),
   127  	}
   128  	return getTableDefBySchemaAndType("t1", columns, schema, types)
   129  }
   130  
   131  func TestBlockMetaMarshal(t *testing.T) {
   132  	meta := BlockMeta{
   133  		Info: catalog.BlockInfo{
   134  			MetaLoc: "test",
   135  		},
   136  		Zonemap: [][64]byte{
   137  			makeZonemapForTest(types.T_int64, int64(10), int64(100)),
   138  			makeZonemapForTest(types.T_blob, []byte("a"), []byte("h")),
   139  			// makeZonemapForTest(types.T_varchar, "a", "h"),
   140  		},
   141  	}
   142  	data := blockMarshal(meta)
   143  	meta0 := blockUnmarshal(data)
   144  	require.Equal(t, meta, meta0)
   145  }
   146  
   147  func TestCheckExprIsMonotonic(t *testing.T) {
   148  	type asserts = struct {
   149  		result bool
   150  		expr   *plan.Expr
   151  	}
   152  	testCases := []asserts{
   153  		// a > 1  -> true
   154  		{true, makeFunctionExprForTest(">", []*plan.Expr{
   155  			makeColExprForTest(0, types.T_int64),
   156  			plan2.MakePlan2Int64ConstExprWithType(10),
   157  		})},
   158  		// a >= b -> true
   159  		{true, makeFunctionExprForTest(">=", []*plan.Expr{
   160  			makeColExprForTest(0, types.T_int64),
   161  			makeColExprForTest(1, types.T_int64),
   162  		})},
   163  		// abs(a) -> false
   164  		{false, makeFunctionExprForTest("abs", []*plan.Expr{
   165  			makeColExprForTest(0, types.T_int64),
   166  		})},
   167  	}
   168  
   169  	t.Run("test checkExprIsMonotonic", func(t *testing.T) {
   170  		for i, testCase := range testCases {
   171  			isMonotonic := plan2.CheckExprIsMonotonic(context.TODO(), testCase.expr)
   172  			if isMonotonic != testCase.result {
   173  				t.Fatalf("checkExprIsMonotonic testExprs[%d] is different with expected", i)
   174  			}
   175  		}
   176  	})
   177  }
   178  
   179  // delete this if TestNeedRead is not skipped anymore
   180  func TestMakeBlockMeta(t *testing.T) {
   181  	_ = makeBlockMetaForTest()
   182  }
   183  
   184  func TestNeedRead(t *testing.T) {
   185  	t.Skip("NeedRead always returns true fot start cn-dn with flushing")
   186  	type asserts = struct {
   187  		result  bool
   188  		columns []string
   189  		expr    *plan.Expr
   190  	}
   191  	blockMeta := makeBlockMetaForTest()
   192  
   193  	testCases := []asserts{
   194  		{true, []string{"a"}, makeFunctionExprForTest(">", []*plan.Expr{
   195  			makeColExprForTest(0, types.T_int64),
   196  			plan2.MakePlan2Int64ConstExprWithType(20),
   197  		})},
   198  		{false, []string{"a"}, makeFunctionExprForTest("<", []*plan.Expr{
   199  			makeColExprForTest(0, types.T_int64),
   200  			plan2.MakePlan2Int64ConstExprWithType(-1),
   201  		})},
   202  		{false, []string{"a"}, makeFunctionExprForTest(">", []*plan.Expr{
   203  			makeColExprForTest(0, types.T_int64),
   204  			plan2.MakePlan2Int64ConstExprWithType(3000000),
   205  		})},
   206  		{false, []string{"a", "d"}, makeFunctionExprForTest("<", []*plan.Expr{
   207  			makeColExprForTest(0, types.T_int64),
   208  			makeColExprForTest(1, types.T_int64),
   209  		})},
   210  		{true, []string{"a", "d"}, makeFunctionExprForTest(">", []*plan.Expr{
   211  			makeColExprForTest(0, types.T_int64),
   212  			makeColExprForTest(1, types.T_int64),
   213  		})},
   214  		// c > (a + d) => true
   215  		{true, []string{"c", "a", "d"}, makeFunctionExprForTest(">", []*plan.Expr{
   216  			makeColExprForTest(0, types.T_int64),
   217  			makeFunctionExprForTest("+", []*plan.Expr{
   218  				makeColExprForTest(1, types.T_int64),
   219  				makeColExprForTest(2, types.T_int64),
   220  			}),
   221  		})},
   222  		// (a > b) and (c > d) => true
   223  		{true, []string{"a", "b", "c", "d"}, makeFunctionExprForTest("and", []*plan.Expr{
   224  			makeFunctionExprForTest(">", []*plan.Expr{
   225  				makeColExprForTest(0, types.T_int64),
   226  				makeColExprForTest(1, types.T_int64),
   227  			}),
   228  			makeFunctionExprForTest(">", []*plan.Expr{
   229  				makeColExprForTest(2, types.T_int64),
   230  				makeColExprForTest(3, types.T_int64),
   231  			}),
   232  		})},
   233  		{true, []string{"a"}, makeFunctionExprForTest("abs", []*plan.Expr{
   234  			makeColExprForTest(0, types.T_int64),
   235  		})},
   236  	}
   237  
   238  	t.Run("test needRead", func(t *testing.T) {
   239  		for i, testCase := range testCases {
   240  			columnMap, columns, maxCol := plan2.GetColumnsByExpr(testCase.expr, makeTableDefForTest(testCase.columns))
   241  			result := needRead(context.Background(), testCase.expr, blockMeta, makeTableDefForTest(testCase.columns), columnMap, columns, maxCol, testutil.NewProc())
   242  			if result != testCase.result {
   243  				t.Fatalf("test needRead at cases[%d], get result is different with expected", i)
   244  			}
   245  		}
   246  	})
   247  }
   248  
   249  func TestBlockWrite(t *testing.T) {
   250  	ctx := context.TODO()
   251  	testFs := testutil.NewFS()
   252  	inputBat := testutil.NewBatch([]types.Type{
   253  		types.T_int64.ToType(),
   254  		types.T_int64.ToType(),
   255  		types.T_int64.ToType(),
   256  		types.T_int64.ToType(),
   257  	}, true, 20, mpool.MustNewZero())
   258  
   259  	_, err := blockWrite(ctx, inputBat, testFs)
   260  	if err != nil {
   261  		t.Fatalf("err: %v", err)
   262  	}
   263  }
   264  
   265  func TestGetNonIntPkValueByExpr(t *testing.T) {
   266  	type asserts = struct {
   267  		result bool
   268  		data   any
   269  		expr   *plan.Expr
   270  		typ    types.T
   271  	}
   272  
   273  	testCases := []asserts{
   274  		// a > "a"  false   only 'and', '=' function is supported
   275  		{false, 0, makeFunctionExprForTest(">", []*plan.Expr{
   276  			makeColExprForTest(0, types.T_int64),
   277  			plan2.MakePlan2StringConstExprWithType("a"),
   278  		}), types.T_int64},
   279  		// a = 100  true
   280  		{true, int64(100),
   281  			makeFunctionExprForTest("=", []*plan.Expr{
   282  				makeColExprForTest(0, types.T_int64),
   283  				plan2.MakePlan2Int64ConstExprWithType(100),
   284  			}), types.T_int64},
   285  		// b > 10 and a = "abc"  true
   286  		{true, []byte("abc"),
   287  			makeFunctionExprForTest("and", []*plan.Expr{
   288  				makeFunctionExprForTest(">", []*plan.Expr{
   289  					makeColExprForTest(1, types.T_int64),
   290  					plan2.MakePlan2Int64ConstExprWithType(10),
   291  				}),
   292  				makeFunctionExprForTest("=", []*plan.Expr{
   293  					makeColExprForTest(0, types.T_int64),
   294  					plan2.MakePlan2StringConstExprWithType("abc"),
   295  				}),
   296  			}), types.T_char},
   297  	}
   298  
   299  	t.Run("test getPkValueByExpr", func(t *testing.T) {
   300  		for i, testCase := range testCases {
   301  			result, data := getPkValueByExpr(testCase.expr, "a", testCase.typ)
   302  			if result != testCase.result {
   303  				t.Fatalf("test getPkValueByExpr at cases[%d], get result is different with expected", i)
   304  			}
   305  			if result {
   306  				if a, ok := data.([]byte); ok {
   307  					b := testCase.data.([]byte)
   308  					if !bytes.Equal(a, b) {
   309  						t.Fatalf("test getPkValueByExpr at cases[%d], data is not match", i)
   310  					}
   311  				} else {
   312  					if data != testCase.data {
   313  						t.Fatalf("test getPkValueByExpr at cases[%d], data is not match", i)
   314  					}
   315  				}
   316  			}
   317  		}
   318  	})
   319  }
   320  
   321  func TestComputeRangeByNonIntPk(t *testing.T) {
   322  	type asserts = struct {
   323  		result bool
   324  		data   uint64
   325  		expr   *plan.Expr
   326  	}
   327  
   328  	getHash := func(e *plan.Expr) uint64 {
   329  		_, ret := getConstantExprHashValue(context.TODO(), e, testutil.NewProc())
   330  		return ret
   331  	}
   332  
   333  	testCases := []asserts{
   334  		// a > "a"  false   only 'and', '=' function is supported
   335  		{false, 0, makeFunctionExprForTest(">", []*plan.Expr{
   336  			makeColExprForTest(0, types.T_int64),
   337  			plan2.MakePlan2StringConstExprWithType("a"),
   338  		})},
   339  		// a > coalesce("a")  false,  the second arg must be constant
   340  		{false, 0, makeFunctionExprForTest(">", []*plan.Expr{
   341  			makeColExprForTest(0, types.T_int64),
   342  			makeFunctionExprForTest("coalesce", []*plan.Expr{
   343  				makeColExprForTest(0, types.T_int64),
   344  				plan2.MakePlan2StringConstExprWithType("a"),
   345  			}),
   346  		})},
   347  		// a = "abc"  true
   348  		{true, getHash(plan2.MakePlan2StringConstExprWithType("abc")),
   349  			makeFunctionExprForTest("=", []*plan.Expr{
   350  				makeColExprForTest(0, types.T_int64),
   351  				plan2.MakePlan2StringConstExprWithType("abc"),
   352  			})},
   353  		// a = "abc" and b > 10  true
   354  		{true, getHash(plan2.MakePlan2StringConstExprWithType("abc")),
   355  			makeFunctionExprForTest("and", []*plan.Expr{
   356  				makeFunctionExprForTest("=", []*plan.Expr{
   357  					makeColExprForTest(0, types.T_int64),
   358  					plan2.MakePlan2StringConstExprWithType("abc"),
   359  				}),
   360  				makeFunctionExprForTest(">", []*plan.Expr{
   361  					makeColExprForTest(1, types.T_int64),
   362  					plan2.MakePlan2Int64ConstExprWithType(10),
   363  				}),
   364  			})},
   365  		// b > 10 and a = "abc"  true
   366  		{true, getHash(plan2.MakePlan2StringConstExprWithType("abc")),
   367  			makeFunctionExprForTest("and", []*plan.Expr{
   368  				makeFunctionExprForTest(">", []*plan.Expr{
   369  					makeColExprForTest(1, types.T_int64),
   370  					plan2.MakePlan2Int64ConstExprWithType(10),
   371  				}),
   372  				makeFunctionExprForTest("=", []*plan.Expr{
   373  					makeColExprForTest(0, types.T_int64),
   374  					plan2.MakePlan2StringConstExprWithType("abc"),
   375  				}),
   376  			})},
   377  		// a = "abc" or b > 10  false
   378  		{false, 0,
   379  			makeFunctionExprForTest("or", []*plan.Expr{
   380  				makeFunctionExprForTest("=", []*plan.Expr{
   381  					makeColExprForTest(0, types.T_int64),
   382  					plan2.MakePlan2StringConstExprWithType("abc"),
   383  				}),
   384  				makeFunctionExprForTest(">", []*plan.Expr{
   385  					makeColExprForTest(1, types.T_int64),
   386  					plan2.MakePlan2Int64ConstExprWithType(10),
   387  				}),
   388  			})},
   389  		// a = "abc" or a > 10  false
   390  		{false, 0,
   391  			makeFunctionExprForTest("or", []*plan.Expr{
   392  				makeFunctionExprForTest("=", []*plan.Expr{
   393  					makeColExprForTest(0, types.T_int64),
   394  					plan2.MakePlan2StringConstExprWithType("abc"),
   395  				}),
   396  				makeFunctionExprForTest(">", []*plan.Expr{
   397  					makeColExprForTest(0, types.T_int64),
   398  					plan2.MakePlan2Int64ConstExprWithType(10),
   399  				}),
   400  			})},
   401  	}
   402  
   403  	t.Run("test computeRangeByNonIntPk", func(t *testing.T) {
   404  		for i, testCase := range testCases {
   405  			result, data := computeRangeByNonIntPk(context.TODO(), testCase.expr, "a", testutil.NewProc())
   406  			if result != testCase.result {
   407  				t.Fatalf("test computeRangeByNonIntPk at cases[%d], get result is different with expected", i)
   408  			}
   409  			if result {
   410  				if data != testCase.data {
   411  					t.Fatalf("test computeRangeByNonIntPk at cases[%d], data is not match", i)
   412  				}
   413  			}
   414  		}
   415  	})
   416  }
   417  
   418  func TestComputeRangeByIntPk(t *testing.T) {
   419  	type asserts = struct {
   420  		result bool
   421  		items  []int64
   422  		expr   *plan.Expr
   423  	}
   424  
   425  	testCases := []asserts{
   426  		// a > abs(20)   not support now
   427  		{false, []int64{21}, makeFunctionExprForTest("like", []*plan.Expr{
   428  			makeColExprForTest(0, types.T_int64),
   429  			makeFunctionExprForTest("abs", []*plan.Expr{
   430  				plan2.MakePlan2Int64ConstExprWithType(20),
   431  			}),
   432  		})},
   433  		// a > 20
   434  		{true, []int64{}, makeFunctionExprForTest(">", []*plan.Expr{
   435  			makeColExprForTest(0, types.T_int64),
   436  			plan2.MakePlan2Int64ConstExprWithType(20),
   437  		})},
   438  		// a > 20 and b < 1  is equal a > 20
   439  		{false, []int64{}, makeFunctionExprForTest("and", []*plan.Expr{
   440  			makeFunctionExprForTest(">", []*plan.Expr{
   441  				makeColExprForTest(0, types.T_int64),
   442  				plan2.MakePlan2Int64ConstExprWithType(20),
   443  			}),
   444  			makeFunctionExprForTest("<", []*plan.Expr{
   445  				makeColExprForTest(1, types.T_int64),
   446  				plan2.MakePlan2Int64ConstExprWithType(1),
   447  			}),
   448  		})},
   449  		// 1 < b and a > 20   is equal a > 20
   450  		{false, []int64{}, makeFunctionExprForTest("and", []*plan.Expr{
   451  			makeFunctionExprForTest("<", []*plan.Expr{
   452  				plan2.MakePlan2Int64ConstExprWithType(1),
   453  				makeColExprForTest(1, types.T_int64),
   454  			}),
   455  			makeFunctionExprForTest(">", []*plan.Expr{
   456  				makeColExprForTest(0, types.T_int64),
   457  				plan2.MakePlan2Int64ConstExprWithType(20),
   458  			}),
   459  		})},
   460  		// a > 20 or b < 1  false.
   461  		{false, []int64{}, makeFunctionExprForTest("or", []*plan.Expr{
   462  			makeFunctionExprForTest(">", []*plan.Expr{
   463  				makeColExprForTest(0, types.T_int64),
   464  				plan2.MakePlan2Int64ConstExprWithType(20),
   465  			}),
   466  			makeFunctionExprForTest("<", []*plan.Expr{
   467  				makeColExprForTest(1, types.T_int64),
   468  				plan2.MakePlan2Int64ConstExprWithType(1),
   469  			}),
   470  		})},
   471  		// a = 20
   472  		{true, []int64{20}, makeFunctionExprForTest("=", []*plan.Expr{
   473  			makeColExprForTest(0, types.T_int64),
   474  			plan2.MakePlan2Int64ConstExprWithType(20),
   475  		})},
   476  		// a > 20 and a < =25
   477  		{true, []int64{21, 22, 23, 24, 25}, makeFunctionExprForTest("and", []*plan.Expr{
   478  			makeFunctionExprForTest(">", []*plan.Expr{
   479  				makeColExprForTest(0, types.T_int64),
   480  				plan2.MakePlan2Int64ConstExprWithType(20),
   481  			}),
   482  			makeFunctionExprForTest("<=", []*plan.Expr{
   483  				makeColExprForTest(0, types.T_int64),
   484  				plan2.MakePlan2Int64ConstExprWithType(25),
   485  			}),
   486  		})},
   487  		// a > 20 and a <=25 and b > 100   todo: unsupport now。  when compute a <=25 and b > 10, we get items too much.
   488  		{false, []int64{21, 22, 23, 24, 25}, makeFunctionExprForTest("and", []*plan.Expr{
   489  			makeFunctionExprForTest(">", []*plan.Expr{
   490  				makeColExprForTest(0, types.T_int64),
   491  				plan2.MakePlan2Int64ConstExprWithType(20),
   492  			}),
   493  			makeFunctionExprForTest("and", []*plan.Expr{
   494  				makeFunctionExprForTest("<=", []*plan.Expr{
   495  					makeColExprForTest(0, types.T_int64),
   496  					plan2.MakePlan2Int64ConstExprWithType(25),
   497  				}),
   498  				makeFunctionExprForTest(">", []*plan.Expr{
   499  					makeColExprForTest(1, types.T_int64),
   500  					plan2.MakePlan2Int64ConstExprWithType(100),
   501  				}),
   502  			}),
   503  		})},
   504  		// a > 20 and a < 10  => empty
   505  		{false, []int64{}, makeFunctionExprForTest("and", []*plan.Expr{
   506  			makeFunctionExprForTest(">", []*plan.Expr{
   507  				makeColExprForTest(0, types.T_int64),
   508  				plan2.MakePlan2Int64ConstExprWithType(20),
   509  			}),
   510  			makeFunctionExprForTest("<", []*plan.Expr{
   511  				makeColExprForTest(0, types.T_int64),
   512  				plan2.MakePlan2Int64ConstExprWithType(10),
   513  			}),
   514  		})},
   515  		// a < 20 or 100 < a
   516  		{false, []int64{}, makeFunctionExprForTest("or", []*plan.Expr{
   517  			makeFunctionExprForTest("<", []*plan.Expr{
   518  				makeColExprForTest(0, types.T_int64),
   519  				plan2.MakePlan2Int64ConstExprWithType(20),
   520  			}),
   521  			makeFunctionExprForTest("<", []*plan.Expr{
   522  				plan2.MakePlan2Int64ConstExprWithType(100),
   523  				makeColExprForTest(0, types.T_int64),
   524  			}),
   525  		})},
   526  		// a =1 or a = 2 or a=30
   527  		{true, []int64{2, 1, 30}, makeFunctionExprForTest("or", []*plan.Expr{
   528  			makeFunctionExprForTest("=", []*plan.Expr{
   529  				makeColExprForTest(0, types.T_int64),
   530  				plan2.MakePlan2Int64ConstExprWithType(2),
   531  			}),
   532  			makeFunctionExprForTest("or", []*plan.Expr{
   533  				makeFunctionExprForTest("=", []*plan.Expr{
   534  					makeColExprForTest(0, types.T_int64),
   535  					plan2.MakePlan2Int64ConstExprWithType(1),
   536  				}),
   537  				makeFunctionExprForTest("=", []*plan.Expr{
   538  					makeColExprForTest(0, types.T_int64),
   539  					plan2.MakePlan2Int64ConstExprWithType(30),
   540  				}),
   541  			}),
   542  		})},
   543  		// (a >5 or a=1) and (a < 8 or a =11) => 1,6,7,11  todo,  now can't compute now
   544  		{false, []int64{6, 7, 11, 1}, makeFunctionExprForTest("and", []*plan.Expr{
   545  			makeFunctionExprForTest("or", []*plan.Expr{
   546  				makeFunctionExprForTest(">", []*plan.Expr{
   547  					makeColExprForTest(0, types.T_int64),
   548  					plan2.MakePlan2Int64ConstExprWithType(5),
   549  				}),
   550  				makeFunctionExprForTest("=", []*plan.Expr{
   551  					makeColExprForTest(0, types.T_int64),
   552  					plan2.MakePlan2Int64ConstExprWithType(1),
   553  				}),
   554  			}),
   555  			makeFunctionExprForTest("or", []*plan.Expr{
   556  				makeFunctionExprForTest("<", []*plan.Expr{
   557  					makeColExprForTest(0, types.T_int64),
   558  					plan2.MakePlan2Int64ConstExprWithType(8),
   559  				}),
   560  				makeFunctionExprForTest("=", []*plan.Expr{
   561  					makeColExprForTest(0, types.T_int64),
   562  					plan2.MakePlan2Int64ConstExprWithType(11),
   563  				}),
   564  			}),
   565  		})},
   566  	}
   567  
   568  	t.Run("test computeRangeByIntPk", func(t *testing.T) {
   569  		for i, testCase := range testCases {
   570  			result, data := computeRangeByIntPk(testCase.expr, "a", "")
   571  			if result != testCase.result {
   572  				t.Fatalf("test computeRangeByIntPk at cases[%d], get result is different with expected", i)
   573  			}
   574  			if result {
   575  				if len(data.items) != len(testCase.items) {
   576  					t.Fatalf("test computeRangeByIntPk at cases[%d], data length is not match", i)
   577  				}
   578  				for j, val := range testCase.items {
   579  					if data.items[j] != val {
   580  						t.Fatalf("test computeRangeByIntPk at cases[%d], data[%d] is not match", i, j)
   581  					}
   582  				}
   583  			}
   584  		}
   585  	})
   586  }
   587  
   588  // func TestGetListByRange(t *testing.T) {
   589  // 	type asserts = struct {
   590  // 		result []DNStore
   591  // 		list   []DNStore
   592  // 		r      [][2]int64
   593  // 	}
   594  
   595  // 	testCases := []asserts{
   596  // 		{[]DNStore{{UUID: "1"}, {UUID: "2"}}, []DNStore{{UUID: "1"}, {UUID: "2"}}, [][2]int64{{14, 32324234234234}}},
   597  // 		{[]DNStore{{UUID: "1"}}, []DNStore{{UUID: "1"}, {UUID: "2"}}, [][2]int64{{14, 14}}},
   598  // 	}
   599  
   600  // 	t.Run("test getListByRange", func(t *testing.T) {
   601  // 		for i, testCase := range testCases {
   602  // 			result := getListByRange(testCase.list, testCase.r)
   603  // 			if len(result) != len(testCase.result) {
   604  // 				t.Fatalf("test getListByRange at cases[%d], data length is not match", i)
   605  // 			}
   606  // 			/*
   607  // 				for j, r := range testCase.result {
   608  // 					if r.UUID != result[j].UUID {
   609  // 						t.Fatalf("test getListByRange at cases[%d], result[%d] is not match", i, j)
   610  // 					}
   611  // 				}
   612  // 			*/
   613  // 		}
   614  // 	})
   615  // }
   616  
   617  func TestCheckIfDataInBlock(t *testing.T) {
   618  	meta := BlockMeta{
   619  		Zonemap: [][64]byte{
   620  			makeZonemapForTest(types.T_int64, int64(10), int64(100)),
   621  			makeZonemapForTest(types.T_blob, []byte("a"), []byte("h")),
   622  			// makeZonemapForTest(types.T_varchar, "a", "h"),
   623  		},
   624  	}
   625  
   626  	type asserts = struct {
   627  		result bool
   628  		data   any
   629  		colIdx int
   630  		typ    types.Type
   631  	}
   632  
   633  	testCases := []asserts{
   634  		{true, int64(12), 0, types.T_int64.ToType()},   // 12 in [10, 100]
   635  		{false, int64(120), 0, types.T_int64.ToType()}, // 120 not in [10, 100]
   636  		{true, []byte("b"), 1, types.T_blob.ToType()},  // "b" in ["a", "h"]
   637  		{false, []byte("i"), 1, types.T_blob.ToType()}, // "i" not in ["a", "h"]
   638  	}
   639  
   640  	t.Run("test checkIfDataInBlock", func(t *testing.T) {
   641  		for i, testCase := range testCases {
   642  			result, _ := checkIfDataInBlock(testCase.data, meta, testCase.colIdx, testCase.typ)
   643  			if result != testCase.result {
   644  				t.Fatalf("test checkIfDataInBlock at cases[%d], result is not match", i)
   645  			}
   646  		}
   647  	})
   648  }