From 105b879d0f541f049a131a5c3b99d678fc7d3213 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sat, 4 Apr 2020 00:53:37 +0300 Subject: MDEV-21941 RENAME doesn't work for system time or period fields - Ignore system-invisible fields (as well as for setting default value); - Handle rename of system time and period fields. --- mysql-test/suite/period/r/alter.result | 17 +++++++++++++++++ mysql-test/suite/period/t/alter.test | 14 ++++++++++++++ mysql-test/suite/versioning/r/alter.result | 23 +++++++++++++++++++++++ mysql-test/suite/versioning/t/alter.test | 21 +++++++++++++++++++++ sql/sql_table.cc | 24 ++++++++++++++++++++---- sql/table.h | 27 +++++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/period/r/alter.result b/mysql-test/suite/period/r/alter.result index e202ba2698f..b2fd85a66fc 100644 --- a/mysql-test/suite/period/r/alter.result +++ b/mysql-test/suite/period/r/alter.result @@ -174,3 +174,20 @@ alter table t add constraint mytime_1 check (x > 2); insert t values (3, @e, @s); ERROR 23000: CONSTRAINT `mytime_2` failed for `test`.`t` drop table t; +# +# MDEV-21941 RENAME doesn't work for system time or period fields +# +create or replace table t1 ( +a int, s date, e date, +period for mytime(s, e)); +alter table t1 rename column s to x; +alter table t1 rename column e to y; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `x` date NOT NULL, + `y` date NOT NULL, + PERIOD FOR `mytime` (`x`, `y`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/suite/period/t/alter.test b/mysql-test/suite/period/t/alter.test index 3f45d68cd61..d89b7c93574 100644 --- a/mysql-test/suite/period/t/alter.test +++ b/mysql-test/suite/period/t/alter.test @@ -131,3 +131,17 @@ alter table t add constraint mytime_1 check (x > 2); insert t values (3, @e, @s); drop table t; + +--echo # +--echo # MDEV-21941 RENAME doesn't work for system time or period fields +--echo # +create or replace table t1 ( + a int, s date, e date, + period for mytime(s, e)); + +alter table t1 rename column s to x; +alter table t1 rename column e to y; + +show create table t1; +# cleanup +drop table t1; diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index 6563638c195..c8114822897 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -687,3 +687,26 @@ add column c int without system versioning, change column c c int, change column b b int without system versioning; drop table t; +# +# MDEV-21941 RENAME doesn't work for system time or period fields +# +create or replace table t1 (a int) with system versioning; +alter table t1 rename column row_start to x; +ERROR 42S22: Unknown column 'row_start' in 't1' +create or replace table t1 ( +a int, +row_start timestamp(6) as row start invisible, +row_end timestamp(6) as row end invisible, +period for system_time (row_start, row_end) +) with system versioning; +alter table t1 rename column row_start to x; +alter table t1 rename column row_end to y; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `x` timestamp(6) GENERATED ALWAYS AS ROW START INVISIBLE, + `y` timestamp(6) GENERATED ALWAYS AS ROW END INVISIBLE, + PERIOD FOR SYSTEM_TIME (`x`, `y`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +drop table t1; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 03c821a2254..05e7fbd962f 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -581,3 +581,24 @@ alter table t change column b b int without system versioning; drop table t; + +--echo # +--echo # MDEV-21941 RENAME doesn't work for system time or period fields +--echo # +create or replace table t1 (a int) with system versioning; +--error ER_BAD_FIELD_ERROR +alter table t1 rename column row_start to x; + +create or replace table t1 ( + a int, + row_start timestamp(6) as row start invisible, + row_end timestamp(6) as row end invisible, + period for system_time (row_start, row_end) +) with system versioning; + +alter table t1 rename column row_start to x; +alter table t1 rename column row_end to y; + +show create table t1; +# cleanup +drop table t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index fb459a95e06..58ca31bf933 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8142,6 +8142,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, Field **f_ptr,*field; MY_BITMAP *dropped_fields= NULL; // if it's NULL - no dropped fields bool drop_period= false; + LEX_CSTRING period_start_name; + LEX_CSTRING period_end_name; + if (table->s->period.name) + { + period_start_name= table->s->period_start_field()->field_name; + period_end_name= table->s->period_end_field()->field_name; + } DBUG_ENTER("mysql_prepare_alter_table"); /* @@ -8338,13 +8345,24 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, alter->name.str)) break; } - if (alter) + if (alter && field->invisible < INVISIBLE_SYSTEM) { if (alter->is_rename()) { def->change= alter->name; def->field_name= alter->new_name; column_rename_param.fields.push_back(def); + if (field->flags & VERS_SYS_START_FLAG) + create_info->vers_info.as_row.start= alter->new_name; + else if (field->flags & VERS_SYS_END_FLAG) + create_info->vers_info.as_row.end= alter->new_name; + if (table->s->period.name) + { + if (field == table->period_start_field()) + period_start_name= alter->new_name; + else if (field == table->period_end_field()) + period_end_name= alter->new_name; + } } else { @@ -8804,9 +8822,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } else { - Field *s= table->s->period.start_field(table->s); - Field *e= table->s->period.end_field(table->s); - create_info->period_info.set_period(s->field_name, e->field_name); + create_info->period_info.set_period(period_start_name, period_end_name); create_info->period_info.name= table->s->period.name; } } diff --git a/sql/table.h b/sql/table.h index 310ffb8c704..67127166ffa 100644 --- a/sql/table.h +++ b/sql/table.h @@ -831,14 +831,28 @@ struct TABLE_SHARE Field *vers_start_field() { + DBUG_ASSERT(versioned); return field[vers.start_fieldno]; } Field *vers_end_field() { + DBUG_ASSERT(versioned); return field[vers.end_fieldno]; } + Field *period_start_field() const + { + DBUG_ASSERT(period.name); + return field[period.start_fieldno]; + } + + Field *period_end_field() const + { + DBUG_ASSERT(period.name); + return field[period.end_fieldno]; + } + /** Cache the checked structure of this table. @@ -1625,6 +1639,19 @@ public: return field[s->vers.end_fieldno]; } + Field *period_start_field() const + { + DBUG_ASSERT(s && s->period.name); + return field[s->period.start_fieldno]; + } + + Field *period_end_field() const + { + DBUG_ASSERT(s && s->period.name); + return field[s->period.end_fieldno]; + } + + ulonglong vers_start_id() const; ulonglong vers_end_id() const; -- cgit v1.2.1