1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

SQL: prohibit column conversion to system fields for non-empty table [fixes #310]

This commit is contained in:
Eugene Kosov
2017-11-20 18:34:25 +03:00
committed by Aleksey Midenkov
parent 00b98264a8
commit 91ba4f04be
6 changed files with 58 additions and 3 deletions

View File

@ -593,6 +593,19 @@ alter table t add column b int;
select * from t for system_time all; select * from t for system_time all;
a b a b
2 NULL 2 NULL
create or replace table non_empty (
a int,
sys_trx_start bigint(20) unsigned,
sys_trx_end bigint(20) unsigned
) engine innodb;
insert into non_empty values (1, 100, 200);
alter table non_empty
change column sys_trx_start sys_trx_start bigint(20) unsigned generated always as row start;
ERROR HY000: Can not modify column `sys_trx_start` to GENERATED ALWAYS AS ROW START/END for non-empty table
alter table non_empty
change column sys_trx_end sys_trx_end bigint(20) unsigned generated always as row end;
ERROR HY000: Can not modify column `sys_trx_end` to GENERATED ALWAYS AS ROW START/END for non-empty table
drop table non_empty;
call verify_vtq; call verify_vtq;
No A B C D No A B C D
1 1 1 1 1 1 1 1 1 1

View File

@ -282,6 +282,21 @@ select * from t for system_time all;
alter table t add column b int; alter table t add column b int;
select * from t for system_time all; select * from t for system_time all;
create or replace table non_empty (
a int,
sys_trx_start bigint(20) unsigned,
sys_trx_end bigint(20) unsigned
) engine innodb;
insert into non_empty values (1, 100, 200);
--error ER_VERS_GENERATED_ALWAYS_NOT_EMPTY
alter table non_empty
change column sys_trx_start sys_trx_start bigint(20) unsigned generated always as row start;
--error ER_VERS_GENERATED_ALWAYS_NOT_EMPTY
alter table non_empty
change column sys_trx_end sys_trx_end bigint(20) unsigned generated always as row end;
drop table non_empty;
call verify_vtq; call verify_vtq;
drop table t; drop table t;

View File

@ -6913,8 +6913,9 @@ static bool add_field_to_drop_list(THD *thd, Alter_info *alter_info,
bool Vers_parse_info::check_and_fix_alter(THD *thd, Alter_info *alter_info, bool Vers_parse_info::check_and_fix_alter(THD *thd, Alter_info *alter_info,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
TABLE_SHARE *share) TABLE *table)
{ {
TABLE_SHARE *share= table->s;
bool integer_fields= bool integer_fields=
create_info->db_type->flags & HTON_NATIVE_SYS_VERSIONING; create_info->db_type->flags & HTON_NATIVE_SYS_VERSIONING;
const char *table_name= share->table_name.str; const char *table_name= share->table_name.str;
@ -6950,6 +6951,29 @@ bool Vers_parse_info::check_and_fix_alter(THD *thd, Alter_info *alter_info,
return false; return false;
} }
{
List_iterator_fast<Create_field> it(alter_info->create_list);
while (Create_field *f= it++)
{
if (f->change.length &&
f->flags & (VERS_SYS_START_FLAG | VERS_SYS_END_FLAG))
{
if (thd->mdl_context.upgrade_shared_lock(
table->mdl_ticket, MDL_EXCLUSIVE,
thd->variables.lock_wait_timeout))
return true;
if (table->file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME))
return true;
if (0 < table->file->records())
{
my_error(ER_VERS_GENERATED_ALWAYS_NOT_EMPTY, MYF(0), f->change.str);
return true;
}
break;
}
}
}
if ((versioned_fields || unversioned_fields) && !share->versioned) if ((versioned_fields || unversioned_fields) && !share->versioned)
{ {
my_error_as(ER_VERS_WRONG_PARAMS, ER_VERS_NOT_VERSIONED, MYF(0), table_name); my_error_as(ER_VERS_WRONG_PARAMS, ER_VERS_NOT_VERSIONED, MYF(0), table_name);

View File

@ -1745,7 +1745,7 @@ public:
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
const char *table_name); const char *table_name);
bool check_and_fix_alter(THD *thd, Alter_info *alter_info, bool check_and_fix_alter(THD *thd, Alter_info *alter_info,
HA_CREATE_INFO *create_info, TABLE_SHARE *share); HA_CREATE_INFO *create_info, TABLE *table);
bool fix_create_like(THD *thd, Alter_info *alter_info, bool fix_create_like(THD *thd, Alter_info *alter_info,
HA_CREATE_INFO *create_info, TABLE_LIST *table); HA_CREATE_INFO *create_info, TABLE_LIST *table);

View File

@ -7907,3 +7907,6 @@ ER_VERS_SYS_FIELD_NOT_HIDDEN
ER_NOT_LOG_TABLE ER_NOT_LOG_TABLE
eng "Table `%s.%s` is not a log table" eng "Table `%s.%s` is not a log table"
ER_VERS_GENERATED_ALWAYS_NOT_EMPTY
eng "Can not modify column `%s` to GENERATED ALWAYS AS ROW START/END for non-empty table"

View File

@ -8977,7 +8977,7 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
DBUG_RETURN(true); DBUG_RETURN(true);
if (create_info->vers_info.check_and_fix_alter(thd, alter_info, create_info, if (create_info->vers_info.check_and_fix_alter(thd, alter_info, create_info,
table->s)) table))
{ {
DBUG_RETURN(true); DBUG_RETURN(true);
} }