diff options
-rw-r--r-- | mysql-test/suite/versioning/r/alter.result | 70 | ||||
-rw-r--r-- | mysql-test/suite/versioning/t/alter.test | 32 | ||||
-rw-r--r-- | sql/handler.cc | 31 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 19 |
6 files changed, 156 insertions, 2 deletions
diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index 5db4020f7f2..d9353f957dd 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -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; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 2fdd59979dc..99d200c93f0 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -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; diff --git a/sql/handler.cc b/sql/handler.cc index 98f558f50cc..c19d04236d7 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -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 diff --git a/sql/handler.h b/sql/handler.h index 56ee1addd6d..e20f95df1f3 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -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, diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9ad37134c86..b5cf35ed17c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -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 */ diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 85f0ce2c9e6..810e285da26 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -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: { |