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  }