github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_string_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 "fmt" 18 "strconv" 19 "strings" 20 "time" 21 "unicode/utf8" 22 23 . "github.com/whtcorpsinc/check" 24 "github.com/whtcorpsinc/errors" 25 "github.com/whtcorpsinc/BerolinaSQL/ast" 26 "github.com/whtcorpsinc/BerolinaSQL/charset" 27 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 28 "github.com/whtcorpsinc/BerolinaSQL/terror" 29 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 30 "github.com/whtcorpsinc/milevadb/types" 31 "github.com/whtcorpsinc/milevadb/soliton/chunk" 32 "github.com/whtcorpsinc/milevadb/soliton/defCauslate" 33 "github.com/whtcorpsinc/milevadb/soliton/mock" 34 "github.com/whtcorpsinc/milevadb/soliton/solitonutil" 35 ) 36 37 func (s *testEvaluatorSuite) TestLengthAndOctetLength(c *C) { 38 cases := []struct { 39 args interface{} 40 expected int64 41 isNil bool 42 getErr bool 43 }{ 44 {"abc", 3, false, false}, 45 {"你好", 6, false, false}, 46 {1, 1, false, false}, 47 {3.14, 4, false, false}, 48 {types.NewDecFromFloatForTest(123.123), 7, false, false}, 49 {types.NewTime(types.FromGoTime(time.Now()), allegrosql.TypeDatetime, 6), 26, false, false}, 50 {types.NewBinaryLiteralFromUint(0x01, -1), 1, false, false}, 51 {types.Set{Value: 1, Name: "abc"}, 3, false, false}, 52 {types.Duration{Duration: 12*time.Hour + 1*time.Minute + 1*time.Second, Fsp: types.DefaultFsp}, 8, false, false}, 53 {nil, 0, true, false}, 54 {errors.New("must error"), 0, false, true}, 55 } 56 57 lengthMethods := []string{ast.Length, ast.OctetLength} 58 for _, lengthMethod := range lengthMethods { 59 for _, t := range cases { 60 f, err := newFunctionForTest(s.ctx, lengthMethod, s.primitiveValsToConstants([]interface{}{t.args})...) 61 c.Assert(err, IsNil) 62 d, err := f.Eval(chunk.Event{}) 63 if t.getErr { 64 c.Assert(err, NotNil) 65 } else { 66 c.Assert(err, IsNil) 67 if t.isNil { 68 c.Assert(d.HoTT(), Equals, types.HoTTNull) 69 } else { 70 c.Assert(d.GetInt64(), Equals, t.expected) 71 } 72 } 73 } 74 } 75 76 _, err := funcs[ast.Length].getFunction(s.ctx, []Expression{NewZero()}) 77 c.Assert(err, IsNil) 78 } 79 80 func (s *testEvaluatorSuite) TestASCII(c *C) { 81 cases := []struct { 82 args interface{} 83 expected int64 84 isNil bool 85 getErr bool 86 }{ 87 {"2", 50, false, false}, 88 {2, 50, false, false}, 89 {"23", 50, false, false}, 90 {23, 50, false, false}, 91 {2.3, 50, false, false}, 92 {nil, 0, true, false}, 93 {"", 0, false, false}, 94 {"你好", 228, false, false}, 95 } 96 for _, t := range cases { 97 f, err := newFunctionForTest(s.ctx, ast.ASCII, s.primitiveValsToConstants([]interface{}{t.args})...) 98 c.Assert(err, IsNil) 99 100 d, err := f.Eval(chunk.Event{}) 101 if t.getErr { 102 c.Assert(err, NotNil) 103 } else { 104 c.Assert(err, IsNil) 105 if t.isNil { 106 c.Assert(d.HoTT(), Equals, types.HoTTNull) 107 } else { 108 c.Assert(d.GetInt64(), Equals, t.expected) 109 } 110 } 111 } 112 _, err := funcs[ast.Length].getFunction(s.ctx, []Expression{NewZero()}) 113 c.Assert(err, IsNil) 114 } 115 116 func (s *testEvaluatorSuite) TestConcat(c *C) { 117 cases := []struct { 118 args []interface{} 119 isNil bool 120 getErr bool 121 res string 122 retType *types.FieldType 123 }{ 124 { 125 []interface{}{nil}, 126 true, false, "", 127 &types.FieldType{Tp: allegrosql.TypeVarString, Flen: 0, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag}, 128 }, 129 { 130 []interface{}{"a", "b", 131 1, 2, 132 1.1, 1.2, 133 types.NewDecFromFloatForTest(1.1), 134 types.NewTime(types.FromDate(2000, 1, 1, 12, 01, 01, 0), allegrosql.TypeDatetime, types.DefaultFsp), 135 types.Duration{ 136 Duration: 12*time.Hour + 1*time.Minute + 1*time.Second, 137 Fsp: types.DefaultFsp}, 138 }, 139 false, false, "ab121.11.21.12000-01-01 12:01:0112:01:01", 140 &types.FieldType{Tp: allegrosql.TypeVarString, Flen: 40, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag}, 141 }, 142 { 143 []interface{}{"a", "b", nil, "c"}, 144 true, false, "", 145 &types.FieldType{Tp: allegrosql.TypeVarString, Flen: 3, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag}, 146 }, 147 { 148 []interface{}{errors.New("must error")}, 149 false, true, "", 150 &types.FieldType{Tp: allegrosql.TypeVarString, Flen: types.UnspecifiedLength, Decimal: types.UnspecifiedLength, Charset: charset.CharsetBin, DefCauslate: charset.DefCauslationBin, Flag: allegrosql.BinaryFlag}, 151 }, 152 } 153 fcName := ast.Concat 154 for _, t := range cases { 155 f, err := newFunctionForTest(s.ctx, fcName, s.primitiveValsToConstants(t.args)...) 156 c.Assert(err, IsNil) 157 v, err := f.Eval(chunk.Event{}) 158 if t.getErr { 159 c.Assert(err, NotNil) 160 } else { 161 c.Assert(err, IsNil) 162 if t.isNil { 163 c.Assert(v.HoTT(), Equals, types.HoTTNull) 164 } else { 165 c.Assert(v.GetString(), Equals, t.res) 166 } 167 } 168 } 169 } 170 171 func (s *testEvaluatorSuite) TestConcatSig(c *C) { 172 defCausTypes := []*types.FieldType{ 173 {Tp: allegrosql.TypeVarchar}, 174 {Tp: allegrosql.TypeVarchar}, 175 } 176 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000} 177 args := []Expression{ 178 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 179 &DeferredCauset{Index: 1, RetType: defCausTypes[1]}, 180 } 181 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 182 concat := &builtinConcatSig{base, 5} 183 184 cases := []struct { 185 args []interface{} 186 warnings int 187 res string 188 }{ 189 {[]interface{}{"a", "b"}, 0, "ab"}, 190 {[]interface{}{"aaa", "bbb"}, 1, ""}, 191 {[]interface{}{"中", "a"}, 0, "中a"}, 192 {[]interface{}{"中文", "a"}, 2, ""}, 193 } 194 195 for _, t := range cases { 196 input := chunk.NewChunkWithCapacity(defCausTypes, 10) 197 input.AppendString(0, t.args[0].(string)) 198 input.AppendString(1, t.args[1].(string)) 199 200 res, isNull, err := concat.evalString(input.GetEvent(0)) 201 c.Assert(res, Equals, t.res) 202 c.Assert(err, IsNil) 203 if t.warnings == 0 { 204 c.Assert(isNull, IsFalse) 205 } else { 206 c.Assert(isNull, IsTrue) 207 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 208 c.Assert(warnings, HasLen, t.warnings) 209 lastWarn := warnings[len(warnings)-1] 210 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue) 211 } 212 } 213 } 214 215 func (s *testEvaluatorSuite) TestConcatWS(c *C) { 216 cases := []struct { 217 args []interface{} 218 isNil bool 219 getErr bool 220 expected string 221 }{ 222 { 223 []interface{}{nil, nil}, 224 true, false, "", 225 }, 226 { 227 []interface{}{nil, "a", "b"}, 228 true, false, "", 229 }, 230 { 231 []interface{}{",", "a", "b", "hello", `$^%`}, 232 false, false, 233 `a,b,hello,$^%`, 234 }, 235 { 236 []interface{}{"|", "a", nil, "b", "c"}, 237 false, false, 238 "a|b|c", 239 }, 240 { 241 []interface{}{",", "a", ",", "b", "c"}, 242 false, false, 243 "a,,,b,c", 244 }, 245 { 246 []interface{}{errors.New("must error"), "a", "b"}, 247 false, true, "", 248 }, 249 { 250 []interface{}{",", "a", "b", 1, 2, 1.1, 0.11, 251 types.NewDecFromFloatForTest(1.1), 252 types.NewTime(types.FromDate(2000, 1, 1, 12, 01, 01, 0), allegrosql.TypeDatetime, types.DefaultFsp), 253 types.Duration{ 254 Duration: 12*time.Hour + 1*time.Minute + 1*time.Second, 255 Fsp: types.DefaultFsp}, 256 }, 257 false, false, "a,b,1,2,1.1,0.11,1.1,2000-01-01 12:01:01,12:01:01", 258 }, 259 } 260 261 fcName := ast.ConcatWS 262 // ERROR 1582 (42000): Incorrect parameter count in the call to native function 'concat_ws' 263 _, err := newFunctionForTest(s.ctx, fcName, s.primitiveValsToConstants([]interface{}{nil})...) 264 c.Assert(err, NotNil) 265 266 for _, t := range cases { 267 f, err := newFunctionForTest(s.ctx, fcName, s.primitiveValsToConstants(t.args)...) 268 c.Assert(err, IsNil) 269 val, err1 := f.Eval(chunk.Event{}) 270 if t.getErr { 271 c.Assert(err1, NotNil) 272 } else { 273 c.Assert(err1, IsNil) 274 if t.isNil { 275 c.Assert(val.HoTT(), Equals, types.HoTTNull) 276 } else { 277 c.Assert(val.GetString(), Equals, t.expected) 278 } 279 } 280 } 281 282 _, err = funcs[ast.ConcatWS].getFunction(s.ctx, s.primitiveValsToConstants([]interface{}{nil, nil})) 283 c.Assert(err, IsNil) 284 } 285 286 func (s *testEvaluatorSuite) TestConcatWSSig(c *C) { 287 defCausTypes := []*types.FieldType{ 288 {Tp: allegrosql.TypeVarchar}, 289 {Tp: allegrosql.TypeVarchar}, 290 {Tp: allegrosql.TypeVarchar}, 291 } 292 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000} 293 args := []Expression{ 294 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 295 &DeferredCauset{Index: 1, RetType: defCausTypes[1]}, 296 &DeferredCauset{Index: 2, RetType: defCausTypes[2]}, 297 } 298 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 299 concat := &builtinConcatWSSig{base, 6} 300 301 cases := []struct { 302 args []interface{} 303 warnings int 304 res string 305 }{ 306 {[]interface{}{",", "a", "b"}, 0, "a,b"}, 307 {[]interface{}{",", "aaa", "bbb"}, 1, ""}, 308 {[]interface{}{",", "中", "a"}, 0, "中,a"}, 309 {[]interface{}{",", "中文", "a"}, 2, ""}, 310 } 311 312 for _, t := range cases { 313 input := chunk.NewChunkWithCapacity(defCausTypes, 10) 314 input.AppendString(0, t.args[0].(string)) 315 input.AppendString(1, t.args[1].(string)) 316 input.AppendString(2, t.args[2].(string)) 317 318 res, isNull, err := concat.evalString(input.GetEvent(0)) 319 c.Assert(res, Equals, t.res) 320 c.Assert(err, IsNil) 321 if t.warnings == 0 { 322 c.Assert(isNull, IsFalse) 323 } else { 324 c.Assert(isNull, IsTrue) 325 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 326 c.Assert(warnings, HasLen, t.warnings) 327 lastWarn := warnings[len(warnings)-1] 328 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue) 329 } 330 } 331 } 332 333 func (s *testEvaluatorSuite) TestLeft(c *C) { 334 stmtCtx := s.ctx.GetStochastikVars().StmtCtx 335 origin := stmtCtx.IgnoreTruncate 336 stmtCtx.IgnoreTruncate = true 337 defer func() { 338 stmtCtx.IgnoreTruncate = origin 339 }() 340 341 cases := []struct { 342 args []interface{} 343 isNil bool 344 getErr bool 345 res string 346 }{ 347 {[]interface{}{"abcde", 3}, false, false, "abc"}, 348 {[]interface{}{"abcde", 0}, false, false, ""}, 349 {[]interface{}{"abcde", 1.2}, false, false, "a"}, 350 {[]interface{}{"abcde", 1.9}, false, false, "ab"}, 351 {[]interface{}{"abcde", -1}, false, false, ""}, 352 {[]interface{}{"abcde", 100}, false, false, "abcde"}, 353 {[]interface{}{"abcde", nil}, true, false, ""}, 354 {[]interface{}{nil, 3}, true, false, ""}, 355 {[]interface{}{"abcde", "3"}, false, false, "abc"}, 356 {[]interface{}{"abcde", "a"}, false, false, ""}, 357 {[]interface{}{1234, 3}, false, false, "123"}, 358 {[]interface{}{12.34, 3}, false, false, "12."}, 359 {[]interface{}{types.NewBinaryLiteralFromUint(0x0102, -1), 1}, false, false, string([]byte{0x01})}, 360 {[]interface{}{errors.New("must err"), 0}, false, true, ""}, 361 } 362 for _, t := range cases { 363 f, err := newFunctionForTest(s.ctx, ast.Left, s.primitiveValsToConstants(t.args)...) 364 c.Assert(err, IsNil) 365 v, err := f.Eval(chunk.Event{}) 366 if t.getErr { 367 c.Assert(err, NotNil) 368 } else { 369 c.Assert(err, IsNil) 370 if t.isNil { 371 c.Assert(v.HoTT(), Equals, types.HoTTNull) 372 } else { 373 c.Assert(v.GetString(), Equals, t.res) 374 } 375 } 376 } 377 378 _, err := funcs[ast.Left].getFunction(s.ctx, []Expression{varcharCon, int8Con}) 379 c.Assert(err, IsNil) 380 } 381 382 func (s *testEvaluatorSuite) TestRight(c *C) { 383 stmtCtx := s.ctx.GetStochastikVars().StmtCtx 384 origin := stmtCtx.IgnoreTruncate 385 stmtCtx.IgnoreTruncate = true 386 defer func() { 387 stmtCtx.IgnoreTruncate = origin 388 }() 389 390 cases := []struct { 391 args []interface{} 392 isNil bool 393 getErr bool 394 res string 395 }{ 396 {[]interface{}{"abcde", 3}, false, false, "cde"}, 397 {[]interface{}{"abcde", 0}, false, false, ""}, 398 {[]interface{}{"abcde", 1.2}, false, false, "e"}, 399 {[]interface{}{"abcde", 1.9}, false, false, "de"}, 400 {[]interface{}{"abcde", -1}, false, false, ""}, 401 {[]interface{}{"abcde", 100}, false, false, "abcde"}, 402 {[]interface{}{"abcde", nil}, true, false, ""}, 403 {[]interface{}{nil, 1}, true, false, ""}, 404 {[]interface{}{"abcde", "3"}, false, false, "cde"}, 405 {[]interface{}{"abcde", "a"}, false, false, ""}, 406 {[]interface{}{1234, 3}, false, false, "234"}, 407 {[]interface{}{12.34, 3}, false, false, ".34"}, 408 {[]interface{}{types.NewBinaryLiteralFromUint(0x0102, -1), 1}, false, false, string([]byte{0x02})}, 409 {[]interface{}{errors.New("must err"), 0}, false, true, ""}, 410 } 411 for _, t := range cases { 412 f, err := newFunctionForTest(s.ctx, ast.Right, s.primitiveValsToConstants(t.args)...) 413 c.Assert(err, IsNil) 414 v, err := f.Eval(chunk.Event{}) 415 if t.getErr { 416 c.Assert(err, NotNil) 417 } else { 418 c.Assert(err, IsNil) 419 if t.isNil { 420 c.Assert(v.HoTT(), Equals, types.HoTTNull) 421 } else { 422 c.Assert(v.GetString(), Equals, t.res) 423 } 424 } 425 } 426 427 _, err := funcs[ast.Right].getFunction(s.ctx, []Expression{varcharCon, int8Con}) 428 c.Assert(err, IsNil) 429 } 430 431 func (s *testEvaluatorSuite) TestRepeat(c *C) { 432 args := []interface{}{"a", int64(2)} 433 fc := funcs[ast.Repeat] 434 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 435 c.Assert(err, IsNil) 436 v, err := evalBuiltinFunc(f, chunk.Event{}) 437 c.Assert(err, IsNil) 438 c.Assert(v.GetString(), Equals, "aa") 439 440 args = []interface{}{"a", uint64(2)} 441 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 442 c.Assert(err, IsNil) 443 v, err = evalBuiltinFunc(f, chunk.Event{}) 444 c.Assert(err, IsNil) 445 c.Assert(v.GetString(), Equals, "aa") 446 447 args = []interface{}{"a", uint64(16777217)} 448 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 449 c.Assert(err, IsNil) 450 v, err = evalBuiltinFunc(f, chunk.Event{}) 451 c.Assert(err, IsNil) 452 c.Assert(v.IsNull(), IsTrue) 453 454 args = []interface{}{"a", uint64(16777216)} 455 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 456 c.Assert(err, IsNil) 457 v, err = evalBuiltinFunc(f, chunk.Event{}) 458 c.Assert(err, IsNil) 459 c.Assert(v.IsNull(), IsFalse) 460 461 args = []interface{}{"a", int64(-1)} 462 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 463 c.Assert(err, IsNil) 464 v, err = evalBuiltinFunc(f, chunk.Event{}) 465 c.Assert(err, IsNil) 466 c.Assert(v.GetString(), Equals, "") 467 468 args = []interface{}{"a", int64(0)} 469 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 470 c.Assert(err, IsNil) 471 v, err = evalBuiltinFunc(f, chunk.Event{}) 472 c.Assert(err, IsNil) 473 c.Assert(v.GetString(), Equals, "") 474 475 args = []interface{}{"a", uint64(0)} 476 f, err = fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(args...))) 477 c.Assert(err, IsNil) 478 v, err = evalBuiltinFunc(f, chunk.Event{}) 479 c.Assert(err, IsNil) 480 c.Assert(v.GetString(), Equals, "") 481 } 482 483 func (s *testEvaluatorSuite) TestRepeatSig(c *C) { 484 defCausTypes := []*types.FieldType{ 485 {Tp: allegrosql.TypeVarchar}, 486 {Tp: allegrosql.TypeLonglong}, 487 } 488 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000} 489 args := []Expression{ 490 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 491 &DeferredCauset{Index: 1, RetType: defCausTypes[1]}, 492 } 493 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 494 repeat := &builtinRepeatSig{base, 1000} 495 496 cases := []struct { 497 args []interface{} 498 warning int 499 res string 500 }{ 501 {[]interface{}{"a", int64(6)}, 0, "aaaaaa"}, 502 {[]interface{}{"a", int64(10001)}, 1, ""}, 503 {[]interface{}{"毅", int64(6)}, 0, "毅毅毅毅毅毅"}, 504 {[]interface{}{"毅", int64(334)}, 2, ""}, 505 } 506 507 for _, t := range cases { 508 input := chunk.NewChunkWithCapacity(defCausTypes, 10) 509 input.AppendString(0, t.args[0].(string)) 510 input.AppendInt64(1, t.args[1].(int64)) 511 512 res, isNull, err := repeat.evalString(input.GetEvent(0)) 513 c.Assert(res, Equals, t.res) 514 c.Assert(err, IsNil) 515 if t.warning == 0 { 516 c.Assert(isNull, IsFalse) 517 } else { 518 c.Assert(isNull, IsTrue) 519 c.Assert(err, IsNil) 520 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 521 c.Assert(len(warnings), Equals, t.warning) 522 lastWarn := warnings[len(warnings)-1] 523 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue) 524 } 525 } 526 } 527 528 func (s *testEvaluatorSuite) TestLower(c *C) { 529 cases := []struct { 530 args []interface{} 531 isNil bool 532 getErr bool 533 res string 534 }{ 535 {[]interface{}{nil}, true, false, ""}, 536 {[]interface{}{"ab"}, false, false, "ab"}, 537 {[]interface{}{1}, false, false, "1"}, 538 {[]interface{}{"one week’s time TEST"}, false, false, "one week’s time test"}, 539 {[]interface{}{"one week's time TEST"}, false, false, "one week's time test"}, 540 {[]interface{}{"ABC测试DEF"}, false, false, "abc测试def"}, 541 {[]interface{}{"ABCテストDEF"}, false, false, "abcテストdef"}, 542 } 543 544 for _, t := range cases { 545 f, err := newFunctionForTest(s.ctx, ast.Lower, s.primitiveValsToConstants(t.args)...) 546 c.Assert(err, IsNil) 547 v, err := f.Eval(chunk.Event{}) 548 if t.getErr { 549 c.Assert(err, NotNil) 550 } else { 551 c.Assert(err, IsNil) 552 if t.isNil { 553 c.Assert(v.HoTT(), Equals, types.HoTTNull) 554 } else { 555 c.Assert(v.GetString(), Equals, t.res) 556 } 557 } 558 } 559 560 _, err := funcs[ast.Lower].getFunction(s.ctx, []Expression{varcharCon}) 561 c.Assert(err, IsNil) 562 } 563 564 func (s *testEvaluatorSuite) TestUpper(c *C) { 565 cases := []struct { 566 args []interface{} 567 isNil bool 568 getErr bool 569 res string 570 }{ 571 {[]interface{}{nil}, true, false, ""}, 572 {[]interface{}{"ab"}, false, false, "ab"}, 573 {[]interface{}{1}, false, false, "1"}, 574 {[]interface{}{"one week’s time TEST"}, false, false, "ONE WEEK’S TIME TEST"}, 575 {[]interface{}{"one week's time TEST"}, false, false, "ONE WEEK'S TIME TEST"}, 576 {[]interface{}{"abc测试def"}, false, false, "ABC测试DEF"}, 577 {[]interface{}{"abcテストdef"}, false, false, "ABCテストDEF"}, 578 } 579 580 for _, t := range cases { 581 f, err := newFunctionForTest(s.ctx, ast.Upper, s.primitiveValsToConstants(t.args)...) 582 c.Assert(err, IsNil) 583 v, err := f.Eval(chunk.Event{}) 584 if t.getErr { 585 c.Assert(err, NotNil) 586 } else { 587 c.Assert(err, IsNil) 588 if t.isNil { 589 c.Assert(v.HoTT(), Equals, types.HoTTNull) 590 } else { 591 c.Assert(v.GetString(), Equals, strings.ToUpper(t.res)) 592 } 593 } 594 } 595 596 _, err := funcs[ast.Upper].getFunction(s.ctx, []Expression{varcharCon}) 597 c.Assert(err, IsNil) 598 } 599 600 func (s *testEvaluatorSuite) TestReverse(c *C) { 601 fc := funcs[ast.Reverse] 602 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(nil))) 603 c.Assert(err, IsNil) 604 d, err := evalBuiltinFunc(f, chunk.Event{}) 605 c.Assert(err, IsNil) 606 c.Assert(d.HoTT(), Equals, types.HoTTNull) 607 608 tbl := []struct { 609 Input interface{} 610 Expect string 611 }{ 612 {"abc", "cba"}, 613 {"LIKE", "EKIL"}, 614 {123, "321"}, 615 {"", ""}, 616 } 617 618 dtbl := tblToDtbl(tbl) 619 620 for _, t := range dtbl { 621 f, err = fc.getFunction(s.ctx, s.datumsToConstants(t["Input"])) 622 c.Assert(err, IsNil) 623 c.Assert(f, NotNil) 624 d, err = evalBuiltinFunc(f, chunk.Event{}) 625 c.Assert(err, IsNil) 626 c.Assert(d, solitonutil.CausetEquals, t["Expect"][0]) 627 } 628 } 629 630 func (s *testEvaluatorSuite) TestStrcmp(c *C) { 631 cases := []struct { 632 args []interface{} 633 isNil bool 634 getErr bool 635 res int64 636 }{ 637 {[]interface{}{"123", "123"}, false, false, 0}, 638 {[]interface{}{"123", "1"}, false, false, 1}, 639 {[]interface{}{"1", "123"}, false, false, -1}, 640 {[]interface{}{"123", "45"}, false, false, -1}, 641 {[]interface{}{123, "123"}, false, false, 0}, 642 {[]interface{}{"12.34", 12.34}, false, false, 0}, 643 {[]interface{}{nil, "123"}, true, false, 0}, 644 {[]interface{}{"123", nil}, true, false, 0}, 645 {[]interface{}{"", "123"}, false, false, -1}, 646 {[]interface{}{"123", ""}, false, false, 1}, 647 {[]interface{}{"", ""}, false, false, 0}, 648 {[]interface{}{"", nil}, true, false, 0}, 649 {[]interface{}{nil, ""}, true, false, 0}, 650 {[]interface{}{nil, nil}, true, false, 0}, 651 {[]interface{}{"123", errors.New("must err")}, false, true, 0}, 652 } 653 for _, t := range cases { 654 f, err := newFunctionForTest(s.ctx, ast.Strcmp, s.primitiveValsToConstants(t.args)...) 655 c.Assert(err, IsNil) 656 d, err := f.Eval(chunk.Event{}) 657 if t.getErr { 658 c.Assert(err, NotNil) 659 } else { 660 c.Assert(err, IsNil) 661 if t.isNil { 662 c.Assert(d.HoTT(), Equals, types.HoTTNull) 663 } else { 664 c.Assert(d.GetInt64(), Equals, t.res) 665 } 666 } 667 } 668 } 669 670 func (s *testEvaluatorSuite) TestReplace(c *C) { 671 cases := []struct { 672 args []interface{} 673 isNil bool 674 getErr bool 675 res string 676 flen int 677 }{ 678 {[]interface{}{"www.allegrosql.com", "allegrosql", "whtcorpsinc"}, false, false, "www.whtcorpsinc.com", 17}, 679 {[]interface{}{"www.allegrosql.com", "w", 1}, false, false, "111.allegrosql.com", 260}, 680 {[]interface{}{1234, 2, 55}, false, false, "15534", 20}, 681 {[]interface{}{"", "a", "b"}, false, false, "", 0}, 682 {[]interface{}{"abc", "", "d"}, false, false, "abc", 3}, 683 {[]interface{}{"aaa", "a", ""}, false, false, "", 3}, 684 {[]interface{}{nil, "a", "b"}, true, false, "", 0}, 685 {[]interface{}{"a", nil, "b"}, true, false, "", 1}, 686 {[]interface{}{"a", "b", nil}, true, false, "", 1}, 687 {[]interface{}{errors.New("must err"), "a", "b"}, false, true, "", -1}, 688 } 689 for i, t := range cases { 690 f, err := newFunctionForTest(s.ctx, ast.Replace, s.primitiveValsToConstants(t.args)...) 691 c.Assert(err, IsNil, Commentf("test %v", i)) 692 c.Assert(f.GetType().Flen, Equals, t.flen, Commentf("test %v", i)) 693 d, err := f.Eval(chunk.Event{}) 694 if t.getErr { 695 c.Assert(err, NotNil, Commentf("test %v", i)) 696 } else { 697 c.Assert(err, IsNil, Commentf("test %v", i)) 698 if t.isNil { 699 c.Assert(d.HoTT(), Equals, types.HoTTNull, Commentf("test %v", i)) 700 } else { 701 c.Assert(d.GetString(), Equals, t.res, Commentf("test %v", i)) 702 } 703 } 704 } 705 706 _, err := funcs[ast.Replace].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()}) 707 c.Assert(err, IsNil) 708 } 709 710 func (s *testEvaluatorSuite) TestSubstring(c *C) { 711 cases := []struct { 712 args []interface{} 713 isNil bool 714 getErr bool 715 res string 716 }{ 717 {[]interface{}{"Quadratically", 5}, false, false, "ratically"}, 718 {[]interface{}{"Sakila", 1}, false, false, "Sakila"}, 719 {[]interface{}{"Sakila", 2}, false, false, "akila"}, 720 {[]interface{}{"Sakila", -3}, false, false, "ila"}, 721 {[]interface{}{"Sakila", 0}, false, false, ""}, 722 {[]interface{}{"Sakila", 100}, false, false, ""}, 723 {[]interface{}{"Sakila", -100}, false, false, ""}, 724 {[]interface{}{"Quadratically", 5, 6}, false, false, "ratica"}, 725 {[]interface{}{"Sakila", -5, 3}, false, false, "aki"}, 726 {[]interface{}{"Sakila", 2, 0}, false, false, ""}, 727 {[]interface{}{"Sakila", 2, -1}, false, false, ""}, 728 {[]interface{}{"Sakila", 2, 100}, false, false, "akila"}, 729 {[]interface{}{nil, 2, 3}, true, false, ""}, 730 {[]interface{}{"Sakila", nil, 3}, true, false, ""}, 731 {[]interface{}{"Sakila", 2, nil}, true, false, ""}, 732 {[]interface{}{errors.New("must error"), 2, 3}, false, true, ""}, 733 } 734 for _, t := range cases { 735 f, err := newFunctionForTest(s.ctx, ast.Substring, s.primitiveValsToConstants(t.args)...) 736 c.Assert(err, IsNil) 737 d, err := f.Eval(chunk.Event{}) 738 if t.getErr { 739 c.Assert(err, NotNil) 740 } else { 741 c.Assert(err, IsNil) 742 if t.isNil { 743 c.Assert(d.HoTT(), Equals, types.HoTTNull) 744 } else { 745 c.Assert(d.GetString(), Equals, t.res) 746 } 747 } 748 } 749 750 _, err := funcs[ast.Substring].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()}) 751 c.Assert(err, IsNil) 752 753 _, err = funcs[ast.Substring].getFunction(s.ctx, []Expression{NewZero(), NewZero()}) 754 c.Assert(err, IsNil) 755 } 756 757 func (s *testEvaluatorSuite) TestConvert(c *C) { 758 tbl := []struct { 759 str interface{} 760 cs string 761 result string 762 hasBinaryFlag bool 763 }{ 764 {"haha", "utf8", "haha", false}, 765 {"haha", "ascii", "haha", false}, 766 {"haha", "binary", "haha", true}, 767 {"haha", "bInAry", "haha", true}, 768 {types.NewBinaryLiteralFromUint(0x7e, -1), "BiNarY", "~", true}, 769 {types.NewBinaryLiteralFromUint(0xe4b8ade696870a, -1), "uTf8", "中文\n", false}, 770 } 771 for _, v := range tbl { 772 fc := funcs[ast.Convert] 773 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.str, v.cs))) 774 c.Assert(err, IsNil) 775 c.Assert(f, NotNil) 776 retType := f.getRetTp() 777 c.Assert(retType.Charset, Equals, strings.ToLower(v.cs)) 778 defCauslate, err := charset.GetDefaultDefCauslation(strings.ToLower(v.cs)) 779 c.Assert(err, IsNil) 780 c.Assert(retType.DefCauslate, Equals, defCauslate) 781 c.Assert(allegrosql.HasBinaryFlag(retType.Flag), Equals, v.hasBinaryFlag) 782 783 r, err := evalBuiltinFunc(f, chunk.Event{}) 784 c.Assert(err, IsNil) 785 c.Assert(r.HoTT(), Equals, types.HoTTString) 786 c.Assert(r.GetString(), Equals, v.result) 787 } 788 789 // Test case for getFunction() error 790 errTbl := []struct { 791 str interface{} 792 cs string 793 err string 794 }{ 795 {"haha", "wrongcharset", "[memex:1115]Unknown character set: 'wrongcharset'"}, 796 {"haha", "cp866", "[memex:1115]Unknown character set: 'cp866'"}, 797 } 798 for _, v := range errTbl { 799 fc := funcs[ast.Convert] 800 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.str, v.cs))) 801 c.Assert(err.Error(), Equals, v.err) 802 c.Assert(f, IsNil) 803 } 804 805 // Test wrong charset while evaluating. 806 fc := funcs[ast.Convert] 807 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets("haha", "utf8"))) 808 c.Assert(err, IsNil) 809 c.Assert(f, NotNil) 810 wrongFunction := f.(*builtinConvertSig) 811 wrongFunction.tp.Charset = "wrongcharset" 812 _, err = evalBuiltinFunc(wrongFunction, chunk.Event{}) 813 c.Assert(err.Error(), Equals, "[memex:1115]Unknown character set: 'wrongcharset'") 814 } 815 816 func (s *testEvaluatorSuite) TestSubstringIndex(c *C) { 817 cases := []struct { 818 args []interface{} 819 isNil bool 820 getErr bool 821 res string 822 }{ 823 {[]interface{}{"www.whtcorpsinc.com", ".", 2}, false, false, "www.whtcorpsinc"}, 824 {[]interface{}{"www.whtcorpsinc.com", ".", -2}, false, false, "whtcorpsinc.com"}, 825 {[]interface{}{"www.whtcorpsinc.com", ".", 0}, false, false, ""}, 826 {[]interface{}{"www.whtcorpsinc.com", ".", 100}, false, false, "www.whtcorpsinc.com"}, 827 {[]interface{}{"www.whtcorpsinc.com", ".", -100}, false, false, "www.whtcorpsinc.com"}, 828 {[]interface{}{"www.whtcorpsinc.com", "d", 0}, false, false, ""}, 829 {[]interface{}{"www.whtcorpsinc.com", "d", 1}, false, false, "www.whtcorpsinc.com"}, 830 {[]interface{}{"www.whtcorpsinc.com", "d", -1}, false, false, "www.whtcorpsinc.com"}, 831 {[]interface{}{"www.whtcorpsinc.com", "", 0}, false, false, ""}, 832 {[]interface{}{"www.whtcorpsinc.com", "", 1}, false, false, ""}, 833 {[]interface{}{"www.whtcorpsinc.com", "", -1}, false, false, ""}, 834 {[]interface{}{"", ".", 0}, false, false, ""}, 835 {[]interface{}{"", ".", 1}, false, false, ""}, 836 {[]interface{}{"", ".", -1}, false, false, ""}, 837 {[]interface{}{nil, ".", 1}, true, false, ""}, 838 {[]interface{}{"www.whtcorpsinc.com", nil, 1}, true, false, ""}, 839 {[]interface{}{"www.whtcorpsinc.com", ".", nil}, true, false, ""}, 840 {[]interface{}{errors.New("must error"), ".", 1}, false, true, ""}, 841 } 842 for _, t := range cases { 843 f, err := newFunctionForTest(s.ctx, ast.SubstringIndex, s.primitiveValsToConstants(t.args)...) 844 c.Assert(err, IsNil) 845 d, err := f.Eval(chunk.Event{}) 846 if t.getErr { 847 c.Assert(err, NotNil) 848 } else { 849 c.Assert(err, IsNil) 850 if t.isNil { 851 c.Assert(d.HoTT(), Equals, types.HoTTNull) 852 } else { 853 c.Assert(d.GetString(), Equals, t.res) 854 } 855 } 856 } 857 858 _, err := funcs[ast.SubstringIndex].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()}) 859 c.Assert(err, IsNil) 860 } 861 862 func (s *testEvaluatorSuite) TestSpace(c *C) { 863 stmtCtx := s.ctx.GetStochastikVars().StmtCtx 864 origin := stmtCtx.IgnoreTruncate 865 stmtCtx.IgnoreTruncate = true 866 defer func() { 867 stmtCtx.IgnoreTruncate = origin 868 }() 869 870 cases := []struct { 871 arg interface{} 872 isNil bool 873 getErr bool 874 res string 875 }{ 876 {0, false, false, ""}, 877 {3, false, false, " "}, 878 {allegrosql.MaxBlobWidth + 1, true, false, ""}, 879 {-1, false, false, ""}, 880 {"abc", false, false, ""}, 881 {"3", false, false, " "}, 882 {1.2, false, false, " "}, 883 {1.9, false, false, " "}, 884 {nil, true, false, ""}, 885 {errors.New("must error"), false, true, ""}, 886 } 887 for _, t := range cases { 888 f, err := newFunctionForTest(s.ctx, ast.Space, s.primitiveValsToConstants([]interface{}{t.arg})...) 889 c.Assert(err, IsNil) 890 d, err := f.Eval(chunk.Event{}) 891 if t.getErr { 892 c.Assert(err, NotNil) 893 } else { 894 c.Assert(err, IsNil) 895 if t.isNil { 896 c.Assert(d.HoTT(), Equals, types.HoTTNull) 897 } else { 898 c.Assert(d.GetString(), Equals, t.res) 899 } 900 } 901 } 902 903 _, err := funcs[ast.Space].getFunction(s.ctx, []Expression{NewZero()}) 904 c.Assert(err, IsNil) 905 } 906 907 func (s *testEvaluatorSuite) TestSpaceSig(c *C) { 908 defCausTypes := []*types.FieldType{ 909 {Tp: allegrosql.TypeLonglong}, 910 } 911 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000} 912 args := []Expression{ 913 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 914 } 915 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 916 space := &builtinSpaceSig{base, 1000} 917 input := chunk.NewChunkWithCapacity(defCausTypes, 10) 918 input.AppendInt64(0, 6) 919 input.AppendInt64(0, 1001) 920 res, isNull, err := space.evalString(input.GetEvent(0)) 921 c.Assert(res, Equals, " ") 922 c.Assert(isNull, IsFalse) 923 c.Assert(err, IsNil) 924 res, isNull, err = space.evalString(input.GetEvent(1)) 925 c.Assert(res, Equals, "") 926 c.Assert(isNull, IsTrue) 927 c.Assert(err, IsNil) 928 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 929 c.Assert(len(warnings), Equals, 1) 930 lastWarn := warnings[len(warnings)-1] 931 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue, Commentf("err %v", lastWarn.Err)) 932 } 933 934 func (s *testEvaluatorSuite) TestLocate(c *C) { 935 // 1. Test LOCATE without binary input. 936 tbl := []struct { 937 Args []interface{} 938 Want interface{} 939 }{ 940 {[]interface{}{"bar", "foobarbar"}, 4}, 941 {[]interface{}{"xbar", "foobar"}, 0}, 942 {[]interface{}{"", "foobar"}, 1}, 943 {[]interface{}{"foobar", ""}, 0}, 944 {[]interface{}{"", ""}, 1}, 945 {[]interface{}{"好世", "你好世界"}, 2}, 946 {[]interface{}{"界面", "你好世界"}, 0}, 947 {[]interface{}{"b", "中a英b文"}, 4}, 948 {[]interface{}{"bAr", "foobArbar"}, 4}, 949 {[]interface{}{nil, "foobar"}, nil}, 950 {[]interface{}{"bar", nil}, nil}, 951 {[]interface{}{"bar", "foobarbar", 5}, 7}, 952 {[]interface{}{"xbar", "foobar", 1}, 0}, 953 {[]interface{}{"", "foobar", 2}, 2}, 954 {[]interface{}{"foobar", "", 1}, 0}, 955 {[]interface{}{"", "", 2}, 0}, 956 {[]interface{}{"A", "大A写的A", 0}, 0}, 957 {[]interface{}{"A", "大A写的A", 1}, 2}, 958 {[]interface{}{"A", "大A写的A", 2}, 2}, 959 {[]interface{}{"A", "大A写的A", 3}, 5}, 960 {[]interface{}{"BaR", "foobarBaR", 5}, 7}, 961 {[]interface{}{nil, nil}, nil}, 962 {[]interface{}{"", nil}, nil}, 963 {[]interface{}{nil, ""}, nil}, 964 {[]interface{}{nil, nil, 1}, nil}, 965 {[]interface{}{"", nil, 1}, nil}, 966 {[]interface{}{nil, "", 1}, nil}, 967 {[]interface{}{"foo", nil, -1}, nil}, 968 {[]interface{}{nil, "bar", 0}, nil}, 969 } 970 Dtbl := tblToDtbl(tbl) 971 instr := funcs[ast.Locate] 972 for i, t := range Dtbl { 973 f, err := instr.getFunction(s.ctx, s.datumsToConstants(t["Args"])) 974 c.Assert(err, IsNil) 975 got, err := evalBuiltinFunc(f, chunk.Event{}) 976 c.Assert(err, IsNil) 977 c.Assert(f, NotNil) 978 c.Assert(got, DeepEquals, t["Want"][0], Commentf("[%d]: args: %v", i, t["Args"])) 979 } 980 // 2. Test LOCATE with binary input 981 tbl2 := []struct { 982 Args []interface{} 983 Want interface{} 984 }{ 985 {[]interface{}{[]byte("BaR"), "foobArbar"}, 0}, 986 {[]interface{}{"BaR", []byte("foobArbar")}, 0}, 987 {[]interface{}{[]byte("bAr"), "foobarBaR", 5}, 0}, 988 {[]interface{}{"bAr", []byte("foobarBaR"), 5}, 0}, 989 {[]interface{}{"bAr", []byte("foobarbAr"), 5}, 7}, 990 } 991 Dtbl2 := tblToDtbl(tbl2) 992 for i, t := range Dtbl2 { 993 exprs := s.datumsToConstants(t["Args"]) 994 types.SetBinChsClnFlag(exprs[0].GetType()) 995 types.SetBinChsClnFlag(exprs[1].GetType()) 996 f, err := instr.getFunction(s.ctx, exprs) 997 c.Assert(err, IsNil) 998 got, err := evalBuiltinFunc(f, chunk.Event{}) 999 c.Assert(err, IsNil) 1000 c.Assert(f, NotNil) 1001 c.Assert(got, DeepEquals, t["Want"][0], Commentf("[%d]: args: %v", i, t["Args"])) 1002 } 1003 } 1004 1005 func (s *testEvaluatorSuite) TestTrim(c *C) { 1006 cases := []struct { 1007 args []interface{} 1008 isNil bool 1009 getErr bool 1010 res string 1011 }{ 1012 {[]interface{}{" bar "}, false, false, "bar"}, 1013 {[]interface{}{"\t bar \n"}, false, false, "\t bar \n"}, 1014 {[]interface{}{"\r bar \t"}, false, false, "\r bar \t"}, 1015 {[]interface{}{" \tbar\n "}, false, false, "\tbar\n"}, 1016 {[]interface{}{""}, false, false, ""}, 1017 {[]interface{}{nil}, true, false, ""}, 1018 {[]interface{}{"xxxbarxxx", "x"}, false, false, "bar"}, 1019 {[]interface{}{"bar", "x"}, false, false, "bar"}, 1020 {[]interface{}{" bar ", ""}, false, false, " bar "}, 1021 {[]interface{}{"", "x"}, false, false, ""}, 1022 {[]interface{}{"bar", nil}, true, false, ""}, 1023 {[]interface{}{nil, "x"}, true, false, ""}, 1024 {[]interface{}{"xxxbarxxx", "x", int(ast.TrimLeading)}, false, false, "barxxx"}, 1025 {[]interface{}{"barxxyz", "xyz", int(ast.TrimTrailing)}, false, false, "barx"}, 1026 {[]interface{}{"xxxbarxxx", "x", int(ast.TrimBoth)}, false, false, "bar"}, 1027 // FIXME: the result for this test shuold be nil, current is "bar" 1028 {[]interface{}{"bar", nil, int(ast.TrimLeading)}, false, false, "bar"}, 1029 {[]interface{}{errors.New("must error")}, false, true, ""}, 1030 } 1031 for _, t := range cases { 1032 f, err := newFunctionForTest(s.ctx, ast.Trim, s.primitiveValsToConstants(t.args)...) 1033 c.Assert(err, IsNil) 1034 d, err := f.Eval(chunk.Event{}) 1035 if t.getErr { 1036 c.Assert(err, NotNil) 1037 } else { 1038 c.Assert(err, IsNil) 1039 if t.isNil { 1040 c.Assert(d.HoTT(), Equals, types.HoTTNull) 1041 } else { 1042 c.Assert(d.GetString(), Equals, t.res) 1043 } 1044 } 1045 } 1046 1047 _, err := funcs[ast.Trim].getFunction(s.ctx, []Expression{NewZero()}) 1048 c.Assert(err, IsNil) 1049 1050 _, err = funcs[ast.Trim].getFunction(s.ctx, []Expression{NewZero(), NewZero()}) 1051 c.Assert(err, IsNil) 1052 1053 _, err = funcs[ast.Trim].getFunction(s.ctx, []Expression{NewZero(), NewZero(), NewZero()}) 1054 c.Assert(err, IsNil) 1055 } 1056 1057 func (s *testEvaluatorSuite) TestLTrim(c *C) { 1058 cases := []struct { 1059 arg interface{} 1060 isNil bool 1061 getErr bool 1062 res string 1063 }{ 1064 {" bar ", false, false, "bar "}, 1065 {"\t bar ", false, false, "\t bar "}, 1066 {" \tbar ", false, false, "\tbar "}, 1067 {"\t bar ", false, false, "\t bar "}, 1068 {" \tbar ", false, false, "\tbar "}, 1069 {"\r bar ", false, false, "\r bar "}, 1070 {" \rbar ", false, false, "\rbar "}, 1071 {"\n bar ", false, false, "\n bar "}, 1072 {" \nbar ", false, false, "\nbar "}, 1073 {"bar", false, false, "bar"}, 1074 {"", false, false, ""}, 1075 {nil, true, false, ""}, 1076 {errors.New("must error"), false, true, ""}, 1077 } 1078 for _, t := range cases { 1079 f, err := newFunctionForTest(s.ctx, ast.LTrim, s.primitiveValsToConstants([]interface{}{t.arg})...) 1080 c.Assert(err, IsNil) 1081 d, err := f.Eval(chunk.Event{}) 1082 if t.getErr { 1083 c.Assert(err, NotNil) 1084 } else { 1085 c.Assert(err, IsNil) 1086 if t.isNil { 1087 c.Assert(d.HoTT(), Equals, types.HoTTNull) 1088 } else { 1089 c.Assert(d.GetString(), Equals, t.res) 1090 } 1091 } 1092 } 1093 1094 _, err := funcs[ast.LTrim].getFunction(s.ctx, []Expression{NewZero()}) 1095 c.Assert(err, IsNil) 1096 } 1097 1098 func (s *testEvaluatorSuite) TestRTrim(c *C) { 1099 cases := []struct { 1100 arg interface{} 1101 isNil bool 1102 getErr bool 1103 res string 1104 }{ 1105 {" bar ", false, false, " bar"}, 1106 {"bar", false, false, "bar"}, 1107 {"bar \n", false, false, "bar \n"}, 1108 {"bar\n ", false, false, "bar\n"}, 1109 {"bar \r", false, false, "bar \r"}, 1110 {"bar\r ", false, false, "bar\r"}, 1111 {"bar \t", false, false, "bar \t"}, 1112 {"bar\t ", false, false, "bar\t"}, 1113 {"", false, false, ""}, 1114 {nil, true, false, ""}, 1115 {errors.New("must error"), false, true, ""}, 1116 } 1117 for _, t := range cases { 1118 f, err := newFunctionForTest(s.ctx, ast.RTrim, s.primitiveValsToConstants([]interface{}{t.arg})...) 1119 c.Assert(err, IsNil) 1120 d, err := f.Eval(chunk.Event{}) 1121 if t.getErr { 1122 c.Assert(err, NotNil) 1123 } else { 1124 c.Assert(err, IsNil) 1125 if t.isNil { 1126 c.Assert(d.HoTT(), Equals, types.HoTTNull) 1127 } else { 1128 c.Assert(d.GetString(), Equals, t.res) 1129 } 1130 } 1131 } 1132 1133 _, err := funcs[ast.RTrim].getFunction(s.ctx, []Expression{NewZero()}) 1134 c.Assert(err, IsNil) 1135 } 1136 1137 func (s *testEvaluatorSuite) TestHexFunc(c *C) { 1138 cases := []struct { 1139 arg interface{} 1140 isNil bool 1141 getErr bool 1142 res string 1143 }{ 1144 {"abc", false, false, "616263"}, 1145 {"你好", false, false, "E4BDA0E5A5BD"}, 1146 {12, false, false, "C"}, 1147 {12.3, false, false, "C"}, 1148 {12.8, false, false, "D"}, 1149 {-1, false, false, "FFFFFFFFFFFFFFFF"}, 1150 {-12.3, false, false, "FFFFFFFFFFFFFFF4"}, 1151 {-12.8, false, false, "FFFFFFFFFFFFFFF3"}, 1152 {types.NewBinaryLiteralFromUint(0xC, -1), false, false, "C"}, 1153 {0x12, false, false, "12"}, 1154 {nil, true, false, ""}, 1155 {errors.New("must err"), false, true, ""}, 1156 } 1157 for _, t := range cases { 1158 f, err := newFunctionForTest(s.ctx, ast.Hex, s.primitiveValsToConstants([]interface{}{t.arg})...) 1159 c.Assert(err, IsNil) 1160 d, err := f.Eval(chunk.Event{}) 1161 if t.getErr { 1162 c.Assert(err, NotNil) 1163 } else { 1164 c.Assert(err, IsNil) 1165 if t.isNil { 1166 c.Assert(d.HoTT(), Equals, types.HoTTNull) 1167 } else { 1168 c.Assert(d.GetString(), Equals, t.res) 1169 } 1170 } 1171 } 1172 1173 _, err := funcs[ast.Hex].getFunction(s.ctx, []Expression{int8Con}) 1174 c.Assert(err, IsNil) 1175 1176 _, err = funcs[ast.Hex].getFunction(s.ctx, []Expression{varcharCon}) 1177 c.Assert(err, IsNil) 1178 } 1179 1180 func (s *testEvaluatorSuite) TestUnhexFunc(c *C) { 1181 cases := []struct { 1182 arg interface{} 1183 isNil bool 1184 getErr bool 1185 res string 1186 }{ 1187 {"4D7953514C", false, false, "MyALLEGROSQL"}, 1188 {"1267", false, false, string([]byte{0x12, 0x67})}, 1189 {"126", false, false, string([]byte{0x01, 0x26})}, 1190 {"", false, false, ""}, 1191 {1267, false, false, string([]byte{0x12, 0x67})}, 1192 {126, false, false, string([]byte{0x01, 0x26})}, 1193 {1267.3, true, false, ""}, 1194 {"string", true, false, ""}, 1195 {"你好", true, false, ""}, 1196 {nil, true, false, ""}, 1197 {errors.New("must error"), false, true, ""}, 1198 } 1199 for _, t := range cases { 1200 f, err := newFunctionForTest(s.ctx, ast.Unhex, s.primitiveValsToConstants([]interface{}{t.arg})...) 1201 c.Assert(err, IsNil) 1202 d, err := f.Eval(chunk.Event{}) 1203 if t.getErr { 1204 c.Assert(err, NotNil) 1205 } else { 1206 c.Assert(err, IsNil) 1207 if t.isNil { 1208 c.Assert(d.HoTT(), Equals, types.HoTTNull) 1209 } else { 1210 c.Assert(d.GetString(), Equals, t.res) 1211 } 1212 } 1213 } 1214 1215 _, err := funcs[ast.Unhex].getFunction(s.ctx, []Expression{NewZero()}) 1216 c.Assert(err, IsNil) 1217 } 1218 1219 func (s *testEvaluatorSuite) TestBitLength(c *C) { 1220 cases := []struct { 1221 args interface{} 1222 expected int64 1223 isNil bool 1224 getErr bool 1225 }{ 1226 {"hi", 16, false, false}, 1227 {"你好", 48, false, false}, 1228 {"", 0, false, false}, 1229 } 1230 1231 for _, t := range cases { 1232 f, err := newFunctionForTest(s.ctx, ast.BitLength, s.primitiveValsToConstants([]interface{}{t.args})...) 1233 c.Assert(err, IsNil) 1234 d, err := f.Eval(chunk.Event{}) 1235 if t.getErr { 1236 c.Assert(err, NotNil) 1237 } else { 1238 c.Assert(err, IsNil) 1239 if t.isNil { 1240 c.Assert(d.HoTT(), Equals, types.HoTTNull) 1241 } else { 1242 c.Assert(d.GetInt64(), Equals, t.expected) 1243 } 1244 } 1245 } 1246 1247 _, err := funcs[ast.BitLength].getFunction(s.ctx, []Expression{NewZero()}) 1248 c.Assert(err, IsNil) 1249 } 1250 1251 func (s *testEvaluatorSuite) TestChar(c *C) { 1252 stmtCtx := s.ctx.GetStochastikVars().StmtCtx 1253 origin := stmtCtx.IgnoreTruncate 1254 stmtCtx.IgnoreTruncate = true 1255 defer func() { 1256 stmtCtx.IgnoreTruncate = origin 1257 }() 1258 1259 tbl := []struct { 1260 str string 1261 iNum int64 1262 fNum float64 1263 result string 1264 }{ 1265 {"65", 66, 67.5, "ABD"}, // float 1266 {"65", 16740, 67.5, "AAdD"}, // large num 1267 {"65", -1, 67.5, "A\xff\xff\xff\xffD"}, // nagtive int 1268 {"a", -1, 67.5, "\x00\xff\xff\xff\xffD"}, // invalid 'a' 1269 } 1270 for _, v := range tbl { 1271 for _, char := range []interface{}{"utf8", nil} { 1272 fc := funcs[ast.CharFunc] 1273 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.str, v.iNum, v.fNum, char))) 1274 c.Assert(err, IsNil) 1275 c.Assert(f, NotNil) 1276 r, err := evalBuiltinFunc(f, chunk.Event{}) 1277 c.Assert(err, IsNil, Commentf("err: %v", err)) 1278 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(v.result)) 1279 } 1280 } 1281 1282 fc := funcs[ast.CharFunc] 1283 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets("65", 66, nil))) 1284 c.Assert(err, IsNil) 1285 r, err := evalBuiltinFunc(f, chunk.Event{}) 1286 c.Assert(err, IsNil) 1287 c.Assert(r, solitonutil.CausetEquals, types.NewCauset("AB")) 1288 } 1289 1290 func (s *testEvaluatorSuite) TestCharLength(c *C) { 1291 tbl := []struct { 1292 input interface{} 1293 result interface{} 1294 }{ 1295 {"33", 2}, // string 1296 {"你好", 2}, // mb string 1297 {33, 2}, // int 1298 {3.14, 4}, // float 1299 {nil, nil}, // nil 1300 } 1301 for _, v := range tbl { 1302 fc := funcs[ast.CharLength] 1303 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(v.input))) 1304 c.Assert(err, IsNil) 1305 r, err := evalBuiltinFunc(f, chunk.Event{}) 1306 c.Assert(err, IsNil) 1307 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(v.result)) 1308 } 1309 1310 // Test binary string 1311 tbl = []struct { 1312 input interface{} 1313 result interface{} 1314 }{ 1315 {"33", 2}, // string 1316 {"你好", 6}, // mb string 1317 {"CAFÉ", 5}, // mb string 1318 {"", 0}, // mb string 1319 {nil, nil}, // nil 1320 } 1321 for _, v := range tbl { 1322 fc := funcs[ast.CharLength] 1323 arg := s.datumsToConstants(types.MakeCausets(v.input)) 1324 tp := arg[0].GetType() 1325 tp.Tp = allegrosql.TypeVarString 1326 tp.Charset = charset.CharsetBin 1327 tp.DefCauslate = charset.DefCauslationBin 1328 tp.Flen = types.UnspecifiedLength 1329 tp.Flag = allegrosql.BinaryFlag 1330 f, err := fc.getFunction(s.ctx, arg) 1331 c.Assert(err, IsNil) 1332 r, err := evalBuiltinFunc(f, chunk.Event{}) 1333 c.Assert(err, IsNil) 1334 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(v.result)) 1335 } 1336 } 1337 1338 func (s *testEvaluatorSuite) TestFindInSet(c *C) { 1339 for _, t := range []struct { 1340 str interface{} 1341 strlst interface{} 1342 ret interface{} 1343 }{ 1344 {"foo", "foo,bar", 1}, 1345 {"foo", "foobar,bar", 0}, 1346 {" foo ", "foo, foo ", 2}, 1347 {"", "foo,bar,", 3}, 1348 {"", "", 0}, 1349 {1, 1, 1}, 1350 {1, "1", 1}, 1351 {"1", 1, 1}, 1352 {"a,b", "a,b,c", 0}, 1353 {"foo", nil, nil}, 1354 {nil, "bar", nil}, 1355 } { 1356 fc := funcs[ast.FindInSet] 1357 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.str, t.strlst))) 1358 c.Assert(err, IsNil) 1359 r, err := evalBuiltinFunc(f, chunk.Event{}) 1360 c.Assert(err, IsNil) 1361 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret), Commentf("FindInSet(%s, %s)", t.str, t.strlst)) 1362 } 1363 } 1364 1365 func (s *testEvaluatorSuite) TestField(c *C) { 1366 stmtCtx := s.ctx.GetStochastikVars().StmtCtx 1367 origin := stmtCtx.IgnoreTruncate 1368 stmtCtx.IgnoreTruncate = true 1369 defer func() { 1370 stmtCtx.IgnoreTruncate = origin 1371 }() 1372 1373 tbl := []struct { 1374 argLst []interface{} 1375 ret interface{} 1376 }{ 1377 {[]interface{}{"ej", "Hej", "ej", "Heja", "hej", "foo"}, int64(2)}, 1378 {[]interface{}{"fo", "Hej", "ej", "Heja", "hej", "foo"}, int64(0)}, 1379 {[]interface{}{"ej", "Hej", "ej", "Heja", "ej", "hej", "foo"}, int64(2)}, 1380 {[]interface{}{1, 2, 3, 11, 1}, int64(4)}, 1381 {[]interface{}{nil, 2, 3, 11, 1}, int64(0)}, 1382 {[]interface{}{1.1, 2.1, 3.1, 11.1, 1.1}, int64(4)}, 1383 {[]interface{}{1.1, "2.1", "3.1", "11.1", "1.1"}, int64(4)}, 1384 {[]interface{}{"1.1a", 2.1, 3.1, 11.1, 1.1}, int64(4)}, 1385 {[]interface{}{1.10, 0, 11e-1}, int64(2)}, 1386 {[]interface{}{"abc", 0, 1, 11.1, 1.1}, int64(1)}, 1387 } 1388 for _, t := range tbl { 1389 fc := funcs[ast.Field] 1390 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argLst...))) 1391 c.Assert(err, IsNil) 1392 c.Assert(f, NotNil) 1393 r, err := evalBuiltinFunc(f, chunk.Event{}) 1394 c.Assert(err, IsNil) 1395 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret)) 1396 } 1397 } 1398 1399 func (s *testEvaluatorSuite) TestLpad(c *C) { 1400 tests := []struct { 1401 str string 1402 len int64 1403 padStr string 1404 expect interface{} 1405 }{ 1406 {"hi", 5, "?", "???hi"}, 1407 {"hi", 1, "?", "h"}, 1408 {"hi", 0, "?", ""}, 1409 {"hi", -1, "?", nil}, 1410 {"hi", 1, "", "h"}, 1411 {"hi", 5, "", nil}, 1412 {"hi", 5, "ab", "abahi"}, 1413 {"hi", 6, "ab", "ababhi"}, 1414 } 1415 fc := funcs[ast.Lpad] 1416 for _, test := range tests { 1417 str := types.NewStringCauset(test.str) 1418 length := types.NewIntCauset(test.len) 1419 padStr := types.NewStringCauset(test.padStr) 1420 f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, length, padStr})) 1421 c.Assert(err, IsNil) 1422 c.Assert(f, NotNil) 1423 result, err := evalBuiltinFunc(f, chunk.Event{}) 1424 c.Assert(err, IsNil) 1425 if test.expect == nil { 1426 c.Assert(result.HoTT(), Equals, types.HoTTNull) 1427 } else { 1428 expect, _ := test.expect.(string) 1429 c.Assert(result.GetString(), Equals, expect) 1430 } 1431 } 1432 } 1433 1434 func (s *testEvaluatorSuite) TestRpad(c *C) { 1435 tests := []struct { 1436 str string 1437 len int64 1438 padStr string 1439 expect interface{} 1440 }{ 1441 {"hi", 5, "?", "hi???"}, 1442 {"hi", 1, "?", "h"}, 1443 {"hi", 0, "?", ""}, 1444 {"hi", -1, "?", nil}, 1445 {"hi", 1, "", "h"}, 1446 {"hi", 5, "", nil}, 1447 {"hi", 5, "ab", "hiaba"}, 1448 {"hi", 6, "ab", "hiabab"}, 1449 } 1450 fc := funcs[ast.Rpad] 1451 for _, test := range tests { 1452 str := types.NewStringCauset(test.str) 1453 length := types.NewIntCauset(test.len) 1454 padStr := types.NewStringCauset(test.padStr) 1455 f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, length, padStr})) 1456 c.Assert(err, IsNil) 1457 c.Assert(f, NotNil) 1458 result, err := evalBuiltinFunc(f, chunk.Event{}) 1459 c.Assert(err, IsNil) 1460 if test.expect == nil { 1461 c.Assert(result.HoTT(), Equals, types.HoTTNull) 1462 } else { 1463 expect, _ := test.expect.(string) 1464 c.Assert(result.GetString(), Equals, expect) 1465 } 1466 } 1467 } 1468 1469 func (s *testEvaluatorSuite) TestRpadSig(c *C) { 1470 defCausTypes := []*types.FieldType{ 1471 {Tp: allegrosql.TypeVarchar}, 1472 {Tp: allegrosql.TypeLonglong}, 1473 {Tp: allegrosql.TypeVarchar}, 1474 } 1475 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 1000} 1476 1477 args := []Expression{ 1478 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 1479 &DeferredCauset{Index: 1, RetType: defCausTypes[1]}, 1480 &DeferredCauset{Index: 2, RetType: defCausTypes[2]}, 1481 } 1482 1483 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 1484 rpad := &builtinRpadUTF8Sig{base, 1000} 1485 1486 input := chunk.NewChunkWithCapacity(defCausTypes, 10) 1487 input.AppendString(0, "abc") 1488 input.AppendString(0, "abc") 1489 input.AppendInt64(1, 6) 1490 input.AppendInt64(1, 10000) 1491 input.AppendString(2, "123") 1492 input.AppendString(2, "123") 1493 1494 res, isNull, err := rpad.evalString(input.GetEvent(0)) 1495 c.Assert(res, Equals, "abc123") 1496 c.Assert(isNull, IsFalse) 1497 c.Assert(err, IsNil) 1498 1499 res, isNull, err = rpad.evalString(input.GetEvent(1)) 1500 c.Assert(res, Equals, "") 1501 c.Assert(isNull, IsTrue) 1502 c.Assert(err, IsNil) 1503 1504 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 1505 c.Assert(len(warnings), Equals, 1) 1506 lastWarn := warnings[len(warnings)-1] 1507 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue, Commentf("err %v", lastWarn.Err)) 1508 } 1509 1510 func (s *testEvaluatorSuite) TestInsertBinarySig(c *C) { 1511 defCausTypes := []*types.FieldType{ 1512 {Tp: allegrosql.TypeVarchar}, 1513 {Tp: allegrosql.TypeLonglong}, 1514 {Tp: allegrosql.TypeLonglong}, 1515 {Tp: allegrosql.TypeVarchar}, 1516 } 1517 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: 3} 1518 1519 args := []Expression{ 1520 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 1521 &DeferredCauset{Index: 1, RetType: defCausTypes[1]}, 1522 &DeferredCauset{Index: 2, RetType: defCausTypes[2]}, 1523 &DeferredCauset{Index: 3, RetType: defCausTypes[3]}, 1524 } 1525 1526 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 1527 insert := &builtinInsertSig{base, 3} 1528 1529 input := chunk.NewChunkWithCapacity(defCausTypes, 2) 1530 input.AppendString(0, "abc") 1531 input.AppendString(0, "abc") 1532 input.AppendString(0, "abc") 1533 input.AppendNull(0) 1534 input.AppendString(0, "abc") 1535 input.AppendString(0, "abc") 1536 input.AppendString(0, "abc") 1537 input.AppendInt64(1, 3) 1538 input.AppendInt64(1, 3) 1539 input.AppendInt64(1, 0) 1540 input.AppendInt64(1, 3) 1541 input.AppendNull(1) 1542 input.AppendInt64(1, 3) 1543 input.AppendInt64(1, 3) 1544 input.AppendInt64(2, -1) 1545 input.AppendInt64(2, -1) 1546 input.AppendInt64(2, -1) 1547 input.AppendInt64(2, -1) 1548 input.AppendInt64(2, -1) 1549 input.AppendNull(2) 1550 input.AppendInt64(2, -1) 1551 input.AppendString(3, "d") 1552 input.AppendString(3, "de") 1553 input.AppendString(3, "d") 1554 input.AppendString(3, "d") 1555 input.AppendString(3, "d") 1556 input.AppendString(3, "d") 1557 input.AppendNull(3) 1558 1559 res, isNull, err := insert.evalString(input.GetEvent(0)) 1560 c.Assert(res, Equals, "abd") 1561 c.Assert(isNull, IsFalse) 1562 c.Assert(err, IsNil) 1563 1564 res, isNull, err = insert.evalString(input.GetEvent(1)) 1565 c.Assert(res, Equals, "") 1566 c.Assert(isNull, IsTrue) 1567 c.Assert(err, IsNil) 1568 1569 res, isNull, err = insert.evalString(input.GetEvent(2)) 1570 c.Assert(res, Equals, "abc") 1571 c.Assert(isNull, IsFalse) 1572 c.Assert(err, IsNil) 1573 1574 res, isNull, err = insert.evalString(input.GetEvent(3)) 1575 c.Assert(res, Equals, "") 1576 c.Assert(isNull, IsTrue) 1577 c.Assert(err, IsNil) 1578 1579 res, isNull, err = insert.evalString(input.GetEvent(4)) 1580 c.Assert(res, Equals, "") 1581 c.Assert(isNull, IsTrue) 1582 c.Assert(err, IsNil) 1583 1584 res, isNull, err = insert.evalString(input.GetEvent(5)) 1585 c.Assert(res, Equals, "") 1586 c.Assert(isNull, IsTrue) 1587 c.Assert(err, IsNil) 1588 1589 res, isNull, err = insert.evalString(input.GetEvent(6)) 1590 c.Assert(res, Equals, "") 1591 c.Assert(isNull, IsTrue) 1592 c.Assert(err, IsNil) 1593 1594 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 1595 c.Assert(len(warnings), Equals, 1) 1596 lastWarn := warnings[len(warnings)-1] 1597 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue, Commentf("err %v", lastWarn.Err)) 1598 } 1599 1600 func (s *testEvaluatorSuite) TestInstr(c *C) { 1601 tbl := []struct { 1602 Args []interface{} 1603 Want interface{} 1604 }{ 1605 {[]interface{}{"foobarbar", "bar"}, 4}, 1606 {[]interface{}{"xbar", "foobar"}, 0}, 1607 1608 {[]interface{}{123456234, 234}, 2}, 1609 {[]interface{}{123456, 567}, 0}, 1610 {[]interface{}{1e10, 1e2}, 1}, 1611 {[]interface{}{1.234, ".234"}, 2}, 1612 {[]interface{}{1.234, ""}, 1}, 1613 {[]interface{}{"", 123}, 0}, 1614 {[]interface{}{"", ""}, 1}, 1615 1616 {[]interface{}{"中文美好", "美好"}, 3}, 1617 {[]interface{}{"中文美好", "世界"}, 0}, 1618 {[]interface{}{"中文abc", "a"}, 3}, 1619 1620 {[]interface{}{"live long and prosper", "long"}, 6}, 1621 1622 {[]interface{}{"not binary string", "binary"}, 5}, 1623 {[]interface{}{"upper case", "upper"}, 1}, 1624 {[]interface{}{"UPPER CASE", "CASE"}, 7}, 1625 {[]interface{}{"中文abc", "abc"}, 3}, 1626 1627 {[]interface{}{"foobar", nil}, nil}, 1628 {[]interface{}{nil, "foobar"}, nil}, 1629 {[]interface{}{nil, nil}, nil}, 1630 } 1631 1632 Dtbl := tblToDtbl(tbl) 1633 instr := funcs[ast.Instr] 1634 for i, t := range Dtbl { 1635 f, err := instr.getFunction(s.ctx, s.datumsToConstants(t["Args"])) 1636 c.Assert(err, IsNil) 1637 c.Assert(f, NotNil) 1638 got, err := evalBuiltinFunc(f, chunk.Event{}) 1639 c.Assert(err, IsNil) 1640 c.Assert(got, DeepEquals, t["Want"][0], Commentf("[%d]: args: %v", i, t["Args"])) 1641 } 1642 } 1643 1644 func (s *testEvaluatorSuite) TestMakeSet(c *C) { 1645 tbl := []struct { 1646 argList []interface{} 1647 ret interface{} 1648 }{ 1649 {[]interface{}{1, "a", "b", "c"}, "a"}, 1650 {[]interface{}{1 | 4, "hello", "nice", "world"}, "hello,world"}, 1651 {[]interface{}{1 | 4, "hello", "nice", nil, "world"}, "hello"}, 1652 {[]interface{}{0, "a", "b", "c"}, ""}, 1653 {[]interface{}{nil, "a", "b", "c"}, nil}, 1654 {[]interface{}{-100 | 4, "hello", "nice", "abc", "world"}, "abc,world"}, 1655 {[]interface{}{-1, "hello", "nice", "abc", "world"}, "hello,nice,abc,world"}, 1656 } 1657 1658 for _, t := range tbl { 1659 fc := funcs[ast.MakeSet] 1660 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argList...))) 1661 c.Assert(err, IsNil) 1662 c.Assert(f, NotNil) 1663 r, err := evalBuiltinFunc(f, chunk.Event{}) 1664 c.Assert(err, IsNil) 1665 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret)) 1666 } 1667 } 1668 1669 func (s *testEvaluatorSuite) TestOct(c *C) { 1670 octTests := []struct { 1671 origin interface{} 1672 ret string 1673 }{ 1674 {"-2.7", "1777777777777777777776"}, 1675 {-1.5, "1777777777777777777777"}, 1676 {-1, "1777777777777777777777"}, 1677 {"0", "0"}, 1678 {"1", "1"}, 1679 {"8", "10"}, 1680 {"12", "14"}, 1681 {"20", "24"}, 1682 {"100", "144"}, 1683 {"1024", "2000"}, 1684 {"2048", "4000"}, 1685 {1.0, "1"}, 1686 {9.5, "11"}, 1687 {13, "15"}, 1688 {1025, "2001"}, 1689 {"8a8", "10"}, 1690 {"abc", "0"}, 1691 //overflow uint64 1692 {"9999999999999999999999999", "1777777777777777777777"}, 1693 {"-9999999999999999999999999", "1777777777777777777777"}, 1694 {types.NewBinaryLiteralFromUint(255, -1), "377"}, // b'11111111' 1695 {types.NewBinaryLiteralFromUint(10, -1), "12"}, // b'1010' 1696 {types.NewBinaryLiteralFromUint(5, -1), "5"}, // b'0101' 1697 } 1698 fc := funcs[ast.Oct] 1699 for _, tt := range octTests { 1700 in := types.NewCauset(tt.origin) 1701 f, _ := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{in})) 1702 c.Assert(f, NotNil) 1703 r, err := evalBuiltinFunc(f, chunk.Event{}) 1704 c.Assert(err, IsNil) 1705 res, err := r.ToString() 1706 c.Assert(err, IsNil) 1707 c.Assert(res, Equals, tt.ret, Commentf("select oct(%v);", tt.origin)) 1708 } 1709 // tt NULL input for sha 1710 var argNull types.Causet 1711 f, _ := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{argNull})) 1712 r, err := evalBuiltinFunc(f, chunk.Event{}) 1713 c.Assert(err, IsNil) 1714 c.Assert(r.IsNull(), IsTrue) 1715 } 1716 1717 func (s *testEvaluatorSuite) TestFormat(c *C) { 1718 formatTests := []struct { 1719 number interface{} 1720 precision interface{} 1721 locale string 1722 ret interface{} 1723 }{ 1724 {12332.12341111111111111111111111111111111111111, 4, "en_US", "12,332.1234"}, 1725 {nil, 22, "en_US", nil}, 1726 } 1727 formatTests1 := []struct { 1728 number interface{} 1729 precision interface{} 1730 ret interface{} 1731 warnings int 1732 }{ 1733 // issue #8796 1734 {1.12345, 4, "1.1235", 0}, 1735 {9.99999, 4, "10.0000", 0}, 1736 {1.99999, 4, "2.0000", 0}, 1737 {1.09999, 4, "1.1000", 0}, 1738 {-2.5000, 0, "-3", 0}, 1739 1740 {12332.123444, 4, "12,332.1234", 0}, 1741 {12332.123444, 0, "12,332", 0}, 1742 {12332.123444, -4, "12,332", 0}, 1743 {-12332.123444, 4, "-12,332.1234", 0}, 1744 {-12332.123444, 0, "-12,332", 0}, 1745 {-12332.123444, -4, "-12,332", 0}, 1746 {"12332.123444", "4", "12,332.1234", 0}, 1747 {"12332.123444A", "4", "12,332.1234", 1}, 1748 {"-12332.123444", "4", "-12,332.1234", 0}, 1749 {"-12332.123444A", "4", "-12,332.1234", 1}, 1750 {"A123345", "4", "0.0000", 1}, 1751 {"-A123345", "4", "0.0000", 1}, 1752 {"-12332.123444", "A", "-12,332", 1}, 1753 {"12332.123444", "A", "12,332", 1}, 1754 {"-12332.123444", "4A", "-12,332.1234", 1}, 1755 {"12332.123444", "4A", "12,332.1234", 1}, 1756 {"-A12332.123444", "A", "0", 2}, 1757 {"A12332.123444", "A", "0", 2}, 1758 {"-A12332.123444", "4A", "0.0000", 2}, 1759 {"A12332.123444", "4A", "0.0000", 2}, 1760 {"-.12332.123444", "4A", "-0.1233", 2}, 1761 {".12332.123444", "4A", "0.1233", 2}, 1762 {"12332.1234567890123456789012345678901", 22, "12,332.1234567890110000000000", 0}, 1763 {nil, 22, nil, 0}, 1764 {1, 1024, "1.000000000000000000000000000000", 0}, 1765 {"", 1, "0.0", 0}, 1766 {1, "", "1", 1}, 1767 } 1768 formatTests2 := struct { 1769 number interface{} 1770 precision interface{} 1771 locale string 1772 ret interface{} 1773 }{-12332.123456, -4, "zh_CN", nil} 1774 formatTests3 := struct { 1775 number interface{} 1776 precision interface{} 1777 locale string 1778 ret interface{} 1779 }{"-12332.123456", "4", "de_GE", nil} 1780 formatTests4 := struct { 1781 number interface{} 1782 precision interface{} 1783 locale interface{} 1784 ret interface{} 1785 }{1, 4, nil, "1.0000"} 1786 1787 fc := funcs[ast.Format] 1788 for _, tt := range formatTests { 1789 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tt.number, tt.precision, tt.locale))) 1790 c.Assert(err, IsNil) 1791 c.Assert(f, NotNil) 1792 r, err := evalBuiltinFunc(f, chunk.Event{}) 1793 c.Assert(err, IsNil) 1794 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(tt.ret)) 1795 } 1796 1797 origConfig := s.ctx.GetStochastikVars().StmtCtx.TruncateAsWarning 1798 s.ctx.GetStochastikVars().StmtCtx.TruncateAsWarning = true 1799 for _, tt := range formatTests1 { 1800 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(tt.number, tt.precision))) 1801 c.Assert(err, IsNil) 1802 c.Assert(f, NotNil) 1803 r, err := evalBuiltinFunc(f, chunk.Event{}) 1804 c.Assert(err, IsNil) 1805 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(tt.ret), Commentf("test %v", tt)) 1806 if tt.warnings > 0 { 1807 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 1808 c.Assert(len(warnings), Equals, tt.warnings, Commentf("test %v", tt)) 1809 for i := 0; i < tt.warnings; i++ { 1810 c.Assert(terror.ErrorEqual(types.ErrTruncatedWrongVal, warnings[i].Err), IsTrue, Commentf("test %v", tt)) 1811 } 1812 s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{}) 1813 } 1814 } 1815 s.ctx.GetStochastikVars().StmtCtx.TruncateAsWarning = origConfig 1816 1817 f2, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(formatTests2.number, formatTests2.precision, formatTests2.locale))) 1818 c.Assert(err, IsNil) 1819 c.Assert(f2, NotNil) 1820 r2, err := evalBuiltinFunc(f2, chunk.Event{}) 1821 c.Assert(types.NewCauset(err), solitonutil.CausetEquals, types.NewCauset(errors.New("not implemented"))) 1822 c.Assert(r2, solitonutil.CausetEquals, types.NewCauset(formatTests2.ret)) 1823 1824 f3, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(formatTests3.number, formatTests3.precision, formatTests3.locale))) 1825 c.Assert(err, IsNil) 1826 c.Assert(f3, NotNil) 1827 r3, err := evalBuiltinFunc(f3, chunk.Event{}) 1828 c.Assert(types.NewCauset(err), solitonutil.CausetEquals, types.NewCauset(errors.New("not support for the specific locale"))) 1829 c.Assert(r3, solitonutil.CausetEquals, types.NewCauset(formatTests3.ret)) 1830 1831 f4, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(formatTests4.number, formatTests4.precision, formatTests4.locale))) 1832 c.Assert(err, IsNil) 1833 c.Assert(f4, NotNil) 1834 r4, err := evalBuiltinFunc(f4, chunk.Event{}) 1835 c.Assert(err, IsNil) 1836 c.Assert(r4, solitonutil.CausetEquals, types.NewCauset(formatTests4.ret)) 1837 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 1838 c.Assert(len(warnings), Equals, 1) 1839 c.Assert(terror.ErrorEqual(errUnknownLocale, warnings[0].Err), IsTrue) 1840 s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{}) 1841 } 1842 1843 func (s *testEvaluatorSuite) TestFromBase64(c *C) { 1844 tests := []struct { 1845 args interface{} 1846 expect interface{} 1847 }{ 1848 {"", ""}, 1849 {"YWJj", "abc"}, 1850 {"YWIgYw==", "ab c"}, 1851 {"YWIKYw==", "ab\nc"}, 1852 {"YWIJYw==", "ab\tc"}, 1853 {"cXdlcnR5MTIzNDU2", "qwerty123456"}, 1854 { 1855 "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4\neXowMTIzNDU2Nzg5Ky9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3Bx\ncnN0dXZ3eHl6MDEyMzQ1Njc4OSsv", 1856 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 1857 }, 1858 { 1859 "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==", 1860 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 1861 }, 1862 { 1863 "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==", 1864 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 1865 }, 1866 { 1867 "QUJDREVGR0hJSkt\tMTU5PUFFSU1RVVld\nYWVphYmNkZ\rWZnaGlqa2xt bm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==", 1868 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 1869 }, 1870 } 1871 fc := funcs[ast.FromBase64] 1872 for _, test := range tests { 1873 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(test.args))) 1874 c.Assert(err, IsNil) 1875 c.Assert(f, NotNil) 1876 result, err := evalBuiltinFunc(f, chunk.Event{}) 1877 c.Assert(err, IsNil) 1878 if test.expect == nil { 1879 c.Assert(result.HoTT(), Equals, types.HoTTNull) 1880 } else { 1881 expect, _ := test.expect.(string) 1882 c.Assert(result.GetString(), Equals, expect) 1883 } 1884 } 1885 } 1886 1887 func (s *testEvaluatorSuite) TestFromBase64Sig(c *C) { 1888 defCausTypes := []*types.FieldType{ 1889 {Tp: allegrosql.TypeVarchar}, 1890 } 1891 1892 tests := []struct { 1893 args string 1894 expect string 1895 isNil bool 1896 maxAllowPacket uint64 1897 }{ 1898 {"YWJj", "abc", false, 3}, 1899 {"YWJj", "", true, 2}, 1900 { 1901 "QUJDREVGR0hJSkt\tMTU5PUFFSU1RVVld\nYWVphYmNkZ\rWZnaGlqa2xt bm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==", 1902 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 1903 false, 1904 70, 1905 }, 1906 { 1907 "QUJDREVGR0hJSkt\tMTU5PUFFSU1RVVld\nYWVphYmNkZ\rWZnaGlqa2xt bm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLw==", 1908 "", 1909 true, 1910 69, 1911 }, 1912 } 1913 1914 args := []Expression{ 1915 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 1916 } 1917 1918 for _, test := range tests { 1919 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: allegrosql.MaxBlobWidth} 1920 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 1921 fromBase64 := &builtinFromBase64Sig{base, test.maxAllowPacket} 1922 1923 input := chunk.NewChunkWithCapacity(defCausTypes, 1) 1924 input.AppendString(0, test.args) 1925 res, isNull, err := fromBase64.evalString(input.GetEvent(0)) 1926 c.Assert(err, IsNil) 1927 c.Assert(isNull, Equals, test.isNil) 1928 if isNull { 1929 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 1930 c.Assert(len(warnings), Equals, 1) 1931 lastWarn := warnings[len(warnings)-1] 1932 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue) 1933 s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{}) 1934 } 1935 c.Assert(res, Equals, test.expect) 1936 } 1937 } 1938 1939 func (s *testEvaluatorSuite) TestInsert(c *C) { 1940 tests := []struct { 1941 args []interface{} 1942 expect interface{} 1943 }{ 1944 {[]interface{}{"Quadratic", 3, 4, "What"}, "QuWhattic"}, 1945 {[]interface{}{"Quadratic", -1, 4, "What"}, "Quadratic"}, 1946 {[]interface{}{"Quadratic", 3, 100, "What"}, "QuWhat"}, 1947 {[]interface{}{nil, 3, 100, "What"}, nil}, 1948 {[]interface{}{"Quadratic", nil, 4, "What"}, nil}, 1949 {[]interface{}{"Quadratic", 3, nil, "What"}, nil}, 1950 {[]interface{}{"Quadratic", 3, 4, nil}, nil}, 1951 {[]interface{}{"Quadratic", 3, -1, "What"}, "QuWhat"}, 1952 {[]interface{}{"Quadratic", 3, 1, "What"}, "QuWhatdratic"}, 1953 {[]interface{}{"Quadratic", -1, nil, "What"}, nil}, 1954 {[]interface{}{"Quadratic", -1, 4, nil}, nil}, 1955 1956 {[]interface{}{"我叫小雨呀", 3, 2, "王雨叶"}, "我叫王雨叶呀"}, 1957 {[]interface{}{"我叫小雨呀", -1, 2, "王雨叶"}, "我叫小雨呀"}, 1958 {[]interface{}{"我叫小雨呀", 3, 100, "王雨叶"}, "我叫王雨叶"}, 1959 {[]interface{}{nil, 3, 100, "王雨叶"}, nil}, 1960 {[]interface{}{"我叫小雨呀", nil, 4, "王雨叶"}, nil}, 1961 {[]interface{}{"我叫小雨呀", 3, nil, "王雨叶"}, nil}, 1962 {[]interface{}{"我叫小雨呀", 3, 4, nil}, nil}, 1963 {[]interface{}{"我叫小雨呀", 3, -1, "王雨叶"}, "我叫王雨叶"}, 1964 {[]interface{}{"我叫小雨呀", 3, 1, "王雨叶"}, "我叫王雨叶雨呀"}, 1965 {[]interface{}{"我叫小雨呀", -1, nil, "王雨叶"}, nil}, 1966 {[]interface{}{"我叫小雨呀", -1, 2, nil}, nil}, 1967 } 1968 fc := funcs[ast.InsertFunc] 1969 for _, test := range tests { 1970 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(test.args...))) 1971 c.Assert(err, IsNil) 1972 c.Assert(f, NotNil) 1973 result, err := evalBuiltinFunc(f, chunk.Event{}) 1974 c.Assert(err, IsNil) 1975 if test.expect == nil { 1976 c.Assert(result.HoTT(), Equals, types.HoTTNull) 1977 } else { 1978 expect, _ := test.expect.(string) 1979 c.Assert(result.GetString(), Equals, expect) 1980 } 1981 } 1982 } 1983 1984 func (s *testEvaluatorSuite) TestOrd(c *C) { 1985 cases := []struct { 1986 args interface{} 1987 expected int64 1988 isNil bool 1989 getErr bool 1990 }{ 1991 {"2", 50, false, false}, 1992 {2, 50, false, false}, 1993 {"23", 50, false, false}, 1994 {23, 50, false, false}, 1995 {2.3, 50, false, false}, 1996 {nil, 0, true, false}, 1997 {"", 0, false, false}, 1998 {"你好", 14990752, false, false}, 1999 {"にほん", 14909867, false, false}, 2000 {"한국", 15570332, false, false}, 2001 {"👍", 4036989325, false, false}, 2002 {"א", 55184, false, false}, 2003 } 2004 for _, t := range cases { 2005 f, err := newFunctionForTest(s.ctx, ast.Ord, s.primitiveValsToConstants([]interface{}{t.args})...) 2006 c.Assert(err, IsNil) 2007 2008 d, err := f.Eval(chunk.Event{}) 2009 if t.getErr { 2010 c.Assert(err, NotNil) 2011 } else { 2012 c.Assert(err, IsNil) 2013 if t.isNil { 2014 c.Assert(d.HoTT(), Equals, types.HoTTNull) 2015 } else { 2016 c.Assert(d.GetInt64(), Equals, t.expected) 2017 } 2018 } 2019 } 2020 _, err := funcs[ast.Ord].getFunction(s.ctx, []Expression{NewZero()}) 2021 c.Assert(err, IsNil) 2022 } 2023 2024 func (s *testEvaluatorSuite) TestElt(c *C) { 2025 tbl := []struct { 2026 argLst []interface{} 2027 ret interface{} 2028 }{ 2029 {[]interface{}{1, "Hej", "ej", "Heja", "hej", "foo"}, "Hej"}, 2030 {[]interface{}{9, "Hej", "ej", "Heja", "hej", "foo"}, nil}, 2031 {[]interface{}{-1, "Hej", "ej", "Heja", "ej", "hej", "foo"}, nil}, 2032 {[]interface{}{0, 2, 3, 11, 1}, nil}, 2033 {[]interface{}{3, 2, 3, 11, 1}, "11"}, 2034 {[]interface{}{1.1, "2.1", "3.1", "11.1", "1.1"}, "2.1"}, 2035 } 2036 for _, t := range tbl { 2037 fc := funcs[ast.Elt] 2038 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argLst...))) 2039 c.Assert(err, IsNil) 2040 r, err := evalBuiltinFunc(f, chunk.Event{}) 2041 c.Assert(err, IsNil) 2042 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret)) 2043 } 2044 } 2045 2046 func (s *testEvaluatorSuite) TestExportSet(c *C) { 2047 estd := []struct { 2048 argLst []interface{} 2049 res string 2050 }{ 2051 {[]interface{}{-9223372036854775807, "Y", "N", ",", 5}, "Y,N,N,N,N"}, 2052 {[]interface{}{-6, "Y", "N", ",", 5}, "N,Y,N,Y,Y"}, 2053 {[]interface{}{5, "Y", "N", ",", 4}, "Y,N,Y,N"}, 2054 {[]interface{}{5, "Y", "N", ",", 0}, ""}, 2055 {[]interface{}{5, "Y", "N", ",", 1}, "Y"}, 2056 {[]interface{}{6, "1", "0", ",", 10}, "0,1,1,0,0,0,0,0,0,0"}, 2057 {[]interface{}{333333, "Ysss", "sN", "---", 9}, "Ysss---sN---Ysss---sN---Ysss---sN---sN---sN---sN"}, 2058 {[]interface{}{7, "Y", "N"}, "Y,Y,Y,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N"}, 2059 {[]interface{}{7, "Y", "N", 6}, "Y6Y6Y6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N"}, 2060 {[]interface{}{7, "Y", "N", 6, 133}, "Y6Y6Y6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N6N"}, 2061 } 2062 fc := funcs[ast.ExportSet] 2063 for _, t := range estd { 2064 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.argLst...))) 2065 c.Assert(err, IsNil) 2066 c.Assert(f, NotNil) 2067 exportSetRes, err := evalBuiltinFunc(f, chunk.Event{}) 2068 c.Assert(err, IsNil) 2069 res, err := exportSetRes.ToString() 2070 c.Assert(err, IsNil) 2071 c.Assert(res, Equals, t.res) 2072 } 2073 } 2074 2075 func (s *testEvaluatorSuite) TestBin(c *C) { 2076 tbl := []struct { 2077 Input interface{} 2078 Expected interface{} 2079 }{ 2080 {"10", "1010"}, 2081 {"10.2", "1010"}, 2082 {"10aa", "1010"}, 2083 {"10.2aa", "1010"}, 2084 {"aaa", "0"}, 2085 {"", nil}, 2086 {10, "1010"}, 2087 {10.0, "1010"}, 2088 {-1, "1111111111111111111111111111111111111111111111111111111111111111"}, 2089 {"-1", "1111111111111111111111111111111111111111111111111111111111111111"}, 2090 {nil, nil}, 2091 } 2092 fc := funcs[ast.Bin] 2093 dtbl := tblToDtbl(tbl) 2094 ctx := mock.NewContext() 2095 ctx.GetStochastikVars().StmtCtx.IgnoreTruncate = true 2096 for _, t := range dtbl { 2097 f, err := fc.getFunction(ctx, s.datumsToConstants(t["Input"])) 2098 c.Assert(err, IsNil) 2099 c.Assert(f, NotNil) 2100 r, err := evalBuiltinFunc(f, chunk.Event{}) 2101 c.Assert(err, IsNil) 2102 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t["Expected"][0])) 2103 } 2104 } 2105 2106 func (s *testEvaluatorSuite) TestQuote(c *C) { 2107 tbl := []struct { 2108 arg interface{} 2109 ret interface{} 2110 }{ 2111 {`Don\'t!`, `'Don\\\'t!'`}, 2112 {`Don't`, `'Don\'t'`}, 2113 {`Don"`, `'Don"'`}, 2114 {`Don\"`, `'Don\\"'`}, 2115 {`\'`, `'\\\''`}, 2116 {`\"`, `'\\"'`}, 2117 {`萌萌哒(๑•ᴗ•๑)😊`, `'萌萌哒(๑•ᴗ•๑)😊'`}, 2118 {`㍿㌍㍑㌫`, `'㍿㌍㍑㌫'`}, 2119 {string([]byte{0, 26}), `'\0\Z'`}, 2120 {nil, "NULL"}, 2121 } 2122 2123 for _, t := range tbl { 2124 fc := funcs[ast.Quote] 2125 f, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(t.arg))) 2126 c.Assert(err, IsNil) 2127 c.Assert(f, NotNil) 2128 r, err := evalBuiltinFunc(f, chunk.Event{}) 2129 c.Assert(err, IsNil) 2130 c.Assert(r, solitonutil.CausetEquals, types.NewCauset(t.ret)) 2131 } 2132 } 2133 2134 func (s *testEvaluatorSuite) TestToBase64(c *C) { 2135 tests := []struct { 2136 args interface{} 2137 expect string 2138 isNil bool 2139 getErr bool 2140 }{ 2141 {"", "", false, false}, 2142 {"abc", "YWJj", false, false}, 2143 {"ab c", "YWIgYw==", false, false}, 2144 {1, "MQ==", false, false}, 2145 {1.1, "MS4x", false, false}, 2146 {"ab\nc", "YWIKYw==", false, false}, 2147 {"ab\tc", "YWIJYw==", false, false}, 2148 {"qwerty123456", "cXdlcnR5MTIzNDU2", false, false}, 2149 { 2150 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 2151 "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrLw==", 2152 false, 2153 false, 2154 }, 2155 { 2156 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 2157 "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4\neXowMTIzNDU2Nzg5Ky9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3Bx\ncnN0dXZ3eHl6MDEyMzQ1Njc4OSsv", 2158 false, 2159 false, 2160 }, 2161 { 2162 "ABCD EFGHI\nJKLMNOPQRSTUVWXY\tZabcdefghijklmnopqrstuv wxyz012\r3456789+/", 2163 "QUJDRCAgRUZHSEkKSktMTU5PUFFSU1RVVldYWQlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1diAgd3h5\nejAxMg0zNDU2Nzg5Ky8=", 2164 false, 2165 false, 2166 }, 2167 {nil, "", true, false}, 2168 } 2169 if strconv.IntSize == 32 { 2170 tests = append(tests, struct { 2171 args interface{} 2172 expect string 2173 isNil bool 2174 getErr bool 2175 }{ 2176 strings.Repeat("a", 1589695687), 2177 "", 2178 true, 2179 false, 2180 }) 2181 } 2182 2183 for _, test := range tests { 2184 f, err := newFunctionForTest(s.ctx, ast.ToBase64, s.primitiveValsToConstants([]interface{}{test.args})...) 2185 c.Assert(err, IsNil) 2186 d, err := f.Eval(chunk.Event{}) 2187 if test.getErr { 2188 c.Assert(err, NotNil) 2189 } else { 2190 c.Assert(err, IsNil) 2191 if test.isNil { 2192 c.Assert(d.HoTT(), Equals, types.HoTTNull) 2193 } else { 2194 c.Assert(d.GetString(), Equals, test.expect) 2195 } 2196 } 2197 } 2198 2199 _, err := funcs[ast.ToBase64].getFunction(s.ctx, []Expression{NewZero()}) 2200 c.Assert(err, IsNil) 2201 } 2202 2203 func (s *testEvaluatorSuite) TestToBase64Sig(c *C) { 2204 defCausTypes := []*types.FieldType{ 2205 {Tp: allegrosql.TypeVarchar}, 2206 } 2207 2208 tests := []struct { 2209 args string 2210 expect string 2211 isNil bool 2212 maxAllowPacket uint64 2213 }{ 2214 {"abc", "YWJj", false, 4}, 2215 {"abc", "", true, 3}, 2216 { 2217 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 2218 "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrLw==", 2219 false, 2220 89, 2221 }, 2222 { 2223 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 2224 "", 2225 true, 2226 88, 2227 }, 2228 { 2229 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 2230 "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0\nNTY3ODkrL0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4\neXowMTIzNDU2Nzg5Ky9BQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3Bx\ncnN0dXZ3eHl6MDEyMzQ1Njc4OSsv", 2231 false, 2232 259, 2233 }, 2234 { 2235 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", 2236 "", 2237 true, 2238 258, 2239 }, 2240 } 2241 2242 args := []Expression{ 2243 &DeferredCauset{Index: 0, RetType: defCausTypes[0]}, 2244 } 2245 2246 for _, test := range tests { 2247 resultType := &types.FieldType{Tp: allegrosql.TypeVarchar, Flen: base64NeededEncodedLength(len(test.args))} 2248 base := baseBuiltinFunc{args: args, ctx: s.ctx, tp: resultType} 2249 toBase64 := &builtinToBase64Sig{base, test.maxAllowPacket} 2250 2251 input := chunk.NewChunkWithCapacity(defCausTypes, 1) 2252 input.AppendString(0, test.args) 2253 res, isNull, err := toBase64.evalString(input.GetEvent(0)) 2254 c.Assert(err, IsNil) 2255 if test.isNil { 2256 c.Assert(isNull, IsTrue) 2257 2258 warnings := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 2259 c.Assert(len(warnings), Equals, 1) 2260 lastWarn := warnings[len(warnings)-1] 2261 c.Assert(terror.ErrorEqual(errWarnAllowedPacketOverflowed, lastWarn.Err), IsTrue) 2262 s.ctx.GetStochastikVars().StmtCtx.SetWarnings([]stmtctx.ALLEGROSQLWarn{}) 2263 2264 } else { 2265 c.Assert(isNull, IsFalse) 2266 } 2267 c.Assert(res, Equals, test.expect) 2268 } 2269 } 2270 2271 func (s *testEvaluatorSuite) TestStringRight(c *C) { 2272 fc := funcs[ast.Right] 2273 tests := []struct { 2274 str interface{} 2275 length interface{} 2276 expect interface{} 2277 }{ 2278 {"helloworld", 5, "world"}, 2279 {"helloworld", 10, "helloworld"}, 2280 {"helloworld", 11, "helloworld"}, 2281 {"helloworld", -1, ""}, 2282 {"", 2, ""}, 2283 {nil, 2, nil}, 2284 } 2285 2286 for _, test := range tests { 2287 str := types.NewCauset(test.str) 2288 length := types.NewCauset(test.length) 2289 f, _ := fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, length})) 2290 result, err := evalBuiltinFunc(f, chunk.Event{}) 2291 c.Assert(err, IsNil) 2292 if result.IsNull() { 2293 c.Assert(test.expect, IsNil) 2294 continue 2295 } 2296 res, err := result.ToString() 2297 c.Assert(err, IsNil) 2298 c.Assert(res, Equals, test.expect) 2299 } 2300 } 2301 2302 func (s *testEvaluatorSuite) TestWeightString(c *C) { 2303 fc := funcs[ast.WeightString] 2304 tests := []struct { 2305 expr interface{} 2306 padding string 2307 length int 2308 expect interface{} 2309 }{ 2310 {nil, "NONE", 0, nil}, 2311 {7, "NONE", 0, nil}, 2312 {7.0, "NONE", 0, nil}, 2313 {"a", "NONE", 0, "a"}, 2314 {"a ", "NONE", 0, "a "}, 2315 {"中", "NONE", 0, "中"}, 2316 {"中 ", "NONE", 0, "中 "}, 2317 {nil, "CHAR", 5, nil}, 2318 {7, "CHAR", 5, nil}, 2319 {7.0, "NONE", 0, nil}, 2320 {"a", "CHAR", 5, "a "}, 2321 {"a ", "CHAR", 5, "a "}, 2322 {"中", "CHAR", 5, "中 "}, 2323 {"中 ", "CHAR", 5, "中 "}, 2324 {nil, "BINARY", 5, nil}, 2325 {7, "BINARY", 2, "7\x00"}, 2326 {7.0, "NONE", 0, nil}, 2327 {"a", "BINARY", 1, "a"}, 2328 {"ab", "BINARY", 1, "a"}, 2329 {"a", "BINARY", 5, "a\x00\x00\x00\x00"}, 2330 {"a ", "BINARY", 5, "a \x00\x00\x00"}, 2331 {"中", "BINARY", 1, "\xe4"}, 2332 {"中", "BINARY", 2, "\xe4\xb8"}, 2333 {"中", "BINARY", 3, "中"}, 2334 {"中", "BINARY", 5, "中\x00\x00"}, 2335 } 2336 2337 for _, test := range tests { 2338 str := types.NewCauset(test.expr) 2339 var f builtinFunc 2340 var err error 2341 if test.padding == "NONE" { 2342 f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str})) 2343 } else { 2344 padding := types.NewCauset(test.padding) 2345 length := types.NewCauset(test.length) 2346 f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, padding, length})) 2347 } 2348 c.Assert(err, IsNil) 2349 // Reset warnings. 2350 s.ctx.GetStochastikVars().StmtCtx.ResetForRetry() 2351 result, err := evalBuiltinFunc(f, chunk.Event{}) 2352 c.Assert(err, IsNil) 2353 if result.IsNull() { 2354 c.Assert(test.expect, IsNil) 2355 continue 2356 } 2357 res, err := result.ToString() 2358 c.Assert(err, IsNil) 2359 c.Assert(res, Equals, test.expect) 2360 if test.expr == nil { 2361 continue 2362 } 2363 strExpr := fmt.Sprintf("%v", test.expr) 2364 if test.padding == "BINARY" && test.length < len(strExpr) { 2365 expectWarn := fmt.Sprintf("[memex:1292]Truncated incorrect BINARY(%d) value: '%s'", test.length, strExpr) 2366 obtainedWarns := s.ctx.GetStochastikVars().StmtCtx.GetWarnings() 2367 c.Assert(len(obtainedWarns), Equals, 1) 2368 c.Assert(obtainedWarns[0].Level, Equals, "Warning") 2369 c.Assert(obtainedWarns[0].Err.Error(), Equals, expectWarn) 2370 } 2371 } 2372 } 2373 2374 func (s *testEvaluatorSerialSuites) TestCIWeightString(c *C) { 2375 defCauslate.SetNewDefCauslationEnabledForTest(true) 2376 defer defCauslate.SetNewDefCauslationEnabledForTest(false) 2377 2378 type weightStringTest struct { 2379 str string 2380 padding string 2381 length int 2382 expect interface{} 2383 } 2384 2385 checkResult := func(defCauslation string, tests []weightStringTest) { 2386 fc := funcs[ast.WeightString] 2387 for _, test := range tests { 2388 str := types.NewDefCauslationStringCauset(test.str, defCauslation, utf8.RuneCountInString(test.str)) 2389 var f builtinFunc 2390 var err error 2391 if test.padding == "NONE" { 2392 f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str})) 2393 } else { 2394 padding := types.NewCauset(test.padding) 2395 length := types.NewCauset(test.length) 2396 f, err = fc.getFunction(s.ctx, s.datumsToConstants([]types.Causet{str, padding, length})) 2397 } 2398 c.Assert(err, IsNil) 2399 result, err := evalBuiltinFunc(f, chunk.Event{}) 2400 c.Assert(err, IsNil) 2401 if result.IsNull() { 2402 c.Assert(test.expect, IsNil) 2403 continue 2404 } 2405 res, err := result.ToString() 2406 c.Assert(err, IsNil) 2407 c.Assert(res, Equals, test.expect) 2408 } 2409 } 2410 2411 generalTests := []weightStringTest{ 2412 {"aAÁàãăâ", "NONE", 0, "\x00A\x00A\x00A\x00A\x00A\x00A\x00A"}, 2413 {"中", "NONE", 0, "\x4E\x2D"}, 2414 {"a", "CHAR", 5, "\x00A"}, 2415 {"a ", "CHAR", 5, "\x00A"}, 2416 {"中", "CHAR", 5, "\x4E\x2D"}, 2417 {"中 ", "CHAR", 5, "\x4E\x2D"}, 2418 {"a", "BINARY", 1, "a"}, 2419 {"ab", "BINARY", 1, "a"}, 2420 {"a", "BINARY", 5, "a\x00\x00\x00\x00"}, 2421 {"a ", "BINARY", 5, "a \x00\x00\x00"}, 2422 {"中", "BINARY", 1, "\xe4"}, 2423 {"中", "BINARY", 2, "\xe4\xb8"}, 2424 {"中", "BINARY", 3, "中"}, 2425 {"中", "BINARY", 5, "中\x00\x00"}, 2426 } 2427 2428 unicodeTests := []weightStringTest{ 2429 {"aAÁàãăâ", "NONE", 0, "\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3\x0e3"}, 2430 {"中", "NONE", 0, "\xfb\x40\xce\x2d"}, 2431 {"a", "CHAR", 5, "\x0e3"}, 2432 {"a ", "CHAR", 5, "\x0e3"}, 2433 {"中", "CHAR", 5, "\xfb\x40\xce\x2d"}, 2434 {"中 ", "CHAR", 5, "\xfb\x40\xce\x2d"}, 2435 {"a", "BINARY", 1, "a"}, 2436 {"ab", "BINARY", 1, "a"}, 2437 {"a", "BINARY", 5, "a\x00\x00\x00\x00"}, 2438 {"a ", "BINARY", 5, "a \x00\x00\x00"}, 2439 {"中", "BINARY", 1, "\xe4"}, 2440 {"中", "BINARY", 2, "\xe4\xb8"}, 2441 {"中", "BINARY", 3, "中"}, 2442 {"中", "BINARY", 5, "中\x00\x00"}, 2443 } 2444 2445 checkResult("utf8mb4_general_ci", generalTests) 2446 checkResult("utf8mb4_unicode_ci", unicodeTests) 2447 }