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:
commit
a3b60d2d51
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
42
mysql-test/include/ctype_regex.inc
Normal file
42
mysql-test/include/ctype_regex.inc
Normal 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;
|
33
mysql-test/include/wait_for_slave_sql_error.inc
Normal file
33
mysql-test/include/wait_for_slave_sql_error.inc
Normal 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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 '[[:<:]]вася[[:>:]]'
|
||||
|
@ -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]+$');
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
136
mysql-test/suite/manual/r/rpl_replication_delay.result
Normal file
136
mysql-test/suite/manual/r/rpl_replication_delay.result
Normal 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;
|
@ -0,0 +1 @@
|
||||
--loose-debug=d,let_first_flush_log_change_timestamp
|
71
mysql-test/suite/manual/t/rpl_replication_delay.test
Normal file
71
mysql-test/suite/manual/t/rpl_replication_delay.test
Normal 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
|
||||
|
3
mysql-test/suite/rpl/data/rpl_bug28618.dat
Normal file
3
mysql-test/suite/rpl/data/rpl_bug28618.dat
Normal file
@ -0,0 +1,3 @@
|
||||
1|master only
|
||||
2|master only
|
||||
3|master only
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 ***
|
||||
|
@ -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 ***
|
||||
|
Binary file not shown.
Binary file not shown.
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Binary file not shown.
@ -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;
|
||||
|
@ -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;
|
||||
|
81
mysql-test/suite/rpl/r/rpl_temporary_errors.result
Normal file
81
mysql-test/suite/rpl/r/rpl_temporary_errors.result
Normal 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;
|
@ -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
|
||||
|
@ -114,4 +114,5 @@ SELECT * FROM visits_events;
|
||||
|
||||
# Cleanup
|
||||
DROP DATABASE track;
|
||||
sync_slave_with_master;
|
||||
--echo End of 5.1 tests
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
--slave-skip-error=1062,1582
|
||||
--slave-skip-error=1062
|
||||
|
@ -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;
|
||||
|
1
mysql-test/suite/rpl/t/rpl_slave_skip-slave.opt
Normal file
1
mysql-test/suite/rpl/t/rpl_slave_skip-slave.opt
Normal file
@ -0,0 +1 @@
|
||||
--innodb
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
3
mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt
Normal file
3
mysql-test/suite/rpl/t/rpl_temporary_errors-slave.opt
Normal file
@ -0,0 +1,3 @@
|
||||
--loose-debug="+d,all_errors_are_temporary_errors" --slave-transaction-retries=2
|
||||
|
||||
|
27
mysql-test/suite/rpl/t/rpl_temporary_errors.test
Normal file
27
mysql-test/suite/rpl/t/rpl_temporary_errors.test
Normal 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;
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
#
|
||||
|
@ -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;
|
||||
|
410
sql/field.cc
410
sql/field.cc
@ -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)
|
||||
|
271
sql/field.h
271
sql/field.h
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
173
sql/log_event.cc
173
sql/log_event.cc
@ -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:
|
||||
|
1040
sql/log_event.h
1040
sql/log_event.h
File diff suppressed because it is too large
Load Diff
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
42
sql/slave.cc
42
sql/slave.cc
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user