List:Commits« Previous MessageNext Message »
From:Marc Alff Date:August 19 2011 10:29am
Subject:bzr push into mysql-trunk branch (marc.alff:3272 to 3273)
View as plain text  
 3273 Marc Alff	2011-08-19 [merge]
      Merge mysql-trunk --> mysql-trunk-stage

    added:
      mysql-test/suite/innodb/r/innodb-2byte-collation.result
      mysql-test/suite/innodb/r/innodb_ctype_ldml.result
      mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt
      mysql-test/suite/innodb/t/innodb-2byte-collation.test
      mysql-test/suite/innodb/t/innodb_ctype_ldml-master.opt
      mysql-test/suite/innodb/t/innodb_ctype_ldml.test
      mysql-test/suite/sys_vars/r/innodb_adaptive_max_sleep_delay_basic.result
      mysql-test/suite/sys_vars/t/innodb_adaptive_max_sleep_delay_basic.test
    modified:
      mysql-test/suite/innodb/t/innodb.test
      storage/innobase/data/data0type.c
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/include/btr0sea.h
      storage/innobase/include/data0type.h
      storage/innobase/include/data0type.ic
      storage/innobase/include/dict0mem.h
      storage/innobase/include/srv0conc.h
      storage/innobase/include/srv0srv.h
      storage/innobase/include/sync0sync.h
      storage/innobase/include/trx0trx.h
      storage/innobase/include/trx0trx.ic
      storage/innobase/srv/srv0conc.c
      storage/innobase/srv/srv0srv.c
      storage/innobase/srv/srv0start.c
      storage/innobase/trx/trx0trx.c
 3272 Tatjana Azundris Nuernberg	2011-08-19
      WL#5706
      
      split rewrite tests as suggested by Horst

    added:
      mysql-test/r/rewrite_slow_log.result
      mysql-test/t/rewrite_slow_log.test
    renamed:
      mysql-test/r/rewrite.result => mysql-test/r/rewrite_general_log.result
      mysql-test/t/rewrite.test => mysql-test/t/rewrite_general_log.test
    modified:
      mysql-test/r/rewrite_general_log.result
      mysql-test/t/rewrite_general_log.test
=== added file 'mysql-test/suite/innodb/r/innodb-2byte-collation.result'
Binary files a/mysql-test/suite/innodb/r/innodb-2byte-collation.result	1970-01-01 00:00:00 +0000 and b/mysql-test/suite/innodb/r/innodb-2byte-collation.result	2011-08-19 09:27:11 +0000 differ

