SQL, IB: ALTER ADD AUTO_INCREMENT for versioned tables [closes #112]

This commit is contained in:
kevg 2017-01-10 15:15:39 +03:00 committed by Aleksey Midenkov
parent c9e4ac4b72
commit 57692d7117
6 changed files with 156 additions and 2 deletions

View file

@ -353,6 +353,70 @@ Table Create Table
t CREATE TABLE `t` (
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
create or replace table t (a int) with system versioning engine=innodb;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b int auto_increment unique;
select * from t for system_time all;
a b
1 -1
2 -2
3 1
insert into t values (4, NULL);
select * from t for system_time all;
a b
1 -1
2 -2
3 1
4 2
create or replace table t (a int) with system versioning;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b int auto_increment unique;
select * from t for system_time all;
a b
1 -1
2 -2
3 1
insert into t values (4, NULL);
select * from t for system_time all;
a b
1 -1
2 -2
3 1
4 2
create or replace table t (a int) with system versioning engine=innodb;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b tinyint auto_increment unique;
select * from t for system_time all;
a b
1 -1
2 -2
3 1
insert into t values (4, NULL);
select * from t for system_time all;
a b
1 -1
2 -2
3 1
4 2
create or replace table t (a int) with system versioning;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b tinyint auto_increment unique;
select * from t for system_time all;
a b
1 -1
2 -2
3 1
insert into t values (4, NULL);
select * from t for system_time all;
a b
1 -1
2 -2
3 1
4 2
call verify_vtq;
No A B C D
1 1 1 1 1
@ -360,5 +424,11 @@ No A B C D
3 1 1 1 1
4 1 1 1 1
5 1 1 1 1
6 1 1 1 1
7 1 1 1 1
8 1 1 1 1
9 1 1 1 1
10 1 1 1 1
11 1 1 1 1
drop table t;
drop procedure verify_vtq;

View file

@ -165,6 +165,38 @@ alter table t without system versioning, algorithm=inplace;
alter table t without system versioning, algorithm=copy;
show create table t;
create or replace table t (a int) with system versioning engine=innodb;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b int auto_increment unique;
select * from t for system_time all;
insert into t values (4, NULL);
select * from t for system_time all;
create or replace table t (a int) with system versioning;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b int auto_increment unique;
select * from t for system_time all;
insert into t values (4, NULL);
select * from t for system_time all;
create or replace table t (a int) with system versioning engine=innodb;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b tinyint auto_increment unique;
select * from t for system_time all;
insert into t values (4, NULL);
select * from t for system_time all;
create or replace table t (a int) with system versioning;
insert into t values (1), (2), (3);
delete from t where a<3;
alter table t add b tinyint auto_increment unique;
select * from t for system_time all;
insert into t values (4, NULL);
select * from t for system_time all;
call verify_vtq;
drop table t;
drop procedure verify_vtq;

View file

@ -3023,6 +3023,35 @@ int handler::update_auto_increment()
enum enum_check_fields save_count_cuted_fields;
DBUG_ENTER("handler::update_auto_increment");
if (table->versioned_by_sql())
{
Field *end= table->vers_end_field();
DBUG_ASSERT(end);
bitmap_set_bit(table->read_set, end->field_index);
if (!end->is_max())
{
uchar *ptr= table->next_number_field->ptr;
switch (table->next_number_field->pack_length())
{
case 8:
int8store(ptr, vers_auto_decrement--);
break;
case 4:
int4store(ptr, vers_auto_decrement--);
break;
case 2:
int2store(ptr, vers_auto_decrement--);
break;
case 1:
*ptr= vers_auto_decrement--;
break;
default:
DBUG_ASSERT(false);
}
DBUG_RETURN(0);
}
}
/*
next_insert_id is a "cursor" into the reserved interval, it may go greater
than the interval, but not smaller.
@ -3145,7 +3174,7 @@ int handler::update_auto_increment()
/* Store field without warning (Warning will be printed by insert) */
save_count_cuted_fields= thd->count_cuted_fields;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
tmp= table->next_number_field->store((longlong) nr, TRUE);
tmp= table->next_number_field->store((longlong)nr, TRUE);
thd->count_cuted_fields= save_count_cuted_fields;
if (unlikely(tmp)) // Out of range value in store

View file

@ -2835,6 +2835,8 @@ public:
*/
uint auto_inc_intervals_count;
ulonglong vers_auto_decrement;
/**
Instrumented table associated with this handler.
This member should be set to NULL when no instrumentation is in place,

View file

@ -9777,6 +9777,10 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
{
from_sys_trx_end= from->field[from->s->row_end_field];
}
else if (from->versioned() && to->versioned())
{
to->file->vers_auto_decrement= 0xffffffffffffffff;
}
THD_STAGE_INFO(thd, stage_copy_to_tmp_table);
/* Tell handler that we have values for all columns in the to table */

View file

@ -1832,6 +1832,7 @@ row_merge_read_clustered_index(
double curr_progress = 0.0;
ib_uint64_t read_rows = 0;
ib_uint64_t table_total_rows = 0;
ulonglong historic_auto_decrement = 0xffffffffffffffff;
DBUG_ENTER("row_merge_read_clustered_index");
@ -2236,6 +2237,18 @@ end_of_index:
ut_ad(add_autoinc
< dict_table_get_n_user_cols(new_table));
bool row_is_historic = false;
if (DICT_TF2_FLAG_IS_SET(
new_table, DICT_TF2_VERSIONED)) {
const dfield_t *dfield = dtuple_get_nth_field(
row, new_table->vers_row_end);
const byte *data = static_cast<const byte *>(
dfield_get_data(dfield));
ut_ad(dfield_get_len(dfield) == 8);
row_is_historic =
mach_read_from_8(data) != TRX_ID_MAX;
}
const dfield_t* dfield;
dfield = dtuple_get_nth_field(row, add_autoinc);
@ -2256,7 +2269,11 @@ end_of_index:
goto func_exit;
}
ulonglong value = sequence++;
ulonglong value;
if (likely(!row_is_historic))
value = sequence++;
else
value = historic_auto_decrement--;
switch (dtype_get_mtype(dtype)) {
case DATA_INT: {