List:Commits« Previous MessageNext Message »
From:Alex Ivanov Date:January 16 2006 11:33am
Subject:bk commit into 5.0 tree (aivanov:1.2021) BUG#14189
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of alexi. When alexi 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.2021 06/01/16 14:32:43 aivanov@stripped +17 -0
  Changes from the innodb-5.0-ss115 snapshot.
   Fixed bugs:
   BUG#15991: "innodb-file-per-table + symlink database + rename = crash"
   BUG#15650: "DELETE with LEFT JOIN crashes server"
   BUG#15308: "Problem of Order with Enum Column in Primary Key"
   BUG#14189: "VARBINARY and BINARY variables: trailing space ignored"

  mysql-test/t/innodb_unsafe_binlog.test
    1.1 06/01/16 14:03:57 aivanov@stripped +67 -0
    Changes from the innodb-5.0-ss115 snapshot.
     Added testcases for bug #15650.

  mysql-test/t/innodb_unsafe_binlog.test
    1.0 06/01/16 14:03:57 aivanov@stripped +0 -0
    BitKeeper file /home/alexi/innodb-ss/mysql-5.0-ss115/mysql-test/t/innodb_unsafe_binlog.test

  mysql-test/t/innodb_unsafe_binlog-master.opt
    1.1 06/01/16 14:03:56 aivanov@stripped +1 -0
    Changes from the innodb-5.0-ss115 snapshot.
    

  mysql-test/r/innodb_unsafe_binlog.result
    1.1 06/01/16 14:03:56 aivanov@stripped +48 -0
    Changes from the innodb-5.0-ss115 snapshot.
    

  sql/ha_innodb.cc
    1.282 06/01/16 14:03:56 aivanov@stripped +106 -66
    Changes from the innodb-5.0-ss115 snapshot.
     Fixed bug #15308.
     Fixed bug #14189: innobase_init(): Assert that
       DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number.
     After review fixes for unlock bug where unlock released all
       locks transaction requested for a row. Only a latest requested
       lock to a row should be released. Update function comments to
       reflect current state. Persistent cursor should be stored
       whenever select lock type != LOCK_NONE.

  mysql-test/t/innodb_unsafe_binlog-master.opt
    1.0 06/01/16 14:03:56 aivanov@stripped +0 -0
    BitKeeper file /home/alexi/innodb-ss/mysql-5.0-ss115/mysql-test/t/innodb_unsafe_binlog-master.opt

  mysql-test/r/innodb_unsafe_binlog.result
    1.0 06/01/16 14:03:56 aivanov@stripped +0 -0
    BitKeeper file /home/alexi/innodb-ss/mysql-5.0-ss115/mysql-test/r/innodb_unsafe_binlog.result

  mysql-test/t/innodb.test
    1.122 06/01/16 14:03:55 aivanov@stripped +197 -18
    Changes from the innodb-5.0-ss115 snapshot.

  mysql-test/r/innodb.result
    1.152 06/01/16 14:03:55 aivanov@stripped +318 -14
    Changes from the innodb-5.0-ss115 snapshot.

  innobase/trx/trx0trx.c
    1.63 06/01/16 14:03:55 aivanov@stripped +2 -1
    Changes from the innodb-5.0-ss115 snapshot.
     trx_commit_off_kernel(): Do not write empty trx->mysql_log_file_name.

  innobase/row/row0sel.c
    1.105 06/01/16 14:03:55 aivanov@stripped +6 -6
    Changes from the innodb-5.0-ss115 snapshot.
     Fixed bug #15308.
     Fixed bug #14189: innobase_init(): Assert that
       DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number.
     After review fixes for unlock bug where unlock released all
       locks transaction requested for a row. Only a latest requested
       lock to a row should be released. Update function comments to
       reflect current state. Persistent cursor should be stored
       whenever select lock type != LOCK_NONE.

  innobase/row/row0mysql.c
    1.117 06/01/16 14:03:55 aivanov@stripped +13 -13
    Changes from the innodb-5.0-ss115 snapshot.
     Fixed bug on unlock_row. In a unlock_row we may unlock
     only the latest lock granted to this transaction to the row.

  innobase/row/row0ins.c
    1.76 06/01/16 14:03:55 aivanov@stripped +9 -0
    Changes from the innodb-5.0-ss115 snapshot.
     Fixed bug #14189. row_ins_cascade_calc_update_vec(): Refuse
     ON UPDATE_CASCADE when trying to change the length of of a
     VARBINARY column that refers to or is referenced by a BINARY
     column. BINARY columns are no longer padded on comparison,
     and thus they cannot be padded on storage either.

  innobase/os/os0file.c
    1.113 06/01/16 14:03:55 aivanov@stripped +72 -40
    Changes from the innodb-5.0-ss115 snapshot.
     os_file_handle_error(): Map the error codes EXDEV, ENOTDIR, and
       EISDIR to the new code OS_FILE_PATH_ERROR. Treat this code as
       OS_FILE_PATH_ERROR. This fixes the crash on RENAME TABLE when
       the .ibd file is a symbolic link to a different file system
       (bug#15991).
     Protect the increment and decrement operations on the statistic
       variables os_n_pending_writes/reads with os_file_count_mutes.

  innobase/lock/lock0lock.c
    1.66 06/01/16 14:03:55 aivanov@stripped +70 -1
    Changes from the innodb-5.0-ss115 snapshot.
     lock_rec_unlock(): Initialize local variable release_lock,
     in order to avoid dereferencing an uninitialized pointer
     when no lock exists on rec.

  innobase/include/row0mysql.h
    1.46 06/01/16 14:03:55 aivanov@stripped +3 -2
    Changes from the innodb-5.0-ss115 snapshot.

  innobase/include/os0file.h
    1.43 06/01/16 14:03:55 aivanov@stripped +3 -2
    Changes from the innodb-5.0-ss115 snapshot.
     os_file_handle_error(): Map the error codes EXDEV, ENOTDIR, and
     EISDIR to the new code OS_FILE_PATH_ERROR. Treat this code as
     OS_FILE_PATH_ERROR. This fixes the crash on RENAME TABLE when
     the .ibd file is a symbolic link to a different file system
     (bug#15991).

  innobase/include/lock0lock.h
    1.26 06/01/16 14:03:55 aivanov@stripped +12 -8
    Changes from the innodb-5.0-ss115 snapshot.

  innobase/include/data0type.ic
    1.27 06/01/16 14:03:55 aivanov@stripped +24 -15
    Changes from the innodb-5.0-ss115 snapshot.
     Fixed bug #14189. dtype_get_pad_char(): Do not pad VARBINARY
     or BINARY cloumns.

  innobase/include/data0type.h
    1.22 06/01/16 14:03:54 aivanov@stripped +2 -1
    Changes from the innodb-5.0-ss115 snapshot.

# 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:	aivanov
# Host:	mysql.creware.com
# Root:	/home/alexi/innodb-ss/mysql-5.0-ss115
--- New file ---
+++ mysql-test/r/innodb_unsafe_binlog.result	06/01/16 14:03:56
drop table if exists t1,t2;
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
id	f_id	f
drop table t1,t2;
create table t1 (id int not null, f_id int not null, f int not null,
primary key(id),key(f_id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id),key(s_id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
delete ml.* from t1 as ml left join t2 as mm on (mm.s_id=ml.f_id) where mm.s is null;
select ml.* from t1 as ml left join t2 as mm on (mm.s_id=ml.f_id) where mm.s is null lock in share mode;
id	f_id	f
drop table t1,t2;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
a	b
1	1
2	2
3	1
4	2
5	1
6	2
update t1 set b = 5 where b = 1;
set autocommit = 0;
select * from t1 where a = 2 and b = 2 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
commit;
drop table t1;

--- New file ---
+++ mysql-test/t/innodb_unsafe_binlog-master.opt	06/01/16 14:03:56
--innodb_locks_unsafe_for_binlog=true

--- New file ---
+++ mysql-test/t/innodb_unsafe_binlog.test	06/01/16 14:03:57
-- source include/have_innodb.inc
#
# Note that these tests uses a innodb_locks_unsafe_for_binlog option.
#
# Test cases for a bug #15650 DELETE with LEFT JOIN crashes server
#

--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
drop table t1,t2;

create table t1 (id int not null, f_id int not null, f int not null,
primary key(id),key(f_id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id),key(s_id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
delete ml.* from t1 as ml left join t2 as mm on (mm.s_id=ml.f_id) where mm.s is null;
select ml.* from t1 as ml left join t2 as mm on (mm.s_id=ml.f_id) where mm.s is null lock in share mode;
drop table t1,t2;

#
# Test case for unlock row bug where unlock releases all locks granted for
# a row. Only the latest lock should be released.
#

connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
commit;
set autocommit = 0; 
select * from t1 lock in share mode;
update t1 set b = 5 where b = 1;
connection b;
set autocommit = 0;
#
# S-lock to records (2,2),(4,2), and (6,2) should not be released in a update
#
--error 1205
select * from t1 where a = 2 and b = 2 for update;
connection a;
commit;
connection b;
commit;
drop table t1;
disconnect a;
disconnect b;



--- 1.21/innobase/include/data0type.h	2005-04-21 16:08:58 +04:00
+++ 1.22/innobase/include/data0type.h	2006-01-16 14:03:54 +03:00
@@ -13,6 +13,7 @@
 
 extern ulint	data_mysql_default_charset_coll;
 #define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8
+#define DATA_MYSQL_BINARY_CHARSET_COLL 63
 
 /* SQL data type struct */
 typedef struct dtype_struct		dtype_t;
@@ -311,7 +312,7 @@
 /*===============*/
 				/* out: padding character code, or
 				ULINT_UNDEFINED if no padding specified */
-	dtype_t*	type);	/* in: type */
+	const dtype_t*	type);	/* in: type */
 /***************************************************************************
 Returns the size of a fixed size data type, 0 if not a fixed size type. */
 UNIV_INLINE

--- 1.26/innobase/include/data0type.ic	2005-09-22 14:09:03 +04:00
+++ 1.27/innobase/include/data0type.ic	2006-01-16 14:03:55 +03:00
@@ -188,26 +188,35 @@
 /*===============*/
 				/* out: padding character code, or
 				ULINT_UNDEFINED if no padding specified */
-	dtype_t*	type)	/* in: type */
+	const dtype_t*	type)	/* in: type */
 {
-	if (type->mtype == DATA_CHAR
-	    || type->mtype == DATA_VARCHAR
-	    || type->mtype == DATA_BINARY
-	    || type->mtype == DATA_FIXBINARY
-	    || type->mtype == DATA_MYSQL
-	    || type->mtype == DATA_VARMYSQL
-	    || (type->mtype == DATA_BLOB
-		&& (type->prtype & DATA_BINARY_TYPE) == 0)) {
-
+	switch (type->mtype) {
+	case DATA_FIXBINARY:
+	case DATA_BINARY:
+		if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
+		    == DATA_MYSQL_BINARY_CHARSET_COLL)) {
+			/* Starting from 5.0.18, do not pad
+			VARBINARY or BINARY columns. */
+			return(ULINT_UNDEFINED);
+		}
+		/* Fall through */
+	case DATA_CHAR:
+	case DATA_VARCHAR:
+	case DATA_MYSQL:
+	case DATA_VARMYSQL:
 		/* Space is the padding character for all char and binary
 	        strings, and starting from 5.0.3, also for TEXT strings. */
 
-		return((ulint)' ');
+		return(0x20);
+	case DATA_BLOB:
+		if ((type->prtype & DATA_BINARY_TYPE) == 0) {
+			return(0x20);
+		}
+		/* Fall through */
+	default:
+		/* No padding specified */
+		return(ULINT_UNDEFINED);
 	}
-
-	/* No padding specified */
-
-	return(ULINT_UNDEFINED);
 }
 
 /**************************************************************************

--- 1.25/innobase/include/lock0lock.h	2005-06-21 08:36:01 +04:00
+++ 1.26/innobase/include/lock0lock.h	2006-01-16 14:03:55 +03:00
@@ -64,14 +64,6 @@
 	dict_index_t*	index,	/* in: clustered index */
 	const ulint*	offsets);/* in: rec_get_offsets(rec, index) */
 /*****************************************************************
-Resets the lock bits for a single record. Releases transactions
-waiting for lock requests here. */
-
-void
-lock_rec_reset_and_release_wait(
-/*============================*/
-	rec_t*	rec);	/* in: record whose locks bits should be reset */
-/*****************************************************************
 Makes a record to inherit the locks of another record as gap type
 locks, but does not reset the lock bits of the other record. Also
 waiting lock requests on rec are inherited as GRANTED gap locks. */
