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 }