From cca65d01d7e5b9ab6d2e36ef5e41885568d935b8 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Sun, 28 Jul 2019 21:05:58 +0800 Subject: [PATCH 1/3] fix decimal wrong DateAdd result --- expression/builtin_time.go | 5 +++-- expression/integration_test.go | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/expression/builtin_time.go b/expression/builtin_time.go index a8062f85d9b06..24eb91ff03644 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -2657,10 +2657,11 @@ func (du *baseDateArithmitical) getIntervalFromString(ctx sessionctx.Context, ar } func (du *baseDateArithmitical) getIntervalFromDecimal(ctx sessionctx.Context, args []Expression, row chunk.Row, unit string) (string, bool, error) { - interval, isNull, err := args[1].EvalString(ctx, row) + decimal, isNull, err := args[1].EvalDecimal(ctx, row) if isNull || err != nil { return "", true, err } + interval := decimal.String() switch strings.ToUpper(unit) { case "HOUR_MINUTE", "MINUTE_SECOND", "YEAR_MONTH", "DAY_HOUR", "DAY_MINUTE", @@ -2726,7 +2727,7 @@ func (du *baseDateArithmitical) getIntervalFromReal(ctx sessionctx.Context, args if isNull || err != nil { return "", true, err } - return strconv.FormatFloat(interval, 'f', -1, 64), false, nil + return strconv.FormatFloat(interval, 'f', args[1].GetType().Decimal, 64), false, nil } func (du *baseDateArithmitical) add(ctx sessionctx.Context, date types.Time, interval string, unit string) (types.Time, bool, error) { diff --git a/expression/integration_test.go b/expression/integration_test.go index 7ae1430955acd..2336a850bb834 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -4615,3 +4615,15 @@ func (s *testIntegrationSuite) TestFuncCaseWithLeftJoin(c *C) { tk.MustQuery("select t1.id from kankan1 t1 left join kankan2 t2 on t1.id = t2.id where (case when t1.name='b' then 'case2' when t1.name='a' then 'case1' else NULL end) = 'case1' order by t1.id").Check(testkit.Rows("1", "2")) } + +func (s *testIntegrationSuite) TestIssue11309(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec(`drop table if exists t;`) + tk.MustExec(`CREATE TABLE t (a decimal(6,3),b double(6,3),c float(6,3));`) + tk.MustExec(`INSERT INTO t VALUES (1.100,1.100,1.100);`) + tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL a MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2003-11-18 07:27:53`)) + tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL b MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2003-11-18 07:27:53`)) + tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL c MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2003-11-18 07:27:53`)) + tk.MustExec(`drop table if exists t;`) +} From f308ded276c7d2ee3ac6ab5b6234817f3ef61151 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 29 Jul 2019 16:02:33 +0800 Subject: [PATCH 2/3] add unit test for getIntervalFromDecimal --- expression/builtin_time_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/expression/builtin_time_test.go b/expression/builtin_time_test.go index 78a1abd7f67de..ea3398c52b414 100644 --- a/expression/builtin_time_test.go +++ b/expression/builtin_time_test.go @@ -2761,3 +2761,29 @@ func (s *testEvaluatorSuite) TestTidbParseTso(c *C) { c.Assert(d.IsNull(), IsTrue) } } + +func (s *testEvaluatorSuite) TestGetIntervalFromDecimal(c *C) { + defer testleak.AfterTest(c)() + du := baseDateArithmitical{} + + tests := []struct { + param string + expect string + unit string + }{ + {"1.100", "1:100", "MINUTE_SECOND"}, + {"1.10000", "1-10000", "YEAR_MONTH"}, + {"1.10000", "1 10000", "DAY_HOUR"}, + {"11000", "0 00:00:11000", "DAY_MICROSECOND"}, + {"11000", "00:00:11000", "HOUR_MICROSECOND"}, + {"11.1000", "00:11:1000", "HOUR_SECOND"}, + {"1000", "00:1000", "MINUTE_MICROSECOND"}, + } + + for _, test := range tests { + interval, isNull, err := du.getIntervalFromDecimal(s.ctx, s.datumsToConstants([]types.Datum{types.NewDatum("CURRENT DATE"), types.NewDecimalDatum(newMyDecimal(c, test.param))}), chunk.Row{}, test.unit) + c.Assert(isNull, IsFalse) + c.Assert(err, IsNil) + c.Assert(interval, Equals, test.expect) + } +} From cad398ffe04ca9405058f08e42b87d10934e9293 Mon Sep 17 00:00:00 2001 From: AndrewDi Date: Mon, 29 Jul 2019 21:00:05 +0800 Subject: [PATCH 3/3] add integration test --- expression/integration_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/expression/integration_test.go b/expression/integration_test.go index 2336a850bb834..47b12cda6607b 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -4626,4 +4626,10 @@ func (s *testIntegrationSuite) TestIssue11309(c *C) { tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL b MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2003-11-18 07:27:53`)) tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL c MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2003-11-18 07:27:53`)) tk.MustExec(`drop table if exists t;`) + tk.MustExec(`CREATE TABLE t (a decimal(11,7),b double(11,7),c float(11,7));`) + tk.MustExec(`INSERT INTO t VALUES (123.9999999,123.9999999,123.9999999),(-123.9999999,-123.9999999,-123.9999999);`) + tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL a MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2004-03-13 03:14:52`, `2003-07-25 11:35:34`)) + tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL b MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2004-03-13 03:14:52`, `2003-07-25 11:35:34`)) + tk.MustQuery(`SELECT DATE_ADD('2003-11-18 07:25:13',INTERVAL c MINUTE_SECOND) FROM t`).Check(testkit.Rows(`2003-11-18 09:29:13`, `2003-11-18 05:21:13`)) + tk.MustExec(`drop table if exists t;`) }