diff --git a/mysql-test/suite/versioning/r/insert.result b/mysql-test/suite/versioning/r/insert.result index 52f6e8824e5..dbeb6028bcd 100644 --- a/mysql-test/suite/versioning/r/insert.result +++ b/mysql-test/suite/versioning/r/insert.result @@ -343,3 +343,15 @@ drop procedure test_02; drop procedure test_03; drop procedure test_04; drop procedure test_05; +set timestamp=1000000019; +select now() < sysdate(); +now() < sysdate() +1 +create table t1 (a int) with system versioning; +insert t1 values (1); +select * from t1 for system_time as of now(6); +a +select * from t1 for system_time as of sysdate(6); +a +1 +drop table t1; diff --git a/mysql-test/suite/versioning/t/insert.test b/mysql-test/suite/versioning/t/insert.test index c24d6bca398..9c1dd6d6257 100644 --- a/mysql-test/suite/versioning/t/insert.test +++ b/mysql-test/suite/versioning/t/insert.test @@ -240,3 +240,14 @@ drop procedure test_04; drop procedure test_05; -- source suite/versioning/common_finish.inc + +# +# MDEV-14788 System versioning cannot be based on local timestamps, as it is now +# +set timestamp=1000000019; +select now() < sysdate(); +create table t1 (a int) with system versioning; +insert t1 values (1); +select * from t1 for system_time as of now(6); +select * from t1 for system_time as of sysdate(6); +drop table t1; diff --git a/sql/sql_class.h b/sql/sql_class.h index 8b3861567f6..48b64d8c741 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2358,6 +2358,8 @@ public: // track down slow pthread_create ulonglong prior_thr_create_utime, thr_create_utime; ulonglong utime_after_query; + my_time_t system_time; + ulong system_time_sec_part; // Process indicator struct { @@ -3377,36 +3379,37 @@ public: MYSQL_TIME query_start_TIME(); private: - void start_time_inc() + bool system_time_ge(my_time_t secs, ulong usecs) { - ++start_time_sec_part; - if (start_time_sec_part == HRTIME_RESOLUTION) - { - ++start_time; - start_time_sec_part= 0; - } + return (system_time == secs && system_time_sec_part >= usecs) || + system_time > secs; } - bool start_time_ge(my_time_t secs, ulong usecs) - { - return (start_time == secs && start_time_sec_part >= usecs) || - start_time > secs; - } - - void set_current_time() + void set_system_time() { my_hrtime_t hrtime= my_hrtime(); my_time_t secs= hrtime_to_my_time(hrtime); ulong usecs= hrtime_sec_part(hrtime); - if (start_time_ge(secs, usecs)) + if (system_time_ge(secs, usecs)) { - start_time_inc(); + if (++system_time_sec_part == HRTIME_RESOLUTION) + { + ++system_time; + system_time_sec_part= 0; + } } else { - start_time= secs; - start_time_sec_part= usecs; + system_time= secs; + system_time_sec_part= usecs; } + } + + void set_current_time() + { + set_system_time(); + start_time= system_time; + start_time_sec_part= system_time_sec_part; PSI_CALL_set_thread_start_time(start_time); } @@ -3415,6 +3418,7 @@ public: { if (user_time.val) { + set_system_time(); start_time= hrtime_to_my_time(user_time); start_time_sec_part= hrtime_sec_part(user_time); PSI_CALL_set_thread_start_time(start_time); diff --git a/sql/table.cc b/sql/table.cc index a6f58440396..052b3e2fe01 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -7768,7 +7768,9 @@ void TABLE::vers_update_fields() { if (!vers_write) return; - if (vers_start_field()->set_time()) + vers_start_field()->set_notnull(); + if (vers_start_field()->store_timestamp(in_use->system_time, + in_use->system_time_sec_part)) DBUG_ASSERT(0); } else @@ -8620,9 +8622,9 @@ bool TR_table::update(ulonglong start_id, ulonglong end_id) if (!table && open()) return true; - timeval start_time= {thd->start_time, long(thd->start_time_sec_part)}; + timeval start_time= {thd->system_time, long(thd->system_time_sec_part)}; thd->set_start_time(); - timeval end_time= {thd->start_time, long(thd->start_time_sec_part)}; + timeval end_time= {thd->system_time, long(thd->system_time_sec_part)}; store(FLD_TRX_ID, start_id); store(FLD_COMMIT_ID, end_id); store(FLD_BEGIN_TS, start_time);