summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_ctype.h3
-rw-r--r--mysql-test/Makefile.am2
-rw-r--r--mysql-test/r/ctype_big5.result13
-rw-r--r--mysql-test/r/ctype_ldml.result296
-rw-r--r--mysql-test/r/innodb.result39
-rw-r--r--mysql-test/r/multi_update.result34
-rw-r--r--mysql-test/r/rpl_grant.result77
-rw-r--r--mysql-test/std_data/Index.xml71
-rw-r--r--mysql-test/t/ctype_big5.test18
-rw-r--r--mysql-test/t/ctype_ldml-master.opt2
-rw-r--r--mysql-test/t/ctype_ldml.test63
-rw-r--r--mysql-test/t/innodb.test39
-rw-r--r--mysql-test/t/multi_update.test41
-rw-r--r--mysql-test/t/rpl_grant.test42
-rw-r--r--mysys/charset-def.c6
-rw-r--r--mysys/charset.c36
-rw-r--r--sql/sql_acl.cc8
-rw-r--r--sql/sql_class.cc59
-rw-r--r--sql/sql_update.cc90
-rw-r--r--strings/ctype-big5.c4
-rw-r--r--strings/ctype-gbk.c4
-rw-r--r--strings/ctype-sjis.c4
-rw-r--r--strings/ctype-uca.c4
-rw-r--r--strings/ctype.c2
24 files changed, 906 insertions, 51 deletions
diff --git a/include/m_ctype.h b/include/m_ctype.h
index e5debc6e032..cc6a3a4fb4e 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -296,10 +296,11 @@ extern CHARSET_INFO my_charset_tis620_thai_ci;
extern CHARSET_INFO my_charset_tis620_bin;
extern CHARSET_INFO my_charset_ucs2_general_ci;
extern CHARSET_INFO my_charset_ucs2_bin;
-extern CHARSET_INFO my_charset_ucs2_general_uca;
+extern CHARSET_INFO my_charset_ucs2_unicode_ci;
extern CHARSET_INFO my_charset_ujis_japanese_ci;
extern CHARSET_INFO my_charset_ujis_bin;
extern CHARSET_INFO my_charset_utf8_general_ci;
+extern CHARSET_INFO my_charset_utf8_unicode_ci;
extern CHARSET_INFO my_charset_utf8_bin;
extern CHARSET_INFO my_charset_cp1250_czech_ci;
extern CHARSET_INFO my_charset_filename;
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 774008bc106..0a6dbc3663a 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -62,6 +62,7 @@ dist-hook:
$(INSTALL_DATA) $(srcdir)/include/*.test $(distdir)/include
$(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/Index.xml $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data
@@ -106,6 +107,7 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/Index.xml $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(DESTDIR)$(testdir)/std_data
diff --git a/mysql-test/r/ctype_big5.result b/mysql-test/r/ctype_big5.result
index 6574908101c..3f1a87838cf 100644
--- a/mysql-test/r/ctype_big5.result
+++ b/mysql-test/r/ctype_big5.result
@@ -192,3 +192,16 @@ drop table t1;
select hex(convert(_big5 0xC84041 using ucs2));
hex(convert(_big5 0xC84041 using ucs2))
003F0041
+End of 4.1 tests
+create table t1 (a blob);
+insert into t1 values (0xEE00);
+delete from t1;
+select hex(load_file('test/t1.txt'));
+hex(load_file('test/t1.txt'))
+5CEE5C300A
+load data infile 't1.txt' into table t1;
+select hex(a) from t1;
+hex(a)
+EE00
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/ctype_ldml.result b/mysql-test/r/ctype_ldml.result
new file mode 100644
index 00000000000..f3d3ff700f0
--- /dev/null
+++ b/mysql-test/r/ctype_ldml.result
@@ -0,0 +1,296 @@
+drop table if exists t1;
+set names utf8;
+show variables like 'character_sets_dir%';
+Variable_name Value
+character_sets_dir MYSQL_TEST_DIR/std_data/
+show collation like 'utf8_test_ci';
+Collation Charset Id Default Compiled Sortlen
+utf8_test_ci utf8 240 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 241 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 'ucs2_vn_ci';
+Collation Charset Id Default Compiled Sortlen
+ucs2_vn_ci ucs2 242 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 Ạ
+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 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 ỉ
+1ECA Ị
+1ECB ị
+004B K
+006B k
+004C L
+006C l
+004D 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 Ộ
+1ED9 ộ
+01A0 Ơ
+01A1 ơ
+1EDA Ớ
+1EDB ớ
+1EDC Ờ
+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 Ỳ
+1EF3 ỳ
+1EF4 Ỵ
+1EF5 ỵ
+1EF6 Ỷ
+1EF7 ỷ
+1EF8 Ỹ
+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ÒÓÕòóõỌọỎỏ
+ÔôỐốỒồỔổỖỗỘộ
+ƠơỚớỜờỞởỠỡỢợ
+Pp
+Qq
+Rr
+Ss
+Tt
+UuÙÚùúŨũỤụỦủ
+ƯưỨứỪừỬửỮữỰự
+Vv
+Xx
+YyÝýỲỳỴỵỶỷỸỹ
+drop table t1;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 073c3e0dc5b..85ff561d1c4 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1086,6 +1086,39 @@ n d
1 30
2 20
drop table t1,t2;
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+CREATE TABLE `t2` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=INNODB DEFAULT CHARSET=latin1 ;
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t1.a+2;
+ERROR 23000: Duplicate entry '3' for key 1
+select * from t2 /* must be (3,1), (4,4) */;
+a b
+1 1
+4 4
+show master status /* there must no UPDATE in binlog */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 98
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+ERROR 23000: Duplicate entry '4' for key 1
+show master status /* there must be no UPDATE query event */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 98
+drop table t1, t2;
create table t1 (a int, b int) engine=innodb;
insert into t1 values(20,null);
select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
@@ -1751,13 +1784,13 @@ Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
-Innodb_rows_deleted 70
+Innodb_rows_deleted 72
show status like "Innodb_rows_inserted";
Variable_name Value
-Innodb_rows_inserted 1083
+Innodb_rows_inserted 1088
show status like "Innodb_rows_updated";
Variable_name Value
-Innodb_rows_updated 886
+Innodb_rows_updated 888
show status like "Innodb_row_lock_waits";
Variable_name Value
Innodb_row_lock_waits 0
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index 6d8e5dfdf2c..7b0b917cf1a 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -604,3 +604,37 @@ id c1 c2
2 test t ppc
9 abc ppc
drop table t1, t2;
+CREATE TABLE `t1` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+CREATE TABLE `t2` (
+`a` int(11) NOT NULL auto_increment,
+`b` int(11) default NULL,
+PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t1.a+2;
+ERROR 23000: Duplicate entry '3' for key 1
+select * from t2 /* must be (3,1), (4,4) */;
+a b
+3 1
+4 4
+show master status /* there must be the UPDATE query event */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 189
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+ERROR 23000: Duplicate entry '4' for key 1
+show master status /* there must be the UPDATE query event */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 204
+drop table t1, t2;
+end of tests
diff --git a/mysql-test/r/rpl_grant.result b/mysql-test/r/rpl_grant.result
new file mode 100644
index 00000000000..4d7ad298ce4
--- /dev/null
+++ b/mysql-test/r/rpl_grant.result
@@ -0,0 +1,77 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+**** On Master ****
+CREATE USER dummy@localhost;
+CREATE USER dummy1@localhost, dummy2@localhost;
+SELECT user, host FROM mysql.user WHERE user != 'root';
+user host
+dummy localhost
+dummy1 localhost
+dummy2 localhost
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+6
+**** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root';
+user host
+dummy localhost
+dummy1 localhost
+dummy2 localhost
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+6
+**** On Master ****
+DROP USER nonexisting@localhost;
+ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost'
+DROP USER nonexisting@localhost, dummy@localhost;
+ERROR HY000: Operation DROP USER failed for 'nonexisting'@'localhost'
+DROP USER dummy1@localhost, dummy2@localhost;
+SELECT user, host FROM mysql.user WHERE user != 'root';
+user host
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+3
+**** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root';
+user host
+SELECT COUNT(*) FROM mysql.user;
+COUNT(*)
+3
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 609
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running Yes
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 609
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
diff --git a/mysql-test/std_data/Index.xml b/mysql-test/std_data/Index.xml
new file mode 100644
index 00000000000..988dddcc68a
--- /dev/null
+++ b/mysql-test/std_data/Index.xml
@@ -0,0 +1,71 @@
+<charsets>
+
+ <charset name="utf8">
+ <collation name="utf8_test_ci" id="240">
+ <rules>
+ <reset>a</reset>
+ <s>b</s>
+ </rules>
+ </collation>
+
+ </charset>
+
+ <charset name="ucs2">
+ <collation name="ucs2_test_ci" id="241">
+ <rules>
+ <reset>a</reset>
+ <s>b</s>
+ </rules>
+ </collation>
+ <collation name="ucs2_vn_ci" id="242">
+ <!-- Vietnamese experimental collation -->
+ <rules>
+ <reset>A</reset>
+ <p>\u0103</p><t>\u0102</t>
+ <s>\u1EB1</s><t>\u1EB0</t>
+ <s>\u1EB3</s><t>\u1EB2</t>
+ <s>\u1EB5</s><t>\u1EB4</t>
+ <s>\u1EAF</s><t>\u1EAE</t>
+ <s>\u1EB7</s><t>\u1EB6</t>
+ <p>\u00E2</p><t>\u00C2</t>
+ <s>\u1EA7</s><t>\u1EA6</t>
+ <s>\u1EA9</s><t>\u1EA8</t>
+ <s>\u1EAB</s><t>\u1EAA</t>
+ <s>\u1EA5</s><t>\u1EA4</t>
+ <s>\u1EAD</s><t>\u1EAC</t>
+ <reset>D</reset>
+ <p>\u0111</p><t>\u0110</t>
+ <reset>E</reset>
+ <p>\u00EA</p><t>\u00CA</t>
+ <s>\u1EC1</s><t>\u1EC0</t>
+ <s>\u1EC3</s><t>\u1EC2</t>
+ <s>\u1EC5</s><t>\u1EC4</t>
+ <s>\u1EBF</s><t>\u1EBE</t>
+ <s>\u1EC7</s><t>\u1EC6</t>
+ <reset>O</reset>
+ <p>\u00F4</p><t>\u00D4</t>
+ <s>\u1ED3</s><t>\u1ED2</t>
+ <s>\u1ED5</s><t>\u1ED4</t>
+ <s>\u1ED7</s><t>\u1ED6</t>
+ <s>\u1ED1</s><t>\u1ED0</t>
+ <s>\u1ED9</s><t>\u1ED8</t>
+ <p>\u01A1</p><t>\u01A0</t>
+ <s>\u1EDD</s><t>\u1EDC</t>
+ <s>\u1EDF</s><t>\u1EDE</t>
+ <s>\u1EE1</s><t>\u1EE0</t>
+ <s>\u1EDB</s><t>\u1EDA</t>
+ <s>\u1EE3</s><t>\u1EE2</t>
+ <reset>U</reset>
+ <p>\u01B0</p><t>\u01AF</t>
+ <s>\u1EEB</s><t>\u1EEA</t>
+ <s>\u1EED</s><t>\u1EEC</t>
+ <s>\u1EEF</s><t>\u1EEE</t>
+ <s>\u1EE9</s><t>\u1EE8</t>
+ <s>\u1EF1</s><t>\u1EF0</t>
+ </rules>
+
+ </collation>
+
+ </charset>
+
+</charsets>
diff --git a/mysql-test/t/ctype_big5.test b/mysql-test/t/ctype_big5.test
index 200002cd235..8e17a27c550 100644
--- a/mysql-test/t/ctype_big5.test
+++ b/mysql-test/t/ctype_big5.test
@@ -63,4 +63,20 @@ drop table t1;
#
select hex(convert(_big5 0xC84041 using ucs2));
-# End of 4.1 tests
+--echo End of 4.1 tests
+
+#
+# Bug#26711 "binary content 0x00 sometimes becomes 0x5C 0x00 after dump/load"
+#
+create table t1 (a blob);
+insert into t1 values (0xEE00);
+--exec $MYSQL_DUMP --default-character-set=big5 -T $MYSQLTEST_VARDIR/master-data/test test t1
+delete from t1;
+select hex(load_file('test/t1.txt'));
+load data infile 't1.txt' into table t1;
+select hex(a) from t1;
+--exec rm $MYSQLTEST_VARDIR/master-data/test/t1.txt
+--exec rm $MYSQLTEST_VARDIR/master-data/test/t1.sql
+drop table t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_ldml-master.opt b/mysql-test/t/ctype_ldml-master.opt
new file mode 100644
index 00000000000..a2532d4cfd9
--- /dev/null
+++ b/mysql-test/t/ctype_ldml-master.opt
@@ -0,0 +1,2 @@
+--character-sets-dir=$MYSQL_TEST_DIR/std_data/
+
diff --git a/mysql-test/t/ctype_ldml.test b/mysql-test/t/ctype_ldml.test
new file mode 100644
index 00000000000..fc6ed0f2579
--- /dev/null
+++ b/mysql-test/t/ctype_ldml.test
@@ -0,0 +1,63 @@
+--source include/have_ucs2.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+set names utf8;
+
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+show variables like 'character_sets_dir%';
+
+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;
+
+#
+# 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;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 8f619139e59..4ec20a3fd8a 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -755,6 +755,45 @@ select * from t2;
drop table t1,t2;
#
+# Bug#27716 multi-update did partially and has not binlogged
+#
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+
+CREATE TABLE `t2` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=INNODB DEFAULT CHARSET=latin1 ;
+
+# A. testing multi_update::send_eof() execution branch
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t1.a+2;
+# check
+select * from t2 /* must be (3,1), (4,4) */;
+show master status /* there must no UPDATE in binlog */;
+
+# B. testing multi_update::send_error() execution branch
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+show master status /* there must be no UPDATE query event */;
+
+# cleanup bug#27716
+drop table t1, t2;
+
+#
# Testing of IFNULL
#
create table t1 (a int, b int) engine=innodb;
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index 9cd93f2c7dd..87f90fd49e8 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -570,3 +570,44 @@ delete t1.*,t2.* from t1,t2 where t1.i2=t2.id;
select * from t1 order by i1;
select * from t2 order by id;
drop table t1, t2;
+
+#
+# Bug#27716 multi-update did partially and has not binlogged
+#
+
+CREATE TABLE `t1` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+
+CREATE TABLE `t2` (
+ `a` int(11) NOT NULL auto_increment,
+ `b` int(11) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
+
+# A. testing multi_update::send_eof() execution branch
+insert into t1 values (1,1),(2,2);
+insert into t2 values (1,1),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t1.a+2;
+# check
+select * from t2 /* must be (3,1), (4,4) */;
+show master status /* there must be the UPDATE query event */;
+
+# B. testing multi_update::send_error() execution branch
+delete from t1;
+delete from t2;
+insert into t1 values (1,2),(3,4),(4,4);
+insert into t2 values (1,2),(3,4),(4,4);
+reset master;
+--error ER_DUP_ENTRY
+UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
+show master status /* there must be the UPDATE query event */;
+
+# cleanup bug#27716
+drop table t1, t2;
+
+--echo end of tests
diff --git a/mysql-test/t/rpl_grant.test b/mysql-test/t/rpl_grant.test
new file mode 100644
index 00000000000..71e36342584
--- /dev/null
+++ b/mysql-test/t/rpl_grant.test
@@ -0,0 +1,42 @@
+# Tests of grants and users
+
+source include/master-slave.inc;
+source include/not_embedded.inc;
+
+--echo **** On Master ****
+connection master;
+
+CREATE USER dummy@localhost;
+CREATE USER dummy1@localhost, dummy2@localhost;
+
+SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+sync_slave_with_master;
+--echo **** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+
+--echo **** On Master ****
+connection master;
+
+# No user exists
+error ER_CANNOT_USER;
+DROP USER nonexisting@localhost;
+
+# At least one user exists, but not all
+error ER_CANNOT_USER;
+DROP USER nonexisting@localhost, dummy@localhost;
+
+# All users exist
+DROP USER dummy1@localhost, dummy2@localhost;
+
+SELECT user, host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+sync_slave_with_master;
+--echo **** On Slave ****
+SELECT user,host FROM mysql.user WHERE user != 'root'; # root host non-determ
+SELECT COUNT(*) FROM mysql.user;
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+query_vertical SHOW SLAVE STATUS;
diff --git a/mysys/charset-def.c b/mysys/charset-def.c
index 71833550ff4..63bbceef29b 100644
--- a/mysys/charset-def.c
+++ b/mysys/charset-def.c
@@ -24,7 +24,6 @@
#ifdef HAVE_UCA_COLLATIONS
#ifdef HAVE_CHARSET_ucs2
-extern CHARSET_INFO my_charset_ucs2_general_uca;
extern CHARSET_INFO my_charset_ucs2_icelandic_uca_ci;
extern CHARSET_INFO my_charset_ucs2_latvian_uca_ci;
extern CHARSET_INFO my_charset_ucs2_romanian_uca_ci;
@@ -46,7 +45,6 @@ extern CHARSET_INFO my_charset_ucs2_hungarian_uca_ci;
#endif
#ifdef HAVE_CHARSET_utf8
-extern CHARSET_INFO my_charset_utf8_general_uca_ci;
extern CHARSET_INFO my_charset_utf8_icelandic_uca_ci;
extern CHARSET_INFO my_charset_utf8_latvian_uca_ci;
extern CHARSET_INFO my_charset_utf8_romanian_uca_ci;
@@ -135,7 +133,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_ucs2_general_ci);
add_compiled_collation(&my_charset_ucs2_bin);
#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_ucs2_general_uca);
+ add_compiled_collation(&my_charset_ucs2_unicode_ci);
add_compiled_collation(&my_charset_ucs2_icelandic_uca_ci);
add_compiled_collation(&my_charset_ucs2_latvian_uca_ci);
add_compiled_collation(&my_charset_ucs2_romanian_uca_ci);
@@ -169,7 +167,7 @@ my_bool init_compiled_charsets(myf flags __attribute__((unused)))
add_compiled_collation(&my_charset_utf8_general_cs);
#endif
#ifdef HAVE_UCA_COLLATIONS
- add_compiled_collation(&my_charset_utf8_general_uca_ci);
+ add_compiled_collation(&my_charset_utf8_unicode_ci);
add_compiled_collation(&my_charset_utf8_icelandic_uca_ci);
add_compiled_collation(&my_charset_utf8_latvian_uca_ci);
add_compiled_collation(&my_charset_utf8_romanian_uca_ci);
diff --git a/mysys/charset.c b/mysys/charset.c
index 5f9521eeab8..f6bcf3f5a4f 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -202,6 +202,19 @@ static my_bool simple_cs_is_full(CHARSET_INFO *cs)
}
+static void
+copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from)
+{
+ to->cset= from->cset;
+ to->coll= from->coll;
+ to->strxfrm_multiply= from->strxfrm_multiply;
+ to->min_sort_char= from->min_sort_char;
+ to->max_sort_char= from->max_sort_char;
+ to->mbminlen= from->mbminlen;
+ to->mbmaxlen= from->mbmaxlen;
+}
+
+
static int add_collation(CHARSET_INFO *cs)
{
if (cs->name && (cs->number ||
@@ -225,29 +238,30 @@ static int add_collation(CHARSET_INFO *cs)
if (!(all_charsets[cs->number]->state & MY_CS_COMPILED))
{
- CHARSET_INFO *new= all_charsets[cs->number];
+ CHARSET_INFO *newcs= all_charsets[cs->number];
if (cs_copy_data(all_charsets[cs->number],cs))
return MY_XML_ERROR;
if (!strcmp(cs->csname,"ucs2") )
{
#if defined(HAVE_CHARSET_ucs2) && defined(HAVE_UCA_COLLATIONS)
- new->cset= my_charset_ucs2_general_uca.cset;
- new->coll= my_charset_ucs2_general_uca.coll;
- new->strxfrm_multiply= my_charset_ucs2_general_uca.strxfrm_multiply;
- new->min_sort_char= my_charset_ucs2_general_uca.min_sort_char;
- new->max_sort_char= my_charset_ucs2_general_uca.max_sort_char;
- new->mbminlen= 2;
- new->mbmaxlen= 2;
- new->state |= MY_CS_AVAILABLE | MY_CS_LOADED;
+ copy_uca_collation(newcs, &my_charset_ucs2_unicode_ci);
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
#endif
}
+ else if (!strcmp(cs->csname, "utf8"))
+ {
+#if defined (HAVE_CHARSET_utf8) && defined(HAVE_UCA_COLLATIONS)
+ copy_uca_collation(newcs, &my_charset_utf8_unicode_ci);
+ newcs->state|= MY_CS_AVAILABLE | MY_CS_LOADED;
+#endif
+ }
else
{
uchar *sort_order= all_charsets[cs->number]->sort_order;
simple_cs_init_functions(all_charsets[cs->number]);
- new->mbminlen= 1;
- new->mbmaxlen= 1;
+ newcs->mbminlen= 1;
+ newcs->mbmaxlen= 1;
if (simple_cs_is_full(all_charsets[cs->number]))
{
all_charsets[cs->number]->state |= MY_CS_LOADED;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 1b57e9363e4..dfdd6f5c5b4 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -5539,6 +5539,12 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
VOID(pthread_mutex_unlock(&acl_cache->lock));
+ if (result)
+ my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
+
+ DBUG_PRINT("info", ("thd->net.last_errno: %d", thd->net.last_errno));
+ DBUG_PRINT("info", ("thd->net.last_error: %s", thd->net.last_error));
+
if (mysql_bin_log.is_open())
{
thd->binlog_query(THD::MYSQL_QUERY_TYPE,
@@ -5547,8 +5553,6 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
- if (result)
- my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
DBUG_RETURN(result);
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 62f6706d717..e83432519d4 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1457,6 +1457,11 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
}
+#define NEED_ESCAPING(x) ((int) (uchar) (x) == escape_char || \
+ (int) (uchar) (x) == field_sep_char || \
+ (int) (uchar) (x) == line_sep_char || \
+ !(x))
+
bool select_export::send_data(List<Item> &items)
{
@@ -1516,14 +1521,20 @@ bool select_export::send_data(List<Item> &items)
used_length=res->length();
if (result_type == STRING_RESULT && escape_char != -1)
{
- char *pos,*start,*end;
-
+ char *pos, *start, *end;
+ CHARSET_INFO *res_charset= res->charset();
+ CHARSET_INFO *character_set_client= thd->variables.
+ character_set_client;
+ bool check_second_byte= (res_charset == &my_charset_bin) &&
+ character_set_client->
+ escape_with_backslash_is_dangerous;
+ DBUG_ASSERT(character_set_client->mbmaxlen == 2 ||
+ !character_set_client->escape_with_backslash_is_dangerous);
for (start=pos=(char*) res->ptr(),end=pos+used_length ;
pos != end ;
pos++)
{
#ifdef USE_MB
- CHARSET_INFO *res_charset=res->charset();
if (use_mb(res_charset))
{
int l;
@@ -1534,9 +1545,45 @@ bool select_export::send_data(List<Item> &items)
}
}
#endif
- if ((int) *pos == escape_char || (int) *pos == field_sep_char ||
- (int) *pos == line_sep_char || !*pos)
- {
+
+ /*
+ Special case when dumping BINARY/VARBINARY/BLOB values
+ for the clients with character sets big5, cp932, gbk and sjis,
+ which can have the escape character (0x5C "\" by default)
+ as the second byte of a multi-byte sequence.
+
+ If
+ - pos[0] is a valid multi-byte head (e.g 0xEE) and
+ - pos[1] is 0x00, which will be escaped as "\0",
+
+ then we'll get "0xEE + 0x5C + 0x30" in the output file.
+
+ If this file is later loaded using this sequence of commands:
+
+ mysql> create table t1 (a varchar(128)) character set big5;
+ mysql> LOAD DATA INFILE 'dump.txt' INTO TABLE t1;
+
+ then 0x5C will be misinterpreted as the second byte
+ of a multi-byte character "0xEE + 0x5C", instead of
+ escape character for 0x00.
+
+ To avoid this confusion, we'll escape the multi-byte
+ head character too, so the sequence "0xEE + 0x00" will be
+ dumped as "0x5C + 0xEE + 0x5C + 0x30".
+
+ Note, in the condition below we only check if
+ mbcharlen is equal to 2, because there are no
+ character sets with mbmaxlen longer than 2
+ and with escape_with_backslash_is_dangerous set.
+ DBUG_ASSERT before the loop makes that sure.
+ */
+
+ if (NEED_ESCAPING(*pos) ||
+ (check_second_byte &&
+ my_mbcharlen(character_set_client, (uchar) *pos) == 2 &&
+ pos + 1 < end &&
+ NEED_ESCAPING(pos[1])))
+ {
char tmp_buff[2];
tmp_buff[0]= escape_char;
tmp_buff[1]= *pos ? *pos : '0';
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index d9bf6b4d918..33ec8152837 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1069,6 +1069,7 @@ bool mysql_multi_update(THD *thd,
SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex)
{
multi_update *result;
+ bool res;
DBUG_ENTER("mysql_multi_update");
if (!(result= new multi_update(table_list,
@@ -1083,7 +1084,7 @@ bool mysql_multi_update(THD *thd,
MODE_STRICT_ALL_TABLES));
List<Item> total_list;
- (void) mysql_select(thd, &select_lex->ref_pointer_array,
+ res= mysql_select(thd, &select_lex->ref_pointer_array,
table_list, select_lex->with_wild,
total_list,
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
@@ -1091,6 +1092,15 @@ bool mysql_multi_update(THD *thd,
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
result, unit, select_lex);
+ DBUG_PRINT("info",("res: %d report_error: %d", res,
+ thd->net.report_error));
+ res|= thd->net.report_error;
+ if (unlikely(res))
+ {
+ /* If we had a another error reported earlier then this will be ignored */
+ result->send_error(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR));
+ result->abort();
+ }
delete result;
thd->abort_on_warning= 0;
DBUG_RETURN(FALSE);
@@ -1441,8 +1451,9 @@ multi_update::~multi_update()
if (copy_field)
delete [] copy_field;
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
- if (!trans_safe)
+ if (!trans_safe) // todo: remove since redundant
thd->no_trans_update.all= TRUE;
+ DBUG_ASSERT(trans_safe || thd->no_trans_update.all);
}
@@ -1531,8 +1542,15 @@ bool multi_update::send_data(List<Item> &not_used_values)
}
else
{
- if (!table->file->has_transactions())
+ /* non-transactional or transactional table got modified */
+ /* either multi_update class' flag is raised in its branch */
+ if (table->file->has_transactions())
+ transactional_tables= 1;
+ else
+ {
+ trans_safe= 0;
thd->no_trans_update.stmt= TRUE;
+ }
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))
@@ -1589,8 +1607,8 @@ void multi_update::send_error(uint errcode,const char *err)
my_error(errcode, MYF(0), err);
/* If nothing updated return */
- if (!updated)
- return;
+ if (updated == 0) /* the counter might be reset in send_eof */
+ return; /* and then the query has been binlogged */
/* Something already updated so we have to invalidate cache */
query_cache_invalidate3(thd, update_tables, 1);
@@ -1601,11 +1619,43 @@ void multi_update::send_error(uint errcode,const char *err)
*/
if (trans_safe)
- ha_rollback_stmt(thd);
- else if (do_update && table_count > 1)
{
- /* Add warning here */
- VOID(do_updates(0));
+ DBUG_ASSERT(transactional_tables);
+ (void) ha_autocommit_or_rollback(thd, 1);
+ }
+ else
+ {
+ DBUG_ASSERT(thd->no_trans_update.stmt);
+ if (do_update && table_count > 1)
+ {
+ /* Add warning here */
+ /*
+ todo/fixme: do_update() is never called with the arg 1.
+ should it change the signature to become argless?
+ */
+ VOID(do_updates(0));
+ }
+ }
+ if (thd->no_trans_update.stmt)
+ {
+ /*
+ The query has to binlog because there's a modified non-transactional table
+ either from the query's list or via a stored routine: bug#13270,23333
+ */
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ transactional_tables, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
+ if (!trans_safe)
+ thd->no_trans_update.all= TRUE;
+ }
+ DBUG_ASSERT(trans_safe || !updated || thd->no_trans_update.stmt);
+
+ if (transactional_tables)
+ {
+ (void) ha_autocommit_or_rollback(thd, 1);
}
}
@@ -1736,9 +1786,12 @@ int multi_update::do_updates(bool from_send_error)
if (updated != org_updated)
{
if (table->file->has_transactions())
- transactional_tables= 1;
+ transactional_tables= 1;
else
- trans_safe= 0; // Can't do safe rollback
+ {
+ trans_safe= 0; // Can't do safe rollback
+ thd->no_trans_update.stmt= TRUE;
+ }
}
(void) table->file->ha_rnd_end();
(void) tmp_table->file->ha_rnd_end();
@@ -1768,7 +1821,10 @@ err2:
if (table->file->has_transactions())
transactional_tables= 1;
else
+ {
trans_safe= 0;
+ thd->no_trans_update.stmt= TRUE;
+ }
}
DBUG_RETURN(1);
}
@@ -1798,14 +1854,20 @@ bool multi_update::send_eof()
Write the SQL statement to the binlog if we updated
rows and we succeeded or if we updated some non
transactional tables.
+
+ The query has to binlog because there's a modified non-transactional table
+ either from the query's list or via a stored routine: bug#13270,23333
*/
- if ((local_error == 0) || (updated && !trans_safe))
+ DBUG_ASSERT(trans_safe || !updated || thd->no_trans_update.stmt);
+ if (local_error == 0 || thd->no_trans_update.stmt)
{
if (mysql_bin_log.is_open())
{
if (local_error == 0)
thd->clear_error();
+ else
+ updated= 0; /* if there's an error binlog it here not in ::send_error */
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE) &&
@@ -1814,7 +1876,7 @@ bool multi_update::send_eof()
local_error= 1; // Rollback update
}
}
- if (!transactional_tables)
+ if (!trans_safe)
thd->no_trans_update.all= TRUE;
}
@@ -1826,7 +1888,7 @@ bool multi_update::send_eof()
if (local_error > 0) // if the above log write did not fail ...
{
- /* Safety: If we haven't got an error before (should not happen) */
+ /* Safety: If we haven't got an error before (can happen in do_updates) */
my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update",
MYF(0));
return TRUE;
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index a0571ff0b22..7bb811a3064 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -6402,7 +6402,7 @@ CHARSET_INFO my_charset_big5_chinese_ci=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_big5_handler,
&my_collation_big5_chinese_ci_handler
};
@@ -6435,7 +6435,7 @@ CHARSET_INFO my_charset_big5_bin=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_big5_handler,
&my_collation_mb_bin_handler
};
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index e9a2b7cf832..c7a2558eb37 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -10048,7 +10048,7 @@ CHARSET_INFO my_charset_gbk_chinese_ci=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_ci_handler
};
@@ -10080,7 +10080,7 @@ CHARSET_INFO my_charset_gbk_bin=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_mb_bin_handler
};
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index dfa8819a4db..ace457af63c 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -4696,7 +4696,7 @@ CHARSET_INFO my_charset_sjis_japanese_ci=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_ci_handler
};
@@ -4728,7 +4728,7 @@ CHARSET_INFO my_charset_sjis_bin=
0, /* min_sort_char */
255, /* max_sort_char */
' ', /* pad char */
- 0, /* escape_with_backslash_is_dangerous */
+ 1, /* escape_with_backslash_is_dangerous */
&my_charset_handler,
&my_collation_mb_bin_handler
};
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index ea0d5a1436a..4d106b5b897 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -8074,7 +8074,7 @@ MY_COLLATION_HANDLER my_collation_ucs2_uca_handler =
my_propagate_complex
};
-CHARSET_INFO my_charset_ucs2_general_uca=
+CHARSET_INFO my_charset_ucs2_unicode_ci=
{
128,0,0, /* number */
MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
@@ -8735,7 +8735,7 @@ static uchar ctype_utf8[] = {
extern MY_CHARSET_HANDLER my_charset_utf8_handler;
-CHARSET_INFO my_charset_utf8_general_uca_ci=
+CHARSET_INFO my_charset_utf8_unicode_ci=
{
192,0,0, /* number */
MY_CS_COMPILED|MY_CS_STRNXFRM|MY_CS_UNICODE,
diff --git a/strings/ctype.c b/strings/ctype.c
index de5625ef074..07f20ccb4ca 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -123,7 +123,7 @@ static struct my_cs_file_section_st * cs_file_sec(const char *attr, size_t len)
}
#define MY_CS_CSDESCR_SIZE 64
-#define MY_CS_TAILORING_SIZE 128
+#define MY_CS_TAILORING_SIZE 1024
typedef struct my_cs_file_info
{