Merge abarkov@bk-internal.mysql.com:/home/bk/mysql-5.1

into  mysql.com:/home/bar/mysql-work/mysql-5.1-new-rpl-merge


client/mysql.cc:
  Auto merged
mysql-test/r/ctype_euckr.result:
  Auto merged
mysql-test/r/ctype_uca.result:
  Auto merged
mysql-test/r/ctype_utf8.result:
  Auto merged
mysql-test/r/func_regexp.result:
  Auto merged
mysql-test/suite/rpl/r/rpl_bug31076.result:
  Auto merged
mysql-test/t/ctype_utf8.test:
  Auto merged
mysql-test/t/func_regexp.test:
  Auto merged
mysql-test/t/partition.test:
  Auto merged
sql/field.cc:
  Auto merged
sql/field.h:
  Auto merged
sql/handler.cc:
  Auto merged
sql/item_cmpfunc.cc:
  Auto merged
sql/item_cmpfunc.h:
  Auto merged
sql/item_xmlfunc.cc:
  Auto merged
sql/log.cc:
  Auto merged
sql/log.h:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_repl.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_update.cc:
  Auto merged
strings/ctype-euc_kr.c:
  Auto merged
sql/sql_yacc.yy:
  Reverting Rafal's changes: TRANSACTIONAL_SYM was removed in a mistake.
mysql-test/r/ctype_ucs.result:
  After merge fix
mysql-test/suite/rpl/t/rpl_bug31076.test:
  After merge fix.
mysql-test/t/ctype_ucs.test:
  After megre fix
This commit is contained in:
unknown 2007-10-30 12:03:34 +04:00
commit a3b60d2d51
89 changed files with 4180 additions and 954 deletions

View File

@ -1087,6 +1087,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;

View File

@ -407,9 +407,11 @@ enum ha_base_keytype {
#define HA_ERR_RECORD_IS_THE_SAME 169 /* row not actually updated :
new values same as the old values */
#define HA_ERR_LOGGING_IMPOSSIBLE 170 /* It is not possible to log this
statement */
#define HA_ERR_LAST 170 /*Copy last error nr.*/
#define HA_ERR_LOGGING_IMPOSSIBLE 170 /* It is not possible to log this
statement */
#define HA_ERR_CORRUPT_EVENT 171 /* The event was corrupt, leading to
illegal data being read */
#define HA_ERR_LAST 171 /*Copy last error nr.*/
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)

View File

@ -0,0 +1,298 @@
# the file to be sourced from binlog.binlog_mix_innodb_myisam
#
# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack
# bug #28960 non-trans temp table changes with insert .. select
# not binlogged after rollback
#
# testing appearence of insert into temp_table in binlog.
# There are two branches of execution that require different setup.
# checking binlog content filled with row-based events due to
# a used stored function modifies non-transactional table
## send_eof() branch
# prepare
create temporary table tt (a int unique);
create table ti (a int) engine=innodb;
reset master;
show master status;
# action
begin;
insert into ti values (1);
insert into ti values (2) ;
insert into tt select * from ti;
rollback;
# check
select count(*) from tt /* 2 */;
show master status;
source include/show_binlog_events.inc;
select count(*) from ti /* zero */;
insert into ti select * from tt;
select * from ti /* that is what slave would miss - bug#28960 */;
## send_error() branch
delete from ti;
delete from tt where a=1;
reset master;
show master status;
# action
begin;
insert into ti values (1);
insert into ti values (2) /* to make the dup error in the following */;
--error ER_DUP_ENTRY
insert into tt select * from ti /* one affected and error */;
rollback;
# check
show master status;
source include/show_binlog_events.inc; # nothing in binlog with row bilog format
select count(*) from ti /* zero */;
insert into ti select * from tt;
select * from tt /* that is what otherwise slave missed - the bug */;
drop table ti;
#
# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack
#
# Testing asserts: if there is a side effect of modifying non-transactional
# table thd->no_trans_update.stmt must be TRUE;
# the assert is active with debug build
#
--disable_warnings
drop function if exists bug27417;
drop table if exists t1,t2;
--enable_warnings
# side effect table
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
# target tables
CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a));
delimiter |;
create function bug27417(n int)
RETURNS int(11)
begin
insert into t1 values (null);
return n;
end|
delimiter ;|
reset master;
# execute
insert into t2 values (bug27417(1));
insert into t2 select bug27417(2);
reset master;
--error ER_DUP_ENTRY
insert into t2 values (bug27417(2));
source include/show_binlog_events.inc; #only (!) with fixes for #23333 will show there is the query
select count(*) from t1 /* must be 3 */;
reset master;
select count(*) from t2;
delete from t2 where a=bug27417(3);
select count(*) from t2 /* nothing got deleted */;
source include/show_binlog_events.inc; # the query must be in regardless of #23333
select count(*) from t1 /* must be 5 */;
--enable_info
delete t2 from t2 where t2.a=bug27417(100) /* must not affect t2 */;
--disable_info
select count(*) from t1 /* must be 7 */;
# 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
source include/show_binlog_events.inc; # must be event of 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
source include/show_binlog_events.inc; # must be events of 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
source include/show_binlog_events.inc; # must be events of 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
source include/show_binlog_events.inc; # 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
source include/show_binlog_events.inc; # 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
source include/show_binlog_events.inc; # must be events of 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 */;
source include/show_binlog_events.inc; # must be events of the query
#
# bug#23333 cleanup
#
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;

View File

@ -466,7 +466,7 @@ binary data';
select * from t2 order by f1;
select * from t3 order by f1;
select * from t4 order by f1;
select * from t31 order by f1;
select * from t31 order by f3;
connection master;

View File

@ -736,7 +736,7 @@ connection slave;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
--echo *** Try to insert in master ****
@ -744,6 +744,8 @@ connection master;
INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);
SELECT * FROM t15 ORDER BY c1;
#SHOW BINLOG EVENTS;
--echo *** Try to select from slave ****
sync_slave_with_master;
--replace_column 7 CURRENT_TIMESTAMP

View File

@ -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;

View File

@ -0,0 +1,33 @@
###################################################
#Author: Sven
#Date: 2007-10-09
#Purpose: Wait until the slave has an error in the
# sql thread, as indicated by
# "SHOW SLAVE STATUS", or at most 30
# seconds.
#Details:
# 1) Fill in and setup variables
# 2) loop, looking for sql error on slave
# 3) If it loops too long, die.
####################################################
connection slave;
let $row_number= 1;
let $run= 1;
let $counter= 300;
while ($run)
{
let $sql_result= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, $row_number);
let $run= `SELECT '$sql_result' = '0'`;
if ($run) {
real_sleep 0.1;
if (!$counter){
--echo "Failed while waiting for slave to produce an error in its sql thread"
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 #
query_vertical SHOW SLAVE STATUS;
exit;
}
dec $counter;
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 '[[:<:]]вася[[:>:]]'

View File

@ -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]+$');

View File

@ -1086,6 +1086,19 @@ n d
1 30
2 20
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 'PRIMARY'
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
@ -1751,10 +1764,10 @@ Variable_name Value
Innodb_page_size 16384
show status like "Innodb_rows_deleted";
Variable_name Value
Innodb_rows_deleted 70
Innodb_rows_deleted 71
show status like "Innodb_rows_inserted";
Variable_name Value
Innodb_rows_inserted 1083
Innodb_rows_inserted 1085
show status like "Innodb_rows_updated";
Variable_name Value
Innodb_rows_updated 886

View File

