func (o *BinaryOperation) evalMul(a interface{}, b interface{}) (interface{}, error) { switch x := a.(type) { case int64: switch y := b.(type) { case int64: return types.MulInt64(x, y) case uint64: return types.MulInteger(y, x) } case uint64: switch y := b.(type) { case int64: return types.MulInteger(x, y) case uint64: return types.MulUint64(x, y) } case float64: switch y := b.(type) { case float64: return x * y, nil } case mysql.Decimal: switch y := b.(type) { case mysql.Decimal: return x.Mul(y), nil } } return types.InvOp2(a, b, opcode.Mul) }
func (o *BinaryOperation) evalPlus(a interface{}, b interface{}) (interface{}, error) { // TODO: check overflow switch x := a.(type) { case int64: switch y := b.(type) { case int64: return x + y, nil case uint64: // For MySQL, if any is unsigned, return unsigned // TODO: check overflow return uint64(x) + y, nil } case uint64: switch y := b.(type) { case int64: // For MySQL, if any is unsigned, return unsigned // TODO: check overflow return x + uint64(y), nil case uint64: return x + y, nil } case float64: switch y := b.(type) { case float64: return x + y, nil } case mysql.Decimal: switch y := b.(type) { case mysql.Decimal: return x.Add(y), nil } } return types.InvOp2(a, b, opcode.Plus) }
func (o *BinaryOperation) evalMinus(a interface{}, b interface{}) (interface{}, error) { switch x := a.(type) { case int64: switch y := b.(type) { case int64: return types.SubInt64(x, y) case uint64: return types.SubIntWithUint(x, y) } case uint64: switch y := b.(type) { case int64: return types.SubUintWithInt(x, y) case uint64: return types.SubUint64(x, y) } case float64: switch y := b.(type) { case float64: return x - y, nil } case mysql.Decimal: switch y := b.(type) { case mysql.Decimal: return x.Sub(y), nil } } return types.InvOp2(a, b, opcode.Minus) }
func computePlus(a, b interface{}) (interface{}, error) { switch x := a.(type) { case int64: switch y := b.(type) { case int64: return types.AddInt64(x, y) case uint64: return types.AddInteger(y, x) } case uint64: switch y := b.(type) { case int64: return types.AddInteger(x, y) case uint64: return types.AddUint64(x, y) } case float64: switch y := b.(type) { case float64: return x + y, nil } case mysql.Decimal: switch y := b.(type) { case mysql.Decimal: return x.Add(y), nil } } return types.InvOp2(a, b, opcode.Plus) }
func (o *BinaryOperation) evalMod(a interface{}, b interface{}) (interface{}, error) { switch x := a.(type) { case int64: switch y := b.(type) { case int64: if y == 0 { return nil, nil } return x % y, nil case uint64: if y == 0 { return nil, nil } else if x < 0 { // TODO: check overflow return -int64(uint64(-x) % y), nil } // TODO: check overflow return uint64(x) % y, nil } case uint64: switch y := b.(type) { case int64: if y == 0 { return nil, nil } else if y < 0 { // TODO: check overflow return -int64(x % uint64(-y)), nil } // TODO: check overflow return x % uint64(y), nil case uint64: if y == 0 { return nil, nil } return x % y, nil } case float64: switch y := b.(type) { case float64: if y == 0 { return nil, nil } return math.Mod(x, y), nil } case mysql.Decimal: switch y := b.(type) { case mysql.Decimal: xf, _ := x.Float64() yf, _ := y.Float64() if yf == 0 { return nil, nil } return math.Mod(xf, yf), nil } } return types.InvOp2(a, b, opcode.Mod) }
func computeMod(a, b interface{}) (interface{}, error) { switch x := a.(type) { case int64: switch y := b.(type) { case int64: if y == 0 { return nil, nil } return x % y, nil case uint64: if y == 0 { return nil, nil } else if x < 0 { // first is int64, return int64. return -int64(uint64(-x) % y), nil } return int64(uint64(x) % y), nil } case uint64: switch y := b.(type) { case int64: if y == 0 { return nil, nil } else if y < 0 { // first is uint64, return uint64. return uint64(x % uint64(-y)), nil } return x % uint64(y), nil case uint64: if y == 0 { return nil, nil } return x % y, nil } case float64: switch y := b.(type) { case float64: if y == 0 { return nil, nil } return math.Mod(x, y), nil } case mysql.Decimal: switch y := b.(type) { case mysql.Decimal: xf, _ := x.Float64() yf, _ := y.Float64() if yf == 0 { return nil, nil } return math.Mod(xf, yf), nil } } return types.InvOp2(a, b, opcode.Mod) }
func computeMul(a, b types.Datum) (d types.Datum, err error) { switch a.Kind() { case types.KindInt64: switch b.Kind() { case types.KindInt64: r, err1 := types.MulInt64(a.GetInt64(), b.GetInt64()) d.SetInt64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.MulInteger(b.GetUint64(), a.GetInt64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindUint64: switch b.Kind() { case types.KindInt64: r, err1 := types.MulInteger(a.GetUint64(), b.GetInt64()) d.SetUint64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.MulUint64(a.GetUint64(), b.GetUint64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindFloat64: switch b.Kind() { case types.KindFloat64: r := a.GetFloat64() * b.GetFloat64() d.SetFloat64(r) return d, nil } case types.KindMysqlDecimal: switch b.Kind() { case types.KindMysqlDecimal: r := a.GetMysqlDecimal().Mul(b.GetMysqlDecimal()) d.SetMysqlDecimal(r) return d, nil } } _, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Mul) return d, errors.Trace(err) }
func computeMinus(a, b types.Datum) (d types.Datum, err error) { switch a.Kind() { case types.KindInt64: switch b.Kind() { case types.KindInt64: r, err1 := types.SubInt64(a.GetInt64(), b.GetInt64()) d.SetInt64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.SubIntWithUint(a.GetInt64(), b.GetUint64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindUint64: switch b.Kind() { case types.KindInt64: r, err1 := types.SubUintWithInt(a.GetUint64(), b.GetInt64()) d.SetUint64(r) return d, errors.Trace(err1) case types.KindUint64: r, err1 := types.SubUint64(a.GetUint64(), b.GetUint64()) d.SetUint64(r) return d, errors.Trace(err1) } case types.KindFloat64: switch b.Kind() { case types.KindFloat64: r := a.GetFloat64() - b.GetFloat64() d.SetFloat64(r) return d, nil } case types.KindMysqlDecimal: switch b.Kind() { case types.KindMysqlDecimal: r := a.GetMysqlDecimal().Sub(b.GetMysqlDecimal()) d.SetMysqlDecimal(r) return d, nil } } _, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Minus) return d, errors.Trace(err) }
func (o *BinaryOperation) evalMul(a interface{}, b interface{}) (interface{}, error) { // TODO: check overflow switch x := a.(type) { case int64: switch y := b.(type) { case int64: return x * y, nil case uint64: // For MySQL, if any is unsigned, return unsigned // TODO: check overflow and negative number // if a negative int64 * uint64, MySQL may throw "BIGINT UNSIGNED value is out of range" error // we skip it now and handle it later. return uint64(x) * y, nil } case uint64: switch y := b.(type) { case int64: // For MySQL, if any is unsigned, return unsigned // TODO: check overflow return x * uint64(y), nil case uint64: return x * y, nil } case float64: switch y := b.(type) { case float64: return x * y, nil } case mysql.Decimal: switch y := b.(type) { case mysql.Decimal: return x.Mul(y), nil } } return types.InvOp2(a, b, opcode.Mul) }
func computeMod(a, b types.Datum) (d types.Datum, err error) { switch a.Kind() { case types.KindInt64: x := a.GetInt64() switch b.Kind() { case types.KindInt64: y := b.GetInt64() if y == 0 { return d, nil } d.SetInt64(x % y) return d, nil case types.KindUint64: y := b.GetUint64() if y == 0 { return d, nil } else if x < 0 { d.SetInt64(-int64(uint64(-x) % y)) // first is int64, return int64. return d, nil } d.SetInt64(int64(uint64(x) % y)) return d, nil } case types.KindUint64: x := a.GetUint64() switch b.Kind() { case types.KindInt64: y := b.GetInt64() if y == 0 { return d, nil } else if y < 0 { // first is uint64, return uint64. d.SetUint64(uint64(x % uint64(-y))) return d, nil } d.SetUint64(x % uint64(y)) return d, nil case types.KindUint64: y := b.GetUint64() if y == 0 { return d, nil } d.SetUint64(x % y) return d, nil } case types.KindFloat64: x := a.GetFloat64() switch b.Kind() { case types.KindFloat64: y := b.GetFloat64() if y == 0 { return d, nil } d.SetFloat64(math.Mod(x, y)) return d, nil } case types.KindMysqlDecimal: x := a.GetMysqlDecimal() switch b.Kind() { case types.KindMysqlDecimal: y := b.GetMysqlDecimal() xf, _ := x.Float64() yf, _ := y.Float64() if yf == 0 { return d, nil } d.SetFloat64(math.Mod(xf, yf)) return d, nil } } _, err = types.InvOp2(a.GetValue(), b.GetValue(), opcode.Mod) return d, errors.Trace(err) }