diff --git a/expression/expressions/binop.go b/expression/expressions/binop.go index 6c83d2aaf5b61..80eeb0f17545d 100644 --- a/expression/expressions/binop.go +++ b/expression/expressions/binop.go @@ -675,11 +675,19 @@ func (o *BinaryOperation) coerceArithmetic(a interface{}) (interface{}, error) { } return f, err case mysql.Time: - // TODO: if time has no precision, return int64 - return x.ToNumber(), nil + // if time has no precision, return int64 + v := x.ToNumber() + if x.Fsp == 0 { + return v.IntPart(), nil + } + return v, nil case mysql.Duration: - // TODO: if duration has no precision, return int64 - return x.ToNumber(), nil + // if duration has no precision, return int64 + v := x.ToNumber() + if x.Fsp == 0 { + return v.IntPart(), nil + } + return v, nil case []byte: // []byte is the same as string, converted to float for arithmetic operator. f, err := types.StrToFloat(string(x)) diff --git a/expression/expressions/binop_test.go b/expression/expressions/binop_test.go index 0d08205eec515..e7ef9e03c61a3 100644 --- a/expression/expressions/binop_test.go +++ b/expression/expressions/binop_test.go @@ -15,6 +15,7 @@ package expressions import ( "errors" + "time" . "github.com/pingcap/check" "github.com/pingcap/tidb/expression" @@ -416,6 +417,9 @@ func (s *testBinOpSuite) TestNumericOp(c *C) { {uint64(1), opcode.Mul, uint64(1), 1}, {mysql.Time{}, opcode.Mul, 0, 0}, {mysql.ZeroDuration, opcode.Mul, 0, 0}, + {mysql.Time{Time: time.Now(), Fsp: 0, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0}, + {mysql.Time{Time: time.Now(), Fsp: 6, Type: mysql.TypeDatetime}, opcode.Mul, 0, 0}, + {mysql.Duration{Duration: 100000000, Fsp: 6}, opcode.Mul, 0, 0}, // div {1, opcode.Div, float64(1), 1}, @@ -540,5 +544,12 @@ func (s *testBinOpSuite) TestNumericOp(c *C) { expr.R = newTestRow(1, 2) expr.Op = opcode.Plus + _, err = expr.Eval(nil, nil) + c.Assert(err, NotNil) + + expr.L = newTestRow(1, 2) + expr.R = newTestRow(1, 2) + expr.Op = opcode.Plus + _, err = expr.Eval(nil, nil) c.Assert(err, NotNil) }