github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_other_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 "math" 18 "time" 19 20 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 21 "github.com/whtcorpsinc/BerolinaSQL/ast" 22 . "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/milevadb/soliton/chunk" 24 "github.com/whtcorpsinc/milevadb/soliton/defCauslate" 25 "github.com/whtcorpsinc/milevadb/soliton/replog" 26 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 27 "github.com/whtcorpsinc/milevadb/types" 28 "github.com/whtcorpsinc/milevadb/types/json" 29 ) 30 31 func (s *testEvaluatorSuite) TestBitCount(c *C) { 32 stmtCtx := s.ctx.GetStochastikVars().StmtCtx 33 origin := stmtCtx.IgnoreTruncate 34 stmtCtx.IgnoreTruncate = true 35 defer func() { 36 stmtCtx.IgnoreTruncate = origin 37 }() 38 fc := funcs[ast.BitCount] 39 var bitCountCases = []struct { 40 origin interface{} 41 count interface{} 42 }{ 43 {int64(8), int64(1)}, 44 {int64(29), int64(4)}, 45 {int64(0), int64(0)}, 46 {int64(-1), int64(64)}, 47 {int64(-11), int64(62)}, 48 {int64(-1000), int64(56)}, 49 {float64(1.1), int64(1)}, 50 {float64(3.1), int64(2)}, 51 {float64(-1.1), int64(64)}, 52 {float64(-3.1), int64(63)}, 53 {uint64(math.MaxUint64), int64(64)}, 54 {"xxx", int64(0)}, 55 {nil, nil}, 56 } 57 for _, test := range bitCountCases { 58 in := types.NewCauset(test.origin) 59 f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{in})) 60 c.Assert(err, IsNil) 61 c.Assert(f, NotNil) 62 count, err := evalBuiltinFunc(f, chunk.Event{}) 63 c.Assert(err, IsNil) 64 if count.IsNull() { 65 c.Assert(test.count, IsNil) 66 continue 67 } 68 sc := new(stmtctx.StatementContext) 69 sc.IgnoreTruncate = true 70 res, err := count.ToInt64(sc) 71 c.Assert(err, IsNil) 72 c.Assert(res, Equals, test.count) 73 } 74 } 75 76 func (s *testEvaluatorSuite) TestInFunc(c *C) { 77 fc := funcs[ast.In] 78 decimal1 := types.NewDecFromFloatForTest(123.121) 79 decimal2 := types.NewDecFromFloatForTest(123.122) 80 decimal3 := types.NewDecFromFloatForTest(123.123) 81 decimal4 := types.NewDecFromFloatForTest(123.124) 82 time1 := types.NewTime(types.FromGoTime(time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC)), allegrosql.TypeDatetime, 6) 83 time2 := types.NewTime(types.FromGoTime(time.Date(2020, 1, 2, 1, 1, 1, 1, time.UTC)), allegrosql.TypeDatetime, 6) 84 time3 := types.NewTime(types.FromGoTime(time.Date(2020, 1, 3, 1, 1, 1, 1, time.UTC)), allegrosql.TypeDatetime, 6) 85 time4 := types.NewTime(types.FromGoTime(time.Date(2020, 1, 4, 1, 1, 1, 1, time.UTC)), allegrosql.TypeDatetime, 6) 86 duration1 := types.Duration{Duration: 12*time.Hour + 1*time.Minute + 1*time.Second} 87 duration2 := types.Duration{Duration: 12*time.Hour + 1*time.Minute} 88 duration3 := types.Duration{Duration: 12*time.Hour + 1*time.Second} 89 duration4 := types.Duration{Duration: 12 * time.Hour} 90 json1 := json.CreateBinary("123") 91 json2 := json.CreateBinary("123.1") 92 json3 := json.CreateBinary("123.2") 93 json4 := json.CreateBinary("123.3") 94 testCases := []struct { 95 args []interface{} 96 res interface{} 97 }{ 98 {[]interface{}{1, 1, 2, 3}, int64(1)}, 99 {[]interface{}{1, 0, 2, 3}, int64(0)}, 100 {[]interface{}{1, nil, 2, 3}, nil}, 101 {[]interface{}{nil, nil, 2, 3}, nil}, 102 {[]interface{}{uint64(0), 0, 2, 3}, int64(1)}, 103 {[]interface{}{uint64(math.MaxUint64), uint64(math.MaxUint64), 2, 3}, int64(1)}, 104 {[]interface{}{-1, uint64(math.MaxUint64), 2, 3}, int64(0)}, 105 {[]interface{}{uint64(math.MaxUint64), -1, 2, 3}, int64(0)}, 106 {[]interface{}{1, 0, 2, 3}, int64(0)}, 107 {[]interface{}{1.1, 1.2, 1.3}, int64(0)}, 108 {[]interface{}{1.1, 1.1, 1.2, 1.3}, int64(1)}, 109 {[]interface{}{decimal1, decimal2, decimal3, decimal4}, int64(0)}, 110 {[]interface{}{decimal1, decimal2, decimal3, decimal1}, int64(1)}, 111 {[]interface{}{"1.1", "1.1", "1.2", "1.3"}, int64(1)}, 112 {[]interface{}{"1.1", replog.Slice("1.1"), "1.2", "1.3"}, int64(1)}, 113 {[]interface{}{replog.Slice("1.1"), "1.1", "1.2", "1.3"}, int64(1)}, 114 {[]interface{}{time1, time2, time3, time1}, int64(1)}, 115 {[]interface{}{time1, time2, time3, time4}, int64(0)}, 116 {[]interface{}{duration1, duration2, duration3, duration4}, int64(0)}, 117 {[]interface{}{duration1, duration2, duration1, duration4}, int64(1)}, 118 {[]interface{}{json1, json2, json3, json4}, int64(0)}, 119 {[]interface{}{json1, json1, json3, json4}, int64(1)}, 120 } 121 for _, tc := range testCases { 122 fn, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...))) 123 c.Assert(err, IsNil) 124 d, err := evalBuiltinFunc(fn, chunk.MutEventFromCausets(types.MakeCausets(tc.args...)).ToEvent()) 125 c.Assert(err, IsNil) 126 c.Assert(d.GetValue(), Equals, tc.res, Commentf("%v", types.MakeCausets(tc.args))) 127 } 128 defCauslate.SetNewDefCauslationEnabledForTest(true) 129 strD1 := types.NewDefCauslationStringCauset("a", "utf8_general_ci", 0) 130 strD2 := types.NewDefCauslationStringCauset("Á", "utf8_general_ci", 0) 131 fn, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{strD1, strD2})) 132 c.Assert(err, IsNil) 133 d, isNull, err := fn.evalInt(chunk.Event{}) 134 c.Assert(isNull, IsFalse) 135 c.Assert(err, IsNil) 136 c.Assert(d, Equals, int64(1), Commentf("%v, %v", strD1, strD2)) 137 chk1 := chunk.NewChunkWithCapacity(nil, 1) 138 chk1.SetNumVirtualEvents(1) 139 chk2 := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(allegrosql.TypeTiny)}, 1) 140 err = fn.vecEvalInt(chk1, chk2.DeferredCauset(0)) 141 c.Assert(err, IsNil) 142 c.Assert(chk2.DeferredCauset(0).GetInt64(0), Equals, int64(1)) 143 defCauslate.SetNewDefCauslationEnabledForTest(false) 144 } 145 146 func (s *testEvaluatorSuite) TestEventFunc(c *C) { 147 fc := funcs[ast.EventFunc] 148 _, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets([]interface{}{"1", 1.2, true, 120}...))) 149 c.Assert(err, IsNil) 150 } 151 152 func (s *testEvaluatorSuite) TestSetVar(c *C) { 153 fc := funcs[ast.SetVar] 154 testCases := []struct { 155 args []interface{} 156 res interface{} 157 }{ 158 {[]interface{}{"a", "12"}, "12"}, 159 {[]interface{}{"b", "34"}, "34"}, 160 {[]interface{}{"c", nil}, ""}, 161 {[]interface{}{"c", "ABC"}, "ABC"}, 162 {[]interface{}{"c", "dEf"}, "dEf"}, 163 } 164 for _, tc := range testCases { 165 fn, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...))) 166 c.Assert(err, IsNil) 167 d, err := evalBuiltinFunc(fn, chunk.MutEventFromCausets(types.MakeCausets(tc.args...)).ToEvent()) 168 c.Assert(err, IsNil) 169 c.Assert(d.GetString(), Equals, tc.res) 170 if tc.args[1] != nil { 171 key, ok := tc.args[0].(string) 172 c.Assert(ok, Equals, true) 173 val, ok := tc.res.(string) 174 c.Assert(ok, Equals, true) 175 stochastikVar, ok := s.ctx.GetStochastikVars().Users[key] 176 c.Assert(ok, Equals, true) 177 c.Assert(stochastikVar.GetString(), Equals, val) 178 } 179 } 180 } 181 182 func (s *testEvaluatorSuite) TestGetVar(c *C) { 183 fc := funcs[ast.GetVar] 184 185 stochastikVars := []struct { 186 key string 187 val string 188 }{ 189 {"a", "中"}, 190 {"b", "文字符chuan"}, 191 {"c", ""}, 192 } 193 for _, ekv := range stochastikVars { 194 s.ctx.GetStochastikVars().Users[ekv.key] = types.NewStringCauset(ekv.val) 195 } 196 197 testCases := []struct { 198 args []interface{} 199 res interface{} 200 }{ 201 {[]interface{}{"a"}, "中"}, 202 {[]interface{}{"b"}, "文字符chuan"}, 203 {[]interface{}{"c"}, ""}, 204 {[]interface{}{"d"}, ""}, 205 } 206 for _, tc := range testCases { 207 fn, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...))) 208 c.Assert(err, IsNil) 209 d, err := evalBuiltinFunc(fn, chunk.MutEventFromCausets(types.MakeCausets(tc.args...)).ToEvent()) 210 c.Assert(err, IsNil) 211 c.Assert(d.GetString(), Equals, tc.res) 212 } 213 } 214 215 func (s *testEvaluatorSuite) TestValues(c *C) { 216 origin := s.ctx.GetStochastikVars().StmtCtx.InInsertStmt 217 s.ctx.GetStochastikVars().StmtCtx.InInsertStmt = false 218 defer func() { 219 s.ctx.GetStochastikVars().StmtCtx.InInsertStmt = origin 220 }() 221 222 fc := &valuesFunctionClass{baseFunctionClass{ast.Values, 0, 0}, 1, types.NewFieldType(allegrosql.TypeVarchar)} 223 _, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(""))) 224 c.Assert(err, ErrorMatches, "*Incorrect parameter count in the call to native function 'values'") 225 226 sig, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets())) 227 c.Assert(err, IsNil) 228 229 ret, err := evalBuiltinFunc(sig, chunk.Event{}) 230 c.Assert(err, IsNil) 231 c.Assert(ret.IsNull(), IsTrue) 232 233 s.ctx.GetStochastikVars().CurrInsertValues = chunk.MutEventFromCausets(types.MakeCausets("1")).ToEvent() 234 ret, err = evalBuiltinFunc(sig, chunk.Event{}) 235 c.Assert(err, IsNil) 236 c.Assert(ret.IsNull(), IsTrue) 237 238 currInsertValues := types.MakeCausets("1", "2") 239 s.ctx.GetStochastikVars().StmtCtx.InInsertStmt = true 240 s.ctx.GetStochastikVars().CurrInsertValues = chunk.MutEventFromCausets(currInsertValues).ToEvent() 241 ret, err = evalBuiltinFunc(sig, chunk.Event{}) 242 c.Assert(err, IsNil) 243 244 cmp, err := ret.CompareCauset(nil, &currInsertValues[1]) 245 c.Assert(err, IsNil) 246 c.Assert(cmp, Equals, 0) 247 } 248 249 func (s *testEvaluatorSuite) TestSetVarFromDeferredCauset(c *C) { 250 // Construct arguments. 251 argVarName := &Constant{ 252 Value: types.NewStringCauset("a"), 253 RetType: &types.FieldType{Tp: allegrosql.TypeVarString, Flen: 20}, 254 } 255 argDefCaus := &DeferredCauset{ 256 RetType: &types.FieldType{Tp: allegrosql.TypeVarString, Flen: 20}, 257 Index: 0, 258 } 259 260 // Construct SetVar function. 261 funcSetVar, err := NewFunction( 262 s.ctx, 263 ast.SetVar, 264 &types.FieldType{Tp: allegrosql.TypeVarString, Flen: 20}, 265 []Expression{argVarName, argDefCaus}..., 266 ) 267 c.Assert(err, IsNil) 268 269 // Construct input and output Chunks. 270 inputChunk := chunk.NewChunkWithCapacity([]*types.FieldType{argDefCaus.RetType}, 1) 271 inputChunk.AppendString(0, "a") 272 outputChunk := chunk.NewChunkWithCapacity([]*types.FieldType{argDefCaus.RetType}, 1) 273 274 // Evaluate the SetVar function. 275 err = evalOneCell(s.ctx, funcSetVar, inputChunk.GetEvent(0), outputChunk, 0) 276 c.Assert(err, IsNil) 277 c.Assert(outputChunk.GetEvent(0).GetString(0), Equals, "a") 278 279 // Change the content of the underlying Chunk. 280 inputChunk.Reset() 281 inputChunk.AppendString(0, "b") 282 283 // Check whether the user variable changed. 284 stochastikVars := s.ctx.GetStochastikVars() 285 stochastikVars.UsersLock.RLock() 286 defer stochastikVars.UsersLock.RUnlock() 287 stochastikVar, ok := stochastikVars.Users["a"] 288 c.Assert(ok, Equals, true) 289 c.Assert(stochastikVar.GetString(), Equals, "a") 290 }