summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/versioning/r/alter.result70
-rw-r--r--mysql-test/suite/versioning/t/alter.test32
-rw-r--r--sql/handler.cc31
-rw-r--r--sql/handler.h2
-rw-r--r--sql/sql_table.cc4
-rw-r--r--storage/innobase/row/row0merge.cc19
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: {