diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index 96a3dc71046..97fd959b048 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -67,6 +67,8 @@ t CREATE TABLE `t` ( alter table t drop system versioning; ERROR HY000: System versioning field `trx_start` exists alter table t drop column trx_start, drop column trx_end; +select row_start from t; +row_start alter table t drop system versioning; show create table t; Table Create Table @@ -133,12 +135,17 @@ with system versioning; select * from t for system_time all; a alter table t drop column row_start; -ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN row_end' +ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_end`' alter table t drop column row_end; -ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN row_start' +ERROR HY000: Wrong parameters for `t`: missing 'DROP COLUMN `row_start`' alter table t drop column row_start, drop column row_end; select * from t for system_time all; a +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING alter table t drop column row_start; ERROR 42000: Can't DROP COLUMN `row_start`; check that it exists alter table t drop column row_end; diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result index 940a6479934..74b75bfa154 100644 --- a/mysql-test/suite/versioning/r/trx_id.result +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -65,7 +65,7 @@ period for system_time (sys_start, sys_end) ) engine innodb with system versioning; insert into t1 values (1); alter table t1 drop column sys_start, drop column sys_end; -select sys_end = 18446744073709551615 as transaction_based from t1 for system_time all; +select row_end = 18446744073709551615 as transaction_based from t1 for system_time all; transaction_based 1 drop table t1; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index faedbc0bd72..4f71345e1e8 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -57,6 +57,7 @@ show create table t; alter table t drop system versioning; alter table t drop column trx_start, drop column trx_end; +select row_start from t; alter table t drop system versioning; show create table t; @@ -95,6 +96,7 @@ alter table t drop column row_start; alter table t drop column row_end; alter table t drop column row_start, drop column row_end; select * from t for system_time all; +show create table t; --error ER_CANT_DROP_FIELD_OR_KEY alter table t drop column row_start; diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test index 933f0618577..edd44822df6 100644 --- a/mysql-test/suite/versioning/t/trx_id.test +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -69,7 +69,7 @@ create or replace table t1 ( ) engine innodb with system versioning; insert into t1 values (1); alter table t1 drop column sys_start, drop column sys_end; -select sys_end = 18446744073709551615 as transaction_based from t1 for system_time all; +select row_end = 18446744073709551615 as transaction_based from t1 for system_time all; drop table t1; drop function check_result; diff --git a/sql/handler.cc b/sql/handler.cc index 4c37e64545c..31cdaa8b18c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7283,60 +7283,6 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, } } - if (alter_info->drop_list.elements) - { - bool done_start= false; - bool done_end= false; - List_iterator it(alter_info->drop_list); - while (Alter_drop *d= it++) - { - const char *name= d->name; - Field *f= NULL; - if (!done_start && is_start(name)) - { - f= share->vers_start_field(); - done_start= true; - } - else if (!done_end && is_end(name)) - { - f= share->vers_end_field(); - done_end= true; - } - else - continue; - if (f->invisible > INVISIBLE_USER) - { - my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), d->type_name(), name); - return true; - } - - bool integer= table->vers_start_field()->type() == MYSQL_TYPE_LONGLONG; - Create_field *field= vers_init_sys_field(thd, name, f->flags & VERS_SYSTEM_FIELD, integer); - if (!field) - return true; - - field->change= f->field_name; - - alter_info->flags|= Alter_info::ALTER_CHANGE_COLUMN; - alter_info->create_list.push_back(field); - - it.remove(); - - if (done_start && done_end) - break; - } - - if ((done_start || done_end) && done_start != done_end) - { - String tmp; - tmp.append("DROP COLUMN "); - tmp.append(done_start ? &table->vers_end_field()->field_name - : &table->vers_start_field()->field_name); - my_error(ER_MISSING, MYF(0), table_name, tmp.c_ptr()); - return true; - } - } - return false; } @@ -7369,7 +7315,7 @@ Vers_parse_info::fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_ int remove= 2; while (remove && (f= it++)) { - if (f->flags & (VERS_SYS_START_FLAG|VERS_SYS_END_FLAG)) + if (f->flags & VERS_SYSTEM_FIELD) { it.remove(); remove--; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 489318ef98d..e9ca9b333f1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7868,7 +7868,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, List new_constraint_list; uint db_create_options= (table->s->db_create_options & ~(HA_OPTION_PACK_RECORD)); - uint used_fields; + uint used_fields, dropped_sys_vers_fields= 0; KEY *key_info=table->key_info; bool rc= TRUE; bool modified_primary_key= FALSE; @@ -7950,7 +7950,15 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, !my_strcasecmp(system_charset_info,field->field_name.str, drop->name)) break; } - if (drop && field->invisible < INVISIBLE_SYSTEM) + /* + DROP COLULMN xxx + 1. it does not see INVISIBLE_SYSTEM columns + 2. otherwise, normally a column is dropped + 3. unless it's a system versioning column (but see below). + */ + if (drop && field->invisible < INVISIBLE_SYSTEM && + !(field->flags & VERS_SYSTEM_FIELD && + !(alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING))) { /* Reset auto_increment value if it was dropped */ if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && @@ -7966,7 +7974,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, bitmap_set_bit(dropped_fields, field->field_index); continue; } - if (!drop && field->invisible == INVISIBLE_SYSTEM && + /* invisible versioning column is dropped automatically on DROP SYSTEM VERSIONING */ + if (!drop && field->invisible >= INVISIBLE_SYSTEM && field->flags & VERS_SYSTEM_FIELD && alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING) { @@ -8016,6 +8025,22 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, my_error(ER_VERS_SYS_FIELD_EXISTS, MYF(0), field->field_name.str); goto err; } + else if (drop && field->invisible < INVISIBLE_SYSTEM && + field->flags & VERS_SYSTEM_FIELD && + !(alter_info->flags & Alter_info::ALTER_DROP_SYSTEM_VERSIONING)) + { + /* "dropping" a versioning field only hides it from the user */ + def= new (thd->mem_root) Create_field(thd, field, field); + def->invisible= INVISIBLE_SYSTEM; + dropped_sys_vers_fields|= field->flags; + alter_info->flags|= Alter_info::ALTER_CHANGE_COLUMN; + if (field->flags & VERS_SYS_START_FLAG) + create_info->vers_info.as_row.start= def->field_name= Vers_parse_info::default_start; + else + create_info->vers_info.as_row.end= def->field_name= Vers_parse_info::default_end; + new_create_list.push_back(def, thd->mem_root); + drop_it.remove(); + } else { /* @@ -8042,6 +8067,18 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } } + if (dropped_sys_vers_fields && + ((dropped_sys_vers_fields & VERS_SYSTEM_FIELD) != VERS_SYSTEM_FIELD)) + { + StringBuffer tmp; + tmp.append(STRING_WITH_LEN("DROP COLUMN ")); + if (dropped_sys_vers_fields & VERS_SYS_START_FLAG) + append_identifier(thd, &tmp, &table->vers_end_field()->field_name); + else + append_identifier(thd, &tmp, &table->vers_start_field()->field_name); + my_error(ER_MISSING, MYF(0), table->s->table_name.str, tmp.c_ptr()); + goto err; + } def_it.rewind(); while ((def=def_it++)) // Add new columns {