// evalString evals CONVERT(expr USING transcoding_name).
// Syntax CONVERT(expr, type) is parsed as cast expr so not handled here.
// See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html#function_convert
764193
func (b *builtinConvertSig) evalString(row chunk.Row) (string, bool, error) {
	expr, isNull, err := b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}

	// Since charset is already validated and set from getFunction(), there's no
	// need to get charset from args again.
	encoding, _ := charset.Lookup(b.tp.Charset)
	// However, if `b.tp.Charset` is abnormally set to a wrong charset, we still
	// return with error.
	if encoding == nil {
		return "", true, errUnknownCharacterSet.GenWithStackByArgs(b.tp.Charset)
	}

	target, _, err := transform.String(encoding.NewDecoder(), expr)
	return target, err != nil, err
}
245203
func (b *builtinLowerSig) evalString(row chunk.Row) (d string, isNull bool, err error) {
	d, isNull, err = b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}

	if types.IsBinaryStr(b.args[0].GetType()) {
		return d, false, nil
	}

	return strings.ToLower(d), false, nil
}
476448
func (b *builtinPasswordSig) evalString(row chunk.Row) (d string, isNull bool, err error) {
	pass, isNull, err := b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", err != nil, err
	}

	if len(pass) == 0 {
		return "", false, nil
	}

	// We should append a warning here because function "PASSWORD" is deprecated since MySQL 5.7.6.
	// See https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_password
	b.ctx.GetSessionVars().StmtCtx.AppendWarning(errDeprecatedSyntaxNoReplacement.GenWithStackByArgs("PASSWORD"))

	return auth.EncodePassword(pass), false, nil
}
224301
func ConvertString(input string, fromEncoding string, toEncoding string) (output string, err error) {
	// create a temporary converter
	converter, err := NewConverter(fromEncoding, toEncoding)

	if err == nil {
		// convert the string
		output, err = converter.ConvertString(input)

		// close the converter
		converter.Close()
	}

	return
}
912650
func Eval(expr string) (result *big.Rat, err error) {
	defer func() {
		if e := recover(); e != nil {
			result = nil
			err = fmt.Errorf("Invalid Expression: %s", expr)
		}
	}()

	tokens := Tokenise(expr)
	postfix := convert2postfix(tokens)
	return evaluatePostfix(postfix)
}
977264
func (b *builtinMD5Sig) evalString(row chunk.Row) (string, bool, error) {
	arg, isNull, err := b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", isNull, err
	}
	sum := md5.Sum([]byte(arg))
	hexStr := fmt.Sprintf("%x", sum)
	return hexStr, false, nil
}
382434
func (b *builtinFormatWithLocaleSig) evalString(row chunk.Row) (string, bool, error) {
	x, d, isNull, err := evalNumDecArgsForFormat(b, row)
	if isNull || err != nil {
		return "", isNull, err
	}
	locale, isNull, err := b.args[2].EvalString(b.ctx, row)
	if err != nil {
		return "", false, err
	}
	if isNull {
		b.ctx.GetSessionVars().StmtCtx.AppendWarning(errUnknownLocale.GenWithStackByArgs("NULL"))
		locale = "en_US"
	}
	formatString, err := mysql.GetLocaleFormatFunction(locale)(x, d)
	return formatString, false, err
}
837313
func (b *builtinLTrimSig) evalString(row chunk.Row) (d string, isNull bool, err error) {
	d, isNull, err = b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	return strings.TrimLeft(d, spaceChars), false, nil
}
740578
func (b *builtinQuoteSig) evalString(row chunk.Row) (string, bool, error) {
	str, isNull, err := b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}

	runes := []rune(str)
	buffer := bytes.NewBufferString("")
	buffer.WriteRune('\'')
	for i, runeLength := 0, len(runes); i < runeLength; i++ {
		switch runes[i] {
		case '\\', '\'':
			buffer.WriteRune('\\')
			buffer.WriteRune(runes[i])
		case 0:
			buffer.WriteRune('\\')
			buffer.WriteRune('0')
		case '\032':
			buffer.WriteRune('\\')
			buffer.WriteRune('Z')
		default:
			buffer.WriteRune(runes[i])
		}
	}
	buffer.WriteRune('\'')

	return buffer.String(), false, nil
}
1302072
func (b *builtinTiDBVersionSig) evalString(_ chunk.Row) (string, bool, error) {
	return printer.GetTiDBInfo(), false, nil
}
1059584
func (b *builtinSpaceSig) evalString(row chunk.Row) (d string, isNull bool, err error) {
	var x int64

	x, isNull, err = b.args[0].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	if x < 0 {
		x = 0
	}
	if uint64(x) > b.maxAllowedPacket {
		b.ctx.GetSessionVars().StmtCtx.AppendWarning(errWarnAllowedPacketOverflowed.GenWithStackByArgs("space", b.maxAllowedPacket))
		return d, true, nil
	}
	if x > mysql.MaxBlobWidth {
		return d, true, nil
	}
	return strings.Repeat(" ", int(x)), false, nil
}
844418
func (this *Converter) ConvertString(input string) (output string, err error) {
	// make sure we are still open
	if this.open {
		// construct the buffers
		inputBuffer := []byte(input)
		outputBuffer := make([]byte, len(inputBuffer)*2) // we use a larger buffer to help avoid resizing later

		// call Convert until all input bytes are read or an error occurs
		var bytesRead, totalBytesRead, bytesWritten, totalBytesWritten int

		for totalBytesRead < len(inputBuffer) && err == nil {
			// use the totals to create buffer slices
			bytesRead, bytesWritten, err = this.Convert(inputBuffer[totalBytesRead:], outputBuffer[totalBytesWritten:])

			totalBytesRead += bytesRead
			totalBytesWritten += bytesWritten

			// check for the E2BIG error specifically, we can add to the output
			// buffer to correct for it and then continue
			if err == syscall.E2BIG {
				// increase the size of the output buffer by another input length
				// first, create a new buffer
				tempBuffer := make([]byte, len(outputBuffer)+len(inputBuffer))

				// copy the existing data
				copy(tempBuffer, outputBuffer)

				// switch the buffers
				outputBuffer = tempBuffer

				// forget the error
				err = nil
			}
		}

		if err == nil {
			// perform a final shift state reset
			_, bytesWritten, err = this.Convert([]byte{}, outputBuffer[totalBytesWritten:])

			// update total count
			totalBytesWritten += bytesWritten
		}

		// construct the final output string
		output = string(outputBuffer[:totalBytesWritten])
	} else {
		err = syscall.EBADF
	}

	return output, err
}
1188355
func (b *builtinTrim3ArgsSig) evalString(row chunk.Row) (d string, isNull bool, err error) {
	var (
		str, remstr  string
		x            int64
		direction    ast.TrimDirectionType
		isRemStrNull bool
	)
	str, isNull, err = b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	remstr, isRemStrNull, err = b.args[1].EvalString(b.ctx, row)
	if err != nil {
		return d, isNull, err
	}
	x, isNull, err = b.args[2].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	direction = ast.TrimDirectionType(x)
	if direction == ast.TrimLeading {
		if isRemStrNull {
			d = strings.TrimLeft(str, spaceChars)
		} else {
			d = trimLeft(str, remstr)
		}
	} else if direction == ast.TrimTrailing {
		if isRemStrNull {
			d = strings.TrimRight(str, spaceChars)
		} else {
			d = trimRight(str, remstr)
		}
	} else {
		if isRemStrNull {
			d = strings.Trim(str, spaceChars)
		} else {
			d = trimLeft(str, remstr)
			d = trimRight(d, remstr)
		}
	}
	return d, false, nil
}
220234
func (b *builtinAesDecryptIVSig) evalString(row chunk.Row) (string, bool, error) {
	// According to doc: If either function argument is NULL, the function returns NULL.
	cryptStr, isNull, err := b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}

	keyStr, isNull, err := b.args[1].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}

	iv, isNull, err := b.args[2].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}
	if len(iv) < aes.BlockSize {
		return "", true, errIncorrectArgs.GenWithStack("The initialization vector supplied to aes_decrypt is too short. Must be at least %d bytes long", aes.BlockSize)
	}
	// init_vector must be 16 bytes or longer (bytes in excess of 16 are ignored)
	iv = iv[0:aes.BlockSize]

	key := encrypt.DeriveKeyMySQL([]byte(keyStr), b.keySize)
	var plainText []byte
	switch b.modeName {
	case "cbc":
		plainText, err = encrypt.AESDecryptWithCBC([]byte(cryptStr), key, []byte(iv))
	case "ofb":
		plainText, err = encrypt.AESDecryptWithOFB([]byte(cryptStr), key, []byte(iv))
	case "cfb":
		plainText, err = encrypt.AESDecryptWithCFB([]byte(cryptStr), key, []byte(iv))
	default:
		return "", true, errors.Errorf("unsupported block encryption mode - %v", b.modeName)
	}
	if err != nil {
		return "", true, nil
	}
	return string(plainText), false, nil
}
746484
func (b *builtinUUIDSig) evalString(_ chunk.Row) (d string, isNull bool, err error) {
	return uuid.NewV1().String(), false, nil
}
913478
func (b *builtinSubstringIndexSig) evalString(row chunk.Row) (d string, isNull bool, err error) {
	var (
		str, delim string
		count      int64
	)
	str, isNull, err = b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	delim, isNull, err = b.args[1].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	count, isNull, err = b.args[2].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	if len(delim) == 0 {
		return "", false, nil
	}

	strs := strings.Split(str, delim)
	start, end := int64(0), int64(len(strs))
	if count > 0 {
		// If count is positive, everything to the left of the final delimiter (counting from the left) is returned.
		if count < end {
			end = count
		}
	} else {
		// If count is negative, everything to the right of the final delimiter (counting from the right) is returned.
		count = -count
		if count < 0 {
			// -count overflows max int64, returns an empty string.
			return "", false, nil
		}

		if count < end {
			start = end - count
		}
	}
	substrs := strs[start:end]
	return strings.Join(substrs, delim), false, nil
}
748356
func (b *builtinSubDateAndDurationSig) evalString(row chunk.Row) (string, bool, error) {
	arg0, isNull, err := b.args[0].EvalDuration(b.ctx, row)
	if isNull || err != nil {
		return "", isNull, err
	}
	arg1, isNull, err := b.args[1].EvalDuration(b.ctx, row)
	if isNull || err != nil {
		return "", isNull, err
	}
	result, err := arg0.Sub(arg1)
	return result.String(), err != nil, err
}