github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_op_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/errors"
    21  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    22  	"github.com/whtcorpsinc/milevadb/types"
    23  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    24  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    25  )
    26  
    27  func (s *testEvaluatorSuite) TestUnary(c *C) {
    28  	cases := []struct {
    29  		args     interface{}
    30  		expected interface{}
    31  		overflow bool
    32  		getErr   bool
    33  	}{
    34  		{uint64(9223372036854775809), "-9223372036854775809", true, false},
    35  		{uint64(9223372036854775810), "-9223372036854775810", true, false},
    36  		{uint64(9223372036854775808), int64(-9223372036854775808), false, false},
    37  		{int64(math.MinInt64), "9223372036854775808", true, false}, // --9223372036854775808
    38  	}
    39  	sc := s.ctx.GetStochastikVars().StmtCtx
    40  	origin := sc.InSelectStmt
    41  	sc.InSelectStmt = true
    42  	defer func() {
    43  		sc.InSelectStmt = origin
    44  	}()
    45  
    46  	for _, t := range cases {
    47  		f, err := newFunctionForTest(s.ctx, ast.UnaryMinus, s.primitiveValsToConstants([]interface{}{t.args})...)
    48  		c.Assert(err, IsNil)
    49  		d, err := f.Eval(chunk.Event{})
    50  		if !t.getErr {
    51  			c.Assert(err, IsNil)
    52  			if !t.overflow {
    53  				c.Assert(d.GetValue(), Equals, t.expected)
    54  			} else {
    55  				c.Assert(d.GetMysqlDecimal().String(), Equals, t.expected)
    56  			}
    57  		} else {
    58  			c.Assert(err, NotNil)
    59  		}
    60  	}
    61  
    62  	_, err := funcs[ast.UnaryMinus].getFunction(s.ctx, []Expression{NewZero()})
    63  	c.Assert(err, IsNil)
    64  }
    65  
    66  func (s *testEvaluatorSuite) TestLogicAnd(c *C) {
    67  	sc := s.ctx.GetStochastikVars().StmtCtx
    68  	origin := sc.IgnoreTruncate
    69  	defer func() {
    70  		sc.IgnoreTruncate = origin
    71  	}()
    72  	sc.IgnoreTruncate = true
    73  
    74  	cases := []struct {
    75  		args     []interface{}
    76  		expected int64
    77  		isNil    bool
    78  		getErr   bool
    79  	}{
    80  		{[]interface{}{1, 1}, 1, false, false},
    81  		{[]interface{}{1, 0}, 0, false, false},
    82  		{[]interface{}{0, 1}, 0, false, false},
    83  		{[]interface{}{0, 0}, 0, false, false},
    84  		{[]interface{}{2, -1}, 1, false, false},
    85  		{[]interface{}{"a", "0"}, 0, false, false},
    86  		{[]interface{}{"a", "1"}, 0, false, false},
    87  		{[]interface{}{"1a", "0"}, 0, false, false},
    88  		{[]interface{}{"1a", "1"}, 1, false, false},
    89  		{[]interface{}{0, nil}, 0, false, false},
    90  		{[]interface{}{nil, 0}, 0, false, false},
    91  		{[]interface{}{nil, 1}, 0, true, false},
    92  		{[]interface{}{0.001, 0}, 0, false, false},
    93  		{[]interface{}{0.001, 1}, 1, false, false},
    94  		{[]interface{}{nil, 0.000}, 0, false, false},
    95  		{[]interface{}{nil, 0.001}, 0, true, false},
    96  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), 0}, 0, false, false},
    97  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), 1}, 1, false, false},
    98  		{[]interface{}{types.NewDecFromStringForTest("0.000000"), nil}, 0, false, false},
    99  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), nil}, 0, true, false},
   100  
   101  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   102  	}
   103  
   104  	for _, t := range cases {
   105  		f, err := newFunctionForTest(s.ctx, ast.LogicAnd, s.primitiveValsToConstants(t.args)...)
   106  		c.Assert(err, IsNil)
   107  		d, err := f.Eval(chunk.Event{})
   108  		if t.getErr {
   109  			c.Assert(err, NotNil)
   110  		} else {
   111  			c.Assert(err, IsNil)
   112  			if t.isNil {
   113  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   114  			} else {
   115  				c.Assert(d.GetInt64(), Equals, t.expected)
   116  			}
   117  		}
   118  	}
   119  
   120  	// Test incorrect parameter count.
   121  	_, err := newFunctionForTest(s.ctx, ast.LogicAnd, NewZero())
   122  	c.Assert(err, NotNil)
   123  
   124  	_, err = funcs[ast.LogicAnd].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   125  	c.Assert(err, IsNil)
   126  }
   127  
   128  func (s *testEvaluatorSuite) TestLeftShift(c *C) {
   129  	cases := []struct {
   130  		args     []interface{}
   131  		expected uint64
   132  		isNil    bool
   133  		getErr   bool
   134  	}{
   135  		{[]interface{}{123, 2}, uint64(492), false, false},
   136  		{[]interface{}{-123, 2}, uint64(18446744073709551124), false, false},
   137  		{[]interface{}{nil, 1}, 0, true, false},
   138  
   139  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   140  	}
   141  
   142  	for _, t := range cases {
   143  		f, err := newFunctionForTest(s.ctx, ast.LeftShift, s.primitiveValsToConstants(t.args)...)
   144  		c.Assert(err, IsNil)
   145  		d, err := f.Eval(chunk.Event{})
   146  		if t.getErr {
   147  			c.Assert(err, NotNil)
   148  		} else {
   149  			c.Assert(err, IsNil)
   150  			if t.isNil {
   151  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   152  			} else {
   153  				c.Assert(d.GetUint64(), Equals, t.expected)
   154  			}
   155  		}
   156  	}
   157  }
   158  
   159  func (s *testEvaluatorSuite) TestRightShift(c *C) {
   160  	cases := []struct {
   161  		args     []interface{}
   162  		expected uint64
   163  		isNil    bool
   164  		getErr   bool
   165  	}{
   166  		{[]interface{}{123, 2}, uint64(30), false, false},
   167  		{[]interface{}{-123, 2}, uint64(4611686018427387873), false, false},
   168  		{[]interface{}{nil, 1}, 0, true, false},
   169  
   170  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   171  	}
   172  
   173  	for _, t := range cases {
   174  		f, err := newFunctionForTest(s.ctx, ast.RightShift, s.primitiveValsToConstants(t.args)...)
   175  		c.Assert(err, IsNil)
   176  		d, err := f.Eval(chunk.Event{})
   177  		if t.getErr {
   178  			c.Assert(err, NotNil)
   179  		} else {
   180  			c.Assert(err, IsNil)
   181  			if t.isNil {
   182  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   183  			} else {
   184  				c.Assert(d.GetUint64(), Equals, t.expected)
   185  			}
   186  		}
   187  	}
   188  
   189  	// Test incorrect parameter count.
   190  	_, err := newFunctionForTest(s.ctx, ast.RightShift, NewZero())
   191  	c.Assert(err, NotNil)
   192  
   193  	_, err = funcs[ast.RightShift].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   194  	c.Assert(err, IsNil)
   195  }
   196  
   197  func (s *testEvaluatorSuite) TestBitXor(c *C) {
   198  	cases := []struct {
   199  		args     []interface{}
   200  		expected uint64
   201  		isNil    bool
   202  		getErr   bool
   203  	}{
   204  		{[]interface{}{123, 321}, uint64(314), false, false},
   205  		{[]interface{}{-123, 321}, uint64(18446744073709551300), false, false},
   206  		{[]interface{}{nil, 1}, 0, true, false},
   207  
   208  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   209  	}
   210  
   211  	for _, t := range cases {
   212  		f, err := newFunctionForTest(s.ctx, ast.Xor, s.primitiveValsToConstants(t.args)...)
   213  		c.Assert(err, IsNil)
   214  		d, err := f.Eval(chunk.Event{})
   215  		if t.getErr {
   216  			c.Assert(err, NotNil)
   217  		} else {
   218  			c.Assert(err, IsNil)
   219  			if t.isNil {
   220  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   221  			} else {
   222  				c.Assert(d.GetUint64(), Equals, t.expected)
   223  			}
   224  		}
   225  	}
   226  
   227  	// Test incorrect parameter count.
   228  	_, err := newFunctionForTest(s.ctx, ast.Xor, NewZero())
   229  	c.Assert(err, NotNil)
   230  
   231  	_, err = funcs[ast.Xor].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   232  	c.Assert(err, IsNil)
   233  }
   234  
   235  func (s *testEvaluatorSuite) TestBitOr(c *C) {
   236  	sc := s.ctx.GetStochastikVars().StmtCtx
   237  	origin := sc.IgnoreTruncate
   238  	defer func() {
   239  		sc.IgnoreTruncate = origin
   240  	}()
   241  	sc.IgnoreTruncate = true
   242  
   243  	cases := []struct {
   244  		args     []interface{}
   245  		expected uint64
   246  		isNil    bool
   247  		getErr   bool
   248  	}{
   249  		{[]interface{}{123, 321}, uint64(379), false, false},
   250  		{[]interface{}{-123, 321}, uint64(18446744073709551557), false, false},
   251  		{[]interface{}{nil, 1}, 0, true, false},
   252  
   253  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   254  	}
   255  
   256  	for _, t := range cases {
   257  		f, err := newFunctionForTest(s.ctx, ast.Or, s.primitiveValsToConstants(t.args)...)
   258  		c.Assert(err, IsNil)
   259  		d, err := f.Eval(chunk.Event{})
   260  		if t.getErr {
   261  			c.Assert(err, NotNil)
   262  		} else {
   263  			c.Assert(err, IsNil)
   264  			if t.isNil {
   265  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   266  			} else {
   267  				c.Assert(d.GetUint64(), Equals, t.expected)
   268  			}
   269  		}
   270  	}
   271  
   272  	// Test incorrect parameter count.
   273  	_, err := newFunctionForTest(s.ctx, ast.Or, NewZero())
   274  	c.Assert(err, NotNil)
   275  
   276  	_, err = funcs[ast.Or].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   277  	c.Assert(err, IsNil)
   278  }
   279  
   280  func (s *testEvaluatorSuite) TestLogicOr(c *C) {
   281  	sc := s.ctx.GetStochastikVars().StmtCtx
   282  	origin := sc.IgnoreTruncate
   283  	defer func() {
   284  		sc.IgnoreTruncate = origin
   285  	}()
   286  	sc.IgnoreTruncate = true
   287  
   288  	cases := []struct {
   289  		args     []interface{}
   290  		expected int64
   291  		isNil    bool
   292  		getErr   bool
   293  	}{
   294  		{[]interface{}{1, 1}, 1, false, false},
   295  		{[]interface{}{1, 0}, 1, false, false},
   296  		{[]interface{}{0, 1}, 1, false, false},
   297  		{[]interface{}{0, 0}, 0, false, false},
   298  		{[]interface{}{2, -1}, 1, false, false},
   299  		{[]interface{}{"a", "0"}, 0, false, false},
   300  		{[]interface{}{"a", "1"}, 1, false, false},
   301  		{[]interface{}{"1a", "0"}, 1, false, false},
   302  		{[]interface{}{"1a", "1"}, 1, false, false},
   303  		{[]interface{}{"0.0a", 0}, 0, false, false},
   304  		{[]interface{}{"0.0001a", 0}, 1, false, false},
   305  		{[]interface{}{1, nil}, 1, false, false},
   306  		{[]interface{}{nil, 1}, 1, false, false},
   307  		{[]interface{}{nil, 0}, 0, true, false},
   308  		{[]interface{}{0.000, 0}, 0, false, false},
   309  		{[]interface{}{0.001, 0}, 1, false, false},
   310  		{[]interface{}{nil, 0.000}, 0, true, false},
   311  		{[]interface{}{nil, 0.001}, 1, false, false},
   312  		{[]interface{}{types.NewDecFromStringForTest("0.000000"), 0}, 0, false, false},
   313  		{[]interface{}{types.NewDecFromStringForTest("0.000000"), 1}, 1, false, false},
   314  		{[]interface{}{types.NewDecFromStringForTest("0.000000"), nil}, 0, true, false},
   315  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), 0}, 1, false, false},
   316  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), 1}, 1, false, false},
   317  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), nil}, 1, false, false},
   318  
   319  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   320  	}
   321  
   322  	for _, t := range cases {
   323  		f, err := newFunctionForTest(s.ctx, ast.LogicOr, s.primitiveValsToConstants(t.args)...)
   324  		c.Assert(err, IsNil)
   325  		d, err := f.Eval(chunk.Event{})
   326  		if t.getErr {
   327  			c.Assert(err, NotNil)
   328  		} else {
   329  			c.Assert(err, IsNil)
   330  			if t.isNil {
   331  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   332  			} else {
   333  				c.Assert(d.GetInt64(), Equals, t.expected)
   334  			}
   335  		}
   336  	}
   337  
   338  	// Test incorrect parameter count.
   339  	_, err := newFunctionForTest(s.ctx, ast.LogicOr, NewZero())
   340  	c.Assert(err, NotNil)
   341  
   342  	_, err = funcs[ast.LogicOr].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   343  	c.Assert(err, IsNil)
   344  }
   345  
   346  func (s *testEvaluatorSuite) TestBitAnd(c *C) {
   347  	cases := []struct {
   348  		args     []interface{}
   349  		expected int64
   350  		isNil    bool
   351  		getErr   bool
   352  	}{
   353  		{[]interface{}{123, 321}, 65, false, false},
   354  		{[]interface{}{-123, 321}, 257, false, false},
   355  		{[]interface{}{nil, 1}, 0, true, false},
   356  
   357  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   358  	}
   359  
   360  	for _, t := range cases {
   361  		f, err := newFunctionForTest(s.ctx, ast.And, s.primitiveValsToConstants(t.args)...)
   362  		c.Assert(err, IsNil)
   363  		d, err := f.Eval(chunk.Event{})
   364  		if t.getErr {
   365  			c.Assert(err, NotNil)
   366  		} else {
   367  			c.Assert(err, IsNil)
   368  			if t.isNil {
   369  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   370  			} else {
   371  				c.Assert(d.GetInt64(), Equals, t.expected)
   372  			}
   373  		}
   374  	}
   375  
   376  	// Test incorrect parameter count.
   377  	_, err := newFunctionForTest(s.ctx, ast.And, NewZero())
   378  	c.Assert(err, NotNil)
   379  
   380  	_, err = funcs[ast.And].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   381  	c.Assert(err, IsNil)
   382  }
   383  
   384  func (s *testEvaluatorSuite) TestBitNeg(c *C) {
   385  	sc := s.ctx.GetStochastikVars().StmtCtx
   386  	origin := sc.IgnoreTruncate
   387  	defer func() {
   388  		sc.IgnoreTruncate = origin
   389  	}()
   390  	sc.IgnoreTruncate = true
   391  
   392  	cases := []struct {
   393  		args     []interface{}
   394  		expected uint64
   395  		isNil    bool
   396  		getErr   bool
   397  	}{
   398  		{[]interface{}{123}, uint64(18446744073709551492), false, false},
   399  		{[]interface{}{-123}, uint64(122), false, false},
   400  		{[]interface{}{nil}, 0, true, false},
   401  
   402  		{[]interface{}{errors.New("must error")}, 0, false, true},
   403  	}
   404  
   405  	for _, t := range cases {
   406  		f, err := newFunctionForTest(s.ctx, ast.BitNeg, s.primitiveValsToConstants(t.args)...)
   407  		c.Assert(err, IsNil)
   408  		d, err := f.Eval(chunk.Event{})
   409  		if t.getErr {
   410  			c.Assert(err, NotNil)
   411  		} else {
   412  			c.Assert(err, IsNil)
   413  			if t.isNil {
   414  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   415  			} else {
   416  				c.Assert(d.GetUint64(), Equals, t.expected)
   417  			}
   418  		}
   419  	}
   420  
   421  	// Test incorrect parameter count.
   422  	_, err := newFunctionForTest(s.ctx, ast.BitNeg, NewZero(), NewZero())
   423  	c.Assert(err, NotNil)
   424  
   425  	_, err = funcs[ast.BitNeg].getFunction(s.ctx, []Expression{NewZero()})
   426  	c.Assert(err, IsNil)
   427  }
   428  
   429  func (s *testEvaluatorSuite) TestUnaryNot(c *C) {
   430  	sc := s.ctx.GetStochastikVars().StmtCtx
   431  	origin := sc.IgnoreTruncate
   432  	defer func() {
   433  		sc.IgnoreTruncate = origin
   434  	}()
   435  	sc.IgnoreTruncate = true
   436  
   437  	cases := []struct {
   438  		args     []interface{}
   439  		expected int64
   440  		isNil    bool
   441  		getErr   bool
   442  	}{
   443  		{[]interface{}{1}, 0, false, false},
   444  		{[]interface{}{0}, 1, false, false},
   445  		{[]interface{}{123}, 0, false, false},
   446  		{[]interface{}{-123}, 0, false, false},
   447  		{[]interface{}{"123"}, 0, false, false},
   448  		{[]interface{}{float64(0.3)}, 0, false, false},
   449  		{[]interface{}{"0.3"}, 0, false, false},
   450  		{[]interface{}{types.NewDecFromFloatForTest(0.3)}, 0, false, false},
   451  		{[]interface{}{nil}, 0, true, false},
   452  
   453  		{[]interface{}{errors.New("must error")}, 0, false, true},
   454  	}
   455  
   456  	for _, t := range cases {
   457  		f, err := newFunctionForTest(s.ctx, ast.UnaryNot, s.primitiveValsToConstants(t.args)...)
   458  		c.Assert(err, IsNil)
   459  		d, err := f.Eval(chunk.Event{})
   460  		if t.getErr {
   461  			c.Assert(err, NotNil)
   462  		} else {
   463  			c.Assert(err, IsNil)
   464  			if t.isNil {
   465  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   466  			} else {
   467  				c.Assert(d.GetInt64(), Equals, t.expected)
   468  			}
   469  		}
   470  	}
   471  
   472  	// Test incorrect parameter count.
   473  	_, err := newFunctionForTest(s.ctx, ast.UnaryNot, NewZero(), NewZero())
   474  	c.Assert(err, NotNil)
   475  
   476  	_, err = funcs[ast.UnaryNot].getFunction(s.ctx, []Expression{NewZero()})
   477  	c.Assert(err, IsNil)
   478  }
   479  
   480  func (s *testEvaluatorSuite) TestIsTrueOrFalse(c *C) {
   481  	sc := s.ctx.GetStochastikVars().StmtCtx
   482  	origin := sc.IgnoreTruncate
   483  	defer func() {
   484  		sc.IgnoreTruncate = origin
   485  	}()
   486  	sc.IgnoreTruncate = true
   487  
   488  	testCases := []struct {
   489  		args    []interface{}
   490  		isTrue  interface{}
   491  		isFalse interface{}
   492  	}{
   493  		{
   494  			args:    []interface{}{-12},
   495  			isTrue:  1,
   496  			isFalse: 0,
   497  		},
   498  		{
   499  			args:    []interface{}{12},
   500  			isTrue:  1,
   501  			isFalse: 0,
   502  		},
   503  		{
   504  			args:    []interface{}{0},
   505  			isTrue:  0,
   506  			isFalse: 1,
   507  		},
   508  		{
   509  			args:    []interface{}{float64(0)},
   510  			isTrue:  0,
   511  			isFalse: 1,
   512  		},
   513  		{
   514  			args:    []interface{}{"aaa"},
   515  			isTrue:  0,
   516  			isFalse: 1,
   517  		},
   518  		{
   519  			args:    []interface{}{""},
   520  			isTrue:  0,
   521  			isFalse: 1,
   522  		},
   523  		{
   524  			args:    []interface{}{"0.3"},
   525  			isTrue:  1,
   526  			isFalse: 0,
   527  		},
   528  		{
   529  			args:    []interface{}{float64(0.3)},
   530  			isTrue:  1,
   531  			isFalse: 0,
   532  		},
   533  		{
   534  			args:    []interface{}{types.NewDecFromFloatForTest(0.3)},
   535  			isTrue:  1,
   536  			isFalse: 0,
   537  		},
   538  		{
   539  			args:    []interface{}{nil},
   540  			isTrue:  0,
   541  			isFalse: 0,
   542  		},
   543  	}
   544  
   545  	for _, tc := range testCases {
   546  		isTrueSig, err := funcs[ast.IsTruthWithoutNull].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...)))
   547  		c.Assert(err, IsNil)
   548  		c.Assert(isTrueSig, NotNil)
   549  
   550  		isTrue, err := evalBuiltinFunc(isTrueSig, chunk.Event{})
   551  		c.Assert(err, IsNil)
   552  		c.Assert(isTrue, solitonutil.CausetEquals, types.NewCauset(tc.isTrue))
   553  	}
   554  
   555  	for _, tc := range testCases {
   556  		isFalseSig, err := funcs[ast.IsFalsity].getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tc.args...)))
   557  		c.Assert(err, IsNil)
   558  		c.Assert(isFalseSig, NotNil)
   559  
   560  		isFalse, err := evalBuiltinFunc(isFalseSig, chunk.Event{})
   561  		c.Assert(err, IsNil)
   562  		c.Assert(isFalse, solitonutil.CausetEquals, types.NewCauset(tc.isFalse))
   563  	}
   564  }
   565  
   566  func (s *testEvaluatorSuite) TestLogicXor(c *C) {
   567  	sc := s.ctx.GetStochastikVars().StmtCtx
   568  	origin := sc.IgnoreTruncate
   569  	defer func() {
   570  		sc.IgnoreTruncate = origin
   571  	}()
   572  	sc.IgnoreTruncate = true
   573  
   574  	cases := []struct {
   575  		args     []interface{}
   576  		expected int64
   577  		isNil    bool
   578  		getErr   bool
   579  	}{
   580  		{[]interface{}{1, 1}, 0, false, false},
   581  		{[]interface{}{1, 0}, 1, false, false},
   582  		{[]interface{}{0, 1}, 1, false, false},
   583  		{[]interface{}{0, 0}, 0, false, false},
   584  		{[]interface{}{2, -1}, 0, false, false},
   585  		{[]interface{}{"a", "0"}, 0, false, false},
   586  		{[]interface{}{"a", "1"}, 1, false, false},
   587  		{[]interface{}{"1a", "0"}, 1, false, false},
   588  		{[]interface{}{"1a", "1"}, 0, false, false},
   589  		{[]interface{}{0, nil}, 0, true, false},
   590  		{[]interface{}{nil, 0}, 0, true, false},
   591  		{[]interface{}{nil, 1}, 0, true, false},
   592  		{[]interface{}{0.5000, 0.4999}, 0, false, false},
   593  		{[]interface{}{0.5000, 1.0}, 0, false, false},
   594  		{[]interface{}{0.4999, 1.0}, 0, false, false},
   595  		{[]interface{}{nil, 0.000}, 0, true, false},
   596  		{[]interface{}{nil, 0.001}, 0, true, false},
   597  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), 0.00001}, 0, false, false},
   598  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), 1}, 0, false, false},
   599  		{[]interface{}{types.NewDecFromStringForTest("0.000000"), nil}, 0, true, false},
   600  		{[]interface{}{types.NewDecFromStringForTest("0.000001"), nil}, 0, true, false},
   601  
   602  		{[]interface{}{errors.New("must error"), 1}, 0, false, true},
   603  	}
   604  
   605  	for _, t := range cases {
   606  		f, err := newFunctionForTest(s.ctx, ast.LogicXor, s.primitiveValsToConstants(t.args)...)
   607  		c.Assert(err, IsNil)
   608  		d, err := f.Eval(chunk.Event{})
   609  		if t.getErr {
   610  			c.Assert(err, NotNil)
   611  		} else {
   612  			c.Assert(err, IsNil)
   613  			if t.isNil {
   614  				c.Assert(d.HoTT(), Equals, types.HoTTNull)
   615  			} else {
   616  				c.Assert(d.GetInt64(), Equals, t.expected)
   617  			}
   618  		}
   619  	}
   620  
   621  	// Test incorrect parameter count.
   622  	_, err := newFunctionForTest(s.ctx, ast.LogicXor, NewZero())
   623  	c.Assert(err, NotNil)
   624  
   625  	_, err = funcs[ast.LogicXor].getFunction(s.ctx, []Expression{NewZero(), NewZero()})
   626  	c.Assert(err, IsNil)
   627  }