func (b *builtinAesEncryptIVSig) vecEvalString(input *chunk.Chunk, result *chunk.Column) error {
	n := input.NumRows()
	strBuf, err := b.bufAllocator.get(types.ETString, n)
	if err != nil {
		return err
	}
	defer b.bufAllocator.put(strBuf)
	if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil {
		return err
	}
	keyBuf, err := b.bufAllocator.get(types.ETString, n)
	if err != nil {
		return err
	}
	defer b.bufAllocator.put(keyBuf)
	if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil {
		return err
	}
	ivBuf, err := b.bufAllocator.get(types.ETString, n)
	if err != nil {
		return err
	}
	defer b.bufAllocator.put(ivBuf)
	if err := b.args[2].VecEvalString(b.ctx, input, ivBuf); err != nil {
		return err
	}
	isCBC := false
	isOFB := false
	isCFB := false
	switch b.modeName {
	case "cbc":
		isCBC = true
	case "ofb":
		isOFB = true
	case "cfb":
		isCFB = true
	default:
		return errors.Errorf("unsupported block encryption mode - %v", b.modeName)
	}
	isConst := b.args[1].ConstItem(b.ctx.GetSessionVars().StmtCtx)
	var key []byte
	if isConst {
		key = encrypt.DeriveKeyMySQL(keyBuf.GetBytes(0), b.keySize)
	}
	result.ReserveString(n)
	for i := 0; i < n; i++ {
		if strBuf.IsNull(i) || keyBuf.IsNull(i) || ivBuf.IsNull(i) {
			result.AppendNull()
			continue
		}
		iv := ivBuf.GetBytes(i)
		if len(iv) < aes.BlockSize {
			return errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_encrypt is too short. Must be at least %d bytes long", aes.BlockSize)
		}
		iv = iv[0:aes.BlockSize]
		if !isConst {
			key = encrypt.DeriveKeyMySQL(keyBuf.GetBytes(i), b.keySize)
		}
		var cipherText []byte
		if isCBC {
			cipherText, err = encrypt.AESEncryptWithCBC([]byte(strBuf.GetString(i)), key, iv)
		}
		if isOFB {
			cipherText, err = encrypt.AESEncryptWithOFB([]byte(strBuf.GetString(i)), key, iv)
		}
		if isCFB {
			cipherText, err = encrypt.AESEncryptWithCFB([]byte(strBuf.GetString(i)), key, iv)
		}
		if err != nil {
			result.AppendNull()
			continue
		}
		result.AppendBytes(cipherText)
	}
	return nil
}
evalString evals AES_ENCRYPT(str, key_str, iv).
See https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_aes-decrypt
package expression
import (
	"bytes"
	"crypto/aes"
	"crypto/md5"
	"crypto/rand"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/binary"
	"fmt"
	"hash"
	"io"
	"sync"
	"github.com/pingcap/errors"
	"github.com/pingcap/parser/auth"
	"github.com/pingcap/tidb/types"
	"github.com/pingcap/tidb/util/chunk"
	"github.com/pingcap/tidb/util/encrypt"
	"github.com/pingcap/tidb/util/hack"
)
func (b *builtinAesDecryptSig) vectorized() bool {
	return true
}
func (b *builtinAesDecryptSig) vecEvalString(input *chunk.Chunk, result *chunk.Column) error {
	n := input.NumRows()
	strBuf, err := b.bufAllocator.get(types.ETString, n)
	if err != nil {
		return err
	}
	defer b.bufAllocator.put(strBuf)
	if err := b.args[0].VecEvalString(b.ctx, input, strBuf); err != nil {
		return err
	}
	keyBuf, err := b.bufAllocator.get(types.ETString, n)
	if err != nil {
		return err
	}
	defer b.bufAllocator.put(keyBuf)
	if err := b.args[1].VecEvalString(b.ctx, input, keyBuf); err != nil {
		return err
	}
	if b.modeName != "ecb" {
		return errors.Errorf("unsupported block encryption mode - %v", b.modeName)
	}
	isWarning := !b.ivRequired && len(b.args) == 3
	isConstKey := b.args[1].ConstItem(b.ctx.GetSessionVars().StmtCtx)
	var key []byte
	if isConstKey {
		key = encrypt.DeriveKeyMySQL(keyBuf.GetBytes(0), b.keySize)
	}
	result.ReserveString(n)
	stmtCtx := b.ctx.GetSessionVars().StmtCtx
	for i := 0; i < n; i++ {
		if strBuf.IsNull(i) || keyBuf.IsNull(i) {
			result.AppendNull()
			continue
		}
		if isWarning {
			stmtCtx.AppendWarning(errWarnOptionIgnored.GenWithStackByArgs("IV"))
		}
		if !isConstKey {
			key = encrypt.DeriveKeyMySQL(keyBuf.GetBytes(i), b.keySize)
		}
		str := []byte(strBuf.GetString(i))
		plainText, err := encrypt.AESDecryptWithECB(str, key)
		if err != nil {
			result.AppendNull()
			continue
		}
		result.AppendBytes(plainText)
	}
	return nil
}
func (b *builtinAesEncryptIVSig) vectorized() bool {
	return true
}