Example #1
0
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)
		}
	}
}
Example #2
0
// ComputeBit computes the bitwise operation on two datums.
func ComputeBit(op tipb.ExprType, left, right types.Datum) (types.Datum, error) {
	var result types.Datum
	a, err := types.CoerceArithmetic(left)
	if err != nil {
		return result, errors.Trace(err)
	}

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

	switch op {
	case tipb.ExprType_BitAnd:
		return types.ComputeBitAnd(a, b)
	case tipb.ExprType_BitOr:
		return types.ComputeBitOr(a, b)
	case tipb.ExprType_BitXor:
		return types.ComputeBitXor(a, b)
	case tipb.ExprType_LeftShift:
		return types.ComputeLeftShift(a, b)
	case tipb.ExprType_RighShift:
		return types.ComputeRightShift(a, b)
	default:
		return result, errors.Errorf("Unknown binop type: %v", op)
	}
}
Example #3
0
// ComputeArithmetic computes the arithmetic operation on two datums.
func ComputeArithmetic(op tipb.ExprType, left types.Datum, right types.Datum) (types.Datum, error) {
	var result types.Datum
	a, err := types.CoerceArithmetic(left)
	if err != nil {
		return result, errors.Trace(err)
	}

	b, err := types.CoerceArithmetic(right)
	if err != nil {
		return result, errors.Trace(err)
	}
	a, b = types.CoerceDatum(a, b)
	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(a, b)
	default:
		return result, errors.Errorf("Unknown binop type: %v", op)
	}
}
Example #4
0
File: eval.go Project: anywhy/tidb
func (e *Evaluator) evalArithmetic(expr *tipb.Expr) (types.Datum, error) {
	var result types.Datum
	left, right, err := e.evalTwoChildren(expr)
	if err != nil {
		return result, errors.Trace(err)
	}
	a, err := types.CoerceArithmetic(left)
	if err != nil {
		return result, errors.Trace(err)
	}

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

	switch expr.GetTp() {
	case tipb.ExprType_Plus:
		return types.ComputePlus(a, b)
	case tipb.ExprType_Div:
		return types.ComputeDiv(a, b)
	default:
		return result, errors.Errorf("Unknown binop type: %v", expr.GetTp())
	}
}
Example #5
0
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
}
Example #6
0
// 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)
	}
}
Example #7
0
func (e *Evaluator) evalBitOps(expr *tipb.Expr) (types.Datum, error) {
	var result types.Datum
	if expr.GetTp() == tipb.ExprType_BitNeg {
		if len(expr.Children) != 1 {
			err := ErrInvalid.Gen("BitNeg(~) need 1 operand but got %d", len(expr.Children))
			return result, err
		}
		operand, err := e.Eval(expr.Children[0])
		if err != nil {
			return types.Datum{}, errors.Trace(err)
		}
		a, err := types.CoerceArithmetic(operand)
		if err != nil {
			return result, errors.Trace(err)
		}
		return types.ComputeBitNeg(a)
	}
	left, right, err := e.evalTwoChildren(expr)
	if err != nil {
		return result, errors.Trace(err)
	}
	return ComputeBit(expr.GetTp(), left, right)
}