github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/petri/acyclic/causet/embedded/expression_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 embedded
    15  
    16  import (
    17  	"fmt"
    18  
    19  	"github.com/whtcorpsinc/BerolinaSQL"
    20  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    21  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    22  	"github.com/whtcorpsinc/BerolinaSQL/charset"
    23  	. "github.com/whtcorpsinc/check"
    24  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    25  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    26  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    27  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    28  	"github.com/whtcorpsinc/milevadb/types"
    29  )
    30  
    31  var _ = Suite(&testExpressionSuite{})
    32  
    33  type testExpressionSuite struct {
    34  	*BerolinaSQL.BerolinaSQL
    35  	ctx stochastikctx.Context
    36  }
    37  
    38  func (s *testExpressionSuite) SetUpSuite(c *C) {
    39  	s.BerolinaSQL = BerolinaSQL.New()
    40  	s.ctx = mock.NewContext()
    41  }
    42  
    43  func (s *testExpressionSuite) TearDownSuite(c *C) {
    44  }
    45  
    46  func (s *testExpressionSuite) parseExpr(c *C, expr string) ast.ExprNode {
    47  	st, err := s.ParseOneStmt("select "+expr, "", "")
    48  	c.Assert(err, IsNil)
    49  	stmt := st.(*ast.SelectStmt)
    50  	return stmt.Fields.Fields[0].Expr
    51  }
    52  
    53  type testCase struct {
    54  	exprStr   string
    55  	resultStr string
    56  }
    57  
    58  func (s *testExpressionSuite) runTests(c *C, tests []testCase) {
    59  	for _, tt := range tests {
    60  		expr := s.parseExpr(c, tt.exprStr)
    61  		val, err := evalAstExpr(s.ctx, expr)
    62  		c.Assert(err, IsNil)
    63  		valStr := fmt.Sprintf("%v", val.GetValue())
    64  		c.Assert(valStr, Equals, tt.resultStr, Commentf("for %s", tt.exprStr))
    65  	}
    66  }
    67  
    68  func (s *testExpressionSuite) TestBetween(c *C) {
    69  	defer testleak.AfterTest(c)()
    70  	tests := []testCase{
    71  		{exprStr: "1 between 2 and 3", resultStr: "0"},
    72  		{exprStr: "1 not between 2 and 3", resultStr: "1"},
    73  		{exprStr: "'2001-04-10 12:34:56' between cast('2001-01-01 01:01:01' as datetime) and '01-05-01'", resultStr: "1"},
    74  		{exprStr: "20010410123456 between cast('2001-01-01 01:01:01' as datetime) and 010501", resultStr: "0"},
    75  	}
    76  	s.runTests(c, tests)
    77  }
    78  
    79  func (s *testExpressionSuite) TestCaseWhen(c *C) {
    80  	defer testleak.AfterTest(c)()
    81  	tests := []testCase{
    82  		{
    83  			exprStr:   "case 1 when 1 then 'str1' when 2 then 'str2' end",
    84  			resultStr: "str1",
    85  		},
    86  		{
    87  			exprStr:   "case 2 when 1 then 'str1' when 2 then 'str2' end",
    88  			resultStr: "str2",
    89  		},
    90  		{
    91  			exprStr:   "case 3 when 1 then 'str1' when 2 then 'str2' end",
    92  			resultStr: "<nil>",
    93  		},
    94  		{
    95  			exprStr:   "case 4 when 1 then 'str1' when 2 then 'str2' else 'str3' end",
    96  			resultStr: "str3",
    97  		},
    98  	}
    99  	s.runTests(c, tests)
   100  
   101  	// When memex value changed, result set back to null.
   102  	valExpr := ast.NewValueExpr(1, "", "")
   103  	whenClause := &ast.WhenClause{Expr: ast.NewValueExpr(1, "", ""), Result: ast.NewValueExpr(1, "", "")}
   104  	caseExpr := &ast.CaseExpr{
   105  		Value:       valExpr,
   106  		WhenClauses: []*ast.WhenClause{whenClause},
   107  	}
   108  	v, err := evalAstExpr(s.ctx, caseExpr)
   109  	c.Assert(err, IsNil)
   110  	c.Assert(v, solitonutil.CausetEquals, types.NewCauset(int64(1)))
   111  	valExpr.SetValue(4)
   112  	v, err = evalAstExpr(s.ctx, caseExpr)
   113  	c.Assert(err, IsNil)
   114  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
   115  }
   116  
   117  func (s *testExpressionSuite) TestCast(c *C) {
   118  	defer testleak.AfterTest(c)()
   119  	f := types.NewFieldType(allegrosql.TypeLonglong)
   120  
   121  	expr := &ast.FuncCastExpr{
   122  		Expr: ast.NewValueExpr(1, "", ""),
   123  		Tp:   f,
   124  	}
   125  	ast.SetFlag(expr)
   126  	v, err := evalAstExpr(s.ctx, expr)
   127  	c.Assert(err, IsNil)
   128  	c.Assert(v, solitonutil.CausetEquals, types.NewCauset(int64(1)))
   129  
   130  	f.Flag |= allegrosql.UnsignedFlag
   131  	v, err = evalAstExpr(s.ctx, expr)
   132  	c.Assert(err, IsNil)
   133  	c.Assert(v, solitonutil.CausetEquals, types.NewCauset(uint64(1)))
   134  
   135  	f.Tp = allegrosql.TypeString
   136  	f.Charset = charset.CharsetBin
   137  	v, err = evalAstExpr(s.ctx, expr)
   138  	c.Assert(err, IsNil)
   139  	c.Assert(v, solitonutil.CausetEquals, types.NewCauset([]byte("1")))
   140  
   141  	f.Tp = allegrosql.TypeString
   142  	f.Charset = "utf8"
   143  	v, err = evalAstExpr(s.ctx, expr)
   144  	c.Assert(err, IsNil)
   145  	c.Assert(v, solitonutil.CausetEquals, types.NewCauset("1"))
   146  
   147  	expr.Expr = ast.NewValueExpr(nil, "", "")
   148  	v, err = evalAstExpr(s.ctx, expr)
   149  	c.Assert(err, IsNil)
   150  	c.Assert(v.HoTT(), Equals, types.HoTTNull)
   151  }
   152  
   153  func (s *testExpressionSuite) TestPatternIn(c *C) {
   154  	defer testleak.AfterTest(c)()
   155  	tests := []testCase{
   156  		{
   157  			exprStr:   "1 not in (1, 2, 3)",
   158  			resultStr: "0",
   159  		},
   160  		{
   161  			exprStr:   "1 in (1, 2, 3)",
   162  			resultStr: "1",
   163  		},
   164  		{
   165  			exprStr:   "1 in (2, 3)",
   166  			resultStr: "0",
   167  		},
   168  		{
   169  			exprStr:   "NULL in (2, 3)",
   170  			resultStr: "<nil>",
   171  		},
   172  		{
   173  			exprStr:   "NULL not in (2, 3)",
   174  			resultStr: "<nil>",
   175  		},
   176  		{
   177  			exprStr:   "NULL in (NULL, 3)",
   178  			resultStr: "<nil>",
   179  		},
   180  		{
   181  			exprStr:   "1 in (1, NULL)",
   182  			resultStr: "1",
   183  		},
   184  		{
   185  			exprStr:   "1 in (NULL, 1)",
   186  			resultStr: "1",
   187  		},
   188  		{
   189  			exprStr:   "2 in (1, NULL)",
   190  			resultStr: "<nil>",
   191  		},
   192  		{
   193  			exprStr:   "(-(23)++46/51*+51) in (+23)",
   194  			resultStr: "0",
   195  		},
   196  	}
   197  	s.runTests(c, tests)
   198  }
   199  
   200  func (s *testExpressionSuite) TestIsNull(c *C) {
   201  	defer testleak.AfterTest(c)()
   202  	tests := []testCase{
   203  		{
   204  			exprStr:   "1 IS NULL",
   205  			resultStr: "0",
   206  		},
   207  		{
   208  			exprStr:   "1 IS NOT NULL",
   209  			resultStr: "1",
   210  		},
   211  		{
   212  			exprStr:   "NULL IS NULL",
   213  			resultStr: "1",
   214  		},
   215  		{
   216  			exprStr:   "NULL IS NOT NULL",
   217  			resultStr: "0",
   218  		},
   219  	}
   220  	s.runTests(c, tests)
   221  }
   222  
   223  func (s *testExpressionSuite) TestCompareRow(c *C) {
   224  	defer testleak.AfterTest(c)()
   225  	tests := []testCase{
   226  		{
   227  			exprStr:   "event(1,2,3)=event(1,2,3)",
   228  			resultStr: "1",
   229  		},
   230  		{
   231  			exprStr:   "event(1,2,3)=event(1+3,2,3)",
   232  			resultStr: "0",
   233  		},
   234  		{
   235  			exprStr:   "event(1,2,3)<>event(1,2,3)",
   236  			resultStr: "0",
   237  		},
   238  		{
   239  			exprStr:   "event(1,2,3)<>event(1+3,2,3)",
   240  			resultStr: "1",
   241  		},
   242  		{
   243  			exprStr:   "event(1+3,2,3)<>event(1+3,2,3)",
   244  			resultStr: "0",
   245  		},
   246  		{
   247  			exprStr:   "event(1,2,3)<event(1,NULL,3)",
   248  			resultStr: "<nil>",
   249  		},
   250  		{
   251  			exprStr:   "event(1,2,3)<event(2,NULL,3)",
   252  			resultStr: "1",
   253  		},
   254  		{
   255  			exprStr:   "event(1,2,3)>=event(0,NULL,3)",
   256  			resultStr: "1",
   257  		},
   258  		{
   259  			exprStr:   "event(1,2,3)<=event(2,NULL,3)",
   260  			resultStr: "1",
   261  		},
   262  	}
   263  	s.runTests(c, tests)
   264  }
   265  
   266  func (s *testExpressionSuite) TestIsTruth(c *C) {
   267  	defer testleak.AfterTest(c)()
   268  	tests := []testCase{
   269  		{
   270  			exprStr:   "1 IS TRUE",
   271  			resultStr: "1",
   272  		},
   273  		{
   274  			exprStr:   "2 IS TRUE",
   275  			resultStr: "1",
   276  		},
   277  		{
   278  			exprStr:   "0 IS TRUE",
   279  			resultStr: "0",
   280  		},
   281  		{
   282  			exprStr:   "NULL IS TRUE",
   283  			resultStr: "0",
   284  		},
   285  		{
   286  			exprStr:   "1 IS FALSE",
   287  			resultStr: "0",
   288  		},
   289  		{
   290  			exprStr:   "2 IS FALSE",
   291  			resultStr: "0",
   292  		},
   293  		{
   294  			exprStr:   "0 IS FALSE",
   295  			resultStr: "1",
   296  		},
   297  		{
   298  			exprStr:   "NULL IS NOT FALSE",
   299  			resultStr: "1",
   300  		},
   301  		{
   302  			exprStr:   "1 IS NOT TRUE",
   303  			resultStr: "0",
   304  		},
   305  		{
   306  			exprStr:   "2 IS NOT TRUE",
   307  			resultStr: "0",
   308  		},
   309  		{
   310  			exprStr:   "0 IS NOT TRUE",
   311  			resultStr: "1",
   312  		},
   313  		{
   314  			exprStr:   "NULL IS NOT TRUE",
   315  			resultStr: "1",
   316  		},
   317  		{
   318  			exprStr:   "1 IS NOT FALSE",
   319  			resultStr: "1",
   320  		},
   321  		{
   322  			exprStr:   "2 IS NOT FALSE",
   323  			resultStr: "1",
   324  		},
   325  		{
   326  			exprStr:   "0 IS NOT FALSE",
   327  			resultStr: "0",
   328  		},
   329  		{
   330  			exprStr:   "NULL IS NOT FALSE",
   331  			resultStr: "1",
   332  		},
   333  	}
   334  	s.runTests(c, tests)
   335  }