func (b *builtinRowSig) evalString(row chunk.Row) (string, bool, error) {
	panic("builtinRowSig.evalString() should never be called.")
}
evalString rowFunc should always be flattened in expression rewrite phrase.
package expression
import (
	"strings"
	"time"
	"github.com/pingcap/errors"
	"github.com/pingcap/parser/mysql"
	"github.com/pingcap/tidb/sessionctx"
	"github.com/pingcap/tidb/types"
	"github.com/pingcap/tidb/types/json"
	"github.com/pingcap/tidb/util/chunk"
	"github.com/pingcap/tidb/util/collate"
	"github.com/pingcap/tidb/util/set"
	"github.com/pingcap/tidb/util/stringutil"
	"github.com/pingcap/tipb/go-tipb"
)
var (
	_ functionClass = &inFunctionClass{}
	_ functionClass = &rowFunctionClass{}
	_ functionClass = &setVarFunctionClass{}
	_ functionClass = &getVarFunctionClass{}
	_ functionClass = &lockFunctionClass{}
	_ functionClass = &releaseLockFunctionClass{}
	_ functionClass = &valuesFunctionClass{}
	_ functionClass = &bitCountFunctionClass{}
	_ functionClass = &getParamFunctionClass{}
)
var (
	_ builtinFunc = &builtinSleepSig{}
	_ builtinFunc = &builtinInIntSig{}
	_ builtinFunc = &builtinInStringSig{}
	_ builtinFunc = &builtinInDecimalSig{}
	_ builtinFunc = &builtinInRealSig{}
	_ builtinFunc = &builtinInTimeSig{}
	_ builtinFunc = &builtinInDurationSig{}
	_ builtinFunc = &builtinInJSONSig{}
	_ builtinFunc = &builtinRowSig{}
	_ builtinFunc = &builtinSetVarSig{}
	_ builtinFunc = &builtinGetVarSig{}
	_ builtinFunc = &builtinLockSig{}
	_ builtinFunc = &builtinReleaseLockSig{}
	_ builtinFunc = &builtinValuesIntSig{}
	_ builtinFunc = &builtinValuesRealSig{}
	_ builtinFunc = &builtinValuesDecimalSig{}
	_ builtinFunc = &builtinValuesStringSig{}
	_ builtinFunc = &builtinValuesTimeSig{}
	_ builtinFunc = &builtinValuesDurationSig{}
	_ builtinFunc = &builtinValuesJSONSig{}
	_ builtinFunc = &builtinBitCountSig{}
	_ builtinFunc = &builtinGetParamStringSig{}
)
type inFunctionClass struct {
	baseFunctionClass
}
func (c *inFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (sig builtinFunc, err error) {
	if err := c.verifyArgs(args); err != nil {
		return nil, err
	}
	argTps := make([]types.EvalType, len(args))
	for i := range args {
		argTps[i] = args[0].GetType().EvalType()
	}
	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...)
	if err != nil {
		return nil, err
	}
	bf.tp.Flen = 1
	switch args[0].GetType().EvalType() {
	case types.ETInt:
		inInt := builtinInIntSig{baseInSig: baseInSig{baseBuiltinFunc: bf}}
		err := inInt.buildHashMapForConstArgs(ctx)
		if err != nil {
			return &inInt, err
		}
		sig = &inInt
		sig.setPbCode(tipb.ScalarFuncSig_InInt)
	case types.ETString:
		inStr := builtinInStringSig{baseInSig: baseInSig{baseBuiltinFunc: bf}}
		err := inStr.buildHashMapForConstArgs(ctx)
		if err != nil {
			return &inStr, err
		}
		sig = &inStr
		sig.setPbCode(tipb.ScalarFuncSig_InString)
	case types.ETReal:
		inReal := builtinInRealSig{baseInSig: baseInSig{baseBuiltinFunc: bf}}
		err := inReal.buildHashMapForConstArgs(ctx)
		if err != nil {
			return &inReal, err
		}
		sig = &inReal
		sig.setPbCode(tipb.ScalarFuncSig_InReal)
	case types.ETDecimal:
		inDecimal := builtinInDecimalSig{baseInSig: baseInSig{baseBuiltinFunc: bf}}
		err := inDecimal.buildHashMapForConstArgs(ctx)
		if err != nil {
			return &inDecimal, err
		}
		sig = &inDecimal
		sig.setPbCode(tipb.ScalarFuncSig_InDecimal)
	case types.ETDatetime, types.ETTimestamp:
		inTime := builtinInTimeSig{baseInSig: baseInSig{baseBuiltinFunc: bf}}
		err := inTime.buildHashMapForConstArgs(ctx)
		if err != nil {
			return &inTime, err
		}
		sig = &inTime
		sig.setPbCode(tipb.ScalarFuncSig_InTime)
	case types.ETDuration:
		inDuration := builtinInDurationSig{baseInSig: baseInSig{baseBuiltinFunc: bf}}
		err := inDuration.buildHashMapForConstArgs(ctx)
		if err != nil {
			return &inDuration, err
		}
		sig = &inDuration
		sig.setPbCode(tipb.ScalarFuncSig_InDuration)
	case types.ETJson:
		sig = &builtinInJSONSig{baseBuiltinFunc: bf}
		sig.setPbCode(tipb.ScalarFuncSig_InJson)
	}
	return sig, nil
}
type baseInSig struct {
	baseBuiltinFunc
	nonConstArgs []Expression
	hasNull      bool
}
type builtinInIntSig struct {
	baseInSig
	hashSet map[int64]bool
}
func (b *builtinInIntSig) buildHashMapForConstArgs(ctx sessionctx.Context) error {
	b.nonConstArgs = []Expression{b.args[0]}
	b.hashSet = make(map[int64]bool, len(b.args)-1)
	for i := 1; i < len(b.args); i++ {
		if b.args[i].ConstItem(b.ctx.GetSessionVars().StmtCtx) {
			val, isNull, err := b.args[i].EvalInt(ctx, chunk.Row{})
			if err != nil {
				return err
			}
			if isNull {
				b.hasNull = true
				continue
			}
			b.hashSet[val] = mysql.HasUnsignedFlag(b.args[i].GetType().Flag)
		} else {
			b.nonConstArgs = append(b.nonConstArgs, b.args[i])
		}
	}
	return nil
}
func (b *builtinInIntSig) Clone() builtinFunc {
	newSig := &builtinInIntSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	newSig.nonConstArgs = make([]Expression, 0, len(b.nonConstArgs))
	for _, arg := range b.nonConstArgs {
		newSig.nonConstArgs = append(newSig.nonConstArgs, arg.Clone())
	}
	newSig.hashSet = b.hashSet
	newSig.hasNull = b.hasNull
	return newSig
}
func (b *builtinInIntSig) evalInt(row chunk.Row) (int64, bool, error) {
	arg0, isNull0, err := b.args[0].EvalInt(b.ctx, row)
	if isNull0 || err != nil {
		return 0, isNull0, err
	}
	isUnsigned0 := mysql.HasUnsignedFlag(b.args[0].GetType().Flag)
	args := b.args
	if len(b.hashSet) != 0 {
		args = b.nonConstArgs
		if isUnsigned, ok := b.hashSet[arg0]; ok {
			if (isUnsigned0 && isUnsigned) || (!isUnsigned0 && !isUnsigned) {
				return 1, false, nil
			}
			if arg0 >= 0 {
				return 1, false, nil
			}
		}
	}
	hasNull := b.hasNull
	for _, arg := range args[1:] {
		evaledArg, isNull, err := arg.EvalInt(b.ctx, row)
		if err != nil {
			return 0, true, err
		}
		if isNull {
			hasNull = true
			continue
		}
		isUnsigned := mysql.HasUnsignedFlag(arg.GetType().Flag)
		if isUnsigned0 && isUnsigned {
			if evaledArg == arg0 {
				return 1, false, nil
			}
		} else if !isUnsigned0 && !isUnsigned {
			if evaledArg == arg0 {
				return 1, false, nil
			}
		} else if !isUnsigned0 && isUnsigned {
			if arg0 >= 0 && evaledArg == arg0 {
				return 1, false, nil
			}
		} else {
			if evaledArg >= 0 && evaledArg == arg0 {
				return 1, false, nil
			}
		}
	}
	return 0, hasNull, nil
}
type builtinInStringSig struct {
	baseInSig
	hashSet set.StringSet
}
func (b *builtinInStringSig) buildHashMapForConstArgs(ctx sessionctx.Context) error {
	b.nonConstArgs = []Expression{b.args[0]}
	b.hashSet = set.NewStringSet()
	collator := collate.GetCollator(b.collation)
	for i := 1; i < len(b.args); i++ {
		if b.args[i].ConstItem(b.ctx.GetSessionVars().StmtCtx) {
			val, isNull, err := b.args[i].EvalString(ctx, chunk.Row{})
			if err != nil {
				return err
			}
			if isNull {
				b.hasNull = true
				continue
			}
			b.hashSet.Insert(string(collator.Key(val)))  
		} else {
			b.nonConstArgs = append(b.nonConstArgs, b.args[i])
		}
	}
	return nil
}
func (b *builtinInStringSig) Clone() builtinFunc {
	newSig := &builtinInStringSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	newSig.nonConstArgs = make([]Expression, 0, len(b.nonConstArgs))
	for _, arg := range b.nonConstArgs {
		newSig.nonConstArgs = append(newSig.nonConstArgs, arg.Clone())
	}
	newSig.hashSet = b.hashSet
	newSig.hasNull = b.hasNull
	return newSig
}
func (b *builtinInStringSig) evalInt(row chunk.Row) (int64, bool, error) {
	arg0, isNull0, err := b.args[0].EvalString(b.ctx, row)
	if isNull0 || err != nil {
		return 0, isNull0, err
	}
	args := b.args
	collator := collate.GetCollator(b.collation)
	if len(b.hashSet) != 0 {
		args = b.nonConstArgs
		if b.hashSet.Exist(string(collator.Key(arg0))) {
			return 1, false, nil
		}
	}
	hasNull := b.hasNull
	for _, arg := range args[1:] {
		evaledArg, isNull, err := arg.EvalString(b.ctx, row)
		if err != nil {
			return 0, true, err
		}
		if isNull {
			hasNull = true
			continue
		}
		if types.CompareString(arg0, evaledArg, b.collation) == 0 {
			return 1, false, nil
		}
	}
	return 0, hasNull, nil
}
type builtinInRealSig struct {
	baseInSig
	hashSet set.Float64Set
}
func (b *builtinInRealSig) buildHashMapForConstArgs(ctx sessionctx.Context) error {
	b.nonConstArgs = []Expression{b.args[0]}
	b.hashSet = set.NewFloat64Set()
	for i := 1; i < len(b.args); i++ {
		if b.args[i].ConstItem(b.ctx.GetSessionVars().StmtCtx) {
			val, isNull, err := b.args[i].EvalReal(ctx, chunk.Row{})
			if err != nil {
				return err
			}
			if isNull {
				b.hasNull = true
				continue
			}
			b.hashSet.Insert(val)
		} else {
			b.nonConstArgs = append(b.nonConstArgs, b.args[i])
		}
	}
	return nil
}
func (b *builtinInRealSig) Clone() builtinFunc {
	newSig := &builtinInRealSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	newSig.nonConstArgs = make([]Expression, 0, len(b.nonConstArgs))
	for _, arg := range b.nonConstArgs {
		newSig.nonConstArgs = append(newSig.nonConstArgs, arg.Clone())
	}
	newSig.hashSet = b.hashSet
	newSig.hasNull = b.hasNull
	return newSig
}
func (b *builtinInRealSig) evalInt(row chunk.Row) (int64, bool, error) {
	arg0, isNull0, err := b.args[0].EvalReal(b.ctx, row)
	if isNull0 || err != nil {
		return 0, isNull0, err
	}
	args := b.args
	if len(b.hashSet) != 0 {
		args = b.nonConstArgs
		if b.hashSet.Exist(arg0) {
			return 1, false, nil
		}
	}
	hasNull := b.hasNull
	for _, arg := range args[1:] {
		evaledArg, isNull, err := arg.EvalReal(b.ctx, row)
		if err != nil {
			return 0, true, err
		}
		if isNull {
			hasNull = true
			continue
		}
		if arg0 == evaledArg {
			return 1, false, nil
		}
	}
	return 0, hasNull, nil
}
type builtinInDecimalSig struct {
	baseInSig
	hashSet set.StringSet
}
func (b *builtinInDecimalSig) buildHashMapForConstArgs(ctx sessionctx.Context) error {
	b.nonConstArgs = []Expression{b.args[0]}
	b.hashSet = set.NewStringSet()
	for i := 1; i < len(b.args); i++ {
		if b.args[i].ConstItem(b.ctx.GetSessionVars().StmtCtx) {
			val, isNull, err := b.args[i].EvalDecimal(ctx, chunk.Row{})
			if err != nil {
				return err
			}
			if isNull {
				b.hasNull = true
				continue
			}
			key, err := val.ToHashKey()
			if err != nil {
				return err
			}
			b.hashSet.Insert(string(key))
		} else {
			b.nonConstArgs = append(b.nonConstArgs, b.args[i])
		}
	}
	return nil
}
func (b *builtinInDecimalSig) Clone() builtinFunc {
	newSig := &builtinInDecimalSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	newSig.nonConstArgs = make([]Expression, 0, len(b.nonConstArgs))
	for _, arg := range b.nonConstArgs {
		newSig.nonConstArgs = append(newSig.nonConstArgs, arg.Clone())
	}
	newSig.hashSet = b.hashSet
	newSig.hasNull = b.hasNull
	return newSig
}
func (b *builtinInDecimalSig) evalInt(row chunk.Row) (int64, bool, error) {
	arg0, isNull0, err := b.args[0].EvalDecimal(b.ctx, row)
	if isNull0 || err != nil {
		return 0, isNull0, err
	}
	args := b.args
	key, err := arg0.ToHashKey()
	if err != nil {
		return 0, true, err
	}
	if len(b.hashSet) != 0 {
		args = b.nonConstArgs
		if b.hashSet.Exist(string(key)) {
			return 1, false, nil
		}
	}
	hasNull := b.hasNull
	for _, arg := range args[1:] {
		evaledArg, isNull, err := arg.EvalDecimal(b.ctx, row)
		if err != nil {
			return 0, true, err
		}
		if isNull {
			hasNull = true
			continue
		}
		if arg0.Compare(evaledArg) == 0 {
			return 1, false, nil
		}
	}
	return 0, hasNull, nil
}
type builtinInTimeSig struct {
	baseInSig
	hashSet map[types.Time]struct{}
}
func (b *builtinInTimeSig) buildHashMapForConstArgs(ctx sessionctx.Context) error {
	b.nonConstArgs = []Expression{b.args[0]}
	b.hashSet = make(map[types.Time]struct{}, len(b.args)-1)
	for i := 1; i < len(b.args); i++ {
		if b.args[i].ConstItem(b.ctx.GetSessionVars().StmtCtx) {
			val, isNull, err := b.args[i].EvalTime(ctx, chunk.Row{})
			if err != nil {
				return err
			}
			if isNull {
				b.hasNull = true
				continue
			}
			b.hashSet[val] = struct{}{}
		} else {
			b.nonConstArgs = append(b.nonConstArgs, b.args[i])
		}
	}
	return nil
}
func (b *builtinInTimeSig) Clone() builtinFunc {
	newSig := &builtinInTimeSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	newSig.nonConstArgs = make([]Expression, 0, len(b.nonConstArgs))
	for _, arg := range b.nonConstArgs {
		newSig.nonConstArgs = append(newSig.nonConstArgs, arg.Clone())
	}
	newSig.hashSet = b.hashSet
	newSig.hasNull = b.hasNull
	return newSig
}
func (b *builtinInTimeSig) evalInt(row chunk.Row) (int64, bool, error) {
	arg0, isNull0, err := b.args[0].EvalTime(b.ctx, row)
	if isNull0 || err != nil {
		return 0, isNull0, err
	}
	args := b.args
	if len(b.hashSet) != 0 {
		args = b.nonConstArgs
		if _, ok := b.hashSet[arg0]; ok {
			return 1, false, nil
		}
	}
	hasNull := b.hasNull
	for _, arg := range args[1:] {
		evaledArg, isNull, err := arg.EvalTime(b.ctx, row)
		if err != nil {
			return 0, true, err
		}
		if isNull {
			hasNull = true
			continue
		}
		if arg0.Compare(evaledArg) == 0 {
			return 1, false, nil
		}
	}
	return 0, hasNull, nil
}
type builtinInDurationSig struct {
	baseInSig
	hashSet map[time.Duration]struct{}
}
func (b *builtinInDurationSig) buildHashMapForConstArgs(ctx sessionctx.Context) error {
	b.nonConstArgs = []Expression{b.args[0]}
	b.hashSet = make(map[time.Duration]struct{}, len(b.args)-1)
	for i := 1; i < len(b.args); i++ {
		if b.args[i].ConstItem(b.ctx.GetSessionVars().StmtCtx) {
			val, isNull, err := b.args[i].EvalDuration(ctx, chunk.Row{})
			if err != nil {
				return err
			}
			if isNull {
				b.hasNull = true
				continue
			}
			b.hashSet[val.Duration] = struct{}{}
		} else {
			b.nonConstArgs = append(b.nonConstArgs, b.args[i])
		}
	}
	return nil
}
func (b *builtinInDurationSig) Clone() builtinFunc {
	newSig := &builtinInDurationSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	newSig.nonConstArgs = make([]Expression, 0, len(b.nonConstArgs))
	for _, arg := range b.nonConstArgs {
		newSig.nonConstArgs = append(newSig.nonConstArgs, arg.Clone())
	}
	newSig.hashSet = b.hashSet
	newSig.hasNull = b.hasNull
	return newSig
}
func (b *builtinInDurationSig) evalInt(row chunk.Row) (int64, bool, error) {
	arg0, isNull0, err := b.args[0].EvalDuration(b.ctx, row)
	if isNull0 || err != nil {
		return 0, isNull0, err
	}
	args := b.args
	if len(b.hashSet) != 0 {
		args = b.nonConstArgs
		if _, ok := b.hashSet[arg0.Duration]; ok {
			return 1, false, nil
		}
	}
	hasNull := b.hasNull
	for _, arg := range args[1:] {
		evaledArg, isNull, err := arg.EvalDuration(b.ctx, row)
		if err != nil {
			return 0, true, err
		}
		if isNull {
			hasNull = true
			continue
		}
		if arg0.Compare(evaledArg) == 0 {
			return 1, false, nil
		}
	}
	return 0, hasNull, nil
}
type builtinInJSONSig struct {
	baseBuiltinFunc
}
func (b *builtinInJSONSig) Clone() builtinFunc {
	newSig := &builtinInJSONSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	return newSig
}
func (b *builtinInJSONSig) evalInt(row chunk.Row) (int64, bool, error) {
	arg0, isNull0, err := b.args[0].EvalJSON(b.ctx, row)
	if isNull0 || err != nil {
		return 0, isNull0, err
	}
	var hasNull bool
	for _, arg := range b.args[1:] {
		evaledArg, isNull, err := arg.EvalJSON(b.ctx, row)
		if err != nil {
			return 0, true, err
		}
		if isNull {
			hasNull = true
			continue
		}
		result := json.CompareBinary(evaledArg, arg0)
		if result == 0 {
			return 1, false, nil
		}
	}
	return 0, hasNull, nil
}
type rowFunctionClass struct {
	baseFunctionClass
}
func (c *rowFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (sig builtinFunc, err error) {
	if err = c.verifyArgs(args); err != nil {
		return nil, err
	}
	argTps := make([]types.EvalType, len(args))
	for i := range argTps {
		argTps[i] = args[i].GetType().EvalType()
	}
	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, argTps...)
	if err != nil {
		return nil, err
	}
	sig = &builtinRowSig{bf}
	return sig, nil
}
type builtinRowSig struct {
	baseBuiltinFunc
}
func (b *builtinRowSig) Clone() builtinFunc {
	newSig := &builtinRowSig{}
	newSig.cloneFrom(&b.baseBuiltinFunc)
	return newSig
}