@@ -427,6 +419,18 @@
 /*=============*/
 				/* out: TRUE if there are lock(s) */
 	dict_table_t*	table);	/* in: database table in dictionary cache */
+/*****************************************************************
+Removes a granted record lock of a transaction from the queue and grants
+locks to other transactions waiting in the queue if they now are entitled
+to a lock. */
+
+void
+lock_rec_unlock(
+/*============*/
+	trx_t*	trx,  		/* in: transaction that has set a record
+				lock */
+	rec_t*	rec,		/* in: record */
+	ulint	lock_mode);	/* in: LOCK_S or LOCK_X */
 /*************************************************************************
 Releases a table lock.
 Releases possible other transactions waiting for this lock. */

--- 1.42/innobase/include/os0file.h	2006-01-15 16:43:22 +03:00
+++ 1.43/innobase/include/os0file.h	2006-01-16 14:03:55 +03:00
@@ -91,9 +91,10 @@
 #define	OS_FILE_NOT_FOUND		71
 #define	OS_FILE_DISK_FULL		72
 #define	OS_FILE_ALREADY_EXISTS		73
-#define OS_FILE_AIO_RESOURCES_RESERVED	74	/* wait for OS aio resources
+#define	OS_FILE_PATH_ERROR		74
+#define	OS_FILE_AIO_RESOURCES_RESERVED	75	/* wait for OS aio resources
 						to become available again */
