diff --git a/executor/show.go b/executor/show.go index 5618f04b20c75..37fad01831aaf 100644 --- a/executor/show.go +++ b/executor/show.go @@ -402,7 +402,7 @@ func (e *ShowExec) fetchShowColumns() error { // SHOW COLUMNS result expects string value defaultValStr := fmt.Sprintf("%v", desc.DefaultValue) // If column is timestamp, and default value is not current_timestamp, should convert the default value to the current session time zone. - if col.Tp == mysql.TypeTimestamp && defaultValStr != types.ZeroDatetimeStr && strings.ToUpper(defaultValStr) != strings.ToUpper(ast.CurrentTimestamp) { + if col.Tp == mysql.TypeTimestamp && defaultValStr != types.ZeroDatetimeStr && !strings.HasPrefix(strings.ToUpper(defaultValStr), strings.ToUpper(ast.CurrentTimestamp)) { timeValue, err := table.GetColDefaultValue(e.ctx, col.ToInfo()) if err != nil { return errors.Trace(err) @@ -692,6 +692,9 @@ func (e *ShowExec) fetchShowCreateTable() error { } case "CURRENT_TIMESTAMP": buf.WriteString(" DEFAULT CURRENT_TIMESTAMP") + if col.Decimal > 0 { + buf.WriteString(fmt.Sprintf("(%d)", col.Decimal)) + } default: defaultValStr := fmt.Sprintf("%v", defaultValue) // If column is timestamp, and default value is not current_timestamp, should convert the default value to the current session time zone. diff --git a/executor/show_test.go b/executor/show_test.go index c34d357c5f825..a1c8afc6548f6 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -186,13 +186,18 @@ func (s *testSuite2) TestShow2(c *C) { c_nchar national char(1) charset ascii collate ascii_bin, c_binary binary, c_varchar varchar(1) charset ascii collate ascii_bin, + c_varchar_default varchar(20) charset ascii collate ascii_bin default 'cUrrent_tImestamp', c_nvarchar national varchar(1) charset ascii collate ascii_bin, c_varbinary varbinary(1), c_year year, c_date date, c_time time, c_datetime datetime, + c_datetime_default datetime default current_timestamp, + c_datetime_default_2 datetime(2) default current_timestamp(2), c_timestamp timestamp, + c_timestamp_default timestamp default current_timestamp, + c_timestamp_default_3 timestamp(3) default current_timestamp(3), c_blob blob, c_tinyblob tinyblob, c_mediumblob mediumblob, @@ -216,13 +221,18 @@ func (s *testSuite2) TestShow2(c *C) { "[c_nchar char(1) ascii_bin YES select,insert,update,references ]\n" + "[c_binary binary(1) YES select,insert,update,references ]\n" + "[c_varchar varchar(1) ascii_bin YES select,insert,update,references ]\n" + + "[c_varchar_default varchar(20) ascii_bin YES cUrrent_tImestamp select,insert,update,references ]\n" + "[c_nvarchar varchar(1) ascii_bin YES select,insert,update,references ]\n" + "[c_varbinary varbinary(1) YES select,insert,update,references ]\n" + "[c_year year(4) YES select,insert,update,references ]\n" + "[c_date date YES select,insert,update,references ]\n" + "[c_time time YES select,insert,update,references ]\n" + "[c_datetime datetime YES select,insert,update,references ]\n" + + "[c_datetime_default datetime YES CURRENT_TIMESTAMP select,insert,update,references ]\n" + + "[c_datetime_default_2 datetime(2) YES CURRENT_TIMESTAMP(2) select,insert,update,references ]\n" + "[c_timestamp timestamp YES select,insert,update,references ]\n" + + "[c_timestamp_default timestamp YES CURRENT_TIMESTAMP select,insert,update,references ]\n" + + "[c_timestamp_default_3 timestamp(3) YES CURRENT_TIMESTAMP(3) select,insert,update,references ]\n" + "[c_blob blob YES select,insert,update,references ]\n" + "[c_tinyblob tinyblob YES select,insert,update,references ]\n" + "[c_mediumblob mediumblob YES select,insert,update,references ]\n" + @@ -451,6 +461,25 @@ func (s *testSuite2) TestShowCreateTable(c *C) { ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", )) + tk.MustExec("drop table if exists t") + tk.MustExec("create table `t` (\n" + + "`a` timestamp not null default current_timestamp,\n" + + "`b` timestamp(3) default current_timestamp(3),\n" + + "`c` datetime default current_timestamp,\n" + + "`d` datetime(4) default current_timestamp(4),\n" + + "`e` varchar(20) default 'cUrrent_tImestamp')") + tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|", + ""+ + "t CREATE TABLE `t` (\n"+ + " `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"+ + " `b` timestamp(3) DEFAULT CURRENT_TIMESTAMP(3),\n"+ + " `c` datetime DEFAULT CURRENT_TIMESTAMP,\n"+ + " `d` datetime(4) DEFAULT CURRENT_TIMESTAMP(4),\n"+ + " `e` varchar(20) DEFAULT 'cUrrent_tImestamp'\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin", + )) + tk.MustExec("drop table t") + tk.MustExec("create table t (a int, b int) shard_row_id_bits = 4 pre_split_regions=3;") tk.MustQuery("show create table `t`").Check(testutil.RowsWithSep("|", ""+ diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 057ec4082ed25..ce102e67bc1a0 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -241,6 +241,42 @@ func (s *testTableSuite) TestCharacterSetCollations(c *C) { tk.MustExec("DROP DATABASE charset_collate_test") } +func (s *testTableSuite) TestCurrentTimestampAsDefault(c *C) { + tk := testkit.NewTestKit(c, s.store) + + tk.MustExec("DROP DATABASE IF EXISTS default_time_test") + tk.MustExec("CREATE DATABASE default_time_test; USE default_time_test") + + tk.MustExec(`CREATE TABLE default_time_table( + c_datetime datetime, + c_datetime_default datetime default current_timestamp, + c_datetime_default_2 datetime(2) default current_timestamp(2), + c_timestamp timestamp, + c_timestamp_default timestamp default current_timestamp, + c_timestamp_default_3 timestamp(3) default current_timestamp(3), + c_varchar_default varchar(20) default "current_timestamp", + c_varchar_default_3 varchar(20) default "current_timestamp(3)", + c_varchar_default_with_case varchar(20) default "cUrrent_tImestamp" + );`) + + tk.MustQuery(`SELECT column_name, column_default + FROM information_schema.COLUMNS + WHERE table_schema = "default_time_test" AND table_name = "default_time_table" + ORDER BY column_name`, + ).Check(testkit.Rows( + "c_datetime ", + "c_datetime_default CURRENT_TIMESTAMP", + "c_datetime_default_2 CURRENT_TIMESTAMP(2)", + "c_timestamp ", + "c_timestamp_default CURRENT_TIMESTAMP", + "c_timestamp_default_3 CURRENT_TIMESTAMP(3)", + "c_varchar_default current_timestamp", + "c_varchar_default_3 current_timestamp(3)", + "c_varchar_default_with_case cUrrent_tImestamp", + )) + tk.MustExec("DROP DATABASE default_time_test") +} + type mockSessionManager struct { processInfoMap map[uint64]*util.ProcessInfo } diff --git a/table/column.go b/table/column.go index ce9fb65454673..08f4884ad5d9c 100644 --- a/table/column.go +++ b/table/column.go @@ -19,6 +19,7 @@ package table import ( "context" + "fmt" "strings" "time" "unicode/utf8" @@ -256,6 +257,13 @@ func NewColDesc(col *Column) *ColDesc { var defaultValue interface{} if !mysql.HasNoDefaultValueFlag(col.Flag) { defaultValue = col.GetDefaultValue() + if defaultValStr, ok := defaultValue.(string); ok { + if (col.Tp == mysql.TypeTimestamp || col.Tp == mysql.TypeDatetime) && + strings.ToUpper(defaultValStr) == strings.ToUpper(ast.CurrentTimestamp) && + col.Decimal > 0 { + defaultValue = fmt.Sprintf("%s(%d)", defaultValStr, col.Decimal) + } + } } extra := ""