コード例 #1
0
ファイル: builtin_other.go プロジェクト: yuyongwei/tidb
func arithmeticFuncFactory(op opcode.Op) BuiltinFunc {
	return func(args []types.Datum, _ context.Context) (d types.Datum, err error) {
		a, err := types.CoerceArithmetic(args[0])
		if err != nil {
			return d, errors.Trace(err)
		}

		b, err := types.CoerceArithmetic(args[1])
		if err != nil {
			return d, errors.Trace(err)
		}

		a, b = types.CoerceDatum(a, b)
		if a.IsNull() || b.IsNull() {
			return
		}

		switch op {
		case opcode.Plus:
			return types.ComputePlus(a, b)
		case opcode.Minus:
			return types.ComputeMinus(a, b)
		case opcode.Mul:
			return types.ComputeMul(a, b)
		case opcode.Div:
			return types.ComputeDiv(a, b)
		case opcode.Mod:
			return types.ComputeMod(a, b)
		case opcode.IntDiv:
			return types.ComputeIntDiv(a, b)
		default:
			return d, ErrInvalidOperation.Gen("invalid op %v in arithmetic operation", op)
		}
	}
}
コード例 #2
0
ファイル: evaluator_binop.go プロジェクト: pingcap/tidb
func (e *Evaluator) handleArithmeticOp(o *ast.BinaryOperationExpr) bool {
	a, err := types.CoerceArithmetic(e.sc, *o.L.GetDatum())
	if err != nil {
		e.err = errors.Trace(err)
		return false
	}
	b, err := types.CoerceArithmetic(e.sc, *o.R.GetDatum())
	if err != nil {
		e.err = errors.Trace(err)
		return false
	}

	a, b, err = types.CoerceDatum(e.sc, a, b)
	if err != nil {
		e.err = errors.Trace(err)
		return false
	}
	if a.IsNull() || b.IsNull() {
		o.SetNull()
		return true
	}

	var result types.Datum
	switch o.Op {
	case opcode.Plus:
		result, e.err = types.ComputePlus(a, b)
	case opcode.Minus:
		result, e.err = types.ComputeMinus(a, b)
	case opcode.Mul:
		result, e.err = types.ComputeMul(a, b)
	case opcode.Div:
		result, e.err = types.ComputeDiv(e.sc, a, b)
	case opcode.Mod:
		result, e.err = types.ComputeMod(e.sc, a, b)
	case opcode.IntDiv:
		result, e.err = types.ComputeIntDiv(e.sc, a, b)
	default:
		e.err = ErrInvalidOperation.Gen("invalid op %v in arithmetic operation", o.Op)
		return false
	}
	o.SetDatum(result)
	return e.err == nil
}
コード例 #3
0
ファイル: eval_arithmetic_ops.go プロジェクト: pingcap/tidb
// ComputeArithmetic computes the arithmetic operation on two datums.
func ComputeArithmetic(sc *variable.StatementContext, op tipb.ExprType, left types.Datum, right types.Datum) (types.Datum, error) {
	var result types.Datum
	a, err := types.CoerceArithmetic(sc, left)
	if err != nil {
		return result, errors.Trace(err)
	}

	b, err := types.CoerceArithmetic(sc, right)
	if err != nil {
		return result, errors.Trace(err)
	}
	a, b, err = types.CoerceDatum(sc, a, b)
	if err != nil {
		return result, errors.Trace(err)
	}
	if a.IsNull() || b.IsNull() {
		return result, nil
	}

	switch op {
	case tipb.ExprType_Plus:
		return types.ComputePlus(a, b)
	case tipb.ExprType_Div:
		return types.ComputeDiv(sc, a, b)
	case tipb.ExprType_Minus:
		return types.ComputeMinus(a, b)
	case tipb.ExprType_Mul:
		return types.ComputeMul(a, b)
	case tipb.ExprType_IntDiv:
		return types.ComputeIntDiv(sc, a, b)
	case tipb.ExprType_Mod:
		return types.ComputeMod(sc, a, b)
	default:
		return result, errors.Errorf("Unknown binop type: %v", op)
	}
}