Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-5.0-rpl
into mysql.com:/nfsdisk1/lars/MERGE/mysql-5.0-merge sql/mysql_priv.h: Auto merged sql/sql_insert.cc: Auto merged sql/sql_yacc.yy: Auto merged
This commit is contained in:
commit
d5e983aafc
@ -11353,3 +11353,15 @@ a
|
||||
a
|
||||
a
|
||||
drop table t1;
|
||||
set names utf8;
|
||||
create table t1 (a text) default character set cp932;
|
||||
insert into t1 values (_utf8 0xE38182);
|
||||
show warnings;
|
||||
Level Code Message
|
||||
select * from t1;
|
||||
a
|
||||
あ
|
||||
select hex(a) from t1;
|
||||
hex(a)
|
||||
82A0
|
||||
drop table t1;
|
||||
|
@ -8,9 +8,9 @@ SET @var1= x'8300';
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
master-bin.000001 98 Query 1 188 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 188 User var 1 227 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 227 Query 1 323 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
SELECT HEX(f1) FROM t1;
|
||||
HEX(f1)
|
||||
8300
|
||||
@ -30,17 +30,17 @@ HEX(s1) HEX(s2) d
|
||||
466F6F2773206120426172 ED40ED41ED42 47.93
|
||||
DROP PROCEDURE bug18293|
|
||||
DROP TABLE t4|
|
||||
SHOW BINLOG EVENTS FROM 393|
|
||||
SHOW BINLOG EVENTS FROM 402|
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 393 Query 1 556 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
|
||||
master-bin.000001 402 Query 1 568 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
|
||||
s2 CHAR(50) CHARACTER SET cp932,
|
||||
d DECIMAL(10,2))
|
||||
master-bin.000001 556 Query 1 801 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE bug18293 (IN ins1 CHAR(50),
|
||||
master-bin.000001 568 Query 1 816 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE bug18293 (IN ins1 CHAR(50),
|
||||
IN ins2 CHAR(50) CHARACTER SET cp932,
|
||||
IN ind DECIMAL(10,2))
|
||||
BEGIN
|
||||
INSERT INTO t4 VALUES (ins1, ins2, ind);
|
||||
END
|
||||
master-bin.000001 801 Query 1 1017 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93))
|
||||
master-bin.000001 1017 Query 1 1103 use `test`; DROP PROCEDURE bug18293
|
||||
master-bin.000001 1103 Query 1 1179 use `test`; DROP TABLE t4
|
||||
master-bin.000001 816 Query 1 1035 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93))
|
||||
master-bin.000001 1035 Query 1 1124 use `test`; DROP PROCEDURE bug18293
|
||||
master-bin.000001 1124 Query 1 1203 use `test`; DROP TABLE t4
|
||||
|
@ -8,9 +8,9 @@ SET @var1= x'8300';
|
||||
EXECUTE stmt1 USING @var1;
|
||||
SHOW BINLOG EVENTS FROM 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
master-bin.000001 98 Query 1 188 use `test`; CREATE TABLE t1(f1 blob)
|
||||
master-bin.000001 188 User var 1 227 @`var1`=_binary 0x8300 COLLATE binary
|
||||
master-bin.000001 227 Query 1 323 use `test`; INSERT INTO t1 VALUES(@'var1')
|
||||
SELECT HEX(f1) FROM t1;
|
||||
HEX(f1)
|
||||
8300
|
||||
|
@ -2,11 +2,11 @@ drop table if exists t1;
|
||||
create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=innodb;
|
||||
select * from t1;
|
||||
c1 c2 stamp
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11"),( "text2","12");
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11");
|
||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||
select * from t1;
|
||||
c1 c2 stamp
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12"),( "text2","13"),( "text3","14", "a" ),( "text4","15", "b" );
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12");
|
||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||
select * from t1;
|
||||
c1 c2 stamp
|
||||
|
@ -272,3 +272,61 @@ call p1();
|
||||
1
|
||||
1
|
||||
drop procedure p1;
|
||||
flush logs;
|
||||
create table t1 (a varchar(64) character set utf8);
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=latin1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=latin1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r;
|
||||
select hex(a) from t1;
|
||||
hex(a)
|
||||
C3BF
|
||||
D0AA
|
||||
C3BF
|
||||
C3BF
|
||||
D0AA
|
||||
C3BF
|
||||
D0AA
|
||||
drop table t1;
|
||||
flush logs;
|
||||
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
|
||||
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
|
||||
DELIMITER /*!*/;
|
||||
use test/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
|
||||
SET @@session.sql_mode=0/*!*/;
|
||||
/*!\C latin1 *//*!*/;
|
||||
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
|
||||
create table t1 (a varchar(64) character set utf8)/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-6-0' INTO table t1/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.collation_database=7/*!*/;
|
||||
load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-7-0' INTO table t1/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-8-0' INTO table t1/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-9-0' INTO table t1/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.collation_database=7/*!*/;
|
||||
load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-a-0' INTO table t1/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
SET @@session.collation_database=DEFAULT/*!*/;
|
||||
load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-b-0' INTO table t1/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
load data LOCAL INFILE '/home/bar/mysql-5.0.b15126/mysql-test/var/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r/*!*/;
|
||||
SET TIMESTAMP=1000000000/*!*/;
|
||||
drop table t1/*!*/;
|
||||
DELIMITER ;
|
||||
# End of log file
|
||||
ROLLBACK /* added by mysqlbinlog */;
|
||||
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
|
||||
|
31
mysql-test/r/rpl_insert_delayed.result
Normal file
31
mysql-test/r/rpl_insert_delayed.result
Normal file
@ -0,0 +1,31 @@
|
||||
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;
|
||||
CREATE TABLE t1 (id INT primary key auto_increment, name VARCHAR(64));
|
||||
truncate table t1;
|
||||
insert delayed into t1 values(10, "my name");
|
||||
insert delayed into t1 values(10, "is Bond"), (20, "James Bond");
|
||||
ERROR 23000: Duplicate entry '10' for key 1
|
||||
flush table t1;
|
||||
select * from t1;
|
||||
id name
|
||||
10 my name
|
||||
select * from t1;
|
||||
id name
|
||||
10 my name
|
||||
delete from t1 where id!=10;
|
||||
insert delayed into t1 values(20, "is Bond"), (10, "James Bond");
|
||||
ERROR 23000: Duplicate entry '10' for key 1
|
||||
flush table t1;
|
||||
select * from t1;
|
||||
id name
|
||||
10 my name
|
||||
20 is Bond
|
||||
select * from t1;
|
||||
id name
|
||||
10 my name
|
||||
20 is Bond
|
||||
drop table t1;
|
@ -234,6 +234,64 @@ n b
|
||||
2 100
|
||||
3 350
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
|
||||
UNIQUE(b));
|
||||
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 10
|
||||
2 2
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 10
|
||||
2 2
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
id bigint(20) unsigned NOT NULL auto_increment,
|
||||
field_1 int(10) unsigned NOT NULL,
|
||||
field_2 varchar(255) NOT NULL,
|
||||
field_3 varchar(255) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY field_1 (field_1, field_2)
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
field_a int(10) unsigned NOT NULL,
|
||||
field_b varchar(255) NOT NULL,
|
||||
field_c varchar(255) NOT NULL
|
||||
);
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (4, 'd', '4d');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (5, 'e', '5e');
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (6, 'f', '6f');
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
SELECT * FROM t1;
|
||||
id field_1 field_2 field_3
|
||||
1 1 a 1a
|
||||
2 2 b 2b
|
||||
3 3 c 3c
|
||||
4 4 d 4d
|
||||
5 5 e 5e
|
||||
6 6 f 6f
|
||||
SELECT * FROM t1;
|
||||
id field_1 field_2 field_3
|
||||
1 1 a 1a
|
||||
2 2 b 2b
|
||||
3 3 c 3c
|
||||
4 4 d 4d
|
||||
5 5 e 5e
|
||||
6 6 f 6f
|
||||
drop table t1, t2;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
SELECT LAST_INSERT_ID(0);
|
||||
|
133
mysql-test/r/rpl_known_bugs_detection.result
Normal file
133
mysql-test/r/rpl_known_bugs_detection.result
Normal file
@ -0,0 +1,133 @@
|
||||
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;
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
|
||||
UNIQUE(b));
|
||||
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
1 10
|
||||
2 2
|
||||
show slave status;;
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port #
|
||||
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 Yes
|
||||
Slave_SQL_Running No
|
||||
Replicate_Do_DB
|
||||
Replicate_Ignore_DB
|
||||
Replicate_Do_Table
|
||||
Replicate_Ignore_Table
|
||||
Replicate_Wild_Do_Table
|
||||
Replicate_Wild_Ignore_Table
|
||||
Last_Errno 1105
|
||||
Last_Error Error 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error log on slave for more info' on query. Default database: 'test'. Query: 'INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10'
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 238
|
||||
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 #
|
||||
SELECT * FROM t1;
|
||||
a b
|
||||
stop slave;
|
||||
reset slave;
|
||||
reset master;
|
||||
drop table t1;
|
||||
start slave;
|
||||
CREATE TABLE t1 (
|
||||
id bigint(20) unsigned NOT NULL auto_increment,
|
||||
field_1 int(10) unsigned NOT NULL,
|
||||
field_2 varchar(255) NOT NULL,
|
||||
field_3 varchar(255) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY field_1 (field_1, field_2)
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
field_a int(10) unsigned NOT NULL,
|
||||
field_b varchar(255) NOT NULL,
|
||||
field_c varchar(255) NOT NULL
|
||||
);
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (4, 'd', '4d');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (5, 'e', '5e');
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (6, 'f', '6f');
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
SELECT * FROM t1;
|
||||
id field_1 field_2 field_3
|
||||
1 1 a 1a
|
||||
2 2 b 2b
|
||||
3 3 c 3c
|
||||
4 4 d 4d
|
||||
5 5 e 5e
|
||||
6 6 f 6f
|
||||
show slave status;;
|
||||
Slave_IO_State #
|
||||
Master_Host 127.0.0.1
|
||||
Master_User root
|
||||
Master_Port #
|
||||
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 Yes
|
||||
Slave_SQL_Running No
|
||||
Replicate_Do_DB
|
||||
Replicate_Ignore_DB
|
||||
Replicate_Do_Table
|
||||
Replicate_Ignore_Table
|
||||
Replicate_Wild_Do_Table
|
||||
Replicate_Wild_Ignore_Table
|
||||
Last_Errno 1105
|
||||
Last_Error Error 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error log on slave for more info' on query. Default database: 'test'. Query: 'INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c'
|
||||
Skip_Counter 0
|
||||
Exec_Master_Log_Pos 1270
|
||||
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 #
|
||||
SELECT * FROM t1;
|
||||
id field_1 field_2 field_3
|
||||
drop table t1, t2;
|
||||
drop table t1, t2;
|
37
mysql-test/r/rpl_loaddata2.result
Normal file
37
mysql-test/r/rpl_loaddata2.result
Normal file
@ -0,0 +1,37 @@
|
||||
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;
|
||||
create table t1 (a varchar(10) character set utf8);
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=DEFAULT;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=DEFAULT;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r;
|
||||
select hex(a) from t1;
|
||||
hex(a)
|
||||
C3BF
|
||||
D0AA
|
||||
C3BF
|
||||
C3BF
|
||||
C3BF
|
||||
D0AA
|
||||
D0AA
|
||||
select hex(a) from t1;
|
||||
hex(a)
|
||||
C3BF
|
||||
D0AA
|
||||
C3BF
|
||||
C3BF
|
||||
C3BF
|
||||
D0AA
|
||||
D0AA
|
||||
drop table t1;
|
@ -41,3 +41,37 @@ select * from t1;
|
||||
ts
|
||||
2005-08-12 00:00:00
|
||||
drop table t1;
|
||||
*** master ***
|
||||
create table t1 (a int, b int);
|
||||
create trigger trg1 before insert on t1 for each row set new.b=2;
|
||||
create table t2 (a int, b int);
|
||||
create trigger trg2 before insert on t2 for each row set new.b=2;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t1
|
||||
t2
|
||||
show triggers;
|
||||
Trigger Event Table Statement Timing Created sql_mode Definer
|
||||
trg1 INSERT t1 set new.b=2 BEFORE NULL root@localhost
|
||||
trg2 INSERT t2 set new.b=2 BEFORE NULL root@localhost
|
||||
*** slave ***
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t1
|
||||
show triggers;
|
||||
Trigger Event Table Statement Timing Created sql_mode Definer
|
||||
trg1 INSERT t1 set new.b=2 BEFORE NULL root@localhost
|
||||
*** master ***
|
||||
drop trigger trg1;
|
||||
drop trigger trg2;
|
||||
show triggers;
|
||||
Trigger Event Table Statement Timing Created sql_mode Definer
|
||||
*** slave ***
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t1
|
||||
show triggers;
|
||||
Trigger Event Table Statement Timing Created sql_mode Definer
|
||||
*** master ***
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
@ -108,4 +108,180 @@ slave-bin.000001 # User var 2 # @`a`=NULL
|
||||
slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a),(@a*5)
|
||||
insert into t1 select * FROM (select @var1 union select @var2) AS t2;
|
||||
drop table t1;
|
||||
End of 4.1 tests.
|
||||
DROP TABLE IF EXISTS t20;
|
||||
DROP TABLE IF EXISTS t21;
|
||||
DROP PROCEDURE IF EXISTS test.insert;
|
||||
CREATE TABLE t20 (a VARCHAR(20));
|
||||
CREATE TABLE t21 (a VARCHAR(20));
|
||||
CREATE PROCEDURE test.insert()
|
||||
BEGIN
|
||||
IF (@VAR)
|
||||
THEN
|
||||
INSERT INTO test.t20 VALUES ('SP_TRUE');
|
||||
ELSE
|
||||
INSERT INTO test.t20 VALUES ('SP_FALSE');
|
||||
END IF;
|
||||
END|
|
||||
CREATE TRIGGER test.insert_bi BEFORE INSERT
|
||||
ON test.t20 FOR EACH ROW
|
||||
BEGIN
|
||||
IF (@VAR)
|
||||
THEN
|
||||
INSERT INTO test.t21 VALUES ('TRIG_TRUE');
|
||||
ELSE
|
||||
INSERT INTO test.t21 VALUES ('TRIG_FALSE');
|
||||
END IF;
|
||||
END|
|
||||
SET @VAR=0;
|
||||
CALL test.insert();
|
||||
SET @VAR=1;
|
||||
CALL test.insert();
|
||||
On master: Check the tables for correct data
|
||||
SELECT * FROM t20;
|
||||
a
|
||||
SP_FALSE
|
||||
SP_TRUE
|
||||
SELECT * FROM t21;
|
||||
a
|
||||
TRIG_FALSE
|
||||
TRIG_TRUE
|
||||
On slave: Check the tables for correct data and it matches master
|
||||
SELECT * FROM t20;
|
||||
a
|
||||
SP_FALSE
|
||||
SP_TRUE
|
||||
SELECT * FROM t21;
|
||||
a
|
||||
TRIG_FALSE
|
||||
TRIG_TRUE
|
||||
DROP TABLE t20;
|
||||
DROP TABLE t21;
|
||||
DROP PROCEDURE test.insert;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS test.square;
|
||||
CREATE TABLE t1 (i INT);
|
||||
CREATE FUNCTION test.square() RETURNS INTEGER DETERMINISTIC RETURN (@var * @var);
|
||||
SET @var = 1;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 2;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 3;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 4;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 5;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
On master: Retrieve the values from the table
|
||||
SELECT * FROM t1;
|
||||
i
|
||||
1
|
||||
4
|
||||
9
|
||||
16
|
||||
25
|
||||
On slave: Retrieve the values from the table and verify they are the same as on master
|
||||
SELECT * FROM t1;
|
||||
i
|
||||
1
|
||||
4
|
||||
9
|
||||
16
|
||||
25
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION test.square;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
CREATE TABLE t1(a int);
|
||||
CREATE FUNCTION f1() returns int deterministic
|
||||
BEGIN
|
||||
return @a;
|
||||
END |
|
||||
CREATE FUNCTION f2() returns int deterministic
|
||||
BEGIN
|
||||
IF (@b > 0) then
|
||||
SET @c = (@a + @b);
|
||||
else
|
||||
SET @c = (@a - 1);
|
||||
END if;
|
||||
return @c;
|
||||
END |
|
||||
SET @a=500;
|
||||
INSERT INTO t1 values(f1());
|
||||
SET @b = 125;
|
||||
SET @c = 1;
|
||||
INSERT INTO t1 values(f2());
|
||||
On master: Retrieve the values from the table
|
||||
SELECT * from t1;
|
||||
a
|
||||
500
|
||||
625
|
||||
On slave: Check the tables for correct data and it matches master
|
||||
SELECT * from t1;
|
||||
a
|
||||
500
|
||||
625
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
CREATE TABLE t1 (i int);
|
||||
CREATE TABLE t2 (k int);
|
||||
CREATE trigger t1_bi before INSERT on t1 for each row
|
||||
BEGIN
|
||||
INSERT INTO t2 values (@a);
|
||||
SET @a:=42;
|
||||
INSERT INTO t2 values (@a);
|
||||
END |
|
||||
SET @a:=100;
|
||||
INSERT INTO t1 values (5);
|
||||
On master: Check to see that data was inserted correctly in both tables
|
||||
SELECT * from t1;
|
||||
i
|
||||
5
|
||||
SELECT * from t2;
|
||||
k
|
||||
100
|
||||
42
|
||||
On slave: Check the tables for correct data and it matches master
|
||||
SELECT * from t1;
|
||||
i
|
||||
5
|
||||
SELECT * from t2;
|
||||
k
|
||||
100
|
||||
42
|
||||
End of 5.0 tests.
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
CREATE TABLE t1 (i INT);
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN @a;
|
||||
CREATE FUNCTION f2() RETURNS INT
|
||||
BEGIN
|
||||
INSERT INTO t1 VALUES (10 + @a);
|
||||
RETURN 0;
|
||||
END|
|
||||
SET @a:=123;
|
||||
SELECT f1(), f2();
|
||||
f1() f2()
|
||||
123 0
|
||||
On master: Check to see that data was inserted correctly
|
||||
INSERT INTO t1 VALUES(f1());
|
||||
SELECT * FROM t1;
|
||||
i
|
||||
133
|
||||
123
|
||||
On slave: Check the table for correct data and it matches master
|
||||
SELECT * FROM t1;
|
||||
i
|
||||
133
|
||||
123
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
DROP TABLE t1;
|
||||
stop slave;
|
||||
|
1
mysql-test/std_data/loaddata6.dat
Normal file
1
mysql-test/std_data/loaddata6.dat
Normal file
@ -0,0 +1 @@
|
||||
<EFBFBD>
|
@ -413,3 +413,14 @@ select * from t1;
|
||||
insert into t1 values ('abc');
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#25815 Data truncated for column TEXT
|
||||
#
|
||||
set names utf8;
|
||||
create table t1 (a text) default character set cp932;
|
||||
insert into t1 values (_utf8 0xE38182);
|
||||
show warnings;
|
||||
select * from t1;
|
||||
select hex(a) from t1;
|
||||
drop table t1;
|
||||
|
@ -51,7 +51,7 @@ CALL bug18293("Foo's a Bar", _cp932 0xED40ED41ED42, 47.93)|
|
||||
SELECT HEX(s1),HEX(s2),d FROM t4|
|
||||
DROP PROCEDURE bug18293|
|
||||
DROP TABLE t4|
|
||||
SHOW BINLOG EVENTS FROM 393|
|
||||
SHOW BINLOG EVENTS FROM 402|
|
||||
delimiter ;|
|
||||
|
||||
# End of 5.0 tests
|
||||
|
@ -13,4 +13,3 @@
|
||||
im_daemon_life_cycle : Bug#24415 see note: [19 Dec 23:17] Trudy Pelzer
|
||||
ndb_load : Bug#17233
|
||||
user_limits : Bug#23921 random failure of user_limits.test
|
||||
|
||||
|
@ -12,10 +12,10 @@ drop table if exists t1;
|
||||
create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=innodb;
|
||||
select * from t1;
|
||||
--error 1031
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11"),( "text2","12");
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11");
|
||||
select * from t1;
|
||||
--error 1031
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12"),( "text2","13"),( "text3","14", "a" ),( "text4","15", "b" );
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12");
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
|
@ -190,4 +190,28 @@ drop procedure p1;
|
||||
--exec $MYSQL_BINLOG --help 2>&1 > /dev/null
|
||||
--enable_query_log
|
||||
|
||||
#
|
||||
# Bug#15126 character_set_database is not replicated
|
||||
# (LOAD DATA INFILE need it)
|
||||
#
|
||||
|
||||
flush logs;
|
||||
create table t1 (a varchar(64) character set utf8);
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=latin1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set character_set_database=latin1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r;
|
||||
select hex(a) from t1;
|
||||
drop table t1;
|
||||
flush logs;
|
||||
--exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000011
|
||||
|
||||
# End of 5.0 tests
|
||||
|
||||
|
67
mysql-test/t/rpl_insert_delayed.test
Normal file
67
mysql-test/t/rpl_insert_delayed.test
Normal file
@ -0,0 +1,67 @@
|
||||
--source include/master-slave.inc
|
||||
--source include/not_embedded.inc
|
||||
--source include/not_windows.inc
|
||||
|
||||
connection master;
|
||||
|
||||
let $binlog_format_statement=1;
|
||||
|
||||
CREATE TABLE t1 (id INT primary key auto_increment, name VARCHAR(64));
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
#
|
||||
# BUG#26116 "If multi-row INSERT DELAYED has errors,
|
||||
# statement-based binlogging breaks";
|
||||
# happened only in statement-based binlogging.
|
||||
#
|
||||
|
||||
connection master;
|
||||
truncate table t1;
|
||||
# first scenario: duplicate on first row
|
||||
insert delayed into t1 values(10, "my name");
|
||||
if ($binlog_format_statement)
|
||||
{
|
||||
# statement below will be converted to non-delayed INSERT and so
|
||||
# will stop at first error, guaranteeing replication.
|
||||
--error ER_DUP_ENTRY
|
||||
insert delayed into t1 values(10, "is Bond"), (20, "James Bond");
|
||||
}
|
||||
if (!$binlog_format_statement)
|
||||
{
|
||||
insert delayed into t1 values(10, "is Bond"), (20, "James Bond");
|
||||
}
|
||||
flush table t1; # to wait for INSERT DELAYED to be done
|
||||
select * from t1;
|
||||
sync_slave_with_master;
|
||||
# when bug existed in statement-based binlogging, t1 on slave had
|
||||
# different content from on master
|
||||
select * from t1;
|
||||
|
||||
# second scenario: duplicate on second row
|
||||
connection master;
|
||||
delete from t1 where id!=10;
|
||||
if ($binlog_format_statement)
|
||||
{
|
||||
# statement below will be converted to non-delayed INSERT and so
|
||||
# will be binlogged with its ER_DUP_ENTRY error code, guaranteeing
|
||||
# replication (slave will hit the same error code and so be fine).
|
||||
--error ER_DUP_ENTRY
|
||||
insert delayed into t1 values(20, "is Bond"), (10, "James Bond");
|
||||
}
|
||||
if (!$binlog_format_statement)
|
||||
{
|
||||
insert delayed into t1 values(20, "is Bond"), (10, "James Bond");
|
||||
}
|
||||
flush table t1; # to wait for INSERT DELAYED to be done
|
||||
select * from t1;
|
||||
sync_slave_with_master;
|
||||
# when bug existed in statement-based binlogging, query was binlogged
|
||||
# with error_code=0 so slave stopped
|
||||
select * from t1;
|
||||
|
||||
# clean up
|
||||
connection master;
|
||||
drop table t1;
|
||||
sync_slave_with_master;
|
||||
connection master;
|
@ -245,6 +245,59 @@ select * from t1 order by n;
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values"
|
||||
#
|
||||
|
||||
# testcase with INSERT VALUES
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
|
||||
UNIQUE(b));
|
||||
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
|
||||
SELECT * FROM t1;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t1;
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
||||
# tescase with INSERT SELECT
|
||||
CREATE TABLE t1 (
|
||||
id bigint(20) unsigned NOT NULL auto_increment,
|
||||
field_1 int(10) unsigned NOT NULL,
|
||||
field_2 varchar(255) NOT NULL,
|
||||
field_3 varchar(255) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY field_1 (field_1, field_2)
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
field_a int(10) unsigned NOT NULL,
|
||||
field_b varchar(255) NOT NULL,
|
||||
field_c varchar(255) NOT NULL
|
||||
);
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (4, 'd', '4d');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (5, 'e', '5e');
|
||||
# Updating table t1 based on values from table t2
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
# Inserting new record into t2
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (6, 'f', '6f');
|
||||
# Updating t1 again
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
SELECT * FROM t1;
|
||||
sync_slave_with_master;
|
||||
SELECT * FROM t1;
|
||||
connection master;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# BUG#20339: stored procedure using LAST_INSERT_ID() does not
|
||||
# replicate statement-based
|
||||
|
1
mysql-test/t/rpl_known_bugs_detection-master.opt
Normal file
1
mysql-test/t/rpl_known_bugs_detection-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--loose-debug=d,pretend_version_50034_in_binlog
|
90
mysql-test/t/rpl_known_bugs_detection.test
Normal file
90
mysql-test/t/rpl_known_bugs_detection.test
Normal file
@ -0,0 +1,90 @@
|
||||
# Test to see if slave can detect certain known bugs present
|
||||
# on the master, and appropriately decides to stop
|
||||
# (assuming the bug is fixed in the slave, slave cannot of course
|
||||
# imitate the bug, so it has to stop).
|
||||
|
||||
source include/have_debug.inc;
|
||||
source include/master-slave.inc;
|
||||
|
||||
#
|
||||
# This is to test that slave properly detects if
|
||||
# master may suffer from:
|
||||
# BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values"
|
||||
# (i.e. on master, INSERT ON DUPLICATE KEY UPDATE is used and manipulates
|
||||
# an auto_increment column, and is binlogged statement-based).
|
||||
#
|
||||
|
||||
# testcase with INSERT VALUES
|
||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
|
||||
UNIQUE(b));
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
|
||||
SELECT * FROM t1;
|
||||
connection slave;
|
||||
wait_for_slave_to_stop;
|
||||
# show the error message
|
||||
--replace_column 1 # 4 # 7 # 8 # 9 # 23 # 33 #
|
||||
--query_vertical show slave status;
|
||||
# show that it was not replicated
|
||||
SELECT * FROM t1;
|
||||
|
||||
# restart replication for the next testcase
|
||||
stop slave;
|
||||
reset slave;
|
||||
connection master;
|
||||
reset master;
|
||||
drop table t1;
|
||||
connection slave;
|
||||
start slave;
|
||||
|
||||
# testcase with INSERT SELECT
|
||||
connection master;
|
||||
CREATE TABLE t1 (
|
||||
id bigint(20) unsigned NOT NULL auto_increment,
|
||||
field_1 int(10) unsigned NOT NULL,
|
||||
field_2 varchar(255) NOT NULL,
|
||||
field_3 varchar(255) NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY field_1 (field_1, field_2)
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
field_a int(10) unsigned NOT NULL,
|
||||
field_b varchar(255) NOT NULL,
|
||||
field_c varchar(255) NOT NULL
|
||||
);
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (4, 'd', '4d');
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (5, 'e', '5e');
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
# Updating table t1 based on values from table t2
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
# Inserting new record into t2
|
||||
INSERT INTO t2 (field_a, field_b, field_c) VALUES (6, 'f', '6f');
|
||||
# Updating t1 again
|
||||
INSERT INTO t1 (field_1, field_2, field_3)
|
||||
SELECT t2.field_a, t2.field_b, t2.field_c
|
||||
FROM t2
|
||||
ON DUPLICATE KEY UPDATE
|
||||
t1.field_3 = t2.field_c;
|
||||
SELECT * FROM t1;
|
||||
connection slave;
|
||||
wait_for_slave_to_stop;
|
||||
# show the error message
|
||||
--replace_column 1 # 4 # 7 # 8 # 9 # 23 # 33 #
|
||||
--query_vertical show slave status;
|
||||
# show that it was not replicated
|
||||
SELECT * FROM t1;
|
||||
connection master;
|
||||
drop table t1, t2;
|
||||
connection slave;
|
||||
drop table t1, t2;
|
||||
|
||||
# End of 5.0 tests
|
33
mysql-test/t/rpl_loaddata2.test
Normal file
33
mysql-test/t/rpl_loaddata2.test
Normal file
@ -0,0 +1,33 @@
|
||||
#
|
||||
# Check LOAD DATA + character sets + replication
|
||||
#
|
||||
source include/master-slave.inc;
|
||||
|
||||
#
|
||||
# Bug#15126 character_set_database is not replicated
|
||||
# (LOAD DATA INFILE need it)
|
||||
#
|
||||
connection master;
|
||||
create table t1 (a varchar(10) character set utf8);
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=DEFAULT;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=koi8r;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1;
|
||||
set @@character_set_database=DEFAULT;
|
||||
load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8r;
|
||||
|
||||
select hex(a) from t1;
|
||||
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
||||
select hex(a) from t1;
|
||||
connection master;
|
||||
drop table t1;
|
||||
sync_slave_with_master;
|
@ -59,3 +59,35 @@ drop table t1;
|
||||
sync_slave_with_master;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Bug#24478 DROP TRIGGER is not caught by replicate-*-table filters
|
||||
#
|
||||
--echo *** master ***
|
||||
connection master;
|
||||
create table t1 (a int, b int);
|
||||
create trigger trg1 before insert on t1 for each row set new.b=2;
|
||||
create table t2 (a int, b int);
|
||||
create trigger trg2 before insert on t2 for each row set new.b=2;
|
||||
show tables;
|
||||
show triggers;
|
||||
sync_slave_with_master;
|
||||
--echo *** slave ***
|
||||
connection slave;
|
||||
show tables;
|
||||
show triggers;
|
||||
--echo *** master ***
|
||||
connection master;
|
||||
drop trigger trg1;
|
||||
drop trigger trg2;
|
||||
show triggers;
|
||||
sync_slave_with_master;
|
||||
--echo *** slave ***
|
||||
connection slave;
|
||||
show tables;
|
||||
show triggers;
|
||||
--echo *** master ***
|
||||
connection master;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
sync_slave_with_master;
|
||||
|
@ -57,8 +57,305 @@ insert into t1 select * FROM (select @var1 union select @var2) AS t2;
|
||||
drop table t1;
|
||||
save_master_pos;
|
||||
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
--echo End of 4.1 tests.
|
||||
|
||||
# BUG#20141
|
||||
# The following tests ensure that if user-defined variables are used in SF/Triggers
|
||||
# that they are replicated correctly. These tests should be run in both SBR and RBR
|
||||
# modes.
|
||||
|
||||
# This test uses a procedure that inserts data values based on the value of a
|
||||
# user-defined variable. It also has a trigger that inserts data based on the
|
||||
# same variable. Successful test runs show that the @var is replicated
|
||||
# properly and that the procedure and trigger insert the correct data on the
|
||||
# slave.
|
||||
#
|
||||
# The test of stored procedure was included for completeness. Replication of stored
|
||||
# procedures was not directly affected by BUG#20141.
|
||||
#
|
||||
# This test was constructed for BUG#20141
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t20;
|
||||
DROP TABLE IF EXISTS t21;
|
||||
DROP PROCEDURE IF EXISTS test.insert;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t20 (a VARCHAR(20));
|
||||
CREATE TABLE t21 (a VARCHAR(20));
|
||||
DELIMITER |;
|
||||
|
||||
# Create a procedure that uses the @var for flow control
|
||||
|
||||
CREATE PROCEDURE test.insert()
|
||||
BEGIN
|
||||
IF (@VAR)
|
||||
THEN
|
||||
INSERT INTO test.t20 VALUES ('SP_TRUE');
|
||||
ELSE
|
||||
INSERT INTO test.t20 VALUES ('SP_FALSE');
|
||||
END IF;
|
||||
END|
|
||||
|
||||
# Create a trigger that uses the @var for flow control
|
||||
|
||||
CREATE TRIGGER test.insert_bi BEFORE INSERT
|
||||
ON test.t20 FOR EACH ROW
|
||||
BEGIN
|
||||
IF (@VAR)
|
||||
THEN
|
||||
INSERT INTO test.t21 VALUES ('TRIG_TRUE');
|
||||
ELSE
|
||||
INSERT INTO test.t21 VALUES ('TRIG_FALSE');
|
||||
END IF;
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
|
||||
# Set @var and call the procedure, repeat with different values
|
||||
|
||||
SET @VAR=0;
|
||||
CALL test.insert();
|
||||
SET @VAR=1;
|
||||
CALL test.insert();
|
||||
|
||||
--echo On master: Check the tables for correct data
|
||||
|
||||
SELECT * FROM t20;
|
||||
SELECT * FROM t21;
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo On slave: Check the tables for correct data and it matches master
|
||||
|
||||
SELECT * FROM t20;
|
||||
SELECT * FROM t21;
|
||||
connection master;
|
||||
|
||||
# Cleanup
|
||||
|
||||
DROP TABLE t20;
|
||||
DROP TABLE t21;
|
||||
DROP PROCEDURE test.insert;
|
||||
|
||||
# This test uses a stored function that uses user-defined variables to return data
|
||||
# This test was constructed for BUG#20141
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS test.square;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
|
||||
# Create function that returns a value from @var. In this case, the square function
|
||||
|
||||
CREATE FUNCTION test.square() RETURNS INTEGER DETERMINISTIC RETURN (@var * @var);
|
||||
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
|
||||
# Set the @var to different values and insert them into a table
|
||||
|
||||
SET @var = 1;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 2;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 3;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 4;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
SET @var = 5;
|
||||
INSERT INTO t1 VALUES (square());
|
||||
|
||||
--echo On master: Retrieve the values from the table
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo On slave: Retrieve the values from the table and verify they are the same as on master
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
connection master;
|
||||
|
||||
# Cleanup
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION test.square;
|
||||
|
||||
# This test uses stored functions that uses user-defined variables to return data
|
||||
# based on the use of @vars inside a function body.
|
||||
# This test was constructed for BUG#14914
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1(a int);
|
||||
DELIMITER |;
|
||||
|
||||
# Create a function that simply returns the value of an @var.
|
||||
# Create a function that uses an @var for flow control, creates and uses another
|
||||
# @var and sets its value to a value based on another @var.
|
||||
|
||||
CREATE FUNCTION f1() returns int deterministic
|
||||
BEGIN
|
||||
return @a;
|
||||
END |
|
||||
|
||||
CREATE FUNCTION f2() returns int deterministic
|
||||
BEGIN
|
||||
IF (@b > 0) then
|
||||
SET @c = (@a + @b);
|
||||
else
|
||||
SET @c = (@a - 1);
|
||||
END if;
|
||||
return @c;
|
||||
END |
|
||||
DELIMITER ;|
|
||||
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
|
||||
# Set an @var to a value and insert data into a table using the first function.
|
||||
# Set two more @vars to some values and insert data into a table using the second function.
|
||||
|
||||
SET @a=500;
|
||||
INSERT INTO t1 values(f1());
|
||||
SET @b = 125;
|
||||
SET @c = 1;
|
||||
INSERT INTO t1 values(f2());
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo On master: Retrieve the values from the table
|
||||
|
||||
SELECT * from t1;
|
||||
|
||||
--echo On slave: Check the tables for correct data and it matches master
|
||||
|
||||
SELECT * from t1;
|
||||
|
||||
connection master;
|
||||
|
||||
# Cleanup
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
|
||||
# This test uses a function that changes a user-defined variable in its body. This test
|
||||
# will ensure the @vars are replicated when needed and not interrupt the normal execution
|
||||
# of the function on the slave. This also applies to triggers.
|
||||
#
|
||||
# This test was constructed for BUG#25167
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t2;
|
||||
--enable_warnings
|
||||
CREATE TABLE t1 (i int);
|
||||
CREATE TABLE t2 (k int);
|
||||
DELIMITER |;
|
||||
|
||||
# Create a trigger that inserts data into another table, changes the @var then inserts
|
||||
# another row with the modified value.
|
||||
|
||||
CREATE trigger t1_bi before INSERT on t1 for each row
|
||||
BEGIN
|
||||
INSERT INTO t2 values (@a);
|
||||
SET @a:=42;
|
||||
INSERT INTO t2 values (@a);
|
||||
END |
|
||||
DELIMITER ;|
|
||||
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
|
||||
# Set the @var to a value then insert data into first table.
|
||||
|
||||
SET @a:=100;
|
||||
INSERT INTO t1 values (5);
|
||||
|
||||
--echo On master: Check to see that data was inserted correctly in both tables
|
||||
|
||||
SELECT * from t1;
|
||||
SELECT * from t2;
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo On slave: Check the tables for correct data and it matches master
|
||||
|
||||
SELECT * from t1;
|
||||
SELECT * from t2;
|
||||
|
||||
connection master;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
# Cleanup
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
|
||||
# This test uses a stored function that uses user-defined variables to return data
|
||||
# The test ensures the value of the user-defined variable is replicated correctly
|
||||
# and in the correct order of assignment.
|
||||
# This test was constructed for BUG#20141
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP FUNCTION IF EXISTS f1;
|
||||
DROP FUNCTION IF EXISTS f2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
|
||||
# Create two functions. One simply returns the user-defined variable. The other
|
||||
# returns a value based on the user-defined variable.
|
||||
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN @a;
|
||||
DELIMITER |;
|
||||
CREATE FUNCTION f2() RETURNS INT
|
||||
BEGIN
|
||||
INSERT INTO t1 VALUES (10 + @a);
|
||||
RETURN 0;
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
sync_slave_with_master;
|
||||
connection master;
|
||||
|
||||
# Set the variable and execute the functions.
|
||||
|
||||
SET @a:=123;
|
||||
SELECT f1(), f2();
|
||||
|
||||
--echo On master: Check to see that data was inserted correctly
|
||||
|
||||
INSERT INTO t1 VALUES(f1());
|
||||
SELECT * FROM t1;
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
--echo On slave: Check the table for correct data and it matches master
|
||||
|
||||
SELECT * FROM t1;
|
||||
|
||||
connection master;
|
||||
|
||||
# Cleanup
|
||||
|
||||
DROP FUNCTION f1;
|
||||
DROP FUNCTION f2;
|
||||
DROP TABLE t1;
|
||||
|
||||
sync_slave_with_master;
|
||||
stop slave;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -7014,7 +7014,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||
cannot_convert_error_pos, from + length))
|
||||
return 2;
|
||||
|
||||
if (copy_length < length)
|
||||
if (from_end_pos < from + length)
|
||||
{
|
||||
report_data_too_long(this);
|
||||
return 2;
|
||||
|
@ -4227,7 +4227,14 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
|
||||
user_var_entry *var_entry;
|
||||
var_entry= get_variable(&thd->user_vars, name, 0);
|
||||
|
||||
if (!(opt_bin_log && is_update_query(sql_command)))
|
||||
/*
|
||||
Any reference to user-defined variable which is done from stored
|
||||
function or trigger affects their execution and the execution of the
|
||||
calling statement. We must log all such variables even if they are
|
||||
not involved in table-updating statements.
|
||||
*/
|
||||
if (!(opt_bin_log &&
|
||||
(is_update_query(sql_command) || thd->in_sub_stmt)))
|
||||
{
|
||||
*out_entry= var_entry;
|
||||
return 0;
|
||||
|
@ -1578,13 +1578,13 @@ bool MYSQL_LOG::flush_and_sync()
|
||||
return err;
|
||||
}
|
||||
|
||||
void MYSQL_LOG::start_union_events(THD *thd)
|
||||
void MYSQL_LOG::start_union_events(THD *thd, query_id_t query_id_param)
|
||||
{
|
||||
DBUG_ASSERT(!thd->binlog_evt_union.do_union);
|
||||
thd->binlog_evt_union.do_union= TRUE;
|
||||
thd->binlog_evt_union.unioned_events= FALSE;
|
||||
thd->binlog_evt_union.unioned_events_trans= FALSE;
|
||||
thd->binlog_evt_union.first_query_id= thd->query_id;
|
||||
thd->binlog_evt_union.first_query_id= query_id_param;
|
||||
}
|
||||
|
||||
void MYSQL_LOG::stop_union_events(THD *thd)
|
||||
@ -2524,7 +2524,7 @@ int TC_LOG_MMAP::open(const char *opt_name)
|
||||
goto err;
|
||||
if (using_heuristic_recover())
|
||||
return 1;
|
||||
if ((fd= my_create(logname, O_RDWR, 0, MYF(MY_WME))) < 0)
|
||||
if ((fd= my_create(logname, CREATE_MODE, O_RDWR, MYF(MY_WME))) < 0)
|
||||
goto err;
|
||||
inited=1;
|
||||
file_length= opt_tc_log_size;
|
||||
|
@ -1092,7 +1092,8 @@ bool Query_log_event::write(IO_CACHE* file)
|
||||
1+4+ // code of autoinc and the 2 autoinc variables
|
||||
1+6+ // code of charset and charset
|
||||
1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
|
||||
1+2 // code of lc_time_names and lc_time_names_number
|
||||
1+2+ // code of lc_time_names and lc_time_names_number
|
||||
1+2 // code of charset_database and charset_database_number
|
||||
], *start, *start_of_status;
|
||||
ulong event_length;
|
||||
|
||||
@ -1211,6 +1212,13 @@ bool Query_log_event::write(IO_CACHE* file)
|
||||
int2store(start, lc_time_names_number);
|
||||
start+= 2;
|
||||
}
|
||||
if (charset_database_number)
|
||||
{
|
||||
DBUG_ASSERT(charset_database_number <= 0xFFFF);
|
||||
*start++= Q_CHARSET_DATABASE_CODE;
|
||||
int2store(start, charset_database_number);
|
||||
start+= 2;
|
||||
}
|
||||
/*
|
||||
Here there could be code like
|
||||
if (command-line-option-which-says-"log_this_variable" && inited)
|
||||
@ -1276,7 +1284,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||
sql_mode(thd_arg->variables.sql_mode),
|
||||
auto_increment_increment(thd_arg->variables.auto_increment_increment),
|
||||
auto_increment_offset(thd_arg->variables.auto_increment_offset),
|
||||
lc_time_names_number(thd_arg->variables.lc_time_names->number)
|
||||
lc_time_names_number(thd_arg->variables.lc_time_names->number),
|
||||
charset_database_number(0)
|
||||
{
|
||||
time_t end_time;
|
||||
time(&end_time);
|
||||
@ -1284,6 +1293,9 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||
catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
|
||||
/* status_vars_len is set just before writing the event */
|
||||
db_len = (db) ? (uint32) strlen(db) : 0;
|
||||
if (thd_arg->variables.collation_database != thd_arg->db_charset)
|
||||
charset_database_number= thd_arg->variables.collation_database->number;
|
||||
|
||||
/*
|
||||
If we don't use flags2 for anything else than options contained in
|
||||
thd->options, it would be more efficient to flags2=thd_arg->options
|
||||
@ -1354,7 +1366,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
||||
db(NullS), catalog_len(0), status_vars_len(0),
|
||||
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
|
||||
auto_increment_increment(1), auto_increment_offset(1),
|
||||
time_zone_len(0), lc_time_names_number(0)
|
||||
time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
|
||||
{
|
||||
ulong data_len;
|
||||
uint32 tmp;
|
||||
@ -1459,6 +1471,10 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
||||
lc_time_names_number= uint2korr(pos);
|
||||
pos+= 2;
|
||||
break;
|
||||
case Q_CHARSET_DATABASE_CODE:
|
||||
charset_database_number= uint2korr(pos);
|
||||
pos+= 2;
|
||||
break;
|
||||
default:
|
||||
/* That's why you must write status vars in growing order of code */
|
||||
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
|
||||
@ -1656,6 +1672,16 @@ void Query_log_event::print_query_header(FILE* file,
|
||||
lc_time_names_number, print_event_info->delimiter);
|
||||
print_event_info->lc_time_names_number= lc_time_names_number;
|
||||
}
|
||||
if (charset_database_number != print_event_info->charset_database_number)
|
||||
{
|
||||
if (charset_database_number)
|
||||
fprintf(file, "SET @@session.collation_database=%d%s\n",
|
||||
charset_database_number, print_event_info->delimiter);
|
||||
else
|
||||
fprintf(file, "SET @@session.collation_database=DEFAULT%s\n",
|
||||
print_event_info->delimiter);
|
||||
print_event_info->charset_database_number= charset_database_number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1821,6 +1847,20 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli,
|
||||
}
|
||||
else
|
||||
thd->variables.lc_time_names= &my_locale_en_US;
|
||||
if (charset_database_number)
|
||||
{
|
||||
CHARSET_INFO *cs;
|
||||
if (!(cs= get_charset(charset_database_number, MYF(0))))
|
||||
{
|
||||
char buf[20];
|
||||
int10_to_str((int) charset_database_number, buf, -10);
|
||||
my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
|
||||
goto compare_errors;
|
||||
}
|
||||
thd->variables.collation_database= cs;
|
||||
}
|
||||
else
|
||||
thd->variables.collation_database= thd->db_charset;
|
||||
|
||||
/* Execute the query (note that we bypass dispatch_command()) */
|
||||
mysql_parse(thd, thd->query, thd->query_length);
|
||||
@ -2051,6 +2091,8 @@ Start_log_event_v3::Start_log_event_v3(const char* buf,
|
||||
binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
|
||||
memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
|
||||
ST_SERVER_VER_LEN);
|
||||
// prevent overrun if log is corrupted on disk
|
||||
server_version[ST_SERVER_VER_LEN-1]= 0;
|
||||
created= uint4korr(buf+ST_CREATED_OFFSET);
|
||||
/* We use log_pos to mark if this was an artificial event or not */
|
||||
artificial_event= (log_pos == 0);
|
||||
@ -2174,6 +2216,8 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
|
||||
switch (binlog_ver) {
|
||||
case 4: /* MySQL 5.0 */
|
||||
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
|
||||
DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
|
||||
strmov(server_version, "5.0.34"););
|
||||
common_header_len= LOG_EVENT_HEADER_LEN;
|
||||
number_of_event_types= LOG_EVENT_TYPES;
|
||||
/* we'll catch my_malloc() error in is_valid() */
|
||||
@ -2245,6 +2289,7 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
|
||||
post_header_len= 0; /* will make is_valid() fail */
|
||||
break;
|
||||
}
|
||||
calc_server_version_split();
|
||||
}
|
||||
|
||||
|
||||
@ -2284,6 +2329,7 @@ Format_description_log_event(const char* buf,
|
||||
post_header_len= (uint8*) my_memdup((byte*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
|
||||
number_of_event_types*
|
||||
sizeof(*post_header_len), MYF(0));
|
||||
calc_server_version_split();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -2384,6 +2430,37 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
Splits the event's 'server_version' string into three numeric pieces stored
|
||||
into 'server_version_split':
|
||||
X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
|
||||
X.Yabc -> {X,Y,0}
|
||||
Xabc -> {X,0,0}
|
||||
'server_version_split' is then used for lookups to find if the server which
|
||||
created this event has some known bug.
|
||||
*/
|
||||
void Format_description_log_event::calc_server_version_split()
|
||||
{
|
||||
char *p= server_version, *r;
|
||||
ulong number;
|
||||
for (uint i= 0; i<=2; i++)
|
||||
{
|
||||
number= strtoul(p, &r, 10);
|
||||
server_version_split[i]= (uchar)number;
|
||||
DBUG_ASSERT(number < 256); // fit in uchar
|
||||
p= r;
|
||||
DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
|
||||
if (*r == '.')
|
||||
p++; // skip the dot
|
||||
}
|
||||
DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
|
||||
" '%s' %d %d %d", server_version,
|
||||
server_version_split[0],
|
||||
server_version_split[1], server_version_split[2]));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Load_log_event methods
|
||||
General note about Load_log_event: the binlogging of LOAD DATA INFILE is
|
||||
|
@ -272,6 +272,7 @@ struct sql_ex_info
|
||||
|
||||
#define Q_LC_TIME_NAMES_CODE 7
|
||||
|
||||
#define Q_CHARSET_DATABASE_CODE 8
|
||||
/* Intvar event post-header */
|
||||
|
||||
#define I_TYPE_OFFSET 0
|
||||
@ -509,10 +510,11 @@ typedef struct st_print_event_info
|
||||
char charset[6]; // 3 variables, each of them storable in 2 bytes
|
||||
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
|
||||
uint lc_time_names_number;
|
||||
uint charset_database_number;
|
||||
st_print_event_info()
|
||||
:flags2_inited(0), sql_mode_inited(0),
|
||||
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0),
|
||||
lc_time_names_number(0)
|
||||
lc_time_names_number(0), charset_database_number(0)
|
||||
{
|
||||
/*
|
||||
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
|
||||
@ -797,6 +799,7 @@ public:
|
||||
uint time_zone_len; /* 0 means uninited */
|
||||
const char *time_zone_str;
|
||||
uint lc_time_names_number; /* 0 means en_US */
|
||||
uint charset_database_number;
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
@ -1104,6 +1107,7 @@ public:
|
||||
uint8 number_of_event_types;
|
||||
/* The list of post-headers' lengthes */
|
||||
uint8 *post_header_len;
|
||||
uchar server_version_split[3];
|
||||
|
||||
Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
|
||||
|
||||
@ -1135,6 +1139,7 @@ public:
|
||||
*/
|
||||
return FORMAT_DESCRIPTION_HEADER_LEN;
|
||||
}
|
||||
void calc_server_version_split();
|
||||
};
|
||||
|
||||
|
||||
|
@ -97,6 +97,18 @@ void net_set_read_timeout(NET *net, uint timeout);
|
||||
#define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1))
|
||||
#define all_bits_set(A,B) ((A) & (B) != (B))
|
||||
|
||||
#define WARN_DEPRECATED(Thd,Ver,Old,New) \
|
||||
do { \
|
||||
DBUG_ASSERT(strncmp(Ver, MYSQL_SERVER_VERSION, sizeof(Ver)-1) > 0); \
|
||||
if (Thd != NULL) \
|
||||
push_warning_printf(((THD *)Thd), MYSQL_ERROR::WARN_LEVEL_WARN, \
|
||||
ER_WARN_DEPRECATED_SYNTAX, ER(ER_WARN_DEPRECATED_SYNTAX), \
|
||||
(Old), (Ver), (New)); \
|
||||
else \
|
||||
sql_print_warning("The syntax %s is deprecated and will be removed " \
|
||||
"in MySQL %s. Please use %s instead.", (Old), (Ver), (New)); \
|
||||
} while(0)
|
||||
|
||||
extern CHARSET_INFO *system_charset_info, *files_charset_info ;
|
||||
extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
||||
|
||||
|
@ -355,6 +355,8 @@ my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
|
||||
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
|
||||
my_bool opt_log_slave_updates= 0;
|
||||
my_bool opt_innodb;
|
||||
bool slave_warning_issued = false;
|
||||
|
||||
#ifdef HAVE_NDBCLUSTER_DB
|
||||
const char *opt_ndbcluster_connectstring= 0;
|
||||
const char *opt_ndb_connectstring= 0;
|
||||
@ -3198,7 +3200,7 @@ server.");
|
||||
(TC_LOG *) &tc_log_mmap) :
|
||||
(TC_LOG *) &tc_log_dummy);
|
||||
|
||||
if (tc_log->open(opt_bin_logname))
|
||||
if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
|
||||
{
|
||||
sql_print_error("Can't init tc log");
|
||||
unireg_abort(1);
|
||||
@ -6936,6 +6938,29 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
case (int) OPT_STANDALONE: /* Dummy option for NT */
|
||||
break;
|
||||
#endif
|
||||
/*
|
||||
The following change issues a deprecation warning if the slave
|
||||
configuration is specified either in the my.cnf file or on
|
||||
the command-line. See BUG#21490.
|
||||
*/
|
||||
case OPT_MASTER_HOST:
|
||||
case OPT_MASTER_USER:
|
||||
case OPT_MASTER_PASSWORD:
|
||||
case OPT_MASTER_PORT:
|
||||
case OPT_MASTER_CONNECT_RETRY:
|
||||
case OPT_MASTER_SSL:
|
||||
case OPT_MASTER_SSL_KEY:
|
||||
case OPT_MASTER_SSL_CERT:
|
||||
case OPT_MASTER_SSL_CAPATH:
|
||||
case OPT_MASTER_SSL_CIPHER:
|
||||
case OPT_MASTER_SSL_CA:
|
||||
if (!slave_warning_issued) //only show the warning once
|
||||
{
|
||||
slave_warning_issued = true;
|
||||
WARN_DEPRECATED(0, "5.2", "for replication startup options",
|
||||
"'CHANGE MASTER'");
|
||||
}
|
||||
break;
|
||||
case OPT_CONSOLE:
|
||||
if (opt_console)
|
||||
opt_error_log= 0; // Force logs to stdout
|
||||
|
81
sql/slave.cc
81
sql/slave.cc
@ -3759,8 +3759,13 @@ err:
|
||||
mi->abort_slave= 0;
|
||||
mi->slave_running= 0;
|
||||
mi->io_thd= 0;
|
||||
pthread_mutex_unlock(&mi->run_lock);
|
||||
/*
|
||||
Note: the order of the two following calls (first broadcast, then unlock)
|
||||
is important. Otherwise a killer_thread can execute between the calls and
|
||||
delete the mi structure leading to a crash! (see BUG#25306 for details)
|
||||
*/
|
||||
pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
|
||||
pthread_mutex_unlock(&mi->run_lock);
|
||||
#ifndef DBUG_OFF
|
||||
if (abort_slave_event_count && !events_till_abort)
|
||||
goto slave_begin;
|
||||
@ -3978,8 +3983,13 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
|
||||
THD_CHECK_SENTRY(thd);
|
||||
delete thd;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
pthread_cond_broadcast(&rli->stop_cond);
|
||||
|
||||
/*
|
||||
Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
|
||||
is important. Otherwise a killer_thread can execute between the calls and
|
||||
delete the mi structure leading to a crash! (see BUG#25306 for details)
|
||||
*/
|
||||
pthread_cond_broadcast(&rli->stop_cond);
|
||||
#ifndef DBUG_OFF
|
||||
/*
|
||||
Bug #19938 Valgrind error (race) in handle_slave_sql()
|
||||
@ -3987,9 +3997,8 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
|
||||
*/
|
||||
const int eta= rli->events_till_abort;
|
||||
#endif
|
||||
pthread_mutex_unlock(&rli->run_lock); // tell the world we are done
|
||||
|
||||
// tell the world we are done
|
||||
pthread_mutex_unlock(&rli->run_lock);
|
||||
#ifndef DBUG_OFF // TODO: reconsider the code below
|
||||
if (abort_slave_event_count && !eta)
|
||||
goto slave_begin;
|
||||
@ -5174,6 +5183,70 @@ end:
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Detects, based on master's version (as found in the relay log), if master
|
||||
has a certain bug.
|
||||
@param rli RELAY_LOG_INFO which tells the master's version
|
||||
@param bug_id Number of the bug as found in bugs.mysql.com
|
||||
@return TRUE if master has the bug, FALSE if it does not.
|
||||
*/
|
||||
bool rpl_master_has_bug(RELAY_LOG_INFO *rli, uint bug_id)
|
||||
{
|
||||
struct st_version_range_for_one_bug {
|
||||
uint bug_id;
|
||||
const uchar introduced_in[3]; // first version with bug
|
||||
const uchar fixed_in[3]; // first version with fix
|
||||
};
|
||||
static struct st_version_range_for_one_bug versions_for_all_bugs[]=
|
||||
{
|
||||
{24432, { 5, 0, 24 }, { 5, 0, 38 } },
|
||||
{24432, { 5, 1, 12 }, { 5, 1, 17 } }
|
||||
};
|
||||
const uchar *master_ver=
|
||||
rli->relay_log.description_event_for_exec->server_version_split;
|
||||
|
||||
DBUG_ASSERT(sizeof(rli->relay_log.description_event_for_exec->server_version_split) == 3);
|
||||
|
||||
for (uint i= 0;
|
||||
i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
|
||||
{
|
||||
const uchar *introduced_in= versions_for_all_bugs[i].introduced_in,
|
||||
*fixed_in= versions_for_all_bugs[i].fixed_in;
|
||||
if ((versions_for_all_bugs[i].bug_id == bug_id) &&
|
||||
(memcmp(introduced_in, master_ver, 3) <= 0) &&
|
||||
(memcmp(fixed_in, master_ver, 3) > 0))
|
||||
{
|
||||
// a verbose message for the error log
|
||||
slave_print_error(rli, ER_UNKNOWN_ERROR,
|
||||
"According to the master's version ('%s'),"
|
||||
" it is probable that master suffers from this bug:"
|
||||
" http://bugs.mysql.com/bug.php?id=%u"
|
||||
" and thus replicating the current binary log event"
|
||||
" may make the slave's data become different from the"
|
||||
" master's data."
|
||||
" To take no risk, slave refuses to replicate"
|
||||
" this event and stops."
|
||||
" We recommend that all updates be stopped on the"
|
||||
" master and slave, that the data of both be"
|
||||
" manually synchronized,"
|
||||
" that master's binary logs be deleted,"
|
||||
" that master be upgraded to a version at least"
|
||||
" equal to '%d.%d.%d'. Then replication can be"
|
||||
" restarted.",
|
||||
rli->relay_log.description_event_for_exec->server_version,
|
||||
bug_id,
|
||||
fixed_in[0], fixed_in[1], fixed_in[2]);
|
||||
// a short message for SHOW SLAVE STATUS (message length constraints)
|
||||
my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
|
||||
" http://bugs.mysql.com/bug.php?id=%u"
|
||||
" so slave stops; check error log on slave"
|
||||
" for more info", MYF(0), bug_id);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
|
||||
template class I_List_iterator<i_string>;
|
||||
template class I_List_iterator<i_string_pair>;
|
||||
|
@ -533,6 +533,7 @@ void table_rule_ent_hash_to_str(String* s, HASH* h);
|
||||
void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a);
|
||||
bool show_master_info(THD* thd, MASTER_INFO* mi);
|
||||
bool show_binlog_info(THD* thd);
|
||||
bool rpl_master_has_bug(RELAY_LOG_INFO *rli, uint bug_id);
|
||||
|
||||
/* See if the query uses any tables that should not be replicated */
|
||||
bool tables_ok(THD* thd, TABLE_LIST* tables);
|
||||
|
@ -1462,8 +1462,24 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
|
||||
binlog_save_options= thd->options;
|
||||
if (need_binlog_call)
|
||||
{
|
||||
query_id_t q;
|
||||
reset_dynamic(&thd->user_var_events);
|
||||
mysql_bin_log.start_union_events(thd);
|
||||
/*
|
||||
In case of artificially constructed events for function calls
|
||||
we have separate union for each such event and hence can't use
|
||||
query_id of real calling statement as the start of all these
|
||||
unions (this will break logic of replication of user-defined
|
||||
variables). So we use artifical value which is guaranteed to
|
||||
be greater than all query_id's of all statements belonging
|
||||
to previous events/unions.
|
||||
Possible alternative to this is logging of all function invocations
|
||||
as one select and not resetting THD::user_var_events before
|
||||
each invocation.
|
||||
*/
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
q= global_query_id;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
mysql_bin_log.start_union_events(thd, q + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -901,6 +901,7 @@ sql_exchange::sql_exchange(char *name,bool flag)
|
||||
enclosed= line_start= &my_empty_string;
|
||||
line_term= &default_line_term;
|
||||
escaped= &default_escaped;
|
||||
cs= NULL;
|
||||
}
|
||||
|
||||
bool select_send::send_fields(List<Item> &list, uint flags)
|
||||
@ -2050,6 +2051,10 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
||||
|
||||
if (!lex->requires_prelocking() || is_update_query(lex->sql_command))
|
||||
options&= ~OPTION_BIN_LOG;
|
||||
|
||||
if ((backup->options & OPTION_BIN_LOG) && is_update_query(lex->sql_command))
|
||||
mysql_bin_log.start_union_events(this, this->query_id);
|
||||
|
||||
/* Disable result sets */
|
||||
client_capabilities &= ~CLIENT_MULTI_RESULTS;
|
||||
in_sub_stmt|= new_state;
|
||||
@ -2096,6 +2101,9 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
|
||||
sent_row_count= backup->sent_row_count;
|
||||
client_capabilities= backup->client_capabilities;
|
||||
|
||||
if ((options & OPTION_BIN_LOG) && is_update_query(lex->sql_command))
|
||||
mysql_bin_log.stop_union_events(this);
|
||||
|
||||
/*
|
||||
The following is added to the old values as we are interested in the
|
||||
total complexity of the query
|
||||
|
@ -311,7 +311,7 @@ public:
|
||||
bool write(Log_event* event_info); // binary log write
|
||||
bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
|
||||
|
||||
void start_union_events(THD *thd);
|
||||
void start_union_events(THD *thd, query_id_t query_id_param);
|
||||
void stop_union_events(THD *thd);
|
||||
bool is_query_in_union(THD *thd, query_id_t query_id_param);
|
||||
|
||||
@ -1687,6 +1687,7 @@ public:
|
||||
bool opt_enclosed;
|
||||
bool dumpfile;
|
||||
ulong skip_lines;
|
||||
CHARSET_INFO *cs;
|
||||
sql_exchange(char *name,bool dumpfile_flag);
|
||||
};
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "sp_head.h"
|
||||
#include "sql_trigger.h"
|
||||
#include "sql_select.h"
|
||||
#include "slave.h"
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
|
||||
@ -380,11 +381,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
List_item *values;
|
||||
Name_resolution_context *context;
|
||||
Name_resolution_context_state ctx_state;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
char *query= thd->query;
|
||||
bool log_on= (thd->options & OPTION_BIN_LOG) ||
|
||||
(!(thd->security_ctx->master_access & SUPER_ACL));
|
||||
#endif
|
||||
thr_lock_type lock_type = table_list->lock_type;
|
||||
Item *unused_conds= 0;
|
||||
DBUG_ENTER("mysql_insert");
|
||||
@ -405,6 +404,27 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
(duplic == DUP_UPDATE))
|
||||
lock_type=TL_WRITE;
|
||||
#endif
|
||||
if ((lock_type == TL_WRITE_DELAYED) &&
|
||||
log_on && mysql_bin_log.is_open() &&
|
||||
(values_list.elements > 1))
|
||||
{
|
||||
/*
|
||||
Statement-based binary logging does not work in this case, because:
|
||||
a) two concurrent statements may have their rows intermixed in the
|
||||
queue, leading to autoincrement replication problems on slave (because
|
||||
the values generated used for one statement don't depend only on the
|
||||
value generated for the first row of this statement, so are not
|
||||
replicable)
|
||||
b) if first row of the statement has an error the full statement is
|
||||
not binlogged, while next rows of the statement may be inserted.
|
||||
c) if first row succeeds, statement is binlogged immediately with a
|
||||
zero error code (i.e. "no error"), if then second row fails, query
|
||||
will fail on slave too and slave will stop (wrongly believing that the
|
||||
master got no error).
|
||||
So we fallback to non-delayed INSERT.
|
||||
*/
|
||||
lock_type= TL_WRITE;
|
||||
}
|
||||
table_list->lock_type= lock_type;
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@ -519,6 +539,14 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
thd->cuted_fields = 0L;
|
||||
table->next_number_field=table->found_next_number_field;
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (thd->slave_thread &&
|
||||
(info.handle_duplicates == DUP_UPDATE) &&
|
||||
(table->next_number_field != NULL) &&
|
||||
rpl_master_has_bug(&active_mi->rli, 24432))
|
||||
goto abort;
|
||||
#endif
|
||||
|
||||
error=0;
|
||||
id=0;
|
||||
thd->proc_info="update";
|
||||
@ -1182,11 +1210,11 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
|
||||
if (res == VIEW_CHECK_ERROR)
|
||||
goto before_trg_err;
|
||||
|
||||
table->file->restore_auto_increment();
|
||||
if ((error=table->file->update_row(table->record[1],table->record[0])))
|
||||
{
|
||||
if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
|
||||
{
|
||||
table->file->restore_auto_increment();
|
||||
goto ok_or_after_trg_err;
|
||||
}
|
||||
goto err;
|
||||
@ -2444,6 +2472,15 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
}
|
||||
restore_record(table,s->default_values); // Get empty record
|
||||
table->next_number_field=table->found_next_number_field;
|
||||
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (thd->slave_thread &&
|
||||
(info.handle_duplicates == DUP_UPDATE) &&
|
||||
(table->next_number_field != NULL) &&
|
||||
rpl_master_has_bug(&active_mi->rli, 24432))
|
||||
DBUG_RETURN(1);
|
||||
#endif
|
||||
|
||||
thd->cuted_fields=0;
|
||||
if (info.ignore || info.handle_duplicates != DUP_ERROR)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
|
@ -314,7 +314,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
info.handle_duplicates=handle_duplicates;
|
||||
info.escape_char=escaped->length() ? (*escaped)[0] : INT_MAX;
|
||||
|
||||
READ_INFO read_info(file,tot_length,thd->variables.collation_database,
|
||||
READ_INFO read_info(file,tot_length,
|
||||
ex->cs ? ex->cs : thd->variables.collation_database,
|
||||
*field_term,*ex->line_start, *ex->line_term, *enclosed,
|
||||
info.escape_char, read_file_from_client, is_fifo);
|
||||
if (read_info.error)
|
||||
@ -455,7 +456,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
}
|
||||
sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted,
|
||||
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
||||
send_ok(thd,info.copied+info.deleted,0L,name);
|
||||
|
||||
if (!transactional_table)
|
||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
||||
@ -476,6 +476,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
if (transactional_table)
|
||||
error=ha_autocommit_or_rollback(thd,error);
|
||||
|
||||
/* ok to client sent only after binlog write and engine commit */
|
||||
send_ok(thd, info.copied + info.deleted, 0L, name);
|
||||
err:
|
||||
if (thd->lock)
|
||||
{
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "sp_head.h"
|
||||
#include "sp.h"
|
||||
#include "sp_cache.h"
|
||||
#include "sql_trigger.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
/*
|
||||
@ -2491,6 +2492,30 @@ mysql_execute_command(THD *thd)
|
||||
#ifdef HAVE_REPLICATION
|
||||
if (unlikely(thd->slave_thread))
|
||||
{
|
||||
if (lex->sql_command == SQLCOM_DROP_TRIGGER)
|
||||
{
|
||||
/*
|
||||
When dropping a trigger, we need to load its table name
|
||||
before checking slave filter rules.
|
||||
*/
|
||||
add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
|
||||
|
||||
if (!all_tables)
|
||||
{
|
||||
/*
|
||||
If table name cannot be loaded,
|
||||
it means the trigger does not exists possibly because
|
||||
CREATE TRIGGER was previously skipped for this trigger
|
||||
according to slave filtering rules.
|
||||
Returning success without producing any errors in this case.
|
||||
*/
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
// force searching in slave.cc:tables_ok()
|
||||
all_tables->updating= 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Check if statment should be skipped because of slave filtering
|
||||
rules
|
||||
|
@ -882,12 +882,14 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
|
||||
|
||||
int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
|
||||
{
|
||||
DBUG_ENTER("stop_slave");
|
||||
|
||||
int slave_errno;
|
||||
if (!thd)
|
||||
thd = current_thd;
|
||||
|
||||
if (check_access(thd, SUPER_ACL, any_db,0,0,0,0))
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
thd->proc_info = "Killing slave";
|
||||
int thread_mask;
|
||||
lock_slave_threads(mi);
|
||||
@ -921,12 +923,12 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
|
||||
{
|
||||
if (net_report)
|
||||
my_message(slave_errno, ER(slave_errno), MYF(0));
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else if (net_report)
|
||||
send_ok(thd);
|
||||
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,10 +106,6 @@ const LEX_STRING trg_event_type_names[]=
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
add_table_for_trigger(THD *thd, sp_name *trig, bool if_exists,
|
||||
TABLE_LIST ** table);
|
||||
|
||||
class Handle_old_incorrect_sql_modes_hook: public Unknown_key_hook
|
||||
{
|
||||
private:
|
||||
@ -1182,7 +1178,7 @@ bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
|
||||
1 Error
|
||||
*/
|
||||
|
||||
static int
|
||||
int
|
||||
add_table_for_trigger(THD *thd, sp_name *trig, bool if_exists,
|
||||
TABLE_LIST **table)
|
||||
{
|
||||
|
@ -139,3 +139,7 @@ private:
|
||||
|
||||
extern const LEX_STRING trg_action_time_type_names[];
|
||||
extern const LEX_STRING trg_event_type_names[];
|
||||
|
||||
int
|
||||
add_table_for_trigger(THD *thd, sp_name *trig, bool if_exists,
|
||||
TABLE_LIST **table);
|
||||
|
@ -992,6 +992,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
old_or_new_charset_name_or_default
|
||||
collation_name
|
||||
collation_name_or_default
|
||||
opt_load_data_charset
|
||||
|
||||
%type <variable> internal_variable_name
|
||||
|
||||
@ -3262,6 +3263,10 @@ charset_name_or_default:
|
||||
charset_name { $$=$1; }
|
||||
| DEFAULT { $$=NULL; } ;
|
||||
|
||||
opt_load_data_charset:
|
||||
/* Empty */ { $$= NULL; }
|
||||
| charset charset_name_or_default { $$= $2; }
|
||||
;
|
||||
|
||||
old_or_new_charset_name:
|
||||
ident_or_text
|
||||
@ -7242,6 +7247,8 @@ load_data:
|
||||
lex->update_list.empty();
|
||||
lex->value_list.empty();
|
||||
}
|
||||
opt_load_data_charset
|
||||
{ Lex->exchange->cs= $12; }
|
||||
opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
|
||||
opt_load_data_set_spec
|
||||
{}
|
||||
|
Loading…
x
Reference in New Issue
Block a user