Skip to content

Commit

Permalink
IB,SQL: Innopart UPDATE [fixes #178]
Browse files Browse the repository at this point in the history
  • Loading branch information
midenok committed May 5, 2017
1 parent 7d2ed77 commit 27a6ef0
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 25 deletions.
146 changes: 135 additions & 11 deletions mysql-test/suite/versioning/r/partition.result
Original file line number Diff line number Diff line change
@@ -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) (
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -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;
3 changes: 0 additions & 3 deletions mysql-test/suite/versioning/t/partition.combinations
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
[innodb]
innodb
partition
default-storage-engine=innodb

[myisam]
skip-innodb
partition
default-storage-engine=myisam

58 changes: 52 additions & 6 deletions mysql-test/suite/versioning/t/partition.test
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
-- source suite/versioning/common.inc

### check System Versioning and conventional partitioning

create table t1 (x int)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions sql/partition_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
8 changes: 3 additions & 5 deletions storage/innobase/handler/ha_innodb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8718,8 +8718,7 @@ ha_innobase::write_row(
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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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(
Expand Down
5 changes: 5 additions & 0 deletions storage/innobase/handler/ha_innodb.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,11 @@ class ha_innobase: public handler

/** If mysql has locked with external_lock() */
bool m_mysql_has_locked;

bool is_innopart()
{
return m_share == NULL;
}
};


Expand Down
40 changes: 40 additions & 0 deletions storage/innobase/handler/ha_innopart.h
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,19 @@ class ha_innopart:
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));
}

Expand All @@ -1127,6 +1140,31 @@ class ha_innopart:
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));
}

Expand All @@ -1145,6 +1183,8 @@ class ha_innopart:
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]);
}
Expand Down

0 comments on commit 27a6ef0

Please sign in to comment.