=== added file 'mysql-test/suite/innodb/r/innodb_ctype_ldml.result'
--- a/mysql-test/suite/innodb/r/innodb_ctype_ldml.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_ctype_ldml.result	2011-08-19 09:27:11 +0000
@@ -0,0 +1,1121 @@
+drop table if exists t1;
+In the following tests we change the order of letter "b"
+making it equal to letter "a", and check that it works
+with all Unicode character sets
+set names utf8;
+show variables like 'character_sets_dir%';
+Variable_name	Value
+character_sets_dir	MYSQL_TEST_DIR/std_data/
+show collation like 'utf8_phone_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+utf8_phone_ci	utf8	352			8
+CREATE TABLE t1 (
+name VARCHAR(64),
+phone VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_phone_ci
+);
+INSERT INTO t1 VALUES ('Svoj','+7 912 800 80 02');
+INSERT INTO t1 VALUES ('Hf','+7 (912) 800 80 04');
+INSERT INTO t1 VALUES ('Bar','+7-912-800-80-01');
+INSERT INTO t1 VALUES ('Ramil','(7912) 800 80 03');
+INSERT INTO t1 VALUES ('Sanja','+380 (912) 8008005');
+SELECT * FROM t1 ORDER BY phone;
+name	phone
+Sanja	+380 (912) 8008005
+Bar	+7-912-800-80-01
+Svoj	+7 912 800 80 02
+Ramil	(7912) 800 80 03
+Hf	+7 (912) 800 80 04
+SELECT * FROM t1 WHERE phone='+7(912)800-80-01';
+name	phone
+Bar	+7-912-800-80-01
+SELECT * FROM t1 WHERE phone='79128008001';
+name	phone
+Bar	+7-912-800-80-01
+SELECT * FROM t1 WHERE phone='7 9 1 2 8 0 0 8 0 0 1';
+name	phone
+Bar	+7-912-800-80-01
+DROP TABLE t1;
+show collation like 'utf8_test_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+utf8_test_ci	utf8	353			8
+create table t1 (c1 char(1) character set utf8 collate utf8_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+c1
+a
+drop table t1;
+show collation like 'ucs2_test_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+ucs2_test_ci	ucs2	358			8
+create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+c1
+a
+drop table t1;
+show collation like 'utf8mb4_test_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+utf8mb4_test_ci	utf8mb4	326			8
+create table t1 (c1 char(1) character set utf8mb4 collate utf8mb4_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+c1
+a
+drop table t1;
+show collation like 'utf16_test_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+utf16_test_ci	utf16	327			8
+create table t1 (c1 char(1) character set utf16 collate utf16_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+c1
+a
+drop table t1;
+show collation like 'utf32_test_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+utf32_test_ci	utf32	391			8
+create table t1 (c1 char(1) character set utf32 collate utf32_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+c1
+a
+drop table t1;
+SELECT hex(weight_string(_utf8mb4'a' collate utf8mb4_test_ci));
+hex(weight_string(_utf8mb4'a' collate utf8mb4_test_ci))
+120F
+SELECT hex(weight_string(convert(_utf32 0x10002 using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_utf32 0x10002 using utf8mb4) collate utf8mb4_test_ci))
+314A
+SELECT hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_ci), hex(lower(@a));
+hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_ci)	hex(lower(@a))
+F0909080	F09090A8
+SELECT hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_ci), hex(upper(@a));
+hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_ci)	hex(upper(@a))
+F09090A8	F0909080
+SELECT hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_ci), hex(lower(@a));
+hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_ci)	hex(lower(@a))
+E2B080	E2B0B0
+SELECT hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_ci), hex(upper(@a));
+hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_ci)	hex(upper(@a))
+E2B0B0	E2B080
+SELECT hex(weight_string(convert(_utf32 0x61 using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_utf32 0x61 using utf8mb4) collate utf8mb4_test_ci))
+120F
+SELECT hex(weight_string(convert(_utf32 0x62 using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_utf32 0x62 using utf8mb4) collate utf8mb4_test_ci))
+120F
+SELECT hex(weight_string(convert(_utf32 0x10062 using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_utf32 0x10062 using utf8mb4) collate utf8mb4_test_ci))
+120F
+SELECT hex(weight_string(convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_ci))
+30D2
+SELECT hex(weight_string(convert(_utf32 0x100400 using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_utf32 0x100400 using utf8mb4) collate utf8mb4_test_ci))
+30D2
+SELECT hex(weight_string(_utf8mb4 0x64 collate utf8mb4_test_ci));
+hex(weight_string(_utf8mb4 0x64 collate utf8mb4_test_ci))
+1250
+SELECT hex(weight_string(convert(_ucs2 0x0064017e using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_ucs2 0x0064017e using utf8mb4) collate utf8mb4_test_ci))
+1251
+SELECT hex(weight_string(convert(_ucs2 0x0044017e using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_ucs2 0x0044017e using utf8mb4) collate utf8mb4_test_ci))
+1251
+SELECT hex(weight_string(convert(_ucs2 0x0044017d using utf8mb4) collate utf8mb4_test_ci));
+hex(weight_string(convert(_ucs2 0x0044017d using utf8mb4) collate utf8mb4_test_ci))
+1251
+#
+# Bug#45645 Mysql server close all connection and restart using lower function
+#
+CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_test_ci;
+INSERT INTO t1 (a) VALUES ('hello!');
+SELECT * FROM t1 WHERE LOWER(a)=LOWER('N');
+a
+DROP TABLE t1;
+#
+# Bug#51976 LDML collations issue (cyrillic example)
+#
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci);
+INSERT INTO t1 (a) VALUES ('Hello');
+SELECT a, UPPER(a), LOWER(a) FROM t1;
+a	UPPER(a)	LOWER(a)
+Hello	HELLO	hello
+DROP TABLE t1;
+#
+# Bug#43827 Server closes connections and restarts
+#
+CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci);
+INSERT INTO t1 SELECT REPEAT('a',11);
+Warnings:
+Warning	1265	Data truncated for column 'c1' at row 1
+DROP TABLE t1;
+Vietnamese experimental collation
+show collation like 'ucs2_vn_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+ucs2_vn_ci	ucs2	359			8
+create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci);
+insert into t1 values (0x0061),(0x0041),(0x00E0),(0x00C0),(0x1EA3),(0x1EA2),
+(0x00E3),(0x00C3),(0x00E1),(0x00C1),(0x1EA1),(0x1EA0);
+insert into t1 values (0x0103),(0x0102),(0x1EB1),(0x1EB0),(0x1EB3),(0x1EB2),
+(0x1EB5),(0x1EB4),(0x1EAF),(0x1EAE),(0x1EB7),(0x1EB6);
+insert into t1 values (0x00E2),(0x00C2),(0x1EA7),(0x1EA6),(0x1EA9),(0x1EA8),
+(0x1EAB),(0x1EAA),(0x1EA5),(0x1EA4),(0x1EAD),(0x1EAC);
+insert into t1 values ('b'),('B'),('c'),('C');
+insert into t1 values ('d'),('D'),(0x0111),(0x0110);
+insert into t1 values (0x0065),(0x0045),(0x00E8),(0x00C8),(0x1EBB),(0x1EBA),
+(0x1EBD),(0x1EBC),(0x00E9),(0x00C9),(0x1EB9),(0x1EB8);
+insert into t1 values (0x00EA),(0x00CA),(0x1EC1),(0x1EC0),(0x1EC3),(0x1EC2),
+(0x1EC5),(0x1EC4),(0x1EBF),(0x1EBE),(0x1EC7),(0x1EC6);
+insert into t1 values ('g'),('G'),('h'),('H');
+insert into t1 values (0x0069),(0x0049),(0x00EC),(0x00CC),(0x1EC9),(0x1EC8),
+(0x0129),(0x0128),(0x00ED),(0x00CD),(0x1ECB),(0x1ECA);
+insert into t1 values ('k'),('K'),('l'),('L'),('m'),('M');
+insert into t1 values (0x006F),(0x004F),(0x00F2),(0x00D2),(0x1ECF),(0x1ECE),
+(0x00F5),(0x00D5),(0x00F3),(0x00D3),(0x1ECD),(0x1ECC);
+insert into t1 values (0x00F4),(0x00D4),(0x1ED3),(0x1ED2),(0x1ED5),(0x1ED4),
+(0x1ED7),(0x1ED6),(0x1ED1),(0x1ED0),(0x1ED9),(0x1ED8);
+insert into t1 values (0x01A1),(0x01A0),(0x1EDD),(0x1EDC),(0x1EDF),(0x1EDE),
+(0x1EE1),(0x1EE0),(0x1EDB),(0x1EDA),(0x1EE3),(0x1EE2);
+insert into t1 values ('p'),('P'),('q'),('Q'),('r'),('R'),('s'),('S'),('t'),('T');
+insert into t1 values (0x0075),(0x0055),(0x00F9),(0x00D9),(0x1EE7),(0x1EE6),
+(0x0169),(0x0168),(0x00FA),(0x00DA),(0x1EE5),(0x1EE4);
+insert into t1 values (0x01B0),(0x01AF),(0x1EEB),(0x1EEA),(0x1EED),(0x1EEC),
+(0x1EEF),(0x1EEE),(0x1EE9),(0x1EE8),(0x1EF1),(0x1EF0);
+insert into t1 values ('v'),('V'),('x'),('X');
+insert into t1 values (0x0079),(0x0059),(0x1EF3),(0x1EF2),(0x1EF7),(0x1EF6),
+(0x1EF9),(0x1EF8),(0x00FD),(0x00DD),(0x1EF5),(0x1EF4);
+select hex(c1) as h, c1 from t1 order by c1, h;
+h	c1
+0041	A
+0061	a
+00C0	À
+00C1	Á
+00C3	Ã
+00E0	à
+00E1	á
+00E3	ã
+1EA0	4	Ẵ
+1EB5	ẵ
+1EB6	Ặ
+1EB7	ặ
+00C2	Â
+00E2	â
+1EA4	Ấ
+1EA5	ấ
+1EA6	Ầ
+1EA7	ầ
+1EA8	Ẩ
+1EA9	ẩ
+1EAA	Ẫ
+1EAB	ẫ
+1EAC	Ậ
+1EAD	ậ
+0042	B
+0062	b
+0043	C
+0063	c
+0044	D
+0064	d
+0110	Đ
+0111	đ
+0045	E
+0065	e
+00C8	È
+00C9	É
+00E8	è
+00E9	é
+1EB8	Ẹ
+1EB9	ẹ
+1EBA	Ẻ
+1EBB	ẻ
+1EBC	Ẽ
+1EBD	ẽ
+00CA	Ê
+00EA	ê
+1EBE	Ế
+1EBF	ế
+1EC0	Ề
+1EC1	ề
+1EC2	Ể
+1EC3	ể
+1EC4	Ễ
+1EC5	ễ
+1EC6	Ệ
+1EC7	ệ
+0047	G
+0067	g
+0048	H
+0068	h
+0049	I
+0069	i
+00CC	Ì
+00CD	Í
+00EC	ì
+00ED	í
+0128	Ĩ
+0129	ĩ
+1EC8	Ỉ
+1EC9	4D	M
+006D	m
+004F	O
+006F	o
+00D2	Ò
+00D3	Ó
+00D5	Õ
+00F2	ò
+00F3	ó
+00F5	õ
+1ECC	Ọ
+1ECD	ọ
+1ECE	Ỏ
+1ECF	ỏ
+00D4	Ô
+00F4	ô
+1ED0	Ố
+1ED1	ố
+1ED2	Ồ
+1ED3	ồ
+1ED4	Ổ
+1ED5	ổ
+1ED6	Ỗ
+1ED7	ỗ
+1ED8	Ờ
+1EDD	ờ
+1EDE	Ở
+1EDF	ở
+1EE0	Ỡ
+1EE1	ỡ
+1EE2	Ợ
+1EE3	ợ
+0050	P
+0070	p
+0051	Q
+0071	q
+0052	R
+0072	r
+0053	S
+0073	s
+0054	T
+0074	t
+0055	U
+0075	u
+00D9	Ù
+00DA	Ú
+00F9	ù
+00FA	ú
+0168	Ũ
+0169	ũ
+1EE4	Ụ
+1EE5	ụ
+1EE6	Ủ
+1EE7	ủ
+01AF	Ư
+01B0	ư
+1EE8	Ứ
+1EE9	ứ
+1EEA	Ừ
+1EEB	ừ
+1EEC	Ử
+1EED	ử
+1EEE	Ữ
+1EEF	ữ
+1EF0	Ự
+1EF1	ự
+0056	V
+0076	v
+0058	X
+0078	x
+0059	Y
+0079	y
+00DD	Ý
+00FD	ý
+1EF2		Ỹ
+1EF9	ỹ
+select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
+group_concat(hex(c1) order by hex(c1))
+0041,0061,00C0,00C1,00C3,00E0,00E1,00E3,1EA0,1EA1,1EA2,1EA3
+0102,0103,1EAE,1EAF,1EB0,1EB1,1EB2,1EB3,1EB4,1EB5,1EB6,1EB7
+00C2,00E2,1EA4,1EA5,1EA6,1EA7,1EA8,1EA9,1EAA,1EAB,1EAC,1EAD
+0042,0062
+0043,0063
+0044,0064
+0110,0111
+0045,0065,00C8,00C9,00E8,00E9,1EB8,1EB9,1EBA,1EBB,1EBC,1EBD
+00CA,00EA,1EBE,1EBF,1EC0,1EC1,1EC2,1EC3,1EC4,1EC5,1EC6,1EC7
+0047,0067
+0048,0068
+0049,0069,00CC,00CD,00EC,00ED,0128,0129,1EC8,1EC9,1ECA,1ECB
+004B,006B
+004C,006C
+004D,006D
+004F,006F,00D2,00D3,00D5,00F2,00F3,00F5,1ECC,1ECD,1ECE,1ECF
+00D4,00F4,1ED0,1ED1,1ED2,1ED3,1ED4,1ED5,1ED6,1ED7,1ED8,1ED9
+01A0,01A1,1EDA,1EDB,1EDC,1EDD,1EDE,1EDF,1EE0,1EE1,1EE2,1EE3
+0050,0070
+0051,0071
+0052,0072
+0053,0073
+0054,0074
+0055,0075,00D9,00DA,00F9,00FA,0168,0169,1EE4,1EE5,1EE6,1EE7
+01AF,01B0,1EE8,1EE9,1EEA,1EEB,1EEC,1EED,1EEE,1EEF,1EF0,1EF1
+0056,0076
+0058,0078
+0059,0079,00DD,00FD,1EF2,1EF3,1EF4,1EF5,1EF6,1EF7,1EF8,1EF9
+select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
+group_concat(c1 order by hex(c1) SEPARATOR '')
+AaÀÁÃàáãẠạẢả
+ĂăẮắẰằẲẳẴẵẶặ
+ÂâẤấẦầẨẩẪẫẬậ
+Bb
+Cc
+Dd
+Đđ
+EeÈÉèéẸẹẺẻẼẽ
+ÊêẾếỀềỂểỄễỆệ
+Gg
+Hh
+IiÌÍìíĨĩỈỉỊị
+Kk
+Ll
+Mm
+OoÒÓÕòóõỌọỎỏ
+ÔôỐ are not ignored when user collation maps space != 0x20
+set names latin1;
+show collation like 'latin1_test';
+Collation	Charset	Id	Default	Compiled	Sortlen
+latin1_test	latin1	99		Yes	1
+select "foo" = "foo " collate latin1_test;
+"foo" = "foo " collate latin1_test
+1
+The following tests check that two-byte collation IDs work
+select * from information_schema.collations where id>256 order by id;
+COLLATION_NAME	CHARACTER_SET_NAME	ID	IS_DEFAULT	IS_COMPILED	SORTLEN
+utf8mb4_test_ci	utf8mb4	326			8
+utf16_test_ci	utf16	327			8
+utf8mb4_test_400_ci	utf8mb4	328			8
+utf8_bengali_standard_ci	utf8	336			8
+utf8_bengali_traditional_ci	utf8	337			8
+utf8_phone_ci	utf8	352			8
+utf8_test_ci	utf8	353			8
+utf8_5624_1	utf8	354			8
+utf8_5624_2	utf8	355			8
+utf8_5624_3	utf8	356			8
+utf8_5624_4	utf8	357			8
+ucs2_test_ci	ucs2	358			8
+ucs2_vn_ci	ucs2	359			8
+ucs2_5624_1	ucs2	360			8
+utf8_5624_5	utf8	368			8
+utf32_test_ci	utf32	391			8
+utf8_maxuserid_ci	utf8	2047			8
+show collation like '%test%';
+Collation	Charset	Id	Default	Compiled	Sortlen
+latin1_test	latin1	99		Yes	1
+utf8_test_ci	utf8	353			8
+ucs2_test_ci	ucs2	358			8
+utf8mb4_test_ci	utf8mb4	326			8
+utf8mb4_test_400_ci	utf8mb4	328			8
+utf16_test_ci	utf16	327			8
+utf32_test_ci	utf32	391			8
+show collation like 'ucs2_vn_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+ucs2_vn_ci	ucs2	359			8
+create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci);
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `c1` char(1) CHARACTER SET ucs2 COLLATE ucs2_vn_ci DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+insert into t1 values (0x0061);
+set @@character_set_results=NULL;
+select * from t1;
+Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
+def	test	t1	t1	c1	c1	254	2	2	Y	0	0	359
+c1
+a
+drop table t1;
+CREATE TABLE t1 (s1 char(10) character set utf8 collate utf8_maxuserid_ci);
+INSERT INTO t1 VALUES ('a'),('b');
+SELECT * FROM t1 WHERE s1='a' ORDER BY BINARY s1;
+s1
+a
+b
+DROP TABLE t1;
+SET NAMES utf8 COLLATE utf8_phone_ci;
+SHOW COLLATION LIKE 'utf8_phone_ci';
+Collation	Charset	Id	Default	Compiled	Sortlen
+utf8_phone_ci	utf8	352			8
+SET NAMES utf8;
+SELECT hex(weight_string(_utf8mb4'a' collate utf8mb4_test_400_ci));
+hex(weight_string(_utf8mb4'a' collate utf8mb4_test_400_ci))
+0E33
+SELECT hex(weight_string(convert(_utf32 0x10002 using utf8mb4) collate utf8mb4_test_400_ci));
+hex(weight_string(convert(_utf32 0x10002 using utf8mb4) collate utf8mb4_test_400_ci))
+FFFD
+SELECT hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_400_ci)	hex(lower(@a))
+F0909080	F0909080
+SELECT hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_400_ci)	hex(upper(@a))
+F09090A8	F09090A8
+SELECT hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_400_ci)	hex(lower(@a))
+E2B080	E2B080
+SELECT hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_400_ci)	hex(upper(@a))
+E2B0B0	E2B0B0
+#
+# WL#5624 Collation customization improvements
+#
+SET NAMES utf8 COLLATE utf8_5624_1;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 16) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('012345'),('001234'),('000123'),('000012'),('000001');
+INSERT INTO t1 VALUES ('12345'),('01234'),('00123'),('00012'),('00001');
+INSERT INTO t1 VALUES ('1234'),('0123'),('0012'),('0001');
+INSERT INTO t1 VALUES ('123'),('012'),('001');
+INSERT INTO t1 VALUES ('12'),('01');
+INSERT INTO t1 VALUES ('1'),('9');
+INSERT INTO t1 VALUES ('ГАИ'),('ГИБДД');
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e');
+INSERT INTO t1 VALUES ('cz'),('Ċ'),('ċ');
+INSERT INTO t1 VALUES ('f'),('fz'),('g'),('Ġ'),('ġ');
+INSERT INTO t1 VALUES ('h'),('hz'),('GĦ'),('Għ'),('gĦ'),('għ');
+INSERT INTO t1 VALUES ('i'),('iz'),('Ħ'),('ħ');
+INSERT INTO t1 VALUES ('y'),('yz'),('z'),('Ż'),('ż');
+INSERT INTO t1 VALUES ('ā'),('Ā'),('á'),('Á'),('à'),('À');
+INSERT INTO t1 VALUES ('ē'),('é'),('ě'),('ê'),('Ē'),('É'),('Ě'),('Ê');
+INSERT INTO t1 VALUES ('a'),('~'),('!'),('@'),('#'),('$'),('%'),('^');
+INSERT INTO t1 VALUES ('('),(')'),('-'),('+'),('|'),('='),(':'),(';');
+INSERT INTO t1 VALUES ('"'),('\''),('?');
+INSERT INTO t1 VALUES ('ch'),('k'),('cs'),('ccs'),('cscs');
+INSERT INTO t1 VALUES ('aa-'),('ab-'),('ac-'),('ad-'),('ae-'),('af-'),('az-');
+INSERT INTO t1 VALUES ('lp-fni'),('lp-lni');
+INSERT INTO t1 VALUES ('lp-fpi'),('lp-lpi');
+INSERT INTO t1 VALUES ('lp-fsi'),('lp-lsi');
+INSERT INTO t1 VALUES ('lp-fti'),('lp-lti');
+INSERT INTO t1 VALUES ('lp-ft'),('lp-lt');
+INSERT INTO t1 VALUES ('lp-fv'),('lp-lv');
+INSERT INTO t1 VALUES ('lb-fni'),('lb-lni');
+INSERT INTO t1 VALUES ('lb-fv'),('lb-lv');
+INSERT INTO t1 VALUES (_ucs2 0x3106),(_ucs2 0x3110), (_ucs2 0x3111), (_ucs2 0x3112);
+INSERT INTO t1 VALUES (_ucs2 0x32A3), (_ucs2 0x3231);
+INSERT INTO t1 VALUES (_ucs2 0x84D9), (_ucs2 0x98F5), (_ucs2 0x7CF3), (_ucs2 0x5497);
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY a;
+a	HEX(WEIGHT_STRING(a))
+lp-ft	0001
+lp-lt	0001
+lp-fpi	0001
+lp-fsi	0001
+lp-fti	0001
+lp-lpi	0001
+lp-lsi	0001
+lp-lti	0001
+lb-fv	0200233E
+lb-fni	0200233E
+lp-fv	0202
+lp-fni	0202
+-	0221
+=	042D
+|	0430
+lb-lv	0DD9233E
+lp-lv	0DDB
+1	0E2A
+01	0E2A
+001	0E2A
+0001	0E2A
+00001	0E2A
+000001	0E2A
+12	0E2A0E2B
+012	0E2A0E2B
+0012	0E2A0E2B
+00012	0E2A0E2B
+000012	0E2A0E2B
+123	0E2A0E2B0E2C
+0123	0E2A0E2B0E2C
+00123	0E2A0E2B0E2C
+000123	0E2A0E2B0E2C
+1234	0E2A0E2B0E2C0E2D
+01234	0E2A0E2B0E2C0E2D
+001234	0E2A0E2B0E2C0E2D
+12345	0E2A0E2B0E2C0E2D0E2E
+012345	0E2A0E2B0E2C0E2D0E2E
+9	0E32
+~	0E32233E
+!	0E32233F
+@	0E322340
+#	0E322341
+$	0E322342
+%	0E322343
+^	0E322344
+(	0E322346
+)	0E322347
++	0E322348
+:	0E322349
+;	0E32234A
+"	0E32234B
+'	0E32234C
+?	0E32234D
+a	0E33
+a	0E33
+aa-	0E330E330221
+ab-	0E330E4A0E34
+ac-	0E330E600E60
+ad-	0E330E6D0E6D
+ae-	0E330E8B0E8B
+af-	0E330EB90EB9
+az-	0E33106A0221
+b	0E4A
+À	0E4A
+Á	0E4A
+à	0E4A
+á	0E4A
+Ā	0E4A
+ā	0E4A
+c	0E60
+k	0E600EE1
+ch	0E600EE1
+cs	0E600FEA
+ccs	0E600FEA0E600FEA
+cscs	0E600FEA0E600FEA
+cz	0E60106A
+Ċ	0E6C233E
+ċ	0E6C233E
+d	0E6D
+É	0E6D
+Ê	0E6D
+é	0E6D
+ê	0E6D
+Ē	0E6D
+ē	0E6D
+Ě	0E6D
+ě	0E6D
+e	0E8B
+f	0EB9
+fz	0EB9106A
+Ġ	0EC0233E
+ġ	0EC0233E
+g	0EC1
+GĦ	0EE0233E
+Għ	0EE0233E
+gĦ	0EE0233E
+għ	0EE0233E
+h	0EE1
+hz	0EE1106A
+Ħ	0EFA233E
+ħ	0EFA233E
+i	0EFB
+iz	0EFB106A
+y	105E
+yz	105E106A
+Ż	1069233E
+ż	1069233E
+z	106A
+ГАИ	11341114117C
+ГИБДД	11341114117C
+lb-lni	233C233E
+lp-lni	233E
+ㄆ	233F
+ㄐ	2349
+ㄑ	234A
+ㄒ	234B
+㊣	7147
+㈱	72D5
+蓙	753C
+飵	753D
+糳	753E
+咗	753F
+#
+# WL#5624, the same test with UCS2
+#
+ALTER TABLE t1 CONVERT TO CHARACTER SET ucs2 COLLATE ucs2_5624_1;
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+a	HEX(WEIGHT_STRING(a))
+lp-ft	0001
+lp-lt	0001
+lp-fpi	0001
+lp-fsi	0001
+lp-fti	0001
+lp-lpi	0001
+lp-lsi	0001
+lp-lti	0001
+lb-fv	0200233E
+lb-fni	0200233E
+lp-fv	0202
+lp-fni	0202
+-	0221
+=	042D
+|	0430
+lb-lv	0DD9233E
+lp-lv	0DDB
+1	0E2A
+01	0E2A
+001	0E2A
+0001	0E2A
+00001	0E2A
+000001	0E2A
+12	0E2A0E2B
+012	0E2A0E2B
+0012	0E2A0E2B
+00012	0E2A0E2B
+000012	0E2A0E2B
+123	0E2A0E2B0E2C
+0123	0E2A0E2B0E2C
+00123	0E2A0E2B0E2C
+000123	0E2A0E2B0E2C
+1234	0E2A0E2B0E2C0E2D
+01234	0E2A0E2B0E2C0E2D
+001234	0E2A0E2B0E2C0E2D
+12345	0E2A0E2B0E2C0E2D0E2E
+012345	0E2A0E2B0E2C0E2D0E2E
+9	0E32
+~	0E32233E
+!	0E32233F
+@	0E322340
+#	0E322341
+$	0E322342
+%	0E322343
+^	0E322344
+(	0E322346
+)	0E322347
++	0E322348
+:	0E322349
+;	0E32234A
+"	0E32234B
+'	0E32234C
+?	0E32234D
+a	0E33
+a	0E33
+aa-	0E330E330221
+ab-	0E330E4A0E34
+ac-	0E330E600E60
+ad-	0E330E6D0E6D
+ae-	0E330E8B0E8B
+af-	0E330EB90EB9
+az-	0E33106A0221
+b	0E4A
+À	0E4A
+Á	0E4A
+à	0E4A
+á	0E4A
+Ā	0E4A
+ā	0E4A
+c	0E60
+k	0E600EE1
+ch	0E600EE1
+cs	0E600FEA
+ccs	0E600FEA0E600FEA
+cscs	0E600FEA0E600FEA
+cz	0E60106A
+Ċ	0E6C233E
+ċ	0E6C233E
+d	0E6D
+É	0E6D
+Ê	0E6D
+é	0E6D
+ê	0E6D
+Ē	0E6D
+ē	0E6D
+Ě	0E6D
+ě	0E6D
+e	0E8B
+f	0EB9
+fz	0EB9106A
+Ġ	0EC0233E
+ġ	0EC0233E
+g	0EC1
+GĦ	0EE0233E
+Għ	0EE0233E
+gĦ	0EE0233E
+għ	0EE0233E
+h	0EE1
+hz	0EE1106A
+Ħ	0EFA233E
+ħ	0EFA233E
+i	0EFB
+iz	0EFB106A
+y	105E
+yz	105E106A
+Ż	1069233E
+ż	1069233E
+z	106A
+ГАИ	11341114117C
+ГИБДД	11341114117C
+lb-lni	233C233E
+lp-lni	233E
+ㄆ	233F
+ㄐ	2349
+ㄑ	234A
+ㄒ	234B
+㊣	7147
+㈱	72D5
+蓙	753C
+飵	753D
+糳	753E
+咗	753F
+DROP TABLE t1;
+#
+# WL#5624, unsupported features
+#
+SET NAMES utf8 COLLATE utf8_5624_2;
+ERROR HY000: Unknown collation: 'utf8_5624_2'
+SHOW WARNINGS;
+Level	Code	Message
+Error	1273	Unknown collation: 'utf8_5624_2'
+Warning	1273	Syntax error at '[strength tertiary]'
+#
+# WL#5624, reset before primary ignorable
+#
+SET NAMES utf8 COLLATE utf8_5624_3;
+ERROR HY000: Unknown collation: 'utf8_5624_3'
+SHOW WARNINGS;
+Level	Code	Message
+Error	1273	Unknown collation: 'utf8_5624_3'
+Warning	1273	Can't reset before a primary ignorable character U+A48C
+#
+# WL#5624, \u without hex digits is equal to {'\', 'u'}
+#
+SET NAMES utf8 COLLATE utf8_5624_4;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('\\'),('u'),('x'),('X');
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+a	HEX(WEIGHT_STRING(a))
+\	02CE
+x	02CE101F
+u	101F
+X	105A
+DROP TABLE t1;
+#
+# WL#5624, testing Bengali collations
+#
+SET NAMES utf8, collation_connection=utf8_bengali_standard_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES (_ucs2 0x09FA), (_ucs2 0x09F8), (_ucs2 0x09F9), (_ucs2 0x09F2);
+INSERT INTO t1 VALUES (_ucs2 0x09DC), (_ucs2 0x09A109BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A2), (_ucs2 0x09DD), (_ucs2 0x09A209BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A3);
+SELECT HEX(WEIGHT_STRING(a)), HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY a;
+HEX(WEIGHT_STRING(a))	HEX(CONVERT(a USING ucs2))	HEX(a)
+0350	09FA	E0A7BA
+0351	09F8	E0A7B8
+0352	09F9	E0A7B9
+0353	09F2	E0A7B2
+0374	09A109BC	E0A6A1E0A6BC
+0374	09DC	E0A79C
+0375	09A2	E0A6A2
+0376	09A209BC	E0A6A2E0A6BC
+0376	09DD	E0A79D
+0377	09A3	E0A6A3
+DROP TABLE t1;
+SET NAMES utf8, collation_connection=utf8_bengali_traditional_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES
+(_ucs2 0x0985),(_ucs2 0x0986),(_ucs2 0x0987),(_ucs2 0x0988),
+(_ucs2 0x0989),(_ucs2 0x098A),(_ucs2 0x098B),(_ucs2 0x09E0),
+(_ucs2 0x098C),(_ucs2 0x09E1),(_ucs2 0x098F),(_ucs2 0x0990),
+(_ucs2 0x0993);
+INSERT INTO t1 VALUES
+(_ucs2 0x0994),(_ucs2 0x0982),(_ucs2 0x0983),(_ucs2 0x0981),
+(_ucs2 0x099509CD), (_ucs2 0x099609CD), (_ucs2 0x099709CD), (_ucs2 0x099809CD),
+(_ucs2 0x099909CD), (_ucs2 0x099A09CD), (_ucs2 0x099B09CD), (_ucs2 0x099C09CD),
+(_ucs2 0x099D09CD), (_ucs2 0x099E09CD), (_ucs2 0x099F09CD), (_ucs2 0x09A009CD),
+(_ucs2 0x09A109CD), (_ucs2 0x09A209CD), (_ucs2 0x09A309CD),
+(_ucs2 0x09CE), (_ucs2 0x09A409CD200D), (_ucs2 0x09A409CD),
+(_ucs2 0x09A509CD),(_ucs2 0x09A609CD),
+(_ucs2 0x09A709CD), (_ucs2 0x09A809CD), (_ucs2 0x09AA09CD), (_ucs2 0x09AB09CD),
+(_ucs2 0x09AC09CD), (_ucs2 0x09AD09CD), (_ucs2 0x09AE09CD), (_ucs2 0x09AF09CD),
+(_ucs2 0x09B009CD), (_ucs2 0x09F009CD), (_ucs2 0x09B209CD), (_ucs2 0x09F109CD),
+(_ucs2 0x09B609CD), (_ucs2 0x09B709CD), (_ucs2 0x09B809CD), (_ucs2 0x09B909CD);
+INSERT INTO t1 VALUES 
+(_ucs2 0x099509CD0985),(_ucs2 0x0995),
+(_ucs2 0x099509CD0986),(_ucs2 0x099509BE),
+(_ucs2 0x099509CD0987),(_ucs2 0x099509BF),
+(_ucs2 0x099509CD0988),(_ucs2 0x099509C0),
+(_ucs2 0x099509CD0989),(_ucs2 0x099509C1),
+(_ucs2 0x099509CD098A),(_ucs2 0x099509C2),
+(_ucs2 0x099509CD098B),(_ucs2 0x099509C3),
+(_ucs2 0x099509CD09E0),(_ucs2 0x099509C4),
+(_ucs2 0x099509CD098C),(_ucs2 0x099509E2),
+(_ucs2 0x099509CD09E1),(_ucs2 0x099509E3),
+(_ucs2 0x099509CD098F),(_ucs2 0x099509C7),
+(_ucs2 0x099509CD0990),(_ucs2 0x099509C8),
+(_ucs2 0x099509CD0993),(_ucs2 0x099509CB),
+(_ucs2 0x099509CD0994),(_ucs2 0x099509CC);
+SELECT HEX(WEIGHT_STRING(a)), HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY(a);
+HEX(WEIGHT_STRING(a))	HEX(CONVERT(a USING ucs2))	HEX(a)
+15A2	0985	E0A685
+15A3	0986	E0A686
+15A4	0987	E0A687
+15A5	0988	E0A688
+15A6	0989	E0A689
+15A7	098A	E0A68A
+15A8	098B	E0A68B
+15A9	09E0	E0A7A0
+15AA	098C	E0A68C
+15AB	09E1	E0A7A1
+15AC	098F	E0A68F
+15AD	0990	E0A690
+15AE	0993	E0A693
+15AF	0994	E0A694
+15B0	0982	E0A682
+15B1	0983	E0A683
+15B2	0981	E0A681
+15B3	099509CD	E0A695E0A78D
+15B315A2	0995	E0A695
+15B315A2	099509CD0985	E0A695E0A78DE0A685
+15B315A3	099509BE	E0A695E0A6BE
+15B315A3	099509CD0986	E0A695E0A78DE0A686
+15B315A4	099509BF	E0A695E0A6BF
+15B315A4	099509CD0987	E0A695E0A78DE0A687
+15B315A5	099509C0	E0A695E0A780
+15B315A5	099509CD0988	E0A695E0A78DE0A688
+15B315A6	099509C1	E0A695E0A781
+15B315A6	099509CD0989	E0A695E0A78DE0A689
+15B315A7	099509C2	E0A695E0A782
+15B315A7	099509CD098A	E0A695E0A78DE0A68A
+15B315A8	099509C3	E0A695E0A783
+15B315A8	099509CD098B	E0A695E0A78DE0A68B
+15B315A9	099509C4	E0A695E0A784
+15B315A9	099509CD09E0	E0A695E0A78DE0A7A0
+15B315AA	099509CD098C	E0A695E0A78DE0A68C
+15B315AA	099509E2	E0A695E0A7A2
+15B315AB	099509CD09E1	E0A695E0A78DE0A7A1
+15B315AB	099509E3	E0A695E0A7A3
+15B315AC	099509C7	E0A695E0A787
+15B315AC	099509CD098F	E0A695E0A78DE0A68F
+15B315AD	099509C8	E0A695E0A788
+15B315AD	099509CD0990	E0A695E0A78DE0A690
+15B315AE	099509CB	E0A695E0A78B
+15B315AE	099509CD0993	E0A695E0A78DE0A693
+15B315AF	099509CC	E0A695E0A78C
+15B315AF	099509CD0994	E0A695E0A78DE0A694
+15B4	099609CD	E0A696E0A78D
+15B5	099709CD	E0A697E0A78D
+15B6	099809CD	E0A698E0A78D
+15B7	099909CD	E0A699E0A78D
+15B8	099A09CD	E0A69AE0A78D
+15B9	099B09CD	E0A69BE0A78D
+15BA	099C09CD	E0A69CE0A78D
+15BB	099D09CD	E0A69DE0A78D
+15BC	099E09CD	E0A69EE0A78D
+15BD	099F09CD	E0A69FE0A78D
+15BE	09A009CD	E0A6A0E0A78D
+15BF	09A109CD	E0A6A1E0A78D
+15C0	09A209CD	E0A6A2E0A78D
+15C1	09A309CD	E0A6A3E0A78D
+15C2	09A409CD	E0A6A4E0A78D
+15C2	09A409CD200D	E0A6A4E0A78DE2808D
+15C2	09CE	E0A78E
+15C3	09A509CD	E0A6A5E0A78D
+15C4	09A609CD	E0A6A6E0A78D
+15C5	09A709CD	E0A6A7E0A78D
+15C6	09A809CD	E0A6A8E0A78D
+15C7	09AA09CD	E0A6AAE0A78D
+15C8	09AB09CD	E0A6ABE0A78D
+15C9	09AC09CD	E0A6ACE0A78D
+15CA	09AD09CD	E0A6ADE0A78D
+15CB	09AE09CD	E0A6AEE0A78D
+15CC	09AF09CD	E0A6AFE0A78D
+15CD	09B009CD	E0A6B0E0A78D
+15CE	09F009CD	E0A7B0E0A78D
+15CF	09B209CD	E0A6B2E0A78D
+15D0	09F109CD	E0A7B1E0A78D
+15D1	09B609CD	E0A6B6E0A78D
+15D2	09B709CD	E0A6B7E0A78D
+15D3	09B809CD	E0A6B8E0A78D
+15D4	09B909CD	E0A6B9E0A78D
+SELECT HEX(WEIGHT_STRING(a)) as wa,
+GROUP_CONCAT(HEX(CONVERT(a USING ucs2)) ORDER BY LENGTH(a), BINARY a)
+FROM t1 GROUP BY a ORDER BY a;
+wa	GROUP_CONCAT(HEX(CONVERT(a USING ucs2)) ORDER BY LENGTH(a), BINARY a)
+15A2	0985
+15A3	0986
+15A4	0987
+15A5	0988
+15A6	0989
+15A7	098A
+15A8	098B
+15A9	09E0
+15AA	098C
+15AB	09E1
+15AC	098F
+15AD	0990
+15AE	0993
+15AF	0994
+15B0	0982
+15B1	0983
+15B2	0981
+15B3	099509CD
+15B315A2	0995,099509CD0985
+15B315A3	099509BE,099509CD0986
+15B315A4	099509BF,099509CD0987
+15B315A5	099509C0,099509CD0988
+15B315A6	099509C1,099509CD0989
+15B315A7	099509C2,099509CD098A
+15B315A8	099509C3,099509CD098B
+15B315A9	099509C4,099509CD09E0
+15B315AA	099509E2,099509CD098C
+15B315AB	099509E3,099509CD09E1
+15B315AC	099509C7,099509CD098F
+15B315AD	099509C8,099509CD0990
+15B315AE	099509CB,099509CD0993
+15B315AF	099509CC,099509CD0994
+15B4	099609CD
+15B5	099709CD
+15B6	099809CD
+15B7	099909CD
+15B8	099A09CD
+15B9	099B09CD
+15BA	099C09CD
+15BB	099D09CD
+15BC	099E09CD
+15BD	099F09CD
+15BE	09A009CD
+15BF	09A109CD
+15C0	09A209CD
+15C1	09A309CD
+15C2	09CE,09A409CD,09A409CD200D
+15C3	09A509CD
+15C4	09A609CD
+15C5	09A709CD
+15C6	09A809CD
+15C7	09AA09CD
+15C8	09AB09CD
+15C9	09AC09CD
+15CA	09AD09CD
+15CB	09AE09CD
+15CC	09AF09CD
+15CD	09B009CD
+15CE	09F009CD
+15CF	09B209CD
+15D0	09F109CD
+15D1	09B609CD
+15D2	09B709CD
+15D3	09B809CD
+15D4	09B909CD
+DROP TABLE t1;
+#
+# WL#5624, shift after, using expansion
+#
+SET NAMES utf8 COLLATE utf8_5624_5;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('0'),('1'),('0z'),(_ucs2 0x0030FF9D);
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i');
+INSERT INTO t1 VALUES ('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r');
+INSERT INTO t1 VALUES ('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z');
+INSERT INTO t1 VALUES ('aa'),('aaa');
+INSERT INTO t1 VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I');
+INSERT INTO t1 VALUES ('J'),('K'),('L'),('M'),('N'),('O'),('P'),('Q'),('R');
+INSERT INTO t1 VALUES ('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z');
+INSERT INTO t1 VALUES ('AA'),('AAA');
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+a	HEX(WEIGHT_STRING(a))
+0	0E29
+0z	0E290E292357
+041
+e	0E292342
+f	0E292343
+g	0E292344
+h	0E292345
+i	0E292346
+j	0E292347
+k	0E292348
+l	0E292349
+m	0E29234A
+n	0E29234B
+o	0E29234C
+p	0E29234D
+q	0E29234E
+r	0E29234F
+s	0E292350
+t	0E292351
+u	0E292352
+v	0E292353
+w	0E292354
+x	0E292355
+y	0E292356
+z	0E292357
+aa	0E292358
+aaa	0E292359
+A	0E29333E
+B	0E29333F
+C	0E293340
+D	0E293341
+E	0E293342
+F	0E293343
+G	0E293344
+H	0E293345
+I	0E293346
+J	0E293347
+K	0E293348
+L	0E293349
+M	0E29334A
+N	0E29334B
+O	0E29334C
+P	0E29334D
+Q	0E29334E
+R	0E29334F
+S	0E293350
+T	0E293351
+U	0E293352
+V	0E293353
+W	0E293354
+X	0E293355
+Y	0E293356
+Z	0E293357
+AA	0E293358
+AAA	0E293359
+1	0E2A
+DROP TABLE t1;
+#
+# End of WL#5624
+#