-#define	OS_FILE_ERROR_NOT_SPECIFIED	75
+#define	OS_FILE_ERROR_NOT_SPECIFIED	76
 
 /* Types for aio operations */
 #define OS_FILE_READ	10

--- 1.45/innobase/include/row0mysql.h	2005-09-23 12:20:22 +04:00
+++ 1.46/innobase/include/row0mysql.h	2006-01-16 14:03:55 +03:00
@@ -250,8 +250,9 @@
 really were set. This function removes a newly set lock under prebuilt->pcur,
 and also under prebuilt->clust_pcur. Currently, this is only used and tested
 in the case of an UPDATE or a DELETE statement, where the row lock is of the
-LOCK_X type.
-Thus, this implements a 'mini-rollback' that releases the latest record
+LOCK_X or LOCK_S type. 
+
+Thus, this implements a 'mini-rollback' that releases the latest record 
 locks we set. */
 
 int

--- 1.65/innobase/lock/lock0lock.c	2005-08-17 12:55:41 +04:00
+++ 1.66/innobase/lock/lock0lock.c	2006-01-16 14:03:55 +03:00
@@ -2392,7 +2392,7 @@
 /*****************************************************************
 Resets the lock bits for a single record. Releases transactions waiting for
 lock requests here. */
-
+static
 void
 lock_rec_reset_and_release_wait(
 /*============================*/
@@ -3759,6 +3759,75 @@
 }	
 
 /*=========================== LOCK RELEASE ==============================*/
+
+/*****************************************************************
+Removes a granted record lock of a transaction from the queue and grants
+locks to other transactions waiting in the queue if they now are entitled
+to a lock. */
+
+void
+lock_rec_unlock(
+/*============*/
+	trx_t*	trx,  		/* in: transaction that has set a record
+				lock */
+	rec_t*	rec,		/* in: record */
+	ulint	lock_mode)	/* in: LOCK_S or LOCK_X */
+{
+	lock_t*	lock;
+	lock_t*	release_lock	= NULL;
+	ulint	heap_no;
+
+	ut_ad(trx && rec);
+
+	mutex_enter(&kernel_mutex);
+
+	heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
+
+	lock = lock_rec_get_first(rec);
+
+	/* Find the last lock with the same lock_mode and transaction
+	from the record. */
+
+	while (lock != NULL) {
+		if (lock->trx == trx && lock_get_mode(lock) == lock_mode) {
+			release_lock = lock;
+			ut_a(!lock_get_wait(lock));
+		}
+
+		lock = lock_rec_get_next(rec, lock);
+	}
+
+	/* If a record lock is found, release the record lock */
+
+	if (UNIV_LIKELY(release_lock != NULL)) {
+		lock_rec_reset_nth_bit(release_lock, heap_no);
+	} else {
+		mutex_exit(&kernel_mutex);
+		ut_print_timestamp(stderr);
+		fprintf(stderr,
+"  InnoDB: Error: unlock row could not find a %lu mode lock on the record\n",
+			(ulong)lock_mode);
+
+		return;
+	}
+
+	/* Check if we can now grant waiting lock requests */
+
+	lock = lock_rec_get_first(rec);
+
+	while (lock != NULL) {
+		if (lock_get_wait(lock)
+			&& !lock_rec_has_to_wait_in_queue(lock)) {
+
+			/* Grant the lock */
+			lock_grant(lock);
+		}
+
+		lock = lock_rec_get_next(rec, lock);
+	}
+
+	mutex_exit(&kernel_mutex);
+} 
 
 /*************************************************************************
 Releases a table lock.

--- 1.112/innobase/os/os0file.c	2006-01-15 16:43:22 +03:00
+++ 1.113/innobase/os/os0file.c	2006-01-16 14:03:55 +03:00
@@ -160,15 +160,12 @@
 
 ibool	os_has_said_disk_full	= FALSE;
 
-/* The mutex protecting the following counts of pending pread and pwrite
-operations */
+/* The mutex protecting the following counts of pending I/O operations */
 static os_mutex_t os_file_count_mutex;
 ulint	os_file_n_pending_preads  = 0;
 ulint	os_file_n_pending_pwrites = 0;
-
-/* These are not protected by any mutex */
-ulint os_n_pending_writes = 0;
-ulint os_n_pending_reads = 0;
+ulint	os_n_pending_writes = 0;
+ulint	os_n_pending_reads = 0;
 
 /***************************************************************************
 Gets the operating system version. Currently works only on Windows. */
@@ -314,6 +311,8 @@
 		return(OS_FILE_NOT_FOUND);
 	} else if (err == EEXIST) {
 		return(OS_FILE_ALREADY_EXISTS);
+	} else if (err == EXDEV || err == ENOTDIR || err == EISDIR) {
+		return(OS_FILE_PATH_ERROR);
 	} else {
 		return(100 + err);
 	}
@@ -363,7 +362,8 @@
 
 		return(TRUE);
 
-	} else if (err == OS_FILE_ALREADY_EXISTS) {
+	} else if (err == OS_FILE_ALREADY_EXISTS
+			|| err == OS_FILE_PATH_ERROR) {
 
 		return(FALSE);
 	} else {
@@ -467,7 +467,8 @@
 
 		return(TRUE);
 
-	} else if (err == OS_FILE_ALREADY_EXISTS) {
+	} else if (err == OS_FILE_ALREADY_EXISTS
+			|| err == OS_FILE_PATH_ERROR) {
 
 		return(FALSE);
 	} else {
@@ -1905,12 +1906,14 @@
 #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
         os_mutex_enter(os_file_count_mutex);
 	os_file_n_pending_preads++;
+	os_n_pending_reads++;
         os_mutex_exit(os_file_count_mutex);
 
         n_bytes = pread(file, buf, (ssize_t)n, offs);
 
         os_mutex_enter(os_file_count_mutex);
 	os_file_n_pending_preads--;
+	os_n_pending_reads--;
         os_mutex_exit(os_file_count_mutex);
 
 	return(n_bytes);
@@ -1920,6 +1923,10 @@
 	ssize_t	ret;
 	ulint	i;
 
+        os_mutex_enter(os_file_count_mutex);
+	os_n_pending_reads++;
+        os_mutex_exit(os_file_count_mutex);
+
 	/* Protect the seek / read operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 	
@@ -1928,15 +1935,17 @@
 	ret_offset = lseek(file, offs, SEEK_SET);
 
 	if (ret_offset < 0) {
-		os_mutex_exit(os_file_seek_mutexes[i]);
-
-		return(-1);
+		ret = -1;
+	} else {
+		ret = read(file, buf, (ssize_t)n);
 	}
-	
-	ret = read(file, buf, (ssize_t)n);
 
 	os_mutex_exit(os_file_seek_mutexes[i]);
 
+        os_mutex_enter(os_file_count_mutex);
+	os_n_pending_reads--;
+        os_mutex_exit(os_file_count_mutex);
+
 	return(ret);
 	}
 #endif
@@ -1981,12 +1990,14 @@
 #if defined(HAVE_PWRITE) && !defined(HAVE_BROKEN_PREAD)
         os_mutex_enter(os_file_count_mutex);
 	os_file_n_pending_pwrites++;
+	os_n_pending_writes++;
         os_mutex_exit(os_file_count_mutex);
 
 	ret = pwrite(file, buf, (ssize_t)n, offs);
 
         os_mutex_enter(os_file_count_mutex);
 	os_file_n_pending_pwrites--;
+	os_n_pending_writes--;
         os_mutex_exit(os_file_count_mutex);
 
 # ifdef UNIV_DO_FLUSH
@@ -2008,6 +2019,10 @@
 	off_t	ret_offset;
 	ulint	i;
 
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_writes++;
+	os_mutex_exit(os_file_count_mutex);
+
 	/* Protect the seek / write operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 	
@@ -2016,9 +2031,9 @@
 	ret_offset = lseek(file, offs, SEEK_SET);
 
 	if (ret_offset < 0) {
-		os_mutex_exit(os_file_seek_mutexes[i]);
+		ret = -1;
 
-		return(-1);
+		goto func_exit;
 	}
 	
 	ret = write(file, buf, (ssize_t)n);
@@ -2036,8 +2051,13 @@
 	}
 # endif /* UNIV_DO_FLUSH */
 
+func_exit:
 	os_mutex_exit(os_file_seek_mutexes[i]);
 
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_writes--;
+	os_mutex_exit(os_file_count_mutex);
+
 	return(ret);
 	}
 #endif
