summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaa@polly.local <>2007-04-23 18:22:33 +0400
committerkaa@polly.local <>2007-04-23 18:22:33 +0400
commit9a99aa81552178b2d7995ea41e0878dc59061c9b (patch)
tree24f873cc5431a99425c7bd62ffd427c12c3ded2f
parent19a263064189d5c8f91c1e78533771525c92abb3 (diff)
downloadmariadb-git-9a99aa81552178b2d7995ea41e0878dc59061c9b.tar.gz
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.
-rw-r--r--mysql-test/r/bdb_notembedded.result35
-rw-r--r--mysql-test/r/update.result35
-rw-r--r--mysql-test/t/bdb_notembedded.test38
-rw-r--r--mysql-test/t/update.test55
-rw-r--r--sql/sql_update.cc19
5 files changed, 172 insertions, 10 deletions
diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result
new file mode 100644
index 00000000000..14cb5fad915
--- /dev/null
+++ b/mysql-test/r/bdb_notembedded.result
@@ -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
diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result
index 748c2644eb9..dc7c7642a9b 100644
--- a/mysql-test/r/update.result
+++ b/mysql-test/r/update.result
@@ -457,3 +457,38 @@ a quux
2 0.100000000000000000000000000000
3 NULL
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
diff --git a/mysql-test/t/bdb_notembedded.test b/mysql-test/t/bdb_notembedded.test
new file mode 100644
index 00000000000..24e64ebbfb2
--- /dev/null
+++ b/mysql-test/t/bdb_notembedded.test
@@ -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
diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test
index 6cec940d286..f79c9e773aa 100644
--- a/mysql-test/t/update.test
+++ b/mysql-test/t/update.test
@@ -376,3 +376,58 @@ INSERT INTO t1( a )
SELECT * FROM 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
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 27d38114885..b316a15e9f7 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1328,19 +1328,18 @@ bool multi_update::send_data(List<Item> &not_used_values)
memcpy((char*) tmp_table->field[0]->ptr,
(char*) table->file->ref, table->file->ref_length);
/* 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 &&
- error != HA_ERR_FOUND_DUPP_UNIQUE &&
+ if (error &&
create_myisam_from_heap(thd, tmp_table,
- tmp_table_param + offset, error, 1))
- {
- do_update=0;
- DBUG_RETURN(1); // Not a table_is_full error
- }
- }
- else
+ tmp_table_param + offset, error, 1))
+ {
+ do_update= 0;
+ DBUG_RETURN(1); // Not a table_is_full error
+ }
found++;
+ }
}
}
DBUG_RETURN(0);