github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/constant_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"fmt"
    18  	"sort"
    19  	"strings"
    20  	"time"
    21  
    22  	. "github.com/whtcorpsinc/check"
    23  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    24  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    25  	"github.com/whtcorpsinc/milevadb/types"
    26  	"github.com/whtcorpsinc/milevadb/types/json"
    27  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    28  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    29  )
    30  
    31  var _ = Suite(&testExpressionSuite{})
    32  
    33  type testExpressionSuite struct{}
    34  
    35  func newDeferredCauset(id int) *DeferredCauset {
    36  	return newDeferredCausetWithType(id, types.NewFieldType(allegrosql.TypeLonglong))
    37  }
    38  
    39  func newDeferredCausetWithType(id int, t *types.FieldType) *DeferredCauset {
    40  	return &DeferredCauset{
    41  		UniqueID: int64(id),
    42  		RetType:  t,
    43  	}
    44  }
    45  
    46  func newLonglong(value int64) *Constant {
    47  	return &Constant{
    48  		Value:   types.NewIntCauset(value),
    49  		RetType: types.NewFieldType(allegrosql.TypeLonglong),
    50  	}
    51  }
    52  
    53  func newDate(year, month, day int) *Constant {
    54  	return newTimeConst(year, month, day, 0, 0, 0, allegrosql.TypeDate)
    55  }
    56  
    57  func newTimestamp(yy, mm, dd, hh, min, ss int) *Constant {
    58  	return newTimeConst(yy, mm, dd, hh, min, ss, allegrosql.TypeTimestamp)
    59  }
    60  
    61  func newTimeConst(yy, mm, dd, hh, min, ss int, tp uint8) *Constant {
    62  	var tmp types.Causet
    63  	tmp.SetMysqlTime(types.NewTime(types.FromDate(yy, mm, dd, 0, 0, 0, 0), tp, types.DefaultFsp))
    64  	return &Constant{
    65  		Value:   tmp,
    66  		RetType: types.NewFieldType(tp),
    67  	}
    68  }
    69  
    70  func newFunction(funcName string, args ...Expression) Expression {
    71  	typeLong := types.NewFieldType(allegrosql.TypeLonglong)
    72  	return NewFunctionInternal(mock.NewContext(), funcName, typeLong, args...)
    73  }
    74  
    75  func (*testExpressionSuite) TestConstantPropagation(c *C) {
    76  	tests := []struct {
    77  		solver     []PropagateConstantSolver
    78  		conditions []Expression
    79  		result     string
    80  	}{
    81  		{
    82  			solver: []PropagateConstantSolver{newPropConstSolver()},
    83  			conditions: []Expression{
    84  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
    85  				newFunction(ast.EQ, newDeferredCauset(1), newDeferredCauset(2)),
    86  				newFunction(ast.EQ, newDeferredCauset(2), newDeferredCauset(3)),
    87  				newFunction(ast.EQ, newDeferredCauset(3), newLonglong(1)),
    88  				newFunction(ast.LogicOr, newLonglong(1), newDeferredCauset(0)),
    89  			},
    90  			result: "1, eq(DeferredCauset#0, 1), eq(DeferredCauset#1, 1), eq(DeferredCauset#2, 1), eq(DeferredCauset#3, 1)",
    91  		},
    92  		{
    93  			solver: []PropagateConstantSolver{newPropConstSolver()},
    94  			conditions: []Expression{
    95  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
    96  				newFunction(ast.EQ, newDeferredCauset(1), newLonglong(1)),
    97  				newFunction(ast.NE, newDeferredCauset(2), newLonglong(2)),
    98  			},
    99  			result: "eq(DeferredCauset#0, 1), eq(DeferredCauset#1, 1), ne(DeferredCauset#2, 2)",
   100  		},
   101  		{
   102  			solver: []PropagateConstantSolver{newPropConstSolver()},
   103  			conditions: []Expression{
   104  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   105  				newFunction(ast.EQ, newDeferredCauset(1), newLonglong(1)),
   106  				newFunction(ast.EQ, newDeferredCauset(2), newDeferredCauset(3)),
   107  				newFunction(ast.GE, newDeferredCauset(2), newLonglong(2)),
   108  				newFunction(ast.NE, newDeferredCauset(2), newLonglong(4)),
   109  				newFunction(ast.NE, newDeferredCauset(3), newLonglong(5)),
   110  			},
   111  			result: "eq(DeferredCauset#0, 1), eq(DeferredCauset#1, 1), eq(DeferredCauset#2, DeferredCauset#3), ge(DeferredCauset#2, 2), ge(DeferredCauset#3, 2), ne(DeferredCauset#2, 4), ne(DeferredCauset#2, 5), ne(DeferredCauset#3, 4), ne(DeferredCauset#3, 5)",
   112  		},
   113  		{
   114  			solver: []PropagateConstantSolver{newPropConstSolver()},
   115  			conditions: []Expression{
   116  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   117  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(2)),
   118  				newFunction(ast.GE, newDeferredCauset(1), newLonglong(0)),
   119  			},
   120  			result: "eq(DeferredCauset#0, DeferredCauset#1), eq(DeferredCauset#0, DeferredCauset#2), ge(DeferredCauset#0, 0), ge(DeferredCauset#1, 0), ge(DeferredCauset#2, 0)",
   121  		},
   122  		{
   123  			solver: []PropagateConstantSolver{newPropConstSolver()},
   124  			conditions: []Expression{
   125  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   126  				newFunction(ast.GT, newDeferredCauset(0), newLonglong(2)),
   127  				newFunction(ast.GT, newDeferredCauset(1), newLonglong(3)),
   128  				newFunction(ast.LT, newDeferredCauset(0), newLonglong(1)),
   129  				newFunction(ast.GT, newLonglong(2), newDeferredCauset(1)),
   130  			},
   131  			result: "eq(DeferredCauset#0, DeferredCauset#1), gt(2, DeferredCauset#0), gt(2, DeferredCauset#1), gt(DeferredCauset#0, 2), gt(DeferredCauset#0, 3), gt(DeferredCauset#1, 2), gt(DeferredCauset#1, 3), lt(DeferredCauset#0, 1), lt(DeferredCauset#1, 1)",
   132  		},
   133  		{
   134  			solver: []PropagateConstantSolver{newPropConstSolver()},
   135  			conditions: []Expression{
   136  				newFunction(ast.EQ, newLonglong(1), newDeferredCauset(0)),
   137  				newLonglong(0),
   138  			},
   139  			result: "0",
   140  		},
   141  		{
   142  			solver: []PropagateConstantSolver{newPropConstSolver()},
   143  			conditions: []Expression{
   144  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   145  				newFunction(ast.In, newDeferredCauset(0), newLonglong(1), newLonglong(2)),
   146  				newFunction(ast.In, newDeferredCauset(1), newLonglong(3), newLonglong(4)),
   147  			},
   148  			result: "eq(DeferredCauset#0, DeferredCauset#1), in(DeferredCauset#0, 1, 2), in(DeferredCauset#0, 3, 4), in(DeferredCauset#1, 1, 2), in(DeferredCauset#1, 3, 4)",
   149  		},
   150  		{
   151  			solver: []PropagateConstantSolver{newPropConstSolver()},
   152  			conditions: []Expression{
   153  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   154  				newFunction(ast.EQ, newDeferredCauset(0), newFunction(ast.BitLength, newDeferredCauset(2))),
   155  			},
   156  			result: "eq(DeferredCauset#0, DeferredCauset#1), eq(DeferredCauset#0, bit_length(cast(DeferredCauset#2, var_string(20)))), eq(DeferredCauset#1, bit_length(cast(DeferredCauset#2, var_string(20))))",
   157  		},
   158  		{
   159  			solver: []PropagateConstantSolver{newPropConstSolver()},
   160  			conditions: []Expression{
   161  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   162  				newFunction(ast.LE, newFunction(ast.Mul, newDeferredCauset(0), newDeferredCauset(0)), newLonglong(50)),
   163  			},
   164  			result: "eq(DeferredCauset#0, DeferredCauset#1), le(mul(DeferredCauset#0, DeferredCauset#0), 50), le(mul(DeferredCauset#1, DeferredCauset#1), 50)",
   165  		},
   166  		{
   167  			solver: []PropagateConstantSolver{newPropConstSolver()},
   168  			conditions: []Expression{
   169  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   170  				newFunction(ast.LE, newDeferredCauset(0), newFunction(ast.Plus, newDeferredCauset(1), newLonglong(1))),
   171  			},
   172  			result: "eq(DeferredCauset#0, DeferredCauset#1), le(DeferredCauset#0, plus(DeferredCauset#0, 1)), le(DeferredCauset#0, plus(DeferredCauset#1, 1)), le(DeferredCauset#1, plus(DeferredCauset#1, 1))",
   173  		},
   174  		{
   175  			solver: []PropagateConstantSolver{newPropConstSolver()},
   176  			conditions: []Expression{
   177  				newFunction(ast.EQ, newDeferredCauset(0), newDeferredCauset(1)),
   178  				newFunction(ast.LE, newDeferredCauset(0), newFunction(ast.Rand)),
   179  			},
   180  			result: "eq(DeferredCauset#0, DeferredCauset#1), le(cast(DeferredCauset#0, double BINARY), rand())",
   181  		},
   182  	}
   183  	for _, tt := range tests {
   184  		for _, solver := range tt.solver {
   185  			ctx := mock.NewContext()
   186  			conds := make([]Expression, 0, len(tt.conditions))
   187  			for _, cd := range tt.conditions {
   188  				conds = append(conds, FoldConstant(cd))
   189  			}
   190  			newConds := solver.PropagateConstant(ctx, conds)
   191  			var result []string
   192  			for _, v := range newConds {
   193  				result = append(result, v.String())
   194  			}
   195  			sort.Strings(result)
   196  			c.Assert(strings.Join(result, ", "), Equals, tt.result, Commentf("different for expr %s", tt.conditions))
   197  		}
   198  	}
   199  }
   200  
   201  func (*testExpressionSuite) TestConstantFolding(c *C) {
   202  	tests := []struct {
   203  		condition Expression
   204  		result    string
   205  	}{
   206  		{
   207  			condition: newFunction(ast.LT, newDeferredCauset(0), newFunction(ast.Plus, newLonglong(1), newLonglong(2))),
   208  			result:    "lt(DeferredCauset#0, 3)",
   209  		},
   210  		{
   211  			condition: newFunction(ast.LT, newDeferredCauset(0), newFunction(ast.Greatest, newLonglong(1), newLonglong(2))),
   212  			result:    "lt(DeferredCauset#0, 2)",
   213  		},
   214  		{
   215  			condition: newFunction(ast.EQ, newDeferredCauset(0), newFunction(ast.Rand)),
   216  			result:    "eq(cast(DeferredCauset#0, double BINARY), rand())",
   217  		},
   218  		{
   219  			condition: newFunction(ast.IsNull, newLonglong(1)),
   220  			result:    "0",
   221  		},
   222  		{
   223  			condition: newFunction(ast.EQ, newDeferredCauset(0), newFunction(ast.UnaryNot, newFunction(ast.Plus, newLonglong(1), newLonglong(1)))),
   224  			result:    "eq(DeferredCauset#0, 0)",
   225  		},
   226  		{
   227  			condition: newFunction(ast.LT, newDeferredCauset(0), newFunction(ast.Plus, newDeferredCauset(1), newFunction(ast.Plus, newLonglong(2), newLonglong(1)))),
   228  			result:    "lt(DeferredCauset#0, plus(DeferredCauset#1, 3))",
   229  		},
   230  	}
   231  	for _, tt := range tests {
   232  		newConds := FoldConstant(tt.condition)
   233  		c.Assert(newConds.String(), Equals, tt.result, Commentf("different for expr %s", tt.condition))
   234  	}
   235  }
   236  
   237  func (*testExpressionSuite) TestDeferredExprNullConstantFold(c *C) {
   238  	nullConst := &Constant{
   239  		Value:        types.NewCauset(nil),
   240  		RetType:      types.NewFieldType(allegrosql.TypeTiny),
   241  		DeferredExpr: NewNull(),
   242  	}
   243  	tests := []struct {
   244  		condition Expression
   245  		deferred  string
   246  	}{
   247  		{
   248  			condition: newFunction(ast.LT, newDeferredCauset(0), nullConst),
   249  			deferred:  "lt(DeferredCauset#0, <nil>)",
   250  		},
   251  	}
   252  	for _, tt := range tests {
   253  		comment := Commentf("different for expr %s", tt.condition)
   254  		sf, ok := tt.condition.(*ScalarFunction)
   255  		c.Assert(ok, IsTrue, comment)
   256  		sf.GetCtx().GetStochastikVars().StmtCtx.InNullRejectCheck = true
   257  		newConds := FoldConstant(tt.condition)
   258  		newConst, ok := newConds.(*Constant)
   259  		c.Assert(ok, IsTrue, comment)
   260  		c.Assert(newConst.DeferredExpr.String(), Equals, tt.deferred, comment)
   261  	}
   262  }
   263  
   264  func (*testExpressionSuite) TestDeferredParamNotNull(c *C) {
   265  	ctx := mock.NewContext()
   266  	testTime := time.Now()
   267  	ctx.GetStochastikVars().PreparedParams = []types.Causet{
   268  		types.NewIntCauset(1),
   269  		types.NewDecimalCauset(types.NewDecFromStringForTest("20170118123950.123")),
   270  		types.NewTimeCauset(types.NewTime(types.FromGoTime(testTime), allegrosql.TypeTimestamp, 6)),
   271  		types.NewDurationCauset(types.ZeroDuration),
   272  		types.NewStringCauset("{}"),
   273  		types.NewBinaryLiteralCauset([]byte{1}),
   274  		types.NewBytesCauset([]byte{'b'}),
   275  		types.NewFloat32Causet(1.1),
   276  		types.NewFloat64Causet(2.1),
   277  		types.NewUintCauset(100),
   278  		types.NewMysqlBitCauset([]byte{1}),
   279  		types.NewMysqlEnumCauset(types.Enum{Name: "n", Value: 2}),
   280  	}
   281  	cstInt := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 0}, RetType: newIntFieldType()}
   282  	cstDec := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 1}, RetType: newDecimalFieldType()}
   283  	cstTime := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 2}, RetType: newDateFieldType()}
   284  	cstDuration := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 3}, RetType: newDurFieldType()}
   285  	cstJSON := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 4}, RetType: newJSONFieldType()}
   286  	cstBytes := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 6}, RetType: newBlobFieldType()}
   287  	cstBinary := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 5}, RetType: newBinaryLiteralFieldType()}
   288  	cstFloat32 := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 7}, RetType: newFloatFieldType()}
   289  	cstFloat64 := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 8}, RetType: newFloatFieldType()}
   290  	cstUint := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 9}, RetType: newIntFieldType()}
   291  	cstBit := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 10}, RetType: newBinaryLiteralFieldType()}
   292  	cstEnum := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 11}, RetType: newEnumFieldType()}
   293  
   294  	c.Assert(allegrosql.TypeVarString, Equals, cstJSON.GetType().Tp)
   295  	c.Assert(allegrosql.TypeNewDecimal, Equals, cstDec.GetType().Tp)
   296  	c.Assert(allegrosql.TypeLonglong, Equals, cstInt.GetType().Tp)
   297  	c.Assert(allegrosql.TypeLonglong, Equals, cstUint.GetType().Tp)
   298  	c.Assert(allegrosql.TypeTimestamp, Equals, cstTime.GetType().Tp)
   299  	c.Assert(allegrosql.TypeDuration, Equals, cstDuration.GetType().Tp)
   300  	c.Assert(allegrosql.TypeBlob, Equals, cstBytes.GetType().Tp)
   301  	c.Assert(allegrosql.TypeBit, Equals, cstBinary.GetType().Tp)
   302  	c.Assert(allegrosql.TypeBit, Equals, cstBit.GetType().Tp)
   303  	c.Assert(allegrosql.TypeFloat, Equals, cstFloat32.GetType().Tp)
   304  	c.Assert(allegrosql.TypeDouble, Equals, cstFloat64.GetType().Tp)
   305  	c.Assert(allegrosql.TypeEnum, Equals, cstEnum.GetType().Tp)
   306  
   307  	d, _, err := cstInt.EvalInt(ctx, chunk.Event{})
   308  	c.Assert(err, IsNil)
   309  	c.Assert(d, Equals, int64(1))
   310  	r, _, err := cstFloat64.EvalReal(ctx, chunk.Event{})
   311  	c.Assert(err, IsNil)
   312  	c.Assert(r, Equals, float64(2.1))
   313  	de, _, err := cstDec.EvalDecimal(ctx, chunk.Event{})
   314  	c.Assert(err, IsNil)
   315  	c.Assert(de.String(), Equals, "20170118123950.123")
   316  	s, _, err := cstBytes.EvalString(ctx, chunk.Event{})
   317  	c.Assert(err, IsNil)
   318  	c.Assert(s, Equals, "b")
   319  	t, _, err := cstTime.EvalTime(ctx, chunk.Event{})
   320  	c.Assert(err, IsNil)
   321  	c.Assert(t.Compare(ctx.GetStochastikVars().PreparedParams[2].GetMysqlTime()), Equals, 0)
   322  	dur, _, err := cstDuration.EvalDuration(ctx, chunk.Event{})
   323  	c.Assert(err, IsNil)
   324  	c.Assert(dur.Duration, Equals, types.ZeroDuration.Duration)
   325  	json, _, err := cstJSON.EvalJSON(ctx, chunk.Event{})
   326  	c.Assert(err, IsNil)
   327  	c.Assert(json, NotNil)
   328  }
   329  
   330  func (*testExpressionSuite) TestDeferredExprNotNull(c *C) {
   331  	m := &MockExpr{}
   332  	ctx := mock.NewContext()
   333  	cst := &Constant{DeferredExpr: m, RetType: newIntFieldType()}
   334  	m.i, m.err = nil, fmt.Errorf("ERROR")
   335  	_, _, err := cst.EvalInt(ctx, chunk.Event{})
   336  	c.Assert(err, NotNil)
   337  	_, _, err = cst.EvalReal(ctx, chunk.Event{})
   338  	c.Assert(err, NotNil)
   339  	_, _, err = cst.EvalDecimal(ctx, chunk.Event{})
   340  	c.Assert(err, NotNil)
   341  	_, _, err = cst.EvalString(ctx, chunk.Event{})
   342  	c.Assert(err, NotNil)
   343  	_, _, err = cst.EvalTime(ctx, chunk.Event{})
   344  	c.Assert(err, NotNil)
   345  	_, _, err = cst.EvalDuration(ctx, chunk.Event{})
   346  	c.Assert(err, NotNil)
   347  	_, _, err = cst.EvalJSON(ctx, chunk.Event{})
   348  	c.Assert(err, NotNil)
   349  
   350  	m.i, m.err = nil, nil
   351  	_, isNull, err := cst.EvalInt(ctx, chunk.Event{})
   352  	c.Assert(err, IsNil)
   353  	c.Assert(isNull, IsTrue)
   354  	_, isNull, err = cst.EvalReal(ctx, chunk.Event{})
   355  	c.Assert(err, IsNil)
   356  	c.Assert(isNull, IsTrue)
   357  	_, isNull, err = cst.EvalDecimal(ctx, chunk.Event{})
   358  	c.Assert(err, IsNil)
   359  	c.Assert(isNull, IsTrue)
   360  	_, isNull, err = cst.EvalString(ctx, chunk.Event{})
   361  	c.Assert(err, IsNil)
   362  	c.Assert(isNull, IsTrue)
   363  	_, isNull, err = cst.EvalTime(ctx, chunk.Event{})
   364  	c.Assert(err, IsNil)
   365  	c.Assert(isNull, IsTrue)
   366  	_, isNull, err = cst.EvalDuration(ctx, chunk.Event{})
   367  	c.Assert(err, IsNil)
   368  	c.Assert(isNull, IsTrue)
   369  	_, isNull, err = cst.EvalJSON(ctx, chunk.Event{})
   370  	c.Assert(err, IsNil)
   371  	c.Assert(isNull, IsTrue)
   372  
   373  	m.i = int64(2333)
   374  	xInt, _, _ := cst.EvalInt(ctx, chunk.Event{})
   375  	c.Assert(xInt, Equals, int64(2333))
   376  
   377  	m.i = float64(123.45)
   378  	xFlo, _, _ := cst.EvalReal(ctx, chunk.Event{})
   379  	c.Assert(xFlo, Equals, float64(123.45))
   380  
   381  	m.i = "abc"
   382  	xStr, _, _ := cst.EvalString(ctx, chunk.Event{})
   383  	c.Assert(xStr, Equals, "abc")
   384  
   385  	m.i = &types.MyDecimal{}
   386  	xDec, _, _ := cst.EvalDecimal(ctx, chunk.Event{})
   387  	c.Assert(xDec.Compare(m.i.(*types.MyDecimal)), Equals, 0)
   388  
   389  	m.i = types.ZeroTime
   390  	xTim, _, _ := cst.EvalTime(ctx, chunk.Event{})
   391  	c.Assert(xTim.Compare(m.i.(types.Time)), Equals, 0)
   392  
   393  	m.i = types.Duration{}
   394  	xDur, _, _ := cst.EvalDuration(ctx, chunk.Event{})
   395  	c.Assert(xDur.Compare(m.i.(types.Duration)), Equals, 0)
   396  
   397  	m.i = json.BinaryJSON{}
   398  	xJsn, _, _ := cst.EvalJSON(ctx, chunk.Event{})
   399  	c.Assert(m.i.(json.BinaryJSON).String(), Equals, xJsn.String())
   400  
   401  	cln := cst.Clone().(*Constant)
   402  	c.Assert(cln.DeferredExpr, Equals, cst.DeferredExpr)
   403  }
   404  
   405  func (*testExpressionSuite) TestVectorizedConstant(c *C) {
   406  	// fixed-length type with/without Sel
   407  	for _, cst := range []*Constant{
   408  		{RetType: newIntFieldType(), Value: types.NewIntCauset(2333)},
   409  		{RetType: newIntFieldType(), DeferredExpr: &Constant{RetType: newIntFieldType(), Value: types.NewIntCauset(2333)}}} {
   410  		chk := chunk.New([]*types.FieldType{newIntFieldType()}, 1024, 1024)
   411  		for i := 0; i < 1024; i++ {
   412  			chk.AppendInt64(0, int64(i))
   413  		}
   414  		defCaus := chunk.NewDeferredCauset(newIntFieldType(), 1024)
   415  		ctx := mock.NewContext()
   416  		c.Assert(cst.VecEvalInt(ctx, chk, defCaus), IsNil)
   417  		i64s := defCaus.Int64s()
   418  		c.Assert(len(i64s), Equals, 1024)
   419  		for _, v := range i64s {
   420  			c.Assert(v, Equals, int64(2333))
   421  		}
   422  
   423  		// fixed-length type with Sel
   424  		sel := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29}
   425  		chk.SetSel(sel)
   426  		c.Assert(cst.VecEvalInt(ctx, chk, defCaus), IsNil)
   427  		i64s = defCaus.Int64s()
   428  		for i := range sel {
   429  			c.Assert(i64s[i], Equals, int64(2333))
   430  		}
   431  	}
   432  
   433  	// var-length type with/without Sel
   434  	for _, cst := range []*Constant{
   435  		{RetType: newStringFieldType(), Value: types.NewStringCauset("hello")},
   436  		{RetType: newStringFieldType(), DeferredExpr: &Constant{RetType: newStringFieldType(), Value: types.NewStringCauset("hello")}}} {
   437  		chk := chunk.New([]*types.FieldType{newIntFieldType()}, 1024, 1024)
   438  		for i := 0; i < 1024; i++ {
   439  			chk.AppendInt64(0, int64(i))
   440  		}
   441  		cst = &Constant{DeferredExpr: nil, RetType: newStringFieldType(), Value: types.NewStringCauset("hello")}
   442  		chk.SetSel(nil)
   443  		defCaus := chunk.NewDeferredCauset(newStringFieldType(), 1024)
   444  		ctx := mock.NewContext()
   445  		c.Assert(cst.VecEvalString(ctx, chk, defCaus), IsNil)
   446  		for i := 0; i < 1024; i++ {
   447  			c.Assert(defCaus.GetString(i), Equals, "hello")
   448  		}
   449  
   450  		// var-length type with Sel
   451  		sel := []int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29}
   452  		chk.SetSel(sel)
   453  		c.Assert(cst.VecEvalString(ctx, chk, defCaus), IsNil)
   454  		for i := range sel {
   455  			c.Assert(defCaus.GetString(i), Equals, "hello")
   456  		}
   457  	}
   458  }
   459  
   460  func (*testExpressionSuite) TestGetTypeThreadSafe(c *C) {
   461  	ctx := mock.NewContext()
   462  	ctx.GetStochastikVars().PreparedParams = []types.Causet{
   463  		types.NewIntCauset(1),
   464  	}
   465  	con := &Constant{ParamMarker: &ParamMarker{ctx: ctx, order: 0}, RetType: newStringFieldType()}
   466  	ft1 := con.GetType()
   467  	ft2 := con.GetType()
   468  	c.Assert(ft1, Not(Equals), ft2)
   469  }