@@ -2082,9 +2102,13 @@
 	low = (DWORD) offset;
 	high = (DWORD) offset_high;
 
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_reads++;
+	os_mutex_exit(os_file_count_mutex);
+
 	/* Protect the seek / read operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-	
+
 	os_mutex_enter(os_file_seek_mutexes[i]);
 
 	ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
@@ -2093,17 +2117,21 @@
 
 		os_mutex_exit(os_file_seek_mutexes[i]);
 
+		os_mutex_enter(os_file_count_mutex);
+		os_n_pending_reads--;
+		os_mutex_exit(os_file_count_mutex);
+
 		goto error_handling;
 	} 
 	
-        os_n_pending_reads++;
-        
 	ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
 
-        os_n_pending_reads--;
-
 	os_mutex_exit(os_file_seek_mutexes[i]);
 	
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_reads--;
+	os_mutex_exit(os_file_count_mutex);
+
 	if (ret && len == n) {
 		return(TRUE);
 	}		
@@ -2114,12 +2142,8 @@
 	os_bytes_read_since_printout += n;
 
 try_again:
-        os_n_pending_reads++;
-        
 	ret = os_file_pread(file, buf, n, offset, offset_high);
 
-        os_n_pending_reads--;
-
 	if ((ulint)ret == n) {
 
 		return(TRUE);
@@ -2193,6 +2217,10 @@
 	low = (DWORD) offset;
 	high = (DWORD) offset_high;
 
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_reads++;
+	os_mutex_exit(os_file_count_mutex);
+
 	/* Protect the seek / read operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 	
@@ -2204,17 +2232,21 @@
 
 		os_mutex_exit(os_file_seek_mutexes[i]);
 
+		os_mutex_enter(os_file_count_mutex);
+		os_n_pending_reads--;
+		os_mutex_exit(os_file_count_mutex);
+
 		goto error_handling;
 	} 
 	
-        os_n_pending_reads++;
-        
 	ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
 
-        os_n_pending_reads--;
-        
 	os_mutex_exit(os_file_seek_mutexes[i]);
 	
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_reads--;
+	os_mutex_exit(os_file_count_mutex);
+
 	if (ret && len == n) {
 		return(TRUE);
 	}		
@@ -2225,12 +2257,8 @@
 	os_bytes_read_since_printout += n;
 
 try_again:
-        os_n_pending_reads++;
-
 	ret = os_file_pread(file, buf, n, offset, offset_high);
 
-        os_n_pending_reads--;
-
 	if ((ulint)ret == n) {
 
 		return(TRUE);
@@ -2310,6 +2338,10 @@
 	low = (DWORD) offset;
 	high = (DWORD) offset_high;
 	
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_writes++;
+	os_mutex_exit(os_file_count_mutex);
+
 	/* Protect the seek / write operation with a mutex */
 	i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
 	
@@ -2321,6 +2353,10 @@
 
 		os_mutex_exit(os_file_seek_mutexes[i]);
 		
+		os_mutex_enter(os_file_count_mutex);
+		os_n_pending_writes--;
+		os_mutex_exit(os_file_count_mutex);
+
 		ut_print_timestamp(stderr);
 
 		fprintf(stderr,
@@ -2335,12 +2371,8 @@
 		return(FALSE);
 	} 
 
-        os_n_pending_writes++;
-        
 	ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
 
-        os_n_pending_writes--;
-	
 	/* Always do fsync to reduce the probability that when the OS crashes,
 	a database page is only partially physically written to disk. */
 
@@ -2352,6 +2384,10 @@
 
 	os_mutex_exit(os_file_seek_mutexes[i]);
 