=== added file 'mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt'
--- a/mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb-2byte-collation-master.opt	2011-08-19 09:27:11 +0000
@@ -0,0 +1,2 @@
+--character-sets-dir=$MYSQL_TEST_DIR/std_data/
+

=== added file 'mysql-test/suite/innodb/t/innodb-2byte-collation.test'
--- a/mysql-test/suite/innodb/t/innodb-2byte-collation.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb-2byte-collation.test	2011-08-19 09:27:11 +0000
@@ -0,0 +1,88 @@
+# Test for InnoDB support of 2 bytes (15 bits) collation ID
+# Some of the example and test setup are adopted from ctype_ldml.test
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_ucs2.inc
+--source include/have_utf8mb4.inc
+--source include/have_utf16.inc
+--source include/have_utf32.inc
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+show variables like 'character_sets_dir%';
+
+set names utf8;
+
+# Test that the "ID" column in I_S and SHOW queries can handle two bytes
+select * from information_schema.collations where id>256 order by id;
+show collation like '%test%';
+
+# Test that two-byte collation ID is correctly transfered to the client side.
+show collation like 'ucs2_vn_ci';
+create table 2byte_collation (c1 char(1) character set ucs2 collate ucs2_vn_ci)
+engine = InnoDB;
+
+insert into 2byte_collation values (0x0061);
+--enable_metadata
+set @@character_set_results=NULL;
+select * from 2byte_collation;
+--disable_metadata
+drop table 2byte_collation;
+
+#
+# Check maximum collation ID (2047 as of MySQL-6.0.9)
+#
+CREATE TABLE 2byte_collation (s1 char(10) character set utf8 collate utf8_maxuserid_ci) engine = innodb;
+INSERT INTO 2byte_collation VALUES ('a'),('b');
+SELECT * FROM 2byte_collation WHERE s1='a' ORDER BY BINARY s1;
+DROP TABLE 2byte_collation;
+
+# Excercise some change buffer code with the help of
+# "innodb_change_buffering_debug"
+-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
+SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug;
+-- error 0,ER_UNKNOWN_SYSTEM_VARIABLE
+SET GLOBAL innodb_change_buffering_debug = 1;
+
+-- enable_query_log
+
+set names utf8;
+
+show collation like 'utf8_maxuserid_ci';
+
+CREATE TABLE 2byte_collation(
+       a INT AUTO_INCREMENT PRIMARY KEY,
+       b CHAR(100) character set utf8 collate utf8_maxuserid_ci,
+       c INT,
+       z INT,
+       INDEX(b))
+ENGINE=InnoDB;
+
+INSERT INTO 2byte_collation VALUES(0,'x',1, 1);
+
+CREATE UNIQUE INDEX idx3 ON 2byte_collation(c, b);
+
+INSERT INTO 2byte_collation SELECT 0,b,c+1,z+1 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+10,z+10 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+20,z+20 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+50,z+50 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+100,z+100 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+200,z+200 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+400,z+400 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+800,z+800 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+1600,z+1600 FROM 2byte_collation;
+INSERT INTO 2byte_collation SELECT 0,b,c+4000,z+4000 FROM 2byte_collation;
+
+CREATE INDEX idx5 ON 2byte_collation(b, c);
+
+SELECT b FROM 2byte_collation LIMIT 10;
+
+INSERT INTO 2byte_collation VALUES (10001, "a", 20001, 20001);
+
+UPDATE 2byte_collation set b = "aaa" where c = 20001;
+
+DROP TABLE 2byte_collation;
+
+-- error 0, ER_UNKNOWN_SYSTEM_VARIABLE
+SET GLOBAL innodb_change_buffering_debug = 0;
+

