From 6d5436ddcd777b7975915ca65aa9c94b5e839520 Mon Sep 17 00:00:00 2001 From: bb7133 Date: Thu, 4 Jul 2019 16:44:12 +0800 Subject: [PATCH] executor, infoschema: fix display of default CURRENT_TIMESTAMP with decimal (#11070) --- executor/show.go | 5 ++++- executor/show_test.go | 39 +++++++++++++++++++++++++++++++++++++++ infoschema/tables_test.go | 36 ++++++++++++++++++++++++++++++++++++ table/column.go | 8 ++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) diff --git a/executor/show.go b/executor/show.go index 77c6aaec37b06..c531f46528b3c 100644 --- a/executor/show.go +++ b/executor/show.go @@ -284,7 +284,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) @@ -563,6 +563,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 9a811ef3fa22a..3d3e263d92f3f 100644 --- a/executor/show_test.go +++ b/executor/show_test.go @@ -562,13 +562,18 @@ func (s *testSuite) 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, @@ -592,13 +597,18 @@ func (s *testSuite) 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 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" + @@ -725,6 +735,35 @@ func (s *testSuite) 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("|", + ""+ + "t CREATE TABLE `t` (\n"+ + " `a` int(11) DEFAULT NULL,\n"+ + " `b` int(11) DEFAULT NULL\n"+ + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin/*!90000 SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=3 */", + )) + tk.MustExec("drop table t") + tk.MustExec("CREATE TABLE `log` (" + "`LOG_ID` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT," + "`ROUND_ID` bigint(20) UNSIGNED NOT NULL," + diff --git a/infoschema/tables_test.go b/infoschema/tables_test.go index 76b34497a548c..c6f0d351e0efa 100644 --- a/infoschema/tables_test.go +++ b/infoschema/tables_test.go @@ -268,6 +268,42 @@ func (s *testTableSuite) TearDownSuite(c *C) { s.store.Close() } +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 da30f968ecf15..229c6af1d4885 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 := ""