From b36ad55741e8010d7a58e96f4a57348028df19d5 Mon Sep 17 00:00:00 2001 From: siddontang Date: Mon, 14 Sep 2015 08:23:04 +0800 Subject: [PATCH 1/2] expressions: use integer for time in arithmetic op if FSP = 0 --- expression/expressions/binop.go | 18 ++++++++++++++---- expression/expressions/binop_test.go | 11 +++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/expression/expressions/binop.go b/expression/expressions/binop.go index 6c83d2aaf5b61..14329f5343556 100644 --- a/expression/expressions/binop.go +++ b/expression/expressions/binop.go @@ -675,11 +675,21 @@ 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 { + // Integer number 20111111101010 can not overflow int64. + 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 { + // Integer number 111111 can not overflow int64. + 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) } From 23f8e96f4129261f5482dda71fc69d9942c337d4 Mon Sep 17 00:00:00 2001 From: siddontang Date: Mon, 14 Sep 2015 08:31:11 +0800 Subject: [PATCH 2/2] expressions: Address comment --- expression/expressions/binop.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/expression/expressions/binop.go b/expression/expressions/binop.go index 14329f5343556..80eeb0f17545d 100644 --- a/expression/expressions/binop.go +++ b/expression/expressions/binop.go @@ -678,7 +678,6 @@ func (o *BinaryOperation) coerceArithmetic(a interface{}) (interface{}, error) { // if time has no precision, return int64 v := x.ToNumber() if x.Fsp == 0 { - // Integer number 20111111101010 can not overflow int64. return v.IntPart(), nil } return v, nil @@ -686,7 +685,6 @@ func (o *BinaryOperation) coerceArithmetic(a interface{}) (interface{}, error) { // if duration has no precision, return int64 v := x.ToNumber() if x.Fsp == 0 { - // Integer number 111111 can not overflow int64. return v.IntPart(), nil } return v, nil