From 9c438fe0e3710cc603e085f003948f2a5c63caf9 Mon Sep 17 00:00:00 2001 From: Yuanjia Zhang Date: Fri, 7 Feb 2020 14:02:52 +0800 Subject: [PATCH] expression: handle ErrTruncated when dividing decimals in non-data-change stmts (#14438) --- expression/builtin_arithmetic.go | 3 +++ expression/builtin_arithmetic_vec.go | 8 ++++++-- expression/integration_test.go | 9 ++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/expression/builtin_arithmetic.go b/expression/builtin_arithmetic.go index 03e0b448c111b..747d9fce0b05c 100644 --- a/expression/builtin_arithmetic.go +++ b/expression/builtin_arithmetic.go @@ -650,6 +650,9 @@ func (s *builtinArithmeticDivideDecimalSig) evalDecimal(row chunk.Row) (*types.M err = types.DecimalDiv(a, b, c, types.DivFracIncr) if err == types.ErrDivByZero { return c, true, handleDivisionByZeroError(s.ctx) + } else if err == types.ErrTruncated { + sc := s.ctx.GetSessionVars().StmtCtx + err = sc.HandleTruncate(errTruncatedWrongValue.GenWithStackByArgs("DECIMAL", c)) } else if err == nil { _, frac := c.PrecisionAndFrac() if frac < s.baseBuiltinFunc.tp.Decimal { diff --git a/expression/builtin_arithmetic_vec.go b/expression/builtin_arithmetic_vec.go index e6d266df6feb3..954861d9e45be 100644 --- a/expression/builtin_arithmetic_vec.go +++ b/expression/builtin_arithmetic_vec.go @@ -79,6 +79,7 @@ func (b *builtinArithmeticDivideDecimalSig) vecEvalDecimal(input *chunk.Chunk, r y := buf.Decimals() var to types.MyDecimal var frac int + sc := b.ctx.GetSessionVars().StmtCtx for i := 0; i < n; i++ { if result.IsNull(i) { continue @@ -90,6 +91,10 @@ func (b *builtinArithmeticDivideDecimalSig) vecEvalDecimal(input *chunk.Chunk, r } result.SetNull(i, true) continue + } else if err == types.ErrTruncated { + if err = sc.HandleTruncate(errTruncatedWrongValue.GenWithStackByArgs("DECIMAL", to)); err != nil { + return err + } } else if err == nil { _, frac = to.PrecisionAndFrac() if frac < b.baseBuiltinFunc.tp.Decimal { @@ -698,8 +703,7 @@ func (b *builtinArithmeticIntDivideDecimalSig) vecEvalInt(input *chunk.Chunk, re } if err == types.ErrTruncated { err = sc.HandleTruncate(errTruncatedWrongValue.GenWithStackByArgs("DECIMAL", c)) - } - if err == types.ErrOverflow { + } else if err == types.ErrOverflow { newErr := errTruncatedWrongValue.GenWithStackByArgs("DECIMAL", c) err = sc.HandleOverflow(newErr, newErr) } diff --git a/expression/integration_test.go b/expression/integration_test.go index 6ba5dfeb0ff15..ea05c6360b303 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -3601,7 +3601,7 @@ func (s *testIntegrationSuite) TestAggregationBuiltinJSONObjectAgg(c *C) { b varchar(100), c decimal(3,2), d json, - e date, + e date, f time, g datetime DEFAULT '2012-01-01', h timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, @@ -4438,6 +4438,13 @@ func (s *testIntegrationSuite) TestDecimalMul(c *C) { res.Check(testkit.Rows("0.55125221922461136")) } +func (s *testIntegrationSuite) TestDecimalDiv(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustQuery("select cast(1 as decimal(60,30)) / cast(1 as decimal(60,30)) / cast(1 as decimal(60, 30))").Check(testkit.Rows("1.000000000000000000000000000000")) + tk.MustQuery("select cast(1 as decimal(60,30)) / cast(3 as decimal(60,30)) / cast(7 as decimal(60, 30))").Check(testkit.Rows("0.047619047619047619047619047619")) + tk.MustQuery("select cast(1 as decimal(60,30)) / cast(3 as decimal(60,30)) / cast(7 as decimal(60, 30)) / cast(13 as decimal(60, 30))").Check(testkit.Rows("0.003663003663003663003663003663")) +} + func (s *testIntegrationSuite) TestUnknowHintIgnore(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("USE test")