+	os_mutex_enter(os_file_count_mutex);
+	os_n_pending_writes--;
+	os_mutex_exit(os_file_count_mutex);
+
 	if (ret && len == n) {
 
 		return(TRUE);
@@ -2402,11 +2438,7 @@
 #else
 	ssize_t	ret;
 	
-        os_n_pending_writes++;
-        
 	ret = os_file_pwrite(file, buf, n, offset, offset_high);
-
-        os_n_pending_writes--;
         
 	if ((ulint)ret == n) {
 

--- 1.75/innobase/row/row0ins.c	2005-12-13 21:35:14 +03:00
+++ 1.76/innobase/row/row0ins.c	2006-01-16 14:03:55 +03:00
@@ -549,6 +549,15 @@
 					default:
 						ut_error;
 					case 1:
+						if (UNIV_UNLIKELY(
+							dtype_get_charset_coll(
+							dtype_get_prtype(type))
+					== DATA_MYSQL_BINARY_CHARSET_COLL)) {
+						    /* Do not pad BINARY
+						    columns. */
+						    return(ULINT_UNDEFINED);
+						}
+
 						/* space=0x20 */
 						memset(pad_start, 0x20,
 							pad_end - pad_start);

--- 1.116/innobase/row/row0mysql.c	2005-12-13 16:12:46 +03:00
+++ 1.117/innobase/row/row0mysql.c	2006-01-16 14:03:55 +03:00
@@ -1436,8 +1436,9 @@
 really were set. This function removes a newly set lock under prebuilt->pcur,
 and also under prebuilt->clust_pcur. Currently, this is only used and tested
 in the case of an UPDATE or a DELETE statement, where the row lock is of the
-LOCK_X type.
-Thus, this implements a 'mini-rollback' that releases the latest record
+LOCK_X or LOCK_S type. 
+
+Thus, this implements a 'mini-rollback' that releases the latest record 
 locks we set. */
 
 int
@@ -1474,7 +1475,14 @@
 
 	index = btr_pcur_get_btr_cur(pcur)->index;
 
-	if (index != NULL && trx_new_rec_locks_contain(trx, index)) {
+	if (UNIV_UNLIKELY(index == NULL)) {
+		fprintf(stderr,
+"InnoDB: Error: Index is not set for persistent cursor.\n");
+		ut_print_buf(stderr, (const byte*)pcur, sizeof(btr_pcur_t));
+		ut_error;
+	}
+
+	if (trx_new_rec_locks_contain(trx, index)) {
 
 		mtr_start(&mtr);
 			
@@ -1486,11 +1494,7 @@
 
 		rec = btr_pcur_get_rec(pcur);
 
-		mutex_enter(&kernel_mutex);
-
-		lock_rec_reset_and_release_wait(rec);
-
-		mutex_exit(&kernel_mutex);
+		lock_rec_unlock(trx, rec, prebuilt->select_lock_type);
 
 		mtr_commit(&mtr);
 
@@ -1520,11 +1524,7 @@
 
 		rec = btr_pcur_get_rec(clust_pcur);
 
-		mutex_enter(&kernel_mutex);
-
-		lock_rec_reset_and_release_wait(rec);
-
-		mutex_exit(&kernel_mutex);
+		lock_rec_unlock(trx, rec, prebuilt->select_lock_type);
 
 		mtr_commit(&mtr);
 	}

--- 1.104/innobase/row/row0sel.c	2005-09-03 13:48:03 +04:00
+++ 1.105/innobase/row/row0sel.c	2006-01-16 14:03:55 +03:00
@@ -2771,8 +2771,8 @@
 func_exit:
 	*out_rec = clust_rec;
 
-	if (prebuilt->select_lock_type == LOCK_X) {
-		/* We may use the cursor in update: store its position */
+	if (prebuilt->select_lock_type != LOCK_NONE) {
+		/* We may use the cursor in unlock: store its position */
 		
 		btr_pcur_store_position(prebuilt->clust_pcur, mtr);
 	}
@@ -3972,12 +3972,12 @@
 	/* We have an optimization to save CPU time: if this is a consistent
 	read on a unique condition on the clustered index, then we do not
 	store the pcur position, because any fetch next or prev will anyway
-	return 'end of file'. An exception is the MySQL HANDLER command
-	where the user can move the cursor with PREV or NEXT even after
-	a unique search. */
+	return 'end of file'. Exceptions are locking reads and the MySQL 
+	HANDLER command where the user can move the cursor with PREV or NEXT 
+	even after a unique search. */
 
 	if (!unique_search_from_clust_index
-	    || prebuilt->select_lock_type == LOCK_X
+	    || prebuilt->select_lock_type != LOCK_NONE
 	    || prebuilt->used_in_HANDLER) {
 
 		/* Inside an update always store the cursor position */

--- 1.62/innobase/trx/trx0trx.c	2005-09-27 10:42:38 +04:00
+++ 1.63/innobase/trx/trx0trx.c	2006-01-16 14:03:55 +03:00
@@ -794,7 +794,8 @@
 		in trx sys header if MySQL binlogging is on or the database
 		server is a MySQL replication slave */
 
-		if (trx->mysql_log_file_name) {
+		if (trx->mysql_log_file_name
+				&& trx->mysql_log_file_name[0] != '\0') {
 			trx_sys_update_mysql_binlog_offset(
 					trx->mysql_log_file_name,
 					trx->mysql_log_offset,

--- 1.151/mysql-test/r/innodb.result	2006-01-15 16:43:22 +03:00
+++ 1.152/mysql-test/r/innodb.result	2006-01-16 14:03:55 +03:00
@@ -2718,6 +2718,32 @@
 insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
 insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a	hex(b)	hex(c)	filler
+1	61626364656667	61626364656667	boo
+4	D0B1	D0B1	eight
+4	5B	5B	five
+4	E880BD	E880BD	four
+4	E880BDD0B1E880BD	E880BDD0B1E880BD	seven
+4	E880BDE880BD	E880BDE880BD	six
+3	71727374757677	71727374757677	three
+2	696A6B696C6D6E	696A6B696C6D6E	two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a	hex(b)	hex(c)	filler
+4	05630563	05630563	email
+4	0563	0563	email
+4	05612020	05612020	email
+4	01FC	01FC	email
+4	0120	0120	email
+4	00640065	00640065	email
+4	00E400E50068	00E400E50068	email
+4	0000E400	0000E400	email
+4	0000563001FC0563	0000563001FC0563	email
+1	0061006200630064006500660067	0061006200630064006500660067	one
+3	0071007200730074007500760077	0071007200730074007500760077	three
+2	0069006A006B0069006C006D006E	0069006A006B0069006C006D006E	two
 drop table t1;
 drop table t2;
 create table t1 (
@@ -2746,6 +2772,32 @@
 insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
 insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a	hex(b)	hex(c)	filler
+1	61626364656667	61626364656667	boo
+4	D0B1	D0B1	eight
+4	5B	5B	five
+4	E880BD	E880BD	four
+4	E880BDD0B1E880BD	E880BDD0B1E880BD	seven
+4	E880BDE880BD	E880BDE880BD	six
+3	71727374757677	71727374757677	three
+2	696A6B696C6D6E	696A6B696C6D6E	two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a	hex(b)	hex(c)	filler
+4	05630563	05630563	email
+4	0563	0563	email
+4	05612020	05612020	email
+4	01FC	01FC	email
+4	0120	0120	email
+4	00640065	00640065	email
+4	00E400E50068	00E400E50068	email
+4	0000E400	0000E400	email
+4	0000563001FC0563	0000563001FC0563	email
+1	0061006200630064006500660067	0061006200630064006500660067	one
+3	0071007200730074007500760077	0071007200730074007500760077	three
+2	0069006A006B0069006C006D006E	0069006A006B0069006C006D006E	two
 drop table t1;
 drop table t2;
 create table t1 (
@@ -2774,6 +2826,32 @@
 insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
 insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a	hex(b)	hex(c)	filler
+1	61626364656667	61626364656667	boo
+4	D0B1	D0B1	eight
+4	5B	5B	five
+4	E880BD	E880BD	four
+4	E880BDD0B1E880BD	E880BDD0B1E880BD	seven
+4	E880BDE880BD	E880BDE880BD	six
+3	71727374757677	71727374757677	three
+2	696A6B696C6D6E	696A6B696C6D6E	two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a	hex(b)	hex(c)	filler
+4	0120	0120	email
+4	01FC	01FC	email
+4	0563	0563	email
+4	0000563001FC0563	0000563001FC0563	email
+4	0000E400	0000E400	email
+4	00640065	00640065	email
+4	00E400E50068	00E400E50068	email
+4	05612020	05612020	email
+4	05630563	05630563	email
+1	0061006200630064006500660067	0061006200630064006500660067	one
+3	0071007200730074007500760077	0071007200730074007500760077	three
+2	0069006A006B0069006C006D006E	0069006A006B0069006C006D006E	two
 drop table t1;
 drop table t2;
 create table t1 (
@@ -2798,6 +2876,28 @@
 insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight');
 insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+a	hex(b)	hex(c)	filler
+1	61626364656667	61626364656667	boo
+4	D0B1	D0B1	eight
+4	5B	5B	five
+4	E880BD	E880BD	four
+3	71727374757677	71727374757677	three
+2	696A6B696C6D6E	696A6B696C6D6E	two
+select a,hex(b),hex(c),filler from t2 order by filler;
+a	hex(b)	hex(c)	filler
+4	0000E400	0000E400	email
+4	00640065	00640065	email
+4	00E400E50068	00E400E50068	email
+4	0120	0120	email
+4	01FC	01FC	email
+4	05612020	05612020	email
+4	0563	0563	email
+1	61626364656667	61626364656667	one
+3	71727374757677	71727374757677	three
+2	696A6B696C6D6E	696A6B696C6D6E	two
 drop table t1;
 drop table t2;
 commit;
@@ -2833,19 +2933,6 @@
 ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
 set foreign_key_checks=1;
 drop table t2,t3;
-create table t1 (a varchar(255) character set utf8,
-b varchar(255) character set utf8,
-c varchar(255) character set utf8,
-d varchar(255) character set utf8,
-key (a,b,c,d)) engine=innodb;
-drop table t1;
-create table t1 (a varchar(255) character set utf8,
-b varchar(255) character set utf8,
-c varchar(255) character set utf8,
-d varchar(255) character set utf8,
-e varchar(255) character set utf8,
-key (a,b,c,d,e)) engine=innodb;
-ERROR 42000: Specified key was too long; max key length is 3072 bytes
 create table t1(a int primary key) row_format=redundant engine=innodb;
 create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
 create table t3(a int primary key) row_format=compact engine=innodb;
@@ -2875,4 +2962,221 @@
 truncate t1;
 truncate t3;
 drop table t4,t3,t2,t1;
-End of 5.0 tests
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+key (a,b,c,d)) engine=innodb;
+drop table t1;
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+e varchar(255) character set utf8,
+key (a,b,c,d,e)) engine=innodb;
+ERROR 42000: Specified key was too long; max key length is 3072 bytes
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+insert into t1 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 1
+insert into t2 values (0x41),(0x4120);
+insert into t3 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A ' for key 1
+insert into t3 values (0x41),(0x4100);
+insert into t4 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 1
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+hex(s1)
+41
+4100
+4120
+select hex(s1) from t2;
+hex(s1)
+4100
+4120
+select hex(s1) from t3;
+hex(s1)
+4100
+41
+select hex(s1) from t4;
+hex(s1)
+4100
+41
+drop table t1,t2,t3,t4;
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+insert into t2 values(0x42);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x12 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x12345678 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x123457 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1220
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1200
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+4200
+delete from t1 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+delete from t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+a	hex(s1)
+3	4120
+select hex(s1) from t2;
+hex(s1)
+4120
+drop table t2,t1;
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+hex(s1)
+12
+delete from t1 where a=1;
+delete from t1 where a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+select a,hex(s1) from t1;
+a	hex(s1)
+2	12
+select hex(s1) from t2;
+hex(s1)
+12
+drop table t2,t1;
+CREATE TABLE t1 (
+ind enum('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ind enum('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+hex(ind)	hex(string1)
+31	
+32	
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+hex(ind)	hex(string1)
+0031	
+0032	
+drop table t1,t2;
+CREATE TABLE t1 (
+ind set('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ind set('0','1','2') NOT NULL default '0',
+string1 varchar(250) NOT NULL,
+PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+hex(ind)	hex(string1)
+31	
+32	
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+hex(ind)	hex(string1)
+0031	
+0032	
+drop table t1,t2;
+CREATE TABLE t1 (
+ind bit not null,
+string1 varchar(250) NOT NULL,
+PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+ind bit not null,
+string1 varchar(250) NOT NULL,
+PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+insert into t1 values(0,''),(1,'');
+insert into t2 values(0,''),(1,'');
+select hex(ind),hex(string1) from t1 order by string1;
+hex(ind)	hex(string1)
+0	
+1	
+select hex(ind),hex(string1) from t2 order by string1;
+hex(ind)	hex(string1)
+0	
+1	
+drop table t1,t2;
+create table t2 (
+a int, b char(10), filler char(10), primary key(a, b(2)) 
+) character set utf8 engine = innodb;
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t2 (
+a int, b char(10), filler char(10), primary key(a, b(2)) 
+) character set ucs2 engine = innodb;
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+a	hex(b)
+1	61626364656667
+2	6465666768696A6B
+6	D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
+7	D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
+update t1 set b = 'three' where a = 6;
+drop table t1;
+create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+a	hex(b)
+1	61626364656667
+2	6465666768696A6B
+6	D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1
+7	D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2
+update t1 set b = 'three' where a = 6;
+drop table t1;

--- 1.121/mysql-test/t/innodb.test	2006-01-15 16:43:22 +03:00
+++ 1.122/mysql-test/t/innodb.test	2006-01-16 14:03:55 +03:00
@@ -1679,6 +1679,10 @@
 insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
 insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
 drop table t1;
 drop table t2;
 
@@ -1708,6 +1712,10 @@
 insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
 insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
 drop table t1;
 drop table t2;
 
@@ -1737,6 +1745,10 @@
 insert into t2 values (4,_ucs2 0x05630563,_ucs2 0x05630563,'eleven');
 insert into t2 values (4,_ucs2 0x0563001fc0563,_ucs2 0x0563001fc0563,'point');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
 drop table t1;
 drop table t2;
 
@@ -1762,6 +1774,10 @@
 insert into t2 values (4,_ucs2 0x0120,_ucs2 0x0120,'eight');
 insert into t2 values (4,_ucs2 0x0563,_ucs2 0x0563,'ten');
 insert into t2 values (4,_ucs2 0x05612020,_ucs2 0x05612020,'taken');
+update t1 set filler = 'boo' where a = 1;
+update t2 set filler ='email' where a = 4;
+select a,hex(b),hex(c),filler from t1 order by filler;
+select a,hex(b),hex(c),filler from t2 order by filler;
 drop table t1;
 drop table t2;
 commit;
@@ -1816,23 +1832,6 @@
 set foreign_key_checks=1;
 drop table t2,t3;
 
-#
-# Test that we can create a large (>1K) key
-#
-create table t1 (a varchar(255) character set utf8,
-                 b varchar(255) character set utf8,
-                 c varchar(255) character set utf8,
-                 d varchar(255) character set utf8,
-                 key (a,b,c,d)) engine=innodb;
-drop table t1;
---error ER_TOO_LONG_KEY
-create table t1 (a varchar(255) character set utf8,
-                 b varchar(255) character set utf8,
-                 c varchar(255) character set utf8,
-                 d varchar(255) character set utf8,
-                 e varchar(255) character set utf8,
-                 key (a,b,c,d,e)) engine=innodb;
-
 # test that foreign key errors are reported correctly (Bug #15550)
 
 create table t1(a int primary key) row_format=redundant engine=innodb;
@@ -1867,4 +1866,184 @@
 
 drop table t4,t3,t2,t1;
 
---echo End of 5.0 tests
+
+#
+# Test that we can create a large (>1K) key
+#
+create table t1 (a varchar(255) character set utf8,
+                 b varchar(255) character set utf8,
+                 c varchar(255) character set utf8,
+                 d varchar(255) character set utf8,
+                 key (a,b,c,d)) engine=innodb;
+drop table t1;
+--error ER_TOO_LONG_KEY
+create table t1 (a varchar(255) character set utf8,
+                 b varchar(255) character set utf8,
+                 c varchar(255) character set utf8,
+                 d varchar(255) character set utf8,
+                 e varchar(255) character set utf8,
+                 key (a,b,c,d,e)) engine=innodb;
+
+
+# test the padding of BINARY types and collations (Bug #14189)
+
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+
+insert into t1 values (0x41),(0x4120),(0x4100);
+-- error 1062
+insert into t2 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120);
+-- error 1062
+insert into t3 values (0x41),(0x4120),(0x4100);
+insert into t3 values (0x41),(0x4100);
+-- error 1062
+insert into t4 values (0x41),(0x4120),(0x4100);
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+select hex(s1) from t2;
+select hex(s1) from t3;
+select hex(s1) from t4;
+drop table t1,t2,t3,t4;
+
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+-- error 1452
+insert into t2 values(0x42);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+-- error 1451
+update t1 set s1=0x12 where a=1;
+-- error 1451
+update t1 set s1=0x12345678 where a=1;
+-- error 1451
+update t1 set s1=0x123457 where a=1;
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+-- error 1451
+delete from t1 where a=1;
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+-- error 1451
+delete from t1;
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+select hex(s1) from t2;
+
+drop table t2,t1;
+
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+delete from t1 where a=1;
+-- error 1451
+delete from t1 where a=2;
+select a,hex(s1) from t1;
+select hex(s1) from t2;
+
+drop table t2,t1;
+#
+# Test cases for bug #15308 Problem of Order with Enum Column in Primary Key
+#
+CREATE TABLE t1 (
+  ind enum('0','1','2') NOT NULL default '0',
+  string1 varchar(250) NOT NULL,
+  PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+  ind enum('0','1','2') NOT NULL default '0',
+  string1 varchar(250) NOT NULL,
+  PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+drop table t1,t2;
+
+CREATE TABLE t1 (
+  ind set('0','1','2') NOT NULL default '0',
+  string1 varchar(250) NOT NULL,
+  PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+  ind set('0','1','2') NOT NULL default '0',
+  string1 varchar(250) NOT NULL,
+  PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+
+INSERT INTO t1 VALUES ('1', ''),('2', '');
+INSERT INTO t2 VALUES ('1', ''),('2', '');
+SELECT hex(ind),hex(string1) FROM t1 ORDER BY string1;
+SELECT hex(ind),hex(string1) FROM t2 ORDER BY string1;
+drop table t1,t2;
+
+CREATE TABLE t1 (
+  ind bit not null,
+  string1 varchar(250) NOT NULL,
+  PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE t2 (
+  ind bit not null,
+  string1 varchar(250) NOT NULL,
+  PRIMARY KEY  (ind)
+) ENGINE=InnoDB DEFAULT CHARSET=ucs2;
+insert into t1 values(0,''),(1,'');
+insert into t2 values(0,''),(1,'');
+select hex(ind),hex(string1) from t1 order by string1;
+select hex(ind),hex(string1) from t2 order by string1;
+drop table t1,t2;
+
+# tests for bug #14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..'
+
+create table t2 (
+  a int, b char(10), filler char(10), primary key(a, b(2)) 
+) character set utf8 engine = innodb;
+
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+create table t2 (
+  a int, b char(10), filler char(10), primary key(a, b(2)) 
+) character set ucs2 engine = innodb;
+
+insert into t2 values (1,'abcdefg','one');
+insert into t2 values (2,'ijkilmn','two');
+insert into t2 values (3, 'qrstuvw','three');
+update t2 set a=5, filler='booo' where a=1;
+drop table t2;
+
+create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+update t1 set b = 'three' where a = 6;
+drop table t1;
+create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8;
+insert into t1 values(1,'abcdefg'),(2,'defghijk');
+insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1);
+insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2);
+select a,hex(b) from t1 order by b;
+update t1 set b = 'three' where a = 6;
+drop table t1;

--- 1.281/sql/ha_innodb.cc	2006-01-15 16:43:22 +03:00
+++ 1.282/sql/ha_innodb.cc	2006-01-16 14:03:56 +03:00
@@ -1218,7 +1218,7 @@
 				"innobase_buffer_pool_size can't be over 4GB"
 				" on 32-bit systems");
 
-			goto error;
+			DBUG_RETURN(0);
 		}
 
 		if (innobase_log_file_size > UINT_MAX32) {
@@ -1226,7 +1226,7 @@
 				"innobase_log_file_size can't be over 4GB"
 				" on 32-bit systems");
 
-			goto error;
+			DBUG_RETURN(0);
 		}
 	}
 
@@ -1391,6 +1391,7 @@
 
 	ut_a(DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL ==
 					my_charset_latin1.number);
+	ut_a(DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number);
 
 	/* Store the latin1_swedish_ci character ordering table to InnoDB. For
 	non-latin1_swedish_ci charsets we use the MySQL comparison functions,
@@ -2847,8 +2848,6 @@
 	char*		buff_start	= buff;
 	enum_field_types mysql_type;
 	Field*		field;
-	ulint		blob_len;
-	byte*		blob_data;
 	ibool		is_null;
 
   	DBUG_ENTER("store_key_val_for_row");
@@ -2903,14 +2902,18 @@
 			ulint	len;
 			byte*	data;
 			ulint	key_len;
+			ulint	true_len;
 			CHARSET_INFO*	cs;
 			int	error=0;
 
+			key_len = key_part->length;
+
 			if (is_null) {
-				buff += key_part->length + 2;
+				buff += key_len + 2;
 				
 				continue;
 			}
+			cs = field->charset();
 
 			lenlen = (ulint)
 				(((Field_varstring*)field)->length_bytes);
@@ -2920,32 +2923,33 @@
 				+ (ulint)get_field_offset(table, field)),
 				lenlen);
 
-			/* In a column prefix index, we may need to truncate
-			the stored value: */
-		
-			cs = key_part->field->charset();
+			true_len = len;
 
-			if (cs->mbmaxlen > 1 && key_part->length > 0) {
-				key_len = (ulint) cs->cset->well_formed_len(cs, 
-					(const char *) data,
-					(const char *) data + key_part->length,
-					key_part->length / cs->mbmaxlen, 
-					&error);
-			} else {
-				key_len = key_part->length;
+			/* For multi byte character sets we need to calculate
+			the true length of the key */
+
+			if (len > 0 && cs->mbmaxlen > 1) {
+				true_len = (ulint) cs->cset->well_formed_len(cs,
+						(const char *) data,
+						(const char *) data + len,
+						key_len / cs->mbmaxlen, 
+						&error);
 			}
 
-			if (len > key_len) {
-				len = key_len;
+			/* In a column prefix index, we may need to truncate
+			the stored value: */
+
+			if (true_len > key_len) {
+				true_len = key_len;
 			}
 
 			/* The length in a key value is always stored in 2
 			bytes */
 
-			row_mysql_store_true_var_len((byte*)buff, len, 2);
+			row_mysql_store_true_var_len((byte*)buff, true_len, 2);
 			buff += 2;
 
-			memcpy(buff, data, len);
+			memcpy(buff, data, true_len);
 
 			/* Note that we always reserve the maximum possible
 			length of the true VARCHAR in the key value, though
@@ -2953,7 +2957,7 @@
 			actual data. The rest of the space was reset to zero
 			in the bzero() call above. */
 
-			buff += key_part->length;
+			buff += key_len;
 
 		} else if (mysql_type == FIELD_TYPE_TINY_BLOB
 		    || mysql_type == FIELD_TYPE_MEDIUM_BLOB
@@ -2963,58 +2967,66 @@
 			CHARSET_INFO*	cs;
 			ulint		key_len;
 			ulint		len;
+			ulint		true_len;
 			int		error=0;
+			ulint		blob_len;
+			byte*		blob_data;
 
 			ut_a(key_part->key_part_flag & HA_PART_KEY_SEG);
 
+			key_len = key_part->length;
+
 		        if (is_null) {
-				buff += key_part->length + 2;
+				buff += key_len + 2;
 				 
 				continue;
 			}
 		    
+			cs = field->charset();
+
 		        blob_data = row_mysql_read_blob_ref(&blob_len,
 				(byte*) (record
 				+ (ulint)get_field_offset(table, field)),
 					(ulint) field->pack_length());
 
+			true_len = blob_len;
+
 			ut_a(get_field_offset(table, field)
 						     == key_part->offset);
 
+			/* For multi byte character sets we need to calculate
+			the true length of the key */
+			
+			if (blob_len > 0 && cs->mbmaxlen > 1) {
+				true_len = (ulint) cs->cset->well_formed_len(cs,
+						(const char *) blob_data,
+						(const char *) blob_data 
+							+ blob_len,
+						key_len / cs->mbmaxlen,
+						&error);
+			}
+
 			/* All indexes on BLOB and TEXT are column prefix
 			indexes, and we may need to truncate the data to be
 			stored in the key value: */
 
-			cs = key_part->field->charset();
-			
-			if (cs->mbmaxlen > 1 && key_part->length > 0) {
-				key_len = (ulint) cs->cset->well_formed_len(cs, 
-					(const char *) blob_data,
-					(const char *) blob_data 
-						+ key_part->length,
-					key_part->length / cs->mbmaxlen,
-					&error);
-			} else {
-				key_len = key_part->length;
-			}
-
-			if (blob_len > key_len) {
-				blob_len = key_len;
+			if (true_len > key_len) {
+				true_len = key_len;
 			}
 
 			/* MySQL reserves 2 bytes for the length and the
 			storage of the number is little-endian */
 
 			innobase_write_to_2_little_endian(
-					(byte*)buff, (ulint)blob_len);
+					(byte*)buff, true_len);
 			buff += 2;
 
-			memcpy(buff, blob_data, blob_len);
+			memcpy(buff, blob_data, true_len);
 
 			/* Note that we always reserve the maximum possible
 			length of the BLOB prefix in the key value. */
 
-			buff += key_part->length;
+			buff += key_len;
 		} else {
 			/* Here we handle all other data types except the
 			true VARCHAR, BLOB and TEXT. Note that the column
@@ -3022,38 +3034,64 @@
 			index. */
 
 			CHARSET_INFO*		cs;
-			ulint			len;
+			ulint			true_len;
+			ulint			key_len;
 			const mysql_byte*	src_start;
 			int			error=0;
+			enum_field_types	real_type;
+
+			key_len = key_part->length;
 
 		        if (is_null) {
-				 buff += key_part->length;
+				 buff += key_len;
 				 
 				 continue;
 			}
 
-			cs = key_part->field->charset();
 			src_start = record + key_part->offset;
+			real_type = field->real_type();
+			true_len = key_len;
 
-			if (key_part->length > 0 && cs->mbmaxlen > 1) {
-				len = (ulint) cs->cset->well_formed_len(cs, 
-					(const char *) src_start,
-					(const char *) src_start + key_part->length,
-					key_part->length / cs->mbmaxlen, 
-					&error);
-			} else {
-				len = key_part->length;
-			}
-
-			memcpy(buff, src_start, len);
-			buff+=len;
-
-			/* Pad the unused space with spaces */
-
-			if (len < key_part->length) {
-				len = key_part->length - len;
-				memset(buff, ' ', len);
-				buff+=len;
+			/* Character set for the field is defined only
+			to fields whose type is string and real field
+			type is not enum or set. For these fields check
+			if character set is multi byte. */
+
+			if (real_type != FIELD_TYPE_ENUM 
+				&& real_type != FIELD_TYPE_SET
+				&& ( mysql_type == MYSQL_TYPE_VAR_STRING
+					|| mysql_type == MYSQL_TYPE_STRING)) {
+
+				cs = field->charset();
+
+				/* For multi byte character sets we need to 
+				calculate the true length of the key */
+
+				if (key_len > 0 && cs->mbmaxlen > 1) {
+
+					true_len = (ulint) 
+						cs->cset->well_formed_len(cs,
+							(const char *)src_start,
+							(const char *)src_start 
+								+ key_len,
+							key_len / cs->mbmaxlen,
+							&error);
+				}
+			}
+
+			memcpy(buff, src_start, true_len);
+			buff += true_len;
+
+			/* Pad the unused space with spaces. Note that no 
+			padding is ever needed for UCS-2 because in MySQL, 
+			all UCS2 characters are 2 bytes, as MySQL does not 
+			support surrogate pairs, which are needed to represent
+			characters in the range U+10000 to U+10FFFF. */
+
+			if (true_len < key_len) {
+				ulint pad_len = key_len - true_len;
+				memset(buff, ' ', pad_len);
+				buff += pad_len;
 			}
 		}
   	}
@@ -3770,9 +3808,8 @@
 }
 
 /**************************************************************************
-Removes a new lock set on a row. This can be called after a row has been read
-in the processing of an UPDATE or a DELETE query, if the option
-innodb_locks_unsafe_for_binlog is set. */
+Removes a new lock set on a row. This method does nothing unless the 
+option innodb_locks_unsafe_for_binlog is set.*/
 
 void
 ha_innobase::unlock_row(void)
@@ -3794,6 +3831,9 @@
 	if (srv_locks_unsafe_for_binlog) {
 		row_unlock_for_mysql(prebuilt, FALSE);
 	}
+
+	DBUG_VOID_RETURN;
+
 }
 
 /**********************************************************************
Thread
bk commit into 5.0 tree (aivanov:1.2021) BUG#14189Alex Ivanov16 Jan