=== modified file 'mysql-test/suite/innodb/t/innodb.test'
--- a/mysql-test/suite/innodb/t/innodb.test	2011-05-19 12:43:26 +0000
+++ b/mysql-test/suite/innodb/t/innodb.test	2011-08-19 06:13:33 +0000
@@ -32,6 +32,8 @@ let $MYSQLD_DATADIR= `select @@datadir`;
 # the test to be run multiple times without restarting the mysqld server.
 # See Bug#43309 Test main.innodb can't be run twice
 -- disable_query_log
+SET @innodb_thread_sleep_delay_orig = @@innodb_thread_sleep_delay;
+
 SET @innodb_thread_concurrency_orig = @@innodb_thread_concurrency;
 
 SET @innodb_rows_deleted_orig = (SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted');
@@ -2551,6 +2553,7 @@ DROP TABLE bug35537;
 DISCONNECT c1;
 CONNECTION default;
 
+SET GLOBAL innodb_thread_sleep_delay = @innodb_thread_sleep_delay_orig;
 SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
 
 -- enable_query_log

=== added file 'mysql-test/suite/innodb/t/innodb_ctype_ldml-master.opt'
--- a/mysql-test/suite/innodb/t/innodb_ctype_ldml-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_ctype_ldml-master.opt	2011-08-19 09:27:11 +0000
@@ -0,0 +1,3 @@
+--character-sets-dir=$MYSQL_TEST_DIR/std_data/
+--default-storage-engine=InnoDB
+

=== added file 'mysql-test/suite/innodb/t/innodb_ctype_ldml.test'
--- a/mysql-test/suite/innodb/t/innodb_ctype_ldml.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_ctype_ldml.test	2011-08-19 09:27:11 +0000
@@ -0,0 +1,358 @@
+--source include/have_ucs2.inc
+--source include/have_utf8mb4.inc
+--source include/have_utf16.inc
+--source include/have_utf32.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+--echo In the following tests we change the order of letter "b"
+--echo making it equal to letter "a", and check that it works
+--echo with all Unicode character sets
+set names utf8;
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+show variables like 'character_sets_dir%';
+
+show collation like 'utf8_phone_ci';
+CREATE TABLE t1 (
+ name VARCHAR(64),
+ phone VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_phone_ci
+);
+INSERT INTO t1 VALUES ('Svoj','+7 912 800 80 02');
+INSERT INTO t1 VALUES ('Hf','+7 (912) 800 80 04');
+INSERT INTO t1 VALUES ('Bar','+7-912-800-80-01');
+INSERT INTO t1 VALUES ('Ramil','(7912) 800 80 03');
+INSERT INTO t1 VALUES ('Sanja','+380 (912) 8008005');
+SELECT * FROM t1 ORDER BY phone;
+SELECT * FROM t1 WHERE phone='+7(912)800-80-01';
+SELECT * FROM t1 WHERE phone='79128008001';
+SELECT * FROM t1 WHERE phone='7 9 1 2 8 0 0 8 0 0 1';
+DROP TABLE t1;
+
+show collation like 'utf8_test_ci';
+create table t1 (c1 char(1) character set utf8 collate utf8_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+drop table t1;
+
+show collation like 'ucs2_test_ci';
+create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+drop table t1;
+
+show collation like 'utf8mb4_test_ci';
+create table t1 (c1 char(1) character set utf8mb4 collate utf8mb4_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+drop table t1;
+
+show collation like 'utf16_test_ci';
+create table t1 (c1 char(1) character set utf16 collate utf16_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+drop table t1;
+
+show collation like 'utf32_test_ci';
+create table t1 (c1 char(1) character set utf32 collate utf32_test_ci);
+insert into t1 values ('a');
+select * from t1 where c1='b';
+drop table t1;
+
+# make sure utf8_test_ci is Unicode-5.0.0
+SELECT hex(weight_string(_utf8mb4'a' collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_utf32 0x10002 using utf8mb4) collate utf8mb4_test_ci));
+SELECT hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_ci), hex(lower(@a));
+SELECT hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_ci), hex(upper(@a));
+SELECT hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_ci), hex(lower(@a));
+SELECT hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_ci), hex(upper(@a));
+
+# check that it works with supplementary characters
+SELECT hex(weight_string(convert(_utf32 0x61 using utf8mb4) collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_utf32 0x62 using utf8mb4) collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_utf32 0x10062 using utf8mb4) collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_utf32 0x100400 using utf8mb4) collate utf8mb4_test_ci));
+
+# check contractions with non-ascii characters
+SELECT hex(weight_string(_utf8mb4 0x64 collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_ucs2 0x0064017e using utf8mb4) collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_ucs2 0x0044017e using utf8mb4) collate utf8mb4_test_ci));
+SELECT hex(weight_string(convert(_ucs2 0x0044017d using utf8mb4) collate utf8mb4_test_ci));
+
+
+--echo #
+--echo # Bug#45645 Mysql server close all connection and restart using lower function
+--echo #
+CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_test_ci;
+INSERT INTO t1 (a) VALUES ('hello!');
+SELECT * FROM t1 WHERE LOWER(a)=LOWER('N');
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#51976 LDML collations issue (cyrillic example)
+--echo #
+CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci);
+INSERT INTO t1 (a) VALUES ('Hello');
+SELECT a, UPPER(a), LOWER(a) FROM t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#43827 Server closes connections and restarts
+--echo #
+# Crash happened with a user-defined utf8 collation,
+# on attempt to insert a string longer than the column can store.
+CREATE TABLE t1 (c1 VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_test_ci);
+INSERT INTO t1 SELECT REPEAT('a',11);
+DROP TABLE t1;
+
+#
+#  Vietnamese experimental collation
+#
+--echo  Vietnamese experimental collation
+
+show collation like 'ucs2_vn_ci';
+create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci);
+insert into t1 values (0x0061),(0x0041),(0x00E0),(0x00C0),(0x1EA3),(0x1EA2),
+                      (0x00E3),(0x00C3),(0x00E1),(0x00C1),(0x1EA1),(0x1EA0);
+insert into t1 values (0x0103),(0x0102),(0x1EB1),(0x1EB0),(0x1EB3),(0x1EB2),
+                      (0x1EB5),(0x1EB4),(0x1EAF),(0x1EAE),(0x1EB7),(0x1EB6);
+insert into t1 values (0x00E2),(0x00C2),(0x1EA7),(0x1EA6),(0x1EA9),(0x1EA8),
+                      (0x1EAB),(0x1EAA),(0x1EA5),(0x1EA4),(0x1EAD),(0x1EAC);
+insert into t1 values ('b'),('B'),('c'),('C');
+insert into t1 values ('d'),('D'),(0x0111),(0x0110);
+insert into t1 values (0x0065),(0x0045),(0x00E8),(0x00C8),(0x1EBB),(0x1EBA),
+                      (0x1EBD),(0x1EBC),(0x00E9),(0x00C9),(0x1EB9),(0x1EB8);
+insert into t1 values (0x00EA),(0x00CA),(0x1EC1),(0x1EC0),(0x1EC3),(0x1EC2),
+                      (0x1EC5),(0x1EC4),(0x1EBF),(0x1EBE),(0x1EC7),(0x1EC6);
+insert into t1 values ('g'),('G'),('h'),('H');
+insert into t1 values (0x0069),(0x0049),(0x00EC),(0x00CC),(0x1EC9),(0x1EC8),
+                      (0x0129),(0x0128),(0x00ED),(0x00CD),(0x1ECB),(0x1ECA);
+insert into t1 values ('k'),('K'),('l'),('L'),('m'),('M');
+insert into t1 values (0x006F),(0x004F),(0x00F2),(0x00D2),(0x1ECF),(0x1ECE),
+                      (0x00F5),(0x00D5),(0x00F3),(0x00D3),(0x1ECD),(0x1ECC);
+insert into t1 values (0x00F4),(0x00D4),(0x1ED3),(0x1ED2),(0x1ED5),(0x1ED4),
+                      (0x1ED7),(0x1ED6),(0x1ED1),(0x1ED0),(0x1ED9),(0x1ED8);
+insert into t1 values (0x01A1),(0x01A0),(0x1EDD),(0x1EDC),(0x1EDF),(0x1EDE),
+                      (0x1EE1),(0x1EE0),(0x1EDB),(0x1EDA),(0x1EE3),(0x1EE2);
+insert into t1 values ('p'),('P'),('q'),('Q'),('r'),('R'),('s'),('S'),('t'),('T');
+insert into t1 values (0x0075),(0x0055),(0x00F9),(0x00D9),(0x1EE7),(0x1EE6),
+                      (0x0169),(0x0168),(0x00FA),(0x00DA),(0x1EE5),(0x1EE4);
+insert into t1 values (0x01B0),(0x01AF),(0x1EEB),(0x1EEA),(0x1EED),(0x1EEC),
+                      (0x1EEF),(0x1EEE),(0x1EE9),(0x1EE8),(0x1EF1),(0x1EF0);
+insert into t1 values ('v'),('V'),('x'),('X');
+insert into t1 values (0x0079),(0x0059),(0x1EF3),(0x1EF2),(0x1EF7),(0x1EF6),
+                      (0x1EF9),(0x1EF8),(0x00FD),(0x00DD),(0x1EF5),(0x1EF4);
+select hex(c1) as h, c1 from t1 order by c1, h;
+select group_concat(hex(c1) order by hex(c1)) from t1 group by c1;
+select group_concat(c1 order by hex(c1) SEPARATOR '') from t1 group by c1;
+drop table t1;
+
+--echo Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20
+set names latin1;
+show collation like 'latin1_test';
+select "foo" = "foo " collate latin1_test;
+
+-- echo The following tests check that two-byte collation IDs work
+# The file ../std-data/Index.xml has a number of collations with high IDs.
+
+# Test that the "ID" column in I_S and SHOW queries can handle two bytes
+select * from information_schema.collations where id>256 order by id;
+show collation like '%test%';
+
+# Test that two-byte collation ID is correctly transfered to the client side.
+show collation like 'ucs2_vn_ci';
+create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci);
+
+show create table t1;
+
+insert into t1 values (0x0061);
+--enable_metadata
+set @@character_set_results=NULL;
+select * from t1;
+--disable_metadata
+drop table t1;
+
+#
+# Check maximum collation ID (2047 as of MySQL-6.0.9)
+#
+CREATE TABLE t1 (s1 char(10) character set utf8 collate utf8_maxuserid_ci);
+INSERT INTO t1 VALUES ('a'),('b');
+SELECT * FROM t1 WHERE s1='a' ORDER BY BINARY s1;
+DROP TABLE t1;
+
+
+#
+# Bug#47756 Setting 2byte collation ID with 'set names' crashes the server
+#
+SET NAMES utf8 COLLATE utf8_phone_ci;
+SHOW COLLATION LIKE 'utf8_phone_ci';
+SET NAMES utf8;
+
+# make sure utf8mb4_test_400_ci is Unicode-4.0.0 based
+SELECT hex(weight_string(_utf8mb4'a' collate utf8mb4_test_400_ci));
+SELECT hex(weight_string(convert(_utf32 0x10002 using utf8mb4) collate utf8mb4_test_400_ci));
+SELECT hex(@a:=convert(_utf32 0x10400 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+SELECT hex(@a:=convert(_utf32 0x10428 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+SELECT hex(@a:=convert(_utf32 0x2C00 using utf8mb4) collate utf8mb4_test_400_ci), hex(lower(@a));
+SELECT hex(@a:=convert(_utf32 0x2C30 using utf8mb4) collate utf8mb4_test_400_ci), hex(upper(@a));
+
+--echo #
+--echo # WL#5624 Collation customization improvements
+--echo #
+SET NAMES utf8 COLLATE utf8_5624_1;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 16) AS a LIMIT 0;
+# Part 1,2,3: long contractions and expansions
+# Part 7: Quarternary difference
+INSERT INTO t1 VALUES ('012345'),('001234'),('000123'),('000012'),('000001');
+INSERT INTO t1 VALUES ('12345'),('01234'),('00123'),('00012'),('00001');
+INSERT INTO t1 VALUES ('1234'),('0123'),('0012'),('0001');
+INSERT INTO t1 VALUES ('123'),('012'),('001');
+INSERT INTO t1 VALUES ('12'),('01');
+INSERT INTO t1 VALUES ('1'),('9');
+INSERT INTO t1 VALUES ('ГАИ'),('ГИБДД');
+# Part 4: reset before
+# Part 6: characters rather than escape sequences
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e');
+INSERT INTO t1 VALUES ('cz'),('Ċ'),('ċ');
+INSERT INTO t1 VALUES ('f'),('fz'),('g'),('Ġ'),('ġ');
+INSERT INTO t1 VALUES ('h'),('hz'),('GĦ'),('Għ'),('gĦ'),('għ');
+INSERT INTO t1 VALUES ('i'),('iz'),('Ħ'),('ħ');
+INSERT INTO t1 VALUES ('y'),('yz'),('z'),('Ż'),('ż');
+INSERT INTO t1 VALUES ('ā'),('Ā'),('á'),('Á'),('à'),('À');
+INSERT INTO t1 VALUES ('ē'),('é'),('ě'),('ê'),('Ē'),('É'),('Ě'),('Ê');
+# Part 8: Abbreviated shift syntax
+INSERT INTO t1 VALUES ('a'),('~'),('!'),('@'),('#'),('$'),('%'),('^');
+INSERT INTO t1 VALUES ('('),(')'),('-'),('+'),('|'),('='),(':'),(';');
+INSERT INTO t1 VALUES ('"'),('\''),('?');
+# Part 9: Normal expansion syntax
+INSERT INTO t1 VALUES ('ch'),('k'),('cs'),('ccs'),('cscs');
+# Part 10: Previous context
+INSERT INTO t1 VALUES ('aa-'),('ab-'),('ac-'),('ad-'),('ae-'),('af-'),('az-');
+# Part 12: Logical reset positions
+INSERT INTO t1 VALUES ('lp-fni'),('lp-lni');
+INSERT INTO t1 VALUES ('lp-fpi'),('lp-lpi');
+INSERT INTO t1 VALUES ('lp-fsi'),('lp-lsi');
+INSERT INTO t1 VALUES ('lp-fti'),('lp-lti');
+INSERT INTO t1 VALUES ('lp-ft'),('lp-lt');
+INSERT INTO t1 VALUES ('lp-fv'),('lp-lv');
+# Logical positions with reset before
+INSERT INTO t1 VALUES ('lb-fni'),('lb-lni');
+INSERT INTO t1 VALUES ('lb-fv'),('lb-lv');
+# Part 5: Long tailoring
+INSERT INTO t1 VALUES (_ucs2 0x3106),(_ucs2 0x3110), (_ucs2 0x3111), (_ucs2 0x3112);
+INSERT INTO t1 VALUES (_ucs2 0x32A3), (_ucs2 0x3231);
+INSERT INTO t1 VALUES (_ucs2 0x84D9), (_ucs2 0x98F5), (_ucs2 0x7CF3), (_ucs2 0x5497);
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY a;
+--echo #
+--echo # WL#5624, the same test with UCS2
+--echo #
+ALTER TABLE t1 CONVERT TO CHARACTER SET ucs2 COLLATE ucs2_5624_1;
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+DROP TABLE t1;
+
+--echo #
+--echo # WL#5624, unsupported features
+--echo #
+# Part 13: More verbosity
+--error ER_UNKNOWN_COLLATION
+SET NAMES utf8 COLLATE utf8_5624_2;
+SHOW WARNINGS;
+
+--echo #
+--echo # WL#5624, reset before primary ignorable
+--echo #
+--error ER_UNKNOWN_COLLATION
+SET NAMES utf8 COLLATE utf8_5624_3;
+SHOW WARNINGS;
+
+--echo #
+--echo # WL#5624, \u without hex digits is equal to {'\\', 'u'}
+--echo #
+SET NAMES utf8 COLLATE utf8_5624_4;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('\\'),('u'),('x'),('X');
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+DROP TABLE t1;
+
+--echo #
+--echo # WL#5624, testing Bengali collations
+--echo #
+SET NAMES utf8, collation_connection=utf8_bengali_standard_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES (_ucs2 0x09FA), (_ucs2 0x09F8), (_ucs2 0x09F9), (_ucs2 0x09F2);
+INSERT INTO t1 VALUES (_ucs2 0x09DC), (_ucs2 0x09A109BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A2), (_ucs2 0x09DD), (_ucs2 0x09A209BC);
+INSERT INTO t1 VALUES (_ucs2 0x09A3);
+SELECT HEX(WEIGHT_STRING(a)), HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY a;
+DROP TABLE t1;
+
+SET NAMES utf8, collation_connection=utf8_bengali_traditional_ci;
+CREATE TABLE t1 AS SELECT REPEAT (' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES
+(_ucs2 0x0985),(_ucs2 0x0986),(_ucs2 0x0987),(_ucs2 0x0988),
+(_ucs2 0x0989),(_ucs2 0x098A),(_ucs2 0x098B),(_ucs2 0x09E0),
+(_ucs2 0x098C),(_ucs2 0x09E1),(_ucs2 0x098F),(_ucs2 0x0990),
+(_ucs2 0x0993);
+
+INSERT INTO t1 VALUES
+(_ucs2 0x0994),(_ucs2 0x0982),(_ucs2 0x0983),(_ucs2 0x0981),
+(_ucs2 0x099509CD), (_ucs2 0x099609CD), (_ucs2 0x099709CD), (_ucs2 0x099809CD),
+(_ucs2 0x099909CD), (_ucs2 0x099A09CD), (_ucs2 0x099B09CD), (_ucs2 0x099C09CD),
+(_ucs2 0x099D09CD), (_ucs2 0x099E09CD), (_ucs2 0x099F09CD), (_ucs2 0x09A009CD),
+(_ucs2 0x09A109CD), (_ucs2 0x09A209CD), (_ucs2 0x09A309CD),
+(_ucs2 0x09CE), (_ucs2 0x09A409CD200D), (_ucs2 0x09A409CD),
+(_ucs2 0x09A509CD),(_ucs2 0x09A609CD),
+(_ucs2 0x09A709CD), (_ucs2 0x09A809CD), (_ucs2 0x09AA09CD), (_ucs2 0x09AB09CD),
+(_ucs2 0x09AC09CD), (_ucs2 0x09AD09CD), (_ucs2 0x09AE09CD), (_ucs2 0x09AF09CD),
+(_ucs2 0x09B009CD), (_ucs2 0x09F009CD), (_ucs2 0x09B209CD), (_ucs2 0x09F109CD),
+(_ucs2 0x09B609CD), (_ucs2 0x09B709CD), (_ucs2 0x09B809CD), (_ucs2 0x09B909CD);
+
+INSERT INTO t1 VALUES 
+ (_ucs2 0x099509CD0985),(_ucs2 0x0995),
+ (_ucs2 0x099509CD0986),(_ucs2 0x099509BE),
+ (_ucs2 0x099509CD0987),(_ucs2 0x099509BF),
+ (_ucs2 0x099509CD0988),(_ucs2 0x099509C0),
+ (_ucs2 0x099509CD0989),(_ucs2 0x099509C1),
+ (_ucs2 0x099509CD098A),(_ucs2 0x099509C2),
+ (_ucs2 0x099509CD098B),(_ucs2 0x099509C3),
+ (_ucs2 0x099509CD09E0),(_ucs2 0x099509C4),
+ (_ucs2 0x099509CD098C),(_ucs2 0x099509E2),
+ (_ucs2 0x099509CD09E1),(_ucs2 0x099509E3),
+ (_ucs2 0x099509CD098F),(_ucs2 0x099509C7),
+ (_ucs2 0x099509CD0990),(_ucs2 0x099509C8),
+ (_ucs2 0x099509CD0993),(_ucs2 0x099509CB),
+ (_ucs2 0x099509CD0994),(_ucs2 0x099509CC);
+
+SELECT HEX(WEIGHT_STRING(a)), HEX(CONVERT(a USING ucs2)), HEX(a)
+FROM t1 ORDER BY a, BINARY(a);
+SELECT HEX(WEIGHT_STRING(a)) as wa,
+GROUP_CONCAT(HEX(CONVERT(a USING ucs2)) ORDER BY LENGTH(a), BINARY a)
+FROM t1 GROUP BY a ORDER BY a;
+DROP TABLE t1;
+
+--echo #
+--echo # WL#5624, shift after, using expansion
+--echo #
+SET NAMES utf8 COLLATE utf8_5624_5;
+CREATE TABLE t1 AS SELECT REPEAT(' ', 10) AS a LIMIT 0;
+INSERT INTO t1 VALUES ('0'),('1'),('0z'),(_ucs2 0x0030FF9D);
+INSERT INTO t1 VALUES ('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i');
+INSERT INTO t1 VALUES ('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r');
+INSERT INTO t1 VALUES ('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z');
+INSERT INTO t1 VALUES ('aa'),('aaa');
+INSERT INTO t1 VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I');
+INSERT INTO t1 VALUES ('J'),('K'),('L'),('M'),('N'),('O'),('P'),('Q'),('R');
+INSERT INTO t1 VALUES ('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z');
+INSERT INTO t1 VALUES ('AA'),('AAA');
+
+SELECT a, HEX(WEIGHT_STRING(a)) FROM t1 ORDER BY a, LENGTH(a), BINARY(a);
+DROP TABLE t1;
+
+
+--echo #
+--echo # End of WL#5624
+--echo #

=== added file 'mysql-test/suite/sys_vars/r/innodb_adaptive_max_sleep_delay_basic.result'
--- a/mysql-test/suite/sys_vars/r/innodb_adaptive_max_sleep_delay_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/innodb_adaptive_max_sleep_delay_basic.result	2011-08-19 06:13:33 +0000
@@ -0,0 +1,46 @@
+SELECT @@GLOBAL.innodb_adaptive_max_sleep_delay;
+@@GLOBAL.innodb_adaptive_max_sleep_delay
+150000
+150000 Expected
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=100;
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=1000001;
+Warnings:
+Warning	1292	Truncated incorrect innodb_adaptive_max_sleep_delay value: '1000001'
+SELECT @@GLOBAL.innodb_adaptive_max_sleep_delay;
+@@GLOBAL.innodb_adaptive_max_sleep_delay
+1000000
+1000000 Expected
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=-1;
+Warnings:
+Warning	1292	Truncated incorrect innodb_adaptive_max_sleep_delay value: '-1'
+SELECT @@GLOBAL.innodb_adaptive_max_sleep_delay;
+@@GLOBAL.innodb_adaptive_max_sleep_delay
+0
+0 Expected
+SELECT COUNT(@@GLOBAL.innodb_adaptive_max_sleep_delay);
+COUNT(@@GLOBAL.innodb_adaptive_max_sleep_delay)
+1
+1 Expected
+SELECT VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_adaptive_max_sleep_delay';
+VARIABLE_VALUE
+0
+100 Expected
+SELECT @@innodb_adaptive_max_sleep_delay = @@GLOBAL.innodb_adaptive_max_sleep_delay;
+@@innodb_adaptive_max_sleep_delay = @@GLOBAL.innodb_adaptive_max_sleep_delay
+1
+1000000 Expected
+SELECT COUNT(@@innodb_adaptive_max_sleep_delay);
+COUNT(@@innodb_adaptive_max_sleep_delay)
+1
+1 Expected
+SELECT COUNT(@@local.innodb_adaptive_max_sleep_delay);
+ERROR HY000: Variable 'innodb_adaptive_max_sleep_delay' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT COUNT(@@SESSION.innodb_adaptive_max_sleep_delay);
+ERROR HY000: Variable 'innodb_adaptive_max_sleep_delay' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT innodb_adaptive_max_sleep_delay = @@SESSION.innodb_adaptive_max_sleep_delay;
+ERROR 42S22: Unknown column 'innodb_adaptive_max_sleep_delay' in 'field list'
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=150000;

=== added file 'mysql-test/suite/sys_vars/t/innodb_adaptive_max_sleep_delay_basic.test'
--- a/mysql-test/suite/sys_vars/t/innodb_adaptive_max_sleep_delay_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/innodb_adaptive_max_sleep_delay_basic.test	2011-08-19 06:13:33 +0000
@@ -0,0 +1,75 @@
+################## mysql-test/t/innodb_adaptive_max_sleep_delay.test ##########
+#                                                                             #
+# Variable Name: innodb_adaptive_max_sleep_delay                              #
+# Scope: Global                                                               #
+# Access Type: Dynamic                                                        #
+# Data Type: numeric                                                          #
+#                                                                             #
+# Note: This variable is only defined if innodb_have_atomic_builtins=ON       #
+#                                                                             #
+# Creation Date: 2011-08-17                                                   #
+# Author : Sunny Bains                                                        #
+#                                                                             #
+#                                                                             #
+# Description: Dynamic config global variable innodb_adaptive_max_sleep_delay #
+#              * Value check                                                  #
+#              * Scope check                                                  #
+#                                                                             #
+###############################################################################
+
+--source include/have_innodb.inc
+
+# Check if builtins are enabled
+if (`SELECT VARIABLE_VALUE='OFF' FROM INFORMATION_SCHEMA.GLOBAL_STATUS
+    WHERE variable_name = 'INNODB_HAVE_ATOMIC_BUILTINS'`) {
+	--skip Test requires InnoDB atomic builtins
+}
+
+# Display default value
+SELECT @@GLOBAL.innodb_adaptive_max_sleep_delay;
+--echo 150000 Expected
+
+# Check if value can be set
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=100;
+
+# Check for out of bounds
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=1000001;
+SELECT @@GLOBAL.innodb_adaptive_max_sleep_delay;
+--echo 1000000 Expected
+
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=-1;
+SELECT @@GLOBAL.innodb_adaptive_max_sleep_delay;
+--echo 0 Expected
+
+SELECT COUNT(@@GLOBAL.innodb_adaptive_max_sleep_delay);
+--echo 1 Expected
+
+# Check if the value in GLOBAL table matches value in variable
+SELECT VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='innodb_adaptive_max_sleep_delay';
+--echo 100 Expected
+
+# Check if accessing variable with and without GLOBAL point to same
+# variable
+SELECT @@innodb_adaptive_max_sleep_delay = @@GLOBAL.innodb_adaptive_max_sleep_delay;
+--echo 1000000 Expected
+
+# Check if innodb_adaptive_max_sleep_delay can be accessed with and
+# without @@ sign.
+SELECT COUNT(@@innodb_adaptive_max_sleep_delay);
+--echo 1 Expected
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@local.innodb_adaptive_max_sleep_delay);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@SESSION.innodb_adaptive_max_sleep_delay);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+--Error ER_BAD_FIELD_ERROR
+SELECT innodb_adaptive_max_sleep_delay = @@SESSION.innodb_adaptive_max_sleep_delay;
+
+# Reset the default
+SET @@GLOBAL.innodb_adaptive_max_sleep_delay=150000;

=== modified file 'storage/innobase/data/data0type.c'
--- a/storage/innobase/data/data0type.c	2010-09-27 16:45:08 +0000
+++ b/storage/innobase/data/data0type.c	2011-08-19 09:27:11 +0000
@@ -158,7 +158,7 @@ dtype_form_prtype(
 	ulint	charset_coll)	/*!< in: MySQL charset-collation code */
 {
 	ut_a(old_prtype < 256 * 256);
-	ut_a(charset_coll < 256);
+	ut_a(charset_coll <= MAX_CHAR_COLL_NUM);
 
 	return(old_prtype + (charset_coll << 16));
 }

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2011-08-17 09:54:51 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2011-08-19 09:27:11 +0000
@@ -297,7 +297,9 @@ static PSI_mutex_info all_innodb_mutexes
 	{&event_os_mutex_key, "event_os_mutex", 0},
 #  endif /* PFS_SKIP_EVENT_MUTEX */
 	{&os_mutex_key, "os_mutex", 0},
+#ifndef HAVE_ATOMIC_BUILTINS
 	{&srv_conc_mutex_key, "srv_conc_mutex", 0},
+#endif /* !HAVE_ATOMIC_BUILTINS */
 	{&ut_list_mutex_key, "ut_list_mutex", 0},
 	{&trx_sys_mutex_key, "trx_sys_mutex", 0},
 };
@@ -881,53 +883,67 @@ Save some CPU by testing the value of sr
 functions. */
 static inline
 void
-innodb_srv_conc_enter_innodb(
-/*=========================*/
+innobase_srv_conc_enter_innodb(
+/*===========================*/
 	trx_t*	trx)	/*!< in: transaction handle */
 {
-	if (UNIV_LIKELY(!srv_thread_concurrency)) {
+	if (srv_thread_concurrency) {
+		if (trx->n_tickets_to_enter_innodb > 0) {
 
-		return;
-	}
+			/* If trx has 'free tickets' to enter the engine left,
+			then use one such ticket */
+
+			--trx->n_tickets_to_enter_innodb;
+
+		} else if (trx->mysql_thd != NULL
+			   && thd_is_replication_slave_thread(trx->mysql_thd)) {
+
+			UT_WAIT_FOR(
+				srv_conc_get_active_threads()
+				< srv_thread_concurrency,
+				srv_replication_delay * 1000);
 
-	srv_conc_enter_innodb(trx);
+		}  else {
+			srv_conc_enter_innodb(trx);
+		}
+	}
 }
 
 /******************************************************************//**
-Save some CPU by testing the value of srv_thread_concurrency in inline
-functions. */
+Note that the thread wants to leave InnoDB only if it doesn't have
+any spare tickets. */
 static inline
 void
-innodb_srv_conc_exit_innodb(
-/*========================*/
+innobase_srv_conc_exit_innodb(
+/*==========================*/
 	trx_t*	trx)	/*!< in: transaction handle */
 {
-	if (UNIV_LIKELY(!trx->declared_to_be_inside_innodb)) {
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
+
+	/* This is to avoid making an unnecessary function call. */
+	if (trx->declared_to_be_inside_innodb
+	    && trx->n_tickets_to_enter_innodb == 0) {
 
-		return;
+		srv_conc_force_exit_innodb(trx);
 	}
-
-	srv_conc_exit_innodb(trx);
 }
 
 /******************************************************************//**
-Releases possible search latch and InnoDB thread FIFO ticket. These should
-be released at each SQL statement end, and also when mysqld passes the
-control to the client. It does no harm to release these also in the middle
-of an SQL statement. */
+Force a thread to leave InnoDB even if it has spare tickets. */
 static inline
 void
-innobase_release_stat_resources(
-/*============================*/
-	trx_t*	trx)	/*!< in: transaction object */
+innobase_srv_conc_force_exit_innodb(
+/*================================*/
+	trx_t*	trx)	/*!< in: transaction handle */
 {
-	if (trx->has_search_latch) {
-		trx_search_latch_release_if_reserved(trx);
-	}
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
 
+	/* This is to avoid making an unnecessary function call. */
 	if (trx->declared_to_be_inside_innodb) {
-		/* Release our possible ticket in the FIFO */
-
 		srv_conc_force_exit_innodb(trx);
 	}
 }
@@ -1026,8 +1042,6 @@ innobase_release_temporary_latches(
 	handlerton*	hton,	/*!< in: handlerton */
 	THD*		thd)	/*!< in: MySQL thread */
 {
-	trx_t*	trx;
-
 	DBUG_ASSERT(hton == innodb_hton_ptr);
 
 	if (!innodb_inited) {
@@ -1035,11 +1049,12 @@ innobase_release_temporary_latches(
 		return(0);
 	}
 
-	trx = thd_to_trx(thd);
+	trx_t*	trx = thd_to_trx(thd);
 
-	if (trx) {
-		innobase_release_stat_resources(trx);
+	if (trx != NULL) {
+		trx_search_latch_release_if_reserved(trx);
 	}
+
 	return(0);
 }
 
@@ -1240,7 +1255,7 @@ innobase_get_cset_width(
 	ulint*	mbmaxlen)	/*!< out: maximum length of a char (in bytes) */
 {
 	CHARSET_INFO*	cs;
-	ut_ad(cset < 256);
+	ut_ad(cset <= MAX_CHAR_COLL_NUM);
 	ut_ad(mbminlen);
 	ut_ad(mbmaxlen);
 
@@ -2043,7 +2058,9 @@ innobase_query_caching_of_table_permitte
 		trx_print(stderr, trx, 1024);
 	}
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
 
@@ -2367,7 +2384,9 @@ ha_innobase::init_table_handle_for_HANDL
 	/* Initialize the prebuilt struct much like it would be inited in
 	external_lock */
 
-	innobase_release_stat_resources(prebuilt->trx);
+	trx_search_latch_release_if_reserved(prebuilt->trx);
+
+	innobase_srv_conc_force_exit_innodb(prebuilt->trx);
 
 	/* If the transaction is not started yet, start it */
 
@@ -2950,7 +2969,9 @@ innobase_start_trx_and_assign_read_view(
 	we have to release the search system latch first to obey the latching
 	order. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* If the transaction is not started yet, start it */
 
@@ -3092,11 +3113,7 @@ retry:
 
 	trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
 
-	if (trx->declared_to_be_inside_innodb) {
-		/* Release our possible ticket in the FIFO */
-
-		srv_conc_force_exit_innodb(trx);
-	}
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* Tell the InnoDB server that there might be work for utility
 	threads: */
@@ -3133,7 +3150,9 @@ innobase_rollback(
 	reserve the trx_sys->mutex, we have to release the search system
 	latch first to obey the latching order. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */
 
@@ -3173,7 +3192,9 @@ innobase_rollback_trx(
 	reserve the trx_sys->mutex, we have to release the search system
 	latch first to obey the latching order. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* If we had reserved the auto-inc lock for some table (if
 	we come here to roll back the latest SQL statement) we
@@ -3214,7 +3235,9 @@ innobase_rollback_to_savepoint(
 	reserve the trx_sys->mutex, we have to release the search system
 	latch first to obey the latching order. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* TODO: use provided savepoint data area to store savepoint data */
 
@@ -3285,7 +3308,9 @@ innobase_savepoint(
 	reserve the trx_sys->mutex, we have to release the search system
 	latch first to obey the latching order. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* Cannot happen outside of transaction */
 	DBUG_ASSERT(trx_is_registered_for_2pc(trx));
@@ -5526,7 +5551,7 @@ no_commit:
 		build_template(true);
 	}
 
-	innodb_srv_conc_enter_innodb(prebuilt->trx);
+	innobase_srv_conc_enter_innodb(prebuilt->trx);
 
 	error = row_insert_for_mysql((byte*) record, prebuilt);
 
@@ -5615,7 +5640,7 @@ set_max_autoinc:
 		}
 	}
 
-	innodb_srv_conc_exit_innodb(prebuilt->trx);
+	innobase_srv_conc_exit_innodb(prebuilt->trx);
 
 report_error:
 	error_result = convert_error_code_to_mysql((int) error,
@@ -5822,7 +5847,7 @@ ha_innobase::update_row(
 
 	ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
 
-	innodb_srv_conc_enter_innodb(trx);
+	innobase_srv_conc_enter_innodb(trx);
 
 	error = row_update_for_mysql((byte*) old_row, prebuilt);
 
@@ -5866,7 +5891,7 @@ ha_innobase::update_row(
 		}
 	}
 
-	innodb_srv_conc_exit_innodb(trx);
+	innobase_srv_conc_exit_innodb(trx);
 
 	error = convert_error_code_to_mysql(error,
 					    prebuilt->table->flags, user_thd);
@@ -5915,11 +5940,11 @@ ha_innobase::delete_row(
 
 	prebuilt->upd_node->is_delete = TRUE;
 
-	innodb_srv_conc_enter_innodb(trx);
+	innobase_srv_conc_enter_innodb(trx);
 
 	error = row_update_for_mysql((byte*) record, prebuilt);
 
-	innodb_srv_conc_exit_innodb(trx);
+	innobase_srv_conc_exit_innodb(trx);
 
 	error = convert_error_code_to_mysql(
 		error, prebuilt->table->flags, user_thd);
@@ -6226,12 +6251,12 @@ ha_innobase::index_read(
 
 	if (mode != PAGE_CUR_UNSUPP) {
 
-		innodb_srv_conc_enter_innodb(prebuilt->trx);
+		innobase_srv_conc_enter_innodb(prebuilt->trx);
 
 		ret = row_search_for_mysql((byte*) buf, mode, prebuilt,
 					   match_mode, 0);
 
-		innodb_srv_conc_exit_innodb(prebuilt->trx);
+		innobase_srv_conc_exit_innodb(prebuilt->trx);
 	} else {
 
 		ret = DB_UNSUPPORTED;
@@ -6462,12 +6487,12 @@ ha_innobase::general_fetch(
 
 	ut_a(prebuilt->trx == thd_to_trx(user_thd));
 
-	innodb_srv_conc_enter_innodb(prebuilt->trx);
+	innobase_srv_conc_enter_innodb(prebuilt->trx);
 
 	ret = row_search_for_mysql(
 		(byte*)buf, 0, prebuilt, match_mode, direction);
 
-	innodb_srv_conc_exit_innodb(prebuilt->trx);
+	innobase_srv_conc_exit_innodb(prebuilt->trx);
 
 	switch (ret) {
 	case DB_SUCCESS:
@@ -6855,7 +6880,7 @@ create_table_def(
 
 			charset_no = (ulint)field->charset()->number;
 
-			if (UNIV_UNLIKELY(charset_no >= 256)) {
+			if (UNIV_UNLIKELY(charset_no > MAX_CHAR_COLL_NUM)) {
 				/* in data0type.h we assume that the
 				number fits in one byte in prtype */
 				push_warning_printf(
@@ -6870,8 +6895,9 @@ create_table_def(
 			}
 		}
 
-		ut_a(field->type() < 256); /* we assume in dtype_form_prtype()
-					   that this fits in one byte */
+		/* we assume in dtype_form_prtype() that this fits in
+		two bytes */
+		ut_a(field->type() <= MAX_CHAR_COLL_NUM);
 		col_len = field->pack_length();
 
 		/* The MySQL pack length contains 1 or 2 bytes length field
@@ -9450,7 +9476,9 @@ ha_innobase::start_stmt(
 	that may not be the case. We MUST release the search latch before an
 	INSERT, for example. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* Reset the AUTOINC statement level counter for multi-row INSERTs. */
 	trx->n_autoinc_rows = 0;
@@ -9648,7 +9676,9 @@ ha_innobase::external_lock(
 	may reserve the trx_sys->mutex, we have to release the search
 	system latch first to obey the latching order. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* If the MySQL lock count drops to zero we know that the current SQL
 	statement has ended */
@@ -9802,7 +9832,9 @@ innodb_show_status(
 
 	trx = check_trx_exists(thd);
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	/* We let the InnoDB Monitor to output at most MAX_STATUS_SIZE
 	bytes of text. */
@@ -10848,7 +10880,9 @@ innobase_xa_prepare(
 	reserve the trx_sys->mutex, we have to release the search system
 	latch first to obey the latching order. */
 
-	innobase_release_stat_resources(trx);
+	trx_search_latch_release_if_reserved(trx);
+
+	innobase_srv_conc_force_exit_innodb(trx);
 
 	if (!trx_is_registered_for_2pc(trx) && trx_is_started(trx)) {
 
@@ -12677,10 +12711,25 @@ static MYSQL_SYSVAR_ULONG(thread_concurr
   "Helps in performance tuning in heavily concurrent environments. Sets the maximum number of threads allowed inside InnoDB. Value 0 will disable the thread throttling.",
   NULL, NULL, 0, 0, 1000, 0);
 
+#ifdef HAVE_ATOMIC_BUILTINS
+static MYSQL_SYSVAR_ULONG(
+  adaptive_max_sleep_delay, srv_adaptive_max_sleep_delay,
+  PLUGIN_VAR_RQCMDARG,
+  "The upper limit of the sleep delay in usec. Value of 0 disables it.",
+  NULL, NULL,
+  150000,			/* Default setting */
+  0,				/* Minimum value */
+  1000000, 0);			/* Maximum value */
+#endif /* HAVE_ATOMIC_BUILTINS */
+
 static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
   PLUGIN_VAR_RQCMDARG,
-  "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
-  NULL, NULL, 10000L, 0L, ~0L, 0);
+  "Time of innodb thread sleeping before joining InnoDB queue (usec). "
+  "Value 0 disable a sleep",
+  NULL, NULL,
+  10000L,
+  0L,
+  ~0L, 0);
 
 static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path,
   PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -12879,6 +12928,9 @@ static struct st_mysql_sys_var* innobase
   MYSQL_SYSVAR(spin_wait_delay),
   MYSQL_SYSVAR(table_locks),
   MYSQL_SYSVAR(thread_concurrency),
+#ifdef HAVE_ATOMIC_BUILTINS
+  MYSQL_SYSVAR(adaptive_max_sleep_delay),
+#endif /* HAVE_ATOMIC_BUILTINS */
   MYSQL_SYSVAR(thread_sleep_delay),
   MYSQL_SYSVAR(autoinc_lock_mode),
   MYSQL_SYSVAR(version),

=== modified file 'storage/innobase/include/btr0sea.h'
--- a/storage/innobase/include/btr0sea.h	2010-10-02 19:12:58 +0000
+++ b/storage/innobase/include/btr0sea.h	2011-08-19 06:13:33 +0000
@@ -270,24 +270,6 @@ struct btr_search_sys_struct{
 /** The adaptive hash index */
 extern btr_search_sys_t*	btr_search_sys;
 
-/** @brief The latch protecting the adaptive search system
-
-This latch protects the
-(1) hash index;
-(2) columns of a record to which we have a pointer in the hash index;
-
-but does NOT protect:
-
-(3) next record offset field in a record;
-(4) next or previous records on the same page.
-
-Bear in mind (3) and (4) when using the hash index.
-*/
-extern rw_lock_t*	btr_search_latch_temp;
-
-/** The latch protecting the adaptive search system */
-#define btr_search_latch	(*btr_search_latch_temp)
-
 #ifdef UNIV_SEARCH_PERF_STAT
 /** Number of successful adaptive hash index lookups */
 extern ulint	btr_search_n_succ;

=== modified file 'storage/innobase/include/data0type.h'
--- a/storage/innobase/include/data0type.h	2010-10-21 22:25:09 +0000
+++ b/storage/innobase/include/data0type.h	2011-08-19 09:27:11 +0000
@@ -182,6 +182,12 @@ because in GCC it returns a long. */
 /* Get mbmaxlen from mbminmaxlen. */
 #define DATA_MBMAXLEN(mbminmaxlen) ((ulint) ((mbminmaxlen) / DATA_MBMAX))
 
+/* We now support 15 bits (up to 32767) collation number */
+#define MAX_CHAR_COLL_NUM	32767
+
+/* Mask to get the Charset Collation number (0x7fff) */
+#define CHAR_COLL_MASK		MAX_CHAR_COLL_NUM
+
 #ifndef UNIV_HOTBACKUP
 /*********************************************************************//**
 Gets the MySQL type code from a dtype.
@@ -491,14 +497,14 @@ dtype_new_read_for_order_and_null_size()
 sym_tab_add_null_lit() */
 
 struct dtype_struct{
-	unsigned	mtype:8;	/*!< main data type */
-	unsigned	prtype:24;	/*!< precise type; MySQL data
+	unsigned	prtype:32;	/*!< precise type; MySQL data
 					type, charset code, flags to
 					indicate nullability,
 					signedness, whether this is a
 					binary string, whether this is
 					a true VARCHAR where MySQL
 					uses 2 bytes to store the length */
+	unsigned	mtype:8;	/*!< main data type */
 
 	/* the remaining fields do not affect alphabetical ordering: */
 

=== modified file 'storage/innobase/include/data0type.ic'
--- a/storage/innobase/include/data0type.ic	2011-03-15 14:33:31 +0000
+++ b/storage/innobase/include/data0type.ic	2011-08-19 09:27:11 +0000
@@ -38,7 +38,7 @@ dtype_get_charset_coll(
 /*===================*/
 	ulint	prtype)	/*!< in: precise data type */
 {
-	return((prtype >> 16) & 0xFFUL);
+	return((prtype >> 16) & CHAR_COLL_MASK);
 }
 
 /*********************************************************************//**
@@ -328,7 +328,7 @@ dtype_new_store_for_order_and_null_size(
 
 	mach_write_to_2(buf + 2, len & 0xFFFFUL);
 
-	ut_ad(dtype_get_charset_coll(type->prtype) < 256);
+	ut_ad(dtype_get_charset_coll(type->prtype) <= MAX_CHAR_COLL_NUM);
 	mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype));
 
 	if (type->prtype & DATA_NOT_NULL) {
@@ -395,10 +395,10 @@ dtype_new_read_for_order_and_null_size(
 
 	type->len = mach_read_from_2(buf + 2);
 
-	charset_coll = mach_read_from_2(buf + 4) & 0x7fff;
+	charset_coll = mach_read_from_2(buf + 4) & CHAR_COLL_MASK;
 
 	if (dtype_is_string_type(type->mtype)) {
-		ut_a(charset_coll < 256);
+		ut_a(charset_coll <= MAX_CHAR_COLL_NUM);
 
 		if (charset_coll == 0) {
 			/* This insert buffer record was inserted with MySQL

=== modified file 'storage/innobase/include/dict0mem.h'
--- a/storage/innobase/include/dict0mem.h	2011-08-17 04:42:00 +0000
+++ b/storage/innobase/include/dict0mem.h	2011-08-19 09:27:11 +0000
@@ -265,14 +265,14 @@ struct dict_col_struct{
 	/** The following are copied from dtype_t,
 	so that all bit-fields can be packed tightly. */
 	/* @{ */
-	unsigned	mtype:8;	/*!< main data type */
-	unsigned	prtype:24;	/*!< precise type; MySQL data
+	unsigned	prtype:32;	/*!< precise type; MySQL data
 					type, charset code, flags to
 					indicate nullability,
 					signedness, whether this is a
 					binary string, whether this is
 					a true VARCHAR where MySQL
 					uses 2 bytes to store the length */
+	unsigned	mtype:8;	/*!< main data type */
 
 	/* the remaining fields do not affect alphabetical ordering: */
 

=== modified file 'storage/innobase/include/srv0conc.h'
--- a/storage/innobase/include/srv0conc.h	2011-04-18 02:17:16 +0000
+++ b/storage/innobase/include/srv0conc.h	2011-08-19 06:13:33 +0000
@@ -48,21 +48,10 @@ extern	ulint	srv_max_n_threads;
 
 /** The following controls how many threads we let inside InnoDB concurrently:
 threads waiting for locks are not counted into the number because otherwise
-we could get a deadlock. MySQL creates a thread for each user session, and
-semaphore contention and convoy problems can occur withput this restriction.
-Value 10 should be good if there are less than 4 processors + 4 disks in the
-computer. Bigger computers need bigger values. Value 0 will disable the
-concurrency check. */
+we could get a deadlock. Value of 0 will disable the concurrency check. */
 
 extern ulong	srv_thread_concurrency;
 
-/** Number of transactions that have declared_to_be_inside_innodb set.
-It used to be a non-error for this value to drop below zero temporarily.
-This is no longer true. We'll, however, keep the lint datatype to add
-assertions to catch any corner cases that we may have missed. */
-
-extern	lint	srv_conc_n_threads;
-
 /*********************************************************************//**
 Initialise the concurrency management data structures */
 void
@@ -106,19 +95,17 @@ srv_conc_force_exit_innodb(
 				the thread */
 
 /*********************************************************************//**
-This must be called when a thread exits InnoDB. */
+Get the count of threads waiting inside InnoDB. */
 UNIV_INTERN
-void
-srv_conc_exit_innodb(
-/*=================*/
-	trx_t*	trx);		/*!< in: transaction object associated with
-				the thread */
+ulint
+srv_conc_get_waiting_threads(void);
+/*==============================*/
 
 /*********************************************************************//**
-Get the count of threads waiting inside InnoDB. */
+Get the count of threads active inside InnoDB. */
 UNIV_INTERN
 ulint
-srv_conc_get_waiting_threads(void);
+srv_conc_get_active_threads(void);
 /*==============================*/
 
 #endif /* srv_conc_h */

=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h	2011-08-17 04:42:00 +0000
+++ b/storage/innobase/include/srv0srv.h	2011-08-19 06:13:33 +0000
@@ -123,9 +123,16 @@ extern char*	srv_arch_dir;
 dictionary tables are in the system tablespace 0 */
 #ifndef UNIV_HOTBACKUP
 extern my_bool	srv_file_per_table;
+/** Sleep delay for threads waiting to enter InnoDB. In micro-seconds. */
+extern	ulong	srv_thread_sleep_delay;
+#if defined(HAVE_ATOMIC_BUILTINS)
+/** Maximum sleep delay (in micro-seconds), value of 0 disables it.*/
+extern	ulong	srv_adaptive_max_sleep_delay;
+#endif /* HAVE_ATOMIC_BUILTINS */
 #else
 extern ibool	srv_file_per_table;
-#endif /* UNIV_HOTBACKUP */
+#endif /* HAVE_ATOMIC_BUILTINS */
+
 /** The file format to use on new *.ibd files. */
 extern ulint	srv_file_format;
 /** Whether to check file format during startup.  A value of

=== modified file 'storage/innobase/include/sync0sync.h'
--- a/storage/innobase/include/sync0sync.h	2011-08-15 09:34:39 +0000
+++ b/storage/innobase/include/sync0sync.h	2011-08-19 06:13:33 +0000
@@ -114,7 +114,9 @@ extern mysql_pfs_key_t	lock_sys_wait_mut
 extern mysql_pfs_key_t	trx_sys_mutex_key;
 extern mysql_pfs_key_t	srv_sys_mutex_key;
 extern mysql_pfs_key_t	srv_sys_tasks_mutex_key;
+#ifndef HAVE_ATOMIC_BUILTINS
 extern mysql_pfs_key_t	srv_conc_mutex_key;
+#endif /* !HAVE_ATOMIC_BUILTINS */
 extern mysql_pfs_key_t	event_os_mutex_key;
 extern mysql_pfs_key_t	ut_list_mutex_key;
 extern mysql_pfs_key_t	os_mutex_key;

=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h	2011-07-26 11:08:42 +0000
+++ b/storage/innobase/include/trx0trx.h	2011-08-19 06:13:33 +0000
@@ -44,7 +44,7 @@ extern sess_t*	trx_dummy_sess;
 
 /********************************************************************//**
 Releases the search latch if trx has reserved it. */
-UNIV_INTERN
+UNIV_INLINE
 void
 trx_search_latch_release_if_reserved(
 /*=================================*/
@@ -884,6 +884,24 @@ struct commit_node_struct{
 	mutex_exit(&t->mutex);			\
 } while (0)
 
+/** @brief The latch protecting the adaptive search system
+
+This latch protects the
+(1) hash index;
+(2) columns of a record to which we have a pointer in the hash index;
+
+but does NOT protect:
+
+(3) next record offset field in a record;
+(4) next or previous records on the same page.
+
+Bear in mind (3) and (4) when using the hash index.
+*/
+extern rw_lock_t*	btr_search_latch_temp;
+
+/** The latch protecting the adaptive search system */
+#define btr_search_latch	(*btr_search_latch_temp)
+
 #ifndef UNIV_NONINL
 #include "trx0trx.ic"
 #endif

=== modified file 'storage/innobase/include/trx0trx.ic'
--- a/storage/innobase/include/trx0trx.ic	2011-07-26 03:21:33 +0000
+++ b/storage/innobase/include/trx0trx.ic	2011-08-19 06:13:33 +0000
@@ -151,3 +151,19 @@ ok:
 
 	trx->dict_operation = op;
 }
+
+/********************************************************************//**
+Releases the search latch if trx has reserved it. */
+UNIV_INLINE
+void
+trx_search_latch_release_if_reserved(
+/*=================================*/
+	trx_t*	   trx) /*!< in: transaction */
+{
+	if (trx->has_search_latch) {
+		rw_lock_s_unlock(&btr_search_latch);
+
+		trx->has_search_latch = FALSE;
+	}
+}
+

=== modified file 'storage/innobase/srv/srv0conc.c'
--- a/storage/innobase/srv/srv0conc.c	2011-05-13 12:47:07 +0000
+++ b/storage/innobase/srv/srv0conc.c	2011-08-19 06:13:33 +0000
@@ -42,7 +42,18 @@ Created 2011/04/18 Sunny Bains
 #include "trx0trx.h"
 
 #include "mysql/plugin.h"
-#include "mysql/service_thd_wait.h"	/* MySQL callback functions */
+
+/** Number of times a thread is allowed to enter InnoDB within the same
+SQL query after it has once got the ticket. */
+UNIV_INTERN ulong	srv_n_free_tickets_to_enter = 500;
+
+#ifdef HAVE_ATOMIC_BUILTINS
+/** Maximum sleep delay (in micro-seconds), value of 0 disables it. */
+UNIV_INTERN ulong	srv_adaptive_max_sleep_delay = 150000;
+#endif /* HAVE_ATOMIC_BUILTINS */
+
+UNIV_INTERN ulong	srv_thread_sleep_delay	= 10000;
+
 
 /** We are prepared for a situation that we have this many threads waiting for
 a semaphore inside InnoDB. innobase_start_or_create_for_mysql() sets the
@@ -52,28 +63,15 @@ UNIV_INTERN ulint	srv_max_n_threads	= 0;
 
 /** The following controls how many threads we let inside InnoDB concurrently:
 threads waiting for locks are not counted into the number because otherwise
-we could get a deadlock. MySQL creates a thread for each user session, and
-semaphore contention and convoy problems can occur withput this restriction.
-Value 10 should be good if there are less than 4 processors + 4 disks in the
-computer. Bigger computers need bigger values. Value 0 will disable the
-concurrency check. */
+we could get a deadlock. Value of 0 will disable the concurrency check. */
 
 UNIV_INTERN ulong	srv_thread_concurrency	= 0;
 
-/** Number of transactions that have declared_to_be_inside_innodb set.
-It used to be a non-error for this value to drop below zero temporarily.
-This is no longer true. We'll, however, keep the lint datatype to add
-assertions to catch any corner cases that we may have missed. */
-
-UNIV_INTERN lint	srv_conc_n_threads	= 0;
+#ifndef HAVE_ATOMIC_BUILTINS
 
 /** This mutex protects srv_conc data structures */
 static os_fast_mutex_t	srv_conc_mutex;
 
-/** Number of OS threads waiting in the FIFO for a permission to enter
-InnoDB */
-static ulint		srv_conc_n_waiting_threads = 0;
-
 /** Slot for a thread waiting in the concurrency control queue. */
 typedef struct srv_conc_slot_struct	srv_conc_slot_t;
 
@@ -100,16 +98,33 @@ static srv_conc_queue_t	srv_conc_queue;
 /** Array of wait slots */
 static srv_conc_slot_t*	srv_conc_slots;
 
-/* Number of times a thread is allowed to enter InnoDB within the same
-SQL query after it has once got the ticket at srv_conc_enter_innodb */
-#define SRV_FREE_TICKETS_TO_ENTER srv_n_free_tickets_to_enter
-#define SRV_THREAD_SLEEP_DELAY srv_thread_sleep_delay
-
-#ifdef UNIV_PFS_MUTEX
+#if defined(UNIV_PFS_MUTEX)
 /* Key to register srv_conc_mutex_key with performance schema */
 UNIV_INTERN mysql_pfs_key_t	srv_conc_mutex_key;
 #endif /* UNIV_PFS_MUTEX */
 
+#endif /* !HAVE_ATOMIC_BUILTINS */
+
+typedef struct srv_conc_struct srv_conc_t;
+
+/** Variables tracking the active and waiting threads. */
+struct srv_conc_struct {
+	char		pad[64  - (sizeof(ulint) + sizeof(lint))];
+
+	/** Number of transactions that have declared_to_be_inside_innodb set.
+	It used to be a non-error for this value to drop below zero temporarily.
+	This is no longer true. We'll, however, keep the lint datatype to add
+	assertions to catch any corner cases that we may have missed. */
+
+	lint		n_active;
+
+	/** Number of OS threads waiting in the FIFO for permission to
+	enter InnoDB */
+	ulint		n_waiting;
+};
+
+/* Control variables for tracking concurrency. */
+static srv_conc_t	srv_conc;
 
 /*********************************************************************//**
 Initialise the concurrency management data structures */
@@ -117,6 +132,7 @@ void
 srv_conc_init(void)
 /*===============*/
 {
+#ifndef HAVE_ATOMIC_BUILTINS
 	ulint		i;
 
 	/* Init the server concurrency restriction data structures */
@@ -133,6 +149,7 @@ srv_conc_init(void)
 		conc_slot->event = os_event_create(NULL);
 		ut_a(conc_slot->event);
 	}
+#endif /* !HAVE_ATOMIC_BUILTINS */
 }
 
 /*********************************************************************//**
@@ -141,47 +158,209 @@ void
 srv_conc_free(void)
 /*===============*/
 {
+#ifndef HAVE_ATOMIC_BUILTINS
 	os_fast_mutex_free(&srv_conc_mutex);
 	mem_free(srv_conc_slots);
 	srv_conc_slots = NULL;
+#endif /* !HAVE_ATOMIC_BUILTINS */
 }
 
+#ifdef HAVE_ATOMIC_BUILTINS
 /*********************************************************************//**
-Puts an OS thread to wait if there are too many concurrent threads
-(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
-UNIV_INTERN
+Note that a user thread is entering InnoDB. */
+static
 void
-srv_conc_enter_innodb(
-/*==================*/
-	trx_t*	trx)	/*!< in: transaction object associated with the
-			thread */
+srv_enter_innodb_with_tickets(
+/*==========================*/
+	trx_t*	trx)			/*!< in/out: transaction that wants
+					to enter InnoDB */
 {
-	ibool			has_slept = FALSE;
-	srv_conc_slot_t*	slot = NULL;
-	ulint			i;
+	trx->declared_to_be_inside_innodb = TRUE;
+	trx->n_tickets_to_enter_innodb = srv_n_free_tickets_to_enter;
+}
 
-#ifdef UNIV_SYNC_DEBUG
-	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
-#endif /* UNIV_SYNC_DEBUG */
+/*********************************************************************//**
+Handle the scheduling of a user thread that wants to enter InnoDB.  Setting
+srv_adaptive_max_sleep_delay > 0 switches the adaptive sleep calibration to
+ON. When set, we want to wait in the queue for as little time as possible.
+However, very short waits will result in a lot of context switches and that
+is also not desirable. When threads need to sleep multiple times we increment
+os_thread_sleep_delay by one. When we see threads getting a slot without
+waiting and there are no other threads waiting in the queue, we try and reduce
+the wait as much as we can. Currently we reduce it by half each time. If the
+thread only had to wait for one turn before it was able to enter InnoDB we
+decrement it by one. This is to try and keep the sleep time stable around the
+"optimum" sleep time. */
+static
+void
+srv_conc_enter_innodb_with_atomics(
+/*===============================*/
+	trx_t*	trx)			/*!< in/out: transaction that wants
+					to enter InnoDB */
+{
+	ulint	n_sleeps = 0;
+	ibool	notified_mysql = FALSE;
 
-	if (trx->mysql_thd != NULL
-	    && thd_is_replication_slave_thread(trx->mysql_thd)) {
+	ut_a(!trx->declared_to_be_inside_innodb);
 
-		UT_WAIT_FOR(srv_conc_n_threads
-			    < (lint)srv_thread_concurrency,
-			    srv_replication_delay * 1000);
+	for (;;) {
+		ulint	sleep_in_us;
 
-		return;
+		if (srv_conc.n_active < (lint) srv_thread_concurrency) {
+			ulint	n_active;
+
+			/* Check if there are any free tickets. */
+			n_active = os_atomic_increment_lint(
+				&srv_conc.n_active, 1);
+
+			if (n_active <= srv_thread_concurrency) {
+
+				srv_enter_innodb_with_tickets(trx);
+
+				if (notified_mysql) {
+
+					(void) os_atomic_decrement_lint(
+						&srv_conc.n_waiting, 1);
+
+					thd_wait_end(trx->mysql_thd);
+				}
+
+				if (srv_adaptive_max_sleep_delay > 0) {
+					if (srv_thread_sleep_delay > 20
+					    && n_sleeps == 1) {
+
+						--srv_thread_sleep_delay;
+					}
+
+					if (srv_conc.n_waiting == 0) {
+						srv_thread_sleep_delay >>= 1;
+					}
+				}
+
+				return;
+			}
+
+			/* Since there were no free seats, we relinquish
+			the overbooked ticket. */
+
+			(void) os_atomic_decrement_lint(
+				&srv_conc.n_active, 1);
+		}
+
+		if (!notified_mysql) {
+			(void) os_atomic_increment_lint(
+				&srv_conc.n_waiting, 1);
+
+			/* Release possible search system latch this
+			thread has */
+
+			if (trx->has_search_latch) {
+				trx_search_latch_release_if_reserved(trx);
+			}
+
+			thd_wait_begin(trx->mysql_thd, THD_WAIT_USER_LOCK);
+
+			notified_mysql = TRUE;
+		}
+
+		trx->op_info = "sleeping before entering InnoDB";
+
+		sleep_in_us = srv_thread_sleep_delay;
+
+		/* Guard against overflow when adaptive sleep delay is on. */
+
+		if (srv_adaptive_max_sleep_delay > 0
+		    && sleep_in_us > srv_adaptive_max_sleep_delay) {
+
+			sleep_in_us = srv_adaptive_max_sleep_delay;
+			srv_thread_sleep_delay = sleep_in_us;
+		}
+
+		os_thread_sleep(sleep_in_us);
+
+		trx->op_info = "";
+
+		++n_sleeps;
+
+		if (srv_adaptive_max_sleep_delay > 0 && n_sleeps > 1) {
+			++srv_thread_sleep_delay;
+		}
 	}
+}
 
-	/* If trx has 'free tickets' to enter the engine left, then use one
-	such ticket */
+/*********************************************************************//**
+Note that a user thread is leaving InnoDB code. */
+static
+void
+srv_conc_exit_innodb_with_atomics(
+/*==============================*/
+	trx_t*	trx)		/*!< in/out: transaction */
+{
+	trx->n_tickets_to_enter_innodb = 0;
+	trx->declared_to_be_inside_innodb = FALSE;
 
-	if (trx->n_tickets_to_enter_innodb > 0) {
-		trx->n_tickets_to_enter_innodb--;
+	(void) os_atomic_decrement_lint(&srv_conc.n_active, 1);
+}
+#else
+/*********************************************************************//**
+Note that a user thread is leaving InnoDB code. */
+static
+void
+srv_conc_exit_innodb_without_atomics(
+/*=================================*/
+	trx_t*	trx)		/*!< in/out: transaction */
+{
+	srv_conc_slot_t*	slot;
 
-		return;
+	os_fast_mutex_lock(&srv_conc_mutex);
+
+	ut_ad(srv_conc.n_active > 0);
+	srv_conc.n_active--;
+	trx->declared_to_be_inside_innodb = FALSE;
+	trx->n_tickets_to_enter_innodb = 0;
+
+	slot = NULL;
+
+	if (srv_conc.n_active < (lint)srv_thread_concurrency) {
+		/* Look for a slot where a thread is waiting and no other
+		thread has yet released the thread */
+
+		for (slot = UT_LIST_GET_FIRST(srv_conc_queue);
+		     slot != NULL && slot->wait_ended == TRUE;
+		     slot = UT_LIST_GET_NEXT(srv_conc_queue, slot)) {
+
+			/* No op */
+		}
+
+		if (slot != NULL) {
+			slot->wait_ended = TRUE;
+
+			/* We increment the count on behalf of the released
+			thread */
+
+			srv_conc.n_active++;
+		}
+	}
+
+	os_fast_mutex_unlock(&srv_conc_mutex);
+
+	if (slot != NULL) {
+		os_event_set(slot->event);
 	}
+}
+
+/*********************************************************************//**
+Handle the scheduling of a user thread that wants to enter InnoDB. */
+static
+void
+srv_conc_enter_innodb_without_atomics(
+/*==================================*/
+	trx_t*	trx)			/*!< in/out: transaction that wants
+					to enter InnoDB */
+{
+	ulint			i;
+	srv_conc_slot_t*	slot = NULL;
+	ibool			has_slept = FALSE;
 
 	os_fast_mutex_lock(&srv_conc_mutex);
 retry:
@@ -193,17 +372,16 @@ retry:
 		      "InnoDB: it already is declared.\n", stderr);
 		trx_print(stderr, trx, 0);
 		putc('\n', stderr);
-
 		return;
 	}
 
-	ut_ad(srv_conc_n_threads >= 0);
+	ut_ad(srv_conc.n_active >= 0);
 
-	if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
+	if (srv_conc.n_active < (lint) srv_thread_concurrency) {
 
-		srv_conc_n_threads++;
+		srv_conc.n_active++;
 		trx->declared_to_be_inside_innodb = TRUE;
-		trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
+		trx->n_tickets_to_enter_innodb = srv_n_free_tickets_to_enter;
 
 		os_fast_mutex_unlock(&srv_conc_mutex);
 
@@ -211,7 +389,7 @@ retry:
 	}
 
 	/* If the transaction is not holding resources, let it sleep
-	for SRV_THREAD_SLEEP_DELAY microseconds, and try again then */
+	for srv_thread_sleep_delay microseconds, and try again then */
 
 	if (!has_slept && !trx->has_search_latch
 	    && NULL == UT_LIST_GET_FIRST(trx->lock.trx_locks)) {
@@ -219,7 +397,7 @@ retry:
 		has_slept = TRUE; /* We let it sleep only once to avoid
 				starvation */
 
-		srv_conc_n_waiting_threads++;
+		srv_conc.n_waiting++;
 
 		os_fast_mutex_unlock(&srv_conc_mutex);
 
@@ -230,15 +408,15 @@ retry:
 		situations of lots of thread switches. Simply put some
 		threads aside for a while to reduce the number of thread
 		switches. */
-		if (SRV_THREAD_SLEEP_DELAY > 0) {
-			os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
+		if (srv_thread_sleep_delay > 0) {
+			os_thread_sleep(srv_thread_sleep_delay);
 		}
 
 		trx->op_info = "";
 
 		os_fast_mutex_lock(&srv_conc_mutex);
 
-		srv_conc_n_waiting_threads--;
+		srv_conc.n_waiting--;
 
 		goto retry;
 	}
@@ -258,7 +436,7 @@ retry:
 		/* Could not find a free wait slot, we must let the
 		thread enter */
 
-		srv_conc_n_threads++;
+		srv_conc.n_active++;
 		trx->declared_to_be_inside_innodb = TRUE;
 		trx->n_tickets_to_enter_innodb = 0;
 
@@ -280,7 +458,7 @@ retry:
 
 	os_event_reset(slot->event);
 
-	srv_conc_n_waiting_threads++;
+	srv_conc.n_waiting++;
 
 	os_fast_mutex_unlock(&srv_conc_mutex);
 
@@ -301,7 +479,7 @@ retry:
 
 	os_fast_mutex_lock(&srv_conc_mutex);
 
-	srv_conc_n_waiting_threads--;
+	srv_conc.n_waiting--;
 
 	/* NOTE that the thread which released this thread already
 	incremented the thread counter on behalf of this thread */
@@ -311,10 +489,32 @@ retry:
 	UT_LIST_REMOVE(srv_conc_queue, srv_conc_queue, slot);
 
 	trx->declared_to_be_inside_innodb = TRUE;
-	trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
+	trx->n_tickets_to_enter_innodb = srv_n_free_tickets_to_enter;
 
 	os_fast_mutex_unlock(&srv_conc_mutex);
 }
+#endif /* HAVE_ATOMIC_BUILTINS */
+
+/*********************************************************************//**
+Puts an OS thread to wait if there are too many concurrent threads
+(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
+UNIV_INTERN
+void
+srv_conc_enter_innodb(
+/*==================*/
+	trx_t*	trx)	/*!< in: transaction object associated with the
+			thread */
+{
+#ifdef UNIV_SYNC_DEBUG
+	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
+#endif /* UNIV_SYNC_DEBUG */
+
+#ifdef HAVE_ATOMIC_BUILTINS
+	srv_conc_enter_innodb_with_atomics(trx);
+#else
+	srv_conc_enter_innodb_without_atomics(trx);
+#endif /* HAVE_ATOMIC_BUILTINS */
+}
 
 /*********************************************************************//**
 This lets a thread enter InnoDB regardless of the number of threads inside
@@ -330,20 +530,23 @@ srv_conc_force_enter_innodb(
 	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
 #endif /* UNIV_SYNC_DEBUG */
 
-	if (UNIV_LIKELY(!srv_thread_concurrency)) {
+	if (!srv_thread_concurrency) {
 
 		return;
 	}
 
-	ut_ad(srv_conc_n_threads >= 0);
+	ut_ad(srv_conc.n_active >= 0);
 
+#ifdef HAVE_ATOMIC_BUILTINS
+	(void) os_atomic_increment_lint(&srv_conc.n_active, 1);
+#else
 	os_fast_mutex_lock(&srv_conc_mutex);
+	++srv_conc.n_active;
+	os_fast_mutex_unlock(&srv_conc_mutex);
+#endif /* HAVE_ATOMIC_BUILTINS */
 
-	srv_conc_n_threads++;
-	trx->declared_to_be_inside_innodb = TRUE;
 	trx->n_tickets_to_enter_innodb = 1;
-
-	os_fast_mutex_unlock(&srv_conc_mutex);
+	trx->declared_to_be_inside_innodb = TRUE;
 }
 
 /*********************************************************************//**
@@ -356,51 +559,18 @@ srv_conc_force_exit_innodb(
 	trx_t*	trx)	/*!< in: transaction object associated with the
 			thread */
 {
-	srv_conc_slot_t*	slot	= NULL;
-
-	if (trx->mysql_thd != NULL
-	    && thd_is_replication_slave_thread(trx->mysql_thd)) {
+	if ((trx->mysql_thd != NULL
+	     && thd_is_replication_slave_thread(trx->mysql_thd))
+	    || trx->declared_to_be_inside_innodb == FALSE) {
 
 		return;
 	}
 
-	if (trx->declared_to_be_inside_innodb == FALSE) {
-
-		return;
-	}
-
-	os_fast_mutex_lock(&srv_conc_mutex);
-
-	ut_ad(srv_conc_n_threads > 0);
-	srv_conc_n_threads--;
-	trx->declared_to_be_inside_innodb = FALSE;
-	trx->n_tickets_to_enter_innodb = 0;
-
-	if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
-		/* Look for a slot where a thread is waiting and no other
-		thread has yet released the thread */
-
-		slot = UT_LIST_GET_FIRST(srv_conc_queue);
-
-		while (slot && slot->wait_ended == TRUE) {
-			slot = UT_LIST_GET_NEXT(srv_conc_queue, slot);
-		}
-
-		if (slot != NULL) {
-			slot->wait_ended = TRUE;
-
-			/* We increment the count on behalf of the released
-			thread */
-
-			srv_conc_n_threads++;
-		}
-	}
-
-	os_fast_mutex_unlock(&srv_conc_mutex);
-
-	if (slot != NULL) {
-		os_event_set(slot->event);
-	}
+#ifdef HAVE_ATOMIC_BUILTINS
+	srv_conc_exit_innodb_with_atomics(trx);
+#else
+	srv_conc_exit_innodb_without_atomics(trx);
+#endif /* HAVE_ATOMIC_BUILTINS */
 
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
@@ -408,38 +578,22 @@ srv_conc_force_exit_innodb(
 }
 
 /*********************************************************************//**
-This must be called when a thread exits InnoDB. */
+Get the count of threads waiting inside InnoDB. */
 UNIV_INTERN
-void
-srv_conc_exit_innodb(
-/*=================*/
-	trx_t*	trx)	/*!< in: transaction object associated with the
-			thread */
+ulint
+srv_conc_get_waiting_threads(void)
+/*==============================*/
 {
-#ifdef UNIV_SYNC_DEBUG
-	ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
-#endif /* UNIV_SYNC_DEBUG */
-
-	if (trx->n_tickets_to_enter_innodb > 0) {
-		/* We will pretend the thread is still inside InnoDB though it
-		now leaves the InnoDB engine. In this way we save
-		a lot of semaphore operations. srv_conc_force_exit_innodb is
-		used to declare the thread definitely outside InnoDB. It
-		should be called when there is a lock wait or an SQL statement
-		ends. */
-
-		return;
-	}
-
-	srv_conc_force_exit_innodb(trx);
+	return(srv_conc.n_waiting);
 }
 
 /*********************************************************************//**
-Get the count of threads waiting inside InnoDB. */
+Get the count of threads active inside InnoDB. */
 UNIV_INTERN
 ulint
-srv_conc_get_waiting_threads(void)
+srv_conc_get_active_threads(void)
 /*==============================*/
 {
-	return(srv_conc_n_waiting_threads);
-}
+	return(srv_conc.n_active);
+ }
+

=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c	2011-08-10 06:26:39 +0000
+++ b/storage/innobase/srv/srv0srv.c	2011-08-19 06:13:33 +0000
@@ -361,8 +361,6 @@ UNIV_INTERN ulong	srv_replication_delay
 
 /*-------------------------------------------*/
 UNIV_INTERN ulong	srv_n_spin_wait_rounds	= 30;
-UNIV_INTERN ulong	srv_n_free_tickets_to_enter = 500;
-UNIV_INTERN ulong	srv_thread_sleep_delay = 10000;
 UNIV_INTERN ulong	srv_spin_wait_delay	= 6;
 UNIV_INTERN ibool	srv_priority_boost	= TRUE;
 
@@ -1218,7 +1216,7 @@ srv_printf_innodb_monitor(
 	      "ROW OPERATIONS\n"
 	      "--------------\n", file);
 	fprintf(file, "%ld queries inside InnoDB, %lu queries in queue\n",
-		(long) srv_conc_n_threads,
+		(long) srv_conc_get_active_threads(),
 		srv_conc_get_waiting_threads());
 
 	/* This is a dirty read, without holding trx_sys->mutex. */

=== modified file 'storage/innobase/srv/srv0start.c'
--- a/storage/innobase/srv/srv0start.c	2011-07-19 00:25:20 +0000
+++ b/storage/innobase/srv/srv0start.c	2011-08-19 06:13:33 +0000
@@ -2433,12 +2433,12 @@ innobase_shutdown_for_mysql(void)
 
 	logs_empty_and_mark_files_at_shutdown();
 
-	if (srv_conc_n_threads != 0) {
+	if (srv_conc_get_active_threads() != 0) {
 		fprintf(stderr,
 			"InnoDB: Warning: query counter shows %ld queries"
 			" still\n"
 			"InnoDB: inside InnoDB at shutdown\n",
-			srv_conc_n_threads);
+			srv_conc_get_active_threads());
 	}
 
 	/* 2. Make all threads created by InnoDB to exit */

=== modified file 'storage/innobase/trx/trx0trx.c'
--- a/storage/innobase/trx/trx0trx.c	2011-07-26 11:08:42 +0000
+++ b/storage/innobase/trx/trx0trx.c	2011-08-19 06:13:33 +0000
@@ -185,21 +185,6 @@ trx_allocate_for_mysql(void)
 }
 
 /********************************************************************//**
-Releases the search latch if trx has reserved it. */
-UNIV_INTERN
-void
-trx_search_latch_release_if_reserved(
-/*=================================*/
-	trx_t*	   trx) /*!< in: transaction */
-{
-	if (trx->has_search_latch) {
-		rw_lock_s_unlock(&btr_search_latch);
-
-		trx->has_search_latch = FALSE;
-	}
-}
-
-/********************************************************************//**
 Frees a transaction object. */
 static
 void

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (marc.alff:3272 to 3273) Marc Alff22 Aug