summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xBUILD/compile-solaris-amd6455
-rw-r--r--client/mysql.cc11
-rw-r--r--mysql-test/include/ctype_regex.inc42
-rw-r--r--mysql-test/r/binlog_killed.result44
-rw-r--r--mysql-test/r/binlog_killed_simulate.result33
-rw-r--r--mysql-test/r/ctype_euckr.result41
-rw-r--r--mysql-test/r/ctype_uca.result45
-rw-r--r--mysql-test/r/ctype_ucs.result45
-rw-r--r--mysql-test/r/ctype_utf8.result45
-rw-r--r--mysql-test/r/func_regexp.result14
-rw-r--r--mysql-test/r/innodb.result17
-rw-r--r--mysql-test/r/mix_innodb_myisam_binlog.result119
-rw-r--r--mysql-test/r/multi_update.result24
-rw-r--r--mysql-test/r/mysql.result2
-rw-r--r--mysql-test/r/mysqlbinlog.result1
-rw-r--r--mysql-test/r/rpl_packet.result37
-rw-r--r--mysql-test/r/rpl_slave_skip.result144
-rw-r--r--mysql-test/r/rpl_sp_effects.result41
-rw-r--r--mysql-test/r/sp_trans_log.result4
-rw-r--r--mysql-test/std_data/corrupt-relay-bin.000624bin0 -> 91418 bytes
-rw-r--r--mysql-test/suite/manual/r/rpl_replication_delay.result121
-rw-r--r--mysql-test/suite/manual/t/rpl_replication_delay-slave.opt1
-rw-r--r--mysql-test/suite/manual/t/rpl_replication_delay.test71
-rw-r--r--mysql-test/t/binlog_killed.test244
-rw-r--r--mysql-test/t/binlog_killed_simulate-master.opt1
-rw-r--r--mysql-test/t/binlog_killed_simulate.test66
-rw-r--r--mysql-test/t/ctype_euckr.test23
-rw-r--r--mysql-test/t/ctype_uca.test6
-rw-r--r--mysql-test/t/ctype_ucs.test3
-rw-r--r--mysql-test/t/ctype_utf8.test7
-rw-r--r--mysql-test/t/func_regexp.test23
-rw-r--r--mysql-test/t/innodb.test32
-rw-r--r--mysql-test/t/mix_innodb_myisam_binlog.test186
-rw-r--r--mysql-test/t/multi_update.test34
-rw-r--r--mysql-test/t/mysql.test9
-rw-r--r--mysql-test/t/mysqlbinlog.test4
-rw-r--r--mysql-test/t/rpl_dual_pos_advance.test6
-rw-r--r--mysql-test/t/rpl_packet.test10
-rw-r--r--mysql-test/t/rpl_slave_skip-slave.opt1
-rw-r--r--mysql-test/t/rpl_slave_skip.test203
-rw-r--r--mysql-test/t/rpl_sp_effects.test51
-rw-r--r--mysql-test/t/rpl_temporary.test2
-rw-r--r--mysql-test/t/sp_trans_log.test2
-rw-r--r--mysql-test/t/subselect.test2
-rw-r--r--sql/item_cmpfunc.cc122
-rw-r--r--sql/item_cmpfunc.h4
-rw-r--r--sql/log.cc11
-rw-r--r--sql/log_event.cc169
-rw-r--r--sql/log_event.h10
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/slave.cc69
-rw-r--r--sql/sp_head.cc5
-rw-r--r--sql/sql_class.h18
-rw-r--r--sql/sql_delete.cc51
-rw-r--r--sql/sql_insert.cc81
-rw-r--r--sql/sql_load.cc28
-rw-r--r--sql/sql_parse.cc18
-rw-r--r--sql/sql_repl.cc10
-rw-r--r--sql/sql_update.cc94
-rw-r--r--strings/ctype-euc_kr.c27
60 files changed, 2200 insertions, 390 deletions
diff --git a/BUILD/compile-solaris-amd64 b/BUILD/compile-solaris-amd64
new file mode 100755
index 00000000000..f128fb12973
--- /dev/null
+++ b/BUILD/compile-solaris-amd64
@@ -0,0 +1,55 @@
+#!/usr/bin/bash
+
+function _find_mysql_root () (
+ while [ "x$PWD" != "x/" ]; do
+ # Check if some directories are present
+ if [ -d BUILD -a -d sql -a -d mysys ]; then
+ echo "$PWD"
+ return 0
+ fi
+ cd ..
+ done
+ return 1
+)
+
+make -k clean || true
+/bin/rm -f */.deps/*.P config.cache
+
+path=`dirname $0`
+. "$path/autorun.sh"
+
+warning_flags="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused"
+compiler_flags="-g -O3 -fno-omit-frame-pointer"
+
+export CC CXX CFLAGS CXXFLAGS LDFLAGS LIBS
+CC="gcc"
+CXX="gcc"
+CFLAGS="$warning_flags $compiler_flags"
+CXXFLAGS=""
+LDFLAGS="-O3 -g -static-libgcc"
+LIBS=-lmtmalloc
+root=$(_find_mysql_root)
+
+$root/configure \
+ --prefix=/usr/local/mysql \
+ --localstatedir=/usr/local/mysql/data \
+ --libexecdir=/usr/local/mysql/bin \
+ --with-extra-charsets=complex \
+ --enable-thread-safe-client \
+ --enable-local-infile \
+ --with-zlib-dir=bundled \
+ --with-big-tables \
+ --with-readline \
+ --with-archive-storage-engine \
+ --with-named-curses=-lcurses \
+ --with-big-tables \
+ --with-innodb \
+ --with-berkeley-db \
+ --with-example-storage-engine \
+ --with-blackhole-storage-engine \
+ --with-ndbcluster \
+ --with-federated-storage-engine \
+ --with-csv-storage-engine \
+ --with-ssl \
+ --with-embedded-server \
+ --disable-shared
diff --git a/client/mysql.cc b/client/mysql.cc
index aa34c69b945..5b1470141e5 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1047,6 +1047,17 @@ static int read_and_execute(bool interactive)
if (!interactive)
{
line=batch_readline(status.line_buff);
+ /*
+ Skip UTF8 Byte Order Marker (BOM) 0xEFBBBF.
+ Editors like "notepad" put this marker in
+ the very beginning of a text file when
+ you save the file using "Unicode UTF-8" format.
+ */
+ if (!line_number &&
+ (uchar) line[0] == 0xEF &&
+ (uchar) line[1] == 0xBB &&
+ (uchar) line[2] == 0xBF)
+ line+= 3;
line_number++;
if (!glob_buffer.length())
status.query_start_line=line_number;
diff --git a/mysql-test/include/ctype_regex.inc b/mysql-test/include/ctype_regex.inc
new file mode 100644
index 00000000000..0e6b4c41607
--- /dev/null
+++ b/mysql-test/include/ctype_regex.inc
@@ -0,0 +1,42 @@
+#
+# To test a desired collation, set session.collation_connection to
+# this collation before including this file
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+#
+# Create a table with two varchar(64) null-able column,
+# using current values of
+# @@character_set_connection and @@collation_connection.
+#
+
+create table t1 as
+select repeat(' ', 64) as s1, repeat(' ',64) as s2
+union
+select null, null;
+show create table t1;
+delete from t1;
+
+insert into t1 values('aaa','aaa');
+insert into t1 values('aaa|qqq','qqq');
+insert into t1 values('gheis','^[^a-dXYZ]+$');
+insert into t1 values('aab','^aa?b');
+insert into t1 values('Baaan','^Ba*n');
+insert into t1 values('aaa','qqq|aaa');
+insert into t1 values('qqq','qqq|aaa');
+
+insert into t1 values('bbb','qqq|aaa');
+insert into t1 values('bbb','qqq');
+insert into t1 values('aaa','aba');
+
+insert into t1 values(null,'abc');
+insert into t1 values('def',null);
+insert into t1 values(null,null);
+insert into t1 values('ghi','ghi[');
+
+select HIGH_PRIORITY s1 regexp s2 from t1;
+
+drop table t1;
diff --git a/mysql-test/r/binlog_killed.result b/mysql-test/r/binlog_killed.result
index ba4f38fb4c1..e04cc192876 100644
--- a/mysql-test/r/binlog_killed.result
+++ b/mysql-test/r/binlog_killed.result
@@ -9,4 +9,48 @@ insert into t2 values (null, null), (null, get_lock("a", 10));
select @result /* must be zero either way */;
@result
0
+select RELEASE_LOCK("a");
+RELEASE_LOCK("a")
+1
+delete from t1;
+delete from t2;
+insert into t1 values (1,1),(2,2);
+begin;
+update t1 set b=11 where a=2;
+begin;
+update t1 set b=b+10;
+kill query ID;
+rollback;
+rollback;
+select * from t1 order by a /* must be the same as before (1,1),(2,2) */;
+a b
+1 1
+2 2
+begin;
+delete from t1 where a=2;
+begin;
+delete from t1 where a=2;
+kill query ID;
+rollback;
+rollback;
+select * from t1 order by a /* must be the same as before (1,1),(2,2) */;
+a b
+1 1
+2 2
+drop table if exists t4;
+create table t4 (a int, b int) engine=innodb;
+insert into t4 values (3, 3);
+begin;
+insert into t1 values (3, 3);
+begin;
+insert into t1 select * from t4 for update;
+kill query ID;
+rollback;
+rollback;
+select * from t1 /* must be the same as before (1,1),(2,2) */;
+a b
+1 1
+2 2
+drop table t4;
drop table t1,t2,t3;
+end of the tests
diff --git a/mysql-test/r/binlog_killed_simulate.result b/mysql-test/r/binlog_killed_simulate.result
new file mode 100644
index 00000000000..a21ac5b1e32
--- /dev/null
+++ b/mysql-test/r/binlog_killed_simulate.result
@@ -0,0 +1,33 @@
+drop table if exists t1,t2;
+create table t1 (a int) engine=MyISAM;
+insert into t1 set a=1;
+reset master;
+update t1 set a=2 /* will be "killed" after work has been done */;
+select
+(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
+is not null;
+(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
+is not null
+1
+select 1 /* must return 1 as query completed before got killed*/;
+1
+1
+create table t2 (a int, b int) ENGINE=MyISAM;
+reset master;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */;
+ERROR 70100: Query execution was interrupted
+show binlog events from 98;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 98 Begin_load_query 1 # ;file_id=1;block_len=12
+master-bin.000001 133 Execute_load_query 1 # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */ ;file_id=1
+select
+(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
+is not null;
+(@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
+is not null
+1
+select 0 /* must return 0 to mean the killed query is in */;
+0
+0
+drop table t1,t2;
+end of the tests
diff --git a/mysql-test/r/ctype_euckr.result b/mysql-test/r/ctype_euckr.result
index b9619370d4c..ee786202c01 100644
--- a/mysql-test/r/ctype_euckr.result
+++ b/mysql-test/r/ctype_euckr.result
@@ -178,3 +178,44 @@ hex(a)
A2E6
FEF7
DROP TABLE t1;
+create table t1 (s1 varchar(5) character set euckr);
+insert into t1 values (0xA141);
+insert into t1 values (0xA15A);
+insert into t1 values (0xA161);
+insert into t1 values (0xA17A);
+insert into t1 values (0xA181);
+insert into t1 values (0xA1FE);
+insert into t1 values (0xA140);
+Warnings:
+Warning 1366 Incorrect string value: '\xA1@' for column 's1' at row 1
+insert into t1 values (0xA15B);
+Warnings:
+Warning 1366 Incorrect string value: '\xA1[' for column 's1' at row 1
+insert into t1 values (0xA160);
+Warnings:
+Warning 1366 Incorrect string value: '\xA1`' for column 's1' at row 1
+insert into t1 values (0xA17B);
+Warnings:
+Warning 1366 Incorrect string value: '\xA1{' for column 's1' at row 1
+insert into t1 values (0xA180);
+Warnings:
+Warning 1366 Incorrect string value: '\xA1\x80' for column 's1' at row 1
+insert into t1 values (0xA1FF);
+Warnings:
+Warning 1366 Incorrect string value: '\xA1\xFF' for column 's1' at row 1
+select hex(s1), hex(convert(s1 using utf8)) from t1 order by binary s1;
+hex(s1) hex(convert(s1 using utf8))
+
+
+
+
+
+
+A141 ECA2A5
+A15A ECA381
+A161 ECA382
+A17A ECA3A5
+A181 ECA3A6
+A1FE EFBFA2
+drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result
index e676d5a5ca0..ae9146fc9db 100644
--- a/mysql-test/r/ctype_uca.result
+++ b/mysql-test/r/ctype_uca.result
@@ -2767,4 +2767,49 @@ a
c
ch
drop table t1;
+set collation_connection=ucs2_unicode_ci;
+drop table if exists t1;
+create table t1 as
+select repeat(' ', 64) as s1, repeat(' ',64) as s2
+union
+select null, null;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `s1` varchar(64) character set ucs2 collate ucs2_unicode_ci default NULL,
+ `s2` varchar(64) character set ucs2 collate ucs2_unicode_ci default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+delete from t1;
+insert into t1 values('aaa','aaa');
+insert into t1 values('aaa|qqq','qqq');
+insert into t1 values('gheis','^[^a-dXYZ]+$');
+insert into t1 values('aab','^aa?b');
+insert into t1 values('Baaan','^Ba*n');
+insert into t1 values('aaa','qqq|aaa');
+insert into t1 values('qqq','qqq|aaa');
+insert into t1 values('bbb','qqq|aaa');
+insert into t1 values('bbb','qqq');
+insert into t1 values('aaa','aba');
+insert into t1 values(null,'abc');
+insert into t1 values('def',null);
+insert into t1 values(null,null);
+insert into t1 values('ghi','ghi[');
+select HIGH_PRIORITY s1 regexp s2 from t1;
+s1 regexp s2
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+NULL
+NULL
+NULL
+NULL
+drop table t1;
+set names utf8;
End for 5.0 tests
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 262055436b8..5a84dd0c3c0 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -922,6 +922,51 @@ ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (ucs2_gen
select * from t1 where a=if(b<10,_ucs2 0x0062,_ucs2 0x00C0);
ERROR HY000: Illegal mix of collations (ascii_general_ci,IMPLICIT) and (ucs2_general_ci,COERCIBLE) for operation '='
drop table t1;
+set collation_connection=ucs2_general_ci;
+drop table if exists t1;
+create table t1 as
+select repeat(' ', 64) as s1, repeat(' ',64) as s2
+union
+select null, null;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `s1` varchar(64) character set ucs2 default NULL,
+ `s2` varchar(64) character set ucs2 default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+delete from t1;
+insert into t1 values('aaa','aaa');
+insert into t1 values('aaa|qqq','qqq');
+insert into t1 values('gheis','^[^a-dXYZ]+$');
+insert into t1 values('aab','^aa?b');
+insert into t1 values('Baaan','^Ba*n');
+insert into t1 values('aaa','qqq|aaa');
+insert into t1 values('qqq','qqq|aaa');
+insert into t1 values('bbb','qqq|aaa');
+insert into t1 values('bbb','qqq');
+insert into t1 values('aaa','aba');
+insert into t1 values(null,'abc');
+insert into t1 values('def',null);
+insert into t1 values(null,null);
+insert into t1 values('ghi','ghi[');
+select HIGH_PRIORITY s1 regexp s2 from t1;
+s1 regexp s2
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+NULL
+NULL
+NULL
+NULL
+drop table t1;
+set names latin1;
select hex(char(0x41 using ucs2));
hex(char(0x41 using ucs2))
0041
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 4a15da71ee2..5ca1d578d2a 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -267,6 +267,51 @@ b
select * from t1 where a = 'b' and a != 'b';
a
drop table t1;
+set collation_connection=utf8_general_ci;
+drop table if exists t1;
+create table t1 as
+select repeat(' ', 64) as s1, repeat(' ',64) as s2
+union
+select null, null;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `s1` varchar(64) character set utf8 default NULL,
+ `s2` varchar(64) character set utf8 default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+delete from t1;
+insert into t1 values('aaa','aaa');
+insert into t1 values('aaa|qqq','qqq');
+insert into t1 values('gheis','^[^a-dXYZ]+$');
+insert into t1 values('aab','^aa?b');
+insert into t1 values('Baaan','^Ba*n');
+insert into t1 values('aaa','qqq|aaa');
+insert into t1 values('qqq','qqq|aaa');
+insert into t1 values('bbb','qqq|aaa');
+insert into t1 values('bbb','qqq');
+insert into t1 values('aaa','aba');
+insert into t1 values(null,'abc');
+insert into t1 values('def',null);
+insert into t1 values(null,null);
+insert into t1 values('ghi','ghi[');
+select HIGH_PRIORITY s1 regexp s2 from t1;
+s1 regexp s2
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+NULL
+NULL
+NULL
+NULL
+drop table t1;
+set names utf8;
set names utf8;
select 'вася' rlike '[[:<:]]вася[[:>:]]';
'вася' rlike '[[:<:]]вася[[:>:]]'
diff --git a/mysql-test/r/func_regexp.result b/mysql-test/r/func_regexp.result
index 2366947d2a7..c2dbfc3c331 100644
--- a/mysql-test/r/func_regexp.result
+++ b/mysql-test/r/func_regexp.result
@@ -1,5 +1,17 @@
drop table if exists t1;
-create table t1 (s1 char(64),s2 char(64));
+set names latin1;
+drop table if exists t1;
+create table t1 as
+select repeat(' ', 64) as s1, repeat(' ',64) as s2
+union
+select null, null;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `s1` varchar(64) default NULL,
+ `s2` varchar(64) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+delete from t1;
insert into t1 values('aaa','aaa');
insert into t1 values('aaa|qqq','qqq');
insert into t1 values('gheis','^[^a-dXYZ]+$');
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 6082a30bce3..38b26425ec8 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1119,6 +1119,19 @@ 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;
+drop table if exists t1, t2;
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create trigger trg_del_t2 after delete on t2 for each row
+insert into t1 values (1);
+insert into t1 values (1);
+insert into t2 values (1),(2);
+delete t2 from t2;
+ERROR 23000: Duplicate entry '1' for key 1
+select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
+count(*)
+2
+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
@@ -1792,10 +1805,10 @@ Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
-Innodb_rows_deleted 72
+Innodb_rows_deleted 73
show status like "Innodb_rows_inserted";
Variable_name Value
-Innodb_rows_inserted 29732
+Innodb_rows_inserted 29734
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 29532
diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
index 5777bd890b2..89ee82e9655 100644
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -351,7 +351,7 @@ drop function if exists bug27417;
drop table if exists t1,t2;
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a));
-create function bug27417(n int)
+create function bug27417(n int)
RETURNS int(11)
begin
insert into t1 values (null);
@@ -365,7 +365,7 @@ insert into t2 values (bug27417(2));
ERROR 23000: Duplicate entry '2' for key 1
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 98
+master-bin.000001 196
/* only (!) with fixes for #23333 will show there is the query */;
select count(*) from t1 /* must be 3 */;
count(*)
@@ -390,6 +390,119 @@ affected rows: 0
select count(*) from t1 /* must be 7 */;
count(*)
7
-drop function bug27417;
drop table t1,t2;
+CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM;
+CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb;
+CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+insert into t2 values (1);
+reset master;
+insert into t2 values (bug27417(1));
+ERROR 23000: Duplicate entry '1' for key 1
+show master status /* the offset must denote there is the query */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 267
+select count(*) from t1 /* must be 1 */;
+count(*)
+1
+delete from t1;
+delete from t2;
+insert into t2 values (2);
+reset master;
+insert into t2 select bug27417(1) union select bug27417(2);
+ERROR 23000: Duplicate entry '2' for key 1
+show master status /* the offset must denote there is the query */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 290
+select count(*) from t1 /* must be 2 */;
+count(*)
+2
+delete from t1;
+insert into t3 values (1,1),(2,3),(3,4);
+reset master;
+update t3 set b=b+bug27417(1);
+ERROR 23000: Duplicate entry '4' for key 2
+show master status /* the offset must denote there is the query */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 190
+select count(*) from t1 /* must be 2 */;
+count(*)
+2
+delete from t3;
+delete from t4;
+insert into t3 values (1,1);
+insert into t4 values (1,1),(2,2);
+reset master;
+UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
+ERROR 23000: Duplicate entry '2' for key 1
+show master status /* the offset must denote there is the query */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 301
+select count(*) from t1 /* must be 4 */;
+count(*)
+4
+delete from t1;
+delete from t3;
+delete from t4;
+insert into t3 values (1,1),(2,2);
+insert into t4 values (1,1),(2,2);
+reset master;
+UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
+ERROR 23000: Duplicate entry '2' for key 1
+select count(*) from t1 /* must be 1 */;
+count(*)
+1
+drop table t4;
+delete from t1;
+delete from t2;
+delete from t3;
+insert into t2 values (1);
+insert into t3 values (1,1);
+create trigger trg_del before delete on t2 for each row
+insert into t3 values (bug27417(1), 2);
+reset master;
+delete from t2;
+ERROR 23000: Duplicate entry '1' for key 1
+show master status /* the offset must denote there is the query */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 246
+select count(*) from t1 /* must be 1 */;
+count(*)
+1
+drop trigger trg_del;
+delete from t1;
+delete from t2;
+delete from t5;
+create trigger trg_del_t2 after delete on t2 for each row
+insert into t1 values (1);
+insert into t2 values (2),(3);
+insert into t5 values (1),(2);
+reset master;
+delete t2.* from t2,t5 where t2.a=t5.a + 1;
+ERROR 23000: Duplicate entry '1' for key 1
+show master status /* the offset must denote there is the query */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 274
+select count(*) from t1 /* must be 1 */;
+count(*)
+1
+delete from t1;
+create table t4 (a int default 0, b int primary key) engine=innodb;
+insert into t4 values (0, 17);
+reset master;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2);
+ERROR 23000: Duplicate entry '17' for key 1
+select * from t4;
+a b
+0 17
+select count(*) from t1 /* must be 2 */;
+count(*)
+2
+show master status /* the offset must denote there is the query */;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000001 376
+drop trigger trg_del_t2;
+drop table t1,t2,t3,t4,t5;
+drop function bug27417;
end of tests
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index 0f624e3ee8d..d95036090a5 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -545,7 +545,7 @@ a b
4 4
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 189
+master-bin.000001 260
delete from t1;
delete from t2;
insert into t1 values (1,2),(3,4),(4,4);
@@ -555,6 +555,26 @@ 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
+master-bin.000001 275
drop table t1, t2;
+drop table if exists t1, t2, t3;
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a));
+CREATE TABLE t3 (a int, PRIMARY KEY (a)) ENGINE=MyISAM;
+create trigger trg_del_t3 before delete on t3 for each row insert into t1 values (1);
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+reset master;
+delete t3.* from t2,t3 where t2.a=t3.a;
+ERROR 23000: Duplicate entry '1' for key 1
+select count(*) from t1 /* must be 1 */;
+count(*)
+1
+select count(*) from t3 /* must be 1 */;
+count(*)
+1
+show binlog events from 98;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 98 Query 1 # use `test`; delete t3.* from t2,t3 where t2.a=t3.a
+drop table t1, t2, t3;
end of tests
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index c6e589a5fb7..eded1a3fc3b 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -178,4 +178,6 @@ ERROR at line 1: DELIMITER cannot contain a backslash character
1
1
1
+This is a file starting with UTF8 BOM 0xEFBBBF
+This is a file starting with UTF8 BOM 0xEFBBBF
End of 5.0 tests
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index d16a4c39a11..9f001c293de 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -325,4 +325,5 @@ flush logs;
drop table t1;
1
drop table t1;
+shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql
End of 5.0 tests
diff --git a/mysql-test/r/rpl_packet.result b/mysql-test/r/rpl_packet.result
index 894bc81b08d..9425724b434 100644
--- a/mysql-test/r/rpl_packet.result
+++ b/mysql-test/r/rpl_packet.result
@@ -21,6 +21,37 @@ STOP SLAVE;
START SLAVE;
CREATE TABLe `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
-SHOW STATUS LIKE 'Slave_running';
-Variable_name Value
-Slave_running OFF
+show slave status;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 2138
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running No
+Slave_SQL_Running #
+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 2138
+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/r/rpl_slave_skip.result b/mysql-test/r/rpl_slave_skip.result
new file mode 100644
index 00000000000..a59ac3eb884
--- /dev/null
+++ b/mysql-test/r/rpl_slave_skip.result
@@ -0,0 +1,144 @@
+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 TABLE t1 (a INT, b SET('master','slave')) ENGINE=INNODB;
+CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MYISAM;
+==== Skipping normal transactions ====
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+BEGIN;
+INSERT INTO t1 VALUES (1, 'master');
+INSERT INTO t1 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, 'master');
+COMMIT;
+BEGIN;
+INSERT INTO t1 VALUES (4, 'master,slave');
+INSERT INTO t1 VALUES (5, 'master,slave');
+INSERT INTO t1 VALUES (6, 'master,slave');
+COMMIT;
+SELECT * FROM t1 ORDER BY a;
+a b
+1 master
+2 master
+3 master
+4 master,slave
+5 master,slave
+6 master,slave
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+SELECT * FROM t1 ORDER BY a;
+a b
+4 master,slave
+5 master,slave
+6 master,slave
+**** On Master ****
+DELETE FROM t1;
+==== Skipping two normal transactions ====
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+BEGIN;
+INSERT INTO t1 VALUES (1, 'master');
+INSERT INTO t1 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, 'master');
+COMMIT;
+BEGIN;
+INSERT INTO t1 VALUES (4, 'master');
+INSERT INTO t1 VALUES (5, 'master');
+INSERT INTO t1 VALUES (6, 'master');
+COMMIT;
+BEGIN;
+INSERT INTO t1 VALUES (7, 'master,slave');
+INSERT INTO t1 VALUES (8, 'master,slave');
+INSERT INTO t1 VALUES (9, 'master,slave');
+COMMIT;
+SELECT * FROM t1 ORDER BY a;
+a b
+1 master
+2 master
+3 master
+4 master
+5 master
+6 master
+7 master,slave
+8 master,slave
+9 master,slave
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=8;
+START SLAVE;
+SELECT * FROM t1 ORDER BY a;
+a b
+7 master,slave
+8 master,slave
+9 master,slave
+**** On Master ****
+DELETE FROM t1;
+==== Skipping without autocommit ====
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1, 'master');
+INSERT INTO t1 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, 'master');
+COMMIT;
+INSERT INTO t1 VALUES (4, 'master,slave');
+INSERT INTO t1 VALUES (5, 'master,slave');
+INSERT INTO t1 VALUES (6, 'master,slave');
+COMMIT;
+SELECT * FROM t1 ORDER BY a;
+a b
+1 master
+2 master
+3 master
+4 master,slave
+5 master,slave
+6 master,slave
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+SELECT * FROM t1 ORDER BY a;
+a b
+4 master,slave
+5 master,slave
+6 master,slave
+==== Rollback of transaction with non-transactional change ====
+**** On Master ****
+DELETE FROM t1;
+SET AUTOCOMMIT=1;
+**** On Slave ****
+STOP SLAVE;
+**** On Master ****
+BEGIN;
+INSERT INTO t1 VALUES (1, '');
+INSERT INTO t2 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, '');
+ROLLBACK;
+BEGIN;
+INSERT INTO t1 VALUES (4, '');
+INSERT INTO t2 VALUES (5, 'master,slave');
+INSERT INTO t1 VALUES (6, '');
+ROLLBACK;
+SELECT * FROM t1 ORDER BY a;
+a b
+SELECT * FROM t2 ORDER BY a;
+a b
+2 master
+5 master,slave
+**** On Slave ****
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+SELECT * FROM t1 ORDER BY a;
+a b
+SELECT * FROM t2 ORDER BY a;
+a b
+5 master,slave
+==== Cleanup ====
+**** On Master ****
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/rpl_sp_effects.result b/mysql-test/r/rpl_sp_effects.result
index bf8128d9385..70b2338d187 100644
--- a/mysql-test/r/rpl_sp_effects.result
+++ b/mysql-test/r/rpl_sp_effects.result
@@ -213,3 +213,44 @@ drop table t1;
drop function f1;
drop function f2;
drop procedure p1;
+create table t2 (b BIT(7));
+create procedure sp_bug26199(bitvalue BIT(7))
+begin
+insert into t2 set b = bitvalue;
+end //
+create function sf_bug26199(b BIT(7)) returns int
+begin
+insert into t2 values(b);
+return 0;
+end//
+call sp_bug26199(b'1110');
+call sp_bug26199('\0');
+select sf_bug26199(b'1111111');
+sf_bug26199(b'1111111')
+0
+select sf_bug26199(b'101111111');
+sf_bug26199(b'101111111')
+0
+Warnings:
+Warning 1264 Out of range value adjusted for column 'b' at row 1
+select sf_bug26199('\'');
+sf_bug26199('\'')
+0
+select hex(b) from t2;
+hex(b)
+E
+0
+7F
+7F
+27
+select hex(b) from t2;
+hex(b)
+E
+0
+7F
+7F
+27
+drop table t2;
+drop procedure sp_bug26199;
+drop function sf_bug26199;
+end of the tests
diff --git a/mysql-test/r/sp_trans_log.result b/mysql-test/r/sp_trans_log.result
index 96e6f76b23c..9b644798079 100644
--- a/mysql-test/r/sp_trans_log.result
+++ b/mysql-test/r/sp_trans_log.result
@@ -12,8 +12,10 @@ end|
reset master|
insert into t2 values (bug23333(),1)|
ERROR 23000: Duplicate entry '1' for key 1
-show binlog events from 98 /* with fixes for #23333 will show there is the query */|
+show binlog events from 98 /* with fixes for #23333 will show there are 2 queries */|
Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Query 1 # #
select count(*),@a from t1 /* must be 1,1 */|
count(*) @a
1 1
diff --git a/mysql-test/std_data/corrupt-relay-bin.000624 b/mysql-test/std_data/corrupt-relay-bin.000624
new file mode 100644
index 00000000000..21b4901211c
--- /dev/null
+++ b/mysql-test/std_data/corrupt-relay-bin.000624
Binary files differ
diff --git a/mysql-test/suite/manual/r/rpl_replication_delay.result b/mysql-test/suite/manual/r/rpl_replication_delay.result
new file mode 100644
index 00000000000..22447a30cba
--- /dev/null
+++ b/mysql-test/suite/manual/r/rpl_replication_delay.result
@@ -0,0 +1,121 @@
+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;
+show slave status /* Second_behind reports 0 */;;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port 9306
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 98
+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 98
+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 0
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+create table t1 (f1 int);
+flush logs /* contaminate rli->last_master_timestamp */;
+lock table t1 write;
+insert into t1 values (1);
+show slave status /* bug emulated: reports slave threads starting time about 3*3 not 3 secs */;;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port 9306
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 359
+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 271
+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 10
+unlock tables;
+flush logs /* this time rli->last_master_timestamp is not affected */;
+lock table t1 write;
+insert into t1 values (2);
+show slave status /* reports the correct diff with master query time about 3+3 secs */;;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port 9306
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 447
+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 359
+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 6
+unlock tables;
+drop table t1;
diff --git a/mysql-test/suite/manual/t/rpl_replication_delay-slave.opt b/mysql-test/suite/manual/t/rpl_replication_delay-slave.opt
new file mode 100644
index 00000000000..24a4c5952fe
--- /dev/null
+++ b/mysql-test/suite/manual/t/rpl_replication_delay-slave.opt
@@ -0,0 +1 @@
+--loose-debug=d,let_first_flush_log_change_timestamp
diff --git a/mysql-test/suite/manual/t/rpl_replication_delay.test b/mysql-test/suite/manual/t/rpl_replication_delay.test
new file mode 100644
index 00000000000..8230698c8f9
--- /dev/null
+++ b/mysql-test/suite/manual/t/rpl_replication_delay.test
@@ -0,0 +1,71 @@
+#
+# Testing replication delay reporting (bug#29309)
+# there is an unavoidable non-determinism in the test
+# please compare the results with the comments
+#
+
+
+source include/master-slave.inc;
+
+connection master;
+#connection slave;
+sync_slave_with_master;
+--replace_result $DEFAULT_MASTER_PORT DEFAULT_MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 #
+--query_vertical show slave status /* Second_behind reports 0 */;
+sleep 3;
+
+### bug emulation
+
+connection master;
+drop table if exists t1;
+create table t1 (f1 int);
+sleep 3;
+
+#connection slave;
+sync_slave_with_master;
+flush logs /* contaminate rli->last_master_timestamp */;
+
+connection slave;
+lock table t1 write;
+
+connection master;
+insert into t1 values (1);
+
+sleep 3;
+
+connection slave;
+--replace_result $DEFAULT_MASTER_PORT DEFAULT_MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 #
+--query_vertical show slave status /* bug emulated: reports slave threads starting time about 3*3 not 3 secs */;
+unlock tables;
+
+connection master;
+sync_slave_with_master;
+
+### bugfix
+
+
+connection slave;
+flush logs /* this time rli->last_master_timestamp is not affected */;
+lock table t1 write;
+
+connection master;
+insert into t1 values (2);
+sleep 3;
+
+connection slave;
+--replace_result $DEFAULT_MASTER_PORT DEFAULT_MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 #
+--query_vertical show slave status /* reports the correct diff with master query time about 3+3 secs */;
+unlock tables;
+
+connection master;
+drop table t1;
+
+#connection slave;
+sync_slave_with_master;
+
+
+# End of tests
+
diff --git a/mysql-test/t/binlog_killed.test b/mysql-test/t/binlog_killed.test
index 034895f17cb..af78adf0abc 100644
--- a/mysql-test/t/binlog_killed.test
+++ b/mysql-test/t/binlog_killed.test
@@ -55,194 +55,162 @@ enable_result_log;
select @result /* must be zero either way */;
-# the functions are either *insensitive* to killing or killing can cause
-# strange problmes with the error propagation out of SF's stack
-# Bug#27563, Bug#27565, BUG#24971
-#
-# TODO: use if's block as regression test for the bugs or remove
-#
-if (0)
-{
-delimiter |;
-create function bug27563()
-RETURNS int(11)
-DETERMINISTIC
-begin
- select get_lock("a", 10) into @a;
- return 1;
-end|
-delimiter ;|
-
-# the function is sensitive to killing requiring innodb though with wrong client error
-# TO FIX in BUG#27565; TODO: remove --error 1105 afterwards
-delimiter |;
-create function bug27565()
-RETURNS int(11)
-DETERMINISTIC
-begin
- select a from t1 where a=1 into @a for update;
- return 1;
-end|
-delimiter ;|
-
-reset master;
+--remove_file $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog
+connection con1;
+select RELEASE_LOCK("a");
-### ta table case: killing causes rollback
+#
+# bug#27571 asynchronous setting mysql_`query`::error and Query_log_e::error_code
+#
-# A. autocommit ON
-connection con1;
-select get_lock("a", 20);
+# checking that killing inside of select loops is safe as before
+# killing after the loop can be only simulated - another test
-connection con2;
-let $ID= `select connection_id()`;
-send insert into t1 values (bug27563(),1);
+delete from t1;
+delete from t2;
+insert into t1 values (1,1),(2,2);
+#
+# simple update
+#
connection con1;
-eval kill query $ID;
+begin; update t1 set b=11 where a=2;
connection con2;
-# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
---enable_info
-# todo: remove 0 return after fixing Bug#27563
---error 0,ER_QUERY_INTERRUPTED
-reap; ### pb: wrong error
---disable_info
-###--replace_column 2 # 5 #
-### show binlog events from 98 /* nothing in binlog unless Bug#27563 */;
-show master status /* must be only FD event unless Bug#27563 */;
-select count(*) from t1 /* must be zero unless Bug#27563 */;
-
-# M. multi-statement-ta
-connection con2;
let $ID= `select connection_id()`;
begin;
-send insert into t1 values (bug27563(),1);
+send update t1 set b=b+10;
connection con1;
+--replace_result $ID ID
eval kill query $ID;
+rollback;
+
+# Bug #32148 killi query may be ineffective
+# forced to comment out the test's outcome
+# and mask out ineffective ER_QUERY_INTERRUPTED
+# todo1: revert back upon fixing bug#32148
+# todo2: the tests need refining in that
+# killing should wait till the victim requested
+# its lock (wait_condition available in 5.1 tests)
+
connection con2;
-# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
---enable_info
-# todo: remove 0 return after fixing Bug#27563
--error 0,ER_QUERY_INTERRUPTED
reap;
---disable_info
-select count(*) from t1 /* must be zero unless Bug#27563 */;
-commit;
+rollback;
+select * from t1 order by a /* must be the same as before (1,1),(2,2) */;
+#
+# multi update
+# commented out as Bug #31807 multi-update,delete killing does not report with ER_QUERY_INTERRUPTED
+# in the way
+#
+# connection con1;
+# begin; update t1 set b=b+10;
-### non-ta table case: killing must be recorded in binlog
+# connection con2;
+# send update t1 as t_1,t1 as t_2 set t_1.b=11 where t_2.a=2;
-reset master;
+# connection con1;
+# --replace_result $ID ID
+# eval kill query $ID;
+# rollback;
+
+# disable_abort_on_error;
+
+# connection con2;
+# --error HY000,ER_QUERY_INTERRUPTED
+# reap;
+# select * from t1 /* must be the same as before (1,1),(2,2) */;
+
+# enable_abort_on_error;
+#
+# simple delete
+#
+connection con1;
+begin; delete from t1 where a=2;
connection con2;
let $ID= `select connection_id()`;
-send insert into t2 values (bug27563(),1);
+begin;
+send delete from t1 where a=2;
connection con1;
+--replace_result $ID ID
eval kill query $ID;
+rollback;
connection con2;
-# todo: remove 0 return after fixing Bug#27563
--error 0,ER_QUERY_INTERRUPTED
reap;
-select count(*) from t2 /* must be one */;
-#show binlog events from 98 /* must have the insert on non-ta table */;
-show master status /* must have the insert event more to FD */;
-# the value of the error flag of KILLED_QUERY is tested further
-
-connection con1;
-select RELEASE_LOCK("a");
-
-### test with effective killing of SF()
-
-delete from t1;
-delete from t2;
-insert into t1 values (1,1);
-insert into t2 values (1,1);
+rollback;
+# todo1,2 above
+select * from t1 order by a /* must be the same as before (1,1),(2,2) */;
-#
-# Bug#27565
-# test where KILL is propagated as error to the top level
-# still another bug with the error message to the user
-# todo: fix reexecute the result file after fixing
-#
-begin; update t1 set b=0 where a=1;
-connection con2;
-let $ID= `select connection_id()`;
-send update t2 set b=bug27565()-1 where a=1;
+#
+# multi delete
+# the same as for multi-update
+#
+# connection con1;
+# begin; delete from t1 where a=2;
-connection con1;
-eval kill query $ID;
-commit;
+# connection con2;
+# send delete t1 from t1 where t1.a=2;
-connection con2;
-# todo: fix Bug #27565 killed query of SF() is not reported correctly and
-# remove 1105 (wrong)
-#--error ER_QUERY_INTERRUPTED
---error 1105,ER_QUERY_INTERRUPTED
-reap; ### pb: wrong error
-select * from t1 /* must be: (1,0) */;
-select * from t2 /* must be as before: (1,1) */;
+# connection con1;
+# --replace_result $ID ID
+# eval kill query $ID;
+# rollback;
-## bug#22725 with effective and propagating killing
+# connection con2;
+# --error 0,ER_QUERY_INTERRUPTED
+# reap;
+# select * from t1 /* must be the same as before (1,1),(2,2) */;
+#
+# insert select
#
-# top-level ta-table
connection con1;
-delete from t3;
-reset master;
-begin; update t1 set b=0 where a=1;
+--disable_warnings
+drop table if exists t4;
+--enable_warnings
+create table t4 (a int, b int) engine=innodb;
+insert into t4 values (3, 3);
+begin; insert into t1 values (3, 3);
connection con2;
let $ID= `select connection_id()`;
-# the query won't perform completely since the function gets interrupted
-send insert into t3 values (0,0),(1,bug27565());
+begin;
+send insert into t1 select * from t4 for update;
connection con1;
+--replace_result $ID ID
eval kill query $ID;
rollback;
connection con2;
-# todo: fix Bug #27565 killed query of SF() is not reported correctly and
-# remove 1105 (wrong)
-#--error ER_QUERY_INTERRUPTED
---error 1105,ER_QUERY_INTERRUPTED
-reap; ### pb: wrong error
-select count(*) from t3 /* must be zero */;
-show master status /* nothing in binlog */;
-
-# top-level non-ta-table
-connection con1;
-delete from t2;
-reset master;
-begin; update t1 set b=0 where a=1;
-
-connection con2;
-let $ID= `select connection_id()`;
-# the query won't perform completely since the function gets intrurrupted
-send insert into t2 values (0,0),(1,bug27565()) /* non-ta t2 */;
-
-connection con1;
-eval kill query $ID;
+--error 0,ER_QUERY_INTERRUPTED
+reap;
+# todo 1,2 above
rollback;
+select * from t1 /* must be the same as before (1,1),(2,2) */;
-connection con2;
-# todo: fix Bug #27565 killed query of SF() is not reported correctly and
-# remove 1105 (wrong)
-#--error ER_QUERY_INTERRUPTED
---error 1105,ER_QUERY_INTERRUPTED
-reap; ### pb: wrong error
+drop table t4; # cleanup for the sub-case
+
+###
+## non-ta table case: killing must be recorded in binlog
+###
-select count(*) from t2 /* count must be one */;
-show master status /* insert into non-ta must be in binlog */;
+# In order to be deterministic the test needs INFORMATION_SCHEMA.PROCESSLIST
+# which is not available on 5.0 at this time.
+# Therefore, skip this part on 5.0.
-drop function bug27563;
-drop function bug27565;
-}
-system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ;
+#
+# common cleanup
+#
drop table t1,t2,t3;
+--echo end of the tests
diff --git a/mysql-test/t/binlog_killed_simulate-master.opt b/mysql-test/t/binlog_killed_simulate-master.opt
new file mode 100644
index 00000000000..90c70ecee29
--- /dev/null
+++ b/mysql-test/t/binlog_killed_simulate-master.opt
@@ -0,0 +1 @@
+--loose-debug=d,simulate_kill_bug27571
diff --git a/mysql-test/t/binlog_killed_simulate.test b/mysql-test/t/binlog_killed_simulate.test
new file mode 100644
index 00000000000..670cd756803
--- /dev/null
+++ b/mysql-test/t/binlog_killed_simulate.test
@@ -0,0 +1,66 @@
+-- source include/have_debug.inc
+#
+# bug#27571 asynchronous setting mysql_$query()'s local error and
+# Query_log_event::error_code
+#
+
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+#
+# Checking that killing upon successful row-loop does not affect binlogging
+#
+
+create table t1 (a int) engine=MyISAM;
+insert into t1 set a=1;
+reset master;
+
+update t1 set a=2 /* will be "killed" after work has been done */;
+
+# a proof the query is binlogged with no error
+
+--exec $MYSQL_BINLOG --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval select
+(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
+is not null;
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+let $error_code= `select @a like "%#%error_code=0%" /* must return 1 */`;
+eval select $error_code /* must return 1 as query completed before got killed*/;
+
+# cleanup for the sub-case
+system rm $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog;
+
+
+#
+# Checking that killing inside of row-loop for LOAD DATA into
+# non-transactional table affects binlogging
+#
+
+create table t2 (a int, b int) ENGINE=MyISAM;
+reset master;
+--error ER_QUERY_INTERRUPTED
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2 /* will be "killed" in the middle */;
+
+
+# a proof the query is binlogged with an error
+
+source include/show_binlog_events.inc;
+
+--exec $MYSQL_BINLOG --start-position=98 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval select
+(@a:=load_file("$MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog"))
+is not null;
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+let $error_code= `select @a like "%#%error_code=0%" /* must return 0*/`;
+eval select $error_code /* must return 0 to mean the killed query is in */;
+
+# cleanup for the sub-case
+system rm $MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog;
+
+
+drop table t1,t2;
+
+--echo end of the tests
diff --git a/mysql-test/t/ctype_euckr.test b/mysql-test/t/ctype_euckr.test
index 56939817b2f..05e4b04eded 100644
--- a/mysql-test/t/ctype_euckr.test
+++ b/mysql-test/t/ctype_euckr.test
@@ -31,3 +31,26 @@ SELECT hex(a) FROM t1 ORDER BY a;
DROP TABLE t1;
# End of 4.1 tests
+
+#
+#Bug #30315 Character sets: insertion of euckr code value 0xa141 fails
+#
+create table t1 (s1 varchar(5) character set euckr);
+# Insert some valid characters
+insert into t1 values (0xA141);
+insert into t1 values (0xA15A);
+insert into t1 values (0xA161);
+insert into t1 values (0xA17A);
+insert into t1 values (0xA181);
+insert into t1 values (0xA1FE);
+# Insert some invalid characters
+insert into t1 values (0xA140);
+insert into t1 values (0xA15B);
+insert into t1 values (0xA160);
+insert into t1 values (0xA17B);
+insert into t1 values (0xA180);
+insert into t1 values (0xA1FF);
+select hex(s1), hex(convert(s1 using utf8)) from t1 order by binary s1;
+drop table t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_uca.test b/mysql-test/t/ctype_uca.test
index 17632e7c8fc..0d917428efb 100644
--- a/mysql-test/t/ctype_uca.test
+++ b/mysql-test/t/ctype_uca.test
@@ -530,7 +530,7 @@ create table t1 (
a varchar(255),
key a(a)
) character set utf8 collate utf8_czech_ci;
--- In Czech 'ch' is a single letter between 'h' and 'i'
+# In Czech 'ch' is a single letter between 'h' and 'i'
insert into t1 values
('b'),('c'),('d'),('e'),('f'),('g'),('h'),('ch'),('i'),('j');
select * from t1 where a like 'c%';
@@ -538,4 +538,8 @@ alter table t1 convert to character set ucs2 collate ucs2_czech_ci;
select * from t1 where a like 'c%';
drop table t1;
+set collation_connection=ucs2_unicode_ci;
+--source include/ctype_regex.inc
+set names utf8;
+
-- echo End for 5.0 tests
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 5525a5beb6f..b837f53a17f 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -651,6 +651,9 @@ select * from t1 where a=if(b<10,_ucs2 0x00C0,_ucs2 0x0062);
select * from t1 where a=if(b<10,_ucs2 0x0062,_ucs2 0x00C0);
drop table t1;
+set collation_connection=ucs2_general_ci;
+--source include/ctype_regex.inc
+set names latin1;
#
# Bug#30981 CHAR(0x41 USING ucs2) doesn't add leading zero
#
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 0ae4b2be0ca..d184200ad5a 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -186,6 +186,13 @@ select * from t1 where a = 'b' and a != 'b';
drop table t1;
#
+# Testing regexp
+#
+set collation_connection=utf8_general_ci;
+--source include/ctype_regex.inc
+set names utf8;
+
+#
# Bug #3928 regexp [[:>:]] and UTF-8
#
set names utf8;
diff --git a/mysql-test/t/func_regexp.test b/mysql-test/t/func_regexp.test
index 5eff404bc0f..1b35fab9d54 100644
--- a/mysql-test/t/func_regexp.test
+++ b/mysql-test/t/func_regexp.test
@@ -6,28 +6,9 @@
drop table if exists t1;
--enable_warnings
-create table t1 (s1 char(64),s2 char(64));
+set names latin1;
+--source include/ctype_regex.inc
-insert into t1 values('aaa','aaa');
-insert into t1 values('aaa|qqq','qqq');
-insert into t1 values('gheis','^[^a-dXYZ]+$');
-insert into t1 values('aab','^aa?b');
-insert into t1 values('Baaan','^Ba*n');
-insert into t1 values('aaa','qqq|aaa');
-insert into t1 values('qqq','qqq|aaa');
-
-insert into t1 values('bbb','qqq|aaa');
-insert into t1 values('bbb','qqq');
-insert into t1 values('aaa','aba');
-
-insert into t1 values(null,'abc');
-insert into t1 values('def',null);
-insert into t1 values(null,null);
-insert into t1 values('ghi','ghi[');
-
-select HIGH_PRIORITY s1 regexp s2 from t1;
-
-drop table t1;
#
# This test a bug in regexp on Alpha
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 04dfa1d0836..d045bad39f7 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -793,6 +793,38 @@ show master status /* there must be no UPDATE query event */;
drop table t1, t2;
#
+# Bug #29136 erred multi-delete on trans table does not rollback
+#
+
+# prepare
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create trigger trg_del_t2 after delete on t2 for each row
+ insert into t1 values (1);
+insert into t1 values (1);
+insert into t2 values (1),(2);
+
+
+# exec cases A, B - see multi_update.test
+
+# A. send_error() w/o send_eof() branch
+
+--error ER_DUP_ENTRY
+delete t2 from t2;
+
+# check
+
+select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
+
+# cleanup bug#29136
+
+drop table t1, t2;
+
+
+#
# Testing of IFNULL
#
create table t1 (a int, b int) engine=innodb;
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
index f9d7235ff84..e0ce802254a 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -347,7 +347,7 @@ CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a));
delimiter |;
-create function bug27417(n int)
+create function bug27417(n int)
RETURNS int(11)
begin
insert into t1 values (null);
@@ -380,8 +380,190 @@ delete t2 from t2 where t2.a=bug27417(100) /* must not affect t2 */;
--disable_info
select count(*) from t1 /* must be 7 */;
-drop function bug27417;
+# function bug27417 remains for the following testing of bug#23333
drop table t1,t2;
+#
+# Bug#23333 using the patch (and the test) for bug#27471
+#
+# throughout the bug tests
+# t1 - non-trans side effects gatherer;
+# t2 - transactional table;
+#
+
+CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM;
+CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb;
+CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+
+
+#
+# INSERT
+#
+
+# prepare
+
+ insert into t2 values (1);
+ reset master;
+
+# execute
+
+ --error ER_DUP_ENTRY
+ insert into t2 values (bug27417(1));
+
+# check
+
+ show master status /* the offset must denote there is the query */;
+ select count(*) from t1 /* must be 1 */;
+
+#
+# INSERT SELECT
+#
+
+# prepare
+ delete from t1;
+ delete from t2;
+ insert into t2 values (2);
+ reset master;
+
+# execute
+
+ --error ER_DUP_ENTRY
+ insert into t2 select bug27417(1) union select bug27417(2);
+
+# check
+
+ show master status /* the offset must denote there is the query */;
+ select count(*) from t1 /* must be 2 */;
+
+#
+# UPDATE inc multi-update
+#
+
+# prepare
+ delete from t1;
+ insert into t3 values (1,1),(2,3),(3,4);
+ reset master;
+
+# execute
+ --error ER_DUP_ENTRY
+ update t3 set b=b+bug27417(1);
+
+# check
+ show master status /* the offset must denote there is the query */;
+ select count(*) from t1 /* must be 2 */;
+
+## multi_update::send_eof() branch
+
+# prepare
+ delete from t3;
+ delete from t4;
+ insert into t3 values (1,1);
+ insert into t4 values (1,1),(2,2);
+
+ reset master;
+
+# execute
+ --error ER_DUP_ENTRY
+ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */;
+
+# check
+ show master status /* the offset must denote there is the query */;
+ select count(*) from t1 /* must be 4 */;
+
+## send_error() branch of multi_update
+
+# prepare
+ delete from t1;
+ delete from t3;
+ delete from t4;
+ insert into t3 values (1,1),(2,2);
+ insert into t4 values (1,1),(2,2);
+
+ reset master;
+
+# execute
+ --error ER_DUP_ENTRY
+ UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
+
+# check
+ select count(*) from t1 /* must be 1 */;
+
+# cleanup
+ drop table t4;
+
+
+#
+# DELETE incl multi-delete
+#
+
+# prepare
+ delete from t1;
+ delete from t2;
+ delete from t3;
+ insert into t2 values (1);
+ insert into t3 values (1,1);
+ create trigger trg_del before delete on t2 for each row
+ insert into t3 values (bug27417(1), 2);
+ reset master;
+
+# execute
+ --error ER_DUP_ENTRY
+ delete from t2;
+# check
+ show master status /* the offset must denote there is the query */;
+ select count(*) from t1 /* must be 1 */;
+
+# cleanup
+ drop trigger trg_del;
+
+# prepare
+ delete from t1;
+ delete from t2;
+ delete from t5;
+ create trigger trg_del_t2 after delete on t2 for each row
+ insert into t1 values (1);
+ insert into t2 values (2),(3);
+ insert into t5 values (1),(2);
+ reset master;
+
+# execute
+ --error ER_DUP_ENTRY
+ delete t2.* from t2,t5 where t2.a=t5.a + 1;
+
+# check
+ show master status /* the offset must denote there is the query */;
+ select count(*) from t1 /* must be 1 */;
+
+
+#
+# LOAD DATA
+#
+
+# prepare
+ delete from t1;
+ create table t4 (a int default 0, b int primary key) engine=innodb;
+ insert into t4 values (0, 17);
+ reset master;
+
+# execute
+ --error ER_DUP_ENTRY
+ load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2);
+# check
+ select * from t4;
+ select count(*) from t1 /* must be 2 */;
+ show master status /* the offset must denote there is the query */;
+
+#
+# bug#23333 cleanup
+#
+
+
+drop trigger trg_del_t2;
+drop table t1,t2,t3,t4,t5;
+drop function bug27417;
+
+
--echo end of tests
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index 84e6a444d47..37cdfcf5f26 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -574,4 +574,38 @@ show master status /* there must be the UPDATE query event */;
# cleanup bug#27716
drop table t1, t2;
+#
+# Bug #29136 erred multi-delete on trans table does not rollback
+#
+
+# prepare
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a));
+CREATE TABLE t3 (a int, PRIMARY KEY (a)) ENGINE=MyISAM;
+create trigger trg_del_t3 before delete on t3 for each row insert into t1 values (1);
+
+insert into t2 values (1),(2);
+insert into t3 values (1),(2);
+reset master;
+
+# exec cases B, A - see innodb.test
+
+# B. send_eof() and send_error() afterward
+
+--error ER_DUP_ENTRY
+delete t3.* from t2,t3 where t2.a=t3.a;
+
+# check
+select count(*) from t1 /* must be 1 */;
+select count(*) from t3 /* must be 1 */;
+# the query must be in binlog (no surprise though)
+source include/show_binlog_events.inc;
+
+# cleanup bug#29136
+drop table t1, t2, t3;
+
+
--echo end of tests
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 6e97d0faede..182b292c817 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -281,4 +281,13 @@ remove_file $MYSQLTEST_VARDIR/tmp/bug21412.sql;
#
--exec $MYSQL test -e "/*! \C latin1 */ select 1;"
+#
+# Bug#29323 mysql client only accetps ANSI encoded files
+#
+--write_file $MYSQLTEST_VARDIR/tmp/bug29323.sql
+select "This is a file starting with UTF8 BOM 0xEFBBBF";
+EOF
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug29323.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/bug29323.sql;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index 451eef17108..c83fe94f2eb 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -237,4 +237,8 @@ let $c= `select $a=$b`;
--echo $c
drop table t1;
+echo shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql;
+error 1;
+exec $MYSQL_BINLOG $MYSQL_TEST_DIR/std_data/corrupt-relay-bin.000624 > $MYSQLTEST_VARDIR/tmp/bug31793.sql;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/rpl_dual_pos_advance.test b/mysql-test/t/rpl_dual_pos_advance.test
index 074aeec63b1..518fa9df885 100644
--- a/mysql-test/t/rpl_dual_pos_advance.test
+++ b/mysql-test/t/rpl_dual_pos_advance.test
@@ -106,9 +106,3 @@ connection slave;
sync_with_master;
# End of 4.1 tests
-
-# Cleanup
-# The A->B->A replication causes the master to start writing relay logs
-# in var/run, remove them
-remove_file $MYSQLTEST_VARDIR/run/master-relay-bin.000001;
-remove_file $MYSQLTEST_VARDIR/run/master-relay-bin.index;
diff --git a/mysql-test/t/rpl_packet.test b/mysql-test/t/rpl_packet.test
index f410b561663..84bc5d908bf 100644
--- a/mysql-test/t/rpl_packet.test
+++ b/mysql-test/t/rpl_packet.test
@@ -64,9 +64,11 @@ CREATE TABLe `t1` (`f1` LONGTEXT) ENGINE=MyISAM;
INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048');
# The slave I/O thread must stop after trying to read the above event
-connection slave;
-sleep 2;
-SHOW STATUS LIKE 'Slave_running';
-
+connection slave;
+--source include/wait_for_slave_io_to_stop.inc
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+# import is only the 11th column Slave_IO_Running
+--replace_column 1 # 8 # 9 # 12 # 23 # 33 #
+query_vertical show slave status;
# End of tests
diff --git a/mysql-test/t/rpl_slave_skip-slave.opt b/mysql-test/t/rpl_slave_skip-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_slave_skip-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_slave_skip.test b/mysql-test/t/rpl_slave_skip.test
new file mode 100644
index 00000000000..04aafc51129
--- /dev/null
+++ b/mysql-test/t/rpl_slave_skip.test
@@ -0,0 +1,203 @@
+source include/have_innodb.inc;
+source include/master-slave.inc;
+
+# This test is for checking that the use of SQL_SLAVE_SKIP_COUNTER
+# behaves as expected, i.e., that it is guaranteed to skip an entire
+# group and not start executing in the middle of a transaction.
+
+# We are checking the correct behaviour when using both a
+# transactional and non-transactional table. The non-transactional
+# table comes into play when rolling back a transaction containing a
+# write to this table. In that case, the transaction should still be
+# written to the binary log, and the slave will apply it and then roll
+# it back to get the non-transactional change into the table.
+
+--echo **** On Master ****
+CREATE TABLE t1 (a INT, b SET('master','slave')) ENGINE=INNODB;
+CREATE TABLE t2 (a INT, b SET('master','slave')) ENGINE=MYISAM;
+
+--echo ==== Skipping normal transactions ====
+
+--echo **** On Slave ****
+sync_slave_with_master;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+
+BEGIN;
+INSERT INTO t1 VALUES (1, 'master');
+INSERT INTO t1 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, 'master');
+COMMIT;
+
+BEGIN;
+INSERT INTO t1 VALUES (4, 'master,slave');
+INSERT INTO t1 VALUES (5, 'master,slave');
+INSERT INTO t1 VALUES (6, 'master,slave');
+COMMIT;
+
+save_master_pos;
+
+SELECT * FROM t1 ORDER BY a;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+SELECT * FROM t1 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t1;
+sync_slave_with_master;
+
+--echo ==== Skipping two normal transactions ====
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+
+BEGIN;
+INSERT INTO t1 VALUES (1, 'master');
+INSERT INTO t1 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, 'master');
+COMMIT;
+
+BEGIN;
+INSERT INTO t1 VALUES (4, 'master');
+INSERT INTO t1 VALUES (5, 'master');
+INSERT INTO t1 VALUES (6, 'master');
+COMMIT;
+
+BEGIN;
+INSERT INTO t1 VALUES (7, 'master,slave');
+INSERT INTO t1 VALUES (8, 'master,slave');
+INSERT INTO t1 VALUES (9, 'master,slave');
+COMMIT;
+
+save_master_pos;
+
+SELECT * FROM t1 ORDER BY a;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=8;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+SELECT * FROM t1 ORDER BY a;
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t1;
+sync_slave_with_master;
+
+--echo ==== Skipping without autocommit ====
+
+# Testing without using autocommit instead. It should still write a
+# BEGIN event, so the behaviour should be the same
+
+--echo **** On Slave ****
+connection slave;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+SET AUTOCOMMIT=0;
+
+INSERT INTO t1 VALUES (1, 'master');
+INSERT INTO t1 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, 'master');
+COMMIT;
+
+INSERT INTO t1 VALUES (4, 'master,slave');
+INSERT INTO t1 VALUES (5, 'master,slave');
+INSERT INTO t1 VALUES (6, 'master,slave');
+COMMIT;
+
+save_master_pos;
+
+SELECT * FROM t1 ORDER BY a;
+
+# This will skip a begin event and the first INSERT of the
+# transaction, and it should keep skipping until it has reached the
+# transaction terminator.
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+SELECT * FROM t1 ORDER BY a;
+
+# Testing with a non-transactional table in the transaction. This will
+# log a ROLLBACK as a transaction terminator, which is a normal Query
+# log event.
+
+--echo ==== Rollback of transaction with non-transactional change ====
+
+--echo **** On Master ****
+connection master;
+DELETE FROM t1;
+SET AUTOCOMMIT=1;
+
+--echo **** On Slave ****
+sync_slave_with_master;
+STOP SLAVE;
+source include/wait_for_slave_to_stop.inc;
+
+--echo **** On Master ****
+connection master;
+disable_warnings;
+BEGIN;
+INSERT INTO t1 VALUES (1, '');
+INSERT INTO t2 VALUES (2, 'master');
+INSERT INTO t1 VALUES (3, '');
+ROLLBACK;
+
+BEGIN;
+INSERT INTO t1 VALUES (4, '');
+INSERT INTO t2 VALUES (5, 'master,slave');
+INSERT INTO t1 VALUES (6, '');
+ROLLBACK;
+enable_warnings;
+
+save_master_pos;
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+--echo **** On Slave ****
+connection slave;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+source include/wait_for_slave_to_start.inc;
+sync_with_master;
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+--echo ==== Cleanup ====
+
+--echo **** On Master ****
+connection master;
+DROP TABLE t1, t2;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_sp_effects.test b/mysql-test/t/rpl_sp_effects.test
index 9da5723b993..f18710efa37 100644
--- a/mysql-test/t/rpl_sp_effects.test
+++ b/mysql-test/t/rpl_sp_effects.test
@@ -195,9 +195,60 @@ sync_slave_with_master;
connection slave;
select 'slave', a from t1;
+#
+# cleanup
+#
+
connection master;
drop table t1;
drop function f1;
drop function f2;
drop procedure p1;
sync_slave_with_master;
+
+#
+# bug#26199 Replication Failure on Slave when using stored procs
+# with bit-type parameters
+
+connection master;
+
+create table t2 (b BIT(7));
+delimiter //;
+create procedure sp_bug26199(bitvalue BIT(7))
+begin
+ insert into t2 set b = bitvalue;
+end //
+
+create function sf_bug26199(b BIT(7)) returns int
+begin
+ insert into t2 values(b);
+ return 0;
+end//
+
+DELIMITER ;//
+
+
+
+call sp_bug26199(b'1110');
+call sp_bug26199('\0');
+select sf_bug26199(b'1111111');
+select sf_bug26199(b'101111111');
+select sf_bug26199('\'');
+select hex(b) from t2;
+
+sync_slave_with_master;
+#connection slave;
+select hex(b) from t2;
+
+#
+# cleanup bug#26199
+#
+connection master;
+drop table t2;
+drop procedure sp_bug26199;
+drop function sf_bug26199;
+
+sync_slave_with_master;
+
+
+--echo end of the tests
diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test
index d09049af217..a7a15aebe7a 100644
--- a/mysql-test/t/rpl_temporary.test
+++ b/mysql-test/t/rpl_temporary.test
@@ -211,6 +211,8 @@ select * from t1;
connection master;
drop table t1;
+--remove_file $MYSQLTEST_VARDIR/tmp/bug14157.sql
+
# Delete the anonymous users
source include/delete_anonymous_users.inc;
diff --git a/mysql-test/t/sp_trans_log.test b/mysql-test/t/sp_trans_log.test
index 3e440b3ccc1..93605722f6b 100644
--- a/mysql-test/t/sp_trans_log.test
+++ b/mysql-test/t/sp_trans_log.test
@@ -27,7 +27,7 @@ reset master|
--error ER_DUP_ENTRY
insert into t2 values (bug23333(),1)|
--replace_column 2 # 5 # 6 #
-show binlog events from 98 /* with fixes for #23333 will show there is the query */|
+show binlog events from 98 /* with fixes for #23333 will show there are 2 queries */|
select count(*),@a from t1 /* must be 1,1 */|
drop table t1, t2|
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index d076ca6bd33..86d2aec870c 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -2970,7 +2970,7 @@ DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
--- returns no rows, when it should
+# returns no rows, when it should
SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
GROUP BY a1.a;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index a9ad5ad675d..2be3dba9bed 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -4268,6 +4268,51 @@ void Item_func_like::cleanup()
#ifdef USE_REGEX
bool
+Item_func_regex::regcomp(bool send_error)
+{
+ char buff[MAX_FIELD_WIDTH];
+ String tmp(buff,sizeof(buff),&my_charset_bin);
+ String *res= args[1]->val_str(&tmp);
+ int error;
+
+ if (args[1]->null_value)
+ return TRUE;
+
+ if (regex_compiled)
+ {
+ if (!stringcmp(res, &prev_regexp))
+ return FALSE;
+ prev_regexp.copy(*res);
+ my_regfree(&preg);
+ regex_compiled= 0;
+ }
+
+ if (cmp_collation.collation != regex_lib_charset)
+ {
+ /* Convert UCS2 strings to UTF8 */
+ uint dummy_errors;
+ if (conv.copy(res->ptr(), res->length(), res->charset(),
+ regex_lib_charset, &dummy_errors))
+ return TRUE;
+ res= &conv;
+ }
+
+ if ((error= my_regcomp(&preg, res->c_ptr_safe(),
+ regex_lib_flags, regex_lib_charset)))
+ {
+ if (send_error)
+ {
+ (void) my_regerror(error, &preg, buff, sizeof(buff));
+ my_error(ER_REGEXP_ERROR, MYF(0), buff);
+ }
+ return TRUE;
+ }
+ regex_compiled= 1;
+ return FALSE;
+}
+
+
+bool
Item_func_regex::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
@@ -4283,35 +4328,34 @@ Item_func_regex::fix_fields(THD *thd, Item **ref)
if (agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1))
return TRUE;
+ regex_lib_flags= (cmp_collation.collation->state &
+ (MY_CS_BINSORT | MY_CS_CSSORT)) ?
+ REG_EXTENDED | REG_NOSUB :
+ REG_EXTENDED | REG_NOSUB | REG_ICASE;
+ /*
+ If the case of UCS2 and other non-ASCII character sets,
+ we will convert patterns and strings to UTF8.
+ */
+ regex_lib_charset= (cmp_collation.collation->mbminlen > 1) ?
+ &my_charset_utf8_general_ci :
+ cmp_collation.collation;
+
used_tables_cache=args[0]->used_tables() | args[1]->used_tables();
not_null_tables_cache= (args[0]->not_null_tables() |
args[1]->not_null_tables());
const_item_cache=args[0]->const_item() && args[1]->const_item();
if (!regex_compiled && args[1]->const_item())
{
- char buff[MAX_FIELD_WIDTH];
- String tmp(buff,sizeof(buff),&my_charset_bin);
- String *res=args[1]->val_str(&tmp);
if (args[1]->null_value)
{ // Will always return NULL
maybe_null=1;
fixed= 1;
return FALSE;
}
- int error;
- if ((error= my_regcomp(&preg,res->c_ptr(),
- ((cmp_collation.collation->state &
- (MY_CS_BINSORT | MY_CS_CSSORT)) ?
- REG_EXTENDED | REG_NOSUB :
- REG_EXTENDED | REG_NOSUB | REG_ICASE),
- cmp_collation.collation)))
- {
- (void) my_regerror(error,&preg,buff,sizeof(buff));
- my_error(ER_REGEXP_ERROR, MYF(0), buff);
+ if (regcomp(TRUE))
return TRUE;
- }
- regex_compiled=regex_is_const=1;
- maybe_null=args[0]->maybe_null;
+ regex_is_const= 1;
+ maybe_null= args[0]->maybe_null;
}
else
maybe_null=1;
@@ -4324,47 +4368,25 @@ longlong Item_func_regex::val_int()
{
DBUG_ASSERT(fixed == 1);
char buff[MAX_FIELD_WIDTH];
- String *res, tmp(buff,sizeof(buff),&my_charset_bin);
+ String tmp(buff,sizeof(buff),&my_charset_bin);
+ String *res= args[0]->val_str(&tmp);
- res=args[0]->val_str(&tmp);
- if (args[0]->null_value)
- {
- null_value=1;
+ if ((null_value= (args[0]->null_value ||
+ (!regex_is_const && regcomp(FALSE)))))
return 0;
- }
- if (!regex_is_const)
- {
- char buff2[MAX_FIELD_WIDTH];
- String *res2, tmp2(buff2,sizeof(buff2),&my_charset_bin);
- res2= args[1]->val_str(&tmp2);
- if (args[1]->null_value)
+ if (cmp_collation.collation != regex_lib_charset)
+ {
+ /* Convert UCS2 strings to UTF8 */
+ uint dummy_errors;
+ if (conv.copy(res->ptr(), res->length(), res->charset(),
+ regex_lib_charset, &dummy_errors))
{
- null_value=1;
+ null_value= 1;
return 0;
}
- if (!regex_compiled || stringcmp(res2,&prev_regexp))
- {
- prev_regexp.copy(*res2);
- if (regex_compiled)
- {
- my_regfree(&preg);
- regex_compiled=0;
- }
- if (my_regcomp(&preg,res2->c_ptr_safe(),
- ((cmp_collation.collation->state &
- (MY_CS_BINSORT | MY_CS_CSSORT)) ?
- REG_EXTENDED | REG_NOSUB :
- REG_EXTENDED | REG_NOSUB | REG_ICASE),
- cmp_collation.collation))
- {
- null_value=1;
- return 0;
- }
- regex_compiled=1;
- }
+ res= &conv;
}
- null_value=0;
return my_regexec(&preg,res->c_ptr_safe(),0,(my_regmatch_t*) 0,0) ? 0 : 1;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 4d3df7aebf9..735081d931f 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1318,6 +1318,10 @@ class Item_func_regex :public Item_bool_func
bool regex_is_const;
String prev_regexp;
DTCollation cmp_collation;
+ CHARSET_INFO *regex_lib_charset;
+ int regex_lib_flags;
+ String conv;
+ bool regcomp(bool send_error);
public:
Item_func_regex(Item *a,Item *b) :Item_bool_func(a,b),
regex_compiled(0),regex_is_const(0) {}
diff --git a/sql/log.cc b/sql/log.cc
index e9aa273676a..af03cecd462 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -448,13 +448,10 @@ const char *MYSQL_LOG::generate_name(const char *log_name,
{
if (!log_name || !log_name[0])
{
- /*
- TODO: The following should be using fn_format(); We just need to
- first change fn_format() to cut the file name if it's too long.
- */
- strmake(buff, pidfile_name,FN_REFLEN-5);
- strmov(fn_ext(buff),suffix);
- return (const char *)buff;
+ strmake(buff, pidfile_name, FN_REFLEN - strlen(suffix) - 1);
+ return (const char *)
+ fn_format(buff, buff, "", suffix, MYF(MY_REPLACE_EXT|MY_REPLACE_DIR));
+
}
// get rid of extension if the log is binary to avoid problems
if (strip_ext)
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 1ef765f607f..5c3fcf2f86b 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -27,6 +27,10 @@
#define log_cs &my_charset_latin1
+#ifndef DBUG_OFF
+uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
+#endif
+
/*
pretty_print_str()
*/
@@ -481,6 +485,18 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
rli->inc_event_relay_log_pos();
else
{
+ /*
+ bug#29309 simulation: resetting the flag to force
+ wrong behaviour of artificial event to update
+ rli->last_master_timestamp for only one time -
+ the first FLUSH LOGS in the test.
+ */
+ DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
+ if (debug_not_change_ts_if_art_event == 1
+ && is_artificial_event())
+ {
+ debug_not_change_ts_if_art_event= 0;
+ });
rli->inc_group_relay_log_pos(log_pos);
flush_relay_log_info(rli);
/*
@@ -491,7 +507,21 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
rare cases, only consequence is that value may take some time to
display in Seconds_Behind_Master - not critical).
*/
- rli->last_master_timestamp= when;
+#ifndef DBUG_OFF
+ if (!(is_artificial_event() && debug_not_change_ts_if_art_event > 0))
+#else
+ if (!is_artificial_event())
+#endif
+ rli->last_master_timestamp= when;
+ /*
+ The flag is set back to be positive so that
+ any further FLUSH LOGS will be handled as prescribed.
+ */
+ DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
+ if (debug_not_change_ts_if_art_event == 0)
+ {
+ debug_not_change_ts_if_art_event= 2;
+ });
}
}
DBUG_RETURN(0);
@@ -1370,18 +1400,48 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
/* 2 utility functions for the next method */
-/*
- Get the pointer for a string (src) that contains the length in
- the first byte. Set the output string (dst) to the string value
- and place the length of the string in the byte after the string.
+/**
+ Read a string with length from memory.
+
+ This function reads the string-with-length stored at
+ <code>src</code> and extract the length into <code>*len</code> and
+ a pointer to the start of the string into <code>*dst</code>. The
+ string can then be copied using <code>memcpy()</code> with the
+ number of bytes given in <code>*len</code>.
+
+ @param src Pointer to variable holding a pointer to the memory to
+ read the string from.
+ @param dst Pointer to variable holding a pointer where the actual
+ string starts. Starting from this position, the string
+ can be copied using @c memcpy().
+ @param len Pointer to variable where the length will be stored.
+ @param end One-past-the-end of the memory where the string is
+ stored.
+
+ @return Zero if the entire string can be copied successfully,
+ @c UINT_MAX if the length could not be read from memory
+ (that is, if <code>*src >= end</code>), otherwise the
+ number of bytes that are missing to read the full
+ string, which happends <code>*dst + *len >= end</code>.
*/
-static void get_str_len_and_pointer(const Log_event::Byte **src,
- const char **dst,
- uint *len)
-{
- if ((*len= **src))
- *dst= (char *)*src + 1; // Will be copied later
- (*src)+= *len + 1;
+static int
+get_str_len_and_pointer(const Log_event::Byte **src,
+ const char **dst,
+ uint *len,
+ const Log_event::Byte *end)
+{
+ if (*src >= end)
+ return -1; // Will be UINT_MAX in two-complement arithmetics
+ uint length= **src;
+ if (length > 0)
+ {
+ if (*src + length >= end)
+ return *src + length - end + 1; // Number of bytes missing
+ *dst= (char *)*src + 1; // Will be copied later
+ }
+ *len= length;
+ *src+= length + 1;
+ return 0;
}
static void copy_str_and_move(const char **src,
@@ -1394,6 +1454,42 @@ static void copy_str_and_move(const char **src,
*(*dst)++= 0;
}
+
+static char const *code_name(int code) {
+ char buf[255];
+ switch (code) {
+ case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
+ case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
+ case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
+ case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
+ case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
+ case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
+ case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
+ case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
+ case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
+ }
+ sprintf(buf, "CODE#%d", code);
+ return buf;
+}
+
+/**
+ Macro to check that there is enough space to read from memory.
+
+ @param PTR Pointer to memory
+ @param END End of memory
+ @param CNT Number of bytes that should be read.
+ */
+#define CHECK_SPACE(PTR,END,CNT) \
+ do { \
+ DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
+ DBUG_ASSERT((PTR) + (CNT) <= (END)); \
+ if ((PTR) + (CNT) > (END)) { \
+ DBUG_PRINT("info", ("query= 0")); \
+ query= 0; \
+ DBUG_VOID_RETURN; \
+ } \
+ } while (0)
+
/*
Query_log_event::Query_log_event()
This is used by the SQL slave thread to prepare the event before execution.
@@ -1445,6 +1541,19 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
if (tmp)
{
status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
+ /*
+ Check if status variable length is corrupt and will lead to very
+ wrong data. We could be even more strict and require data_len to
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+ if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len: %d; data_len: %d; query= 0",
+ status_vars_len, data_len));
+ query= 0;
+ DBUG_VOID_RETURN;
+ }
data_len-= status_vars_len;
DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
(uint) status_vars_len));
@@ -1464,6 +1573,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
{
switch (*pos++) {
case Q_FLAGS2_CODE:
+ CHECK_SPACE(pos, end, 4);
flags2_inited= 1;
flags2= uint4korr(pos);
DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
@@ -1474,6 +1584,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
#ifndef DBUG_OFF
char buff[22];
#endif
+ CHECK_SPACE(pos, end, 8);
sql_mode_inited= 1;
sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is ulonglong
DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
@@ -1482,15 +1593,24 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
break;
}
case Q_CATALOG_NZ_CODE:
- get_str_len_and_pointer(&pos, &catalog, &catalog_len);
+ DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
+ pos, end));
+ if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
+ {
+ DBUG_PRINT("info", ("query= 0"));
+ query= 0;
+ DBUG_VOID_RETURN;
+ }
break;
case Q_AUTO_INCREMENT:
+ CHECK_SPACE(pos, end, 4);
auto_increment_increment= uint2korr(pos);
auto_increment_offset= uint2korr(pos+2);
pos+= 4;
break;
case Q_CHARSET_CODE:
{
+ CHECK_SPACE(pos, end, 6);
charset_inited= 1;
memcpy(charset, pos, 6);
pos+= 6;
@@ -1498,20 +1618,29 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
}
case Q_TIME_ZONE_CODE:
{
- get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len);
+ if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
+ {
+ DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
+ query= 0;
+ DBUG_VOID_RETURN;
+ }
break;
}
case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
+ CHECK_SPACE(pos, end, 1);
if ((catalog_len= *pos))
catalog= (char*) pos+1; // Will be copied later
+ CHECK_SPACE(pos, end, catalog_len + 2);
pos+= catalog_len+2; // leap over end 0
catalog_nz= 0; // catalog has end 0 in event
break;
case Q_LC_TIME_NAMES_CODE:
+ CHECK_SPACE(pos, end, 2);
lc_time_names_number= uint2korr(pos);
pos+= 2;
break;
case Q_CHARSET_DATABASE_CODE:
+ CHECK_SPACE(pos, end, 2);
charset_database_number= uint2korr(pos);
pos+= 2;
break;
@@ -2021,6 +2150,7 @@ end:
*/
thd->catalog= 0;
thd->set_db(NULL, 0); /* will free the current database */
+ DBUG_PRINT("info", ("end: query= 0"));
thd->query= 0; // just to be sure
thd->query_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@@ -4964,12 +5094,13 @@ int Begin_load_query_log_event::get_create_or_append() const
#ifndef MYSQL_CLIENT
Execute_load_query_log_event::
Execute_load_query_log_event(THD* thd_arg, const char* query_arg,
- ulong query_length_arg, uint fn_pos_start_arg,
- uint fn_pos_end_arg,
- enum_load_dup_handling dup_handling_arg,
- bool using_trans, bool suppress_use):
+ ulong query_length_arg, uint fn_pos_start_arg,
+ uint fn_pos_end_arg,
+ enum_load_dup_handling dup_handling_arg,
+ bool using_trans, bool suppress_use,
+ THD::killed_state killed_err_arg):
Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
- suppress_use),
+ suppress_use, killed_err_arg),
file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
{
diff --git a/sql/log_event.h b/sql/log_event.h
index 04aac5d08fc..5b065a33dd1 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1619,10 +1619,12 @@ public:
#ifndef MYSQL_CLIENT
Execute_load_query_log_event(THD* thd, const char* query_arg,
- ulong query_length, uint fn_pos_start_arg,
- uint fn_pos_end_arg,
- enum_load_dup_handling dup_handling_arg,
- bool using_trans, bool suppress_use);
+ ulong query_length, uint fn_pos_start_arg,
+ uint fn_pos_end_arg,
+ enum_load_dup_handling dup_handling_arg,
+ bool using_trans, bool suppress_use,
+ THD::killed_state
+ killed_err_arg= THD::KILLED_NO_VALUE);
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index c128aeaa47d..f336e769c7d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2862,7 +2862,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
global_system_variables.collation_connection= default_charset_info;
global_system_variables.character_set_results= default_charset_info;
global_system_variables.character_set_client= default_charset_info;
- global_system_variables.collation_connection= default_charset_info;
if (!(character_set_filesystem=
get_charset_by_csname(character_set_filesystem_name,
diff --git a/sql/slave.cc b/sql/slave.cc
index c1b0d655bea..1509916fe91 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3279,7 +3279,43 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
now the relay log starts with its Format_desc, has a Rotate etc).
*/
- DBUG_PRINT("info",("type_code=%d, server_id=%d",type_code,ev->server_id));
+ DBUG_PRINT("info",("type_code: %d; server_id: %d; slave_skip_counter: %d",
+ type_code, ev->server_id, rli->slave_skip_counter));
+
+ /*
+ If the slave skip counter is positive, we still need to set the
+ OPTION_BEGIN flag correctly and not skip the log events that
+ start or end a transaction. If we do this, the slave will not
+ notice that it is inside a transaction, and happily start
+ executing from inside the transaction.
+
+ Note that the code block below is strictly 5.0.
+ */
+#if MYSQL_VERSION_ID < 50100
+ if (unlikely(rli->slave_skip_counter > 0))
+ {
+ switch (type_code)
+ {
+ case QUERY_EVENT:
+ {
+ Query_log_event* const qev= (Query_log_event*) ev;
+ DBUG_PRINT("info", ("QUERY_EVENT { query: '%s', q_len: %u }",
+ qev->query, qev->q_len));
+ if (memcmp("BEGIN", qev->query, qev->q_len+1) == 0)
+ thd->options|= OPTION_BEGIN;
+ else if (memcmp("COMMIT", qev->query, qev->q_len+1) == 0 ||
+ memcmp("ROLLBACK", qev->query, qev->q_len+1) == 0)
+ thd->options&= ~OPTION_BEGIN;
+ }
+ break;
+
+ case XID_EVENT:
+ DBUG_PRINT("info", ("XID_EVENT"));
+ thd->options&= ~OPTION_BEGIN;
+ break;
+ }
+ }
+#endif
if ((ev->server_id == (uint32) ::server_id &&
!replicate_same_server_id &&
@@ -3301,6 +3337,9 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
flush_relay_log_info(rli);
}
+ DBUG_PRINT("info", ("thd->options: %s",
+ (thd->options & OPTION_BEGIN) ? "OPTION_BEGIN" : ""))
+
/*
Protect against common user error of setting the counter to 1
instead of 2 while recovering from an insert which used auto_increment,
@@ -3311,6 +3350,15 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
type_code == RAND_EVENT ||
type_code == USER_VAR_EVENT) &&
rli->slave_skip_counter == 1) &&
+#if MYSQL_VERSION_ID < 50100
+ /*
+ Decrease the slave skip counter only if we are not inside
+ a transaction or the slave skip counter is more than
+ 1. The slave skip counter will be decreased from 1 to 0
+ when reaching the final ROLLBACK, COMMIT, or XID_EVENT.
+ */
+ (!(thd->options & OPTION_BEGIN) || rli->slave_skip_counter > 1) &&
+#endif
/*
The events from ourselves which have something to do with the relay
log itself must be skipped, true, but they mustn't decrement
@@ -3321,8 +3369,10 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
would not be skipped.
*/
!(ev->server_id == (uint32) ::server_id &&
- (type_code == ROTATE_EVENT || type_code == STOP_EVENT ||
- type_code == START_EVENT_V3 || type_code == FORMAT_DESCRIPTION_EVENT)))
+ (type_code == ROTATE_EVENT ||
+ type_code == STOP_EVENT ||
+ type_code == START_EVENT_V3 ||
+ type_code == FORMAT_DESCRIPTION_EVENT)))
--rli->slave_skip_counter;
pthread_mutex_unlock(&rli->data_lock);
delete ev;
@@ -3530,7 +3580,7 @@ connected:
on with life.
*/
thd->proc_info = "Registering slave on master";
- if (register_slave_on_master(mysql) || update_slave_list(mysql, mi))
+ if (register_slave_on_master(mysql))
goto err;
}
@@ -4931,7 +4981,16 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
a new event and is queuing it; the false "0" will exist until SQL
finishes executing the new event; it will be look abnormal only if
the events have old timestamps (then you get "many", 0, "many").
- Transient phases like this can't really be fixed.
+
+ Transient phases like this can be fixed with implemeting
+ Heartbeat event which provides the slave the status of the
+ master at time the master does not have any new update to send.
+ Seconds_Behind_Master would be zero only when master has no
+ more updates in binlog for slave. The heartbeat can be sent
+ in a (small) fraction of slave_net_timeout. Until it's done
+ rli->last_master_timestamp is temporarely (for time of
+ waiting for the following event) reset whenever EOF is
+ reached.
*/
time_t save_timestamp= rli->last_master_timestamp;
rli->last_master_timestamp= 0;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 69dda9ec1e8..5759d619e7e 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -100,8 +100,9 @@ sp_get_item_value(THD *thd, Item *item, String *str)
case REAL_RESULT:
case INT_RESULT:
case DECIMAL_RESULT:
- return item->val_str(str);
-
+ if (item->field_type() != MYSQL_TYPE_BIT)
+ return item->val_str(str);
+ else {/* Bit type is handled as binary string */}
case STRING_RESULT:
{
String *result= item->val_str(str);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index e6d65f3133a..1f71a582a25 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -159,7 +159,13 @@ typedef struct st_log_info
my_off_t pos;
bool fatal; // if the purge happens to give us a negative offset
pthread_mutex_t lock;
- st_log_info():fatal(0) { pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);}
+ st_log_info()
+ : index_file_offset(0), index_file_start_offset(0),
+ pos(0), fatal(0)
+ {
+ log_file_name[0] = '\0';
+ pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);
+ }
~st_log_info() { pthread_mutex_destroy(&lock);}
} LOG_INFO;
@@ -2350,6 +2356,11 @@ class multi_delete :public select_result_interceptor
/* True if at least one table we delete from is not transactional */
bool normal_tables;
bool delete_while_scanning;
+ /*
+ error handling (rollback and binlogging) can happen in send_eof()
+ so that afterward send_error() needs to find out that.
+ */
+ bool error_handled;
public:
multi_delete(TABLE_LIST *dt, uint num_of_tables);
@@ -2385,6 +2396,11 @@ class multi_update :public select_result_interceptor
/* True if the update operation has made a change in a transactional table */
bool transactional_tables;
bool ignore;
+ /*
+ error handling (rollback and binlogging) can happen in send_eof()
+ so that afterward send_error() needs to find out that.
+ */
+ bool error_handled;
public:
multi_update(TABLE_LIST *ut, TABLE_LIST *leaves_list,
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 56edfa6c5b2..a28a39a769d 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -38,6 +38,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
ha_rows deleted;
uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex;
+ THD::killed_state killed_status= THD::NOT_KILLED;
DBUG_ENTER("mysql_delete");
if (open_and_lock_tables(thd, table_list))
@@ -280,8 +281,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
else
table->file->unlock_row(); // Row failed selection, release lock on it
}
- if (thd->killed && !error)
- error= 1; // Aborted
+ killed_status= thd->killed;
+ error= (killed_status == THD::NOT_KILLED)? error : 1;
thd->proc_info="end";
end_read_record(&info);
free_io_cache(table); // Will not do any harm
@@ -319,14 +320,14 @@ cleanup:
thd->transaction.stmt.modified_non_trans_table= TRUE;
/* See similar binlogging code in sql_update.cc, for comments */
- if ((error < 0) || (deleted && !transactional_table))
+ if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
{
if (mysql_bin_log.is_open())
{
if (error < 0)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
+ transactional_table, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1;
}
@@ -504,7 +505,7 @@ bool mysql_multi_delete_prepare(THD *thd)
multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg)
: delete_tables(dt), deleted(0), found(0),
num_of_tables(num_of_tables_arg), error(0),
- do_delete(0), transactional_tables(0), normal_tables(0)
+ do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0)
{
tempfiles= (Unique **) sql_calloc(sizeof(Unique *) * num_of_tables);
}
@@ -685,12 +686,14 @@ void multi_delete::send_error(uint errcode,const char *err)
/* First send error what ever it is ... */
my_message(errcode, err, MYF(0));
- /* If nothing deleted return */
- if (!deleted)
+ /* the error was handled or nothing deleted and no side effects return */
+ if (error_handled ||
+ !thd->transaction.stmt.modified_non_trans_table && !deleted)
DBUG_VOID_RETURN;
/* Something already deleted so we have to invalidate cache */
- query_cache_invalidate3(thd, delete_tables, 1);
+ if (deleted)
+ query_cache_invalidate3(thd, delete_tables, 1);
/*
If rows from the first table only has been deleted and it is
@@ -710,12 +713,30 @@ void multi_delete::send_error(uint errcode,const char *err)
*/
error= 1;
send_eof();
+ DBUG_ASSERT(error_handled);
+ DBUG_VOID_RETURN;
}
- DBUG_ASSERT(!normal_tables || !deleted || thd->transaction.stmt.modified_non_trans_table);
+
+ if (thd->transaction.stmt.modified_non_trans_table)
+ {
+ /*
+ there is only side effects; to binlog with the error
+ */
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ transactional_tables, FALSE);
+ mysql_bin_log.write(&qinfo);
+ }
+ thd->transaction.all.modified_non_trans_table= true;
+ }
+ DBUG_ASSERT(!normal_tables || !deleted ||
+ thd->transaction.stmt.modified_non_trans_table);
DBUG_VOID_RETURN;
}
+
/*
Do delete from other tables.
Returns values:
@@ -798,6 +819,7 @@ int multi_delete::do_deletes()
bool multi_delete::send_eof()
{
+ THD::killed_state killed_status= THD::NOT_KILLED;
thd->proc_info="deleting from reference tables";
/* Does deletes for the last n - 1 tables, returns 0 if ok */
@@ -805,7 +827,7 @@ bool multi_delete::send_eof()
/* compute a total error to know if something failed */
local_error= local_error || error;
-
+ killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
/* reset used flags */
thd->proc_info="end";
@@ -817,21 +839,24 @@ bool multi_delete::send_eof()
{
query_cache_invalidate3(thd, delete_tables, 1);
}
- if ((local_error == 0) || (deleted && normal_tables))
+ DBUG_ASSERT(!normal_tables || !deleted ||
+ thd->transaction.stmt.modified_non_trans_table);
+ if ((local_error == 0) || thd->transaction.stmt.modified_non_trans_table)
{
if (mysql_bin_log.is_open())
{
if (local_error == 0)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_tables, FALSE);
+ transactional_tables, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && !normal_tables)
local_error=1; // Log write failed: roll back the SQL statement
}
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
}
- DBUG_ASSERT(!normal_tables || !deleted || thd->transaction.stmt.modified_non_trans_table);
+ if (local_error != 0)
+ error_handled= TRUE; // to force early leave from ::send_error()
/* Commit or rollback the current SQL statement */
if (transactional_tables)
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 770bbd1349d..65d8bb23706 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -864,8 +864,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
transactional_table= table->file->has_transactions();
- if ((changed= (info.copied || info.deleted || info.updated)) ||
- was_insert_delayed)
+ if ((changed= (info.copied || info.deleted || info.updated)))
{
/*
Invalidate the table in the query cache if something changed.
@@ -874,46 +873,47 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
*/
if (changed)
query_cache_invalidate3(thd, table_list, 1);
- if (error <= 0 || !transactional_table)
+ }
+ if (changed && error <= 0 || thd->transaction.stmt.modified_non_trans_table
+ || was_insert_delayed)
+ {
+ if (mysql_bin_log.is_open())
{
- if (mysql_bin_log.is_open())
+ if (error <= 0)
{
- if (error <= 0)
- {
- /*
- [Guilhem wrote] Temporary errors may have filled
- thd->net.last_error/errno. For example if there has
- been a disk full error when writing the row, and it was
- MyISAM, then thd->net.last_error/errno will be set to
- "disk full"... and the my_pwrite() will wait until free
- space appears, and so when it finishes then the
- write_row() was entirely successful
- */
- /* todo: consider removing */
- thd->clear_error();
- }
- /* bug#22725:
-
- A query which per-row-loop can not be interrupted with
- KILLED, like INSERT, and that does not invoke stored
- routines can be binlogged with neglecting the KILLED error.
-
- If there was no error (error == zero) until after the end of
- inserting loop the KILLED flag that appeared later can be
- disregarded since previously possible invocation of stored
- routines did not result in any error due to the KILLED. In
- such case the flag is ignored for constructing binlog event.
+ /*
+ [Guilhem wrote] Temporary errors may have filled
+ thd->net.last_error/errno. For example if there has
+ been a disk full error when writing the row, and it was
+ MyISAM, then thd->net.last_error/errno will be set to
+ "disk full"... and the my_pwrite() will wait until free
+ space appears, and so when it finishes then the
+ write_row() was entirely successful
*/
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE,
- (error>0) ? thd->killed : THD::NOT_KILLED);
- DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
- if (mysql_bin_log.write(&qinfo) && transactional_table)
- error=1;
+ /* todo: consider removing */
+ thd->clear_error();
}
- if (thd->transaction.stmt.modified_non_trans_table)
- thd->transaction.all.modified_non_trans_table= TRUE;
+ /* bug#22725:
+
+ A query which per-row-loop can not be interrupted with
+ KILLED, like INSERT, and that does not invoke stored
+ routines can be binlogged with neglecting the KILLED error.
+
+ If there was no error (error == zero) until after the end of
+ inserting loop the KILLED flag that appeared later can be
+ disregarded since previously possible invocation of stored
+ routines did not result in any error due to the KILLED. In
+ such case the flag is ignored for constructing binlog event.
+ */
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ transactional_table, FALSE,
+ (error>0) ? thd->killed : THD::NOT_KILLED);
+ DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
+ if (mysql_bin_log.write(&qinfo) && transactional_table)
+ error=1;
}
+ if (thd->transaction.stmt.modified_non_trans_table)
+ thd->transaction.all.modified_non_trans_table= TRUE;
}
DBUG_ASSERT(transactional_table || !changed ||
thd->transaction.stmt.modified_non_trans_table);
@@ -2938,6 +2938,7 @@ bool select_insert::send_eof()
{
int error, error2;
bool changed, transactional_table= table->file->has_transactions();
+ THD::killed_state killed_status= thd->killed;
DBUG_ENTER("select_insert::send_eof");
error= (!thd->prelocked_mode) ? table->file->end_bulk_insert():0;
@@ -2967,7 +2968,7 @@ bool select_insert::send_eof()
if (!error)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
+ transactional_table, FALSE, killed_status);
mysql_bin_log.write(&qinfo);
}
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
@@ -3004,6 +3005,7 @@ void select_insert::abort()
*/
DBUG_VOID_RETURN;
}
+ changed= (info.copied || info.deleted || info.updated);
transactional_table= table->file->has_transactions();
if (!thd->prelocked_mode)
table->file->end_bulk_insert();
@@ -3013,8 +3015,7 @@ void select_insert::abort()
error while inserting into a MyISAM table) we must write to the binlog (and
the error code will make the slave stop).
*/
- if ((changed= info.copied || info.deleted || info.updated) &&
- !transactional_table)
+ if (thd->transaction.stmt.modified_non_trans_table)
{
if (last_insert_id)
thd->insert_id(last_insert_id); // For binary log
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 55cbbf1c540..d687ceff393 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -85,7 +85,8 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY
static bool write_execute_load_query_log_event(THD *thd,
bool duplicates, bool ignore,
- bool transactional_table);
+ bool transactional_table,
+ THD::killed_state killed_status);
#endif /* EMBEDDED_LIBRARY */
/*
@@ -135,6 +136,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
char *tdb= thd->db ? thd->db : db; // Result is never null
ulong skip_lines= ex->skip_lines;
bool transactional_table;
+ THD::killed_state killed_status= THD::NOT_KILLED;
DBUG_ENTER("mysql_load");
#ifdef EMBEDDED_LIBRARY
@@ -404,7 +406,16 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
free_blobs(table); /* if pack_blob was used */
table->copy_blobs=0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
-
+ /*
+ simulated killing in the middle of per-row loop
+ must be effective for binlogging
+ */
+ DBUG_EXECUTE_IF("simulate_kill_bug27571",
+ {
+ error=1;
+ thd->killed= THD::KILL_QUERY;
+ };);
+ killed_status= (error == 0)? THD::NOT_KILLED : thd->killed;
/*
We must invalidate the table in query cache before binlog writing and
ha_autocommit_...
@@ -444,9 +455,10 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* If the file was not empty, wrote_create_file is true */
if (lf_info.wrote_create_file)
{
- if ((info.copied || info.deleted) && !transactional_table)
+ if (thd->transaction.stmt.modified_non_trans_table)
write_execute_load_query_log_event(thd, handle_duplicates,
- ignore, transactional_table);
+ ignore, transactional_table,
+ killed_status);
else
{
Delete_file_log_event d(thd, db, transactional_table);
@@ -477,7 +489,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info.end_io_cache();
if (lf_info.wrote_create_file)
write_execute_load_query_log_event(thd, handle_duplicates,
- ignore, transactional_table);
+ ignore, transactional_table,
+ killed_status);
}
#endif /*!EMBEDDED_LIBRARY*/
if (transactional_table)
@@ -504,7 +517,8 @@ err:
/* Not a very useful function; just to avoid duplication of code */
static bool write_execute_load_query_log_event(THD *thd,
bool duplicates, bool ignore,
- bool transactional_table)
+ bool transactional_table,
+ THD::killed_state killed_err_arg)
{
Execute_load_query_log_event
e(thd, thd->query, thd->query_length,
@@ -512,7 +526,7 @@ static bool write_execute_load_query_log_event(THD *thd,
(char*)thd->lex->fname_end - (char*)thd->query,
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
- transactional_table, FALSE);
+ transactional_table, FALSE, killed_err_arg);
return mysql_bin_log.write(&e);
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 0a8b92d28c0..16a64c48cdd 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2853,7 +2853,16 @@ mysql_execute_command(THD *thd)
if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
goto error;
pthread_mutex_lock(&LOCK_active_mi);
- res = show_master_info(thd,active_mi);
+ if (active_mi != NULL)
+ {
+ res = show_master_info(thd, active_mi);
+ }
+ else
+ {
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
+ "the master info structure does not exist");
+ send_ok(thd);
+ }
pthread_mutex_unlock(&LOCK_active_mi);
break;
}
@@ -3701,6 +3710,13 @@ end_with_restore_list:
SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
OPTION_SETUP_TABLES_DONE,
del_result, unit, select_lex);
+ res|= thd->net.report_error;
+ if (unlikely(res))
+ {
+ /* If we had a another error reported earlier then this will be ignored */
+ del_result->send_error(ER_UNKNOWN_ERROR, "Execution of the query failed");
+ del_result->abort();
+ }
delete del_result;
}
else
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 9cc0ba7c29a..903d254db8f 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -364,7 +364,6 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
name=0; // Find first log
linfo.index_file_offset = 0;
- thd->current_linfo = &linfo;
if (mysql_bin_log.find_log_pos(&linfo, name, 1))
{
@@ -373,6 +372,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
goto err;
}
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->current_linfo = &linfo;
+ pthread_mutex_unlock(&LOCK_thread_count);
+
if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0)
{
my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
@@ -1338,7 +1341,6 @@ bool mysql_show_binlog_events(THD* thd)
name=0; // Find first log
linfo.index_file_offset = 0;
- thd->current_linfo = &linfo;
if (mysql_bin_log.find_log_pos(&linfo, name, 1))
{
@@ -1346,6 +1348,10 @@ bool mysql_show_binlog_events(THD* thd)
goto err;
}
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->current_linfo = &linfo;
+ pthread_mutex_unlock(&LOCK_thread_count);
+
if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
goto err;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 321d07dec76..84349a40977 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -134,6 +134,7 @@ int mysql_update(THD *thd,
SELECT_LEX *select_lex= &thd->lex->select_lex;
bool need_reopen;
List<Item> all_fields;
+ THD::killed_state killed_status= THD::NOT_KILLED;
DBUG_ENTER("mysql_update");
LINT_INIT(timestamp_query_id);
@@ -519,43 +520,26 @@ int mysql_update(THD *thd,
table->file->unlock_row();
thd->row_count++;
}
+ /*
+ Caching the killed status to pass as the arg to query event constuctor;
+ The cached value can not change whereas the killed status can
+ (externally) since this point and change of the latter won't affect
+ binlogging.
+ It's assumed that if an error was set in combination with an effective
+ killed status then the error is due to killing.
+ */
+ killed_status= thd->killed; // get the status of the volatile
+ // simulated killing after the loop must be ineffective for binlogging
+ DBUG_EXECUTE_IF("simulate_kill_bug27571",
+ {
+ thd->killed= THD::KILL_QUERY;
+ };);
+ error= (killed_status == THD::NOT_KILLED)? error : 1;
+
if (!transactional_table && updated > 0)
thd->transaction.stmt.modified_non_trans_table= TRUE;
-
- /*
- todo bug#27571: to avoid asynchronization of `error' and
- `error_code' of binlog event constructor
-
- The concept, which is a bit different for insert(!), is to
- replace `error' assignment with the following lines
-
- killed_status= thd->killed; // get the status of the volatile
-
- Notice: thd->killed is type of "state" whereas the lhs has
- "status" the suffix which translates according to WordNet: a state
- at a particular time - at the time of the end of per-row loop in
- our case. Binlogging ops are conducted with the status.
-
- error= (killed_status == THD::NOT_KILLED)? error : 1;
-
- which applies to most mysql_$query functions.
- Event's constructor will accept `killed_status' as an argument:
-
- Query_log_event qinfo(..., killed_status);
-
- thd->killed might be changed after killed_status had got cached and this
- won't affect binlogging event but other effects remain.
-
- Open issue: In a case the error happened not because of KILLED -
- and then KILLED was caught later still within the loop - we shall
- do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN
- error_code.
- */
-
- if (thd->killed && !error)
- error= 1; // Aborted
end_read_record(&info);
free_io_cache(table); // If ORDER BY
delete select;
@@ -580,14 +564,14 @@ int mysql_update(THD *thd,
Sometimes we want to binlog even if we updated no rows, in case user used
it to be sure master and slave are in same state.
*/
- if ((error < 0) || (updated && !transactional_table))
+ if ((error < 0) || thd->transaction.stmt.modified_non_trans_table)
{
if (mysql_bin_log.is_open())
{
if (error < 0)
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
+ transactional_table, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && transactional_table)
error=1; // Rollback update
}
@@ -994,8 +978,8 @@ multi_update::multi_update(TABLE_LIST *table_list,
:all_tables(table_list), leaves(leaves_list), update_tables(0),
tmp_tables(0), updated(0), found(0), fields(field_list),
values(value_list), table_count(0), copy_field(0),
- handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0),
- transactional_tables(1), ignore(ignore_arg)
+ handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1),
+ transactional_tables(1), ignore(ignore_arg), error_handled(0)
{}
@@ -1202,7 +1186,6 @@ multi_update::initialize_tables(JOIN *join)
if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join))
DBUG_RETURN(1);
main_table=join->join_tab->table;
- trans_safe= transactional_tables= main_table->file->has_transactions();
table_to_update= 0;
/* Any update has at least one pair (field, value) */
@@ -1484,12 +1467,14 @@ void multi_update::send_error(uint errcode,const char *err)
/* First send error what ever it is ... */
my_error(errcode, MYF(0), err);
- /* If nothing updated return */
- if (updated == 0) /* the counter might be reset in send_eof */
- return; /* and then the query has been binlogged */
+ /* the error was handled or nothing deleted and no side effects return */
+ if (error_handled ||
+ !thd->transaction.stmt.modified_non_trans_table && !updated)
+ return;
/* Something already updated so we have to invalidate cache */
- query_cache_invalidate3(thd, update_tables, 1);
+ if (updated)
+ query_cache_invalidate3(thd, update_tables, 1);
/*
If all tables that has been updated are trans safe then just do rollback.
If not attempt to do remaining updates.
@@ -1521,12 +1506,16 @@ void multi_update::send_error(uint errcode,const char *err)
*/
if (mysql_bin_log.is_open())
{
+ /*
+ THD::killed status might not have been set ON at time of an error
+ got caught and if happens later the killed error is written
+ into repl event.
+ */
Query_log_event qinfo(thd, thd->query, thd->query_length,
transactional_tables, FALSE);
mysql_bin_log.write(&qinfo);
}
- if (!trans_safe)
- thd->transaction.all.modified_non_trans_table= TRUE;
+ thd->transaction.all.modified_non_trans_table= TRUE;
}
DBUG_ASSERT(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table);
@@ -1709,10 +1698,19 @@ err2:
bool multi_update::send_eof()
{
char buff[STRING_BUFFER_USUAL_SIZE];
+ THD::killed_state killed_status= THD::NOT_KILLED;
thd->proc_info="updating reference tables";
- /* Does updates for the last n - 1 tables, returns 0 if ok */
+ /*
+ Does updates for the last n - 1 tables, returns 0 if ok;
+ error takes into account killed status gained in do_updates()
+ */
int local_error = (table_count) ? do_updates(0) : 0;
+ /*
+ if local_error is not set ON until after do_updates() then
+ later carried out killing should not affect binlogging.
+ */
+ killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
thd->proc_info= "end";
/* We must invalidate the query cache before binlog writing and
@@ -1739,16 +1737,16 @@ bool multi_update::send_eof()
{
if (local_error == 0)
thd->clear_error();
- else
- updated= 0; /* if there's an error binlog it here not in ::send_error */
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_tables, FALSE);
+ transactional_tables, FALSE, killed_status);
if (mysql_bin_log.write(&qinfo) && trans_safe)
local_error= 1; // Rollback update
}
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
}
+ if (local_error != 0)
+ error_handled= TRUE; // to force early leave from ::send_error()
if (transactional_tables)
{
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index 0a67d4c0a54..511a81f0cd4 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -179,20 +179,39 @@ static uchar NEAR sort_order_euc_kr[]=
/* Support for Korean(EUC_KR) characters, by powerm90@tinc.co.kr and mrpark@tinc.co.kr */
-#define iseuc_kr(c) ((0xa1<=(uchar)(c) && (uchar)(c)<=0xfe))
+/*
+ Unicode mapping is done according to:
+ ftp://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/KSC/KSC5601.TXT
+
+ Valid multi-byte characters:
+
+ [A1..FE][41..5A,61..7A,81..FE]
+
+ Note, 0x5C is not a valid MB tail,
+ so escape_with_backslash_is_dangerous is not set.
+*/
+
+#define iseuc_kr_head(c) ((0xa1<=(uchar)(c) && (uchar)(c)<=0xfe))
+
+#define iseuc_kr_tail1(c) ((uchar) (c) >= 0x41 && (uchar) (c) <= 0x5A)
+#define iseuc_kr_tail2(c) ((uchar) (c) >= 0x61 && (uchar) (c) <= 0x7A)
+#define iseuc_kr_tail3(c) ((uchar) (c) >= 0x81 && (uchar) (c) <= 0xFE)
+#define iseuc_kr_tail(c) (iseuc_kr_tail1(c) || \
+ iseuc_kr_tail2(c) || \
+ iseuc_kr_tail3(c))
static int ismbchar_euc_kr(CHARSET_INFO *cs __attribute__((unused)),
const char* p, const char *e)
{
return ((*(uchar*)(p)<0x80)? 0:\
- iseuc_kr(*(p)) && (e)-(p)>1 && iseuc_kr(*((p)+1))? 2:\
+ iseuc_kr_head(*(p)) && (e)-(p)>1 && iseuc_kr_tail(*((p)+1))? 2:\
0);
}
static int mbcharlen_euc_kr(CHARSET_INFO *cs __attribute__((unused)),uint c)
{
- return (iseuc_kr(c) ? 2 : 1);
+ return (iseuc_kr_head(c) ? 2 : 1);
}
@@ -8653,7 +8672,7 @@ my_well_formed_len_euckr(CHARSET_INFO *cs __attribute__((unused)),
/* Single byte ascii character */
b++;
}
- else if (b < emb && iseuc_kr(*b) && iseuc_kr(b[1]))
+ else if (b < emb && iseuc_kr_head(*b) && iseuc_kr_tail(b[1]))
{
/* Double byte character */
b+= 2;