github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_encryption_vec.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 "bytes" 18 "crypto/aes" 19 "crypto/md5" 20 "crypto/rand" 21 "crypto/sha1" 22 "crypto/sha256" 23 "crypto/sha512" 24 "encoding/binary" 25 "fmt" 26 "hash" 27 "io" 28 "sync" 29 30 "github.com/whtcorpsinc/errors" 31 "github.com/whtcorpsinc/BerolinaSQL/auth" 32 "github.com/whtcorpsinc/milevadb/types" 33 "github.com/whtcorpsinc/milevadb/soliton/chunk" 34 "github.com/whtcorpsinc/milevadb/soliton/encrypt" 35 "github.com/whtcorpsinc/milevadb/soliton/replog" 36 ) 37 38 func (b *builtinAesDecryptSig) vectorized() bool { 39 return true 40 } 41 42 func (b *builtinAesDecryptSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 43 n := input.NumEvents() 44 strBuf, err := b.bufSlabPredictor.get(types.ETString, n) 45 if err != nil { 46 return err 47 } 48 defer b.bufSlabPredictor.put(strBuf) 49 if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil { 50 return err 51 } 52 53 keyBuf, err := b.bufSlabPredictor.get(types.ETString, n) 54 if err != nil { 55 return err 56 } 57 defer b.bufSlabPredictor.put(keyBuf) 58 if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil { 59 return err 60 } 61 62 if b.modeName != "ecb" { 63 return errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 64 } 65 66 isWarning := !b.ivRequired && len(b.args) == 3 67 isConstKey := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx) 68 69 var key []byte 70 if isConstKey { 71 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize) 72 } 73 74 result.ReserveString(n) 75 stmtCtx := b.ctx.GetStochastikVars().StmtCtx 76 for i := 0; i < n; i++ { 77 // According to doc: If either function argument is NULL, the function returns NULL. 78 if strBuf.IsNull(i) || keyBuf.IsNull(i) { 79 result.AppendNull() 80 continue 81 } 82 if isWarning { 83 // For modes that do not require init_vector, it is ignored and a warning is generated if it is specified. 84 stmtCtx.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV")) 85 } 86 if !isConstKey { 87 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize) 88 } 89 // ANNOTATION: 90 // we can't use GetBytes here because GetBytes return raw memory in strBuf, 91 // and the memory will be modified in AESEncryptWithECB & AESDecryptWithECB 92 str := []byte(strBuf.GetString(i)) 93 plainText, err := encrypt.AESDecryptWithECB(str, key) 94 if err != nil { 95 result.AppendNull() 96 continue 97 } 98 result.AppendBytes(plainText) 99 } 100 101 return nil 102 } 103 104 func (b *builtinAesEncryptIVSig) vectorized() bool { 105 return true 106 } 107 108 // evalString evals AES_ENCRYPT(str, key_str, iv). 109 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt 110 func (b *builtinAesEncryptIVSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 111 n := input.NumEvents() 112 strBuf, err := b.bufSlabPredictor.get(types.ETString, n) 113 if err != nil { 114 return err 115 } 116 defer b.bufSlabPredictor.put(strBuf) 117 if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil { 118 return err 119 } 120 121 keyBuf, err := b.bufSlabPredictor.get(types.ETString, n) 122 if err != nil { 123 return err 124 } 125 defer b.bufSlabPredictor.put(keyBuf) 126 if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil { 127 return err 128 } 129 130 ivBuf, err := b.bufSlabPredictor.get(types.ETString, n) 131 if err != nil { 132 return err 133 } 134 defer b.bufSlabPredictor.put(ivBuf) 135 if err := b.args[2].VecEvalString(b.ctx, input, ivBuf); err != nil { 136 return err 137 } 138 139 isCBC := false 140 isOFB := false 141 isCFB := false 142 switch b.modeName { 143 case "cbc": 144 isCBC = true 145 case "ofb": 146 isOFB = true 147 case "cfb": 148 isCFB = true 149 default: 150 return errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 151 } 152 153 isConst := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx) 154 var key []byte 155 if isConst { 156 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize) 157 } 158 159 result.ReserveString(n) 160 for i := 0; i < n; i++ { 161 // According to doc: If either function argument is NULL, the function returns NULL. 162 if strBuf.IsNull(i) || keyBuf.IsNull(i) || ivBuf.IsNull(i) { 163 result.AppendNull() 164 continue 165 } 166 167 iv := ivBuf.GetBytes(i) 168 if len(iv) < aes.BlockSize { 169 return errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_encrypt is too short. Must be at least %d bytes long", aes.BlockSize) 170 } 171 // init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored) 172 iv = iv[0:aes.BlockSize] 173 if !isConst { 174 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize) 175 } 176 var cipherText []byte 177 178 // ANNOTATION: 179 // we can't use GetBytes here because GetBytes return raw memory in strBuf, 180 // and the memory will be modified in AESEncryptWithCBC & AESEncryptWithOFB & AESEncryptWithCFB 181 if isCBC { 182 cipherText, err = encrypt.AESEncryptWithCBC([]byte(strBuf.GetString(i)), key, iv) 183 } 184 if isOFB { 185 cipherText, err = encrypt.AESEncryptWithOFB([]byte(strBuf.GetString(i)), key, iv) 186 } 187 if isCFB { 188 cipherText, err = encrypt.AESEncryptWithCFB([]byte(strBuf.GetString(i)), key, iv) 189 } 190 if err != nil { 191 result.AppendNull() 192 continue 193 } 194 result.AppendBytes(cipherText) 195 } 196 return nil 197 } 198 199 func (b *builtinDecodeSig) vectorized() bool { 200 return true 201 } 202 203 func (b *builtinDecodeSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 204 n := input.NumEvents() 205 buf, err := b.bufSlabPredictor.get(types.ETString, n) 206 if err != nil { 207 return err 208 } 209 defer b.bufSlabPredictor.put(buf) 210 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 211 return err 212 } 213 buf1, err1 := b.bufSlabPredictor.get(types.ETString, n) 214 if err1 != nil { 215 return err1 216 } 217 defer b.bufSlabPredictor.put(buf1) 218 if err := b.args[1].VecEvalString(b.ctx, input, buf1); err != nil { 219 return err 220 } 221 result.ReserveString(n) 222 for i := 0; i < n; i++ { 223 if buf.IsNull(i) || buf1.IsNull(i) { 224 result.AppendNull() 225 continue 226 } 227 dataStr := buf.GetString(i) 228 passwordStr := buf1.GetString(i) 229 decodeStr, err := encrypt.ALLEGROSQLDecode(dataStr, passwordStr) 230 if err != nil { 231 return err 232 } 233 result.AppendString(decodeStr) 234 } 235 return nil 236 } 237 238 func (b *builtinEncodeSig) vectorized() bool { 239 return true 240 } 241 242 func (b *builtinEncodeSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 243 n := input.NumEvents() 244 buf, err := b.bufSlabPredictor.get(types.ETString, n) 245 if err != nil { 246 return err 247 } 248 defer b.bufSlabPredictor.put(buf) 249 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 250 return err 251 } 252 buf1, err1 := b.bufSlabPredictor.get(types.ETString, n) 253 if err1 != nil { 254 return err1 255 } 256 defer b.bufSlabPredictor.put(buf1) 257 if err := b.args[1].VecEvalString(b.ctx, input, buf1); err != nil { 258 return err 259 } 260 result.ReserveString(n) 261 for i := 0; i < n; i++ { 262 if buf.IsNull(i) || buf1.IsNull(i) { 263 result.AppendNull() 264 continue 265 } 266 decodeStr := buf.GetString(i) 267 passwordStr := buf1.GetString(i) 268 dataStr, err := encrypt.ALLEGROSQLEncode(decodeStr, passwordStr) 269 if err != nil { 270 return err 271 } 272 result.AppendString(dataStr) 273 } 274 return nil 275 } 276 277 func (b *builtinAesDecryptIVSig) vectorized() bool { 278 return true 279 } 280 281 // evalString evals AES_DECRYPT(crypt_str, key_key, iv). 282 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt 283 func (b *builtinAesDecryptIVSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 284 n := input.NumEvents() 285 strBuf, err := b.bufSlabPredictor.get(types.ETString, n) 286 if err != nil { 287 return err 288 } 289 defer b.bufSlabPredictor.put(strBuf) 290 if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil { 291 return err 292 } 293 294 keyBuf, err := b.bufSlabPredictor.get(types.ETString, n) 295 if err != nil { 296 return err 297 } 298 defer b.bufSlabPredictor.put(keyBuf) 299 if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil { 300 return err 301 } 302 303 ivBuf, err := b.bufSlabPredictor.get(types.ETString, n) 304 if err != nil { 305 return err 306 } 307 defer b.bufSlabPredictor.put(ivBuf) 308 if err := b.args[2].VecEvalString(b.ctx, input, ivBuf); err != nil { 309 return err 310 } 311 312 isCBC := false 313 isOFB := false 314 isCFB := false 315 switch b.modeName { 316 case "cbc": 317 isCBC = true 318 case "ofb": 319 isOFB = true 320 case "cfb": 321 isCFB = true 322 default: 323 return errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 324 } 325 326 isConst := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx) 327 var key []byte 328 if isConst { 329 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize) 330 } 331 332 result.ReserveString(n) 333 for i := 0; i < n; i++ { 334 // According to doc: If either function argument is NULL, the function returns NULL. 335 if strBuf.IsNull(i) || keyBuf.IsNull(i) || ivBuf.IsNull(i) { 336 result.AppendNull() 337 continue 338 } 339 340 iv := ivBuf.GetBytes(i) 341 if len(iv) < aes.BlockSize { 342 return errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_decrypt is too short. Must be at least %d bytes long", aes.BlockSize) 343 } 344 // init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored) 345 iv = iv[0:aes.BlockSize] 346 if !isConst { 347 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize) 348 } 349 var plainText []byte 350 351 // ANNOTATION: 352 // we can't use GetBytes here because GetBytes return raw memory in strBuf, 353 // and the memory will be modified in AESDecryptWithCBC & AESDecryptWithOFB & AESDecryptWithCFB 354 if isCBC { 355 plainText, err = encrypt.AESDecryptWithCBC([]byte(strBuf.GetString(i)), key, iv) 356 } 357 if isOFB { 358 plainText, err = encrypt.AESDecryptWithOFB([]byte(strBuf.GetString(i)), key, iv) 359 } 360 if isCFB { 361 plainText, err = encrypt.AESDecryptWithCFB([]byte(strBuf.GetString(i)), key, iv) 362 } 363 if err != nil { 364 result.AppendNull() 365 continue 366 } 367 result.AppendBytes(plainText) 368 } 369 return nil 370 } 371 372 func (b *builtinRandomBytesSig) vectorized() bool { 373 return true 374 } 375 376 func (b *builtinRandomBytesSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 377 n := input.NumEvents() 378 buf, err := b.bufSlabPredictor.get(types.ETInt, n) 379 if err != nil { 380 return err 381 } 382 defer b.bufSlabPredictor.put(buf) 383 if err := b.args[0].VecEvalInt(b.ctx, input, buf); err != nil { 384 return err 385 } 386 result.ReserveString(n) 387 i64s := buf.Int64s() 388 var dst bytes.Buffer 389 for i := 0; i < n; i++ { 390 if buf.IsNull(i) { 391 result.AppendNull() 392 continue 393 } 394 byteLen := i64s[i] 395 if byteLen < 1 || byteLen > 1024 { 396 return types.ErrOverflow.GenWithStackByArgs("length", "random_bytes") 397 } 398 if n, err := io.CopyN(&dst, rand.Reader, byteLen); err != nil { 399 return err 400 } else if n != byteLen { 401 return errors.New("fail to generate random bytes") 402 } 403 result.AppendBytes(dst.Bytes()) 404 dst.Reset() 405 } 406 return nil 407 } 408 409 func (b *builtinMD5Sig) vectorized() bool { 410 return true 411 } 412 413 func (b *builtinMD5Sig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 414 n := input.NumEvents() 415 buf, err := b.bufSlabPredictor.get(types.ETString, n) 416 if err != nil { 417 return err 418 } 419 defer b.bufSlabPredictor.put(buf) 420 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 421 return err 422 } 423 result.ReserveString(n) 424 digest := md5.New() 425 for i := 0; i < n; i++ { 426 if buf.IsNull(i) { 427 result.AppendNull() 428 continue 429 } 430 cryptByte := buf.GetBytes(i) 431 _, err := digest.Write(cryptByte) 432 if err != nil { 433 return err 434 } 435 result.AppendString(fmt.Sprintf("%x", digest.Sum(nil))) 436 digest.Reset() 437 } 438 return nil 439 } 440 441 func (b *builtinSHA2Sig) vectorized() bool { 442 return true 443 } 444 445 // vecEvalString evals SHA2(str, hash_length). 446 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_sha2 447 func (b *builtinSHA2Sig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 448 n := input.NumEvents() 449 buf, err := b.bufSlabPredictor.get(types.ETString, n) 450 if err != nil { 451 return err 452 } 453 defer b.bufSlabPredictor.put(buf) 454 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 455 return err 456 } 457 buf1, err := b.bufSlabPredictor.get(types.ETInt, n) 458 if err != nil { 459 return err 460 } 461 defer b.bufSlabPredictor.put(buf1) 462 if err := b.args[1].VecEvalInt(b.ctx, input, buf1); err != nil { 463 return err 464 } 465 result.ReserveString(n) 466 i64s := buf1.Int64s() 467 var ( 468 hasher224 hash.Hash 469 hasher256 hash.Hash 470 hasher384 hash.Hash 471 hasher512 hash.Hash 472 ) 473 for i := 0; i < n; i++ { 474 if buf.IsNull(i) || buf1.IsNull(i) { 475 result.AppendNull() 476 continue 477 } 478 hashLength := i64s[i] 479 var hasher hash.Hash 480 switch int(hashLength) { 481 case SHA0, SHA256: 482 if hasher256 == nil { 483 hasher256 = sha256.New() 484 } 485 hasher = hasher256 486 case SHA224: 487 if hasher224 == nil { 488 hasher224 = sha256.New224() 489 } 490 hasher = hasher224 491 case SHA384: 492 if hasher384 == nil { 493 hasher384 = sha512.New384() 494 } 495 hasher = hasher384 496 case SHA512: 497 if hasher512 == nil { 498 hasher512 = sha512.New() 499 } 500 hasher = hasher512 501 } 502 if hasher == nil { 503 result.AppendNull() 504 continue 505 } 506 507 str := buf.GetBytes(i) 508 _, err = hasher.Write(str) 509 if err != nil { 510 return err 511 } 512 result.AppendString(fmt.Sprintf("%x", hasher.Sum(nil))) 513 hasher.Reset() 514 } 515 return nil 516 } 517 518 func (b *builtinCompressSig) vectorized() bool { 519 return true 520 } 521 522 var ( 523 defaultByteSliceSize = 1024 524 bytePool = sync.Pool{ 525 New: func() interface{} { 526 return make([]byte, defaultByteSliceSize) 527 }, 528 } 529 ) 530 531 func allocByteSlice(n int) []byte { 532 if n > defaultByteSliceSize { 533 return make([]byte, n) 534 } 535 return bytePool.Get().([]byte) 536 } 537 538 func deallocateByteSlice(b []byte) { 539 if cap(b) <= defaultByteSliceSize { 540 bytePool.Put(b) 541 } 542 } 543 544 // evalString evals COMPRESS(str). 545 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_compress 546 func (b *builtinCompressSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 547 n := input.NumEvents() 548 buf, err := b.bufSlabPredictor.get(types.ETString, n) 549 if err != nil { 550 return err 551 } 552 defer b.bufSlabPredictor.put(buf) 553 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 554 return err 555 } 556 557 result.ReserveString(n) 558 for i := 0; i < n; i++ { 559 if buf.IsNull(i) { 560 result.AppendNull() 561 continue 562 } 563 564 str := buf.GetString(i) 565 566 // According to doc: Empty strings are stored as empty strings. 567 if len(str) == 0 { 568 result.AppendString("") 569 } 570 571 compressed, err := deflate(replog.Slice(str)) 572 if err != nil { 573 result.AppendNull() 574 continue 575 } 576 577 resultLength := 4 + len(compressed) 578 579 // append "." if ends with space 580 shouldAppendSuffix := compressed[len(compressed)-1] == 32 581 if shouldAppendSuffix { 582 resultLength++ 583 } 584 585 buffer := allocByteSlice(resultLength) 586 defer deallocateByteSlice(buffer) 587 buffer = buffer[:resultLength] 588 589 binary.LittleEndian.PutUint32(buffer, uint32(len(str))) 590 copy(buffer[4:], compressed) 591 592 if shouldAppendSuffix { 593 buffer[len(buffer)-1] = '.' 594 } 595 596 result.AppendBytes(buffer) 597 } 598 return nil 599 } 600 601 func (b *builtinAesEncryptSig) vectorized() bool { 602 return true 603 } 604 605 // evalString evals AES_ENCRYPT(str, key_str). 606 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt 607 func (b *builtinAesEncryptSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 608 n := input.NumEvents() 609 strBuf, err := b.bufSlabPredictor.get(types.ETString, n) 610 if err != nil { 611 return err 612 } 613 defer b.bufSlabPredictor.put(strBuf) 614 if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil { 615 return err 616 } 617 618 keyBuf, err := b.bufSlabPredictor.get(types.ETString, n) 619 if err != nil { 620 return err 621 } 622 defer b.bufSlabPredictor.put(keyBuf) 623 if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil { 624 return err 625 } 626 627 if b.modeName != "ecb" { 628 // For modes that do not require init_vector, it is ignored and a warning is generated if it is specified. 629 return errors.Errorf("unsupported causet encryption mode - %v", b.modeName) 630 } 631 632 isWarning := !b.ivRequired && len(b.args) == 3 633 isConst := b.args[1].ConstItem(b.ctx.GetStochastikVars().StmtCtx) 634 var key []byte 635 if isConst { 636 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(0), b.keySize) 637 } 638 639 sc := b.ctx.GetStochastikVars().StmtCtx 640 result.ReserveString(n) 641 for i := 0; i < n; i++ { 642 // According to doc: If either function argument is NULL, the function returns NULL. 643 if strBuf.IsNull(i) || keyBuf.IsNull(i) { 644 result.AppendNull() 645 continue 646 } 647 if isWarning { 648 sc.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV")) 649 } 650 if !isConst { 651 key = encrypt.DeriveKeyMyALLEGROSQL(keyBuf.GetBytes(i), b.keySize) 652 } 653 654 // NOTE: we can't use GetBytes, because in AESEncryptWithECB padding is automatically 655 // added to str and this will damange the data layout in chunk.DeferredCauset 656 str := []byte(strBuf.GetString(i)) 657 cipherText, err := encrypt.AESEncryptWithECB(str, key) 658 if err != nil { 659 result.AppendNull() 660 continue 661 } 662 result.AppendBytes(cipherText) 663 } 664 665 return nil 666 } 667 668 func (b *builtinPasswordSig) vectorized() bool { 669 return true 670 } 671 672 func (b *builtinPasswordSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 673 n := input.NumEvents() 674 buf, err := b.bufSlabPredictor.get(types.ETString, n) 675 if err != nil { 676 return err 677 } 678 defer b.bufSlabPredictor.put(buf) 679 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 680 return err 681 } 682 result.ReserveString(n) 683 for i := 0; i < n; i++ { 684 if buf.IsNull(i) { 685 result.AppendString("") 686 continue 687 } 688 pass := buf.GetString(i) 689 if len(pass) == 0 { 690 result.AppendString("") 691 continue 692 } 693 // We should append a warning here because function "PASSWORD" is deprecated since MyALLEGROSQL 5.7.6. 694 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_password 695 b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errDeprecatedSyntaxNoRememristed.GenWithStackByArgs("PASSWORD")) 696 697 result.AppendString(auth.EncodePassword(pass)) 698 } 699 return nil 700 } 701 702 func (b *builtinSHA1Sig) vectorized() bool { 703 return true 704 } 705 706 func (b *builtinSHA1Sig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 707 n := input.NumEvents() 708 buf, err := b.bufSlabPredictor.get(types.ETString, n) 709 if err != nil { 710 return err 711 } 712 defer b.bufSlabPredictor.put(buf) 713 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 714 return err 715 } 716 result.ReserveString(n) 717 hasher := sha1.New() 718 for i := 0; i < n; i++ { 719 if buf.IsNull(i) { 720 result.AppendNull() 721 continue 722 } 723 str := buf.GetBytes(i) 724 _, err = hasher.Write(str) 725 if err != nil { 726 return err 727 } 728 result.AppendString(fmt.Sprintf("%x", hasher.Sum(nil))) 729 hasher.Reset() 730 } 731 return nil 732 } 733 734 func (b *builtinUncompressSig) vectorized() bool { 735 return true 736 } 737 738 // evalString evals UNCOMPRESS(compressed_string). 739 // See https://dev.allegrosql.com/doc/refman/5.7/en/encryption-functions.html#function_uncompress 740 func (b *builtinUncompressSig) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 741 n := input.NumEvents() 742 buf, err := b.bufSlabPredictor.get(types.ETString, n) 743 if err != nil { 744 return err 745 } 746 defer b.bufSlabPredictor.put(buf) 747 if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { 748 return err 749 } 750 751 result.ReserveString(n) 752 sc := b.ctx.GetStochastikVars().StmtCtx 753 for i := 0; i < n; i++ { 754 if buf.IsNull(i) { 755 result.AppendNull() 756 continue 757 } 758 759 payload := buf.GetString(i) 760 761 if len(payload) == 0 { 762 result.AppendString("") 763 continue 764 } 765 if len(payload) <= 4 { 766 // corrupted 767 sc.AppendWarning(errZlibZData) 768 result.AppendNull() 769 continue 770 } 771 length := binary.LittleEndian.Uint32([]byte(payload[0:4])) 772 bytes, err := inflate([]byte(payload[4:])) 773 if err != nil { 774 sc.AppendWarning(errZlibZData) 775 result.AppendNull() 776 continue 777 } 778 if length < uint32(len(bytes)) { 779 sc.AppendWarning(errZlibZBuf) 780 result.AppendNull() 781 continue 782 } 783 784 result.AppendBytes(bytes) 785 } 786 787 return nil 788 } 789 790 func (b *builtinUncompressedLengthSig) vectorized() bool { 791 return true 792 } 793 794 func (b *builtinUncompressedLengthSig) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 795 sc := b.ctx.GetStochastikVars().StmtCtx 796 nr := input.NumEvents() 797 payloadBuf, err := b.bufSlabPredictor.get(types.ETString, nr) 798 if err != nil { 799 return err 800 } 801 defer b.bufSlabPredictor.put(payloadBuf) 802 if err := b.args[0].VecEvalString(b.ctx, input, payloadBuf); err != nil { 803 return err 804 } 805 806 result.ResizeInt64(nr, false) 807 result.MergeNulls(payloadBuf) 808 i64s := result.Int64s() 809 for i := 0; i < nr; i++ { 810 if result.IsNull(i) { 811 continue 812 } 813 str := payloadBuf.GetString(i) 814 if len(str) == 0 { 815 i64s[i] = 0 816 continue 817 } 818 if len(str) <= 4 { 819 sc.AppendWarning(errZlibZData) 820 i64s[i] = 0 821 continue 822 } 823 i64s[i] = int64(binary.LittleEndian.Uint32([]byte(str)[0:4])) 824 } 825 return nil 826 }