@ -614,6 +614,7 @@ CREATE TABLE `t2` (
`b` int(11) default NULL,
PRIMARY KEY (`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
set @sav_binlog_format= @@session.binlog_format;
set @@session.binlog_format= mixed;
insert into t1 values (1,1),(2,2);
insert into t2 values (1,1),(4,4);
@ -626,7 +627,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 197
master-bin.000001 268
delete from t1;
delete from t2;
insert into t1 values (1,2),(3,4),(4,4);
@ -636,6 +637,24 @@ UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
show master status /* there must be the UPDATE query event */;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 212
master-bin.000001 283
drop table t1, t2;
set @@session.binlog_format= @sav_binlog_format;
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 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
1
select count(*) from t3 /* must be 1 */;
count(*)
1
drop table t1, t2, t3;
end of tests

View File

@ -178,5 +178,7 @@ 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
WARNING: --server-arg option not supported in this configuration.

View File

@ -413,3 +413,236 @@ select
@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%"
1 1
drop table t1, t2;
create temporary table tt (a int unique);
create table ti (a int) engine=innodb;
reset master;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 106
begin;
insert into ti values (1);
insert into ti values (2) ;
insert into tt select * from ti;
rollback;
Warnings:
Warning 1196 Some non-transactional changed tables couldn't be rolled back
select count(*) from tt /* 2 */;
count(*)
2
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 395
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.ti)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Table_map # # table_id: # (test.ti)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from ti /* zero */;
count(*)
0
insert into ti select * from tt;
select * from ti /* that is what slave would miss - bug#28960 */;
a
1
2
delete from ti;
delete from tt where a=1;
reset master;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 106
begin;
insert into ti values (1);
insert into ti values (2) /* to make the dup error in the following */;
insert into tt select * from ti /* one affected and error */;
ERROR 23000: Duplicate entry '2' for key 'a'
rollback;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 106
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
select count(*) from ti /* zero */;
count(*)
0
insert into ti select * from tt;
select * from tt /* that is what otherwise slave missed - the bug */;
a
1
2
drop table ti;
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)
RETURNS int(11)
begin
insert into t1 values (null);
return n;
end|
reset master;
insert into t2 values (bug27417(1));
insert into t2 select bug27417(2);
reset master;
insert into t2 values (bug27417(2));
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=3
master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(2))
select count(*) from t1 /* must be 3 */;
count(*)
3
reset master;
select count(*) from t2;
count(*)
2
delete from t2 where a=bug27417(3);
select count(*) from t2 /* nothing got deleted */;
count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=4
master-bin.000001 # Query # # use `test`; delete from t2 where a=bug27417(3)
select count(*) from t1 /* must be 5 */;
count(*)
5
delete t2 from t2 where t2.a=bug27417(100) /* must not affect t2 */;
affected rows: 0
select count(*) from t1 /* must be 7 */;
count(*)
7
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=1
master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1))
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=2
master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2)
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'b'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=4
master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1)
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=6
master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=9
master-bin.000001 # Query # # use `test`; delete from t2
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
select * from t4;
a b
0 17
select count(*) from t1 /* must be 2 */;
count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=12
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=1
master-bin.000001 # Query # # use `test`; ROLLBACK
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;

View File

@ -380,7 +380,8 @@ select
@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" @a not like "%#%error_code=%error_code=%"
1 1
drop table t1, t2;
create table tt (a int unique);
set @@session.binlog_format=statement;
create temporary table tt (a int unique);
create table ti (a int) engine=innodb;
reset master;
show master status;
@ -399,18 +400,18 @@ count(*)
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 515
show binlog events from 106;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; BEGIN
master-bin.000001 # Query 1 # use `test`; insert into ti values (1)
master-bin.000001 # Query 1 # use `test`; insert into ti values (2)
master-bin.000001 # Query 1 # use `test`; insert into tt select * from ti
master-bin.000001 # Query 1 # use `test`; ROLLBACK
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; insert into ti values (1)
master-bin.000001 # Query # # use `test`; insert into ti values (2)
master-bin.000001 # Query # # use `test`; insert into tt select * from ti
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from ti /* zero */;
count(*)
0
insert into ti select * from tt;
select * from ti /* that is what slave would miss - a bug */;
select * from ti /* that is what slave would miss - bug#28960 */;
a
1
2
@ -431,13 +432,13 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
master-bin.000001 589
show binlog events from 106;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; BEGIN
master-bin.000001 # Query 1 # use `test`; insert into ti values (1)
master-bin.000001 # Query 1 # use `test`; insert into ti values (2) /* to make the dup error in the following */
master-bin.000001 # Query 1 # use `test`; insert into tt select * from ti /* one affected and error */
master-bin.000001 # Query 1 # use `test`; ROLLBACK
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; insert into ti values (1)
master-bin.000001 # Query # # use `test`; insert into ti values (2) /* to make the dup error in the following */
master-bin.000001 # Query # # use `test`; insert into tt select * from ti /* one affected and error */
master-bin.000001 # Query # # use `test`; ROLLBACK
select count(*) from ti /* zero */;
count(*)
0
@ -446,7 +447,7 @@ select * from tt /* that is what otherwise slave missed - the bug */;
a
1
2
drop table ti,tt;
drop table ti;
drop function if exists bug27417;
drop table if exists t1,t2;
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
@ -463,6 +464,10 @@ insert into t2 select bug27417(2);
reset master;
insert into t2 values (bug27417(2));
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=3
master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(2))
select count(*) from t1 /* must be 3 */;
count(*)
3
@ -474,6 +479,10 @@ delete from t2 where a=bug27417(3);
select count(*) from t2 /* nothing got deleted */;
count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=4
master-bin.000001 # Query # # use `test`; delete from t2 where a=bug27417(3)
select count(*) from t1 /* must be 5 */;
count(*)
5
@ -482,6 +491,134 @@ 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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=1
master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1))
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=2
master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2)
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'b'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=4
master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1)
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=6
master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=9
master-bin.000001 # Query # # use `test`; delete from t2
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1
master-bin.000001 # Query # # use `test`; ROLLBACK
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 'PRIMARY'
select * from t4;
a b
0 17
select count(*) from t1 /* must be 2 */;
count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Begin_load_query # # ;file_id=1;block_len=12
master-bin.000001 # Intvar # # INSERT_ID=10
master-bin.000001 # Execute_load_query # # use `test`; load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2) ;file_id=1
master-bin.000001 # Query # # use `test`; ROLLBACK
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;
set @@session.binlog_format=@@global.binlog_format;
end of tests

View File

@ -31,3 +31,5 @@ eval select
@a like "%#%error_code=0%ROLLBACK/*!*/;%ROLLBACK /* added by mysqlbinlog */;%",
@a not like "%#%error_code=%error_code=%";
drop table t1, t2;
-- source extra/binlog_tests/mix_innodb_myisam_side_effects.test

View File

@ -24,123 +24,9 @@ eval select
drop table t1, t2;
#
# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack
# bug #28960 non-trans temp table changes with insert .. select
# not binlogged after rollback
#
# testing appearence of insert into temp_table in binlog.
# There are two branches of execution that require different setup.
set @@session.binlog_format=statement;
-- source extra/binlog_tests/mix_innodb_myisam_side_effects.test
set @@session.binlog_format=@@global.binlog_format;
## send_eof() branch
# prepare
create table tt (a int unique);
create table ti (a int) engine=innodb;
reset master;
show master status;
# action
begin;
insert into ti values (1);
insert into ti values (2) ;
insert into tt select * from ti;
rollback;
# check
select count(*) from tt /* 2 */;
show master status;
--replace_column 2 # 5 #
show binlog events from 106;
select count(*) from ti /* zero */;
insert into ti select * from tt;
select * from ti /* that is what slave would miss - a bug */;
## send_error() branch
delete from ti;
delete from tt where a=1;
reset master;
show master status;
# action
begin;
insert into ti values (1);
insert into ti values (2) /* to make the dup error in the following */;
--error ER_DUP_ENTRY
insert into tt select * from ti /* one affected and error */;
rollback;
# check
show master status;
--replace_column 2 # 5 #
show binlog events from 106;
select count(*) from ti /* zero */;
insert into ti select * from tt;
select * from tt /* that is what otherwise slave missed - the bug */;
drop table ti,tt;
#
# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack
#
# Testing asserts: if there is a side effect of modifying non-transactional
# table thd->no_trans_update.stmt must be TRUE;
# the assert is active with debug build
#
--disable_warnings
drop function if exists bug27417;
drop table if exists t1,t2;
--enable_warnings
# side effect table
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM;
# target tables
CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a));
delimiter |;
create function bug27417(n int)
RETURNS int(11)
begin
insert into t1 values (null);
return n;
end|
delimiter ;|
reset master;
# execute
insert into t2 values (bug27417(1));
insert into t2 select bug27417(2);
reset master;
--error ER_DUP_ENTRY
insert into t2 values (bug27417(2));
#TODO: Andrei: enable this test after 23333 is pushed
#show master status; /* only (!) with fixes for #23333 will show there is the query */;
select count(*) from t1 /* must be 3 */;
reset master;
select count(*) from t2;
delete from t2 where a=bug27417(3);
select count(*) from t2 /* nothing got deleted */;
#TODO: Andrei: enable this test after 23333 is pushed
#show master status; /* the query must be in regardless of #23333 */;
select count(*) from t1 /* must be 5 */;
--enable_info
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;
drop table t1,t2;
--echo end of tests

View File

@ -0,0 +1,136 @@
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 106
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 106
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
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 0
Last_SQL_Error
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 367
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 279
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 9
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 0
Last_SQL_Error
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 455
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 367
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 7
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 0
Last_SQL_Error
unlock tables;
drop table t1;

View File

@ -0,0 +1 @@
--loose-debug=d,let_first_flush_log_change_timestamp

View File

@ -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

View File

@ -0,0 +1,3 @@
1|master only
2|master only
3|master only

View File

@ -7,15 +7,15 @@
--echo ==========MASTER==========
SELECT COUNT(*) FROM t1;
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
SELECT COUNT(*) FROM t2;
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
sync_slave_with_master;
--echo ==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
SELECT COUNT(*) FROM t2;
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
connection master;

View File

@ -7,11 +7,11 @@
--echo ==========MASTER==========
SHOW CREATE VIEW v1;
SELECT * FROM v1;
SELECT * FROM v1 ORDER BY a;
sync_slave_with_master;
--echo ==========SLAVE===========
USE test_rpl;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
SELECT * FROM v1 ORDER BY a;
connection master;

View File

@ -54,7 +54,7 @@ DELETE FROM t2 WHERE a = 2;
--exec cp ./suite/rpl/data/rpl_mixed.dat $MYSQLTEST_VARDIR/tmp/
LOAD DATA INFILE '../tmp/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ;
--exec rm $MYSQLTEST_VARDIR/tmp/rpl_mixed.dat
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
--source suite/rpl/include/rpl_mixed_check_select.inc
--source suite/rpl/include/rpl_mixed_clear_tables.inc
@ -75,7 +75,7 @@ DELETE FROM t1 WHERE a = 2;
--echo
--echo ******************** SELECT ********************
INSERT INTO t1 VALUES(1, 't1, text 1');
SELECT * FROM t1 WHERE b <> UUID();
SELECT * FROM t1 WHERE b <> UUID() ORDER BY a;
--source suite/rpl/include/rpl_mixed_clear_tables.inc
# JOIN
@ -85,8 +85,8 @@ INSERT INTO t1 VALUES(1, 'CCC');
INSERT INTO t1 VALUES(2, 'DDD');
INSERT INTO t2 VALUES(1, 'DDD');
INSERT INTO t2 VALUES(2, 'CCC');
SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a;
SELECT * FROM t1 INNER JOIN t2 ON t1.b = t2.b;
SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a ORDER BY t1.a,t2.a;
SELECT * FROM t1 INNER JOIN t2 ON t1.b = t2.b ORDER BY t1.a,t2.a;
--source suite/rpl/include/rpl_mixed_clear_tables.inc
# UNION

View File

@ -707,7 +707,7 @@ Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1060
Last_SQL_Error Error 'Duplicate column name 'c6'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
*** Try to insert in master ****
INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);
@ -723,6 +723,7 @@ c1 c2 c3 c4 c5 c6 c7
1 1.00 Replication Testing Extra Col b1b1b1b1b1b1b1b1 Kyle 1 CURRENT_TIMESTAMP
2 2.00 This Test Should work b1b1b1b1b1b1b1b1 JOE 1 CURRENT_TIMESTAMP
3 3.00 If is does not, I will open a bug b1b1b1b1b1b1b1b1 QA 1 CURRENT_TIMESTAMP
5 2.00 Replication Testing b1b1b1b1b1b1b1b1 Buda 2 CURRENT_TIMESTAMP
*** DROP TABLE t15 ***
DROP TABLE t15;
*** Create t16 on slave ***

View File

@ -707,7 +707,7 @@ Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1060
Last_SQL_Error Error 'Duplicate column name 'c6'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
*** Try to insert in master ****
INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);
@ -723,6 +723,7 @@ c1 c2 c3 c4 c5 c6 c7
1 1.00 Replication Testing Extra Col b1b1b1b1b1b1b1b1 Kyle 1 CURRENT_TIMESTAMP
2 2.00 This Test Should work b1b1b1b1b1b1b1b1 JOE 1 CURRENT_TIMESTAMP
3 3.00 If is does not, I will open a bug b1b1b1b1b1b1b1b1 QA 1 CURRENT_TIMESTAMP
5 2.00 Replication Testing b1b1b1b1b1b1b1b1 Buda 2 CURRENT_TIMESTAMP
*** DROP TABLE t15 ***
DROP TABLE t15;
*** Create t16 on slave ***

View File

@ -41,26 +41,26 @@ DELETE FROM t2 WHERE b <> UUID();
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
2 t1, text 2
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
2 t1, text 2
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
DELETE FROM t1;
DELETE FROM t2;
@ -76,13 +76,13 @@ DELETE FROM t2 WHERE a = 2;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 1
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 t2, text 1
==========SLAVE===========
@ -90,13 +90,13 @@ USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 1
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 t2, text 1
DELETE FROM t1;
@ -104,7 +104,7 @@ DELETE FROM t2;
******************** LOAD DATA INFILE ********************
LOAD DATA INFILE '../tmp/rpl_mixed.dat' INTO TABLE t1 FIELDS TERMINATED BY '|' ;
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
10 line A
20 line B
@ -113,7 +113,7 @@ a b
SELECT COUNT(*) FROM t1;
COUNT(*)
3
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
10 line A
20 line B
@ -121,14 +121,14 @@ a b
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
3
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
10 line A
20 line B
@ -136,7 +136,7 @@ a b
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
DELETE FROM t1;
DELETE FROM t2;
@ -153,35 +153,35 @@ DELETE FROM t1 WHERE a = 2;
SELECT COUNT(*) FROM t1;
COUNT(*)
2
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 11
3 t1, text 33
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
2
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 11
3 t1, text 33
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
DELETE FROM t1;
DELETE FROM t2;
******************** SELECT ********************
INSERT INTO t1 VALUES(1, 't1, text 1');
SELECT * FROM t1 WHERE b <> UUID();
SELECT * FROM t1 WHERE b <> UUID() ORDER BY a;
a b
1 t1, text 1
DELETE FROM t1;
@ -192,11 +192,11 @@ INSERT INTO t1 VALUES(1, 'CCC');
INSERT INTO t1 VALUES(2, 'DDD');
INSERT INTO t2 VALUES(1, 'DDD');
INSERT INTO t2 VALUES(2, 'CCC');
SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a;
SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a ORDER BY t1.a,t2.a;
a b a b
1 CCC 1 DDD
2 DDD 2 CCC
SELECT * FROM t1 INNER JOIN t2 ON t1.b = t2.b;
SELECT * FROM t1 INNER JOIN t2 ON t1.b = t2.b ORDER BY t1.a,t2.a;
a b a b
1 CCC 2 CCC
2 DDD 1 DDD
@ -219,50 +219,50 @@ INSERT INTO t1 VALUES(1, 't1, text 1');
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
TRUNCATE t1;
==========MASTER==========
SELECT COUNT(*) FROM t1;
COUNT(*)
0
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
0
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
DELETE FROM t1;
DELETE FROM t2;
@ -275,13 +275,13 @@ UPDATE t1 SET b = 't1, text 1 updated' WHERE a = 1;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 1 updated
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 t2, text 1
==========SLAVE===========
@ -289,13 +289,13 @@ USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 t1, text 1 updated
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 t2, text 1
UPDATE t1, t2 SET t1.b = 'test', t2.b = 'test';
@ -303,13 +303,13 @@ UPDATE t1, t2 SET t1.b = 'test', t2.b = 'test';
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 test
==========SLAVE===========
@ -317,13 +317,13 @@ USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 test
DELETE FROM t1;
@ -349,26 +349,26 @@ COMMIT;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
START TRANSACTION;
INSERT INTO t1 VALUES (2, 'rollback');
@ -377,26 +377,26 @@ ROLLBACK;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
START TRANSACTION;
INSERT INTO t1 VALUES (3, 'before savepoint s1');
@ -407,27 +407,27 @@ ROLLBACK TO SAVEPOINT s1;
SELECT COUNT(*) FROM t1;
COUNT(*)
2
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
3 before savepoint s1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
START TRANSACTION;
INSERT INTO t1 VALUES (5, 'before savepoint s2');
@ -441,7 +441,7 @@ DELETE FROM t1 WHERE a = 7;
SELECT COUNT(*) FROM t1;
COUNT(*)
4
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
3 before savepoint s1
@ -450,14 +450,14 @@ a b
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
4
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 start
3 before savepoint s1
@ -466,7 +466,7 @@ a b
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
DELETE FROM t1;
DELETE FROM t2;
@ -610,28 +610,28 @@ DELETE FROM t1 WHERE a = 202;
SELECT COUNT(*) FROM t1;
COUNT(*)
2
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
100 test
201 test
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
2
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
100 test
201 test
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
ALTER PROCEDURE p1 COMMENT 'p1';
DROP PROCEDURE p1;
@ -649,13 +649,13 @@ INSERT INTO t1 VALUES (1, 'test');
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 test
==========SLAVE===========
@ -663,13 +663,13 @@ USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test
SELECT COUNT(*) FROM t2;
COUNT(*)
1
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
1 test
DELETE FROM t1;
@ -694,51 +694,51 @@ test_rpl e1 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========MASTER==========
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
ALTER EVENT e1 RENAME TO e2;
==========MASTER==========
@ -754,26 +754,26 @@ test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
==========SLAVE===========
USE test_rpl;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SELECT * FROM t1;
SELECT * FROM t1 ORDER BY a;
a b
1 test1
SELECT COUNT(*) FROM t2;
COUNT(*)
0
SELECT * FROM t2;
SELECT * FROM t2 ORDER BY a;
a b
DROP EVENT e2;
==========MASTER==========
@ -795,7 +795,7 @@ CREATE VIEW v2 AS SELECT * FROM t1 WHERE b <> UUID();
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` where (`t1`.`a` = 1) latin1 latin1_swedish_ci
SELECT * FROM v1;
SELECT * FROM v1 ORDER BY a;
a b
1 test1
==========SLAVE===========
@ -803,7 +803,7 @@ USE test_rpl;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` where (`t1`.`a` = 1) latin1 latin1_swedish_ci
SELECT * FROM v1;
SELECT * FROM v1 ORDER BY a;
a b
1 test1
ALTER VIEW v1 AS SELECT * FROM t1 WHERE a = 2;
@ -811,7 +811,7 @@ ALTER VIEW v1 AS SELECT * FROM t1 WHERE a = 2;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` where (`t1`.`a` = 2) latin1 latin1_swedish_ci
SELECT * FROM v1;
SELECT * FROM v1 ORDER BY a;
a b
2 test2
==========SLAVE===========
@ -819,7 +819,7 @@ USE test_rpl;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` where (`t1`.`a` = 2) latin1 latin1_swedish_ci
SELECT * FROM v1;
SELECT * FROM v1 ORDER BY a;
a b
2 test2
DROP VIEW v1;

View File

@ -17,13 +17,13 @@ DROP EVENT IF EXISTS e11;
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=myisam;
INSERT INTO t1 VALUES (1,1,'1');
INSERT INTO t1 VALUES (2,2,UUID());
CREATE TABLE t2 (a INT, b INT, c VARCHAR(64)) ENGINE=myisam;
CREATE TABLE t2 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=myisam;
INSERT INTO t2 VALUES (1,1,'1');
INSERT INTO t2 VALUES (2,2,UUID());
CREATE TABLE t11 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=innodb;
INSERT INTO t11 VALUES (1,1,'1');
INSERT INTO t11 VALUES (2,2,UUID());
CREATE TABLE t12 (a INT, b INT, c VARCHAR(64)) ENGINE=innodb;
CREATE TABLE t12 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=innodb;
INSERT INTO t12 VALUES (1,1,'1');
INSERT INTO t12 VALUES (2,2,UUID());
@ -49,21 +49,15 @@ BEGIN
UPDATE t12 SET c = '';
UPDATE t13 SET c = '';
END|
CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND ENABLE DO
CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DISABLE DO
BEGIN
DECLARE c INT;
SELECT a INTO c FROM t1 WHERE a < 11 ORDER BY a DESC LIMIT 1;
IF c = 7 THEN
ALTER EVENT e1 DISABLE;
CALL p1(10, '');
END IF;
END|
CREATE EVENT e11 ON SCHEDULE EVERY 1 SECOND ENABLE DO
CREATE EVENT e11 ON SCHEDULE EVERY 1 SECOND DISABLE DO
BEGIN
DECLARE c INT;
SELECT a INTO c FROM t11 WHERE a < 11 ORDER BY a DESC LIMIT 1;
IF c = 7 THEN
ALTER EVENT e11 DISABLE;
CALL p11(10, '');
END IF;
END|
CREATE FUNCTION f1 (x INT) RETURNS VARCHAR(64)
BEGIN
@ -78,11 +72,11 @@ RETURN f1(x);
END|
CREATE PROCEDURE p1 (IN x INT, IN y VARCHAR(64))
BEGIN
INSERT INTO t1 VALUES (x,x,y);
INSERT IGNORE INTO t1 VALUES (x,x,y);
END|
CREATE PROCEDURE p11 (IN x INT, IN y VARCHAR(64))
BEGIN
INSERT INTO t11 VALUES (x,x,y);
INSERT IGNORE INTO t11 VALUES (x,x,y);
END|
CREATE TABLE t3 SELECT * FROM v1;
@ -110,6 +104,8 @@ INSERT INTO t11 VALUES(7,7,f2(7));
INSERT INTO t11 VALUES (103,103,'');
SET GLOBAL EVENT_SCHEDULER = on;
ALTER EVENT e1 ENABLE;
ALTER EVENT e11 ENABLE;
SET GLOBAL EVENT_SCHEDULER = off;
SHOW TABLES LIKE 't%';
@ -138,8 +134,8 @@ PROCEDURE p1
PROCEDURE p11
SELECT event_name, status FROM information_schema.events WHERE event_schema='test';
event_name status
e1 ENABLED
e11 ENABLED
e1 DISABLED
e11 DISABLED
SELECT COUNT(*) FROM t1;
COUNT(*)
@ -438,6 +434,8 @@ UPDATE t3 SET c='';
UPDATE t11 SET c='';
UPDATE t12 SET c='';
UPDATE t13 SET c='';
ALTER TABLE t3 ORDER BY a;
ALTER TABLE t13 ORDER BY a;

View File

@ -27,6 +27,42 @@ 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 #
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 #
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 #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno 0
Last_IO_Error
Last_SQL_Errno 0
Last_SQL_Error

View File

@ -242,3 +242,34 @@ a b
3 1
4 4
drop table t1,t2;
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 ****
SET SESSION BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT PRIMARY KEY, b SET('master','slave'));
INSERT INTO t1 VALUES (1,'master,slave'), (2,'master,slave');
**** On Slave ****
UPDATE t1 SET a = 5, b = 'slave' WHERE a = 1;
SELECT * FROM t1 ORDER BY a;
a b
2 master,slave
5 slave
**** On Master ****
UPDATE t1 SET a = 5, b = 'master' WHERE a = 1;
SELECT * FROM t1 ORDER BY a;
a b
2 master,slave
5 master
**** On Slave ****
Last_SQL_Error
SELECT * FROM t1 ORDER BY a;
a b
2 master,slave
5 slave
DROP TABLE t1;
**** On Master ****
DROP TABLE t1;

View File

@ -29,8 +29,7 @@ select * from t1;
a
1
2
3
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running 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 Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 786 # # master-bin.000001 Yes Yes 0 0 786 # None 0 No # No 0 0
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 851 # # master-bin.000001 Yes Yes 0 0 851 # None 0 No # No 0 0
drop table t1;

View File

@ -142,3 +142,211 @@ Last_SQL_Errno 0
Last_SQL_Error
**** On Master ****
DROP TABLE t1, t2;
SET SESSION BINLOG_FORMAT=ROW;
SET AUTOCOMMIT=0;
CREATE TABLE t1 (a INT, b VARCHAR(20)) ENGINE=myisam;
CREATE TABLE t2 (a INT, b VARCHAR(20)) ENGINE=myisam;
CREATE TABLE t3 (a INT, b VARCHAR(20)) ENGINE=myisam;
INSERT INTO t1 VALUES (1,'master/slave');
INSERT INTO t2 VALUES (1,'master/slave');
INSERT INTO t3 VALUES (1,'master/slave');
CREATE TRIGGER tr1 AFTER UPDATE on t1 FOR EACH ROW
BEGIN
INSERT INTO t2 VALUES (NEW.a,NEW.b);
DELETE FROM t2 WHERE a < NEW.a;
END|
CREATE TRIGGER tr2 AFTER INSERT on t2 FOR EACH ROW
BEGIN
UPDATE t3 SET a =2, b = 'master only';
END|
**** On Slave ****
STOP SLAVE;
**** On Master ****
UPDATE t1 SET a = 2, b = 'master only' WHERE a = 1;
DROP TRIGGER tr1;
DROP TRIGGER tr2;
INSERT INTO t1 VALUES (3,'master/slave');
INSERT INTO t2 VALUES (3,'master/slave');
INSERT INTO t3 VALUES (3,'master/slave');
SELECT * FROM t1 ORDER BY a;
a b
2 master only
3 master/slave
SELECT * FROM t2 ORDER BY a;
a b
2 master only
3 master/slave
SELECT * FROM t3 ORDER BY a;
a b
2 master only
3 master/slave
*** On Slave ***
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SELECT * FROM t1 ORDER BY a;
a b
1 master/slave
3 master/slave
SELECT * FROM t2 ORDER BY a;
a b
1 master/slave
3 master/slave
SELECT * FROM t3 ORDER BY a;
a b
1 master/slave
3 master/slave
DROP TABLE t1, t2, t3;
**** Case 2: Row binlog format and transactional tables ****
*** On Master ***
CREATE TABLE t4 (a INT, b VARCHAR(20)) ENGINE=innodb;
CREATE TABLE t5 (a INT, b VARCHAR(20)) ENGINE=innodb;
CREATE TABLE t6 (a INT, b VARCHAR(20)) ENGINE=innodb;
**** On Slave ****
STOP SLAVE;
*** On Master ***
BEGIN;
INSERT INTO t4 VALUES (2, 'master only');
INSERT INTO t5 VALUES (2, 'master only');
INSERT INTO t6 VALUES (2, 'master only');
COMMIT;
BEGIN;
INSERT INTO t4 VALUES (3, 'master/slave');
INSERT INTO t5 VALUES (3, 'master/slave');
INSERT INTO t6 VALUES (3, 'master/slave');
COMMIT;
SELECT * FROM t4 ORDER BY a;
a b
2 master only
3 master/slave
SELECT * FROM t5 ORDER BY a;
a b
2 master only
3 master/slave
SELECT * FROM t6 ORDER BY a;
a b
2 master only
3 master/slave
*** On Slave ***
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SELECT * FROM t4 ORDER BY a;
a b
3 master/slave
SELECT * FROM t5 ORDER BY a;
a b
3 master/slave
SELECT * FROM t6 ORDER BY a;
a b
3 master/slave
**** On Slave ****
STOP SLAVE;
*** On Master ***
BEGIN;
INSERT INTO t4 VALUES (6, 'master only');
INSERT INTO t5 VALUES (6, 'master only');
INSERT INTO t6 VALUES (6, 'master only');
COMMIT;
BEGIN;
INSERT INTO t4 VALUES (7, 'master only');
INSERT INTO t5 VALUES (7, 'master only');
INSERT INTO t6 VALUES (7, 'master only');
COMMIT;
SELECT * FROM t4 ORDER BY a;
a b
2 master only
3 master/slave
6 master only
7 master only
SELECT * FROM t5 ORDER BY a;
a b
2 master only
3 master/slave
6 master only
7 master only
SELECT * FROM t6 ORDER BY a;
a b
2 master only
3 master/slave
6 master only
7 master only
*** On Slave ***
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=10;
START SLAVE;
SELECT * FROM t4 ORDER BY a;
a b
3 master/slave
SELECT * FROM t5 ORDER BY a;
a b
3 master/slave
SELECT * FROM t6 ORDER BY a;
a b
3 master/slave
STOP SLAVE;
SET AUTOCOMMIT=0;
INSERT INTO t4 VALUES (4, 'master only');
INSERT INTO t5 VALUES (4, 'master only');
INSERT INTO t6 VALUES (4, 'master only');
COMMIT;
INSERT INTO t4 VALUES (5, 'master/slave');
INSERT INTO t5 VALUES (5, 'master/slave');
INSERT INTO t6 VALUES (5, 'master/slave');
COMMIT;
SELECT * FROM t4 ORDER BY a;
a b
2 master only
3 master/slave
4 master only
5 master/slave
6 master only
7 master only
SELECT * FROM t5 ORDER BY a;
a b
2 master only
3 master/slave
4 master only
5 master/slave
6 master only
7 master only
SELECT * FROM t6 ORDER BY a;
a b
2 master only
3 master/slave
4 master only
5 master/slave
6 master only
7 master only
*** On Slave ***
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SELECT * FROM t4 ORDER BY a;
a b
3 master/slave
5 master/slave
SELECT * FROM t5 ORDER BY a;
a b
3 master/slave
5 master/slave
SELECT * FROM t6 ORDER BY a;
a b
3 master/slave
5 master/slave
DROP TABLE t4, t5, t6;
**** Case 3: Statement logging format and LOAD DATA with non-transactional table ****
*** On Master ***
CREATE TABLE t10 (a INT, b VARCHAR(20)) ENGINE=myisam;
*** On Slave ***
STOP SLAVE;
*** On Master ***
SET SESSION BINLOG_FORMAT=STATEMENT;
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/rpl_bug28618.dat' INTO TABLE t10 FIELDS TERMINATED BY '|';
SELECT * FROM t10 ORDER BY a;
a b
1 master only
2 master only
3 master only
*** On Slave ***
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
SELECT * FROM t10 ORDER BY a;
a b
DROP TABLE t10;

View File

@ -0,0 +1,81 @@
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 ****
SET SESSION BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
**** On Slave ****
SHOW STATUS LIKE 'Slave_retried_transactions';
Variable_name Value
Slave_retried_transactions 0
UPDATE t1 SET a = 5, b = 47 WHERE a = 1;
SELECT * FROM t1;
a b
5 47
2 2
3 3
4 4
**** On Master ****
UPDATE t1 SET a = 5, b = 5 WHERE a = 1;
SELECT * FROM t1;
a b
5 5
2 2
3 3
4 4
**** On Slave ****
SHOW STATUS LIKE 'Slave_retried_transactions';
Variable_name Value
Slave_retried_transactions 0
SELECT * FROM t1;
a b
5 47
2 2
3 3
4 4
SHOW SLAVE STATUS;
Slave_IO_State #
Master_Host 127.0.0.1
Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 408
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 408
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 #
Master_SSL_Verify_Server_Cert No
Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 0
Last_SQL_Error
DROP TABLE t1;
**** On Master ****
DROP TABLE t1;

View File

@ -11,7 +11,5 @@
##############################################################################
rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master
rpl_invoked_features : BUG#29020 2007-06-21 Lars Non-deterministic test case
rpl_auto_increment_11932 : Bug#29809 2007-07-16 ingo Slave SQL errors in warnings file
rpl_stm_extraColmaster_ndb : WL#3915 : Statement-based replication not supported in ndb. Enable test when supported.
rpl_row_extraColmaster_ndb : BUG#29549 : Replication of BLOBs fail for NDB

View File

@ -114,4 +114,5 @@ SELECT * FROM visits_events;
# Cleanup
DROP DATABASE track;
sync_slave_with_master;
--echo End of 5.1 tests

View File

@ -8,10 +8,9 @@
--source include/master-slave.inc
--source include/have_innodb.inc
#
# Define variables used by test case
#
# --disable_warnings/--enable_warnings added before/after query
# if one uses UUID() function because we need to avoid warnings
# for STATEMENT binlog format
# Non-transactional engine
--let $engine_type= myisam
@ -45,20 +44,24 @@ DROP EVENT IF EXISTS e11;
--echo
eval CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=$engine_type;
--disable_warnings
INSERT INTO t1 VALUES (1,1,'1');
--disable_warnings
INSERT INTO t1 VALUES (2,2,UUID());
eval CREATE TABLE t2 (a INT, b INT, c VARCHAR(64)) ENGINE=$engine_type;
--enable_warnings
eval CREATE TABLE t2 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=$engine_type;
INSERT INTO t2 VALUES (1,1,'1');
--disable_warnings
INSERT INTO t2 VALUES (2,2,UUID());
--enable_warnings
eval CREATE TABLE t11 (a INT NOT NULL PRIMARY KEY, b INT, c VARCHAR(64)) ENGINE=$engine_type2;
--disable_warnings
INSERT INTO t11 VALUES (1,1,'1');
--disable_warnings
INSERT INTO t11 VALUES (2,2,UUID());
eval CREATE TABLE t12 (a INT, b INT, c VARCHAR(64)) ENGINE=$engine_type2;
--enable_warnings
eval CREATE TABLE t12 (a INT UNIQUE, b INT, c VARCHAR(64)) ENGINE=$engine_type2;
INSERT INTO t12 VALUES (1,1,'1');
--disable_warnings
INSERT INTO t12 VALUES (2,2,UUID());
--enable_warnings
@ -96,22 +99,16 @@ BEGIN
END|
# Create events which will run every 1 sec
CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND ENABLE DO
CREATE EVENT e1 ON SCHEDULE EVERY 1 SECOND DISABLE DO
BEGIN
DECLARE c INT;
SELECT a INTO c FROM t1 WHERE a < 11 ORDER BY a DESC LIMIT 1;
IF c = 7 THEN
CALL p1(10, '');
END IF;
ALTER EVENT e1 DISABLE;
CALL p1(10, '');
END|
CREATE EVENT e11 ON SCHEDULE EVERY 1 SECOND ENABLE DO
CREATE EVENT e11 ON SCHEDULE EVERY 1 SECOND DISABLE DO
BEGIN
DECLARE c INT;
SELECT a INTO c FROM t11 WHERE a < 11 ORDER BY a DESC LIMIT 1;
IF c = 7 THEN
CALL p11(10, '');
END IF;
ALTER EVENT e11 DISABLE;
CALL p11(10, '');
END|
# Create functions and procedures used for events
@ -130,12 +127,12 @@ END|
CREATE PROCEDURE p1 (IN x INT, IN y VARCHAR(64))
BEGIN
INSERT INTO t1 VALUES (x,x,y);
INSERT IGNORE INTO t1 VALUES (x,x,y);
END|
CREATE PROCEDURE p11 (IN x INT, IN y VARCHAR(64))
BEGIN
INSERT INTO t11 VALUES (x,x,y);
INSERT IGNORE INTO t11 VALUES (x,x,y);
END|
DELIMITER ;|
@ -147,17 +144,24 @@ DELIMITER ;|
# Do some actions for non-transactional tables
--echo
--disable_warnings
CREATE TABLE t3 SELECT * FROM v1;
INSERT INTO t1 VALUES (3,3,'');
UPDATE t1 SET c='2' WHERE a = 1;
--disable_warnings
INSERT INTO t1 VALUES(4,4,f1(4));
--enable_warnings
INSERT INTO t1 VALUES (100,100,'');
--disable_warnings
CALL p1(5, UUID());
--enable_warnings
INSERT INTO t1 VALUES (101,101,'');
--disable_warnings
INSERT INTO t1 VALUES(6,6,f1(6));
--enable_warnings
INSERT INTO t1 VALUES (102,102,'');
--disable_warnings
INSERT INTO t1 VALUES(7,7,f2(7));
--enable_warnings
INSERT INTO t1 VALUES (103,103,'');
# Do some actions for transactional tables
@ -165,21 +169,34 @@ INSERT INTO t1 VALUES (103,103,'');
CREATE TABLE t13 SELECT * FROM v11;
INSERT INTO t11 VALUES (3,3,'');
UPDATE t11 SET c='2' WHERE a = 1;
--disable_warnings
INSERT INTO t11 VALUES(4,4,f1(4));
INSERT INTO t11 VALUES (100,100,'');
CALL p11(5, UUID());
INSERT INTO t11 VALUES (101,101,'');
INSERT INTO t11 VALUES(6,6,f1(6));
INSERT INTO t11 VALUES (102,102,'');
INSERT INTO t11 VALUES(7,7,f2(7));
INSERT INTO t11 VALUES (103,103,'');
--enable_warnings
INSERT INTO t11 VALUES (100,100,'');
--disable_warnings
CALL p11(5, UUID());
--enable_warnings
INSERT INTO t11 VALUES (101,101,'');
--disable_warnings
INSERT INTO t11 VALUES(6,6,f1(6));
--enable_warnings
INSERT INTO t11 VALUES (102,102,'');
--disable_warnings
INSERT INTO t11 VALUES(7,7,f2(7));
--enable_warnings
INSERT INTO t11 VALUES (103,103,'');
# Scheduler is on
--echo
# Temporally events fire sequentally due Bug#29020.
SET GLOBAL EVENT_SCHEDULER = on;
# Wait 2 sec while events will executed
--sleep 2
# Wait while events will executed
ALTER EVENT e1 ENABLE;
let $wait_condition= SELECT COUNT(*) = 1 FROM t1 WHERE t1.a = 10;
--source include/wait_condition.inc
ALTER EVENT e11 ENABLE;
let $wait_condition= SELECT COUNT(*) = 1 FROM t11 WHERE t11.a = 10;
--source include/wait_condition.inc
SET GLOBAL EVENT_SCHEDULER = off;
# Check original objects
@ -234,7 +251,7 @@ SELECT COUNT(*) FROM t13;
SELECT a,b FROM t13 ORDER BY a;
SELECT a,b FROM v11 ORDER BY a;
# Remove UUID() before comparing
# Remove UUID() before comparing and sort tables
--connection master
--echo
@ -245,6 +262,9 @@ UPDATE t11 SET c='';
UPDATE t12 SET c='';
UPDATE t13 SET c='';
ALTER TABLE t3 ORDER BY a;
ALTER TABLE t13 ORDER BY a;
--sync_slave_with_master slave
# Compare a data from master and slave
@ -260,13 +280,12 @@ UPDATE t13 SET c='';
# Remove dumps
--echo
--exec rm $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql
--exec rm $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql
--remove_file $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_master.sql
--remove_file $MYSQLTEST_VARDIR/tmp/rpl_invoked_features_slave.sql
# Remove tables,views,procedures,functions
--connection master
--echo
--disable_warnings
DROP VIEW IF EXISTS v1,v11;
DROP TABLE IF EXISTS t1,t2,t3,t11,t12,t13;
DROP PROCEDURE IF EXISTS p1;
@ -275,7 +294,6 @@ DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP EVENT IF EXISTS e1;
DROP EVENT IF EXISTS e11;
--enable_warnings
--sync_slave_with_master slave

View File

@ -66,16 +66,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;
--source include/wait_for_slave_io_to_stop.inc
SHOW STATUS LIKE 'Slave_running';
# cleanup
#connection master;
#drop table t1;
#connection slave;
#drop table t1;
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 # 7 # 8 # 9 # 12 # 22 # 23 # 33 #
query_vertical show slave status;
# End of tests

View File

@ -223,3 +223,38 @@ connection master;
drop table t1,t2;
sync_slave_with_master;
#
# BUG#31702: Missing row on slave causes assertion failure under
# row-based replication
#
disable_query_log;
source include/master-slave-reset.inc;
enable_query_log;
--echo **** On Master ****
connection master;
SET SESSION BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT PRIMARY KEY, b SET('master','slave'));
INSERT INTO t1 VALUES (1,'master,slave'), (2,'master,slave');
--echo **** On Slave ****
sync_slave_with_master;
UPDATE t1 SET a = 5, b = 'slave' WHERE a = 1;
SELECT * FROM t1 ORDER BY a;
--echo **** On Master ****
connection master;
UPDATE t1 SET a = 5, b = 'master' WHERE a = 1;
SELECT * FROM t1 ORDER BY a;
--echo **** On Slave ****
sync_slave_with_master;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
SELECT * FROM t1 ORDER BY a;
DROP TABLE t1;
--echo **** On Master ****
connection master;
DROP TABLE t1;

View File

@ -344,5 +344,6 @@ FLUSH LOGS;
--exec rm $MYSQLTEST_VARDIR/tmp/local.sql
DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5;
sync_slave_with_master;
# End of 4.1 tests

View File

@ -1 +1 @@
--slave-skip-error=1062,1582
--slave-skip-error=1062

View File

@ -3,6 +3,14 @@
#########################################
# Note that errors are ignored by opt file.
source include/master-slave.inc;
source include/have_binlog_format_mixed_or_statement.inc;
#
# Bug #30594
# Skipping error due to applying Row-based repliation events
# should be checked with another test file
# consider names like rpl_row_skip_error
#
create table t1 (n int not null primary key);
save_master_pos;

View File

@ -0,0 +1 @@
--innodb

View File

@ -1,7 +1,9 @@
source include/master-slave.inc;
source include/have_innodb.inc;
--echo **** On Slave ****
connection slave;
source include/have_innodb.inc;
STOP SLAVE;
--echo **** On Master ****
@ -69,3 +71,240 @@ query_vertical SHOW SLAVE STATUS;
connection master;
DROP TABLE t1, t2;
sync_slave_with_master;
#
# More tests for BUG#28618
#
# Case 1.
# ROW binlog format and non-transactional tables.
# Create the group of events via triggers and try to skip
# some items of that group.
#
connection master;
SET SESSION BINLOG_FORMAT=ROW;
SET AUTOCOMMIT=0;
CREATE TABLE t1 (a INT, b VARCHAR(20)) ENGINE=myisam;
CREATE TABLE t2 (a INT, b VARCHAR(20)) ENGINE=myisam;
CREATE TABLE t3 (a INT, b VARCHAR(20)) ENGINE=myisam;
INSERT INTO t1 VALUES (1,'master/slave');
INSERT INTO t2 VALUES (1,'master/slave');
INSERT INTO t3 VALUES (1,'master/slave');
DELIMITER |;
CREATE TRIGGER tr1 AFTER UPDATE on t1 FOR EACH ROW
BEGIN
INSERT INTO t2 VALUES (NEW.a,NEW.b);
DELETE FROM t2 WHERE a < NEW.a;
END|
CREATE TRIGGER tr2 AFTER INSERT on t2 FOR EACH ROW
BEGIN
UPDATE t3 SET a =2, b = 'master only';
END|
DELIMITER ;|
--echo **** On Slave ****
sync_slave_with_master;
STOP SLAVE;
source include/wait_for_slave_to_stop.inc;
--echo **** On Master ****
connection master;
UPDATE t1 SET a = 2, b = 'master only' WHERE a = 1;
DROP TRIGGER tr1;
DROP TRIGGER tr2;
INSERT INTO t1 VALUES (3,'master/slave');
INSERT INTO t2 VALUES (3,'master/slave');
INSERT INTO t3 VALUES (3,'master/slave');
SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
SELECT * FROM t3 ORDER BY a;
save_master_pos;
--echo *** On Slave ***
connection slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
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;
SELECT * FROM t3 ORDER BY a;
connection master;
DROP TABLE t1, t2, t3;
sync_slave_with_master;
--echo **** Case 2: Row binlog format and transactional tables ****
# Create the transaction and try to skip some
# queries from one.
--echo *** On Master ***
connection master;
CREATE TABLE t4 (a INT, b VARCHAR(20)) ENGINE=innodb;
CREATE TABLE t5 (a INT, b VARCHAR(20)) ENGINE=innodb;
CREATE TABLE t6 (a INT, b VARCHAR(20)) ENGINE=innodb;
--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 t4 VALUES (2, 'master only');
INSERT INTO t5 VALUES (2, 'master only');
INSERT INTO t6 VALUES (2, 'master only');
COMMIT;
BEGIN;
INSERT INTO t4 VALUES (3, 'master/slave');
INSERT INTO t5 VALUES (3, 'master/slave');
INSERT INTO t6 VALUES (3, 'master/slave');
COMMIT;
SELECT * FROM t4 ORDER BY a;
SELECT * FROM t5 ORDER BY a;
SELECT * FROM t6 ORDER BY a;
save_master_pos;
--echo *** On Slave ***
connection slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
source include/wait_for_slave_to_start.inc;
sync_with_master;
SELECT * FROM t4 ORDER BY a;
SELECT * FROM t5 ORDER BY a;
SELECT * FROM t6 ORDER BY a;
# Test skipping two groups
--echo **** On Slave ****
connection slave;
STOP SLAVE;
source include/wait_for_slave_to_stop.inc;
--echo *** On Master ***
connection master;
BEGIN;
INSERT INTO t4 VALUES (6, 'master only');
INSERT INTO t5 VALUES (6, 'master only');
INSERT INTO t6 VALUES (6, 'master only');
COMMIT;
BEGIN;
INSERT INTO t4 VALUES (7, 'master only');
INSERT INTO t5 VALUES (7, 'master only');
INSERT INTO t6 VALUES (7, 'master only');
COMMIT;
SELECT * FROM t4 ORDER BY a;
SELECT * FROM t5 ORDER BY a;
SELECT * FROM t6 ORDER BY a;
save_master_pos;
--echo *** On Slave ***
connection slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=10;
START SLAVE;
source include/wait_for_slave_to_start.inc;
sync_with_master;
SELECT * FROM t4 ORDER BY a;
SELECT * FROM t5 ORDER BY a;
SELECT * FROM t6 ORDER BY a;
#
# And the same, but with autocommit = 0
#
connection slave;
STOP SLAVE;
source include/wait_for_slave_to_stop.inc;
connection master;
SET AUTOCOMMIT=0;
INSERT INTO t4 VALUES (4, 'master only');
INSERT INTO t5 VALUES (4, 'master only');
INSERT INTO t6 VALUES (4, 'master only');
COMMIT;
INSERT INTO t4 VALUES (5, 'master/slave');
INSERT INTO t5 VALUES (5, 'master/slave');
INSERT INTO t6 VALUES (5, 'master/slave');
COMMIT;
SELECT * FROM t4 ORDER BY a;
SELECT * FROM t5 ORDER BY a;
SELECT * FROM t6 ORDER BY a;
save_master_pos;
--echo *** On Slave ***
connection slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
source include/wait_for_slave_to_start.inc;
sync_with_master;
SELECT * FROM t4 ORDER BY a;
SELECT * FROM t5 ORDER BY a;
SELECT * FROM t6 ORDER BY a;
connection master;
DROP TABLE t4, t5, t6;
sync_slave_with_master;
--echo **** Case 3: Statement logging format and LOAD DATA with non-transactional table ****
# LOAD DATA creates two events in binary log for statement binlog format.
# Try to skip the first.
--echo *** On Master ***
connection master;
CREATE TABLE t10 (a INT, b VARCHAR(20)) ENGINE=myisam;
--echo *** On Slave ***
sync_slave_with_master;
STOP SLAVE;
source include/wait_for_slave_to_stop.inc;
--echo *** On Master ***
connection master;
SET SESSION BINLOG_FORMAT=STATEMENT;
exec cp ./suite/rpl/data/rpl_bug28618.dat $MYSQLTEST_VARDIR/tmp/;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/rpl_bug28618.dat' INTO TABLE t10 FIELDS TERMINATED BY '|';
remove_file $MYSQLTEST_VARDIR/tmp/rpl_bug28618.dat;
SELECT * FROM t10 ORDER BY a;
save_master_pos;
--echo *** On Slave ***
connection slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
source include/wait_for_slave_to_start.inc;
sync_with_master;
SELECT * FROM t10 ORDER BY a;
connection master;
DROP TABLE t10;
sync_slave_with_master;

View File

@ -28,7 +28,7 @@ insert into t1 values(NULL,'new');
save_master_pos;
connection slave;
# wait until the slave tries to run the query, fails and aborts slave thread
wait_for_slave_to_stop;
source include/wait_for_slave_sql_error.inc;
select * from t1 order by n;
delete from t1 where n = 2;
--disable_warnings

View File

@ -0,0 +1,3 @@
--loose-debug="+d,all_errors_are_temporary_errors" --slave-transaction-retries=2

View File

@ -0,0 +1,27 @@
source include/master-slave.inc;
--echo **** On Master ****
connection master;
SET SESSION BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
--echo **** On Slave ****
sync_slave_with_master;
SHOW STATUS LIKE 'Slave_retried_transactions';
UPDATE t1 SET a = 5, b = 47 WHERE a = 1;
SELECT * FROM t1;
--echo **** On Master ****
connection master;
UPDATE t1 SET a = 5, b = 5 WHERE a = 1;
SELECT * FROM t1;
#SHOW BINLOG EVENTS;
--echo **** On Slave ****
sync_slave_with_master;
SHOW STATUS LIKE 'Slave_retried_transactions';
SELECT * FROM t1;
source include/show_slave_status.inc;
DROP TABLE t1;
--echo **** On Master ****
connection master;
DROP TABLE t1;

View File

@ -707,7 +707,7 @@ Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 1060
Last_SQL_Error Error 'Duplicate column name 'c6'' on query. Default database: 'test'. Query: 'ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5'
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
*** Try to insert in master ****
INSERT INTO t15 () VALUES(5,2.00,'Replication Testing',@b1,'Buda',2);

View File

@ -15,8 +15,6 @@ rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not r
rpl_ndb_2myisam : BUG#19227 Seems to pass currently
rpl_ndb_2other : BUG#21842 2007-08-30 tsmith test has never worked on bigendian (sol10-sparc-a, powermacg5
rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD
rpl_ndb_innodb2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue
rpl_ndb_myisam2ndb : Bug#29549 rpl_ndb_myisam2ndb,rpl_ndb_innodb2ndb failed on Solaris for pack_length issue
rpl_ndb_ddl : BUG#28798 2007-05-31 lars Valgrind failure in NDB
rpl_ndb_mix_innodb : BUG#28123 rpl_ndb_mix_innodb.test casue slave to core on sol10-sparc-a
rpl_ndb_ctype_ucs2_def : BUG#27404 util thd mysql_parse sig11 when mysqld default multibyte charset

View File

@ -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

View File

@ -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

View File

@ -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
#

View File

@ -185,6 +185,13 @@ select * from t1 where a = 'b' and a = 'b';
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
#

View File

@ -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

View File

@ -753,6 +753,38 @@ select * from t1;
select * from t2;
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
#

View File

@ -588,6 +588,7 @@ CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ;
# as the test is about to see erroed queries in binlog
set @sav_binlog_format= @@session.binlog_format;
set @@session.binlog_format= mixed;
@ -614,5 +615,42 @@ show master status /* there must be the UPDATE query event */;
# cleanup bug#27716
drop table t1, t2;
set @@session.binlog_format= @sav_binlog_format;
#
# 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 */;
# cleanup bug#29136
drop table t1, t2, t3;
#
# Add further tests from here
#
--echo end of tests

View File

@ -282,6 +282,15 @@ 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
#

View File

@ -3,7 +3,8 @@
# Simple test for the partition storage engine
# Taken fromm the select test
#
-- source include/have_partition.inc
source include/have_partition.inc;
source include/have_archive.inc;
--disable_warnings
drop table if exists t1;

View File

@ -1393,21 +1393,86 @@ int Field::store(const char *to, uint length, CHARSET_INFO *cs,
}
/**
Pack the field into a format suitable for storage and transfer.
To implement packing functionality, only the virtual function
should be overridden. The other functions are just convenience
functions and hence should not be overridden.
The value of <code>low_byte_first</code> is dependent on how the
packed data is going to be used: for local use, e.g., temporary
store on disk or in memory, use the native format since that is
faster. For data that is going to be transfered to other machines
(e.g., when writing data to the binary log), data should always be
stored in little-endian format.
@note The default method for packing fields just copy the raw bytes
of the record into the destination, but never more than
<code>max_length</code> characters.
@param to
Pointer to memory area where representation of field should be put.
@param from
Pointer to memory area where record representation of field is
stored.
@param max_length
Maximum length of the field, as given in the column definition. For
example, for <code>CHAR(1000)</code>, the <code>max_length</code>
is 1000. This information is sometimes needed to decide how to pack
the data.
@param low_byte_first
@c TRUE if integers should be stored little-endian, @c FALSE if
native format should be used. Note that for little-endian machines,
the value of this flag is a moot point since the native format is
little-endian.
*/
uchar *
Field::pack(uchar *to, const uchar *from, uint max_length,
bool low_byte_first __attribute__((unused)))
{
uint32 length= pack_length();
set_if_smaller(length, max_length);
memcpy(to, from, length);
return to+length;
}
/**
Unpack a field from row data.
This method is used to unpack a field from a master whose size
of the field is less than that of the slave.
This method is used to unpack a field from a master whose size of
the field is less than that of the slave.
The <code>param_data</code> parameter is a two-byte integer (stored
in the least significant 16 bits of the unsigned integer) usually
consisting of two parts: the real type in the most significant byte
and a original pack length in the least significant byte.
The exact layout of the <code>param_data</code> field is given by
the <code>Table_map_log_event::save_field_metadata()</code>.
This is the default method for unpacking a field. It just copies
the memory block in byte order (of original pack length bytes or
length of field, whichever is smaller).
@param to Destination of the data
@param from Source of the data
@param param_data Pack length of the field data
@param param_data Real type and original pack length of the field
data
@param low_byte_first
If this flag is @c true, all composite entities (e.g., lengths)
should be unpacked in little-endian format; otherwise, the entities
are unpacked in native order.
@return New pointer into memory based on from + length of the data
*/
const uchar *Field::unpack(uchar* to,
const uchar *from,
uint param_data)
const uchar *
Field::unpack(uchar* to, const uchar *from, uint param_data,
bool low_byte_first __attribute__((unused)))
{
uint length=pack_length();
int from_type= 0;
@ -1420,19 +1485,18 @@ const uchar *Field::unpack(uchar* to,
from_type= (param_data & 0xff00) >> 8U; // real_type.
param_data= param_data & 0x00ff; // length.
}
if ((param_data == 0) ||
(length == param_data) ||
(from_type != real_type()))
{
memcpy(to, from, length);
return from+length;
}
uint len= (param_data && (param_data < length)) ?
param_data : length;
/*
If the length is the same, use old unpack method.
If the param_data is 0, use the old unpack method.
This is possible if the table map was generated from a down-level
master or if the data was not available on the master.
If the real_types are not the same, use the old unpack method.
*/
if ((length == param_data) ||
(param_data == 0) ||
(from_type != real_type()))
return(unpack(to, from));
memcpy(to, from, param_data > length ? length : len);
return from+len;
}
@ -2814,10 +2878,15 @@ uint Field_new_decimal::is_equal(Create_field *new_field)
@return New pointer into memory based on from + length of the data
*/
const uchar *Field_new_decimal::unpack(uchar* to,
const uchar *from,
uint param_data)
const uchar *
Field_new_decimal::unpack(uchar* to,
const uchar *from,
uint param_data,
bool low_byte_first)
{
if (param_data == 0)
return Field::unpack(to, from, param_data, low_byte_first);
uint from_precision= (param_data & 0xff00) >> 8U;
uint from_decimal= param_data & 0x00ff;
uint length=pack_length();
@ -3959,6 +4028,49 @@ void Field_longlong::sql_type(String &res) const
}
/*
Floating-point numbers
*/
uchar *
Field_real::pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first)
{
DBUG_ENTER("Field_real::pack");
DBUG_ASSERT(max_length >= pack_length());
DBUG_PRINT("debug", ("pack_length(): %u", pack_length()));
#ifdef WORDS_BIGENDIAN
if (low_byte_first != table->s->db_low_byte_first)
{
const uchar *dptr= from + pack_length();
while (dptr-- > from)
*to++ = *dptr;
DBUG_RETURN(to);
}
else
#endif
DBUG_RETURN(Field::pack(to, from, max_length, low_byte_first));
}
const uchar *
Field_real::unpack(uchar *to, const uchar *from,
uint param_data, bool low_byte_first)
{
DBUG_ENTER("Field_real::unpack");
DBUG_PRINT("debug", ("pack_length(): %u", pack_length()));
#ifdef WORDS_BIGENDIAN
if (low_byte_first != table->s->db_low_byte_first)
{
const uchar *dptr= from + pack_length();
while (dptr-- > from)
*to++ = *dptr;
DBUG_RETURN(from + pack_length());
}
else
#endif
DBUG_RETURN(Field::unpack(to, from, param_data, low_byte_first));
}
/****************************************************************************
single precision float
****************************************************************************/
@ -6363,6 +6475,11 @@ int Field_longstr::store_decimal(const my_decimal *d)
return store(str.ptr(), str.length(), str.charset());
}
uint32 Field_longstr::max_data_length() const
{
return field_length + (field_length > 255 ? 2 : 1);
}
double Field_string::val_real(void)
{
@ -6507,7 +6624,9 @@ void Field_string::sql_type(String &res) const
}
uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
uchar *Field_string::pack(uchar *to, const uchar *from,
uint max_length,
bool low_byte_first __attribute__((unused)))
{
uint length= min(field_length,max_length);
uint local_char_length= max_length/field_charset->mbmaxlen;
@ -6515,11 +6634,15 @@ uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
local_char_length= my_charpos(field_charset, from, from+length,
local_char_length);
set_if_smaller(length, local_char_length);
while (length && from[length-1] == ' ')
while (length && from[length-1] == field_charset->pad_char)
length--;
// Length always stored little-endian
*to++= (uchar) length;
if (field_length > 255)
*to++= (uchar) (length >> 8);
// Store the actual bytes of the string
memcpy(to, from, length);
return to+length;
}
@ -6541,34 +6664,27 @@ uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length)
@return New pointer into memory based on from + length of the data
*/
const uchar *Field_string::unpack(uchar *to,
const uchar *from,
uint param_data)
{
uint from_len= param_data & 0x00ff; // length.
uint length= 0;
uint f_length;
f_length= (from_len < field_length) ? from_len : field_length;
DBUG_ASSERT(f_length <= 255);
length= (uint) *from++;
bitmap_set_bit(table->write_set,field_index);
store((const char *)from, length, system_charset_info);
return from+length;
}
const uchar *Field_string::unpack(uchar *to, const uchar *from)
const uchar *
Field_string::unpack(uchar *to,
const uchar *from,
uint param_data,
bool low_byte_first __attribute__((unused)))
{
uint from_length=
param_data ? min(param_data & 0x00ff, field_length) : field_length;
uint length;
if (field_length > 255)
if (from_length > 255)
{
length= uint2korr(from);
from+= 2;
}
else
length= (uint) *from++;
memcpy(to, from, (int) length);
bfill(to+length, field_length - length, ' ');
memcpy(to, from, length);
// Pad the string with the pad character of the fields charset
bfill(to + length, field_length - length, field_charset->pad_char);
return from+length;
}
@ -6758,6 +6874,7 @@ const uint Field_varstring::MAX_SIZE= UINT_MAX16;
int Field_varstring::do_save_field_metadata(uchar *metadata_ptr)
{
char *ptr= (char *)metadata_ptr;
DBUG_ASSERT(field_length <= 65535);
int2store(ptr, field_length);
return 2;
}
@ -6985,22 +7102,30 @@ uint32 Field_varstring::data_length()
Here the number of length bytes are depending on the given max_length
*/
uchar *Field_varstring::pack(uchar *to, const uchar *from, uint max_length)
uchar *Field_varstring::pack(uchar *to, const uchar *from,
uint max_length,
bool low_byte_first __attribute__((unused)))
{
uint length= length_bytes == 1 ? (uint) *from : uint2korr(from);
set_if_smaller(max_length, field_length);
if (length > max_length)
length=max_length;
*to++= (char) (length & 255);
/* Length always stored little-endian */
*to++= length & 0xFF;
if (max_length > 255)
*to++= (char) (length >> 8);
if (length)
*to++= (length >> 8) & 0xFF;
/* Store bytes of string */
if (length > 0)
memcpy(to, from+length_bytes, length);
return to+length;
}
uchar *Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length)
uchar *
Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
bool low_byte_first __attribute__((unused)))
{
uint length= length_bytes == 1 ? (uint) *key : uint2korr(key);
uint local_char_length= ((field_charset->mbmaxlen > 1) ?
@ -7039,8 +7164,9 @@ uchar *Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length)
Pointer to end of 'key' (To the next key part if multi-segment key)
*/
const uchar *Field_varstring::unpack_key(uchar *to, const uchar *key,
uint max_length)
const uchar *
Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
bool low_byte_first __attribute__((unused)))
{
/* get length of the blob key */
uint32 length= *key++;
@ -7069,8 +7195,9 @@ const uchar *Field_varstring::unpack_key(uchar *to, const uchar *key,
end of key storage
*/
uchar *Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from,
uint max_length)
uchar *
Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
bool low_byte_first __attribute__((unused)))
{
/* Key length is always stored as 2 bytes */
uint length= uint2korr(from);
@ -7090,6 +7217,9 @@ uchar *Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from,
This method is used to unpack a varstring field from a master
whose size of the field is less than that of the slave.
@note
The string length is always packed little-endian.
@param to Destination of the data
@param from Source of the data
@ -7097,9 +7227,10 @@ uchar *Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from,
@return New pointer into memory based on from + length of the data
*/
const uchar *Field_varstring::unpack(uchar *to,
const uchar *from,
uint param_data)
const uchar *
Field_varstring::unpack(uchar *to, const uchar *from,
uint param_data,
bool low_byte_first __attribute__((unused)))
{
uint length;
uint l_bytes= (param_data && (param_data < field_length)) ?
@ -7111,28 +7242,7 @@ const uchar *Field_varstring::unpack(uchar *to,
if (length_bytes == 2)
to[1]= 0;
}
else
{
length= uint2korr(from);
to[0]= *from++;
to[1]= *from++;
}
if (length)
memcpy(to+ length_bytes, from, length);
return from+length;
}
/*
unpack field packed with Field_varstring::pack()
*/
const uchar *Field_varstring::unpack(uchar *to, const uchar *from)
{
uint length;
if (length_bytes == 1)
length= (uint) (*to= *from++);
else
else /* l_bytes == 2 */
{
length= uint2korr(from);
to[0]= *from++;
@ -7381,9 +7491,9 @@ void Field_blob::store_length(uchar *i_ptr,
}
uint32 Field_blob::get_length(const uchar *pos, bool low_byte_first)
uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg, bool low_byte_first)
{
switch (packlength) {
switch (packlength_arg) {
case 1:
return (uint32) pos[0];
case 2:
@ -7814,26 +7924,37 @@ void Field_blob::sql_type(String &res) const
}
}
uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length)
uchar *Field_blob::pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first)
{
DBUG_ENTER("Field_blob::pack");
DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx;"
" max_length: %u; low_byte_first: %d",
(ulong) to, (ulong) from,
max_length, low_byte_first));
DBUG_DUMP("record", from, table->s->reclength);
uchar *save= ptr;
ptr= (uchar*) from;
uint32 length=get_length(); // Length of from string
if (length > max_length)
{
length=max_length;
store_length(to,packlength,length,TRUE);
}
else
memcpy(to,from,packlength); // Copy length
if (length)
/*
Store max length, which will occupy packlength bytes. If the max
length given is smaller than the actual length of the blob, we
just store the initial bytes of the blob.
*/
store_length(to, packlength, min(length, max_length), low_byte_first);
/*
Store the actual blob data, which will occupy 'length' bytes.
*/
if (length > 0)
{
get_ptr((uchar**) &from);
memcpy(to+packlength, from,length);
}
ptr=save; // Restore org row pointer
return to+packlength+length;
DBUG_DUMP("packed", to, packlength + length);
DBUG_RETURN(to+packlength+length);
}
@ -7848,28 +7969,30 @@ uchar *Field_blob::pack(uchar *to, const uchar *from, uint max_length)
@param to Destination of the data
@param from Source of the data
@param param_data not used
@param param_data @c TRUE if base types should be stored in little-
endian format, @c FALSE if native format should
be used.
@return New pointer into memory based on from + length of the data
*/
const uchar *Field_blob::unpack(uchar *to,
const uchar *from,
uint param_data)
uint param_data,
bool low_byte_first)
{
return unpack(to, from);
}
const uchar *Field_blob::unpack(uchar *to, const uchar *from)
{
uint32 length=get_length(from);
memcpy(to,from,packlength);
from+=packlength;
if (length)
memcpy_fixed(to+packlength, &from, sizeof(from));
else
bzero(to+packlength,sizeof(from));
return from+length;
DBUG_ENTER("Field_blob::unpack");
DBUG_PRINT("enter", ("to: 0x%lx; from: 0x%lx;"
" param_data: %u; low_byte_first: %d",
(ulong) to, (ulong) from, param_data, low_byte_first));
uint const master_packlength=
param_data > 0 ? param_data & 0xFF : packlength;
uint32 const length= get_length(from, master_packlength, low_byte_first);
DBUG_DUMP("packed", from, length + master_packlength);
bitmap_set_bit(table->write_set, field_index);
store(reinterpret_cast<const char*>(from) + master_packlength,
length, field_charset);
DBUG_DUMP("record", to, table->s->reclength);
DBUG_RETURN(from + master_packlength + length);
}
/* Keys for blobs are like keys on varchars */
@ -7919,7 +8042,9 @@ int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
/* Create a packed key that will be used for storage from a MySQL row */
uchar *Field_blob::pack_key(uchar *to, const uchar *from, uint max_length)
uchar *
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
bool low_byte_first __attribute__((unused)))
{
uchar *save= ptr;
ptr= (uchar*) from;
@ -7964,8 +8089,9 @@ uchar *Field_blob::pack_key(uchar *to, const uchar *from, uint max_length)
Pointer into 'from' past the last byte copied from packed key.
*/
const uchar *Field_blob::unpack_key(uchar *to, const uchar *from,
uint max_length)
const uchar *
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
bool low_byte_first __attribute__((unused)))
{
/* get length of the blob key */
uint32 length= *from++;
@ -7988,8 +8114,9 @@ const uchar *Field_blob::unpack_key(uchar *to, const uchar *from,
/* Create a packed key that will be used for storage from a MySQL key */
uchar *Field_blob::pack_key_from_key_image(uchar *to, const uchar *from,
uint max_length)
uchar *
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
bool low_byte_first __attribute__((unused)))
{
uint length=uint2korr(from);
if (length > max_length)
@ -8936,9 +9063,11 @@ void Field_bit::sql_type(String &res) const
}
uchar *Field_bit::pack(uchar *to, const uchar *from, uint max_length)
uchar *
Field_bit::pack(uchar *to, const uchar *from, uint max_length,
bool low_byte_first __attribute__((unused)))
{
DBUG_ASSERT(max_length);
DBUG_ASSERT(max_length > 0);
uint length;
if (bit_len > 0)
{
@ -8973,28 +9102,44 @@ uchar *Field_bit::pack(uchar *to, const uchar *from, uint max_length)
/**
Unpack a bit field from row data.
This method is used to unpack a bit field from a master whose size
This method is used to unpack a bit field from a master whose size
of the field is less than that of the slave.
@param to Destination of the data
@param from Source of the data
@param param_data Bit length (upper) and length (lower) values
@return New pointer into memory based on from + length of the data
*/
const uchar *Field_bit::unpack(uchar *to,
const uchar *from,
uint param_data)
const uchar *
Field_bit::unpack(uchar *to, const uchar *from, uint param_data,
bool low_byte_first __attribute__((unused)))
{
uint const from_len= (param_data >> 8U) & 0x00ff;
uint const from_bit_len= param_data & 0x00ff;
/*
If the master and slave have the same sizes, then use the old
unpack() method.
If the parameter data is zero (i.e., undefined), or if the master
and slave have the same sizes, then use the old unpack() method.
*/
if ((from_bit_len == bit_len) &&
(from_len == bytes_in_rec))
return(unpack(to, from));
if (param_data == 0 ||
(from_bit_len == bit_len) && (from_len == bytes_in_rec))
{
if (bit_len > 0)
{
/*
set_rec_bits is a macro, don't put the post-increment in the
argument since that might cause strange side-effects.
For the choice of the second argument, see the explanation for
Field_bit::pack().
*/
set_rec_bits(*from, bit_ptr + (to - ptr), bit_ofs, bit_len);
from++;
}
memcpy(to, from, bytes_in_rec);
return from + bytes_in_rec;
}
/*
We are converting a smaller bit field to a larger one here.
To do that, we first need to construct a raw value for the original
@ -9022,25 +9167,6 @@ const uchar *Field_bit::unpack(uchar *to,
}
const uchar *Field_bit::unpack(uchar *to, const uchar *from)
{
if (bit_len > 0)
{
/*
set_rec_bits is a macro, don't put the post-increment in the
argument since that might cause strange side-effects.
For the choice of the second argument, see the explanation for
Field_bit::pack().
*/
set_rec_bits(*from, bit_ptr + (to - ptr), bit_ofs, bit_len);
from++;
}
memcpy(to, from, bytes_in_rec);
return from + bytes_in_rec;
}
void Field_bit::set_default()
{
if (bit_len > 0)

View File

@ -175,6 +175,17 @@ public:
*/
virtual uint32 data_length() { return pack_length(); }
virtual uint32 sort_length() const { return pack_length(); }
/**
Get the maximum size of the data in packed format.
@return Maximum data length of the field when packed using the
Field::pack() function.
*/
virtual uint32 max_data_length() const {
return pack_length();
};
virtual int reset(void) { bzero(ptr,pack_length()); return 0; }
virtual void reset_fields() {}
virtual void set_default()
@ -357,32 +368,45 @@ public:
return str;
}
virtual bool send_binary(Protocol *protocol);
virtual uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0)
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
/**
@overload Field::pack(uchar*, const uchar*, uint, bool)
*/
uchar *pack(uchar *to, const uchar *from)
{
uint32 length=pack_length();
memcpy(to,from,length);
return to+length;
DBUG_ENTER("Field::pack");
uchar *result= this->pack(to, from, UINT_MAX, table->s->db_low_byte_first);
DBUG_RETURN(result);
}
virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data);
virtual const uchar *unpack(uchar* to, const uchar *from)
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
/**
@overload Field::unpack(uchar*, const uchar*, uint, bool)
*/
const uchar *unpack(uchar* to, const uchar *from)
{
uint length=pack_length();
memcpy(to,from,length);
return from+length;
DBUG_ENTER("Field::unpack");
const uchar *result= unpack(to, from, 0U, table->s->db_low_byte_first);
DBUG_RETURN(result);
}
virtual uchar *pack_key(uchar* to, const uchar *from, uint max_length)
virtual uchar *pack_key(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
return pack(to,from,max_length);
return pack(to, from, max_length, low_byte_first);
}
virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from,
uint max_length)
uint max_length, bool low_byte_first)
{
return pack(to,from,max_length);
return pack(to, from, max_length, low_byte_first);
}
virtual const uchar *unpack_key(uchar* to, const uchar *from,
uint max_length)
uint max_length, bool low_byte_first)
{
return unpack(to,from);
return unpack(to, from, max_length, low_byte_first);
}
virtual uint packed_col_length(const uchar *to, uint length)
{ return length;}
@ -567,6 +591,7 @@ public:
{}
int store_decimal(const my_decimal *d);
uint32 max_data_length() const;
};
/* base class for float and double and decimal (old one) */
@ -587,6 +612,10 @@ public:
int truncate(double *nr, double max_length);
uint32 max_display_length() { return field_length; }
uint size_of() const { return sizeof(*this); }
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first);
};
@ -615,6 +644,16 @@ public:
void overflow(bool negative);
bool zero_pack() const { return 0; }
void sql_type(String &str) const;
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
return Field::unpack(to, from, param_data, low_byte_first);
}
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
return Field::pack(to, from, max_length, low_byte_first);
}
};
@ -665,7 +704,8 @@ public:
uint row_pack_length() { return pack_length(); }
int compatible_field_size(uint field_metadata);
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
};
@ -696,6 +736,20 @@ public:
uint32 pack_length() const { return 1; }
void sql_type(String &str) const;
uint32 max_display_length() { return 4; }
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
*to= *from;
return to + 1;
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
*to= *from;
return from + 1;
}
};
@ -731,8 +785,47 @@ public:
uint32 pack_length() const { return 2; }
void sql_type(String &str) const;
uint32 max_display_length() { return 6; }
};
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
int16 val;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
val = sint2korr(from);
else
#endif
shortget(val, from);
#ifdef WORDS_BIGENDIAN
if (low_byte_first)
int2store(to, val);
else
#endif
shortstore(to, val);
return to + sizeof(val);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
int16 val;
#ifdef WORDS_BIGENDIAN
if (low_byte_first)
val = sint2korr(from);
else
#endif
shortget(val, from);
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
int2store(to, val);
else
#endif
shortstore(to, val);
return from + sizeof(val);
}
};
class Field_medium :public Field_num {
public:
@ -761,6 +854,18 @@ public:
uint32 pack_length() const { return 3; }
void sql_type(String &str) const;
uint32 max_display_length() { return 8; }
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
return Field::pack(to, from, max_length, low_byte_first);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
return Field::unpack(to, from, param_data, low_byte_first);
}
};
@ -796,6 +901,45 @@ public:
uint32 pack_length() const { return 4; }
void sql_type(String &str) const;
uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; }
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
int32 val;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
val = sint4korr(from);
else
#endif
longget(val, from);
#ifdef WORDS_BIGENDIAN
if (low_byte_first)
int4store(to, val);
else
#endif
longstore(to, val);
return to + sizeof(val);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
int32 val;
#ifdef WORDS_BIGENDIAN
if (low_byte_first)
val = sint4korr(from);
else
#endif
longget(val, from);
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
int4store(to, val);
else
#endif
longstore(to, val);
return from + sizeof(val);
}
};
@ -838,6 +982,45 @@ public:
void sql_type(String &str) const;
bool can_be_compared_as_longlong() const { return TRUE; }
uint32 max_display_length() { return 20; }
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
int64 val;
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
val = sint8korr(from);
else
#endif
longlongget(val, from);
#ifdef WORDS_BIGENDIAN
if (low_byte_first)
int8store(to, val);
else
#endif
longlongstore(to, val);
return to + sizeof(val);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
int64 val;
#ifdef WORDS_BIGENDIAN
if (low_byte_first)
val = sint8korr(from);
else
#endif
longlongget(val, from);
#ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first)
int8store(to, val);
else
#endif
longlongstore(to, val);
return from + sizeof(val);
}
};
#endif
@ -1218,9 +1401,10 @@ public:
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
void sql_type(String &str) const;
uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0);
virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data);
const uchar *unpack(uchar* to, const uchar *from);
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
uint pack_length_from_metadata(uint field_metadata)
{ return (field_metadata & 0x00ff); }
uint row_pack_length() { return (field_length + 1); }
@ -1298,13 +1482,15 @@ public:
uint get_key_image(uchar *buff,uint length, imagetype type);
void set_key_image(const uchar *buff,uint length);
void sql_type(String &str) const;
uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0);
uchar *pack_key(uchar *to, const uchar *from, uint max_length);
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
uchar *pack_key(uchar *to, const uchar *from, uint max_length, bool low_byte_first);
uchar *pack_key_from_key_image(uchar* to, const uchar *from,
uint max_length);
virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data);
const uchar *unpack(uchar* to, const uchar *from);
const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
uint max_length, bool low_byte_first);
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first);
const uchar *unpack_key(uchar* to, const uchar *from,
uint max_length, bool low_byte_first);
int pack_cmp(const uchar *a, const uchar *b, uint key_length,
my_bool insert_or_update);
int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
@ -1397,7 +1583,7 @@ public:
{ return (uint32) (packlength); }
uint row_pack_length() { return pack_length_no_ptr(); }
uint32 sort_length() const;
inline uint32 max_data_length() const
virtual uint32 max_data_length() const
{
return (uint32) (((ulonglong) 1 << (packlength*8)) -1);
}
@ -1425,13 +1611,13 @@ public:
@returns The length in the row plus the size of the data.
*/
uint32 get_packed_size(const uchar *ptr_arg, bool low_byte_first)
{return packlength + get_length(ptr_arg, low_byte_first);}
{return packlength + get_length(ptr_arg, packlength, low_byte_first);}
inline uint32 get_length(uint row_offset= 0)
{ return get_length(ptr+row_offset, table->s->db_low_byte_first); }
uint32 get_length(const uchar *ptr, bool low_byte_first);
{ return get_length(ptr+row_offset, this->packlength, table->s->db_low_byte_first); }
uint32 get_length(const uchar *ptr, uint packlength, bool low_byte_first);
uint32 get_length(const uchar *ptr_arg)
{ return get_length(ptr_arg, table->s->db_low_byte_first); }
{ return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first); }
void put_length(uchar *pos, uint32 length);
inline void get_ptr(uchar **str)
{
@ -1472,13 +1658,16 @@ public:
memcpy_fixed(ptr+packlength,&tmp,sizeof(char*));
return 0;
}
uchar *pack(uchar *to, const uchar *from, uint max_length= ~(uint) 0);
uchar *pack_key(uchar *to, const uchar *from, uint max_length);
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
uchar *pack_key(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
uchar *pack_key_from_key_image(uchar* to, const uchar *from,
uint max_length);
virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data);
const uchar *unpack(uchar *to, const uchar *from);
const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
uint max_length, bool low_byte_first);
virtual const uchar *unpack(uchar *to, const uchar *from,
uint param_data, bool low_byte_first);
const uchar *unpack_key(uchar* to, const uchar *from,
uint max_length, bool low_byte_first);
int pack_cmp(const uchar *a, const uchar *b, uint key_length,
my_bool insert_or_update);
int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update);
@ -1630,6 +1819,7 @@ public:
enum_field_types type() const { return MYSQL_TYPE_BIT; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
uint32 max_data_length() const { return (field_length + 7) / 8; }
uint32 max_display_length() { return field_length; }
uint size_of() const { return sizeof(*this); }
Item_result result_type () const { return INT_RESULT; }
@ -1671,9 +1861,10 @@ public:
{ return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); }
int compatible_field_size(uint field_metadata);
void sql_type(String &str) const;
uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0);
virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data);
const uchar *unpack(uchar* to, const uchar *from);
virtual uchar *pack(uchar *to, const uchar *from,
uint max_length, bool low_byte_first);
virtual const uchar *unpack(uchar *to, const uchar *from,
uint param_data, bool low_byte_first);
virtual void set_default();
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,

View File

@ -411,7 +411,7 @@ Ndb *ha_ndbcluster::get_ndb()
void ha_ndbcluster::set_rec_per_key()
{
DBUG_ENTER("ha_ndbcluster::get_status_const");
DBUG_ENTER("ha_ndbcluster::set_rec_per_key");
for (uint i=0 ; i < table_share->keys ; i++)
{
table->key_info[i].rec_per_key[table->key_info[i].key_parts-1]= 1;
@ -558,7 +558,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
THD *thd= current_thd;
int res;
NdbError err= trans->getNdbError();
DBUG_ENTER("ndb_err");
DBUG_ENTER("ha_ndbcluster::ndb_err");
set_ndb_err(thd, err);
@ -695,7 +695,7 @@ static bool field_type_forces_var_part(enum_field_types type)
bool ha_ndbcluster::set_hidden_key(NdbOperation *ndb_op,
uint fieldnr, const uchar *field_ptr)
{
DBUG_ENTER("set_hidden_key");
DBUG_ENTER("ha_ndbcluster::set_hidden_key");
DBUG_RETURN(ndb_op->equal(fieldnr, (char*)field_ptr) != 0);
}
@ -708,7 +708,7 @@ int ha_ndbcluster::set_ndb_key(NdbOperation *ndb_op, Field *field,
uint fieldnr, const uchar *field_ptr)
{
uint32 pack_len= field->pack_length();
DBUG_ENTER("set_ndb_key");
DBUG_ENTER("ha_ndbcluster::set_ndb_key");
DBUG_PRINT("enter", ("%d: %s, ndb_type: %u, len=%d",
fieldnr, field->field_name, field->type(),
pack_len));
@ -731,7 +731,7 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
{
const uchar* field_ptr= field->ptr + row_offset;
uint32 pack_len= field->pack_length();
DBUG_ENTER("set_ndb_value");
DBUG_ENTER("ha_ndbcluster::set_ndb_value");
DBUG_PRINT("enter", ("%d: %s type: %u len=%d is_null=%s",
fieldnr, field->field_name, field->type(),
pack_len, field->is_null(row_offset) ? "Y" : "N"));
@ -934,7 +934,7 @@ int get_ndb_blobs_value(TABLE* table, NdbValue* value_array,
int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field,
uint fieldnr, uchar* buf)
{
DBUG_ENTER("get_ndb_value");
DBUG_ENTER("ha_ndbcluster::get_ndb_value");
DBUG_PRINT("enter", ("fieldnr: %d flags: %o", fieldnr,
(int)(field != NULL ? field->flags : 0)));
@ -985,7 +985,7 @@ int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field,
*/
int ha_ndbcluster::get_ndb_partition_id(NdbOperation *ndb_op)
{
DBUG_ENTER("get_ndb_partition_id");
DBUG_ENTER("ha_ndbcluster::get_ndb_partition_id");
DBUG_RETURN(ndb_op->getValue(NdbDictionary::Column::FRAGMENT,
(char *)&m_part_id) == NULL);
}
@ -1044,7 +1044,7 @@ int ha_ndbcluster::get_metadata(const char *path)
NDBDICT *dict= ndb->getDictionary();
const NDBTAB *tab;
int error;
DBUG_ENTER("get_metadata");
DBUG_ENTER("ha_ndbcluster::get_metadata");
DBUG_PRINT("enter", ("m_tabname: %s, path: %s", m_tabname, path));
DBUG_ASSERT(m_table == NULL);
@ -1463,7 +1463,7 @@ void ha_ndbcluster::release_metadata(THD *thd, Ndb *ndb)
{
uint i;
DBUG_ENTER("release_metadata");
DBUG_ENTER("ha_ndbcluster::release_metadata");
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
NDBDICT *dict= ndb->getDictionary();
@ -1604,7 +1604,7 @@ int ha_ndbcluster::set_primary_key(NdbOperation *op, const uchar *key)
KEY* key_info= table->key_info + table_share->primary_key;
KEY_PART_INFO* key_part= key_info->key_part;
KEY_PART_INFO* end= key_part+key_info->key_parts;
DBUG_ENTER("set_primary_key");
DBUG_ENTER("ha_ndbcluster::set_primary_key");
for (; key_part != end; key_part++)
{
@ -1626,7 +1626,7 @@ int ha_ndbcluster::set_primary_key_from_record(NdbOperation *op, const uchar *re
KEY* key_info= table->key_info + table_share->primary_key;
KEY_PART_INFO* key_part= key_info->key_part;
KEY_PART_INFO* end= key_part+key_info->key_parts;
DBUG_ENTER("set_primary_key_from_record");
DBUG_ENTER("ha_ndbcluster::set_primary_key_from_record");
for (; key_part != end; key_part++)
{
@ -1645,7 +1645,7 @@ int ha_ndbcluster::set_index_key_from_record(NdbOperation *op,
KEY_PART_INFO* key_part= key_info->key_part;
KEY_PART_INFO* end= key_part+key_info->key_parts;
uint i;
DBUG_ENTER("set_index_key_from_record");
DBUG_ENTER("ha_ndbcluster::set_index_key_from_record");
for (i= 0; key_part != end; key_part++, i++)
{
@ -1684,7 +1684,7 @@ inline
int ha_ndbcluster::define_read_attrs(uchar* buf, NdbOperation* op)
{
uint i;
DBUG_ENTER("define_read_attrs");
DBUG_ENTER("ha_ndbcluster::define_read_attrs");
// Define attributes to read
for (i= 0; i < table_share->fields; i++)
@ -1731,7 +1731,7 @@ int ha_ndbcluster::pk_read(const uchar *key, uint key_len, uchar *buf,
NdbOperation *op;
int res;
DBUG_ENTER("pk_read");
DBUG_ENTER("ha_ndbcluster::pk_read");
DBUG_PRINT("enter", ("key_len: %u", key_len));
DBUG_DUMP("key", key, key_len);
m_write_op= FALSE;
@ -1798,7 +1798,7 @@ int ha_ndbcluster::complemented_read(const uchar *old_data, uchar *new_data,
uint no_fields= table_share->fields, i;
NdbTransaction *trans= m_active_trans;
NdbOperation *op;
DBUG_ENTER("complemented_read");
DBUG_ENTER("ha_ndbcluster::complemented_read");
m_write_op= FALSE;
if (bitmap_is_set_all(table->read_set))
@ -1964,7 +1964,7 @@ int ha_ndbcluster::peek_indexed_rows(const uchar *record,
const NdbOperation *first, *last;
uint i;
int res;
DBUG_ENTER("peek_indexed_rows");
DBUG_ENTER("ha_ndbcluster::peek_indexed_rows");
NdbOperation::LockMode lm=
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
@ -2104,7 +2104,7 @@ int ha_ndbcluster::unique_index_read(const uchar *key,
inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor)
{
DBUG_ENTER("fetch_next");
DBUG_ENTER("ha_ndbcluster::fetch_next");
int local_check;
NdbTransaction *trans= m_active_trans;
@ -2213,7 +2213,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor)
inline int ha_ndbcluster::next_result(uchar *buf)
{
int res;
DBUG_ENTER("next_result");
DBUG_ENTER("ha_ndbcluster::next_result");
if (!m_active_cursor)
DBUG_RETURN(HA_ERR_END_OF_FILE);
@ -2256,7 +2256,7 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op,
uint tot_len;
uint i, j;
DBUG_ENTER("set_bounds");
DBUG_ENTER("ha_ndbcluster::set_bounds");
DBUG_PRINT("info", ("key_parts=%d", key_parts));
for (j= 0; j <= 1; j++)
@ -2543,7 +2543,7 @@ int ha_ndbcluster::unique_index_scan(const KEY* key_info,
NdbTransaction *trans= m_active_trans;
part_id_range part_spec;
DBUG_ENTER("unique_index_scan");
DBUG_ENTER("ha_ndbcluster::unique_index_scan");
DBUG_PRINT("enter", ("Starting new scan on %s", m_tabname));
NdbOperation::LockMode lm=
@ -2617,7 +2617,7 @@ int ha_ndbcluster::full_table_scan(uchar *buf)
NdbTransaction *trans= m_active_trans;
part_id_range part_spec;
DBUG_ENTER("full_table_scan");
DBUG_ENTER("ha_ndbcluster::full_table_scan");
DBUG_PRINT("enter", ("Starting new scan on %s", m_tabname));
m_write_op= FALSE;
@ -2950,7 +2950,7 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
longlong func_value;
bool pk_update= (table_share->primary_key != MAX_KEY &&
key_cmp(table_share->primary_key, old_data, new_data));
DBUG_ENTER("update_row");
DBUG_ENTER("ha_ndbcluster::update_row");
m_write_op= TRUE;
/*
@ -3154,7 +3154,7 @@ int ha_ndbcluster::delete_row(const uchar *record)
NdbOperation *op;
uint32 part_id;
int error;
DBUG_ENTER("delete_row");
DBUG_ENTER("ha_ndbcluster::delete_row");
m_write_op= TRUE;
ha_statistic_increment(&SSV::ha_delete_count);
@ -3434,7 +3434,7 @@ void ha_ndbcluster::unpack_record(uchar *buf)
void ha_ndbcluster::print_results()
{
DBUG_ENTER("print_results");
DBUG_ENTER("ha_ndbcluster::print_results");
#ifndef DBUG_OFF
@ -3701,7 +3701,7 @@ int ha_ndbcluster::read_range_next()
int ha_ndbcluster::rnd_init(bool scan)
{
NdbScanOperation *cursor= m_active_cursor;
DBUG_ENTER("rnd_init");
DBUG_ENTER("ha_ndbcluster::rnd_init");
DBUG_PRINT("enter", ("scan: %d", scan));
// Check if scan is to be restarted
if (cursor)
@ -3721,7 +3721,7 @@ int ha_ndbcluster::rnd_init(bool scan)
int ha_ndbcluster::close_scan()
{
NdbTransaction *trans= m_active_trans;
DBUG_ENTER("close_scan");
DBUG_ENTER("ha_ndbcluster::close_scan");
m_multi_cursor= 0;
if (!m_active_cursor && !m_multi_cursor)
@ -3770,14 +3770,14 @@ int ha_ndbcluster::close_scan()
int ha_ndbcluster::rnd_end()
{
DBUG_ENTER("rnd_end");
DBUG_ENTER("ha_ndbcluster::rnd_end");
DBUG_RETURN(close_scan());
}
int ha_ndbcluster::rnd_next(uchar *buf)
{
DBUG_ENTER("rnd_next");
DBUG_ENTER("ha_ndbcluster::rnd_next");
ha_statistic_increment(&SSV::ha_read_rnd_next_count);
if (!m_active_cursor)
@ -3795,7 +3795,7 @@ int ha_ndbcluster::rnd_next(uchar *buf)
int ha_ndbcluster::rnd_pos(uchar *buf, uchar *pos)
{
DBUG_ENTER("rnd_pos");
DBUG_ENTER("ha_ndbcluster::rnd_pos");
ha_statistic_increment(&SSV::ha_read_rnd_count);
// The primary key for the record is stored in pos
// Perform a pk_read using primary key "index"
@ -3847,7 +3847,7 @@ void ha_ndbcluster::position(const uchar *record)
uchar *buff;
uint key_length;
DBUG_ENTER("position");
DBUG_ENTER("ha_ndbcluster::position");
if (table_share->primary_key != MAX_KEY)
{
@ -3931,7 +3931,7 @@ void ha_ndbcluster::position(const uchar *record)
int ha_ndbcluster::info(uint flag)
{
int result= 0;
DBUG_ENTER("info");
DBUG_ENTER("ha_ndbcluster::info");
DBUG_PRINT("enter", ("flag: %d", flag));
if (flag & HA_STATUS_POS)
@ -4032,7 +4032,7 @@ void ha_ndbcluster::get_dynamic_partition_info(PARTITION_INFO *stat_info,
int ha_ndbcluster::extra(enum ha_extra_function operation)
{
DBUG_ENTER("extra");
DBUG_ENTER("ha_ndbcluster::extra");
switch (operation) {
case HA_EXTRA_IGNORE_DUP_KEY: /* Dup keys don't rollback everything*/
DBUG_PRINT("info", ("HA_EXTRA_IGNORE_DUP_KEY"));
@ -4125,7 +4125,7 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows)
int bytes, batch;
const NDBTAB *tab= m_table;
DBUG_ENTER("start_bulk_insert");
DBUG_ENTER("ha_ndbcluster::start_bulk_insert");
DBUG_PRINT("enter", ("rows: %d", (int)rows));
m_rows_inserted= (ha_rows) 0;
@ -4174,7 +4174,7 @@ int ha_ndbcluster::end_bulk_insert()
{
int error= 0;
DBUG_ENTER("end_bulk_insert");
DBUG_ENTER("ha_ndbcluster::end_bulk_insert");
// Check if last inserts need to be flushed
if (m_bulk_insert_not_flushed)
{
@ -4215,7 +4215,7 @@ int ha_ndbcluster::end_bulk_insert()
int ha_ndbcluster::extra_opt(enum ha_extra_function operation, ulong cache_size)
{
DBUG_ENTER("extra_opt");
DBUG_ENTER("ha_ndbcluster::extra_opt");
DBUG_PRINT("enter", ("cache_size: %lu", cache_size));
DBUG_RETURN(extra(operation));
}
@ -4257,7 +4257,7 @@ THR_LOCK_DATA **ha_ndbcluster::store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)
{
DBUG_ENTER("store_lock");
DBUG_ENTER("ha_ndbcluster::store_lock");
if (lock_type != TL_IGNORE && m_lock.type == TL_UNLOCK)
{
@ -4375,7 +4375,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
{
int error=0;
NdbTransaction* trans= NULL;
DBUG_ENTER("external_lock");
DBUG_ENTER("ha_ndbcluster::external_lock");
/*
Check that this handler instance has a connection
@ -4591,7 +4591,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
void ha_ndbcluster::unlock_row()
{
DBUG_ENTER("unlock_row");
DBUG_ENTER("ha_ndbcluster::unlock_row");
DBUG_PRINT("info", ("Unlocking row"));
m_lock_tuple= FALSE;
@ -4609,7 +4609,7 @@ void ha_ndbcluster::unlock_row()
int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
{
int error=0;
DBUG_ENTER("start_stmt");
DBUG_ENTER("ha_ndbcluster::start_stmt");
PRINT_OPTION_FLAGS(thd);
Thd_ndb *thd_ndb= get_thd_ndb(thd);
@ -5446,7 +5446,7 @@ int ha_ndbcluster::create_handler_files(const char *file,
size_t length, pack_length;
int error= 0;
DBUG_ENTER("create_handler_files");
DBUG_ENTER("ha_ndbcluster::create_handler_files");
if (action_flag != CHF_INDEX_FLAG)
{
@ -6131,7 +6131,7 @@ void ha_ndbcluster::get_auto_increment(ulonglong offset, ulonglong increment,
{
int cache_size;
Uint64 auto_value;
DBUG_ENTER("get_auto_increment");
DBUG_ENTER("ha_ndbcluster::get_auto_increment");
DBUG_PRINT("enter", ("m_tabname: %s", m_tabname));
Ndb *ndb= get_ndb();
@ -6238,7 +6238,7 @@ ha_ndbcluster::ha_ndbcluster(handlerton *hton, TABLE_SHARE *table_arg):
{
int i;
DBUG_ENTER("ha_ndbcluster");
DBUG_ENTER("ha_ndbcluster::ha_ndbcluster");
m_tabname[0]= '\0';
m_dbname[0]= '\0';
@ -6271,7 +6271,7 @@ ha_ndbcluster::~ha_ndbcluster()
{
THD *thd= current_thd;
Ndb *ndb= thd ? check_ndb_in_thd(thd) : g_ndb;
DBUG_ENTER("~ha_ndbcluster");
DBUG_ENTER("ha_ndbcluster::~ha_ndbcluster");
if (m_share)
{
@ -6426,7 +6426,7 @@ void ha_ndbcluster::set_part_info(partition_info *part_info)
int ha_ndbcluster::close(void)
{
DBUG_ENTER("close");
DBUG_ENTER("ha_ndbcluster::close");
THD *thd= table->in_use;
Ndb *ndb= thd ? check_ndb_in_thd(thd) : g_ndb;
/* ndb_share reference handler free */
@ -6442,7 +6442,7 @@ int ha_ndbcluster::close(void)
Thd_ndb* ha_ndbcluster::seize_thd_ndb()
{
Thd_ndb *thd_ndb;
DBUG_ENTER("seize_thd_ndb");
DBUG_ENTER("ha_ndbcluster::seize_thd_ndb");
thd_ndb= new Thd_ndb();
if (thd_ndb == NULL)
@ -6468,7 +6468,7 @@ Thd_ndb* ha_ndbcluster::seize_thd_ndb()
void ha_ndbcluster::release_thd_ndb(Thd_ndb* thd_ndb)
{
DBUG_ENTER("release_thd_ndb");
DBUG_ENTER("ha_ndbcluster::release_thd_ndb");
delete thd_ndb;
DBUG_VOID_RETURN;
}
@ -6498,7 +6498,7 @@ Ndb* check_ndb_in_thd(THD* thd)
int ha_ndbcluster::check_ndb_connection(THD* thd)
{
Ndb *ndb;
DBUG_ENTER("check_ndb_connection");
DBUG_ENTER("ha_ndbcluster::check_ndb_connection");
if (!(ndb= check_ndb_in_thd(thd)))
DBUG_RETURN(HA_ERR_NO_CONNECTION);
@ -7549,7 +7549,7 @@ ha_ndbcluster::records_in_range(uint inx, key_range *min_key,
uint key_length= key_info->key_length;
NDB_INDEX_TYPE idx_type= get_index_type(inx);
DBUG_ENTER("records_in_range");
DBUG_ENTER("ha_ndbcluster::records_in_range");
// Prevent partial read of hash indexes by returning HA_POS_ERROR
if ((idx_type == UNIQUE_INDEX || idx_type == PRIMARY_KEY_INDEX) &&
((min_key && min_key->length < key_length) ||
@ -8509,7 +8509,7 @@ int ha_ndbcluster::write_ndb_file(const char *name)
bool error=1;
char path[FN_REFLEN];
DBUG_ENTER("write_ndb_file");
DBUG_ENTER("ha_ndbcluster::write_ndb_file");
DBUG_PRINT("enter", ("name: %s", name));
(void)strxnmov(path, FN_REFLEN-1,
@ -8553,7 +8553,7 @@ ha_ndbcluster::null_value_index_search(KEY_MULTI_RANGE *ranges,
KEY_MULTI_RANGE *end_range,
HANDLER_BUFFER *buffer)
{
DBUG_ENTER("null_value_index_search");
DBUG_ENTER("ha_ndbcluster::null_value_index_search");
KEY* key_info= table->key_info + active_index;
KEY_MULTI_RANGE *range= ranges;
ulong reclength= table->s->reclength;
@ -8948,7 +8948,7 @@ found_next:
int
ha_ndbcluster::setup_recattr(const NdbRecAttr* curr)
{
DBUG_ENTER("setup_recattr");
DBUG_ENTER("ha_ndbcluster::setup_recattr");
Field **field, **end;
NdbValue *value= m_value;
@ -9319,7 +9319,7 @@ const
COND*
ha_ndbcluster::cond_push(const COND *cond)
{
DBUG_ENTER("cond_push");
DBUG_ENTER("ha_ndbcluster::cond_push");
if (!m_cond)
m_cond= new ha_ndbcluster_cond;
if (!m_cond)
@ -9554,7 +9554,7 @@ int ha_ndbcluster::set_range_data(void *tab_ref, partition_info *part_info)
uint i;
int error= 0;
bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("set_range_data");
DBUG_ENTER("ha_ndbcluster::set_range_data");
if (!range_data)
{
@ -9593,7 +9593,7 @@ int ha_ndbcluster::set_list_data(void *tab_ref, partition_info *part_info)
uint32 *part_id, i;
int error= 0;
bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("set_list_data");
DBUG_ENTER("ha_ndbcluster::set_list_data");
if (!list_data)
{
@ -9924,7 +9924,7 @@ int ndbcluster_alter_tablespace(handlerton *hton,
int error;
const char *errmsg;
Ndb *ndb;
DBUG_ENTER("ha_ndbcluster::alter_tablespace");
DBUG_ENTER("alter_tablespace");
LINT_INIT(errmsg);
ndb= check_ndb_in_thd(thd);

View File

@ -4380,6 +4380,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(),
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)
{
@ -4396,35 +4441,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;
@ -4437,47 +4481,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;
}

View File

@ -1382,6 +1382,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) {}

View File

@ -2612,35 +2612,27 @@ typedef struct
uint level;
String *pxml; // parsed XML
uint pos[MAX_LEVEL]; // Tag position stack
uint parent; // Offset of the parent of the current node
} MY_XML_USER_DATA;
/*
Find the parent node
SYNOPSYS
Find the parent node, i.e. a tag or attrubute node on the given level.
RETURN
1 - success
0 - failure
*/
static uint xml_parent_tag(MY_XML_NODE *items, uint nitems, uint level)
static bool
append_node(String *str, MY_XML_NODE *node)
{
if (!nitems)
return 0;
MY_XML_NODE *p, *last= &items[nitems-1];
for (p= last; p >= items; p--)
{
if (p->level == level &&
(p->type == MY_XML_NODE_TAG ||
p->type == MY_XML_NODE_ATTR))
{
return p - items;
}
}
return 0;
/*
If "str" doesn't have space for a new node,
it will allocate two times more space that it has had so far.
(2*len+512) is a heuristic value,
which gave the best performance during tests.
The ideas behind this formula are:
- It allows to have a very small number of reallocs:
about 10 reallocs on a 1Mb-long XML value.
- At the same time, it avoids excessive memory use.
*/
if (str->reserve(sizeof(MY_XML_NODE), 2 * str->length() + 512))
return TRUE;
str->q_append((const char*) node, sizeof(MY_XML_NODE));
return FALSE;
}
@ -2662,19 +2654,17 @@ extern "C" int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len);
int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len)
{
MY_XML_USER_DATA *data= (MY_XML_USER_DATA*)st->user_data;
MY_XML_NODE *nodes= (MY_XML_NODE*) data->pxml->ptr();
uint numnodes= data->pxml->length() / sizeof(MY_XML_NODE);
uint parent= xml_parent_tag(nodes, numnodes, data->level - 1);
MY_XML_NODE node;
node.parent= data->parent; // Set parent for the new node to old parent
data->parent= numnodes; // Remember current node as new parent
data->pos[data->level]= numnodes;
node.level= data->level++;
node.type= st->current_node_type; // TAG or ATTR
node.beg= attr;
node.end= attr + len;
node.parent= parent;
data->pxml->append((const char*) &node, sizeof(MY_XML_NODE));
return MY_XML_OK;
return append_node(data->pxml, &node) ? MY_XML_ERROR : MY_XML_OK;
}
@ -2695,18 +2685,14 @@ extern "C" int xml_value(MY_XML_PARSER *st,const char *attr, size_t len);
int xml_value(MY_XML_PARSER *st,const char *attr, size_t len)
{
MY_XML_USER_DATA *data= (MY_XML_USER_DATA*)st->user_data;
MY_XML_NODE *nodes= (MY_XML_NODE*) data->pxml->ptr();
uint numnodes= data->pxml->length() / sizeof(MY_XML_NODE);
uint parent= xml_parent_tag(nodes, numnodes, data->level - 1);
MY_XML_NODE node;
node.parent= data->parent; // Set parent for the new text node to old parent
node.level= data->level;
node.type= MY_XML_NODE_TEXT;
node.beg= attr;
node.end= attr + len;
node.parent= parent;
data->pxml->append((const char*) &node, sizeof(MY_XML_NODE));
return MY_XML_OK;
return append_node(data->pxml, &node) ? MY_XML_ERROR : MY_XML_OK;
}
@ -2731,6 +2717,7 @@ int xml_leave(MY_XML_PARSER *st,const char *attr, size_t len)
data->level--;
MY_XML_NODE *nodes= (MY_XML_NODE*) data->pxml->ptr();
data->parent= nodes[data->parent].parent;
nodes+= data->pos[data->level];
nodes->tagend= st->cur;
@ -2761,6 +2748,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf)
p.flags= MY_XML_FLAG_RELATIVE_NAMES | MY_XML_FLAG_SKIP_TEXT_NORMALIZATION;
user_data.level= 0;
user_data.pxml= parsed_xml_buf;
user_data.parent= 0;
my_xml_set_enter_handler(&p, xml_enter);
my_xml_set_value_handler(&p, xml_value);
my_xml_set_leave_handler(&p, xml_leave);

View File

@ -3568,9 +3568,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
(!binlog_filter->db_ok(local_db)))
{
VOID(pthread_mutex_unlock(&LOCK_log));
DBUG_PRINT("info",("OPTION_BIN_LOG is %s, db_ok('%s') == %d",
(thd->options & OPTION_BIN_LOG) ? "set" : "clear",
local_db, binlog_filter->db_ok(local_db)));
DBUG_RETURN(0);
}
#endif /* HAVE_REPLICATION */

View File

@ -130,7 +130,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;

View File

@ -114,6 +114,9 @@ private:
flag_set m_flags;
};
#ifndef DBUG_OFF
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
#endif
/*
pretty_print_str()
@ -555,8 +558,32 @@ int Log_event::do_update_pos(Relay_log_info *rli)
Matz: I don't think we will need this check with this refactoring.
*/
if (rli)
rli->stmt_done(log_pos, when);
{
/*
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;
});
#ifndef DBUG_OFF
rli->stmt_done(log_pos,
is_artificial_event() &&
debug_not_change_ts_if_art_event > 0 ? 0 : when);
#else
rli->stmt_done(log_pos, is_artificial_event()? 0 : when);
#endif
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;
});
}
return 0; // Cannot fail currently
}
@ -570,7 +597,8 @@ Log_event::do_shall_skip(Relay_log_info *rli)
(ulong) server_id, (ulong) ::server_id,
rli->replicate_same_server_id,
rli->slave_skip_counter));
if (server_id == ::server_id && !rli->replicate_same_server_id)
if (server_id == ::server_id && !rli->replicate_same_server_id ||
rli->slave_skip_counter == 1 && rli->is_in_group())
return EVENT_SKIP_IGNORE;
else if (rli->slave_skip_counter > 0)
return EVENT_SKIP_COUNT;
@ -1227,6 +1255,16 @@ void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
#endif /* MYSQL_CLIENT */
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
inline Log_event::enum_skip_reason
Log_event::continue_group(Relay_log_info *rli)
{
if (rli->slave_skip_counter == 1)
return Log_event::EVENT_SKIP_IGNORE;
return Log_event::do_shall_skip(rli);
}
#endif
/**************************************************************************
Query_log_event methods
**************************************************************************/
@ -1290,6 +1328,11 @@ static void write_str_with_code_and_len(char **dst, const char *src,
bool Query_log_event::write(IO_CACHE* file)
{
/**
@todo if catalog can be of length FN_REFLEN==512, then we are not
replicating it correctly, since the length is stored in a byte
/sven
*/
uchar buf[QUERY_HEADER_LEN+
1+4+ // code of flags2 and flags2
1+8+ // code of sql_mode and sql_mode
@ -1516,6 +1559,10 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
time(&end_time);
exec_time = (ulong) (end_time - thd_arg->start_time);
/**
@todo this means that if we have no catalog, then it is replicated
as an existing catalog of length zero. is that safe? /sven
*/
catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
/* status_vars_len is set just before writing the event */
db_len = (db) ? (uint32) strlen(db) : 0;
@ -1525,7 +1572,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
/*
If we don't use flags2 for anything else than options contained in
thd_arg->options, it would be more efficient to flags2=thd_arg->options
(OPTIONS_WRITTEN_TO_BINLOG would be used only at reading time).
(OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
But it's likely that we don't want to use 32 bits for 3 bits; in the future
we will probably want to reclaim the 29 bits. So we need the &.
*/
@ -1726,6 +1773,11 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
DBUG_VOID_RETURN;
if (catalog_len) // If catalog is given
{
/**
@todo we should clean up and do only copy_str_and_move; it
works for both cases. Then we can remove the catalog_nz
flag. /sven
*/
if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
copy_str_and_move(&catalog, &start, catalog_len);
else
@ -1738,6 +1790,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
if (time_zone_len)
copy_str_and_move(&time_zone_str, &start, time_zone_len);
/**
if time_zone_len or catalog_len are 0, then time_zone and catalog
are uninitialized at this point. shouldn't they point to the
zero-length null-terminated strings we allocated space for in the
my_alloc call above? /sven
*/
/* A 2nd variable part; this is common to all versions */
memcpy((char*) start, end, data_len); // Copy db and query
start[data_len]= '\0'; // End query with \0 (For safetly)
@ -2235,6 +2294,30 @@ int Query_log_event::do_update_pos(Relay_log_info *rli)
}
Log_event::enum_skip_reason
Query_log_event::do_shall_skip(Relay_log_info *rli)
{
DBUG_ENTER("Query_log_event::do_shall_skip");
DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
DBUG_ASSERT(query && q_len > 0);
if (rli->slave_skip_counter > 0)
{
if (strcmp("BEGIN", query) == 0)
{
thd->options|= OPTION_BEGIN;
DBUG_RETURN(Log_event::continue_group(rli));
}
if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
{
thd->options&= ~OPTION_BEGIN;
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
}
}
DBUG_RETURN(Log_event::do_shall_skip(rli));
}
#endif
@ -2774,7 +2857,7 @@ uint Load_log_event::get_query_buffer_length()
21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
21 + sql_ex.line_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
15 + 22 + // " IGNORE xxx LINES"
3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
@ -3871,10 +3954,7 @@ Intvar_log_event::do_shall_skip(Relay_log_info *rli)
that we do not change the value of the slave skip counter since it
will be decreased by the following insert event.
*/
if (rli->slave_skip_counter == 1)
return Log_event::EVENT_SKIP_IGNORE;
else
return Log_event::do_shall_skip(rli);
return continue_group(rli);
}
#endif
@ -3970,10 +4050,7 @@ Rand_log_event::do_shall_skip(Relay_log_info *rli)
that we do not change the value of the slave skip counter since it
will be decreased by the following insert event.
*/
if (rli->slave_skip_counter == 1)
return Log_event::EVENT_SKIP_IGNORE;
else
return Log_event::do_shall_skip(rli);
return continue_group(rli);
}
#endif /* !MYSQL_CLIENT */
@ -4049,6 +4126,17 @@ int Xid_log_event::do_apply_event(Relay_log_info const *rli)
"COMMIT /* implicit, from Xid_log_event */");
return end_trans(thd, COMMIT);
}
Log_event::enum_skip_reason
Xid_log_event::do_shall_skip(Relay_log_info *rli)
{
DBUG_ENTER("Xid_log_event::do_shall_skip");
if (rli->slave_skip_counter > 0) {
thd->options&= ~OPTION_BEGIN;
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
}
DBUG_RETURN(Log_event::do_shall_skip(rli));
}
#endif /* !MYSQL_CLIENT */
@ -4427,10 +4515,7 @@ User_var_log_event::do_shall_skip(Relay_log_info *rli)
that we do not change the value of the slave skip counter since it
will be decreased by the following insert event.
*/
if (rli->slave_skip_counter == 1)
return Log_event::EVENT_SKIP_IGNORE;
else
return Log_event::do_shall_skip(rli);
return continue_group(rli);
}
#endif /* !MYSQL_CLIENT */
@ -5366,6 +5451,19 @@ int Begin_load_query_log_event::get_create_or_append() const
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
Log_event::enum_skip_reason
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
{
/*
If the slave skip counter is 1, then we should not start executing
on the next event.
*/
return continue_group(rli);
}
#endif
/**************************************************************************
Execute_load_query_log_event methods
**************************************************************************/
@ -5577,6 +5675,10 @@ bool sql_ex_info::write_data(IO_CACHE* file)
}
else
{
/**
@todo This is sensitive to field padding. We should write a
char[7], not an old_sql_ex. /sven
*/
old_sql_ex old_ex;
old_ex.field_term= *field_term;
old_ex.enclosed= *enclosed;
@ -6146,13 +6248,15 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
table->in_use = old_thd;
switch (error)
{
/* Some recoverable errors */
case 0:
break;
/* Some recoverable errors */
case HA_ERR_RECORD_CHANGED:
case HA_ERR_KEY_NOT_FOUND: /* Idempotency support: OK if
tuple does not exist */
error= 0;
case 0:
break;
error= 0;
break;
default:
rli->report(ERROR_LEVEL, thd->net.last_errno,
@ -6170,6 +6274,10 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
m_curr_row_end.
*/
DBUG_PRINT("info", ("error: %d", error));
DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
(ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
if (!m_curr_row_end && !error)
unpack_current_row(rli);
@ -6469,6 +6577,16 @@ void Rows_log_event::print_helper(FILE *file,
data) in the table map are initialized as zero (0). The array size is the
same as the columns for the table on the slave.
Additionally, values saved for field metadata on the master are saved as a
string of bytes (uchar) in the binlog. A field may require 1 or more bytes
to store the information. In cases where values require multiple bytes
(e.g. values > 255), the endian-safe methods are used to properly encode
the values on the master and decode them on the slave. When the field
metadata values are captured on the slave, they are stored in an array of
type uint16. This allows the least number of casts to prevent casting bugs
when the field metadata is used in comparisons of field attributes. When
the field metadata is used for calculating addresses in pointer math, the
type used is uint32.
*/
/**
@ -6860,10 +6978,7 @@ Table_map_log_event::do_shall_skip(Relay_log_info *rli)
If the slave skip counter is 1, then we should not start executing
on the next event.
*/
if (rli->slave_skip_counter == 1)
return Log_event::EVENT_SKIP_IGNORE;
else
return Log_event::do_shall_skip(rli);
return continue_group(rli);
}
int Table_map_log_event::do_update_pos(Relay_log_info *rli)
@ -7894,7 +8009,15 @@ Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
int error= find_row(rli);
if (error)
{
/*
We need to read the second image in the event of error to be
able to skip to the next pair of updates
*/
m_curr_row= m_curr_row_end;
unpack_current_row(rli);
return error;
}
/*
This is the situation after locating BI:

File diff suppressed because it is too large Load Diff

View File

@ -2936,7 +2936,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,

View File

@ -55,6 +55,7 @@ static int rr_index(READ_RECORD *info);
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
bool print_error, uint idx)
{
empty_record(table);
bzero((char*) info,sizeof(*info));
info->table= table;
info->file= table->file;
@ -161,6 +162,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
else
{
empty_record(table);
info->record= table->record[0];
info->ref_length= table->file->ref_length;
}

View File

@ -65,6 +65,8 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
my_ptrdiff_t const rec_offset= record - table->record[0];
my_ptrdiff_t const def_offset= table->s->default_values - table->record[0];
DBUG_ENTER("pack_row");
/*
We write the null bits and the packed records using one pass
through all the fields. The null bytes are written little-endian,
@ -96,26 +98,17 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
For big-endian machines, we have to make sure that the
length is stored in little-endian format, since this is the
format used for the binlog.
We do this by setting the db_low_byte_first, which is used
inside some store_length() to decide what order to write the
bytes in.
In reality, db_log_byte_first is only set for legacy table
type Isam, but in the event of a bug, we need to guarantee
the endianess when writing to the binlog.
This is currently broken for NDB due to BUG#29549, so we
will fix it when NDB has fixed their way of handling BLOBs.
*/
#if 0
bool save= table->s->db_low_byte_first;
table->s->db_low_byte_first= TRUE;
#endif
pack_ptr= field->pack(pack_ptr, field->ptr + offset);
#if 0
table->s->db_low_byte_first= save;
#ifndef DBUG_OFF
const uchar *old_pack_ptr= pack_ptr;
#endif
pack_ptr= field->pack(pack_ptr, field->ptr + offset,
field->max_data_length(), TRUE);
DBUG_PRINT("debug", ("field: %s; pack_ptr: 0x%lx;"
" pack_ptr':0x%lx; bytes: %d",
field->field_name, (ulong) old_pack_ptr,
(ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
}
null_mask <<= 1;
@ -143,8 +136,8 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
packed data. If it doesn't, something is very wrong.
*/
DBUG_ASSERT(null_ptr == row_data + null_byte_count);
return static_cast<size_t>(pack_ptr - row_data);
DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
DBUG_RETURN(static_cast<size_t>(pack_ptr - row_data));
}
#endif
@ -242,18 +235,16 @@ unpack_row(Relay_log_info const *rli,
Use the master's size information if available else call
normal unpack operation.
*/
#if 0
bool save= table->s->db_low_byte_first;
table->s->db_low_byte_first= TRUE;
#endif
uint16 const metadata= tabledef->field_metadata(i);
if (tabledef && metadata)
pack_ptr= f->unpack(f->ptr, pack_ptr, metadata);
else
pack_ptr= f->unpack(f->ptr, pack_ptr);
#if 0
table->s->db_low_byte_first= save;
#ifndef DBUG_OFF
uchar const *const old_pack_ptr= pack_ptr;
#endif
pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, TRUE);
DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;"
" pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
f->field_name, metadata,
(ulong) old_pack_ptr, (ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
}
null_mask <<= 1;
@ -289,6 +280,8 @@ unpack_row(Relay_log_info const *rli,
*/
DBUG_ASSERT(null_ptr == row_data + master_null_byte_count);
DBUG_DUMP("row_data", row_data, pack_ptr - row_data);
*row_end = pack_ptr;
if (master_reclength)
{

View File

@ -1082,6 +1082,9 @@ bool Relay_log_info::cached_charset_compare(char *charset) const
void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
time_t event_creation_time)
{
#ifndef DBUG_OFF
extern uint debug_not_change_ts_if_art_event;
#endif
clear_flag(IN_STMT);
/*
@ -1121,7 +1124,12 @@ void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
is that value may take some time to display in
Seconds_Behind_Master - not critical).
*/
last_master_timestamp= event_creation_time;
#ifndef DBUG_OFF
if (!(event_creation_time == 0 && debug_not_change_ts_if_art_event > 0))
#else
if (event_creation_time != 0)
#endif
last_master_timestamp= event_creation_time;
}
}

View File

@ -365,6 +365,18 @@ public:
m_flags |= (1UL << flag);
}
/**
Get the value of a replication state flag.
@param flag Flag to get value of
@return @c true if the flag was set, @c false otherwise.
*/
bool get_flag(enum_state_flag flag)
{
return m_flags & (1UL << flag);
}
/**
Clear the value of a replication state flag.

View File

@ -31,31 +31,34 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
switch (type(col)) {
case MYSQL_TYPE_NEWDECIMAL:
length= my_decimal_get_binary_size(m_field_metadata[col] >> 8,
m_field_metadata[col] - ((m_field_metadata[col] >> 8) << 8));
m_field_metadata[col] & 0xff);
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
length= m_field_metadata[col];
break;
/*
The cases for SET and ENUM are include for completeness, however
both are mapped to type MYSQL_TYPE_STRING and their real types
are encoded in the field metadata.
*/
case MYSQL_TYPE_SET:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_STRING:
{
if (((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_SET << 8)) ||
((m_field_metadata[col] & 0xff00) == (MYSQL_TYPE_ENUM << 8)))
uchar type= m_field_metadata[col] >> 8U;
if ((type == MYSQL_TYPE_SET) || (type == MYSQL_TYPE_ENUM))
length= m_field_metadata[col] & 0x00ff;
else
{
length= m_field_metadata[col] & 0x00ff;
DBUG_ASSERT(length > 0);
if (length > 255)
{
DBUG_ASSERT(uint2korr(master_data) > 0);
length= uint2korr(master_data) + 2;
}
else
length= (uint) *master_data + 1;
/*
We are reading the actual size from the master_data record
because this field has the actual lengh stored in the first
byte.
*/
length= (uint) *master_data + 1;
DBUG_ASSERT(length != 0);
}
break;
}
@ -95,6 +98,13 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
break;
case MYSQL_TYPE_BIT:
{
/*
Decode the size of the bit field from the master.
from_len is the length in bytes from the master
from_bit_len is the number of extra bits stored in the master record
If from_bit_len is not 0, add 1 to the length to account for accurate
number of bytes needed.
*/
uint from_len= (m_field_metadata[col] >> 8U) & 0x00ff;
uint from_bit_len= m_field_metadata[col] & 0x00ff;
DBUG_ASSERT(from_bit_len <= 7);
@ -136,7 +146,7 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
length= *master_data;
break;
case 2:
length= sint2korr(master_data);
length= uint2korr(master_data);
break;
case 3:
length= uint3korr(master_data);

View File

@ -99,7 +99,7 @@ public:
/*
These types store a single byte.
*/
m_field_metadata[i]= (uchar)field_metadata[index];
m_field_metadata[i]= field_metadata[index];
index++;
break;
}
@ -107,14 +107,14 @@ public:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_STRING:
{
short int x= field_metadata[index++] << 8U; // real_type
x = x + field_metadata[index++]; // pack or field length
uint16 x= field_metadata[index++] << 8U; // real_type
x+= field_metadata[index++]; // pack or field length
m_field_metadata[i]= x;
break;
}
case MYSQL_TYPE_BIT:
{
short int x= field_metadata[index++];
uint16 x= field_metadata[index++];
x = x + (field_metadata[index++] << 8U);
m_field_metadata[i]= x;
break;
@ -125,14 +125,14 @@ public:
These types store two bytes.
*/
char *ptr= (char *)&field_metadata[index];
m_field_metadata[i]= sint2korr(ptr);
m_field_metadata[i]= uint2korr(ptr);
index= index + 2;
break;
}
case MYSQL_TYPE_NEWDECIMAL:
{
short int x= field_metadata[index++] << 8U; // precision
x = x + field_metadata[index++]; // decimals
uint16 x= field_metadata[index++] << 8U; // precision
x+= field_metadata[index++]; // decimals
m_field_metadata[i]= x;
break;
}

View File

@ -1714,7 +1714,14 @@ static int has_temporary_error(THD *thd)
DBUG_ENTER("has_temporary_error");
if (thd->is_fatal_error)
{
DBUG_PRINT("info", ("thd->net.last_errno: %s", ER(thd->net.last_errno)));
DBUG_RETURN(0);
}
DBUG_EXECUTE_IF("all_errors_are_temporary_errors",
if (thd->net.last_errno)
thd->net.last_errno= ER_LOCK_DEADLOCK;);
/*
Temporary error codes:
@ -1723,7 +1730,10 @@ static int has_temporary_error(THD *thd)
*/
if (thd->net.last_errno == ER_LOCK_DEADLOCK ||
thd->net.last_errno == ER_LOCK_WAIT_TIMEOUT)
{
DBUG_PRINT("info", ("thd->net.last_errno: %s", ER(thd->net.last_errno)));
DBUG_RETURN(1);
}
#ifdef HAVE_NDB_BINLOG
/*
@ -1853,10 +1863,13 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
// EVENT_SKIP_NOT,
"not skipped",
// EVENT_SKIP_IGNORE,
"skipped because event originated from this server",
"skipped because event should be ignored",
// EVENT_SKIP_COUNT
"skipped because event skip counter was non-zero"
};
DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
thd->options & OPTION_BEGIN ? 1 : 0,
rli->get_flag(Relay_log_info::IN_STMT)));
DBUG_PRINT("skip_event", ("%s event was %s",
ev->get_type_str(), explain[reason]));
#endif
@ -1905,7 +1918,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
}
if (slave_trans_retries)
{
if (exec_res && has_temporary_error(thd))
int temp_err;
if (exec_res && (temp_err= has_temporary_error(thd)))
{
const char *errmsg;
/*
@ -1953,15 +1967,19 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
"the slave_transaction_retries variable.",
slave_trans_retries);
}
else if (!((thd->options & OPTION_BEGIN) && opt_using_transactions))
else if (exec_res && !temp_err ||
(opt_using_transactions &&
rli->group_relay_log_pos == rli->event_relay_log_pos))
{
/*
Only reset the retry counter if the event succeeded or
failed with a non-transient error. On a successful event,
the execution will proceed as usual; in the case of a
Only reset the retry counter if the entire group succeeded
or failed with a non-transient error. On a successful
event, the execution will proceed as usual; in the case of a
non-transient error, the slave will stop with an error.
*/
rli->trans_retries= 0; // restart from fresh
DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %d",
rli->trans_retries));
}
}
DBUG_RETURN(exec_res);
@ -2450,6 +2468,7 @@ pthread_handler_t handle_slave_sql(void *arg)
rli->ignore_log_space_limit= 0;
pthread_mutex_unlock(&rli->log_space_lock);
rli->trans_retries= 0; // start from "no error"
DBUG_PRINT("info", ("rli->trans_retries: %d", rli->trans_retries));
if (init_relay_log_pos(rli,
rli->group_relay_log_name,
@ -3581,7 +3600,16 @@ static 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;

View File

@ -1263,14 +1263,16 @@ public:
We follow this logic:
- when stmt starts, first_successful_insert_id_in_prev_stmt contains the
first insert id successfully inserted by the previous stmt.
- as stmt makes progress, handler::insert_id_for_cur_row changes; every
time get_auto_increment() is called, auto_inc_intervals_for_binlog is
augmented with the reserved interval (if statement-based binlogging).
- as stmt makes progress, handler::insert_id_for_cur_row changes;
every time get_auto_increment() is called,
auto_inc_intervals_in_cur_stmt_for_binlog is augmented with the
reserved interval (if statement-based binlogging).
- at first successful insertion of an autogenerated value,
first_successful_insert_id_in_cur_stmt is set to
handler::insert_id_for_cur_row.
- when stmt goes to binlog, auto_inc_intervals_for_binlog is
binlogged if non-empty.
- when stmt goes to binlog,
auto_inc_intervals_in_cur_stmt_for_binlog is binlogged if
non-empty.
- when stmt ends, first_successful_insert_id_in_prev_stmt is set to
first_successful_insert_id_in_cur_stmt.
*/
@ -2441,6 +2443,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);
@ -2476,6 +2483,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,

View File

@ -345,7 +345,7 @@ 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())
{
@ -541,7 +541,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);
}
@ -720,12 +720,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
@ -745,12 +747,29 @@ void multi_delete::send_error(uint errcode,const char *err)
*/
error= 1;
send_eof();
DBUG_ASSERT(error_handled);
DBUG_VOID_RETURN;
}
if (thd->transaction.stmt.modified_non_trans_table)
{
/*
there is only side effects; to binlog with the error
*/
if (mysql_bin_log.is_open())
{
thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE);
}
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:
@ -862,7 +881,8 @@ 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())
{
@ -879,7 +899,8 @@ bool multi_delete::send_eof()
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)

View File

@ -837,59 +837,58 @@ 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.
For the transactional algorithm to work the invalidation must be
before binlog writing and ha_autocommit_or_rollback
*/
if (changed)
query_cache_invalidate3(thd, table_list, 1);
if (error <= 0 || !transactional_table)
query_cache_invalidate3(thd, table_list, 1);
}
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:
/*
[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.
*/
DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_table, FALSE,
(error>0) ? thd->killed : THD::NOT_KILLED) &&
transactional_table)
{
error=1;
}
}
if (thd->transaction.stmt.modified_non_trans_table)
thd->transaction.all.modified_non_trans_table= TRUE;
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.
*/
DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_table, FALSE,
(error>0) ? thd->killed : THD::NOT_KILLED) &&
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);
@ -3175,6 +3174,7 @@ void select_insert::abort() {
*/
if (table)
{
bool changed, transactional_table;
/*
If we are not in prelocked mode, we end the bulk insert started
before.
@ -3196,20 +3196,20 @@ void select_insert::abort() {
If table creation failed, the number of rows modified will also be
zero, so no check for that is made.
*/
if (info.copied || info.deleted || info.updated)
changed= (info.copied || info.deleted || info.updated);
transactional_table= table->file->has_transactions();
if (thd->transaction.stmt.modified_non_trans_table)
{
DBUG_ASSERT(table != NULL);
if (!table->file->has_transactions())
{
if (mysql_bin_log.is_open())
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
table->file->has_transactions(), FALSE);
if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table &&
!can_rollback_data())
transactional_table, FALSE);
if (!thd->current_stmt_binlog_row_based && !can_rollback_data())
thd->transaction.all.modified_non_trans_table= TRUE;
query_cache_invalidate3(thd, table, 1);
}
if (changed)
query_cache_invalidate3(thd, table, 1);
}
DBUG_ASSERT(transactional_table || !changed ||
thd->transaction.stmt.modified_non_trans_table);
table->file->ha_release_auto_increment();
}

View File

@ -445,7 +445,7 @@ 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);
else

View File

@ -2087,7 +2087,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;
}
@ -2942,6 +2951,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

View File

@ -369,7 +369,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))
{
@ -378,6 +377,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;
@ -1359,7 +1362,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))
{
@ -1367,6 +1369,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;

View File

@ -29,6 +29,8 @@
#include "event_data_objects.h"
#include <my_dir.h>
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
#endif
@ -3135,8 +3137,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
goto err;
}
DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
lookup_field_vals.db_value.str,
lookup_field_vals.table_value.str));
STR_OR_NIL(lookup_field_vals.db_value.str),
STR_OR_NIL(lookup_field_vals.table_value.str)));
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
{

View File

@ -797,7 +797,7 @@ 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())
{
@ -1215,8 +1215,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)
{}
@ -1418,7 +1418,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) */
@ -1713,12 +1712,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.
@ -1754,8 +1755,7 @@ void multi_update::send_error(uint errcode,const char *err)
thd->query, thd->query_length,
transactional_tables, FALSE);
}
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);
@ -1978,8 +1978,6 @@ 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 */
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length,
transactional_tables, FALSE) &&
@ -1991,6 +1989,8 @@ bool multi_update::send_eof()
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)
{

View File

@ -179,20 +179,40 @@ 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 uint 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 uint mbcharlen_euc_kr(CHARSET_INFO *cs __attribute__((unused)),uint c)
{
return (iseuc_kr(c) ? 2 : 1);
return (iseuc_kr_head(c) ? 2 : 1);
}
@ -8654,7 +8674,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;