// evalString evals a builtinLeastTimeSig.
// See http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#functionleast
173676
func (b *builtinLeastTimeSig) evalString(row chunk.Row) (res string, isNull bool, err error) {
	var (
		v string
		t types.Time
	)
	min := types.Time{
		Time: types.MaxDatetime,
		Type: mysql.TypeDatetime,
		Fsp:  types.MaxFsp,
	}
	findInvalidTime := false
	sc := b.ctx.GetSessionVars().StmtCtx
	for i := 0; i < len(b.args); i++ {
		v, isNull, err = b.args[i].EvalString(b.ctx, row)
		if isNull || err != nil {
			return "", true, err
		}
		t, err = types.ParseDatetime(sc, v)
		if err != nil {
			if err = handleInvalidTimeError(b.ctx, err); err != nil {
				return v, true, err
			} else if !findInvalidTime {
				res = v
				findInvalidTime = true
			}
		}
		if t.Compare(min) < 0 {
			min = t
		}
	}
	if !findInvalidTime {
		res = min.String()
	}
	return res, false, nil
}
431104
func ValidateString(input string) (bool, error) {
	_, err := time.ParseDuration(input)
	if err != nil {
		return false, err
	}

	return true, nil
}
1030820
func (b *builtinCharSig) evalString(row chunk.Row) (string, bool, error) {
	bigints := make([]int64, 0, len(b.args)-1)

	for i := 0; i < len(b.args)-1; i++ {
		val, IsNull, err := b.args[i].EvalInt(b.ctx, row)
		if err != nil {
			return "", true, err
		}
		if IsNull {
			continue
		}
		bigints = append(bigints, val)
	}
	// The last argument represents the charset name after "using".
	// Use default charset utf8 if it is nil.
	argCharset, IsNull, err := b.args[len(b.args)-1].EvalString(b.ctx, row)
	if err != nil {
		return "", true, err
	}

	result := string(b.convertToBytes(bigints))
	charsetLabel := strings.ToLower(argCharset)
	if IsNull || charsetLabel == "ascii" || strings.HasPrefix(charsetLabel, "utf8") {
		return result, false, nil
	}

	encoding, charsetName := charset.Lookup(charsetLabel)
	if encoding == nil {
		return "", true, errors.Errorf("unknown encoding: %s", argCharset)
	}

	oldStr := result
	result, _, err = transform.String(encoding.NewDecoder(), result)
	if err != nil {
		logutil.Logger(context.Background()).Warn("change charset of string",
			zap.String("string", oldStr),
			zap.String("charset", charsetName),
			zap.Error(err))
		return "", true, err
	}
	return result, false, nil
}
735877
func (b *builtinFromBase64Sig) evalString(row chunk.Row) (string, bool, error) {
	str, isNull, err := b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}

	needDecodeLen := base64NeededDecodedLength(len(str))
	if needDecodeLen == -1 {
		return "", true, nil
	}
	if needDecodeLen > int(b.maxAllowedPacket) {
		b.ctx.GetSessionVars().StmtCtx.AppendWarning(errWarnAllowedPacketOverflowed.GenWithStackByArgs("from_base64", b.maxAllowedPacket))
		return "", true, nil
	}

	str = strings.Replace(str, "\t", "", -1)
	str = strings.Replace(str, " ", "", -1)
	result, err := base64.StdEncoding.DecodeString(str)
	if err != nil {
		// When error happens, take `from_base64("asc")` as an example, we should return NULL.
		return "", true, nil
	}
	return string(result), false, nil
}
111202
func (b *builtinInet6NtoaSig) evalString(row chunk.Row) (string, bool, error) {
	val, isNull, err := b.args[0].EvalString(b.ctx, row)
	if err != nil || isNull {
		return "", true, err
	}
	ip := net.IP([]byte(val)).String()
	if len(val) == net.IPv6len && !strings.Contains(ip, ":") {
		ip = fmt.Sprintf("::ffff:%s", ip)
	}

	if net.ParseIP(ip) == nil {
		return "", true, nil
	}

	return ip, false, nil
}
444866
func (b *builtinCaseWhenTimeSig) evalTime(row chunk.Row) (ret types.Time, isNull bool, err error) {
	var condition int64
	args, l := b.getArgs(), len(b.getArgs())
	for i := 0; i < l-1; i += 2 {
		condition, isNull, err = args[i].EvalInt(b.ctx, row)
		if err != nil {
			return ret, isNull, err
		}
		if isNull || condition == 0 {
			continue
		}
		ret, isNull, err = args[i+1].EvalTime(b.ctx, row)
		return ret, isNull, err
	}
	// when clause(condition, result) -> args[i], args[i+1]; (i >= 0 && i+1 < l-1)
	// else clause -> args[l-1]
	// If case clause has else clause, l%2 == 1.
	if l%2 == 1 {
		ret, isNull, err = args[l-1].EvalTime(b.ctx, row)
		return ret, isNull, err
	}
	return ret, true, 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
}
855486
func (b *builtinConcatWSSig) evalString(row chunk.Row) (string, bool, error) {
	args := b.getArgs()
	strs := make([]string, 0, len(args))
	var sep string
	for i, arg := range args {
		val, isNull, err := arg.EvalString(b.ctx, row)
		if err != nil {
			return val, isNull, err
		}

		if isNull {
			// If the separator is NULL, the result is NULL.
			if i == 0 {
				return val, isNull, nil
			}
			// CONCAT_WS() does not skip empty strings. However,
			// it does skip any NULL values after the separator argument.
			continue
		}

		if i == 0 {
			sep = val
			continue
		}
		strs = append(strs, val)
	}

	// TODO: check whether the length of result is larger than Flen
	return strings.Join(strs, sep), false, nil
}
653607
func Eval(expression string) (time.Time, error) {
	return EvalAnchor(time.Now(), expression)
}
77009
func (b *builtinInsertSig) 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)
	runeLength := int64(len(runes))

	pos, isNull, err := b.args[1].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}
	if pos < 1 || pos > runeLength {
		return str, false, nil
	}

	length, isNull, err := b.args[2].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}

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

	if length > runeLength-pos+1 || length < 0 {
		length = runeLength - pos + 1
	}

	strHead := string(runes[0 : pos-1])
	strTail := string(runes[pos+length-1:])
	if uint64(len(strHead)+len(newstr)+len(strTail)) > b.maxAllowedPacket {
		b.ctx.GetSessionVars().StmtCtx.AppendWarning(errWarnAllowedPacketOverflowed.GenWithStackByArgs("insert", b.maxAllowedPacket))
		return "", true, nil
	}
	return strHead + newstr + strTail, false, nil
}
1297782
func (p *Parser) ParseString(s string, v interface{}) error {
	return p.Parse(strings.NewReader(s), v)
}
1374349
func (sf *ScalarFunction) EvalString(ctx sessionctx.Context, row chunk.Row) (string, bool, error) {
	return sf.Function.evalString(row)
}
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
}
1203519
func (b *builtinLeftBinarySig) evalString(row chunk.Row) (string, bool, error) {
	str, isNull, err := b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}
	left, isNull, err := b.args[1].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return "", true, err
	}
	leftLength := int(left)
	if strLength := len(str); leftLength > strLength {
		leftLength = strLength
	} else if leftLength < 0 {
		leftLength = 0
	}
	return str[:leftLength], false, nil
}
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
}
965265
func (b *builtinHexIntArgSig) evalString(row chunk.Row) (string, bool, error) {
	x, isNull, err := b.args[0].EvalInt(b.ctx, row)
	if isNull || err != nil {
		return "", isNull, err
	}
	return strings.ToUpper(fmt.Sprintf("%x", uint64(x))), false, nil
}
365685
func (b *builtinReplaceSig) evalString(row chunk.Row) (d string, isNull bool, err error) {
	var str, oldStr, newStr string

	str, isNull, err = b.args[0].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	oldStr, isNull, err = b.args[1].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	newStr, isNull, err = b.args[2].EvalString(b.ctx, row)
	if isNull || err != nil {
		return d, isNull, err
	}
	if oldStr == "" {
		return str, false, nil
	}
	return strings.Replace(str, oldStr, newStr, -1), false, nil
}