github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_math_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  	"runtime"
    19  	"time"
    20  
    21  	. "github.com/whtcorpsinc/check"
    22  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    23  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    24  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    25  	"github.com/whtcorpsinc/milevadb/types"
    26  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    27  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    28  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    29  )
    30  
    31  func (s *testEvaluatorSuite) TestAbs(c *C) {
    32  	tbl := []struct {
    33  		Arg interface{}
    34  		Ret interface{}
    35  	}{
    36  		{nil, nil},
    37  		{int64(1), int64(1)},
    38  		{uint64(1), uint64(1)},
    39  		{int64(-1), int64(1)},
    40  		{float64(3.14), float64(3.14)},
    41  		{float64(-3.14), float64(3.14)},
    42  	}
    43  
    44  	Dtbl := tblToDtbl(tbl)
    45  
    46  	for _, t := range Dtbl {
    47  		fc := funcs[ast.Abs]
    48  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
    49  		c.Assert(err, IsNil)
    50  		v, err := evalBuiltinFunc(f, chunk.Event{})
    51  		c.Assert(err, IsNil)
    52  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
    53  	}
    54  }
    55  
    56  func (s *testEvaluatorSuite) TestCeil(c *C) {
    57  	sc := s.ctx.GetStochastikVars().StmtCtx
    58  	tmpIT := sc.IgnoreTruncate
    59  	sc.IgnoreTruncate = true
    60  	defer func() {
    61  		sc.IgnoreTruncate = tmpIT
    62  	}()
    63  
    64  	type testCase struct {
    65  		arg    interface{}
    66  		expect interface{}
    67  		isNil  bool
    68  		getErr bool
    69  	}
    70  
    71  	cases := []testCase{
    72  		{nil, nil, true, false},
    73  		{int64(1), int64(1), false, false},
    74  		{float64(1.23), float64(2), false, false},
    75  		{float64(-1.23), float64(-1), false, false},
    76  		{"1.23", float64(2), false, false},
    77  		{"-1.23", float64(-1), false, false},
    78  		{"milevadb", float64(0), false, false},
    79  		{"1milevadb", float64(1), false, false}}
    80  
    81  	memexs := []Expression{
    82  		&Constant{
    83  			Value:   types.NewCauset(0),
    84  			RetType: types.NewFieldType(allegrosql.TypeTiny),
    85  		},
    86  		&Constant{
    87  			Value:   types.NewFloat64Causet(float64(12.34)),
    88  			RetType: types.NewFieldType(allegrosql.TypeFloat),
    89  		},
    90  	}
    91  
    92  	runCasesOn := func(funcName string, cases []testCase, exps []Expression) {
    93  		for _, test := range cases {
    94  			f, err := newFunctionForTest(s.ctx, funcName, s.primitiveValsToConstants([]interface{}{test.arg})...)
    95  			c.Assert(err, IsNil)
    96  
    97  			result, err := f.Eval(chunk.Event{})
    98  			if test.getErr {
    99  				c.Assert(err, NotNil)
   100  			} else {
   101  				c.Assert(err, IsNil)
   102  				if test.isNil {
   103  					c.Assert(result.HoTT(), Equals, types.HoTTNull)
   104  				} else {
   105  					c.Assert(result, solitonutil.CausetEquals, types.NewCauset(test.expect))
   106  				}
   107  			}
   108  		}
   109  
   110  		for _, exp := range exps {
   111  			_, err := funcs[funcName].getFunction(s.ctx, []Expression{exp})
   112  			c.Assert(err, IsNil)
   113  		}
   114  	}
   115  
   116  	runCasesOn(ast.Ceil, cases, memexs)
   117  	runCasesOn(ast.Ceiling, cases, memexs)
   118  }
   119  
   120  func (s *testEvaluatorSuite) TestExp(c *C) {
   121  	tests := []struct {
   122  		args       interface{}
   123  		expect     float64
   124  		isNil      bool
   125  		getWarning bool
   126  		errMsg     string
   127  	}{
   128  		{nil, 0, true, false, ""},
   129  		{int64(1), 2.718281828459045, false, false, ""},
   130  		{float64(1.23), 3.4212295362896734, false, false, ""},
   131  		{float64(-1.23), 0.2922925776808594, false, false, ""},
   132  		{float64(0), 1, false, false, ""},
   133  		{"0", 1, false, false, ""},
   134  		{"milevadb", 0, false, true, ""},
   135  		{float64(100000), 0, false, true, "[types:1690]DOUBLE value is out of range in 'exp(100000)'"},
   136  	}
   137  
   138  	if runtime.GOARCH == "ppc64le" {
   139  		tests[1].expect = 2.7182818284590455
   140  	}
   141  
   142  	for _, test := range tests {
   143  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   144  		f, err := newFunctionForTest(s.ctx, ast.Exp, s.primitiveValsToConstants([]interface{}{test.args})...)
   145  		c.Assert(err, IsNil)
   146  
   147  		result, err := f.Eval(chunk.Event{})
   148  		if test.getWarning {
   149  			if test.errMsg != "" {
   150  				c.Assert(err, NotNil)
   151  				c.Assert(err.Error(), Equals, test.errMsg)
   152  			} else {
   153  				c.Assert(err, IsNil)
   154  				c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   155  			}
   156  		} else {
   157  			c.Assert(err, IsNil)
   158  			if test.isNil {
   159  				c.Assert(result.HoTT(), Equals, types.HoTTNull)
   160  			} else {
   161  				c.Assert(result.GetFloat64(), Equals, test.expect)
   162  			}
   163  		}
   164  	}
   165  
   166  	_, err := funcs[ast.Exp].getFunction(s.ctx, []Expression{NewZero()})
   167  	c.Assert(err, IsNil)
   168  }
   169  
   170  func (s *testEvaluatorSuite) TestFloor(c *C) {
   171  	sc := s.ctx.GetStochastikVars().StmtCtx
   172  	tmpIT := sc.IgnoreTruncate
   173  	sc.IgnoreTruncate = true
   174  	defer func() {
   175  		sc.IgnoreTruncate = tmpIT
   176  	}()
   177  
   178  	genDuration := func(h, m, s int64) types.Duration {
   179  		duration := time.Duration(h)*time.Hour +
   180  			time.Duration(m)*time.Minute +
   181  			time.Duration(s)*time.Second
   182  
   183  		return types.Duration{Duration: duration, Fsp: types.DefaultFsp}
   184  	}
   185  
   186  	genTime := func(y, m, d int) types.Time {
   187  		return types.NewTime(types.FromDate(y, m, d, 0, 0, 0, 0), allegrosql.TypeDatetime, types.DefaultFsp)
   188  	}
   189  
   190  	for _, test := range []struct {
   191  		arg    interface{}
   192  		expect interface{}
   193  		isNil  bool
   194  		getErr bool
   195  	}{
   196  		{nil, nil, true, false},
   197  		{int64(1), int64(1), false, false},
   198  		{float64(1.23), float64(1), false, false},
   199  		{float64(-1.23), float64(-2), false, false},
   200  		{"1.23", float64(1), false, false},
   201  		{"-1.23", float64(-2), false, false},
   202  		{"-1.b23", float64(-1), false, false},
   203  		{"abce", float64(0), false, false},
   204  		{genDuration(12, 59, 59), float64(125959), false, false},
   205  		{genDuration(0, 12, 34), float64(1234), false, false},
   206  		{genTime(2020, 7, 19), float64(20170719000000), false, false},
   207  	} {
   208  		f, err := newFunctionForTest(s.ctx, ast.Floor, s.primitiveValsToConstants([]interface{}{test.arg})...)
   209  		c.Assert(err, IsNil)
   210  
   211  		result, err := f.Eval(chunk.Event{})
   212  		if test.getErr {
   213  			c.Assert(err, NotNil)
   214  		} else {
   215  			c.Assert(err, IsNil)
   216  			if test.isNil {
   217  				c.Assert(result.HoTT(), Equals, types.HoTTNull)
   218  			} else {
   219  				c.Assert(result, solitonutil.CausetEquals, types.NewCauset(test.expect))
   220  			}
   221  		}
   222  	}
   223  
   224  	for _, exp := range []Expression{
   225  		&Constant{
   226  			Value:   types.NewCauset(0),
   227  			RetType: types.NewFieldType(allegrosql.TypeTiny),
   228  		},
   229  		&Constant{
   230  			Value:   types.NewFloat64Causet(float64(12.34)),
   231  			RetType: types.NewFieldType(allegrosql.TypeFloat),
   232  		},
   233  	} {
   234  		_, err := funcs[ast.Floor].getFunction(s.ctx, []Expression{exp})
   235  		c.Assert(err, IsNil)
   236  	}
   237  }
   238  
   239  func (s *testEvaluatorSuite) TestLog(c *C) {
   240  	tests := []struct {
   241  		args         []interface{}
   242  		expect       float64
   243  		isNil        bool
   244  		warningCount uint16
   245  	}{
   246  		{[]interface{}{nil}, 0, true, 0},
   247  		{[]interface{}{nil, nil}, 0, true, 0},
   248  		{[]interface{}{int64(100)}, 4.605170185988092, false, 0},
   249  		{[]interface{}{float64(100)}, 4.605170185988092, false, 0},
   250  		{[]interface{}{int64(10), int64(100)}, 2, false, 0},
   251  		{[]interface{}{float64(10), float64(100)}, 2, false, 0},
   252  		{[]interface{}{float64(-1)}, 0, true, 1},
   253  		{[]interface{}{float64(2), float64(-1)}, 0, true, 1},
   254  		{[]interface{}{float64(-1), float64(2)}, 0, true, 1},
   255  		{[]interface{}{float64(1), float64(2)}, 0, true, 1},
   256  		{[]interface{}{float64(0.5), float64(0.25)}, 2, false, 0},
   257  		{[]interface{}{"abc"}, 0, true, 2},
   258  	}
   259  
   260  	for _, test := range tests {
   261  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   262  		f, err := newFunctionForTest(s.ctx, ast.Log, s.primitiveValsToConstants(test.args)...)
   263  		c.Assert(err, IsNil)
   264  
   265  		result, err := f.Eval(chunk.Event{})
   266  		c.Assert(err, IsNil)
   267  		if test.warningCount > 0 {
   268  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+test.warningCount)
   269  		}
   270  		if test.isNil {
   271  			c.Assert(result.HoTT(), Equals, types.HoTTNull)
   272  		} else {
   273  			c.Assert(result.GetFloat64(), Equals, test.expect)
   274  		}
   275  	}
   276  
   277  	_, err := funcs[ast.Log].getFunction(s.ctx, []Expression{NewZero()})
   278  	c.Assert(err, IsNil)
   279  }
   280  
   281  func (s *testEvaluatorSuite) TestLog2(c *C) {
   282  	tests := []struct {
   283  		args         interface{}
   284  		expect       float64
   285  		isNil        bool
   286  		warningCount uint16
   287  	}{
   288  		{nil, 0, true, 0},
   289  		{int64(16), 4, false, 0},
   290  		{float64(16), 4, false, 0},
   291  		{int64(5), 2.321928094887362, false, 0},
   292  		{int64(-1), 0, true, 1},
   293  		{"4abc", 2, false, 1},
   294  		{"abc", 0, true, 2},
   295  	}
   296  
   297  	for _, test := range tests {
   298  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   299  		f, err := newFunctionForTest(s.ctx, ast.Log2, s.primitiveValsToConstants([]interface{}{test.args})...)
   300  		c.Assert(err, IsNil)
   301  
   302  		result, err := f.Eval(chunk.Event{})
   303  		c.Assert(err, IsNil)
   304  		if test.warningCount > 0 {
   305  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+test.warningCount)
   306  		}
   307  		if test.isNil {
   308  			c.Assert(result.HoTT(), Equals, types.HoTTNull)
   309  		} else {
   310  			c.Assert(result.GetFloat64(), Equals, test.expect)
   311  		}
   312  	}
   313  
   314  	_, err := funcs[ast.Log2].getFunction(s.ctx, []Expression{NewZero()})
   315  	c.Assert(err, IsNil)
   316  }
   317  
   318  func (s *testEvaluatorSuite) TestLog10(c *C) {
   319  	tests := []struct {
   320  		args         interface{}
   321  		expect       float64
   322  		isNil        bool
   323  		warningCount uint16
   324  	}{
   325  		{nil, 0, true, 0},
   326  		{int64(100), 2, false, 0},
   327  		{float64(100), 2, false, 0},
   328  		{int64(101), 2.0043213737826426, false, 0},
   329  		{int64(-1), 0, true, 1},
   330  		{"100abc", 2, false, 1},
   331  		{"abc", 0, true, 2},
   332  	}
   333  
   334  	for _, test := range tests {
   335  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   336  		f, err := newFunctionForTest(s.ctx, ast.Log10, s.primitiveValsToConstants([]interface{}{test.args})...)
   337  		c.Assert(err, IsNil)
   338  
   339  		result, err := f.Eval(chunk.Event{})
   340  		c.Assert(err, IsNil)
   341  		if test.warningCount > 0 {
   342  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+test.warningCount)
   343  		}
   344  		if test.isNil {
   345  			c.Assert(result.HoTT(), Equals, types.HoTTNull)
   346  		} else {
   347  			c.Assert(result.GetFloat64(), Equals, test.expect)
   348  		}
   349  	}
   350  
   351  	_, err := funcs[ast.Log10].getFunction(s.ctx, []Expression{NewZero()})
   352  	c.Assert(err, IsNil)
   353  }
   354  
   355  func (s *testEvaluatorSuite) TestRand(c *C) {
   356  	fc := funcs[ast.Rand]
   357  	f, err := fc.getFunction(s.ctx, nil)
   358  	c.Assert(err, IsNil)
   359  	v, err := evalBuiltinFunc(f, chunk.Event{})
   360  	c.Assert(err, IsNil)
   361  	c.Assert(v.GetFloat64(), Less, float64(1))
   362  	c.Assert(v.GetFloat64(), GreaterEqual, float64(0))
   363  
   364  	// issue 3211
   365  	f2, err := fc.getFunction(s.ctx, []Expression{&Constant{Value: types.NewIntCauset(20160101), RetType: types.NewFieldType(allegrosql.TypeLonglong)}})
   366  	c.Assert(err, IsNil)
   367  	randGen := NewWithSeed(20160101)
   368  	for i := 0; i < 3; i++ {
   369  		v, err = evalBuiltinFunc(f2, chunk.Event{})
   370  		c.Assert(err, IsNil)
   371  		c.Assert(v.GetFloat64(), Equals, randGen.Gen())
   372  	}
   373  }
   374  
   375  func (s *testEvaluatorSuite) TestPow(c *C) {
   376  	tbl := []struct {
   377  		Arg []interface{}
   378  		Ret float64
   379  	}{
   380  		{[]interface{}{1, 3}, 1},
   381  		{[]interface{}{2, 2}, 4},
   382  		{[]interface{}{4, 0.5}, 2},
   383  		{[]interface{}{4, -2}, 0.0625},
   384  	}
   385  
   386  	Dtbl := tblToDtbl(tbl)
   387  
   388  	for _, t := range Dtbl {
   389  		fc := funcs[ast.Pow]
   390  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   391  		c.Assert(err, IsNil)
   392  		v, err := evalBuiltinFunc(f, chunk.Event{})
   393  		c.Assert(err, IsNil)
   394  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
   395  	}
   396  
   397  	errTbl := []struct {
   398  		Arg []interface{}
   399  	}{
   400  		{[]interface{}{"test", "test"}},
   401  		{[]interface{}{1, "test"}},
   402  		{[]interface{}{10, 700}}, // added overflow test
   403  	}
   404  
   405  	errDtbl := tblToDtbl(errTbl)
   406  	for i, t := range errDtbl {
   407  		fc := funcs[ast.Pow]
   408  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   409  		c.Assert(err, IsNil)
   410  		_, err = evalBuiltinFunc(f, chunk.Event{})
   411  		if i == 2 {
   412  			c.Assert(err, NotNil)
   413  			c.Assert(err.Error(), Equals, "[types:1690]DOUBLE value is out of range in 'pow(10, 700)'")
   414  		} else {
   415  			c.Assert(err, IsNil)
   416  		}
   417  	}
   418  	c.Assert(int(s.ctx.GetStochastikVars().StmtCtx.WarningCount()), Equals, 3)
   419  }
   420  
   421  func (s *testEvaluatorSuite) TestRound(c *C) {
   422  	newDec := types.NewDecFromStringForTest
   423  	tbl := []struct {
   424  		Arg []interface{}
   425  		Ret interface{}
   426  	}{
   427  		{[]interface{}{-1.23}, -1},
   428  		{[]interface{}{-1.23, 0}, -1},
   429  		{[]interface{}{-1.58}, -2},
   430  		{[]interface{}{1.58}, 2},
   431  		{[]interface{}{1.298, 1}, 1.3},
   432  		{[]interface{}{1.298}, 1},
   433  		{[]interface{}{1.298, 0}, 1},
   434  		{[]interface{}{23.298, -1}, 20},
   435  		{[]interface{}{newDec("-1.23")}, newDec("-1")},
   436  		{[]interface{}{newDec("-1.23"), 1}, newDec("-1.2")},
   437  		{[]interface{}{newDec("-1.58")}, newDec("-2")},
   438  		{[]interface{}{newDec("1.58")}, newDec("2")},
   439  		{[]interface{}{newDec("1.58"), 1}, newDec("1.6")},
   440  		{[]interface{}{newDec("23.298"), -1}, newDec("20")},
   441  		{[]interface{}{nil, 2}, nil},
   442  		{[]interface{}{1, -2012}, 0},
   443  		{[]interface{}{1, -201299999999999}, 0},
   444  	}
   445  
   446  	Dtbl := tblToDtbl(tbl)
   447  
   448  	for _, t := range Dtbl {
   449  		fc := funcs[ast.Round]
   450  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   451  		c.Assert(err, IsNil)
   452  		switch f.(type) {
   453  		case *builtinRoundWithFracIntSig:
   454  			c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundWithFracInt)
   455  		case *builtinRoundWithFracDecSig:
   456  			c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundWithFracDec)
   457  		case *builtinRoundWithFracRealSig:
   458  			c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundWithFracReal)
   459  		case *builtinRoundIntSig:
   460  			c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundInt)
   461  		case *builtinRoundDecSig:
   462  			c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundDec)
   463  		case *builtinRoundRealSig:
   464  			c.Assert(f.PbCode(), Equals, fidelpb.ScalarFuncSig_RoundReal)
   465  		}
   466  		v, err := evalBuiltinFunc(f, chunk.Event{})
   467  		c.Assert(err, IsNil)
   468  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
   469  	}
   470  }
   471  
   472  func (s *testEvaluatorSuite) TestTruncate(c *C) {
   473  	newDec := types.NewDecFromStringForTest
   474  	tbl := []struct {
   475  		Arg []interface{}
   476  		Ret interface{}
   477  	}{
   478  		{[]interface{}{-1.23, 0}, -1},
   479  		{[]interface{}{1.58, 0}, 1},
   480  		{[]interface{}{1.298, 1}, 1.2},
   481  		{[]interface{}{123.2, -1}, 120},
   482  		{[]interface{}{123.2, 100}, 123.2},
   483  		{[]interface{}{123.2, -100}, 0},
   484  		{[]interface{}{123.2, -100}, 0},
   485  		{[]interface{}{1.797693134862315708145274237317043567981e+308, 2},
   486  			1.797693134862315708145274237317043567981e+308},
   487  		{[]interface{}{newDec("-1.23"), 0}, newDec("-1")},
   488  		{[]interface{}{newDec("-1.23"), 1}, newDec("-1.2")},
   489  		{[]interface{}{newDec("-11.23"), -1}, newDec("-10")},
   490  		{[]interface{}{newDec("1.58"), 0}, newDec("1")},
   491  		{[]interface{}{newDec("1.58"), 1}, newDec("1.5")},
   492  		{[]interface{}{newDec("11.58"), -1}, newDec("10")},
   493  		{[]interface{}{newDec("23.298"), -1}, newDec("20")},
   494  		{[]interface{}{newDec("23.298"), -100}, newDec("0")},
   495  		{[]interface{}{newDec("23.298"), 100}, newDec("23.298")},
   496  		{[]interface{}{nil, 2}, nil},
   497  		{[]interface{}{uint64(9223372036854775808), -10}, 9223372030000000000},
   498  		{[]interface{}{9223372036854775807, -7}, 9223372036850000000},
   499  		{[]interface{}{uint64(18446744073709551615), -10}, uint64(18446744070000000000)},
   500  	}
   501  
   502  	Dtbl := tblToDtbl(tbl)
   503  
   504  	for _, t := range Dtbl {
   505  		fc := funcs[ast.Truncate]
   506  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   507  		c.Assert(err, IsNil)
   508  		c.Assert(f, NotNil)
   509  		v, err := evalBuiltinFunc(f, chunk.Event{})
   510  		c.Assert(err, IsNil)
   511  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
   512  	}
   513  }
   514  
   515  func (s *testEvaluatorSuite) TestCRC32(c *C) {
   516  	tbl := []struct {
   517  		Arg []interface{}
   518  		Ret interface{}
   519  	}{
   520  		{[]interface{}{nil}, nil},
   521  		{[]interface{}{""}, 0},
   522  		{[]interface{}{-1}, 808273962},
   523  		{[]interface{}{"-1"}, 808273962},
   524  		{[]interface{}{"allegrosql"}, 2501908538},
   525  		{[]interface{}{"MyALLEGROSQL"}, 3259397556},
   526  		{[]interface{}{"hello"}, 907060870},
   527  	}
   528  
   529  	Dtbl := tblToDtbl(tbl)
   530  
   531  	for _, t := range Dtbl {
   532  		fc := funcs[ast.CRC32]
   533  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   534  		c.Assert(err, IsNil)
   535  		v, err := evalBuiltinFunc(f, chunk.Event{})
   536  		c.Assert(err, IsNil)
   537  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
   538  	}
   539  }
   540  
   541  func (s *testEvaluatorSuite) TestConv(c *C) {
   542  	cases := []struct {
   543  		args     []interface{}
   544  		expected interface{}
   545  		isNil    bool
   546  		getErr   bool
   547  	}{
   548  		{[]interface{}{"a", 16, 2}, "1010", false, false},
   549  		{[]interface{}{"6E", 18, 8}, "172", false, false},
   550  		{[]interface{}{"-17", 10, -18}, "-H", false, false},
   551  		{[]interface{}{"-17", 10, 18}, "2D3FGB0B9CG4BD1H", false, false},
   552  		{[]interface{}{nil, 10, 10}, "0", true, false},
   553  		{[]interface{}{"+18aZ", 7, 36}, "1", false, false},
   554  		{[]interface{}{"18446744073709551615", -10, 16}, "7FFFFFFFFFFFFFFF", false, false},
   555  		{[]interface{}{"12F", -10, 16}, "C", false, false},
   556  		{[]interface{}{"  FF ", 16, 10}, "255", false, false},
   557  		{[]interface{}{"MilevaDB", 10, 8}, "0", false, false},
   558  		{[]interface{}{"aa", 10, 2}, "0", false, false},
   559  		{[]interface{}{" A", -10, 16}, "0", false, false},
   560  		{[]interface{}{"a6a", 10, 8}, "0", false, false},
   561  		{[]interface{}{"a6a", 1, 8}, "0", true, false},
   562  	}
   563  
   564  	for _, t := range cases {
   565  		f, err := newFunctionForTest(s.ctx, ast.Conv, s.primitiveValsToConstants(t.args)...)
   566  		c.Assert(err, IsNil)
   567  		tp := f.GetType()
   568  		c.Assert(tp.Tp, Equals, allegrosql.TypeVarString)
   569  		c.Assert(tp.Charset, Equals, charset.CharsetUTF8MB4)
   570  		c.Assert(tp.DefCauslate, Equals, charset.DefCauslationUTF8MB4)
   571  		c.Assert(tp.Flag, Equals, uint(0))
   572  
   573  		d, err := f.Eval(chunk.Event{})
   574  		if t.getErr {
   575  			c.Assert(err, NotNil)
   576  		} else {
   577  			c.Assert(err, IsNil)
   578  			if t.isNil {
   579  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   580  			} else {
   581  				c.Assert(d.GetString(), Equals, t.expected)
   582  			}
   583  		}
   584  	}
   585  
   586  	v := []struct {
   587  		s    string
   588  		base int64
   589  		ret  string
   590  	}{
   591  		{"-123456D1f", 5, "-1234"},
   592  		{"+12azD", 16, "12a"},
   593  		{"+", 12, ""},
   594  	}
   595  	for _, t := range v {
   596  		r := getValidPrefix(t.s, t.base)
   597  		c.Assert(r, Equals, t.ret)
   598  	}
   599  
   600  	_, err := funcs[ast.Conv].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()})
   601  	c.Assert(err, IsNil)
   602  }
   603  
   604  func (s *testEvaluatorSuite) TestSign(c *C) {
   605  	sc := s.ctx.GetStochastikVars().StmtCtx
   606  	tmpIT := sc.IgnoreTruncate
   607  	sc.IgnoreTruncate = true
   608  	defer func() {
   609  		sc.IgnoreTruncate = tmpIT
   610  	}()
   611  
   612  	for _, t := range []struct {
   613  		num []interface{}
   614  		ret interface{}
   615  	}{
   616  		{[]interface{}{nil}, nil},
   617  		{[]interface{}{1}, int64(1)},
   618  		{[]interface{}{0}, int64(0)},
   619  		{[]interface{}{-1}, int64(-1)},
   620  		{[]interface{}{0.4}, int64(1)},
   621  		{[]interface{}{-0.4}, int64(-1)},
   622  		{[]interface{}{"1"}, int64(1)},
   623  		{[]interface{}{"-1"}, int64(-1)},
   624  		{[]interface{}{"1a"}, int64(1)},
   625  		{[]interface{}{"-1a"}, int64(-1)},
   626  		{[]interface{}{"a"}, int64(0)},
   627  		{[]interface{}{uint64(9223372036854775808)}, int64(1)},
   628  	} {
   629  		fc := funcs[ast.Sign]
   630  		f, err := fc.getFunction(s.ctx, s.primitiveValsToConstants(t.num))
   631  		c.Assert(err, IsNil, Commentf("%v", t))
   632  		v, err := evalBuiltinFunc(f, chunk.Event{})
   633  		c.Assert(err, IsNil, Commentf("%v", t))
   634  		c.Assert(v, solitonutil.CausetEquals, types.NewCauset(t.ret), Commentf("%v", t))
   635  	}
   636  }
   637  
   638  func (s *testEvaluatorSuite) TestDegrees(c *C) {
   639  	sc := s.ctx.GetStochastikVars().StmtCtx
   640  	sc.IgnoreTruncate = false
   641  	cases := []struct {
   642  		args       interface{}
   643  		expected   float64
   644  		isNil      bool
   645  		getWarning bool
   646  	}{
   647  		{nil, 0, true, false},
   648  		{int64(0), float64(0), false, false},
   649  		{int64(1), float64(57.29577951308232), false, false},
   650  		{float64(1), float64(57.29577951308232), false, false},
   651  		{float64(math.Pi), float64(180), false, false},
   652  		{float64(-math.Pi / 2), float64(-90), false, false},
   653  		{"", float64(0), false, false},
   654  		{"-2", float64(-114.59155902616465), false, false},
   655  		{"abc", float64(0), false, true},
   656  		{"+1abc", 57.29577951308232, false, true},
   657  	}
   658  
   659  	for _, t := range cases {
   660  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   661  		f, err := newFunctionForTest(s.ctx, ast.Degrees, s.primitiveValsToConstants([]interface{}{t.args})...)
   662  		c.Assert(err, IsNil)
   663  		d, err := f.Eval(chunk.Event{})
   664  		if t.getWarning {
   665  			c.Assert(err, IsNil)
   666  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   667  		} else {
   668  			c.Assert(err, IsNil)
   669  			if t.isNil {
   670  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   671  			} else {
   672  				c.Assert(d.GetFloat64(), Equals, t.expected)
   673  			}
   674  		}
   675  	}
   676  	_, err := funcs[ast.Degrees].getFunction(s.ctx, []Expression{NewZero()})
   677  	c.Assert(err, IsNil)
   678  }
   679  
   680  func (s *testEvaluatorSuite) TestSqrt(c *C) {
   681  	tbl := []struct {
   682  		Arg []interface{}
   683  		Ret interface{}
   684  	}{
   685  		{[]interface{}{nil}, nil},
   686  		{[]interface{}{int64(1)}, float64(1)},
   687  		{[]interface{}{float64(4)}, float64(2)},
   688  		{[]interface{}{"4"}, float64(2)},
   689  		{[]interface{}{"9"}, float64(3)},
   690  		{[]interface{}{"-16"}, nil},
   691  	}
   692  
   693  	for _, t := range tbl {
   694  		fc := funcs[ast.Sqrt]
   695  		f, err := fc.getFunction(s.ctx, s.primitiveValsToConstants(t.Arg))
   696  		c.Assert(err, IsNil)
   697  		v, err := evalBuiltinFunc(f, chunk.Event{})
   698  		c.Assert(err, IsNil)
   699  		c.Assert(v, solitonutil.CausetEquals, types.NewCauset(t.Ret), Commentf("%v", t))
   700  	}
   701  }
   702  
   703  func (s *testEvaluatorSuite) TestPi(c *C) {
   704  	f, err := funcs[ast.PI].getFunction(s.ctx, nil)
   705  	c.Assert(err, IsNil)
   706  
   707  	pi, err := evalBuiltinFunc(f, chunk.Event{})
   708  	c.Assert(err, IsNil)
   709  	c.Assert(pi, solitonutil.CausetEquals, types.NewCauset(math.Pi))
   710  }
   711  
   712  func (s *testEvaluatorSuite) TestRadians(c *C) {
   713  	tbl := []struct {
   714  		Arg interface{}
   715  		Ret interface{}
   716  	}{
   717  		{nil, nil},
   718  		{0, float64(0)},
   719  		{float64(180), float64(math.Pi)},
   720  		{-360, -2 * float64(math.Pi)},
   721  		{"180", float64(math.Pi)},
   722  	}
   723  
   724  	Dtbl := tblToDtbl(tbl)
   725  	for _, t := range Dtbl {
   726  		fc := funcs[ast.Radians]
   727  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Arg"]))
   728  		c.Assert(err, IsNil)
   729  		c.Assert(f, NotNil)
   730  		v, err := evalBuiltinFunc(f, chunk.Event{})
   731  		c.Assert(err, IsNil)
   732  		c.Assert(v, solitonutil.CausetEquals, t["Ret"][0])
   733  	}
   734  
   735  	invalidArg := "notNum"
   736  	fc := funcs[ast.Radians]
   737  	f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{types.NewCauset(invalidArg)}))
   738  	c.Assert(err, IsNil)
   739  	_, err = evalBuiltinFunc(f, chunk.Event{})
   740  	c.Assert(err, IsNil)
   741  	c.Assert(int(s.ctx.GetStochastikVars().StmtCtx.WarningCount()), Equals, 1)
   742  }
   743  
   744  func (s *testEvaluatorSuite) TestSin(c *C) {
   745  	cases := []struct {
   746  		args       interface{}
   747  		expected   float64
   748  		isNil      bool
   749  		getWarning bool
   750  	}{
   751  		{nil, 0, true, false},
   752  		{int64(0), float64(0), false, false},
   753  		{math.Pi, float64(math.Sin(math.Pi)), false, false}, // Pie ==> 0
   754  		{-math.Pi, float64(math.Sin(-math.Pi)), false, false},
   755  		{math.Pi / 2, float64(math.Sin(math.Pi / 2)), false, false}, // Pie/2 ==> 1
   756  		{-math.Pi / 2, float64(math.Sin(-math.Pi / 2)), false, false},
   757  		{math.Pi / 6, float64(math.Sin(math.Pi / 6)), false, false}, // Pie/6(30 degrees) ==> 0.5
   758  		{-math.Pi / 6, float64(math.Sin(-math.Pi / 6)), false, false},
   759  		{math.Pi * 2, float64(math.Sin(math.Pi * 2)), false, false},
   760  		{"adfsdfgs", 0, false, true},
   761  		{"0.000", 0, false, false},
   762  	}
   763  
   764  	for _, t := range cases {
   765  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   766  		f, err := newFunctionForTest(s.ctx, ast.Sin, s.primitiveValsToConstants([]interface{}{t.args})...)
   767  		c.Assert(err, IsNil)
   768  
   769  		d, err := f.Eval(chunk.Event{})
   770  		if t.getWarning {
   771  			c.Assert(err, IsNil)
   772  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   773  		} else {
   774  			c.Assert(err, IsNil)
   775  			if t.isNil {
   776  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   777  			} else {
   778  				c.Assert(d.GetFloat64(), Equals, t.expected)
   779  			}
   780  		}
   781  	}
   782  
   783  	_, err := funcs[ast.Sin].getFunction(s.ctx, []Expression{NewZero()})
   784  	c.Assert(err, IsNil)
   785  }
   786  
   787  func (s *testEvaluatorSuite) TestCos(c *C) {
   788  	cases := []struct {
   789  		args       interface{}
   790  		expected   float64
   791  		isNil      bool
   792  		getWarning bool
   793  	}{
   794  		{nil, 0, true, false},
   795  		{int64(0), float64(1), false, false},
   796  		{math.Pi, float64(-1), false, false}, // cos pi equals -1
   797  		{-math.Pi, float64(-1), false, false},
   798  		{math.Pi / 2, float64(math.Cos(math.Pi / 2)), false, false}, // Pi/2 is some near 0 (6.123233995736766e-17) but not 0. Even in math it is 0.
   799  		{-math.Pi / 2, float64(math.Cos(-math.Pi / 2)), false, false},
   800  		{"0.000", float64(1), false, false}, // string value case
   801  		{"sdfgsfsdf", float64(0), false, true},
   802  	}
   803  
   804  	for _, t := range cases {
   805  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   806  		f, err := newFunctionForTest(s.ctx, ast.Cos, s.primitiveValsToConstants([]interface{}{t.args})...)
   807  		c.Assert(err, IsNil)
   808  
   809  		d, err := f.Eval(chunk.Event{})
   810  		if t.getWarning {
   811  			c.Assert(err, IsNil)
   812  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   813  		} else {
   814  			c.Assert(err, IsNil)
   815  			if t.isNil {
   816  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   817  			} else {
   818  				c.Assert(d.GetFloat64(), Equals, t.expected)
   819  			}
   820  		}
   821  	}
   822  
   823  	_, err := funcs[ast.Cos].getFunction(s.ctx, []Expression{NewZero()})
   824  	c.Assert(err, IsNil)
   825  }
   826  
   827  func (s *testEvaluatorSuite) TestAcos(c *C) {
   828  	tests := []struct {
   829  		args       interface{}
   830  		expect     float64
   831  		isNil      bool
   832  		getWarning bool
   833  	}{
   834  		{nil, 0, true, false},
   835  		{float64(1), 0, false, false},
   836  		{float64(2), 0, true, false},
   837  		{float64(-1), 3.141592653589793, false, false},
   838  		{float64(-2), 0, true, false},
   839  		{"milevadb", 0, false, true},
   840  	}
   841  
   842  	for _, test := range tests {
   843  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   844  		f, err := newFunctionForTest(s.ctx, ast.Acos, s.primitiveValsToConstants([]interface{}{test.args})...)
   845  		c.Assert(err, IsNil)
   846  
   847  		result, err := f.Eval(chunk.Event{})
   848  		if test.getWarning {
   849  			c.Assert(err, IsNil)
   850  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   851  		} else {
   852  			c.Assert(err, IsNil)
   853  			if test.isNil {
   854  				c.Assert(result.HoTT(), Equals, types.HoTTNull)
   855  			} else {
   856  				c.Assert(result.GetFloat64(), Equals, test.expect)
   857  			}
   858  		}
   859  	}
   860  
   861  	_, err := funcs[ast.Acos].getFunction(s.ctx, []Expression{NewZero()})
   862  	c.Assert(err, IsNil)
   863  }
   864  
   865  func (s *testEvaluatorSuite) TestAsin(c *C) {
   866  	tests := []struct {
   867  		args       interface{}
   868  		expect     float64
   869  		isNil      bool
   870  		getWarning bool
   871  	}{
   872  		{nil, 0, true, false},
   873  		{float64(1), 1.5707963267948966, false, false},
   874  		{float64(2), 0, true, false},
   875  		{float64(-1), -1.5707963267948966, false, false},
   876  		{float64(-2), 0, true, false},
   877  		{"milevadb", 0, false, true},
   878  	}
   879  
   880  	for _, test := range tests {
   881  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   882  		f, err := newFunctionForTest(s.ctx, ast.Asin, s.primitiveValsToConstants([]interface{}{test.args})...)
   883  		c.Assert(err, IsNil)
   884  
   885  		result, err := f.Eval(chunk.Event{})
   886  		if test.getWarning {
   887  			c.Assert(err, IsNil)
   888  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   889  		} else {
   890  			c.Assert(err, IsNil)
   891  			if test.isNil {
   892  				c.Assert(result.HoTT(), Equals, types.HoTTNull)
   893  			} else {
   894  				c.Assert(result.GetFloat64(), Equals, test.expect)
   895  			}
   896  		}
   897  	}
   898  
   899  	_, err := funcs[ast.Asin].getFunction(s.ctx, []Expression{NewZero()})
   900  	c.Assert(err, IsNil)
   901  }
   902  
   903  func (s *testEvaluatorSuite) TestAtan(c *C) {
   904  	tests := []struct {
   905  		args       []interface{}
   906  		expect     float64
   907  		isNil      bool
   908  		getWarning bool
   909  	}{
   910  		{[]interface{}{nil}, 0, true, false},
   911  		{[]interface{}{nil, nil}, 0, true, false},
   912  		{[]interface{}{float64(1)}, 0.7853981633974483, false, false},
   913  		{[]interface{}{float64(-1)}, -0.7853981633974483, false, false},
   914  		{[]interface{}{float64(0), float64(-2)}, float64(math.Pi), false, false},
   915  		{[]interface{}{"milevadb"}, 0, false, true},
   916  	}
   917  
   918  	for _, test := range tests {
   919  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   920  		f, err := newFunctionForTest(s.ctx, ast.Atan, s.primitiveValsToConstants(test.args)...)
   921  		c.Assert(err, IsNil)
   922  
   923  		result, err := f.Eval(chunk.Event{})
   924  		if test.getWarning {
   925  			c.Assert(err, IsNil)
   926  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   927  		} else {
   928  			c.Assert(err, IsNil)
   929  			if test.isNil {
   930  				c.Assert(result.HoTT(), Equals, types.HoTTNull)
   931  			} else {
   932  				c.Assert(result.GetFloat64(), Equals, test.expect)
   933  			}
   934  		}
   935  	}
   936  
   937  	_, err := funcs[ast.Atan].getFunction(s.ctx, []Expression{NewZero()})
   938  	c.Assert(err, IsNil)
   939  }
   940  
   941  func (s *testEvaluatorSuite) TestTan(c *C) {
   942  	cases := []struct {
   943  		args       interface{}
   944  		expected   float64
   945  		isNil      bool
   946  		getWarning bool
   947  	}{
   948  		{nil, 0, true, false},
   949  		{int64(0), float64(0), false, false},
   950  		{math.Pi / 4, float64(1), false, false},
   951  		{-math.Pi / 4, float64(-1), false, false},
   952  		{math.Pi * 3 / 4, math.Tan(math.Pi * 3 / 4), false, false}, //in allegrosql and golang, it equals -1.0000000000000002, not -1
   953  		{"0.000", float64(0), false, false},
   954  		{"sdfgsdfg", 0, false, true},
   955  	}
   956  
   957  	for _, t := range cases {
   958  		preWarningCnt := s.ctx.GetStochastikVars().StmtCtx.WarningCount()
   959  		f, err := newFunctionForTest(s.ctx, ast.Tan, s.primitiveValsToConstants([]interface{}{t.args})...)
   960  		c.Assert(err, IsNil)
   961  
   962  		d, err := f.Eval(chunk.Event{})
   963  		if t.getWarning {
   964  			c.Assert(err, IsNil)
   965  			c.Assert(s.ctx.GetStochastikVars().StmtCtx.WarningCount(), Equals, preWarningCnt+1)
   966  		} else {
   967  			c.Assert(err, IsNil)
   968  			if t.isNil {
   969  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   970  			} else {
   971  				c.Assert(d.GetFloat64(), Equals, t.expected)
   972  			}
   973  		}
   974  	}
   975  
   976  	_, err := funcs[ast.Tan].getFunction(s.ctx, []Expression{NewZero()})
   977  	c.Assert(err, IsNil)
   978  }
   979  
   980  func (s *testEvaluatorSuite) TestCot(c *C) {
   981  	tests := []struct {
   982  		args   interface{}
   983  		expect float64
   984  		isNil  bool
   985  		getErr bool
   986  		errMsg string
   987  	}{
   988  		{nil, 0, true, false, ""},
   989  		{float64(0), 0, false, true, "[types:1690]DOUBLE value is out of range in 'cot(0)'"},
   990  		{float64(-1), -0.6420926159343308, false, false, ""},
   991  		{float64(1), 0.6420926159343308, false, false, ""},
   992  		{math.Pi / 4, 1 / math.Tan(math.Pi/4), false, false, ""},
   993  		{math.Pi / 2, 1 / math.Tan(math.Pi/2), false, false, ""},
   994  		{math.Pi, 1 / math.Tan(math.Pi), false, false, ""},
   995  		{"milevadb", 0, false, true, ""},
   996  	}
   997  
   998  	for _, test := range tests {
   999  		f, err := newFunctionForTest(s.ctx, ast.Cot, s.primitiveValsToConstants([]interface{}{test.args})...)
  1000  		c.Assert(err, IsNil)
  1001  
  1002  		result, err := f.Eval(chunk.Event{})
  1003  		if test.getErr {
  1004  			c.Assert(err, NotNil)
  1005  			if test.errMsg != "" {
  1006  				c.Assert(err.Error(), Equals, test.errMsg)
  1007  			}
  1008  		} else {
  1009  			c.Assert(err, IsNil)
  1010  			if test.isNil {
  1011  				c.Assert(result.HoTT(), Equals, types.HoTTNull)
  1012  			} else {
  1013  				c.Assert(result.GetFloat64(), Equals, test.expect)
  1014  			}
  1015  		}
  1016  	}
  1017  
  1018  	_, err := funcs[ast.Cot].getFunction(s.ctx, []Expression{NewOne()})
  1019  	c.Assert(err, IsNil)
  1020  }