Commit dfd42ed9 authored by Sergei Golubchik's avatar Sergei Golubchik

ALTER TABLE ... DROP COLUMN sys_start should rename a "dropped" column

parent c847089e
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......@@ -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<Alter_drop> 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--;
......
......@@ -7868,7 +7868,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
List<Virtual_column_info> 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<NAME_LEN*2> 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
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment