github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_info_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  
    19  	. "github.com/whtcorpsinc/check"
    20  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    21  	"github.com/whtcorpsinc/BerolinaSQL/auth"
    22  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    23  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    24  	"github.com/whtcorpsinc/milevadb/types"
    25  	"github.com/whtcorpsinc/milevadb/types/json"
    26  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    27  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    28  	"github.com/whtcorpsinc/milevadb/soliton/printer"
    29  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    30  )
    31  
    32  func (s *testEvaluatorSuite) TestDatabase(c *C) {
    33  	fc := funcs[ast.Database]
    34  	ctx := mock.NewContext()
    35  	f, err := fc.getFunction(ctx, nil)
    36  	c.Assert(err, IsNil)
    37  	d, err := evalBuiltinFunc(f, chunk.Event{})
    38  	c.Assert(err, IsNil)
    39  	c.Assert(d.HoTT(), Equals, types.HoTTNull)
    40  	ctx.GetStochastikVars().CurrentDB = "test"
    41  	d, err = evalBuiltinFunc(f, chunk.Event{})
    42  	c.Assert(err, IsNil)
    43  	c.Assert(d.GetString(), Equals, "test")
    44  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
    45  
    46  	// Test case for schemaReplicant().
    47  	fc = funcs[ast.Schema]
    48  	c.Assert(fc, NotNil)
    49  	f, err = fc.getFunction(ctx, nil)
    50  	c.Assert(err, IsNil)
    51  	d, err = evalBuiltinFunc(f, chunk.MutEventFromCausets(types.MakeCausets()).ToEvent())
    52  	c.Assert(err, IsNil)
    53  	c.Assert(d.GetString(), Equals, "test")
    54  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
    55  }
    56  
    57  func (s *testEvaluatorSuite) TestFoundEvents(c *C) {
    58  	ctx := mock.NewContext()
    59  	stochastikVars := ctx.GetStochastikVars()
    60  	stochastikVars.LastFoundEvents = 2
    61  
    62  	fc := funcs[ast.FoundEvents]
    63  	f, err := fc.getFunction(ctx, nil)
    64  	c.Assert(err, IsNil)
    65  	d, err := evalBuiltinFunc(f, chunk.Event{})
    66  	c.Assert(err, IsNil)
    67  	c.Assert(d.GetUint64(), Equals, uint64(2))
    68  }
    69  
    70  func (s *testEvaluatorSuite) TestUser(c *C) {
    71  	ctx := mock.NewContext()
    72  	stochastikVars := ctx.GetStochastikVars()
    73  	stochastikVars.User = &auth.UserIdentity{Username: "root", Hostname: "localhost"}
    74  
    75  	fc := funcs[ast.User]
    76  	f, err := fc.getFunction(ctx, nil)
    77  	c.Assert(err, IsNil)
    78  	d, err := evalBuiltinFunc(f, chunk.Event{})
    79  	c.Assert(err, IsNil)
    80  	c.Assert(d.GetString(), Equals, "root@localhost")
    81  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
    82  }
    83  
    84  func (s *testEvaluatorSuite) TestCurrentUser(c *C) {
    85  	ctx := mock.NewContext()
    86  	stochastikVars := ctx.GetStochastikVars()
    87  	stochastikVars.User = &auth.UserIdentity{Username: "root", Hostname: "localhost", AuthUsername: "root", AuthHostname: "localhost"}
    88  
    89  	fc := funcs[ast.CurrentUser]
    90  	f, err := fc.getFunction(ctx, nil)
    91  	c.Assert(err, IsNil)
    92  	d, err := evalBuiltinFunc(f, chunk.Event{})
    93  	c.Assert(err, IsNil)
    94  	c.Assert(d.GetString(), Equals, "root@localhost")
    95  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
    96  }
    97  
    98  func (s *testEvaluatorSuite) TestCurrentRole(c *C) {
    99  	ctx := mock.NewContext()
   100  	stochastikVars := ctx.GetStochastikVars()
   101  	stochastikVars.ActiveRoles = make([]*auth.RoleIdentity, 0, 10)
   102  	stochastikVars.ActiveRoles = append(stochastikVars.ActiveRoles, &auth.RoleIdentity{Username: "r_1", Hostname: "%"})
   103  	stochastikVars.ActiveRoles = append(stochastikVars.ActiveRoles, &auth.RoleIdentity{Username: "r_2", Hostname: "localhost"})
   104  
   105  	fc := funcs[ast.CurrentRole]
   106  	f, err := fc.getFunction(ctx, nil)
   107  	c.Assert(err, IsNil)
   108  	d, err := evalBuiltinFunc(f, chunk.Event{})
   109  	c.Assert(err, IsNil)
   110  	c.Assert(d.GetString(), Equals, "`r_1`@`%`,`r_2`@`localhost`")
   111  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
   112  }
   113  
   114  func (s *testEvaluatorSuite) TestConnectionID(c *C) {
   115  	ctx := mock.NewContext()
   116  	stochastikVars := ctx.GetStochastikVars()
   117  	stochastikVars.ConnectionID = uint64(1)
   118  
   119  	fc := funcs[ast.ConnectionID]
   120  	f, err := fc.getFunction(ctx, nil)
   121  	c.Assert(err, IsNil)
   122  	d, err := evalBuiltinFunc(f, chunk.Event{})
   123  	c.Assert(err, IsNil)
   124  	c.Assert(d.GetUint64(), Equals, uint64(1))
   125  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
   126  }
   127  
   128  func (s *testEvaluatorSuite) TestVersion(c *C) {
   129  	fc := funcs[ast.Version]
   130  	f, err := fc.getFunction(s.ctx, nil)
   131  	c.Assert(err, IsNil)
   132  	v, err := evalBuiltinFunc(f, chunk.Event{})
   133  	c.Assert(err, IsNil)
   134  	c.Assert(v.GetString(), Equals, allegrosql.ServerVersion)
   135  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
   136  }
   137  
   138  func (s *testEvaluatorSuite) TestBenchMark(c *C) {
   139  	cases := []struct {
   140  		LoopCount  int
   141  		Expression interface{}
   142  		Expected   int64
   143  		IsNil      bool
   144  	}{
   145  		{-3, 1, 0, true},
   146  		{0, 1, 0, false},
   147  		{3, 1, 0, false},
   148  		{3, 1.234, 0, false},
   149  		{3, types.NewDecFromFloatForTest(1.234), 0, false},
   150  		{3, "abc", 0, false},
   151  		{3, types.CurrentTime(allegrosql.TypeDatetime), 0, false},
   152  		{3, types.CurrentTime(allegrosql.TypeTimestamp), 0, false},
   153  		{3, types.CurrentTime(allegrosql.TypeDuration), 0, false},
   154  		{3, json.CreateBinary("[1]"), 0, false},
   155  	}
   156  
   157  	for _, t := range cases {
   158  		f, err := newFunctionForTest(s.ctx, ast.Benchmark, s.primitiveValsToConstants([]interface{}{
   159  			t.LoopCount,
   160  			t.Expression,
   161  		})...)
   162  		c.Assert(err, IsNil)
   163  
   164  		d, err := f.Eval(chunk.Event{})
   165  		c.Assert(err, IsNil)
   166  		if t.IsNil {
   167  			c.Assert(d.IsNull(), IsTrue)
   168  		} else {
   169  			c.Assert(d.GetInt64(), Equals, t.Expected)
   170  		}
   171  
   172  		// test clone
   173  		b1 := f.Clone().(*ScalarFunction).Function.(*builtinBenchmarkSig)
   174  		c.Assert(b1.constLoopCount, Equals, int64(t.LoopCount))
   175  	}
   176  }
   177  
   178  func (s *testEvaluatorSuite) TestCharset(c *C) {
   179  	fc := funcs[ast.Charset]
   180  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   181  	c.Assert(f, IsNil)
   182  	c.Assert(err, ErrorMatches, "*FUNCTION CHARSET does not exist")
   183  }
   184  
   185  func (s *testEvaluatorSuite) TestCoercibility(c *C) {
   186  	fc := funcs[ast.Coercibility]
   187  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   188  	c.Assert(f, NotNil)
   189  	c.Assert(err, IsNil)
   190  }
   191  
   192  func (s *testEvaluatorSuite) TestDefCauslation(c *C) {
   193  	fc := funcs[ast.DefCauslation]
   194  	f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil)))
   195  	c.Assert(f, NotNil)
   196  	c.Assert(err, IsNil)
   197  }
   198  
   199  func (s *testEvaluatorSuite) TestEventCount(c *C) {
   200  	ctx := mock.NewContext()
   201  	stochastikVars := ctx.GetStochastikVars()
   202  	stochastikVars.StmtCtx.PrevAffectedEvents = 10
   203  
   204  	f, err := funcs[ast.EventCount].getFunction(ctx, nil)
   205  	c.Assert(err, IsNil)
   206  	c.Assert(f, NotNil)
   207  	sig, ok := f.(*builtinEventCountSig)
   208  	c.Assert(ok, IsTrue)
   209  	c.Assert(sig, NotNil)
   210  	intResult, isNull, err := sig.evalInt(chunk.Event{})
   211  	c.Assert(err, IsNil)
   212  	c.Assert(isNull, IsFalse)
   213  	c.Assert(intResult, Equals, int64(10))
   214  	c.Assert(f.Clone().PbCode(), Equals, f.PbCode())
   215  }
   216  
   217  // TestMilevaDBVersion for milevadb_server().
   218  func (s *testEvaluatorSuite) TestMilevaDBVersion(c *C) {
   219  	f, err := newFunctionForTest(s.ctx, ast.MilevaDBVersion, s.primitiveValsToConstants([]interface{}{})...)
   220  	c.Assert(err, IsNil)
   221  	v, err := f.Eval(chunk.Event{})
   222  	c.Assert(err, IsNil)
   223  	c.Assert(v.GetString(), Equals, printer.GetMilevaDBInfo())
   224  }
   225  
   226  func (s *testEvaluatorSuite) TestLastInsertID(c *C) {
   227  	maxUint64 := uint64(math.MaxUint64)
   228  	cases := []struct {
   229  		insertID uint64
   230  		args     interface{}
   231  		expected uint64
   232  		isNil    bool
   233  		getErr   bool
   234  	}{
   235  		{0, 1, 1, false, false},
   236  		{0, 1.1, 1, false, false},
   237  		{0, maxUint64, maxUint64, false, false},
   238  		{0, -1, math.MaxUint64, false, false},
   239  		{1, nil, 1, false, false},
   240  		{math.MaxUint64, nil, math.MaxUint64, false, false},
   241  	}
   242  
   243  	for _, t := range cases {
   244  		var (
   245  			f   Expression
   246  			err error
   247  		)
   248  		if t.insertID > 0 {
   249  			s.ctx.GetStochastikVars().StmtCtx.PrevLastInsertID = t.insertID
   250  		}
   251  
   252  		if t.args != nil {
   253  			f, err = newFunctionForTest(s.ctx, ast.LastInsertId, s.primitiveValsToConstants([]interface{}{t.args})...)
   254  		} else {
   255  			f, err = newFunctionForTest(s.ctx, ast.LastInsertId)
   256  		}
   257  		tp := f.GetType()
   258  		c.Assert(err, IsNil)
   259  		c.Assert(tp.Tp, Equals, allegrosql.TypeLonglong)
   260  		c.Assert(tp.Charset, Equals, charset.CharsetBin)
   261  		c.Assert(tp.DefCauslate, Equals, charset.DefCauslationBin)
   262  		c.Assert(tp.Flag&allegrosql.BinaryFlag, Equals, allegrosql.BinaryFlag)
   263  		c.Assert(tp.Flen, Equals, allegrosql.MaxIntWidth)
   264  		d, err := f.Eval(chunk.Event{})
   265  		if t.getErr {
   266  			c.Assert(err, NotNil)
   267  		} else {
   268  			c.Assert(err, IsNil)
   269  			if t.isNil {
   270  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   271  			} else {
   272  				c.Assert(d.GetUint64(), Equals, t.expected)
   273  			}
   274  		}
   275  	}
   276  
   277  	_, err := funcs[ast.LastInsertId].getFunction(s.ctx, []Expression{NewZero()})
   278  	c.Assert(err, IsNil)
   279  }
   280  
   281  func (s *testEvaluatorSuite) TestFormatBytes(c *C) {
   282  	tbl := []struct {
   283  		Arg interface{}
   284  		Ret interface{}
   285  	}{
   286  		{nil, nil},
   287  		{float64(0), "0 bytes"},
   288  		{float64(2048), "2.00 KiB"},
   289  		{float64(75295729), "71.81 MiB"},
   290  		{float64(5287242702), "4.92 GiB"},
   291  		{float64(5039757204245), "4.58 TiB"},
   292  		{float64(890250274520475525), "790.70 PiB"},
   293  		{float64(18446644073709551615), "16.00 EiB"},
   294  		{float64(287952852482075252752429875), "2.50e+08 EiB"},
   295  		{float64(-18446644073709551615), "-16.00 EiB"},
   296  	}
   297  	Dtbl := tblToDtbl(tbl)
   298  
   299  	for _, t := range Dtbl {
   300  		fc := funcs[ast.FormatBytes]
   301  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   302  		c.Assert(err, IsNil)
   303  		v, err := evalBuiltinFunc(f, chunk.Event{})
   304  		c.Assert(err, IsNil)
   305  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
   306  	}
   307  }
   308  
   309  func (s *testEvaluatorSuite) TestFormatNanoTime(c *C) {
   310  	tbl := []struct {
   311  		Arg interface{}
   312  		Ret interface{}
   313  	}{
   314  		{nil, nil},
   315  		{float64(0), "0 ns"},
   316  		{float64(2000), "2.00 us"},
   317  		{float64(898787877), "898.79 ms"},
   318  		{float64(9999999991), "10.00 s"},
   319  		{float64(898787877424), "14.98 min"},
   320  		{float64(5827527520021), "1.62 h"},
   321  		{float64(42566623663736353), "492.67 d"},
   322  		{float64(4827524825702572425242552), "5.59e+10 d"},
   323  		{float64(-9999999991), "-10.00 s"},
   324  	}
   325  	Dtbl := tblToDtbl(tbl)
   326  
   327  	for _, t := range Dtbl {
   328  		fc := funcs[ast.FormatNanoTime]
   329  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   330  		c.Assert(err, IsNil)
   331  		v, err := evalBuiltinFunc(f, chunk.Event{})
   332  		c.Assert(err, IsNil)
   333  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
   334  	}
   335  }