Skip to content

Commit 27a6ef0

Browse files
committed
IB,SQL: Innopart UPDATE [fixes #178]
1 parent 7d2ed77 commit 27a6ef0

File tree

7 files changed

+236
-25
lines changed

7 files changed

+236
-25
lines changed

mysql-test/suite/versioning/r/partition.result

Lines changed: 135 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,65 @@
1+
set @@session.time_zone='+00:00';
2+
select ifnull(max(trx_id), 0) into @start_trx_id from information_schema.innodb_vtq;
3+
create procedure if not exists verify_vtq()
4+
begin
5+
set @i= 0;
6+
select
7+
@i:= @i + 1 as No,
8+
trx_id > 0 as A,
9+
commit_id >= trx_id as B,
10+
begin_ts > '1-1-1 0:0:0' as C,
11+
commit_ts > begin_ts as D
12+
from information_schema.innodb_vtq
13+
where trx_id > @start_trx_id;
14+
select ifnull(max(trx_id), 0)
15+
into @start_trx_id
16+
from information_schema.innodb_vtq;
17+
end~~
18+
create function if not exists default_engine()
19+
returns varchar(255)
20+
deterministic
21+
begin
22+
declare e varchar(255);
23+
select lower(engine) from information_schema.engines where support='DEFAULT' into e;
24+
return e;
25+
end~~
26+
create function if not exists sys_datatype()
27+
returns varchar(255)
28+
deterministic
29+
begin
30+
if default_engine() = 'innodb' then
31+
return 'bigint unsigned';
32+
elseif default_engine() = 'myisam' then
33+
return 'timestamp(6)';
34+
end if;
35+
return NULL;
36+
end~~
37+
create function if not exists sys_commit_ts(sys_field varchar(255))
38+
returns varchar(255)
39+
deterministic
40+
begin
41+
if default_engine() = 'innodb' then
42+
return concat('vtq_commit_ts(', sys_field, ')');
43+
elseif default_engine() = 'myisam' then
44+
return sys_field;
45+
end if;
46+
return NULL;
47+
end~~
48+
create procedure if not exists innodb_verify_vtq(recs int)
49+
begin
50+
declare i int default 1;
51+
if default_engine() = 'innodb' then
52+
call verify_vtq;
53+
elseif default_engine() = 'myisam' then
54+
create temporary table tmp (No int, A bool, B bool, C bool, D bool);
55+
while i <= recs do
56+
insert into tmp values (i, 1, 1, 1, 1);
57+
set i= i + 1;
58+
end while;
59+
select * from tmp;
60+
drop table tmp;
61+
end if;
62+
end~~
163
create table t1 (x int)
264
with system versioning
365
partition by range columns (x) (
@@ -90,21 +152,78 @@ ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: `AS OF NOW` partition can no
90152
alter table t1 drop partition p1;
91153
alter table t1 drop partition p0;
92154
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: one `AS OF NOW` and at least one `VERSIONING` partition required
155+
set @now= now(6);
93156
insert into t1 values (1);
94-
select * from t1;
95-
x
157+
set @ts_start= sys_commit_ts('sys_trx_start');
158+
set @ts_end= sys_commit_ts('sys_trx_end');
159+
set @str= concat('select x, ', @ts_start, ' < @now as A, ', @ts_end, ' > @now as B from t1 partition (p0) for system_time all');
160+
prepare select_p0 from @str;
161+
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');
162+
prepare select_pn from @str;
163+
execute select_p0;
164+
x A B
165+
execute select_pn;
166+
x C D
167+
1 1 1
168+
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
169+
prepare stmt from @str;
170+
execute stmt;
171+
drop prepare stmt;
172+
set @now= now(6);
173+
delete from t1;
174+
execute select_p0;
175+
x A B
176+
1 1 1
177+
execute select_pn;
178+
x C D
179+
set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all into @ts1');
180+
prepare stmt from @str;
181+
execute stmt;
182+
drop prepare stmt;
183+
select @ts0 = @ts1;
184+
@ts0 = @ts1
96185
1
97-
select * from t1 partition (p0);
98-
x
99-
select * from t1 partition (pn);
100-
x
186+
set @now= now(6);
187+
insert into t1 values (2);
188+
execute select_p0;
189+
x A B
190+
1 1 0
191+
execute select_pn;
192+
x C D
193+
2 1 1
194+
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
195+
prepare stmt from @str;
196+
execute stmt;
197+
drop prepare stmt;
198+
set @now= now(6);
199+
update t1 set x = x + 1;
200+
execute select_p0;
201+
x A B
202+
1 1 0
203+
2 1 1
204+
execute select_pn;
205+
x C D
206+
3 1 1
207+
drop prepare select_p0;
208+
drop prepare select_pn;
209+
set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all where x = 2 into @ts1');
210+
prepare stmt from @str;
211+
execute stmt;
212+
drop prepare stmt;
213+
set @str= concat('select ', @ts_end, ' from t1 partition (p0) for system_time all where x = 2 into @ts2');
214+
prepare stmt from @str;
215+
execute stmt;
216+
drop prepare stmt;
217+
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts3');
218+
prepare stmt from @str;
219+
execute stmt;
220+
drop prepare stmt;
221+
select @ts0 = @ts1;
222+
@ts0 = @ts1
101223
1
102-
delete from t1;
103-
select * from t1 partition (p0) for system_time all;
104-
x
224+
select @ts2 = @ts3;
225+
@ts2 = @ts3
105226
1
106-
select * from t1 partition (pn) for system_time all;
107-
x
108227
create or replace table t1 (x int)
109228
with system versioning
110229
partition by system_time limit 1 (
@@ -190,3 +309,8 @@ select * from t1 partition (p1sp1) for system_time all;
190309
x
191310
2
192311
drop table t1;
312+
drop procedure verify_vtq;
313+
drop procedure innodb_verify_vtq;
314+
drop function default_engine;
315+
drop function sys_commit_ts;
316+
drop function sys_datatype;
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
[innodb]
2-
innodb
32
partition
43
default-storage-engine=innodb
54

65
[myisam]
7-
skip-innodb
86
partition
97
default-storage-engine=myisam
10-

mysql-test/suite/versioning/t/partition.test

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
-- source suite/versioning/common.inc
2+
13
### check System Versioning and conventional partitioning
24

35
create table t1 (x int)
@@ -83,15 +85,57 @@ alter table t1 drop partition p1;
8385
--error ER_VERS_WRONG_PARAMS
8486
alter table t1 drop partition p0;
8587

86-
# insertion, deletion
88+
# insert, delete, update
89+
set @now= now(6);
8790
insert into t1 values (1);
88-
select * from t1;
89-
select * from t1 partition (p0);
90-
select * from t1 partition (pn);
91+
set @ts_start= sys_commit_ts('sys_trx_start');
92+
set @ts_end= sys_commit_ts('sys_trx_end');
93+
set @str= concat('select x, ', @ts_start, ' < @now as A, ', @ts_end, ' > @now as B from t1 partition (p0) for system_time all');
94+
prepare select_p0 from @str;
95+
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');
96+
prepare select_pn from @str;
9197

98+
execute select_p0;
99+
execute select_pn;
100+
101+
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
102+
prepare stmt from @str; execute stmt; drop prepare stmt;
103+
104+
set @now= now(6);
92105
delete from t1;
93-
select * from t1 partition (p0) for system_time all;
94-
select * from t1 partition (pn) for system_time all;
106+
execute select_p0;
107+
execute select_pn;
108+
109+
set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all into @ts1');
110+
prepare stmt from @str; execute stmt; drop prepare stmt;
111+
112+
select @ts0 = @ts1;
113+
114+
set @now= now(6);
115+
insert into t1 values (2);
116+
execute select_p0;
117+
execute select_pn;
118+
119+
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts0');
120+
prepare stmt from @str; execute stmt; drop prepare stmt;
121+
122+
set @now= now(6);
123+
update t1 set x = x + 1;
124+
execute select_p0;
125+
execute select_pn;
126+
127+
drop prepare select_p0;
128+
drop prepare select_pn;
129+
130+
set @str= concat('select ', @ts_start, ' from t1 partition (p0) for system_time all where x = 2 into @ts1');
131+
prepare stmt from @str; execute stmt; drop prepare stmt;
132+
set @str= concat('select ', @ts_end, ' from t1 partition (p0) for system_time all where x = 2 into @ts2');
133+
prepare stmt from @str; execute stmt; drop prepare stmt;
134+
set @str= concat('select ', @ts_start, ' from t1 partition (pn) into @ts3');
135+
prepare stmt from @str; execute stmt; drop prepare stmt;
136+
137+
select @ts0 = @ts1;
138+
select @ts2 = @ts3;
95139

96140
# rotation by LIMIT
97141
create or replace table t1 (x int)
@@ -150,3 +194,5 @@ select * from t1 partition (p1sp0) for system_time all;
150194
select * from t1 partition (p1sp1) for system_time all;
151195

152196
drop table t1;
197+
198+
-- source suite/versioning/common_finish.inc

sql/partition_info.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,7 @@ bool partition_info::vers_setup_2(THD * thd, bool is_create_table_ind)
12111211
}
12121212
else if (vers_scan_min_max(thd, el))
12131213
{
1214+
table->s->stat_trx= NULL; // may be a leak on endless table open
12141215
error= true;
12151216
break;
12161217
}

storage/innobase/handler/ha_innodb.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8718,8 +8718,7 @@ ha_innobase::write_row(
87188718
innobase_srv_conc_enter_innodb(m_prebuilt);
87198719

87208720
vers_set_fields = table->versioned() && (
8721-
(sql_command != SQLCOM_DELETE ||
8722-
(m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS)) &&
8721+
!is_innopart() &&
87238722
sql_command != SQLCOM_CREATE_TABLE) ?
87248723
ROW_INS_VERSIONED :
87258724
ROW_INS_NORMAL;
@@ -9527,8 +9526,7 @@ ha_innobase::update_row(
95279526

95289527
innobase_srv_conc_enter_innodb(m_prebuilt);
95299528

9530-
vers_set_fields = m_prebuilt->upd_node->versioned &&
9531-
(m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS);
9529+
vers_set_fields = m_prebuilt->upd_node->versioned && !is_innopart();
95329530

95339531
error = row_update_for_mysql((byte*) old_row, m_prebuilt, vers_set_fields);
95349532

@@ -9652,7 +9650,7 @@ ha_innobase::delete_row(
96529650

96539651
bool vers_set_fields =
96549652
table->versioned() &&
9655-
(m_int_table_flags & HA_INNOPART_DISABLED_TABLE_FLAGS) &&
9653+
!is_innopart() &&
96569654
table->vers_end_field()->is_max();
96579655

96589656
error = row_update_for_mysql(

storage/innobase/handler/ha_innodb.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,11 @@ class ha_innobase: public handler
519519

520520
/** If mysql has locked with external_lock() */
521521
bool m_mysql_has_locked;
522+
523+
bool is_innopart()
524+
{
525+
return m_share == NULL;
526+
}
522527
};
523528

524529

storage/innobase/handler/ha_innopart.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,19 @@ class ha_innopart:
11191119
write_row(
11201120
uchar* record)
11211121
{
1122+
if (table->versioned())
1123+
{
1124+
trx_t* trx = thd_to_trx(ha_thd());
1125+
if (!trx->id)
1126+
trx_start_if_not_started_xa(trx, true);
1127+
ut_a(trx->id);
1128+
ut_a(table->record[0] == record);
1129+
bitmap_set_bit(table->write_set, table->vers_start_field()->field_index);
1130+
bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
1131+
table->vers_start_field()->set_notnull();
1132+
table->vers_start_field()->store(trx->id, true);
1133+
table->vers_end_field()->set_max();
1134+
}
11221135
return(Partition_helper::ph_write_row(record));
11231136
}
11241137

@@ -1127,6 +1140,31 @@ class ha_innopart:
11271140
const uchar* old_record,
11281141
uchar* new_record)
11291142
{
1143+
int err;
1144+
if (table->versioned() && table->vers_end_field()->is_max()) {
1145+
trx_t* trx = thd_to_trx(ha_thd());
1146+
if (!trx->id)
1147+
trx_start_if_not_started_xa(trx, true);
1148+
ut_a(trx->id);
1149+
ut_a(table->record[0] == new_record);
1150+
ut_a(table->record[1] == old_record);
1151+
store_record(table, record[2]); // store new_record
1152+
restore_record(table, record[1]); // restore old_record
1153+
// modify and insert old_record
1154+
bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
1155+
table->vers_end_field()->set_notnull();
1156+
table->vers_end_field()->store(trx->id, true);
1157+
err = Partition_helper::ph_write_row(const_cast<uchar*>(table->record[0]));
1158+
restore_record(table, record[2]); // restore new_record
1159+
if (err)
1160+
return err;
1161+
table->vers_start_field()->store(trx->id, true);
1162+
}
1163+
if (unlikely(get_part_for_delete(old_record,
1164+
new_record,
1165+
m_part_info,
1166+
&m_last_part)))
1167+
return HA_ERR_INTERNAL_ERROR;
11301168
return(Partition_helper::ph_update_row(old_record, new_record));
11311169
}
11321170

@@ -1145,6 +1183,8 @@ class ha_innopart:
11451183
ut_a(table->record[0] == record);
11461184
store_record(table, record[1]);
11471185
ut_a(trx->id);
1186+
bitmap_set_bit(table->write_set, table->vers_end_field()->field_index);
1187+
table->vers_end_field()->set_notnull();
11481188
table->vers_end_field()->store(trx->id, true);
11491189
return Partition_helper::ph_update_row(table->record[1], table->record[0]);
11501190
}

0 commit comments

Comments
 (0)