Fix for bug #22364 "Inconsistent "matched rows" when executing UPDATE"
In multi_update::send_data(), the counter of matched rows was not correctly incremented, when during insertion of a new row to a temporay table it had to be converted from HEAP to MyISAM. This fix changes the logic to increment the counter of matched rows in the following cases: 1. If the error returned from write_row() is zero. 2. If the error returned from write_row() is non-zero, is neither HA_ERR_FOUND_DUPP_KEY nor HA_ERR_FOUND_DUPP_UNIQUE, and a call to create_myisam_from_heap() succeeds. mysql-test/r/update.result: Added a test case for bug #22364 "Inconsistent "matched rows" when executing UPDATE" mysql-test/t/update.test: Added a test case for bug #22364 "Inconsistent "matched rows" when executing UPDATE" sql/sql_update.cc: In multi_update::send_data(), the counter of matched rows was not correctly incremented, when during insertion of a new row to a temporay table it had to be converted from HEAP to MyISAM. This fix changes the logic to increment the counter of matched rows in the following cases: 1. If the error returned from write_row() is zero. 2. If the error returned from write_row() is non-zero, is neither HA_ERR_FOUND_DUPP_KEY nor HA_ERR_FOUND_DUPP_UNIQUE, and a call to create_myisam_from_heap() succeeds.
This commit is contained in:
parent
f7417a299e
commit
c705567e9c
35
mysql-test/r/bdb_notembedded.result
Normal file
35
mysql-test/r/bdb_notembedded.result
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
set autocommit=1;
|
||||||
|
reset master;
|
||||||
|
create table bug16206 (a int);
|
||||||
|
insert into bug16206 values(1);
|
||||||
|
start transaction;
|
||||||
|
insert into bug16206 values(2);
|
||||||
|
commit;
|
||||||
|
show binlog events;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
|
||||||
|
f n Query 1 n use `test`; create table bug16206 (a int)
|
||||||
|
f n Query 1 n use `test`; insert into bug16206 values(1)
|
||||||
|
f n Query 1 n use `test`; insert into bug16206 values(2)
|
||||||
|
drop table bug16206;
|
||||||
|
reset master;
|
||||||
|
create table bug16206 (a int) engine= bdb;
|
||||||
|
insert into bug16206 values(0);
|
||||||
|
insert into bug16206 values(1);
|
||||||
|
start transaction;
|
||||||
|
insert into bug16206 values(2);
|
||||||
|
commit;
|
||||||
|
insert into bug16206 values(3);
|
||||||
|
show binlog events;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4
|
||||||
|
f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb
|
||||||
|
f n Query 1 n use `test`; insert into bug16206 values(0)
|
||||||
|
f n Query 1 n use `test`; insert into bug16206 values(1)
|
||||||
|
f n Query 1 n use `test`; BEGIN
|
||||||
|
f n Query 1 n use `test`; insert into bug16206 values(2)
|
||||||
|
f n Query 1 n use `test`; COMMIT
|
||||||
|
f n Query 1 n use `test`; insert into bug16206 values(3)
|
||||||
|
drop table bug16206;
|
||||||
|
set autocommit=0;
|
||||||
|
End of 5.0 tests
|
@ -457,3 +457,38 @@ a quux
|
|||||||
2 0.100000000000000000000000000000
|
2 0.100000000000000000000000000000
|
||||||
3 NULL
|
3 NULL
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
set tmp_table_size=1024;
|
||||||
|
create table t1 (id int, a int, key idx(a));
|
||||||
|
create table t2 (id int unsigned not null auto_increment primary key, a int);
|
||||||
|
insert into t2(a) values(1),(2),(3),(4),(5),(6),(7),(8);
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
update t2 set a=id;
|
||||||
|
insert into t1 select * from t2;
|
||||||
|
select count(*) from t1 join t2 on (t1.a=t2.a);
|
||||||
|
count(*)
|
||||||
|
64
|
||||||
|
update t1 join t2 on (t1.a=t2.a) set t1.id=t2.id;
|
||||||
|
affected rows: 0
|
||||||
|
info: Rows matched: 64 Changed: 0 Warnings: 0
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
update t2 set a=id;
|
||||||
|
truncate t1;
|
||||||
|
insert into t1 select * from t2;
|
||||||
|
select count(*) from t1 join t2 on (t1.a=t2.a);
|
||||||
|
count(*)
|
||||||
|
128
|
||||||
|
update t1 join t2 on (t1.a=t2.a) set t1.id=t2.id;
|
||||||
|
affected rows: 0
|
||||||
|
info: Rows matched: 128 Changed: 0 Warnings: 0
|
||||||
|
update t1 set a=1;
|
||||||
|
update t2 set a=1;
|
||||||
|
select count(*) from t1 join t2 on (t1.a=t2.a);
|
||||||
|
count(*)
|
||||||
|
16384
|
||||||
|
update t1 join t2 on (t1.a=t2.a) set t1.id=t2.id;
|
||||||
|
affected rows: 127
|
||||||
|
info: Rows matched: 128 Changed: 127 Warnings: 0
|
||||||
|
drop table t1,t2;
|
||||||
|
End of 5.0 tests
|
||||||
|
38
mysql-test/t/bdb_notembedded.test
Normal file
38
mysql-test/t/bdb_notembedded.test
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
-- source include/not_embedded.inc
|
||||||
|
-- source include/have_bdb.inc
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode
|
||||||
|
#
|
||||||
|
set autocommit=1;
|
||||||
|
|
||||||
|
let $VERSION=`select version()`;
|
||||||
|
|
||||||
|
reset master;
|
||||||
|
create table bug16206 (a int);
|
||||||
|
insert into bug16206 values(1);
|
||||||
|
start transaction;
|
||||||
|
insert into bug16206 values(2);
|
||||||
|
commit;
|
||||||
|
--replace_result $VERSION VERSION
|
||||||
|
--replace_column 1 f 2 n 5 n
|
||||||
|
show binlog events;
|
||||||
|
drop table bug16206;
|
||||||
|
|
||||||
|
reset master;
|
||||||
|
create table bug16206 (a int) engine= bdb;
|
||||||
|
insert into bug16206 values(0);
|
||||||
|
insert into bug16206 values(1);
|
||||||
|
start transaction;
|
||||||
|
insert into bug16206 values(2);
|
||||||
|
commit;
|
||||||
|
insert into bug16206 values(3);
|
||||||
|
--replace_result $VERSION VERSION
|
||||||
|
--replace_column 1 f 2 n 5 n
|
||||||
|
show binlog events;
|
||||||
|
drop table bug16206;
|
||||||
|
|
||||||
|
set autocommit=0;
|
||||||
|
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
@ -376,3 +376,58 @@ INSERT INTO t1( a )
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #22364: Inconsistent "matched rows" when executing UPDATE
|
||||||
|
#
|
||||||
|
|
||||||
|
connect (con1,localhost,root,,test);
|
||||||
|
connection con1;
|
||||||
|
|
||||||
|
set tmp_table_size=1024;
|
||||||
|
|
||||||
|
# Create the test tables
|
||||||
|
create table t1 (id int, a int, key idx(a));
|
||||||
|
create table t2 (id int unsigned not null auto_increment primary key, a int);
|
||||||
|
insert into t2(a) values(1),(2),(3),(4),(5),(6),(7),(8);
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
update t2 set a=id;
|
||||||
|
insert into t1 select * from t2;
|
||||||
|
|
||||||
|
# Check that the number of matched rows is correct when the temporary
|
||||||
|
# table is small enough to not be converted to MyISAM
|
||||||
|
select count(*) from t1 join t2 on (t1.a=t2.a);
|
||||||
|
--enable_info
|
||||||
|
update t1 join t2 on (t1.a=t2.a) set t1.id=t2.id;
|
||||||
|
--disable_info
|
||||||
|
|
||||||
|
# Increase table sizes
|
||||||
|
insert into t2(a) select a from t2;
|
||||||
|
update t2 set a=id;
|
||||||
|
truncate t1;
|
||||||
|
insert into t1 select * from t2;
|
||||||
|
|
||||||
|
# Check that the number of matched rows is correct when the temporary
|
||||||
|
# table has to be converted to MyISAM
|
||||||
|
select count(*) from t1 join t2 on (t1.a=t2.a);
|
||||||
|
--enable_info
|
||||||
|
update t1 join t2 on (t1.a=t2.a) set t1.id=t2.id;
|
||||||
|
--disable_info
|
||||||
|
|
||||||
|
# Check that the number of matched rows is correct when there are duplicate
|
||||||
|
# key errors
|
||||||
|
update t1 set a=1;
|
||||||
|
update t2 set a=1;
|
||||||
|
select count(*) from t1 join t2 on (t1.a=t2.a);
|
||||||
|
--enable_info
|
||||||
|
update t1 join t2 on (t1.a=t2.a) set t1.id=t2.id;
|
||||||
|
--disable_info
|
||||||
|
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
disconnect con1;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
@ -1328,21 +1328,20 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
memcpy((char*) tmp_table->field[0]->ptr,
|
memcpy((char*) tmp_table->field[0]->ptr,
|
||||||
(char*) table->file->ref, table->file->ref_length);
|
(char*) table->file->ref, table->file->ref_length);
|
||||||
/* Write row, ignoring duplicated updates to a row */
|
/* Write row, ignoring duplicated updates to a row */
|
||||||
if ((error= tmp_table->file->write_row(tmp_table->record[0])))
|
error= tmp_table->file->write_row(tmp_table->record[0]);
|
||||||
|
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
|
||||||
{
|
{
|
||||||
if (error != HA_ERR_FOUND_DUPP_KEY &&
|
if (error &&
|
||||||
error != HA_ERR_FOUND_DUPP_UNIQUE &&
|
|
||||||
create_myisam_from_heap(thd, tmp_table,
|
create_myisam_from_heap(thd, tmp_table,
|
||||||
tmp_table_param + offset, error, 1))
|
tmp_table_param + offset, error, 1))
|
||||||
{
|
{
|
||||||
do_update= 0;
|
do_update= 0;
|
||||||
DBUG_RETURN(1); // Not a table_is_full error
|
DBUG_RETURN(1); // Not a table_is_full error
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user