diff --git a/mysql-test/include/have_innodb.combinations b/mysql-test/include/have_innodb.combinations index ac760f7fcad..f1131c448f3 100644 --- a/mysql-test/include/have_innodb.combinations +++ b/mysql-test/include/have_innodb.combinations @@ -6,6 +6,7 @@ innodb-cmpmem innodb-cmp-per-index innodb-trx innodb-locks +innodb-lock-waits innodb-buffer-pool-stats innodb-buffer-page innodb-buffer-page-lru @@ -24,6 +25,7 @@ innodb-cmpmem innodb-cmp-per-index innodb-trx innodb-locks +innodb-lock-waits innodb-metrics innodb-buffer-pool-stats innodb-buffer-page diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result index cd6f300d907..7df786c45d1 100644 --- a/mysql-test/suite/versioning/r/insert.result +++ b/mysql-test/suite/versioning/r/insert.result @@ -371,3 +371,9 @@ create or replace table t1 (pk int primary key) with system versioning; create trigger tr before insert on t1 for each row select 1 into @a; insert into t1 values (1),(2); drop table t1; +create table t1 (pk int primary key, i int) with system versioning; +replace into t1 values (1,10),(1,100),(1,1000); +select pk,i,row_end > '2038-01-01' from t1 for system_time all; +pk i row_end > '2038-01-01' +1 1000 1 +drop table t1; diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index e0daf1d6588..7dd3d6d2124 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -620,6 +620,20 @@ create or replace table t1 (a int primary key, b int) with system versioning engine myisam; insert into t1 (a) values (1); replace t1 values (1,2),(1,3),(2,4); -ERROR 23000: Duplicate entry '1-YYYY-MM-DD hh:mm:ss.uuuuuu' for key 'PRIMARY' +create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) +engine=innodb with system versioning; +insert into t1 (pk) values (1); +connect con1,localhost,root,,test; +start transaction; +select * from t1 for update; +pk a b +1 NULL NULL +connection default; +update t1 set b = 'foo'; +connection con1; +update t1 set a = 'bar'; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +disconnect con1; +connection default; drop database test; create database test; diff --git a/mysql-test/suite/versioning/t/insert.test b/mysql-test/suite/versioning/t/insert.test index b3c344d6f12..01d10c1c21f 100644 --- a/mysql-test/suite/versioning/t/insert.test +++ b/mysql-test/suite/versioning/t/insert.test @@ -267,5 +267,12 @@ select *, row_start > @a, row_end > @a from t1 for system_time all; create or replace table t1 (pk int primary key) with system versioning; create trigger tr before insert on t1 for each row select 1 into @a; insert into t1 values (1),(2); - +drop table t1; + +# +# MDEV-14794 Limitations which the row end as a part of PK imposes due to CURRENT_TIMESTAMP behavior and otherwise +# +create table t1 (pk int primary key, i int) with system versioning; +replace into t1 values (1,10),(1,100),(1,1000); +select pk,i,row_end > '2038-01-01' from t1 for system_time all; drop table t1; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index 60f20705276..5a3034e5cae 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -1,4 +1,4 @@ --- source suite/versioning/common.inc +--source suite/versioning/common.inc delimiter ~~; create procedure test_01( @@ -280,9 +280,30 @@ call verify_vtq; create or replace table t1 (a int primary key, b int) with system versioning engine myisam; insert into t1 (a) values (1); ---replace_regex /'1-[- .\d:]+'/'1-YYYY-MM-DD hh:mm:ss.uuuuuu'/ ---error ER_DUP_ENTRY + replace t1 values (1,2),(1,3),(2,4); +# +# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE +# + +create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) + engine=innodb with system versioning; + +insert into t1 (pk) values (1); +connect (con1,localhost,root,,test); +start transaction; +select * from t1 for update; +connection default; +send update t1 set b = 'foo'; +connection con1; +let $wait_condition= select count(*) from information_schema.innodb_lock_waits; +source include/wait_condition.inc; +error ER_LOCK_DEADLOCK; +update t1 set a = 'bar'; +disconnect con1; +connection default; +reap; + drop database test; create database test; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 84ec1513cf4..809c649a5d1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1640,6 +1640,11 @@ int vers_insert_history_row(TABLE *table) // Set Sys_end to now() table->vers_update_end(); + Field *row_start= table->vers_start_field(); + Field *row_end= table->vers_end_field(); + if (row_start->cmp(row_start->ptr, row_end->ptr) >= 0) + return 0; + return table->file->ha_write_row(table->record[0]); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b5bae06e1fb..38638d3aa1d 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -948,25 +948,22 @@ update_begin: } else if (!error) { - updated++; - if (has_vers_fields && table->versioned()) { if (table->versioned(VERS_TIMESTAMP)) { store_record(table, record[2]); - if ((error = vers_insert_history_row(table))) - { - restore_record(table, record[2]); - break; - } + error= vers_insert_history_row(table); restore_record(table, record[2]); } - updated_sys_ver++; + if (!error) + updated_sys_ver++; } + if (!error) + updated++; } - else if (!ignore || - table->file->is_fatal_error(error, HA_CHECK_ALL)) + + if (error && (!ignore || table->file->is_fatal_error(error, HA_CHECK_ALL))) { /* If (ignore && error is ignorable) we don't have to