// CompareDatum compares datum to another datum.
// TODO: return error properly.
345491
func (d *Datum) CompareDatum(sc *variable.StatementContext, ad Datum) (int, error) {
	switch ad.k {
	case KindNull:
		if d.k == KindNull {
			return 0, nil
		}
		return 1, nil
	case KindMinNotNull:
		if d.k == KindNull {
			return -1, nil
		} else if d.k == KindMinNotNull {
			return 0, nil
		}
		return 1, nil
	case KindMaxValue:
		if d.k == KindMaxValue {
			return 0, nil
		}
		return -1, nil
	case KindInt64:
		return d.compareInt64(sc, ad.GetInt64())
	case KindUint64:
		return d.compareUint64(sc, ad.GetUint64())
	case KindFloat32, KindFloat64:
		return d.compareFloat64(sc, ad.GetFloat64())
	case KindString:
		return d.compareString(sc, ad.GetString())
	case KindBytes:
		return d.compareBytes(sc, ad.GetBytes())
	case KindMysqlBit:
		return d.compareMysqlBit(sc, ad.GetMysqlBit())
	case KindMysqlDecimal:
		return d.compareMysqlDecimal(sc, ad.GetMysqlDecimal())
	case KindMysqlDuration:
		return d.compareMysqlDuration(sc, ad.GetMysqlDuration())
	case KindMysqlEnum:
		return d.compareMysqlEnum(sc, ad.GetMysqlEnum())
	case KindMysqlHex:
		return d.compareMysqlHex(sc, ad.GetMysqlHex())
	case KindMysqlSet:
		return d.compareMysqlSet(sc, ad.GetMysqlSet())
	case KindMysqlTime:
		return d.compareMysqlTime(sc, ad.GetMysqlTime())
	case KindRow:
		return d.compareRow(sc, ad.GetRow())
	default:
		return 0, nil
	}
}
112615
func EqualDatums(sc *stmtctx.StatementContext, a []Datum, b []Datum) (bool, error) {
	if len(a) != len(b) {
		return false, nil
	}
	if a == nil && b == nil {
		return true, nil
	}
	if a == nil || b == nil {
		return false, nil
	}
	for i, ai := range a {
		v, err := ai.CompareDatum(sc, &b[i])
		if err != nil {
			return false, errors.Trace(err)
		}
		if v != 0 {
			return false, nil
		}
	}
	return true, nil
}
746687
func (sf *ScalarFunction) Eval(row chunk.Row) (d types.Datum, err error) {
	var (
		res    interface{}
		isNull bool
	)
	switch tp, evalType := sf.GetType(), sf.GetType().EvalType(); evalType {
	case types.ETInt:
		var intRes int64
		intRes, isNull, err = sf.EvalInt(sf.GetCtx(), row)
		if mysql.HasUnsignedFlag(tp.Flag) {
			res = uint64(intRes)
		} else {
			res = intRes
		}
	case types.ETReal:
		res, isNull, err = sf.EvalReal(sf.GetCtx(), row)
	case types.ETDecimal:
		res, isNull, err = sf.EvalDecimal(sf.GetCtx(), row)
	case types.ETDatetime, types.ETTimestamp:
		res, isNull, err = sf.EvalTime(sf.GetCtx(), row)
	case types.ETDuration:
		res, isNull, err = sf.EvalDuration(sf.GetCtx(), row)
	case types.ETJson:
		res, isNull, err = sf.EvalJSON(sf.GetCtx(), row)
	case types.ETString:
		res, isNull, err = sf.EvalString(sf.GetCtx(), row)
	}

	if isNull || err != nil {
		d.SetValue(nil)
		return d, err
	}
	d.SetValue(res)
	return
}
1257065
func (d *MyDecimal) Compare(to *MyDecimal) int {
	if d.negative == to.negative {
		cmp, _ := doSub(d, to, nil)
		return cmp
	}
	if d.negative {
		return -1
	}
	return 1
}
295631
func (d *Datum) ToDecimal(sc *stmtctx.StatementContext) (*MyDecimal, error) {
	switch d.Kind() {
	case KindMysqlTime:
		return d.GetMysqlTime().ToNumber(), nil
	case KindMysqlDuration:
		return d.GetMysqlDuration().ToNumber(), nil
	default:
		return ConvertDatumToDecimal(sc, *d)
	}
}
428244
func (col *CorrelatedColumn) EvalDecimal(ctx sessionctx.Context, row chunk.Row) (*types.MyDecimal, bool, error) {
	if col.Data.IsNull() {
		return nil, true, nil
	}
	return col.Data.GetMysqlDecimal(), false, nil
}
1030137
func SortDatums(sc *variable.StatementContext, datums []Datum) error {
	sorter := datumsSorter{datums: datums, sc: sc}
	sort.Sort(&sorter)
	return sorter.err
}
1215669
func compareConstant(ctx sessionctx.Context, fn string, c1, c2 Expression) (int64, bool, error) {
	cmp, err := NewFunction(ctx, fn, types.NewFieldType(mysql.TypeTiny), c1, c2)
	if err != nil {
		return 0, false, err
	}
	return cmp.EvalInt(ctx, chunk.Row{})
}
828889
func (mat *MatMxN) ApproxEqual(m2 *MatMxN) bool {
	if mat == m2 {
		return true
	}
	if mat.m != m2.m || mat.n != m2.n {
		return false
	}

	for i, el := range mat.dat {
		if !FloatEqual(el, m2.dat[i]) {
			return false
		}
	}

	return true
}
900225
func (s *SummarizedCounter) SetSum(v float64) *SummarizedCounter {
	s.Sum = &v
	return s
}
304004
func (m1 Mat2) ApproxFuncEqual(m2 Mat2, eq func(float64, float64) bool) bool {
	for i := range m1 {
		if !eq(m1[i], m2[i]) {
			return false
		}
	}
	return true
}
1235950
func (so SortOrder) Compare(cachedScoring, cachedDesc []bool, i, j *DocumentMatch) int {
	// compare the documents on all search sorts until a differences is found
	for x := range so {
		c := 0
		if cachedScoring[x] {
			if i.Score < j.Score {
				c = -1
			} else if i.Score > j.Score {
				c = 1
			}
		} else {
			iVal := i.Sort[x]
			jVal := j.Sort[x]
			c = strings.Compare(iVal, jVal)
		}

		if c == 0 {
			continue
		}
		if cachedDesc[x] {
			c = -c
		}
		return c
	}
	// if they are the same at this point, impose order based on index natural sort order
	if i.HitNumber == j.HitNumber {
		return 0
	} else if i.HitNumber > j.HitNumber {
		return 1
	}
	return -1
}
1221961
func calculateSum(sc *variable.StatementContext, sum, v types.Datum) (data types.Datum, err error) {
	// for avg and sum calculation
	// avg and sum use decimal for integer and decimal type, use float for others
	// see https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html

	switch v.Kind() {
	case types.KindNull:
	case types.KindInt64, types.KindUint64:
		var d *types.MyDecimal
		d, err = v.ToDecimal(sc)
		if err == nil {
			data = types.NewDecimalDatum(d)
		}
	case types.KindMysqlDecimal:
		data = v
	default:
		var f float64
		f, err = v.ToFloat64(sc)
		if err == nil {
			data = types.NewFloat64Datum(f)
		}
	}

	if err != nil {
		return data, errors.Trace(err)
	}
	if data.IsNull() {
		return sum, nil
	}
	switch sum.Kind() {
	case types.KindNull:
		return data, nil
	case types.KindFloat64, types.KindMysqlDecimal:
		return types.ComputePlus(sum, data)
	default:
		return data, errors.Errorf("invalid value %v for aggregate", sum.Kind())
	}
}
824901
func builtinTrim(args []types.Datum, _ context.Context) (d types.Datum, err error) {
	// args[0] -> Str
	// args[1] -> RemStr
	// args[2] -> Direction
	// eval str
	if args[0].IsNull() {
		return d, nil
	}
	str, err := args[0].ToString()
	if err != nil {
		return d, errors.Trace(err)
	}
	remstr := ""
	// eval remstr
	if len(args) > 1 {
		if args[1].Kind() != types.KindNull {
			remstr, err = args[1].ToString()
			if err != nil {
				return d, errors.Trace(err)
			}
		}
	}
	// do trim
	var result string
	var direction ast.TrimDirectionType
	if len(args) > 2 {
		direction = args[2].GetValue().(ast.TrimDirectionType)
	} else {
		direction = ast.TrimBothDefault
	}
	if direction == ast.TrimLeading {
		if len(remstr) > 0 {
			result = trimLeft(str, remstr)
		} else {
			result = strings.TrimLeft(str, spaceChars)
		}
	} else if direction == ast.TrimTrailing {
		if len(remstr) > 0 {
			result = trimRight(str, remstr)
		} else {
			result = strings.TrimRight(str, spaceChars)
		}
	} else if len(remstr) > 0 {
		x := trimLeft(str, remstr)
		result = trimRight(x, remstr)
	} else {
		result = strings.Trim(str, spaceChars)
	}
	d.SetString(result)
	return d, nil
}
23169
func compareByDigits(n1, n2 []rune) (less, greater, equal bool) {
	offset := len(n2) - len(n1)
	n1n2 := offset < 0 // len(n1) > len(n2)
	if n1n2 {
		// if n1 longer, swap with n2
		offset = -offset
		n1, n2 = n2, n1
	}

	var j int
	// len(n1) always be <= len(n2)
	for i := range n2 {
		var r1 rune
		if offset == 0 {
			// begin actual read
			r1 = n1[j]
			j++
		} else {
			// emulate zero-padding
			r1 = '0'
			offset--
		}

		r2 := n2[i]
		if r1 != r2 {
			if n1n2 {
				return r2 < r1, r2 > r1, false // actually r1 < r2
			}
			return r1 < r2, r1 > r2, false
		}
	}

	// numeric value equals, compare by length
	if n1n2 {
		// n1 was > n2
		return false, true, true
	}
	// eval a comparison only if n1 known to be <= n2
	return len(n1) < len(n2), len(n1) > len(n2), true
}
1342266
func (v1 Version) Compare(v2 Version) int {
	// Equal
	if reflect.DeepEqual(v1, v2) {
		return 0
	}

	// Compare epochs
	if v1.epoch > v2.epoch {
		return 1
	} else if v1.epoch < v2.epoch {
		return -1
	}

	// Compare version
	ret := rpmvercmp(v1.version, v2.version)
	if ret != 0 {
		return ret
	}

	//Compare release
	return rpmvercmp(v1.release, v2.release)
}
439890
func (rf *RulerRule) compare(comp int, value interface{}) *RulerRule {
	var comparator string
	switch comp {
	case eq:
		comparator = "eq"
	case neq:
		comparator = "neq"
	case lt:
		comparator = "lt"
	case lte:
		comparator = "lte"
	case gt:
		comparator = "gt"
	case gte:
		comparator = "gte"
	case contains:
		comparator = "contains"
	case matches:
		comparator = "matches"
	case ncontains:
		comparator = "ncontains"
	}

	// if this thing has a comparator already, we need to make a new ruler filter
	if rf.Comparator != "" {
		rf = &RulerRule{
			rf.Ruler,
			&Rule{
				comparator,
				rf.Path,
				value,
			},
		}
		// attach the new filter to the ruler
		rf.Ruler.rules = append(rf.Ruler.rules, rf.Rule)
	} else {
		//if there is no comparator, we can just set things on the current filter
		rf.Comparator = comparator
		rf.Value = value
	}

	return rf
}