diff --git a/expression/builtin_time.go b/expression/builtin_time.go index c0ea24fcb7541..65ac3cf311cbf 100644 --- a/expression/builtin_time.go +++ b/expression/builtin_time.go @@ -2744,6 +2744,10 @@ func (du *baseDateArithmitical) add(ctx sessionctx.Context, date types.Time, int date.Fsp = 6 } + if goTime.Year() < 0 || goTime.Year() > (1<<16-1) { + return types.Time{}, true, handleInvalidTimeError(ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime")) + } + date.Time = types.FromGoTime(goTime) overflow, err := types.DateTimeIsOverflow(ctx.GetSessionVars().StmtCtx, date) if err := handleInvalidTimeError(ctx, err); err != nil { @@ -2789,6 +2793,10 @@ func (du *baseDateArithmitical) sub(ctx sessionctx.Context, date types.Time, int date.Fsp = 6 } + if goTime.Year() < 0 || goTime.Year() > (1<<16-1) { + return types.Time{}, true, handleInvalidTimeError(ctx, types.ErrDatetimeFunctionOverflow.GenWithStackByArgs("datetime")) + } + date.Time = types.FromGoTime(goTime) overflow, err := types.DateTimeIsOverflow(ctx.GetSessionVars().StmtCtx, date) if err := handleInvalidTimeError(ctx, err); err != nil { diff --git a/expression/builtin_time_test.go b/expression/builtin_time_test.go index 23e2858feef15..aa4064c6a5797 100644 --- a/expression/builtin_time_test.go +++ b/expression/builtin_time_test.go @@ -1762,6 +1762,35 @@ func (s *testEvaluatorSuite) TestDateArithFuncs(c *C) { c.Assert(err, IsNil) c.Assert(v.GetMysqlTime().String(), Equals, test.expected) } + + testOverflowYears := []struct { + input string + year int + }{ + {"2008-11-23", -1465647104}, + {"2008-11-23", 1465647104}, + } + + for _, test := range testOverflowYears { + args = types.MakeDatums(test.input, test.year, "YEAR") + f, err = fcAdd.getFunction(s.ctx, s.datumsToConstants(args)) + c.Assert(err, IsNil) + c.Assert(f, NotNil) + v, err = evalBuiltinFunc(f, chunk.Row{}) + c.Assert(err, IsNil) + c.Assert(v.IsNull(), IsTrue) + } + + for _, test := range testOverflowYears { + args = types.MakeDatums(test.input, test.year, "YEAR") + f, err = fcSub.getFunction(s.ctx, s.datumsToConstants(args)) + c.Assert(err, IsNil) + c.Assert(f, NotNil) + v, err = evalBuiltinFunc(f, chunk.Row{}) + c.Assert(err, IsNil) + c.Assert(v.IsNull(), IsTrue) + } + testDurations := []struct { dur string fsp int diff --git a/expression/integration_test.go b/expression/integration_test.go index 2be144299678b..f1d88eeaa0a49 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -1966,6 +1966,12 @@ func (s *testIntegrationSuite) TestDatetimeOverflow(c *C) { rows = append(rows, "") } tk.MustQuery("select * from t1").Check(testkit.Rows(rows...)) + + //Fix ISSUE 11256 + tk.MustQuery(`select DATE_ADD('2000-04-13 07:17:02',INTERVAL -1465647104 YEAR);`).Check(testkit.Rows("")) + tk.MustQuery(`select DATE_ADD('2008-11-23 22:47:31',INTERVAL 266076160 QUARTER);`).Check(testkit.Rows("")) + tk.MustQuery(`select DATE_SUB('2000-04-13 07:17:02',INTERVAL 1465647104 YEAR);`).Check(testkit.Rows("")) + tk.MustQuery(`select DATE_SUB('2008-11-23 22:47:31',INTERVAL -266076160 QUARTER);`).Check(testkit.Rows("")) } func (s *testIntegrationSuite) TestBuiltin(c *C) {