github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_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 "reflect" 18 "sync" 19 20 . "github.com/whtcorpsinc/check" 21 "github.com/whtcorpsinc/BerolinaSQL/ast" 22 "github.com/whtcorpsinc/BerolinaSQL/charset" 23 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 24 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 25 "github.com/whtcorpsinc/milevadb/stochastikctx" 26 "github.com/whtcorpsinc/milevadb/types" 27 "github.com/whtcorpsinc/milevadb/soliton/chunk" 28 ) 29 30 func evalBuiltinFuncConcurrent(f builtinFunc, event chunk.Event) (d types.Causet, err error) { 31 wg := sync.WaitGroup{} 32 concurrency := 10 33 wg.Add(concurrency) 34 var dagger sync.Mutex 35 err = nil 36 for i := 0; i < concurrency; i++ { 37 go func() { 38 defer wg.Done() 39 di, erri := evalBuiltinFunc(f, chunk.Event{}) 40 dagger.Lock() 41 if err == nil { 42 d, err = di, erri 43 } 44 dagger.Unlock() 45 }() 46 } 47 wg.Wait() 48 return 49 } 50 51 func evalBuiltinFunc(f builtinFunc, event chunk.Event) (d types.Causet, err error) { 52 var ( 53 res interface{} 54 isNull bool 55 ) 56 switch f.getRetTp().EvalType() { 57 case types.ETInt: 58 var intRes int64 59 intRes, isNull, err = f.evalInt(event) 60 if allegrosql.HasUnsignedFlag(f.getRetTp().Flag) { 61 res = uint64(intRes) 62 } else { 63 res = intRes 64 } 65 case types.ETReal: 66 res, isNull, err = f.evalReal(event) 67 case types.ETDecimal: 68 res, isNull, err = f.evalDecimal(event) 69 case types.ETDatetime, types.ETTimestamp: 70 res, isNull, err = f.evalTime(event) 71 case types.ETDuration: 72 res, isNull, err = f.evalDuration(event) 73 case types.ETJson: 74 res, isNull, err = f.evalJSON(event) 75 case types.ETString: 76 res, isNull, err = f.evalString(event) 77 } 78 79 if isNull || err != nil { 80 d.SetNull() 81 return d, err 82 } 83 d.SetValue(res, f.getRetTp()) 84 return 85 } 86 87 // tblToDtbl is a soliton function for test. 88 func tblToDtbl(i interface{}) []map[string][]types.Causet { 89 l := reflect.ValueOf(i).Len() 90 tbl := make([]map[string][]types.Causet, l) 91 for j := 0; j < l; j++ { 92 v := reflect.ValueOf(i).Index(j).Interface() 93 val := reflect.ValueOf(v) 94 t := reflect.TypeOf(v) 95 item := make(map[string][]types.Causet, val.NumField()) 96 for k := 0; k < val.NumField(); k++ { 97 tmp := val.Field(k).Interface() 98 item[t.Field(k).Name] = makeCausets(tmp) 99 } 100 tbl[j] = item 101 } 102 return tbl 103 } 104 105 func makeCausets(i interface{}) []types.Causet { 106 if i != nil { 107 t := reflect.TypeOf(i) 108 val := reflect.ValueOf(i) 109 switch t.HoTT() { 110 case reflect.Slice: 111 l := val.Len() 112 res := make([]types.Causet, l) 113 for j := 0; j < l; j++ { 114 res[j] = types.NewCauset(val.Index(j).Interface()) 115 } 116 return res 117 } 118 } 119 return types.MakeCausets(i) 120 } 121 122 func (s *testEvaluatorSuite) TestIsNullFunc(c *C) { 123 fc := funcs[ast.IsNull] 124 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(1))) 125 c.Assert(err, IsNil) 126 v, err := evalBuiltinFunc(f, chunk.Event{}) 127 c.Assert(err, IsNil) 128 c.Assert(v.GetInt64(), Equals, int64(0)) 129 130 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil))) 131 c.Assert(err, IsNil) 132 v, err = evalBuiltinFunc(f, chunk.Event{}) 133 c.Assert(err, IsNil) 134 c.Assert(v.GetInt64(), Equals, int64(1)) 135 } 136 137 func (s *testEvaluatorSuite) TestLock(c *C) { 138 dagger := funcs[ast.GetLock] 139 f, err := dagger.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil, 1))) 140 c.Assert(err, IsNil) 141 v, err := evalBuiltinFunc(f, chunk.Event{}) 142 c.Assert(err, IsNil) 143 c.Assert(v.GetInt64(), Equals, int64(1)) 144 145 releaseLock := funcs[ast.ReleaseLock] 146 f, err = releaseLock.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(1))) 147 c.Assert(err, IsNil) 148 v, err = evalBuiltinFunc(f, chunk.Event{}) 149 c.Assert(err, IsNil) 150 c.Assert(v.GetInt64(), Equals, int64(1)) 151 } 152 153 // newFunctionForTest creates a new ScalarFunction using funcName and arguments, 154 // it is different from memex.NewFunction which needs an additional retType argument. 155 func newFunctionForTest(ctx stochastikctx.Context, funcName string, args ...Expression) (Expression, error) { 156 fc, ok := funcs[funcName] 157 if !ok { 158 return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", funcName) 159 } 160 funcArgs := make([]Expression, len(args)) 161 copy(funcArgs, args) 162 f, err := fc.getFunction(ctx, funcArgs) 163 if err != nil { 164 return nil, err 165 } 166 return &ScalarFunction{ 167 FuncName: perceptron.NewCIStr(funcName), 168 RetType: f.getRetTp(), 169 Function: f, 170 }, nil 171 } 172 173 var ( 174 // MyALLEGROSQL int8. 175 int8Con = &Constant{RetType: &types.FieldType{Tp: allegrosql.TypeLonglong, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin}} 176 // MyALLEGROSQL varchar. 177 varcharCon = &Constant{RetType: &types.FieldType{Tp: allegrosql.TypeVarchar, Charset: charset.CharsetUTF8, DefCauslate: charset.DefCauslationUTF8}} 178 )