MDEV-19906 Port show_old_temporals from MySQL 5.6

Old temporal data types (created with a pre-10.0 version of MariaDB)
are now displayed with a /* mariadb-5.3 */ comment in:

- SHOW CREATE TABLE
- DESCRIBE
- INFORMATION_SCHEMA.COLUMNS.COLUMN_TYPE

For example:

CREATE TABLE `t1` (
  `t0` datetime /* mariadb-5.3 */ DEFAULT NULL,
  `t6` datetime(6) /* mariadb-5.3 */ DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Note, new temporal data types are displayed without a format comment.
This commit is contained in:
Alexander Barkov 2020-01-16 13:29:29 +04:00
parent e7558d4760
commit 6f65931f88
10 changed files with 376 additions and 53 deletions

View file

@ -0,0 +1,237 @@
#
# MDEV-19906 Port show_old_temporals from MySQL 5.6
#
TRUNCATE TABLE mariadb5312_datetime;
SHOW CREATE TABLE mariadb5312_datetime;
Table Create Table
mariadb5312_datetime CREATE TABLE `mariadb5312_datetime` (
`t0` datetime /* mariadb-5.3 */ DEFAULT NULL,
`t1` datetime(1) /* mariadb-5.3 */ DEFAULT NULL,
`t2` datetime(2) /* mariadb-5.3 */ DEFAULT NULL,
`t3` datetime(3) /* mariadb-5.3 */ DEFAULT NULL,
`t4` datetime(4) /* mariadb-5.3 */ DEFAULT NULL,
`t5` datetime(5) /* mariadb-5.3 */ DEFAULT NULL,
`t6` datetime(6) /* mariadb-5.3 */ DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mariadb5312_datetime';
COLUMN_NAME t0
DATA_TYPE datetime
COLUMN_TYPE datetime /* mariadb-5.3 */
COLUMN_NAME t1
DATA_TYPE datetime
COLUMN_TYPE datetime(1) /* mariadb-5.3 */
COLUMN_NAME t2
DATA_TYPE datetime
COLUMN_TYPE datetime(2) /* mariadb-5.3 */
COLUMN_NAME t3
DATA_TYPE datetime
COLUMN_TYPE datetime(3) /* mariadb-5.3 */
COLUMN_NAME t4
DATA_TYPE datetime
COLUMN_TYPE datetime(4) /* mariadb-5.3 */
COLUMN_NAME t5
DATA_TYPE datetime
COLUMN_TYPE datetime(5) /* mariadb-5.3 */
COLUMN_NAME t6
DATA_TYPE datetime
COLUMN_TYPE datetime(6) /* mariadb-5.3 */
DESCRIBE mariadb5312_datetime;
Field t0
Type datetime /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t1
Type datetime(1) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t2
Type datetime(2) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t3
Type datetime(3) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t4
Type datetime(4) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t5
Type datetime(5) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t6
Type datetime(6) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
DROP TABLE mariadb5312_datetime;
TRUNCATE TABLE mariadb5312_timestamp;
SHOW CREATE TABLE mariadb5312_timestamp;
Table Create Table
mariadb5312_timestamp CREATE TABLE `mariadb5312_timestamp` (
`t0` timestamp /* mariadb-5.3 */ NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`t1` timestamp(1) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00 00:00:00.0',
`t2` timestamp(2) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00 00:00:00.00',
`t3` timestamp(3) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00 00:00:00.000',
`t4` timestamp(4) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00 00:00:00.0000',
`t5` timestamp(5) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00 00:00:00.00000',
`t6` timestamp(6) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mariadb5312_timestamp';
COLUMN_NAME t0
DATA_TYPE timestamp
COLUMN_TYPE timestamp /* mariadb-5.3 */
COLUMN_NAME t1
DATA_TYPE timestamp
COLUMN_TYPE timestamp(1) /* mariadb-5.3 */
COLUMN_NAME t2
DATA_TYPE timestamp
COLUMN_TYPE timestamp(2) /* mariadb-5.3 */
COLUMN_NAME t3
DATA_TYPE timestamp
COLUMN_TYPE timestamp(3) /* mariadb-5.3 */
COLUMN_NAME t4
DATA_TYPE timestamp
COLUMN_TYPE timestamp(4) /* mariadb-5.3 */
COLUMN_NAME t5
DATA_TYPE timestamp
COLUMN_TYPE timestamp(5) /* mariadb-5.3 */
COLUMN_NAME t6
DATA_TYPE timestamp
COLUMN_TYPE timestamp(6) /* mariadb-5.3 */
DESCRIBE mariadb5312_timestamp;
Field t0
Type timestamp /* mariadb-5.3 */
Null NO
Key
Default current_timestamp()
Extra on update current_timestamp()
Field t1
Type timestamp(1) /* mariadb-5.3 */
Null NO
Key
Default 0000-00-00 00:00:00.0
Extra
Field t2
Type timestamp(2) /* mariadb-5.3 */
Null NO
Key
Default 0000-00-00 00:00:00.00
Extra
Field t3
Type timestamp(3) /* mariadb-5.3 */
Null NO
Key
Default 0000-00-00 00:00:00.000
Extra
Field t4
Type timestamp(4) /* mariadb-5.3 */
Null NO
Key
Default 0000-00-00 00:00:00.0000
Extra
Field t5
Type timestamp(5) /* mariadb-5.3 */
Null NO
Key
Default 0000-00-00 00:00:00.00000
Extra
Field t6
Type timestamp(6) /* mariadb-5.3 */
Null NO
Key
Default 0000-00-00 00:00:00.000000
Extra
DROP TABLE mariadb5312_timestamp;
TRUNCATE TABLE mariadb5312_time;
SHOW CREATE TABLE mariadb5312_time;
Table Create Table
mariadb5312_time CREATE TABLE `mariadb5312_time` (
`t0` time /* mariadb-5.3 */ DEFAULT NULL,
`t1` time(1) /* mariadb-5.3 */ DEFAULT NULL,
`t2` time(2) /* mariadb-5.3 */ DEFAULT NULL,
`t3` time(3) /* mariadb-5.3 */ DEFAULT NULL,
`t4` time(4) /* mariadb-5.3 */ DEFAULT NULL,
`t5` time(5) /* mariadb-5.3 */ DEFAULT NULL,
`t6` time(6) /* mariadb-5.3 */ DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mariadb5312_time';
COLUMN_NAME t0
DATA_TYPE time
COLUMN_TYPE time /* mariadb-5.3 */
COLUMN_NAME t1
DATA_TYPE time
COLUMN_TYPE time(1) /* mariadb-5.3 */
COLUMN_NAME t2
DATA_TYPE time
COLUMN_TYPE time(2) /* mariadb-5.3 */
COLUMN_NAME t3
DATA_TYPE time
COLUMN_TYPE time(3) /* mariadb-5.3 */
COLUMN_NAME t4
DATA_TYPE time
COLUMN_TYPE time(4) /* mariadb-5.3 */
COLUMN_NAME t5
DATA_TYPE time
COLUMN_TYPE time(5) /* mariadb-5.3 */
COLUMN_NAME t6
DATA_TYPE time
COLUMN_TYPE time(6) /* mariadb-5.3 */
DESCRIBE mariadb5312_time;
Field t0
Type time /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t1
Type time(1) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t2
Type time(2) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t3
Type time(3) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t4
Type time(4) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t5
Type time(5) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
Field t6
Type time(6) /* mariadb-5.3 */
Null YES
Key
Default NULL
Extra
DROP TABLE mariadb5312_time;

View file

@ -0,0 +1,32 @@
--let $MYSQLD_DATADIR= `select @@datadir`
--echo #
--echo # MDEV-19906 Port show_old_temporals from MySQL 5.6
--echo #
--copy_file $MYSQL_TEST_DIR/std_data/mariadb53_temporal/mariadb5312_datetime.frm $MYSQLD_DATADIR/test/mariadb5312_datetime.frm
TRUNCATE TABLE mariadb5312_datetime;
SHOW CREATE TABLE mariadb5312_datetime;
--vertical_results
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mariadb5312_datetime';
DESCRIBE mariadb5312_datetime;
--horizontal_results
DROP TABLE mariadb5312_datetime;
--copy_file $MYSQL_TEST_DIR/std_data/mariadb53_temporal/mariadb5312_timestamp.frm $MYSQLD_DATADIR/test/mariadb5312_timestamp.frm
TRUNCATE TABLE mariadb5312_timestamp;
SHOW CREATE TABLE mariadb5312_timestamp;
--vertical_results
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mariadb5312_timestamp';
DESCRIBE mariadb5312_timestamp;
--horizontal_results
DROP TABLE mariadb5312_timestamp;
--copy_file $MYSQL_TEST_DIR/std_data/mariadb53_temporal/mariadb5312_time.frm $MYSQLD_DATADIR/test/mariadb5312_time.frm
TRUNCATE TABLE mariadb5312_time;
SHOW CREATE TABLE mariadb5312_time;
--vertical_results
SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='mariadb5312_time';
DESCRIBE mariadb5312_time;
--horizontal_results
DROP TABLE mariadb5312_time;

View file

@ -5329,19 +5329,6 @@ void Field_timestamp0::sort_string(uchar *to,uint length __attribute__((unused))
}
void Field_timestamp::sql_type(String &res) const
{
if (!decimals())
{
res.set_ascii(STRING_WITH_LEN("timestamp"));
return;
}
CHARSET_INFO *cs=res.charset();
res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"timestamp(%u)", decimals()));
}
int Field_timestamp0::set_time()
{
set_notnull();
@ -5621,6 +5608,44 @@ void Field_temporal::set_warnings(Sql_condition::enum_warning_level trunc_level,
}
void Field_temporal::sql_type_dec_comment(String &res,
const Name &name,
uint dec,
const Name &comment) const
{
CHARSET_INFO *cs=res.charset();
res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"%.*s(%u)%s%.*s%s",
(uint) name.length(), name.ptr(),
dec,
comment.length() ? " /* " : "",
(uint) comment.length(), comment.ptr(),
comment.length() ? " */" : ""));
}
void Field_temporal::sql_type_comment(String &res,
const Name &name,
const Name &comment) const
{
CHARSET_INFO *cs=res.charset();
res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"%.*s%s%.*s%s",
(uint) name.length(), name.ptr(),
comment.length() ? " /* " : "",
(uint) comment.length(), comment.ptr(),
comment.length() ? " */" : ""));
}
const Name & Field_temporal::type_version_mysql56()
{
DBUG_EXECUTE_IF("sql_type", return Type_handler::version_mysql56(); );
static Name none(NULL, 0);
return none;
}
/*
Store string into a date/time field
@ -5991,17 +6016,6 @@ void Field_time0::sort_string(uchar *to,uint length __attribute__((unused)))
to[2] = ptr[0];
}
void Field_time::sql_type(String &res) const
{
if (decimals() == 0)
{
res.set_ascii(STRING_WITH_LEN("time"));
return;
}
CHARSET_INFO *cs= res.charset();
res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"time(%d)", decimals()));
}
int Field_time_hires::reset()
{
@ -6811,19 +6825,6 @@ void Field_datetime0::sort_string(uchar *to,uint length __attribute__((unused)))
}
void Field_datetime::sql_type(String &res) const
{
if (decimals() == 0)
{
res.set_ascii(STRING_WITH_LEN("datetime"));
return;
}
CHARSET_INFO *cs= res.charset();
res.length(cs->cset->snprintf(cs, (char*) res.ptr(), res.alloced_length(),
"datetime(%u)", decimals()));
}
int Field_datetime::set_time()
{
THD *thd= table->in_use;

View file

@ -2938,6 +2938,22 @@ protected:
set_warnings(level, str, MYSQL_TIME_WARN_TRUNCATED, typestr);
return 1;
}
void sql_type_comment(String &str,
const Name &name,
const Name &comment) const;
void sql_type_dec_comment(String &str,
const Name &name, uint dec,
const Name &comment) const;
void sql_type_opt_dec_comment(String &str,
const Name &name, uint dec,
const Name &comment) const
{
if (dec)
sql_type_dec_comment(str, name, dec, comment);
else
sql_type_comment(str, name, comment);
}
static const Name &type_version_mysql56();
public:
Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
@ -3068,7 +3084,6 @@ public:
int save_in_field(Field *to) override;
longlong val_int() override;
String *val_str(String *, String *) override;
void sql_type(String &str) const override;
bool zero_pack() const override { return false; }
/*
This method is used by storage/perfschema and
@ -3110,6 +3125,11 @@ public:
{ }
enum ha_base_keytype key_type() const override
{ return HA_KEYTYPE_ULONG_INT; }
void sql_type(String &str) const override
{
sql_type_comment(str, Field_timestamp0::type_handler()->name(),
Type_handler::version_mariadb53());
}
double val_real() override
{
return (double) Field_timestamp0::val_int();
@ -3193,6 +3213,11 @@ public:
{
DBUG_ASSERT(dec);
}
void sql_type(String &str) const override
{
sql_type_dec_comment(str, Field_timestamp_hires::type_handler()->name(),
dec, Type_handler::version_mariadb53());
}
bool val_native(Native *to) override;
my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const override;
int cmp(const uchar *,const uchar *) const override;
@ -3219,6 +3244,12 @@ public:
{ return &type_handler_timestamp2; }
enum_field_types binlog_type() const override
{ return MYSQL_TYPE_TIMESTAMP2; }
void sql_type(String &str) const override
{
sql_type_opt_dec_comment(str, Field_timestampf::type_handler()->name(),
dec, type_version_mysql56());
}
enum_conv_type rpl_conv_type_from(const Conv_source &source,
const Relay_log_info *rli,
const Conv_param &param) const override;
@ -3455,7 +3486,6 @@ public:
int store_decimal(const my_decimal *) override;
String *val_str(String *, String *) override;
bool send_binary(Protocol *protocol) override;
void sql_type(String &str) const override;
void set_curdays(THD *thd);
Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
uchar *new_ptr, uint32 length,
@ -3477,6 +3507,11 @@ public:
unireg_check_arg, field_name_arg)
{ }
enum ha_base_keytype key_type() const override { return HA_KEYTYPE_INT24; }
void sql_type(String &str) const override
{
sql_type_comment(str, Field_time0::type_handler()->name(),
Type_handler::version_mariadb53());
}
double val_real() override;
longlong val_int() override;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override;
@ -3532,6 +3567,11 @@ public:
zero_point= sec_part_shift(
((TIME_MAX_VALUE_SECONDS+1LL)*TIME_SECOND_PART_FACTOR), dec);
}
void sql_type(String &str) const override
{
sql_type_dec_comment(str, Field_time_hires::type_handler()->name(),
dec, Type_handler::version_mariadb53());
}
int reset() override;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) override;
int cmp(const uchar *,const uchar *) const override;
@ -3560,6 +3600,11 @@ public:
const Type_handler *type_handler() const override
{ return &type_handler_time2; }
enum_field_types binlog_type() const override { return MYSQL_TYPE_TIME2; }
void sql_type(String &str) const override
{
sql_type_opt_dec_comment(str, Field_timef::type_handler()->name(),
dec, type_version_mysql56());
}
enum_conv_type rpl_conv_type_from(const Conv_source &source,
const Relay_log_info *rli,
const Conv_param &param) const override;
@ -3616,7 +3661,6 @@ public:
int store(longlong nr, bool unsigned_val) override;
int store_time_dec(const MYSQL_TIME *ltime, uint dec) override;
int store_decimal(const my_decimal *) override;
void sql_type(String &str) const override;
int set_time() override;
Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item)
override
@ -3640,6 +3684,11 @@ public:
{}
enum ha_base_keytype key_type() const override
{ return HA_KEYTYPE_ULONGLONG; }
void sql_type(String &str) const override
{
sql_type_comment(str, Field_datetime0::type_handler()->name(),
Type_handler::version_mariadb53());
}
double val_real() override
{
return (double) Field_datetime0::val_int();
@ -3719,6 +3768,11 @@ public:
{
DBUG_ASSERT(dec);
}
void sql_type(String &str) const override
{
sql_type_dec_comment(str, Field_datetime_hires::type_handler()->name(),
dec, Type_handler::version_mariadb53());
}
int cmp(const uchar *,const uchar *) const override;
uint32 pack_length() const override
{ return Type_handler_datetime::hires_bytes(dec); }
@ -3746,6 +3800,11 @@ public:
{ return &type_handler_datetime2; }
enum_field_types binlog_type() const override
{ return MYSQL_TYPE_DATETIME2; }
void sql_type(String &str) const override
{
sql_type_opt_dec_comment(str, Field_datetimef::type_handler()->name(),
dec, type_version_mysql56());
}
enum_conv_type rpl_conv_type_from(const Conv_source &source,
const Relay_log_info *rli,
const Conv_param &param) const override;

View file

@ -2116,12 +2116,6 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
field->sql_type(type);
packet->append(type.ptr(), type.length(), system_charset_info);
DBUG_EXECUTE_IF("sql_type",
packet->append(" /* ");
packet->append(field->type_handler()->version().ptr());
packet->append(" */");
);
if (field->has_charset() && !(sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
{
if (field->charset() != share->table_charset)

View file

@ -1469,13 +1469,13 @@ const Name Type_handler::version() const
return ver;
}
const Name Type_handler::version_mariadb53() const
const Name & Type_handler::version_mariadb53()
{
static const Name ver(STRING_WITH_LEN("mariadb-5.3"));
return ver;
}
const Name Type_handler::version_mysql56() const
const Name & Type_handler::version_mysql56()
{
static const Name ver(STRING_WITH_LEN("mysql-5.6"));
return ver;
@ -3986,9 +3986,9 @@ Field *Type_handler_datetime_common::make_schema_field(MEM_ROOT *root,
bool show_field) const
{
LEX_CSTRING name= def.name();
return new_Field_datetime(root,
addr.ptr(), addr.null_ptr(), addr.null_bit(),
Field::NONE, &name, def.fsp());
return new (root) Field_datetimef(addr.ptr(),
addr.null_ptr(), addr.null_bit(),
Field::NONE, &name, def.fsp());
}

View file

@ -3326,8 +3326,6 @@ class Type_handler
{
Name m_name;
protected:
const Name version_mysql56() const;
const Name version_mariadb53() const;
String *print_item_value_csstr(THD *thd, Item *item, String *str) const;
String *print_item_value_temporal(THD *thd, Item *item, String *str,
const Name &type_name, String *buf) const;
@ -3390,6 +3388,8 @@ public:
static void partition_field_type_not_allowed(const LEX_CSTRING &field_name);
static bool partition_field_check_result_type(Item *item,
Item_result expected_type);
static const Name & version_mysql56();
static const Name & version_mariadb53();
void set_name(Name n) { DBUG_ASSERT(!m_name.ptr()); m_name= n; }
const Name name() const { return m_name; }