Skip to content

Commit

Permalink
table: handling the boundary value of the timestamp type's default va…
Browse files Browse the repository at this point in the history
…lue (#9578) (#9987)
  • Loading branch information
zimulala authored and zz-jason committed Apr 2, 2019
1 parent 59eb553 commit 9436866
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 14 deletions.
8 changes: 8 additions & 0 deletions executor/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,11 @@ func (s *testSuite) TestSetDDLReorgBatchSize(c *C) {
// If do not LoadDDLReorgVars, the local variable will be the last loaded value.
c.Assert(variable.GetDDLReorgBatchSize(), Equals, int32(100))
}

func (s *testSuite) TestTimestampMinDefaultValue(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists tdv;")
tk.MustExec("create table tdv(a int);")
tk.MustExec("ALTER TABLE tdv ADD COLUMN ts timestamp DEFAULT '1970-01-01 08:00:01';")
}
37 changes: 23 additions & 14 deletions table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,27 +360,36 @@ func getColDefaultValue(ctx sessionctx.Context, col *model.ColumnInfo, defaultVa
}
return value, nil
}

// Check and get timestamp/datetime default value.
value, err := expression.GetTimeValue(ctx, defaultVal, col.Tp, col.Decimal)
if err != nil {
return types.Datum{}, errGetDefaultFailed.GenWithStack("Field '%s' get default value fail - %s",
col.Name, errors.Trace(err))
}
// If column is timestamp, and default value is not current_timestamp, should convert the default value to the current session time zone.
sc := ctx.GetSessionVars().StmtCtx
var needChangeTimeZone bool
// If the column's default value is not ZeroDatetimeStr nor CurrentTimestamp, should use the time zone of the default value itself.
if col.Tp == mysql.TypeTimestamp {
if vv, ok := defaultVal.(string); ok && vv != types.ZeroDatetimeStr && strings.ToUpper(vv) != strings.ToUpper(ast.CurrentTimestamp) {
t := value.GetMysqlTime()
needChangeTimeZone = true
originalTZ := sc.TimeZone
// For col.Version = 0, the timezone information of default value is already lost, so use the system timezone as the default value timezone.
defaultTimeZone := timeutil.SystemLocation()
sc.TimeZone = timeutil.SystemLocation()
if col.Version >= model.ColumnInfoVersion1 {
defaultTimeZone = time.UTC
}
err = t.ConvertTimeZone(defaultTimeZone, ctx.GetSessionVars().Location())
if err != nil {
return value, errors.Trace(err)
sc.TimeZone = time.UTC
}
value.SetMysqlTime(t)
defer func() { sc.TimeZone = originalTZ }()
}
}
value, err := expression.GetTimeValue(ctx, defaultVal, col.Tp, col.Decimal)
if err != nil {
return types.Datum{}, errGetDefaultFailed.GenWithStack("Field '%s' get default value fail - %s",
col.Name, errors.Trace(err))
}
// If the column's default value is not ZeroDatetimeStr nor CurrentTimestamp, should convert the default value to the current session time zone.
if needChangeTimeZone {
t := value.GetMysqlTime()
err = t.ConvertTimeZone(sc.TimeZone, ctx.GetSessionVars().Location())
if err != nil {
return value, errors.Trace(err)
}
value.SetMysqlTime(t)
}
return value, nil
}
Expand Down

0 comments on commit 9436866

Please sign in to comment.