From: Date: October 15 2005 2:48pm Subject: bk commit into 5.0 tree (sergefp:1.2034) BUG#11704 List-Archive: http://lists.mysql.com/internals/31131 X-Bug: 11704 Message-Id: <20051015124804.4F9C837AFE@newbox.mylan> Below is the list of changes that have just been committed into a local 5.0 repository of psergey. When psergey does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2034 05/10/15 16:47:57 sergefp@stripped +3 -0 Fix for BUG#11704: 1. The source of "Found locks from different thread" - this scenario in OPTIMIZE: thr1: lock table with TL_WRITE_ONLY (InnoDB converted lock to TL_WRITE_ALLOW_WRITE) thr2: (UPDATE command) obtains a TL_WRITE_ALLOW_WRITE lock thr1: call mysql_lock_abort(). This function sets type of thr'1 lock to TL_WRITE_ONLY thr2: try to release thr2's lock. See two locks: TL_WRITE_ONLY, TL_WRITE_ALLOW_WRITE and produce a warning. 3. The source of "record not found" errors: in ha_innobase::position(): If primary key partially covers CHAR(N) field, and field's charset has mbmaxlen>1, mbminlen !=mbmaxlen (e.g. UTF-8). sql/ha_innodb.cc 1.272 05/10/15 16:47:48 sergefp@stripped +27 -16 Fix for BUG#11704: 1. The source of "Found locks from different thread" - this scenario in OPTIMIZE: thr1: lock table with TL_WRITE_ONLY (InnoDB converted lock to TL_WRITE_ALLOW_WRITE) thr2: (UPDATE command) obtains a TL_WRITE_ALLOW_WRITE lock thr1: call mysql_lock_abort(). This function sets type of thr'1 lock to TL_WRITE_ONLY thr2: try to release thr2's lock. See two locks: TL_WRITE_ONLY, TL_WRITE_ALLOW_WRITE and produce a warning. 3. The source of "record not found" errors: in ha_innobase::position(): If primary key partially covers CHAR(N) field, and field's charset has mbmaxlen>1, mbminlen !=mbmaxlen (e.g. UTF-8). mysql-test/t/innodb.test 1.116 05/10/15 16:47:48 sergefp@stripped +12 -0 Testcase for BUG#11704 mysql-test/r/innodb.result 1.145 05/10/15 16:47:47 sergefp@stripped +8 -0 Testcase for BUG#11704 # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: sergefp # Host: newbox.mylan # Root: /home/psergey/mysql-5.0-bug11704-r3 --- 1.144/mysql-test/r/innodb.result 2005-10-04 23:35:26 +04:00 +++ 1.145/mysql-test/r/innodb.result 2005-10-15 16:47:47 +04:00 @@ -2644,6 +2644,14 @@ Table Checksum test.t1 2050879373 drop table t1; +create table t1 ( +a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; +insert into t1 values (1,'abcdefg','one'); +insert into t1 values (2,'ijkilmn','two'); +insert into t1 values (3, 'qrstuvw','three'); +update t1 set a=5, filler='booo' where a=1; +drop table t1; create table t1 (col1 integer primary key, col2 integer) engine=innodb; insert t1 values (1,100); create function f1 () returns integer begin --- 1.115/mysql-test/t/innodb.test 2005-09-30 22:19:43 +04:00 +++ 1.116/mysql-test/t/innodb.test 2005-10-15 16:47:48 +04:00 @@ -1605,6 +1605,18 @@ checksum table t1; drop table t1; +# Part of BUG#11704: ha_innobase::position() produces incorrect rowids +# if primary key partially covers char(N) charset = utf8. +create table t1 ( + a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; + +insert into t1 values (1,'abcdefg','one'); +insert into t1 values (2,'ijkilmn','two'); +insert into t1 values (3, 'qrstuvw','three'); +update t1 set a=5, filler='booo' where a=1; +drop table t1; + # # BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to # non-blocking SELECT --- 1.271/sql/ha_innodb.cc 2005-10-07 11:14:38 +04:00 +++ 1.272/sql/ha_innodb.cc 2005-10-15 16:47:48 +04:00 @@ -2953,21 +2953,31 @@ buff += key_part->length; } else { - /* Here we handle all other data types except the - true VARCHAR, BLOB and TEXT. Note that the column - value we store may be also in a column prefix - index. */ - - if (is_null) { - buff += key_part->length; - - continue; - } - - memcpy(buff, record + key_part->offset, - key_part->length); - buff += key_part->length; - } + /* Here we handle all other data types except the + true VARCHAR, BLOB and TEXT. Note that the column + value we store may be also in a column prefix + index. */ + + if (is_null) { + buff += key_part->length; + continue; + } + CHARSET_INFO *cs= key_part->field->charset(); + const mysql_byte *src_start= record + key_part->offset; + const mysql_byte *src_end = src_start + key_part->length; + int error; + uint len; + len= cs->cset->well_formed_len(cs, src_start, src_end, + key_part->length/ + cs->mbmaxlen, + &error); + DBUG_ASSERT(!error); + memcpy(buff, src_start, len); + char *buff_end = buff + key_part->length; + /* Pad the unused space with spaces */ + for(buff+=len; buff != buff_end; buff++) + *buff=' '; + } } ut_a(buff <= buff_start + buff_len); @@ -6753,7 +6763,8 @@ || thd->lex->sql_command == SQLCOM_CALL) && !thd->tablespace_op && thd->lex->sql_command != SQLCOM_TRUNCATE - && thd->lex->sql_command != SQLCOM_CREATE_TABLE) { + && thd->lex->sql_command != SQLCOM_CREATE_TABLE + && thd->lex->sql_command != SQLCOM_OPTIMIZE) { lock_type = TL_WRITE_ALLOW_WRITE; }