github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_vectorized_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  	"math/rand"
    19  	"sync"
    20  	"testing"
    21  	"time"
    22  
    23  	. "github.com/whtcorpsinc/check"
    24  	"github.com/whtcorpsinc/errors"
    25  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    26  	"github.com/whtcorpsinc/milevadb/types"
    27  	"github.com/whtcorpsinc/milevadb/types/json"
    28  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    29  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    30  )
    31  
    32  type mockVecPlusIntBuiltinFunc struct {
    33  	baseBuiltinFunc
    34  
    35  	buf         *chunk.DeferredCauset
    36  	enableAlloc bool
    37  }
    38  
    39  func (p *mockVecPlusIntBuiltinFunc) allocBuf(n int) (*chunk.DeferredCauset, error) {
    40  	if p.enableAlloc {
    41  		return p.bufSlabPredictor.get(types.ETInt, n)
    42  	}
    43  	if p.buf == nil {
    44  		p.buf = chunk.NewDeferredCauset(types.NewFieldType(allegrosql.TypeLonglong), n)
    45  	}
    46  	return p.buf, nil
    47  }
    48  
    49  func (p *mockVecPlusIntBuiltinFunc) releaseBuf(buf *chunk.DeferredCauset) {
    50  	if p.enableAlloc {
    51  		p.bufSlabPredictor.put(buf)
    52  	}
    53  }
    54  
    55  func (p *mockVecPlusIntBuiltinFunc) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error {
    56  	n := input.NumRows()
    57  	buf, err := p.allocBuf(n)
    58  	if err != nil {
    59  		return err
    60  	}
    61  	defer p.releaseBuf(buf)
    62  	if err := p.args[0].VecEvalInt(p.ctx, input, result); err != nil {
    63  		return err
    64  	}
    65  	if err := p.args[1].VecEvalInt(p.ctx, input, buf); err != nil {
    66  		return err
    67  	}
    68  	dst64s := result.Int64s()
    69  	src64s := buf.Int64s()
    70  	for i := range dst64s {
    71  		dst64s[i] += src64s[i]
    72  	}
    73  	for i := 0; i < n; i++ {
    74  		if buf.IsNull(i) && !result.IsNull(i) {
    75  			result.SetNull(i, true)
    76  		}
    77  	}
    78  	return nil
    79  }
    80  
    81  func genMockVecPlusIntBuiltinFunc() (*mockVecPlusIntBuiltinFunc, *chunk.Chunk, *chunk.DeferredCauset) {
    82  	tp := types.NewFieldType(allegrosql.TypeLonglong)
    83  	defCaus1 := newDeferredCauset(0)
    84  	defCaus1.Index, defCaus1.RetType = 0, tp
    85  	defCaus2 := newDeferredCauset(1)
    86  	defCaus2.Index, defCaus2.RetType = 1, tp
    87  	bf, err := newBaseBuiltinFuncWithTp(mock.NewContext(), "", []Expression{defCaus1, defCaus2}, types.ETInt, types.ETInt, types.ETInt)
    88  	if err != nil {
    89  		panic(err)
    90  	}
    91  	plus := &mockVecPlusIntBuiltinFunc{bf, nil, false}
    92  	input := chunk.New([]*types.FieldType{tp, tp}, 1024, 1024)
    93  	buf := chunk.NewDeferredCauset(types.NewFieldType(allegrosql.TypeLonglong), 1024)
    94  	for i := 0; i < 1024; i++ {
    95  		input.AppendInt64(0, int64(i))
    96  		input.AppendInt64(1, int64(i))
    97  	}
    98  	return plus, input, buf
    99  }
   100  
   101  func (s *testEvaluatorSuite) TestMockVecPlusInt(c *C) {
   102  	plus, input, buf := genMockVecPlusIntBuiltinFunc()
   103  	plus.enableAlloc = false
   104  	c.Assert(plus.vecEvalInt(input, buf), IsNil)
   105  	for i := 0; i < 1024; i++ {
   106  		c.Assert(buf.IsNull(i), IsFalse)
   107  		c.Assert(buf.GetInt64(i), Equals, int64(i*2))
   108  	}
   109  
   110  	plus.enableAlloc = true
   111  	c.Assert(plus.vecEvalInt(input, buf), IsNil)
   112  	for i := 0; i < 1024; i++ {
   113  		c.Assert(buf.IsNull(i), IsFalse)
   114  		c.Assert(buf.GetInt64(i), Equals, int64(i*2))
   115  	}
   116  }
   117  
   118  func (s *testVectorizeSuite2) TestMockVecPlusIntParallel(c *C) {
   119  	plus, input, buf := genMockVecPlusIntBuiltinFunc()
   120  	plus.enableAlloc = true // it's concurrency-safe if enableAlloc is true
   121  	var wg sync.WaitGroup
   122  	for i := 0; i < 50; i++ {
   123  		wg.Add(1)
   124  		go func() {
   125  			result := buf.CopyConstruct(nil)
   126  			for i := 0; i < 200; i++ {
   127  				c.Assert(plus.vecEvalInt(input, result), IsNil)
   128  				for i := 0; i < 1024; i++ {
   129  					c.Assert(result.IsNull(i), IsFalse)
   130  					c.Assert(result.GetInt64(i), Equals, int64(i*2))
   131  				}
   132  			}
   133  			wg.Done()
   134  		}()
   135  	}
   136  	wg.Wait()
   137  }
   138  
   139  func BenchmarkDeferredCausetBufferAllocate(b *testing.B) {
   140  	allocator := newLocalSliceBuffer(1)
   141  	b.ResetTimer()
   142  	for i := 0; i < b.N; i++ {
   143  		buf, _ := allocator.get(types.ETInt, 1024)
   144  		allocator.put(buf)
   145  	}
   146  }
   147  
   148  func BenchmarkDeferredCausetBufferAllocateParallel(b *testing.B) {
   149  	allocator := newLocalSliceBuffer(1)
   150  	b.ResetTimer()
   151  	b.RunParallel(func(pb *testing.PB) {
   152  		for pb.Next() {
   153  			buf, _ := allocator.get(types.ETInt, 1024)
   154  			allocator.put(buf)
   155  		}
   156  	})
   157  }
   158  
   159  func BenchmarkPlusIntBufSlabPredictor(b *testing.B) {
   160  	plus, input, buf := genMockVecPlusIntBuiltinFunc()
   161  	names := []string{"enable", "disable"}
   162  	enable := []bool{true, false}
   163  	for i := range enable {
   164  		b.Run(names[i], func(b *testing.B) {
   165  			plus.enableAlloc = enable[i]
   166  			b.ResetTimer()
   167  			for i := 0; i < b.N; i++ {
   168  				if err := plus.vecEvalInt(input, buf); err != nil {
   169  					b.Fatal(err)
   170  				}
   171  			}
   172  		})
   173  	}
   174  }
   175  
   176  type mockBuiltinDouble struct {
   177  	baseBuiltinFunc
   178  
   179  	evalType  types.EvalType
   180  	enableVec bool
   181  }
   182  
   183  func (p *mockBuiltinDouble) vectorized() bool {
   184  	return p.enableVec
   185  }
   186  
   187  func (p *mockBuiltinDouble) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   188  	if err := p.args[0].VecEvalInt(p.ctx, input, result); err != nil {
   189  		return err
   190  	}
   191  	i64s := result.Int64s()
   192  	for i := range i64s {
   193  		i64s[i] <<= 1
   194  	}
   195  	return nil
   196  }
   197  
   198  func (p *mockBuiltinDouble) vecEvalReal(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   199  	if err := p.args[0].VecEvalReal(p.ctx, input, result); err != nil {
   200  		return err
   201  	}
   202  	f64s := result.Float64s()
   203  	for i := range f64s {
   204  		f64s[i] *= 2
   205  	}
   206  	return nil
   207  }
   208  
   209  func (p *mockBuiltinDouble) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   210  	var buf *chunk.DeferredCauset
   211  	var err error
   212  	if buf, err = p.baseBuiltinFunc.bufSlabPredictor.get(p.evalType, input.NumRows()); err != nil {
   213  		return err
   214  	}
   215  	if err := p.args[0].VecEvalString(p.ctx, input, buf); err != nil {
   216  		return err
   217  	}
   218  	result.ReserveString(input.NumRows())
   219  	for i := 0; i < input.NumRows(); i++ {
   220  		str := buf.GetString(i)
   221  		result.AppendString(str + str)
   222  	}
   223  	p.baseBuiltinFunc.bufSlabPredictor.put(buf)
   224  	return nil
   225  }
   226  
   227  func (p *mockBuiltinDouble) vecEvalDecimal(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   228  	if err := p.args[0].VecEvalDecimal(p.ctx, input, result); err != nil {
   229  		return err
   230  	}
   231  	ds := result.Decimals()
   232  	for i := range ds {
   233  		r := new(types.MyDecimal)
   234  		if err := types.DecimalAdd(&ds[i], &ds[i], r); err != nil {
   235  			return err
   236  		}
   237  		ds[i] = *r
   238  	}
   239  	return nil
   240  }
   241  
   242  func (p *mockBuiltinDouble) vecEvalTime(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   243  	if err := p.args[0].VecEvalTime(p.ctx, input, result); err != nil {
   244  		return err
   245  	}
   246  	ts := result.Times()
   247  	for i := range ts {
   248  		d, err := ts[i].ConvertToDuration()
   249  		if err != nil {
   250  			return err
   251  		}
   252  		if ts[i], err = ts[i].Add(p.ctx.GetStochastikVars().StmtCtx, d); err != nil {
   253  			return err
   254  		}
   255  	}
   256  	return nil
   257  }
   258  
   259  func (p *mockBuiltinDouble) vecEvalDuration(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   260  	if err := p.args[0].VecEvalDuration(p.ctx, input, result); err != nil {
   261  		return err
   262  	}
   263  	ds := result.GoDurations()
   264  	for i := range ds {
   265  		ds[i] *= 2
   266  	}
   267  	return nil
   268  }
   269  
   270  func (p *mockBuiltinDouble) vecEvalJSON(input *chunk.Chunk, result *chunk.DeferredCauset) error {
   271  	var buf *chunk.DeferredCauset
   272  	var err error
   273  	if buf, err = p.baseBuiltinFunc.bufSlabPredictor.get(p.evalType, input.NumRows()); err != nil {
   274  		return err
   275  	}
   276  	if err := p.args[0].VecEvalJSON(p.ctx, input, buf); err != nil {
   277  		return err
   278  	}
   279  	result.ReserveString(input.NumRows())
   280  	for i := 0; i < input.NumRows(); i++ {
   281  		j := buf.GetJSON(i)
   282  		path, err := json.ParseJSONPathExpr("$.key")
   283  		if err != nil {
   284  			return err
   285  		}
   286  		ret, ok := j.Extract([]json.PathExpression{path})
   287  		if !ok {
   288  			return errors.Errorf("path not found")
   289  		}
   290  		if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, 2*ret.GetInt64()))); err != nil {
   291  			return err
   292  		}
   293  		result.AppendJSON(j)
   294  	}
   295  	p.baseBuiltinFunc.bufSlabPredictor.put(buf)
   296  	return nil
   297  }
   298  
   299  func (p *mockBuiltinDouble) evalInt(event chunk.Row) (int64, bool, error) {
   300  	v, isNull, err := p.args[0].EvalInt(p.ctx, event)
   301  	if err != nil {
   302  		return 0, false, err
   303  	}
   304  	return v * 2, isNull, nil
   305  }
   306  
   307  func (p *mockBuiltinDouble) evalReal(event chunk.Row) (float64, bool, error) {
   308  	v, isNull, err := p.args[0].EvalReal(p.ctx, event)
   309  	if err != nil {
   310  		return 0, false, err
   311  	}
   312  	return v * 2, isNull, nil
   313  }
   314  
   315  func (p *mockBuiltinDouble) evalString(event chunk.Row) (string, bool, error) {
   316  	v, isNull, err := p.args[0].EvalString(p.ctx, event)
   317  	if err != nil {
   318  		return "", false, err
   319  	}
   320  	return v + v, isNull, nil
   321  }
   322  
   323  func (p *mockBuiltinDouble) evalDecimal(event chunk.Row) (*types.MyDecimal, bool, error) {
   324  	v, isNull, err := p.args[0].EvalDecimal(p.ctx, event)
   325  	if err != nil {
   326  		return nil, false, err
   327  	}
   328  	r := new(types.MyDecimal)
   329  	if err := types.DecimalAdd(v, v, r); err != nil {
   330  		return nil, false, err
   331  	}
   332  	return r, isNull, nil
   333  }
   334  
   335  func (p *mockBuiltinDouble) evalTime(event chunk.Row) (types.Time, bool, error) {
   336  	v, isNull, err := p.args[0].EvalTime(p.ctx, event)
   337  	if err != nil {
   338  		return types.ZeroTime, false, err
   339  	}
   340  	d, err := v.ConvertToDuration()
   341  	if err != nil {
   342  		return types.ZeroTime, false, err
   343  	}
   344  	v, err = v.Add(p.ctx.GetStochastikVars().StmtCtx, d)
   345  	return v, isNull, err
   346  }
   347  
   348  func (p *mockBuiltinDouble) evalDuration(event chunk.Row) (types.Duration, bool, error) {
   349  	v, isNull, err := p.args[0].EvalDuration(p.ctx, event)
   350  	if err != nil {
   351  		return types.Duration{}, false, err
   352  	}
   353  	v, err = v.Add(v)
   354  	return v, isNull, err
   355  }
   356  
   357  func (p *mockBuiltinDouble) evalJSON(event chunk.Row) (json.BinaryJSON, bool, error) {
   358  	j, isNull, err := p.args[0].EvalJSON(p.ctx, event)
   359  	if err != nil {
   360  		return json.BinaryJSON{}, false, err
   361  	}
   362  	if isNull {
   363  		return json.BinaryJSON{}, true, nil
   364  	}
   365  	path, err := json.ParseJSONPathExpr("$.key")
   366  	if err != nil {
   367  		return json.BinaryJSON{}, false, err
   368  	}
   369  	ret, ok := j.Extract([]json.PathExpression{path})
   370  	if !ok {
   371  		return json.BinaryJSON{}, true, err
   372  	}
   373  	if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, 2*ret.GetInt64()))); err != nil {
   374  		return json.BinaryJSON{}, false, err
   375  	}
   376  	return j, false, nil
   377  }
   378  
   379  func convertETType(eType types.EvalType) (mysqlType byte) {
   380  	switch eType {
   381  	case types.ETInt:
   382  		mysqlType = allegrosql.TypeLonglong
   383  	case types.ETReal:
   384  		mysqlType = allegrosql.TypeDouble
   385  	case types.ETDecimal:
   386  		mysqlType = allegrosql.TypeNewDecimal
   387  	case types.ETDuration:
   388  		mysqlType = allegrosql.TypeDuration
   389  	case types.ETJson:
   390  		mysqlType = allegrosql.TypeJSON
   391  	case types.ETString:
   392  		mysqlType = allegrosql.TypeVarString
   393  	case types.ETDatetime:
   394  		mysqlType = allegrosql.TypeDatetime
   395  	}
   396  	return
   397  }
   398  
   399  func genMockRowDouble(eType types.EvalType, enableVec bool) (builtinFunc, *chunk.Chunk, *chunk.DeferredCauset, error) {
   400  	mysqlType := convertETType(eType)
   401  	tp := types.NewFieldType(mysqlType)
   402  	defCaus1 := newDeferredCauset(1)
   403  	defCaus1.Index = 0
   404  	defCaus1.RetType = tp
   405  	bf, err := newBaseBuiltinFuncWithTp(mock.NewContext(), "", []Expression{defCaus1}, eType, eType)
   406  	if err != nil {
   407  		return nil, nil, nil, err
   408  	}
   409  	rowDouble := &mockBuiltinDouble{bf, eType, enableVec}
   410  	input := chunk.New([]*types.FieldType{tp}, 1024, 1024)
   411  	buf := chunk.NewDeferredCauset(types.NewFieldType(convertETType(eType)), 1024)
   412  	for i := 0; i < 1024; i++ {
   413  		switch eType {
   414  		case types.ETInt:
   415  			input.AppendInt64(0, int64(i))
   416  		case types.ETReal:
   417  			input.AppendFloat64(0, float64(i))
   418  		case types.ETDecimal:
   419  			dec := new(types.MyDecimal)
   420  			if err := dec.FromFloat64(float64(i)); err != nil {
   421  				return nil, nil, nil, err
   422  			}
   423  			input.AppendMyDecimal(0, dec)
   424  		case types.ETDuration:
   425  			input.AppendDuration(0, types.Duration{Duration: time.Duration(i)})
   426  		case types.ETJson:
   427  			j := new(json.BinaryJSON)
   428  			if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, i))); err != nil {
   429  				return nil, nil, nil, err
   430  			}
   431  			input.AppendJSON(0, *j)
   432  		case types.ETString:
   433  			input.AppendString(0, fmt.Sprintf("%v", i))
   434  		case types.ETDatetime:
   435  			t := types.FromDate(i, 0, 0, 0, 0, 0, 0)
   436  			input.AppendTime(0, types.NewTime(t, mysqlType, 0))
   437  		}
   438  	}
   439  	return rowDouble, input, buf, nil
   440  }
   441  
   442  func (s *testEvaluatorSuite) checkVecEval(c *C, eType types.EvalType, sel []int, result *chunk.DeferredCauset) {
   443  	if sel == nil {
   444  		for i := 0; i < 1024; i++ {
   445  			sel = append(sel, i)
   446  		}
   447  	}
   448  	switch eType {
   449  	case types.ETInt:
   450  		i64s := result.Int64s()
   451  		c.Assert(len(i64s), Equals, len(sel))
   452  		for i, j := range sel {
   453  			c.Assert(i64s[i], Equals, int64(j*2))
   454  		}
   455  	case types.ETReal:
   456  		f64s := result.Float64s()
   457  		c.Assert(len(f64s), Equals, len(sel))
   458  		for i, j := range sel {
   459  			c.Assert(f64s[i], Equals, float64(j*2))
   460  		}
   461  	case types.ETDecimal:
   462  		ds := result.Decimals()
   463  		c.Assert(len(ds), Equals, len(sel))
   464  		for i, j := range sel {
   465  			dec := new(types.MyDecimal)
   466  			c.Assert(dec.FromFloat64(float64(j)), IsNil)
   467  			rst := new(types.MyDecimal)
   468  			c.Assert(types.DecimalAdd(dec, dec, rst), IsNil)
   469  			c.Assert(rst.Compare(&ds[i]), Equals, 0)
   470  		}
   471  	case types.ETDuration:
   472  		ds := result.GoDurations()
   473  		c.Assert(len(ds), Equals, len(sel))
   474  		for i, j := range sel {
   475  			c.Assert(ds[i], Equals, time.Duration(j+j))
   476  		}
   477  	case types.ETDatetime:
   478  		ds := result.Times()
   479  		c.Assert(len(ds), Equals, len(sel))
   480  		for i, j := range sel {
   481  			gt := types.FromDate(j, 0, 0, 0, 0, 0, 0)
   482  			t := types.NewTime(gt, convertETType(eType), 0)
   483  			d, err := t.ConvertToDuration()
   484  			c.Assert(err, IsNil)
   485  			v, err := t.Add(mock.NewContext().GetStochastikVars().StmtCtx, d)
   486  			c.Assert(err, IsNil)
   487  			c.Assert(v.Compare(ds[i]), Equals, 0)
   488  		}
   489  	case types.ETJson:
   490  		for i, j := range sel {
   491  			path, err := json.ParseJSONPathExpr("$.key")
   492  			c.Assert(err, IsNil)
   493  			ret, ok := result.GetJSON(i).Extract([]json.PathExpression{path})
   494  			c.Assert(ok, IsTrue)
   495  			c.Assert(ret.GetInt64(), Equals, int64(j*2))
   496  		}
   497  	case types.ETString:
   498  		for i, j := range sel {
   499  			c.Assert(result.GetString(i), Equals, fmt.Sprintf("%v%v", j, j))
   500  		}
   501  	}
   502  }
   503  
   504  func vecEvalType(f builtinFunc, eType types.EvalType, input *chunk.Chunk, result *chunk.DeferredCauset) error {
   505  	switch eType {
   506  	case types.ETInt:
   507  		return f.vecEvalInt(input, result)
   508  	case types.ETReal:
   509  		return f.vecEvalReal(input, result)
   510  	case types.ETDecimal:
   511  		return f.vecEvalDecimal(input, result)
   512  	case types.ETDuration:
   513  		return f.vecEvalDuration(input, result)
   514  	case types.ETString:
   515  		return f.vecEvalString(input, result)
   516  	case types.ETDatetime:
   517  		return f.vecEvalTime(input, result)
   518  	case types.ETJson:
   519  		return f.vecEvalJSON(input, result)
   520  	}
   521  	panic("not implement")
   522  }
   523  
   524  func (s *testEvaluatorSuite) TestDoubleRow2Vec(c *C) {
   525  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson}
   526  	for _, eType := range eTypes {
   527  		rowDouble, input, result, err := genMockRowDouble(eType, false)
   528  		c.Assert(err, IsNil)
   529  		c.Assert(vecEvalType(rowDouble, eType, input, result), IsNil)
   530  		s.checkVecEval(c, eType, nil, result)
   531  
   532  		sel := []int{0}
   533  		for {
   534  			end := sel[len(sel)-1]
   535  			gap := 1024 - end
   536  			if gap < 10 {
   537  				break
   538  			}
   539  			sel = append(sel, end+rand.Intn(gap-1)+1)
   540  		}
   541  		input.SetSel(sel)
   542  		c.Assert(vecEvalType(rowDouble, eType, input, result), IsNil)
   543  
   544  		s.checkVecEval(c, eType, sel, result)
   545  	}
   546  }
   547  
   548  func (s *testEvaluatorSuite) TestDoubleVec2Row(c *C) {
   549  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson}
   550  	for _, eType := range eTypes {
   551  		rowDouble, input, result, err := genMockRowDouble(eType, true)
   552  		result.Reset(eType)
   553  		c.Assert(err, IsNil)
   554  		it := chunk.NewIterator4Chunk(input)
   555  		for event := it.Begin(); event != it.End(); event = it.Next() {
   556  			switch eType {
   557  			case types.ETInt:
   558  				v, _, err := rowDouble.evalInt(event)
   559  				c.Assert(err, IsNil)
   560  				result.AppendInt64(v)
   561  			case types.ETReal:
   562  				v, _, err := rowDouble.evalReal(event)
   563  				c.Assert(err, IsNil)
   564  				result.AppendFloat64(v)
   565  			case types.ETDecimal:
   566  				v, _, err := rowDouble.evalDecimal(event)
   567  				c.Assert(err, IsNil)
   568  				result.AppendMyDecimal(v)
   569  			case types.ETDuration:
   570  				v, _, err := rowDouble.evalDuration(event)
   571  				c.Assert(err, IsNil)
   572  				result.AppendDuration(v)
   573  			case types.ETString:
   574  				v, _, err := rowDouble.evalString(event)
   575  				c.Assert(err, IsNil)
   576  				result.AppendString(v)
   577  			case types.ETDatetime:
   578  				v, _, err := rowDouble.evalTime(event)
   579  				c.Assert(err, IsNil)
   580  				result.AppendTime(v)
   581  			case types.ETJson:
   582  				v, _, err := rowDouble.evalJSON(event)
   583  				c.Assert(err, IsNil)
   584  				result.AppendJSON(v)
   585  			}
   586  		}
   587  		s.checkVecEval(c, eType, nil, result)
   588  	}
   589  }
   590  
   591  func evalRows(b *testing.B, it *chunk.Iterator4Chunk, eType types.EvalType, result *chunk.DeferredCauset, rowDouble builtinFunc) {
   592  	switch eType {
   593  	case types.ETInt:
   594  		for i := 0; i < b.N; i++ {
   595  			result.Reset(eType)
   596  			for r := it.Begin(); r != it.End(); r = it.Next() {
   597  				v, isNull, err := rowDouble.evalInt(r)
   598  				if err != nil {
   599  					b.Fatal(err)
   600  				}
   601  				if isNull {
   602  					result.AppendNull()
   603  				} else {
   604  					result.AppendInt64(v)
   605  				}
   606  			}
   607  		}
   608  	case types.ETReal:
   609  		for i := 0; i < b.N; i++ {
   610  			result.Reset(eType)
   611  			for r := it.Begin(); r != it.End(); r = it.Next() {
   612  				v, isNull, err := rowDouble.evalReal(r)
   613  				if err != nil {
   614  					b.Fatal(err)
   615  				}
   616  				if isNull {
   617  					result.AppendNull()
   618  				} else {
   619  					result.AppendFloat64(v)
   620  				}
   621  			}
   622  		}
   623  	case types.ETDecimal:
   624  		for i := 0; i < b.N; i++ {
   625  			result.Reset(eType)
   626  			for r := it.Begin(); r != it.End(); r = it.Next() {
   627  				v, isNull, err := rowDouble.evalDecimal(r)
   628  				if err != nil {
   629  					b.Fatal(err)
   630  				}
   631  				if isNull {
   632  					result.AppendNull()
   633  				} else {
   634  					result.AppendMyDecimal(v)
   635  				}
   636  			}
   637  		}
   638  	case types.ETDuration:
   639  		for i := 0; i < b.N; i++ {
   640  			result.Reset(eType)
   641  			for r := it.Begin(); r != it.End(); r = it.Next() {
   642  				v, isNull, err := rowDouble.evalDuration(r)
   643  				if err != nil {
   644  					b.Fatal(err)
   645  				}
   646  				if isNull {
   647  					result.AppendNull()
   648  				} else {
   649  					result.AppendDuration(v)
   650  				}
   651  			}
   652  		}
   653  	case types.ETString:
   654  		for i := 0; i < b.N; i++ {
   655  			result.Reset(eType)
   656  			for r := it.Begin(); r != it.End(); r = it.Next() {
   657  				v, isNull, err := rowDouble.evalString(r)
   658  				if err != nil {
   659  					b.Fatal(err)
   660  				}
   661  				if isNull {
   662  					result.AppendNull()
   663  				} else {
   664  					result.AppendString(v)
   665  				}
   666  			}
   667  		}
   668  	case types.ETDatetime:
   669  		for i := 0; i < b.N; i++ {
   670  			result.Reset(eType)
   671  			for r := it.Begin(); r != it.End(); r = it.Next() {
   672  				v, isNull, err := rowDouble.evalTime(r)
   673  				if err != nil {
   674  					b.Fatal(err)
   675  				}
   676  				if isNull {
   677  					result.AppendNull()
   678  				} else {
   679  					result.AppendTime(v)
   680  				}
   681  			}
   682  		}
   683  	case types.ETJson:
   684  		for i := 0; i < b.N; i++ {
   685  			result.Reset(eType)
   686  			for r := it.Begin(); r != it.End(); r = it.Next() {
   687  				v, isNull, err := rowDouble.evalJSON(r)
   688  				if err != nil {
   689  					b.Fatal(err)
   690  				}
   691  				if isNull {
   692  					result.AppendNull()
   693  				} else {
   694  					result.AppendJSON(v)
   695  				}
   696  			}
   697  		}
   698  	}
   699  }
   700  
   701  func BenchmarkMockDoubleRow(b *testing.B) {
   702  	typeNames := []string{"Int", "Real", "Decimal", "Duration", "String", "Datetime", "JSON"}
   703  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson}
   704  	for i, eType := range eTypes {
   705  		b.Run(typeNames[i], func(b *testing.B) {
   706  			rowDouble, input, result, _ := genMockRowDouble(eType, false)
   707  			it := chunk.NewIterator4Chunk(input)
   708  			b.ResetTimer()
   709  			evalRows(b, it, eType, result, rowDouble)
   710  		})
   711  	}
   712  }
   713  
   714  func BenchmarkMockDoubleVec(b *testing.B) {
   715  	typeNames := []string{"Int", "Real", "Decimal", "Duration", "String", "Datetime", "JSON"}
   716  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETDuration, types.ETString, types.ETDatetime, types.ETJson}
   717  	for i, eType := range eTypes {
   718  		b.Run(typeNames[i], func(b *testing.B) {
   719  			rowDouble, input, result, _ := genMockRowDouble(eType, true)
   720  			b.ResetTimer()
   721  			for i := 0; i < b.N; i++ {
   722  				if err := vecEvalType(rowDouble, eType, input, result); err != nil {
   723  					b.Fatal(err)
   724  				}
   725  			}
   726  		})
   727  	}
   728  }
   729  
   730  func (s *testEvaluatorSuite) TestVectorizedCheck(c *C) {
   731  	con := &Constant{}
   732  	c.Assert(con.Vectorized(), IsTrue)
   733  	defCaus := &DeferredCauset{}
   734  	c.Assert(defCaus.Vectorized(), IsTrue)
   735  	cor := CorrelatedDeferredCauset{DeferredCauset: *defCaus}
   736  	c.Assert(cor.Vectorized(), IsTrue)
   737  
   738  	vecF, _, _, _ := genMockRowDouble(types.ETInt, true)
   739  	sf := &ScalarFunction{Function: vecF}
   740  	c.Assert(sf.Vectorized(), IsTrue)
   741  
   742  	rowF, _, _, _ := genMockRowDouble(types.ETInt, false)
   743  	sf = &ScalarFunction{Function: rowF}
   744  	c.Assert(sf.Vectorized(), IsFalse)
   745  }
   746  
   747  func genFloat32DefCaus() (*DeferredCauset, *chunk.Chunk, *chunk.DeferredCauset) {
   748  	typeFloat := types.NewFieldType(allegrosql.TypeFloat)
   749  	defCaus := &DeferredCauset{Index: 0, RetType: typeFloat}
   750  	chk := chunk.NewChunkWithCapacity([]*types.FieldType{typeFloat}, 1024)
   751  	for i := 0; i < 1024; i++ {
   752  		chk.AppendFloat32(0, rand.Float32())
   753  	}
   754  	result := chunk.NewDeferredCauset(typeFloat, 1024)
   755  	return defCaus, chk, result
   756  }
   757  
   758  func (s *testEvaluatorSuite) TestFloat32DefCausVec(c *C) {
   759  	defCaus, chk, result := genFloat32DefCaus()
   760  	ctx := mock.NewContext()
   761  	c.Assert(defCaus.VecEvalReal(ctx, chk, result), IsNil)
   762  	it := chunk.NewIterator4Chunk(chk)
   763  	i := 0
   764  	for event := it.Begin(); event != it.End(); event = it.Next() {
   765  		v, _, err := defCaus.EvalReal(ctx, event)
   766  		c.Assert(err, IsNil)
   767  		c.Assert(v, Equals, result.GetFloat64(i))
   768  		i++
   769  	}
   770  
   771  	// set Sel
   772  	n := chk.NumRows()
   773  	sel := make([]int, n/2)
   774  	for i := 0; i < n; i += 2 {
   775  		sel = append(sel, i)
   776  	}
   777  	chk.SetSel(sel)
   778  	c.Assert(defCaus.VecEvalReal(ctx, chk, result), IsNil)
   779  	i = 0
   780  	for event := it.Begin(); event != it.End(); event = it.Next() {
   781  		v, _, err := defCaus.EvalReal(ctx, event)
   782  		c.Assert(err, IsNil)
   783  		c.Assert(v, Equals, result.GetFloat64(i))
   784  		i++
   785  	}
   786  
   787  	c.Assert(defCaus.VecEvalReal(ctx, chk, result), IsNil)
   788  }
   789  
   790  func BenchmarkFloat32DefCausRow(b *testing.B) {
   791  	defCaus, chk, _ := genFloat32DefCaus()
   792  	ctx := mock.NewContext()
   793  	it := chunk.NewIterator4Chunk(chk)
   794  	b.ResetTimer()
   795  	for i := 0; i < b.N; i++ {
   796  		for event := it.Begin(); event != it.End(); event = it.Next() {
   797  			if _, _, err := defCaus.EvalReal(ctx, event); err != nil {
   798  				b.Fatal(err)
   799  			}
   800  
   801  		}
   802  	}
   803  }
   804  
   805  func BenchmarkFloat32DefCausVec(b *testing.B) {
   806  	defCaus, chk, result := genFloat32DefCaus()
   807  	ctx := mock.NewContext()
   808  	b.ResetTimer()
   809  	for i := 0; i < b.N; i++ {
   810  		if err := defCaus.VecEvalReal(ctx, chk, result); err != nil {
   811  			b.Fatal(err)
   812  		}
   813  	}
   814  }