summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/versioning/r/partition.result146
-rw-r--r--mysql-test/suite/versioning/t/partition.combinations3
-rw-r--r--mysql-test/suite/versioning/t/partition.test58
-rw-r--r--sql/partition_info.cc1
-rw-r--r--storage/innobase/handler/ha_innodb.cc8
-rw-r--r--storage/innobase/handler/ha_innodb.h5
-rw-r--r--storage/innobase/handler/ha_innopart.h40
7 files changed, 236 insertions, 25 deletions
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result
index f4c8ce3b286..ff9f583042a 100644
--- a/mysql-test/suite/versioning/r/partition.result
+++ b/mysql-test/suite/versioning/r/partition.result
@@ -1,3 +1,65 @@
+set @@session.time_zone='+00:00';
+select ifnull(max(trx_id), 0) into @start_trx_id from information_schema.innodb_vtq;
+create procedure if not exists verify_vtq()
+begin
+set @i= 0;
+select
+@i:= @i + 1 as No,
+trx_id > 0 as A,
+commit_id >= trx_id as B,
+begin_ts > '1-1-1 0:0:0' as C,
+commit_ts > begin_ts as D
+from information_schema.innodb_vtq
+where trx_id > @start_trx_id;
+select ifnull(max(trx_id), 0)
+into @start_trx_id
+from information_schema.innodb_vtq;
+end~~
+create function if not exists default_engine()
+returns varchar(255)
+deterministic
+begin
+declare e varchar(255);
+select lower(engine) from information_schema.engines where support='DEFAULT' into e;
+return e;
+end~~
+create function if not exists sys_datatype()
+returns varchar(255)
+deterministic
+begin
+if default_engine() = 'innodb' then
+return 'bigint unsigned';
+elseif default_engine() = 'myisam' then
+return 'timestamp(6)';
+end if;
+return NULL;
+end~~
+create function if not exists sys_commit_ts(sys_field varchar(255))
+returns varchar(255)
+deterministic
+begin
+if default_engine() = 'innodb' then
+return concat('vtq_commit_ts(', sys_field, ')');
+elseif default_engine() = 'myisam' then
+return sys_field;
+end if;
+return NULL;
+end~~
+create procedure if not exists innodb_verify_vtq(recs int)
+begin
+declare i int default 1;
+if default_engine() = 'innodb' then
+call verify_vtq;
+elseif default_engine() = 'myisam' then
+create temporary table tmp (No int, A bool, B bool, C bool, D bool);
+while i <= recs do
+insert into tmp values (i, 1, 1, 1, 1);
+set i= i + 1;
+end while;
+select * from tmp;
+drop table tmp;
+end if;
+end~~
create table t1 (x int)
with system versioning
partition by range columns (x) (
@@ -90,21 +152,78 @@ ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: `AS OF NOW` partition can no
alter table t1 drop partition p1;
alter table t1 drop partition p0;
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: one `AS OF NOW` and at least one `VERSIONING` partition required
+set @now= now(6);
insert into t1 values (1);
-select * from t1;
-x
+set @ts_start= sys_commit_ts('sys_trx_start');
+set @ts_end= sys_commit_ts('sys_trx_end');
+set @str= concat('select x, ', @ts_start, ' < @now as A, ', @ts_end, ' > @now as B from t1 partition (p0) for system_time all');
+prepare select_p0 from @str;
+set @str= concat('select x, ', @ts_start, ' > @now as C, ', @ts_end, ' = timestamp\'2038-01-19 03:14:07\' as D from t1 partition (pn) for system_time all');
+prepare select_pn from @str;
+execute select_p0;
+x A B
+execute select_pn;
+x C D
+1 1 1
+set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @now= now(6);
+delete from t1;
+execute select_p0;
+x A B
+1 1 1
+execute select_pn;
+x C D
+set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all into @ts1');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+select @ts0 = @ts1;
+@ts0 = @ts1
1
-select * from t1 partition (p0);
-x
-select * from t1 partition (pn);
-x
+set @now= now(6);
+insert into t1 values (2);
+execute select_p0;
+x A B
+1 1 0
+execute select_pn;
+x C D
+2 1 1
+set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @now= now(6);
+update t1 set x = x + 1;
+execute select_p0;
+x A B
+1 1 0
+2 1 1
+execute select_pn;
+x C D
+3 1 1
+drop prepare select_p0;
+drop prepare select_pn;
+set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all where x = 2 into @ts1');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @str= concat('select ', @ts_end, ' from t1 partition (p0) for system_time all where x = 2 into @ts2');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts3');
+prepare stmt from @str;
+execute stmt;
+drop prepare stmt;
+select @ts0 = @ts1;
+@ts0 = @ts1
1
-delete from t1;
-select * from t1 partition (p0) for system_time all;
-x
+select @ts2 = @ts3;
+@ts2 = @ts3
1
-select * from t1 partition (pn) for system_time all;
-x
create or replace table t1 (x int)
with system versioning
partition by system_time limit 1 (
@@ -190,3 +309,8 @@ select * from t1 partition (p1sp1) for system_time all;
x
2
drop table t1;
+drop procedure verify_vtq;
+drop procedure innodb_verify_vtq;
+drop function default_engine;
+drop function sys_commit_ts;
+drop function sys_datatype;
diff --git a/mysql-test/suite/versioning/t/partition.combinations b/mysql-test/suite/versioning/t/partition.combinations
index 4c1c009e7be..d79429f34f7 100644
--- a/mysql-test/suite/versioning/t/partition.combinations
+++ b/mysql-test/suite/versioning/t/partition.combinations
@@ -1,10 +1,7 @@
[innodb]
-innodb
partition
default-storage-engine=innodb
[myisam]
-skip-innodb
partition
default-storage-engine=myisam
-
diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test
index e0500284a6f..6dc7f56923b 100644
--- a/mysql-test/suite/versioning/t/partition.test
+++ b/mysql-test/suite/versioning/t/partition.test
@@ -1,3 +1,5 @@
+-- source suite/versioning/common.inc
+
### check System Versioning and conventional partitioning
create table t1 (x int)
@@ -83,15 +85,57 @@ alter table t1 drop partition p1;
--error ER_VERS_WRONG_PARAMS
alter table t1 drop partition p0;
-# insertion, deletion
+# insert, delete, update
+set @now= now(6);
insert into t1 values (1);
-select * from t1;
-select * from t1 partition (p0);
-select * from t1 partition (pn);
+set @ts_start= sys_commit_ts('sys_trx_start');
+set @ts_end= sys_commit_ts('sys_trx_end');
+set @str= concat('select x, ', @ts_start, ' < @now as A, ', @ts_end, ' > @now as B from t1 partition (p0) for system_time all');
+prepare select_p0 from @str;
+set @str= concat('select x, ', @ts_start, ' > @now as C, ', @ts_end, ' = timestamp\'2038-01-19 03:14:07\' as D from t1 partition (pn) for system_time all');
+prepare select_pn from @str;
+execute select_p0;
+execute select_pn;
+
+set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+set @now= now(6);
delete from t1;
-select * from t1 partition (p0) for system_time all;
-select * from t1 partition (pn) for system_time all;
+execute select_p0;
+execute select_pn;
+
+set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all into @ts1');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+select @ts0 = @ts1;
+
+set @now= now(6);
+insert into t1 values (2);
+execute select_p0;
+execute select_pn;
+
+set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+set @now= now(6);
+update t1 set x = x + 1;
+execute select_p0;
+execute select_pn;
+
+drop prepare select_p0;
+drop prepare select_pn;
+
+set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all where x = 2 into @ts1');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+set @str= concat('select ', @ts_end, ' from t1 partition (p0) for system_time all where x = 2 into @ts2');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts3');
+prepare stmt from @str; execute stmt; drop prepare stmt;
+
+select @ts0 = @ts1;
+select @ts2 = @ts3;
# rotation by LIMIT
create or replace table t1 (x int)
@@ -150,3 +194,5 @@ select * from t1 partition (p1sp0) for system_time all;
select * from t1 partition (p1sp1) for system_time all;
drop table t1;
+
+-- source suite/versioning/common_finish.inc
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index c1a792c87e0..2b1bc41931d 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1211,6 +1211,7 @@ bool partition_info::vers_setup_2(THD * thd, bool is_create_table_ind)
}
else if (vers_scan_min_max(thd, el))
{
+ table->s->stat_trx= NULL; // may be a leak on endless table open
error= true;
break;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index ac3e2edf304..bd8eb6b4d88 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -8718,8 +8718,7 @@ no_commit:
innobase_srv_conc_enter_innodb(m_prebuilt);
vers_set_fields = table->versioned() && (
- (sql_command != SQLCOM_DELETE ||
- (m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS)) &&
+ !is_innopart() &&
sql_command != SQLCOM_CREATE_TABLE) ?
ROW_INS_VERSIONED :
ROW_INS_NORMAL;
@@ -9527,8 +9526,7 @@ ha_innobase::update_row(
innobase_srv_conc_enter_innodb(m_prebuilt);
- vers_set_fields = m_prebuilt->upd_node->versioned &&
- (m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS);
+ vers_set_fields = m_prebuilt->upd_node->versioned && !is_innopart();
error = row_update_for_mysql((byte*) old_row, m_prebuilt, vers_set_fields);
@@ -9652,7 +9650,7 @@ ha_innobase::delete_row(
bool vers_set_fields =
table->versioned() &&
- (m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS) &&
+ !is_innopart() &&
table->vers_end_field()->is_max();
error = row_update_for_mysql(
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index f4600a6415b..94155fdf18b 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -519,6 +519,11 @@ protected:
/** If mysql has locked with external_lock() */
bool m_mysql_has_locked;
+
+ bool is_innopart()
+ {
+ return m_share == NULL;
+ }
};
diff --git a/storage/innobase/handler/ha_innopart.h b/storage/innobase/handler/ha_innopart.h
index ab445cf25ca..ef66420acb1 100644
--- a/storage/innobase/handler/ha_innopart.h
+++ b/storage/innobase/handler/ha_innopart.h
@@ -1119,6 +1119,19 @@ private:
write_row(
uchar* record)
{
+ if (table->versioned())
+ {
+ trx_t* trx = thd_to_trx(ha_thd());
+ if (!trx->id)
+ trx_start_if_not_started_xa(trx, true);
+ ut_a(trx->id);
+ ut_a(table->record[0] == record);
+ bitmap_set_bit(table->write_set, table->vers_start_field()->field_index);
+ bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
+ table->vers_start_field()->set_notnull();
+ table->vers_start_field()->store(trx->id, true);
+ table->vers_end_field()->set_max();
+ }
return(Partition_helper::ph_write_row(record));
}
@@ -1127,6 +1140,31 @@ private:
const uchar* old_record,
uchar* new_record)
{
+ int err;
+ if (table->versioned() && table->vers_end_field()->is_max()) {
+ trx_t* trx = thd_to_trx(ha_thd());
+ if (!trx->id)
+ trx_start_if_not_started_xa(trx, true);
+ ut_a(trx->id);
+ ut_a(table->record[0] == new_record);
+ ut_a(table->record[1] == old_record);
+ store_record(table, record[2]); // store new_record
+ restore_record(table, record[1]); // restore old_record
+ // modify and insert old_record
+ bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
+ table->vers_end_field()->set_notnull();
+ table->vers_end_field()->store(trx->id, true);
+ err = Partition_helper::ph_write_row(const_cast<uchar*>(table->record[0]));
+ restore_record(table, record[2]); // restore new_record
+ if (err)
+ return err;
+ table->vers_start_field()->store(trx->id, true);
+ }
+ if (unlikely(get_part_for_delete(old_record,
+ new_record,
+ m_part_info,
+ &m_last_part)))
+ return HA_ERR_INTERNAL_ERROR;
return(Partition_helper::ph_update_row(old_record, new_record));
}
@@ -1145,6 +1183,8 @@ private:
ut_a(table->record[0] == record);
store_record(table, record[1]);
ut_a(trx->id);
+ bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
+ table->vers_end_field()->set_notnull();
table->vers_end_field()->store(trx->id, true);
return Partition_helper::ph_update_row(table->record[1], table->record[0]);
}