Commit 73ca08a4 authored by lars/lthalmann@dl145j.mysql.com's avatar lars/lthalmann@dl145j.mysql.com

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

into  mysql.com:/nfsdisk1/lars/bk/mysql-5.1-new-rpl
parents b2d39478 4835204d
...@@ -635,6 +635,7 @@ Create_file event for file_id: %u\n",exv->file_id); ...@@ -635,6 +635,7 @@ Create_file event for file_id: %u\n",exv->file_id);
print_event_info->common_header_len= print_event_info->common_header_len=
glob_description_event->common_header_len; glob_description_event->common_header_len;
ev->print(result_file, print_event_info); ev->print(result_file, print_event_info);
ev->temp_buf= 0; // as the event ref is zeroed
/* /*
We don't want this event to be deleted now, so let's hide it (I We don't want this event to be deleted now, so let's hide it (I
(Guilhem) should later see if this triggers a non-serious Valgrind (Guilhem) should later see if this triggers a non-serious Valgrind
...@@ -682,8 +683,16 @@ Begin_load_query event for file_id: %u\n", exlq->file_id); ...@@ -682,8 +683,16 @@ Begin_load_query event for file_id: %u\n", exlq->file_id);
end: end:
rec_count++; rec_count++;
/*
Destroy the log_event object. If reading from a remote host,
set the temp_buf to NULL so that memory isn't freed twice.
*/
if (ev) if (ev)
{
if (remote_opt)
ev->temp_buf= 0;
delete ev; delete ev;
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -1172,6 +1181,12 @@ could be out of memory"); ...@@ -1172,6 +1181,12 @@ could be out of memory");
error= 1; error= 1;
goto err; goto err;
} }
/*
If reading from a remote host, ensure the temp_buf for the
Log_event class is pointing to the incoming stream.
*/
if (remote_opt)
ev->register_temp_buf((char*) net->read_pos + 1);
Log_event_type type= ev->get_type_code(); Log_event_type type= ev->get_type_code();
if (glob_description_event->binlog_version >= 3 || if (glob_description_event->binlog_version >= 3 ||
......
...@@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM ...@@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM
# #
# When changing major version number please also check switch statement # When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version(). # in mysqlbinlog::check_master_version().
AM_INIT_AUTOMAKE(mysql, 5.1.19-beta) AM_INIT_AUTOMAKE(mysql, 5.1.20-beta)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
......
...@@ -350,7 +350,10 @@ inline double ulonglong2double(ulonglong value) ...@@ -350,7 +350,10 @@ inline double ulonglong2double(ulonglong value)
#define SPRINTF_RETURNS_INT #define SPRINTF_RETURNS_INT
#define HAVE_SETFILEPOINTER #define HAVE_SETFILEPOINTER
#define HAVE_VIO_READ_BUFF #define HAVE_VIO_READ_BUFF
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* strnlen() appeared in Studio 2005 */
#define HAVE_STRNLEN #define HAVE_STRNLEN
#endif
#define HAVE_WINSOCK2 #define HAVE_WINSOCK2
#define strcasecmp stricmp #define strcasecmp stricmp
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986) # Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986)
-- source include/master-slave.inc -- source include/master-slave.inc
source include/have_innodb.inc;
connection slave; connection slave;
reset master; reset master;
...@@ -156,4 +157,15 @@ drop table t2; ...@@ -156,4 +157,15 @@ drop table t2;
connection master; connection master;
drop table t2; drop table t2;
drop table t1; drop table t1;
# BUG#17233 LOAD DATA INFILE: failure causes mysqld dbug_assert, binlog not flushed
CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
--error ER_DUP_ENTRY_WITH_KEY_NAME
LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1;
--disable warnings
DROP TABLE IF EXISTS t1;
--enable warnings
# End of 4.1 tests # End of 4.1 tests
...@@ -1804,6 +1804,18 @@ sub environment_setup () { ...@@ -1804,6 +1804,18 @@ sub environment_setup () {
$ENV{'CHARSETSDIR'}= $path_charsetsdir; $ENV{'CHARSETSDIR'}= $path_charsetsdir;
$ENV{'UMASK'}= "0660"; # The octal *string* $ENV{'UMASK'}= "0660"; # The octal *string*
$ENV{'UMASK_DIR'}= "0770"; # The octal *string* $ENV{'UMASK_DIR'}= "0770"; # The octal *string*
#
# MySQL tests can produce output in various character sets
# (especially, ctype_xxx.test). To avoid confusing Perl
# with output which is incompatible with the current locale
# settings, we reset the current values of LC_ALL and LC_CTYPE to "C".
# For details, please see
# Bug#27636 tests fails if LC_* variables set to *_*.UTF-8
#
$ENV{'LC_ALL'}= "C";
$ENV{'LC_CTYPE'}= "C";
$ENV{'LC_COLLATE'}= "C"; $ENV{'LC_COLLATE'}= "C";
$ENV{'USE_RUNNING_SERVER'}= $opt_extern; $ENV{'USE_RUNNING_SERVER'}= $opt_extern;
$ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir; $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir;
...@@ -3851,13 +3863,15 @@ sub mysqld_arguments ($$$$) { ...@@ -3851,13 +3863,15 @@ sub mysqld_arguments ($$$$) {
} }
else else
{ {
mtr_add_arg($args, "%s--master-user=root", $prefix); if ($mysql_version_id < 50200)
mtr_add_arg($args, "%s--master-connect-retry=1", $prefix); {
mtr_add_arg($args, "%s--master-host=127.0.0.1", $prefix); mtr_add_arg($args, "%s--master-user=root", $prefix);
mtr_add_arg($args, "%s--master-password=", $prefix); mtr_add_arg($args, "%s--master-connect-retry=1", $prefix);
mtr_add_arg($args, "%s--master-port=%d", $prefix, mtr_add_arg($args, "%s--master-host=127.0.0.1", $prefix);
$master->[0]->{'port'}); # First master mtr_add_arg($args, "%s--master-password=", $prefix);
mtr_add_arg($args, "%s--master-port=%d", $prefix,
$master->[0]->{'port'}); # First master
}
my $slave_server_id= 2 + $idx; my $slave_server_id= 2 + $idx;
my $slave_rpl_rank= $slave_server_id; my $slave_rpl_rank= $slave_server_id;
mtr_add_arg($args, "%s--server-id=%d", $prefix, $slave_server_id); mtr_add_arg($args, "%s--server-id=%d", $prefix, $slave_server_id);
......
create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM;
create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
select get_lock("a", 20);
get_lock("a", 20)
1
reset master;
insert into t2 values (null, null), (null, get_lock("a", 10));
select @result /* must be zero either way */;
@result
0
drop table t1,t2,t3;
...@@ -31,7 +31,7 @@ Master_Host 127.0.0.1 ...@@ -31,7 +31,7 @@ Master_Host 127.0.0.1
Master_User root Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000002 Master_Log_File #
Read_Master_Log_Pos # Read_Master_Log_Pos #
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
...@@ -74,7 +74,7 @@ Master_Host 127.0.0.1 ...@@ -74,7 +74,7 @@ Master_Host 127.0.0.1
Master_User root Master_User root
Master_Port MASTER_PORT Master_Port MASTER_PORT
Connect_Retry 1 Connect_Retry 1
Master_Log_File master-bin.000002 Master_Log_File #
Read_Master_Log_Pos # Read_Master_Log_Pos #
Relay_Log_File # Relay_Log_File #
Relay_Log_Pos # Relay_Log_Pos #
...@@ -104,4 +104,3 @@ Master_SSL_Key ...@@ -104,4 +104,3 @@ Master_SSL_Key
Seconds_Behind_Master # Seconds_Behind_Master #
Master_SSL_Verify_Server_Cert No Master_SSL_Verify_Server_Cert No
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t1;
...@@ -86,3 +86,7 @@ ERROR 23000: Duplicate entry '2003-03-22' for key 'day' ...@@ -86,3 +86,7 @@ ERROR 23000: Duplicate entry '2003-03-22' for key 'day'
drop table t2; drop table t2;
drop table t2; drop table t2;
drop table t1; drop table t1;
CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB;
LOAD DATA INFILE "../std_data_ln/words.dat" INTO TABLE t1;
ERROR 23000: Duplicate entry 'Aarhus' for key 'PRIMARY'
DROP TABLE IF EXISTS t1;
...@@ -159,8 +159,8 @@ Replicate_Do_Table ...@@ -159,8 +159,8 @@ Replicate_Do_Table
Replicate_Ignore_Table <Replicate_Ignore_Table> Replicate_Ignore_Table <Replicate_Ignore_Table>
Replicate_Wild_Do_Table Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table Replicate_Wild_Ignore_Table
Last_Errno 1105 Last_Errno <Last_Errno>
Last_Error Unknown error Last_Error <Last_Error>
Skip_Counter 0 Skip_Counter 0
Exec_Master_Log_Pos <Exec_Master_Log_Pos> Exec_Master_Log_Pos <Exec_Master_Log_Pos>
Relay_Log_Space <Relay_Log_Space> Relay_Log_Space <Relay_Log_Space>
......
...@@ -190,6 +190,75 @@ DELIMITER ; ...@@ -190,6 +190,75 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */; ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- Test 4 Second Remote test --
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
stop slave;
reset master;
reset slave;
start slave;
SELECT COUNT(*) from t1;
COUNT(*)
352
SELECT COUNT(*) from t2;
COUNT(*)
500
SELECT COUNT(*) from t3;
COUNT(*)
500
SELECT * FROM t1 ORDER BY word LIMIT 5;
word
Aarhus
Aarhus
Aarhus
Aarhus
Aarhus
SELECT * FROM t2 ORDER BY id LIMIT 5;
id
1
2
3
4
5
SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5;
c1 c3 c4 c5
1 2006-02-22 00:00:00 Tested in Texas 2.2
2 2006-02-22 00:00:00 Tested in Texas 4.4
3 2006-02-22 00:00:00 Tested in Texas 6.6
4 2006-02-22 00:00:00 Tested in Texas 8.8
5 2006-02-22 00:00:00 Tested in Texas 11
SELECT COUNT(*) from t1;
COUNT(*)
352
SELECT COUNT(*) from t2;
COUNT(*)
500
SELECT COUNT(*) from t3;
COUNT(*)
500
SELECT * FROM t1 ORDER BY word LIMIT 5;
word
Aarhus
Aarhus
Aarhus
Aarhus
Aarhus
SELECT * FROM t2 ORDER BY id LIMIT 5;
id
1
2
3
4
5
SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5;
c1 c3 c4 c5
1 2006-02-22 00:00:00 Tested in Texas 2.2
2 2006-02-22 00:00:00 Tested in Texas 4.4
3 2006-02-22 00:00:00 Tested in Texas 6.6
4 2006-02-22 00:00:00 Tested in Texas 8.8
5 2006-02-22 00:00:00 Tested in Texas 11
--- Test 5 LOAD DATA -- --- Test 5 LOAD DATA --
/*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
...@@ -273,4 +342,11 @@ HEX(f) ...@@ -273,4 +342,11 @@ HEX(f)
835C 835C
--- Test cleanup -- --- Test cleanup --
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT NOT NULL KEY, b INT);
INSERT INTO t1 VALUES(1,1);
SELECT * FROM t1;
a b
1 1
FLUSH LOGS;
DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5; DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5;
...@@ -19,9 +19,41 @@ n ...@@ -19,9 +19,41 @@ n
2 2
3 3
4 4
show slave status; 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 Slave_IO_State #
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-bin.000001 311 No # No 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 744
Relay_Log_File slave-relay-bin.000004
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running #
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 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 315
Relay_Log_Space #
Until_Condition Master
Until_Log_File master-bin.000001
Until_Log_Pos 311
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
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
select * from t1; select * from t1;
n n
...@@ -29,23 +61,119 @@ n ...@@ -29,23 +61,119 @@ n
2 2
3 3
4 4
show slave status; 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 Slave_IO_State #
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 315 # Master master-no-such-bin.000001 291 No # No 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 744
Relay_Log_File slave-relay-bin.000004
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running #
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 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 315
Relay_Log_Space #
Until_Condition Master
Until_Log_File master-no-such-bin.000001
Until_Log_Pos 291
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
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728;
select * from t2; select * from t2;
n n
1 1
2 2
show slave status; 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 Slave_IO_State #
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 # No 0 0 590 # Relay slave-relay-bin.000004 728 No # No 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 744
Relay_Log_File slave-relay-bin.000004
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
Slave_IO_Running #
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 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 590
Relay_Log_Space #
Until_Condition Relay
Until_Log_File slave-relay-bin.000004
Until_Log_Pos 728
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
start slave; start slave;
stop slave; stop slave;
start slave until master_log_file='master-bin.000001', master_log_pos=740; start slave until master_log_file='master-bin.000001', master_log_pos=740;
show slave status; 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 Slave_IO_State #
# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 744 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 744 # Master master-bin.000001 740 No # No 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 744
Relay_Log_File slave-relay-bin.000004
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 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 744
Relay_Log_Space #
Until_Condition Master
Until_Log_File master-bin.000001
Until_Log_Pos 740
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
start slave until master_log_file='master-bin', master_log_pos=561; start slave until master_log_file='master-bin', master_log_pos=561;
ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
......
...@@ -547,6 +547,13 @@ UpdateXML(@xml, '/a/b/@bb2', '') ...@@ -547,6 +547,13 @@ UpdateXML(@xml, '/a/b/@bb2', '')
select UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"'); select UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"');
UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"') UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"')
<a aa1="aa1" aa2="aa2"><b bb1="bb1" bb3="bb3">bb</b></a> <a aa1="aa1" aa2="aa2"><b bb1="bb1" bb3="bb3">bb</b></a>
select updatexml('<div><div><span>1</span><span>2</span></div></div>',
'/','<tr><td>1</td><td>2</td></tr>') as upd1;
upd1
<tr><td>1</td><td>2</td></tr>
select updatexml('', '/', '') as upd2;
upd2
SET @xml= '<order><clerk>lesser wombat</clerk></order>'; SET @xml= '<order><clerk>lesser wombat</clerk></order>';
select extractvalue(@xml,'order/clerk'); select extractvalue(@xml,'order/clerk');
extractvalue(@xml,'order/clerk') extractvalue(@xml,'order/clerk')
...@@ -884,3 +891,124 @@ test ...@@ -884,3 +891,124 @@ test
select ExtractValue('<a><self>test</self></a>', '/a/self'); select ExtractValue('<a><self>test</self></a>', '/a/self');
ExtractValue('<a><self>test</self></a>', '/a/self') ExtractValue('<a><self>test</self></a>', '/a/self')
test test
set @i=1;
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
b1
set @i=2;
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
b2
set @i=NULL;
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
CREATE PROCEDURE spxml(xml VARCHAR(128))
BEGIN
DECLARE c INT;
DECLARE i INT DEFAULT 1;
SET c= ExtractValue(xml,'count(/a/b)');
SET @i= c;
WHILE i <= c DO
BEGIN
SELECT i, @i, ExtractValue(xml,'/a/b[$i]'), ExtractValue(xml,'/a/b[$@i]');
SET i= i + 1;
SET @i= @i - 1;
END;
END WHILE;
END|
call spxml('<a><b>b1</b><b>b2</b><b>b3</b></a>');
i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]')
1 3 b1 b3
i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]')
2 2 b2 b2
i @i ExtractValue(xml,'/a/b[$i]') ExtractValue(xml,'/a/b[$@i]')
3 1 b3 b1
drop procedure spxml;
Multiple matches, but no index specification
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b')
b1 b2
No matches
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/c');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/c')
Index out of range
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[-1]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[-1]')
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[10]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[10]')
With string-to-number conversion
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1"]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1"]')
b1
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1 and string"]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1 and string"]')
b1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '1 and string"]'
Warning 1292 Truncated incorrect INTEGER value: '1 and string"]'
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string and 1"]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string and 1"]')
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'string and 1"]'
Warning 1292 Truncated incorrect INTEGER value: 'string and 1"]'
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string"]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string"]')
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'string"]'
Warning 1292 Truncated incorrect INTEGER value: 'string"]'
String-to-number conversion from a user variable
SET @i='1';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
b1
SET @i='1 and string';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
b1
SET @i='string and 1';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
SET @i='string';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]')
String-to-number conversion with a CHAR SP variable
CREATE PROCEDURE spxml(xml VARCHAR(128), i CHAR(16))
BEGIN
SELECT ExtractValue(xml,'/a/b[$i]');
END|
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1');
ExtractValue(xml,'/a/b[$i]')
b1
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1 and string');
ExtractValue(xml,'/a/b[$i]')
b1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '1 and string '
Warning 1292 Truncated incorrect INTEGER value: '1 and string '
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string and 1');
ExtractValue(xml,'/a/b[$i]')
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'string and 1 '
Warning 1292 Truncated incorrect INTEGER value: 'string and 1 '
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string');
ExtractValue(xml,'/a/b[$i]')
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'string '
Warning 1292 Truncated incorrect INTEGER value: 'string '
DROP PROCEDURE spxml;
select UpdateXML('<a>a</a>',repeat('a b ',1000),'');
ERROR HY000: XPATH syntax error: 'b a b a b a b a b a b a b a b a '
select ExtractValue('<a>a</a>', '/a[@x=@y0123456789_0123456789_0123456789_0123456789]');
ERROR HY000: XPATH error: comparison of two nodesets is not supported: '=@y0123456789_0123456789_0123456'
select ExtractValue('<a>a</a>', '/a[@x=$y0123456789_0123456789_0123456789_0123456789]');
ERROR HY000: Unknown XPATH variable at: '$y0123456789_0123456789_01234567'
-- source include/have_innodb.inc
-- source include/have_binlog_format_mixed_or_statement.inc
-- source include/not_embedded.inc
###
### bug#22725 : incorrect killed error in binlogged query
###
connect (con1, localhost, root,,);
connect (con2, localhost, root,,);
create table t1 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
create table t2 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=MyISAM;
create table t3 (a int auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB;
#
# effective test for bug#22725
#
connection con1;
select get_lock("a", 20);
connection con2;
let $ID= `select connection_id()`;
reset master;
send insert into t2 values (null, null), (null, get_lock("a", 10));
connection con1;
disable_abort_on_error;
disable_query_log;
disable_result_log;
eval kill query $ID;
connection con2;
--error 0,ER_QUERY_INTERRUPTED
reap;
let $rows= `select count(*) from t2 /* must be 2 or 0 */`;
--exec $MYSQL_BINLOG --start-position=134 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog"))
is not null;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
let $error_code= `select @a like "%#%error_code=0%" /* must return 1 or 0*/`;
let $insert_binlogged= `select @a like "%insert into%" /* must return 1 or 0 */`;
eval set @result= $rows- $error_code - $insert_binlogged;
enable_abort_on_error;
enable_query_log;
enable_result_log;
select @result /* must be zero either way */;
# the functions are either *insensitive* to killing or killing can cause
# strange problmes with the error propagation out of SF's stack
# Bug#27563, Bug#27565, BUG#24971
#
# TODO: use if's block as regression test for the bugs or remove
#
if (0)
{
delimiter |;
create function bug27563()
RETURNS int(11)
DETERMINISTIC
begin
select get_lock("a", 10) into @a;
return 1;
end|
delimiter ;|
# the function is sensitive to killing requiring innodb though with wrong client error
# TO FIX in BUG#27565; TODO: remove --error 1105 afterwards
delimiter |;
create function bug27565()
RETURNS int(11)
DETERMINISTIC
begin
select a from t1 where a=1 into @a for update;
return 1;
end|
delimiter ;|
reset master;
### ta table case: killing causes rollback
# A. autocommit ON
connection con1;
select get_lock("a", 20);
connection con2;
let $ID= `select connection_id()`;
send insert into t1 values (bug27563(),1);
connection con1;
eval kill query $ID;
connection con2;
# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
--enable_info
# todo: remove 0 return after fixing Bug#27563
--error 0,ER_QUERY_INTERRUPTED
reap; ### pb: wrong error
--disable_info
###--replace_column 2 # 5 #
### show binlog events from 98 /* nothing in binlog unless Bug#27563 */;
show master status /* must be only FD event unless Bug#27563 */;
select count(*) from t1 /* must be zero unless Bug#27563 */;
# M. multi-statement-ta
connection con2;
let $ID= `select connection_id()`;
begin;
send insert into t1 values (bug27563(),1);
connection con1;
eval kill query $ID;
connection con2;
# todo (re-record test): after bugs 27563,27565 got fixed affected rows will report zero
--enable_info
# todo: remove 0 return after fixing Bug#27563
--error 0,ER_QUERY_INTERRUPTED
reap;
--disable_info
select count(*) from t1 /* must be zero unless Bug#27563 */;
commit;
### non-ta table case: killing must be recorded in binlog
reset master;
connection con2;
let $ID= `select connection_id()`;
send insert into t2 values (bug27563(),1);
connection con1;
eval kill query $ID;
connection con2;
# todo: remove 0 return after fixing Bug#27563
--error 0,ER_QUERY_INTERRUPTED
reap;
select count(*) from t2 /* must be one */;
#show binlog events from 98 /* must have the insert on non-ta table */;
show master status /* must have the insert event more to FD */;
# the value of the error flag of KILLED_QUERY is tested further
connection con1;
select RELEASE_LOCK("a");
### test with effective killing of SF()
delete from t1;
delete from t2;
insert into t1 values (1,1);
insert into t2 values (1,1);
#
# Bug#27565
# test where KILL is propagated as error to the top level
# still another bug with the error message to the user
# todo: fix reexecute the result file after fixing
#
begin; update t1 set b=0 where a=1;
connection con2;
let $ID= `select connection_id()`;
send update t2 set b=bug27565()-1 where a=1;
connection con1;
eval kill query $ID;
commit;
connection con2;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# remove 1105 (wrong)
#--error ER_QUERY_INTERRUPTED
--error 1105,ER_QUERY_INTERRUPTED
reap; ### pb: wrong error
select * from t1 /* must be: (1,0) */;
select * from t2 /* must be as before: (1,1) */;
## bug#22725 with effective and propagating killing
#
# top-level ta-table
connection con1;
delete from t3;
reset master;
begin; update t1 set b=0 where a=1;
connection con2;
let $ID= `select connection_id()`;
# the query won't perform completely since the function gets interrupted
send insert into t3 values (0,0),(1,bug27565());
connection con1;
eval kill query $ID;
rollback;
connection con2;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# remove 1105 (wrong)
#--error ER_QUERY_INTERRUPTED
--error 1105,ER_QUERY_INTERRUPTED
reap; ### pb: wrong error
select count(*) from t3 /* must be zero */;
show master status /* nothing in binlog */;
# top-level non-ta-table
connection con1;
delete from t2;
reset master;
begin; update t1 set b=0 where a=1;
connection con2;
let $ID= `select connection_id()`;
# the query won't perform completely since the function gets intrurrupted
send insert into t2 values (0,0),(1,bug27565()) /* non-ta t2 */;
connection con1;
eval kill query $ID;
rollback;
connection con2;
# todo: fix Bug #27565 killed query of SF() is not reported correctly and
# remove 1105 (wrong)
#--error ER_QUERY_INTERRUPTED
--error 1105,ER_QUERY_INTERRUPTED
reap; ### pb: wrong error
select count(*) from t2 /* count must be one */;
show master status /* insert into non-ta must be in binlog */;
drop function bug27563;
drop function bug27565;
}
system rm $MYSQLTEST_VARDIR/tmp/kill_query_calling_sp.binlog ;
drop table t1,t2,t3;
...@@ -27,11 +27,10 @@ rpl_ndb_circular_simplex : BUG#27972 2007-04-20 mats Slave cannot start where it ...@@ -27,11 +27,10 @@ rpl_ndb_circular_simplex : BUG#27972 2007-04-20 mats Slave cannot start where it
rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated
rpl_ndb_2myisam : BUG#19227 Seems to pass currently rpl_ndb_2myisam : BUG#19227 Seems to pass currently
rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD
rpl_ndb_ddl : BUG#18946 result file needs update + test needs to checked
rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master rpl_ddl : BUG#26418 2007-03-01 mleich Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK on master
rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement
rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly #rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
#ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events
......
...@@ -22,7 +22,7 @@ connection slave; ...@@ -22,7 +22,7 @@ connection slave;
SELECT * FROM t1; SELECT * FROM t1;
--replace_result $MASTER_MYPORT MASTER_PORT --replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # --replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical SHOW SLAVE STATUS --query_vertical SHOW SLAVE STATUS
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
...@@ -34,10 +34,9 @@ START SLAVE; ...@@ -34,10 +34,9 @@ START SLAVE;
SELECT * FROM t1; SELECT * FROM t1;
--replace_result $MASTER_MYPORT MASTER_PORT --replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # --replace_column 1 # 6 # 7 # 8 # 9 # 22 # 23 # 33 #
--query_vertical SHOW SLAVE STATUS --query_vertical SHOW SLAVE STATUS
DROP TABLE t1;
connection master; connection master;
DROP TABLE t1; DROP TABLE t1;
--sync_slave_with_master
...@@ -197,7 +197,7 @@ UPDATE t1 SET `nom`="DEAD" WHERE `nid`=1; ...@@ -197,7 +197,7 @@ UPDATE t1 SET `nom`="DEAD" WHERE `nid`=1;
--connection slave --connection slave
--echo **** On Slave **** --echo **** On Slave ****
--replace_result $MASTER_MYPORT MASTER_PORT --replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 <Slave_IO_State> 7 <Read_Master_Log_Pos> 8 <Relay_Log_File> 9 <Relay_Log_Pos> 16 <Replicate_Ignore_Table> 22 <Exec_Master_Log_Pos> 23 <Relay_Log_Space> 33 <Seconds_Behind_Master> --replace_column 1 <Slave_IO_State> 7 <Read_Master_Log_Pos> 8 <Relay_Log_File> 9 <Relay_Log_Pos> 16 <Replicate_Ignore_Table> 19 <Last_Errno> 20 <Last_Error> 22 <Exec_Master_Log_Pos> 23 <Relay_Log_Space> 33 <Seconds_Behind_Master>
--query_vertical SHOW SLAVE STATUS; --query_vertical SHOW SLAVE STATUS;
# now set max retries high enough to succeed, and start slave again # now set max retries high enough to succeed, and start slave again
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
# #
--source include/master-slave.inc --source include/master-slave.inc
--source include/have_binlog_format_row.inc
--source include/have_ndb.inc --source include/have_ndb.inc
let $engine_type= NDB; let $engine_type= NDB;
let $temp_engine_type= MEMORY; let $temp_engine_type= MEMORY;
......
...@@ -183,67 +183,67 @@ select "--- Test 3 First Remote test --" as ""; ...@@ -183,67 +183,67 @@ select "--- Test 3 First Remote test --" as "";
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 --exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
# This part is disabled due to bug #17654 # This part is disabled due to bug #17654
################### Start Bug 17654 ######################
#--disable_query_log
#select "--- Test 4 Second Remote test --" as "";
#--enable_query_log
#--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql
#--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 >> $MYSQLTEST_VARDIR/tmp/remote.sql --disable_query_log
select "--- Test 4 Second Remote test --" as "";
--enable_query_log
--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql
--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 >> $MYSQLTEST_VARDIR/tmp/remote.sql
# Now that we have our file, lets get rid of the current database. # Now that we have our file, lets get rid of the current database.
# Cleanup the master and the slave and try to recreate. # Cleanup the master and the slave and try to recreate.
#DROP TABLE t1; DROP TABLE t1;
#DROP TABLE t2; DROP TABLE t2;
#DROP TABLE t3; DROP TABLE t3;
#sync_slave_with_master; sync_slave_with_master;
#we expect STOP SLAVE to produce a warning as the slave is stopped #we expect STOP SLAVE to produce a warning as the slave is stopped
#(the server was started with skip-slave-start) #(the server was started with skip-slave-start)
#--disable_warnings --disable_warnings
#stop slave; stop slave;
#--enable_warnings --enable_warnings
#--require r/slave-stopped.result --require r/slave-stopped.result
#show status like 'Slave_running'; show status like 'Slave_running';
#connection master; connection master;
#reset master; reset master;
#connection slave; connection slave;
#reset slave; reset slave;
#start slave; start slave;
#--require r/slave-running.result --require r/slave-running.result
#show status like 'Slave_running'; show status like 'Slave_running';
#connection master; connection master;
# We should be clean at this point, now we will run in the file from above. # We should be clean at this point, now we will run in the file from above.
#--exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/remote.sql" --exec $MYSQL -e "source $MYSQLTEST_VARDIR/tmp/remote.sql"
# Lets Check the tables on the Master # Lets Check the tables on the Master
#SELECT COUNT(*) from t1; SELECT COUNT(*) from t1;
#SELECT COUNT(*) from t2; SELECT COUNT(*) from t2;
#SELECT COUNT(*) from t3; SELECT COUNT(*) from t3;
#SELECT * FROM t1 ORDER BY word LIMIT 5; SELECT * FROM t1 ORDER BY word LIMIT 5;
#SELECT * FROM t2 ORDER BY id LIMIT 5; SELECT * FROM t2 ORDER BY id LIMIT 5;
#SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5;
# Should have the same on the slave; # Should have the same on the slave;
#sync_slave_with_master; sync_slave_with_master;
#SELECT COUNT(*) from t1; SELECT COUNT(*) from t1;
#SELECT COUNT(*) from t2; SELECT COUNT(*) from t2;
#SELECT COUNT(*) from t3; SELECT COUNT(*) from t3;
#SELECT * FROM t1 ORDER BY word LIMIT 5; SELECT * FROM t1 ORDER BY word LIMIT 5;
#SELECT * FROM t2 ORDER BY id LIMIT 5; SELECT * FROM t2 ORDER BY id LIMIT 5;
#SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5; SELECT c1, c3, c4, c5 FROM t3 ORDER BY c1 LIMIT 5;
#connection master; connection master;
# We should be gold by the time, so I will get rid of our file. # We should be gold by the time, so I will get rid of our file.
#--exec rm $MYSQLTEST_VARDIR/tmp/remote.sql --exec rm $MYSQLTEST_VARDIR/tmp/remote.sql
################### End Bug 17654 ###################### ################### End Bug 17654 ######################
# LOAD DATA # LOAD DATA
...@@ -315,7 +315,34 @@ select "--- Test cleanup --" as ""; ...@@ -315,7 +315,34 @@ select "--- Test cleanup --" as "";
--enable_query_log --enable_query_log
# clean up # clean up
connection master; connection master;
DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5;
sync_slave_with_master; sync_slave_with_master;
connection master;
# BUG#17654 also test mysqlbinlog to ensure it can read the binlog from a remote server
# and ensure that the results are the same as if read from a file (the same file).
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a INT NOT NULL KEY, b INT);
INSERT INTO t1 VALUES(1,1);
SELECT * FROM t1;
FLUSH LOGS;
--exec $MYSQL_BINLOG --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 > $MYSQLTEST_VARDIR/tmp/remote.sql
--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/local.sql
--diff_files $MYSQLTEST_VARDIR/tmp/local.sql $MYSQLTEST_VARDIR/tmp/remote.sql
--exec rm $MYSQLTEST_VARDIR/tmp/remote.sql
--exec rm $MYSQLTEST_VARDIR/tmp/local.sql
DROP TABLE IF EXISTS t1, t2, t3, t04, t05, t4, t5;
# End of 4.1 tests # End of 4.1 tests
...@@ -33,7 +33,7 @@ wait_for_slave_to_stop; ...@@ -33,7 +33,7 @@ wait_for_slave_to_stop;
select * from t1; select * from t1;
--replace_result $MASTER_MYPORT MASTER_MYPORT --replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 # --replace_column 1 # 9 # 11 # 23 # 33 #
show slave status; --query_vertical SHOW SLAVE STATUS;
# this should fail right after start # this should fail right after start
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
...@@ -43,7 +43,7 @@ sleep 2; ...@@ -43,7 +43,7 @@ sleep 2;
wait_for_slave_to_stop; wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_MYPORT --replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 # --replace_column 1 # 9 # 11 # 23 # 33 #
show slave status; --query_vertical SHOW SLAVE STATUS;
# try replicate all up to and not including the second insert to t2; # try replicate all up to and not including the second insert to t2;
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728;
...@@ -52,7 +52,7 @@ wait_for_slave_to_stop; ...@@ -52,7 +52,7 @@ wait_for_slave_to_stop;
select * from t2; select * from t2;
--replace_result $MASTER_MYPORT MASTER_MYPORT --replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 # --replace_column 1 # 9 # 11 # 23 # 33 #
show slave status; --query_vertical SHOW SLAVE STATUS;
# clean up # clean up
start slave; start slave;
...@@ -69,7 +69,7 @@ wait_for_slave_to_stop; ...@@ -69,7 +69,7 @@ wait_for_slave_to_stop;
# here the sql slave thread should be stopped # here the sql slave thread should be stopped
--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 --replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
--replace_column 1 # 9 # 23 # 33 # --replace_column 1 # 9 # 23 # 33 #
show slave status; --query_vertical SHOW SLAVE STATUS;
#testing various error conditions #testing various error conditions
--error 1277 --error 1277
......
...@@ -231,6 +231,13 @@ select UpdateXML(@xml, '/a/b/@bb1', 'bb3="bb3"'); ...@@ -231,6 +231,13 @@ select UpdateXML(@xml, '/a/b/@bb1', 'bb3="bb3"');
select UpdateXML(@xml, '/a/b/@bb2', ''); select UpdateXML(@xml, '/a/b/@bb2', '');
select UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"'); select UpdateXML(@xml, '/a/b/@bb2', 'bb3="bb3"');
#
# Bug#27898 UPDATEXML Crashes the Server!
#
select updatexml('<div><div><span>1</span><span>2</span></div></div>',
'/','<tr><td>1</td><td>2</td></tr>') as upd1;
select updatexml('', '/', '') as upd2;
# #
# Bug#16234 XML: Crash if ExtractValue() # Bug#16234 XML: Crash if ExtractValue()
# #
...@@ -444,3 +451,85 @@ select ExtractValue('<a><parent>test</parent></a>', '/a/parent'); ...@@ -444,3 +451,85 @@ select ExtractValue('<a><parent>test</parent></a>', '/a/parent');
select ExtractValue('<a><preceding>test</preceding></a>', '/a/preceding'); select ExtractValue('<a><preceding>test</preceding></a>', '/a/preceding');
select ExtractValue('<a><preceding-sibling>test</preceding-sibling></a>', '/a/preceding-sibling'); select ExtractValue('<a><preceding-sibling>test</preceding-sibling></a>', '/a/preceding-sibling');
select ExtractValue('<a><self>test</self></a>', '/a/self'); select ExtractValue('<a><self>test</self></a>', '/a/self');
#
# Bug#26518 XPath and variables problem
# Check with user defined variables
#
set @i=1;
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
set @i=2;
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
set @i=NULL;
select ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
#
# Check variables in a stored procedure - both local and user variables
# Make sure that SP and local variables with the same name work together.
#
DELIMITER |;
CREATE PROCEDURE spxml(xml VARCHAR(128))
BEGIN
DECLARE c INT;
DECLARE i INT DEFAULT 1;
SET c= ExtractValue(xml,'count(/a/b)');
SET @i= c;
WHILE i <= c DO
BEGIN
SELECT i, @i, ExtractValue(xml,'/a/b[$i]'), ExtractValue(xml,'/a/b[$@i]');
SET i= i + 1;
SET @i= @i - 1;
END;
END WHILE;
END|
DELIMITER ;|
call spxml('<a><b>b1</b><b>b2</b><b>b3</b></a>');
drop procedure spxml;
#
# Additional tests for bug#26518
--echo Multiple matches, but no index specification
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b');
--echo No matches
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/c');
--echo Index out of range
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[-1]');
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[10]');
--echo With string-to-number conversion
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1"]');
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["1 and string"]');
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string and 1"]');
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b["string"]');
--echo String-to-number conversion from a user variable
SET @i='1';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
SET @i='1 and string';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
SET @i='string and 1';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
SET @i='string';
SELECT ExtractValue('<a><b>b1</b><b>b2</b></a>','/a/b[$@i]');
--echo String-to-number conversion with a CHAR SP variable
DELIMITER |;
CREATE PROCEDURE spxml(xml VARCHAR(128), i CHAR(16))
BEGIN
SELECT ExtractValue(xml,'/a/b[$i]');
END|
DELIMITER ;|
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1');
CALL spxml('<a><b>b1</b><b>b2</b></a>', '1 and string');
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string and 1');
CALL spxml('<a><b>b1</b><b>b2</b></a>', 'string');
DROP PROCEDURE spxml;
#
# Bug#28558 UpdateXML called with garbage crashes server
#
--error 1105
select UpdateXML('<a>a</a>',repeat('a b ',1000),'');
--error 1105
select ExtractValue('<a>a</a>', '/a[@x=@y0123456789_0123456789_0123456789_0123456789]');
--error 1105
select ExtractValue('<a>a</a>', '/a[@x=$y0123456789_0123456789_0123456789_0123456789]');
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include "my_xml.h" #include "my_xml.h"
#include "sp_pcontext.h"
/* /*
TODO: future development directions: TODO: future development directions:
...@@ -923,8 +923,8 @@ static Item *create_comparator(MY_XPATH *xpath, ...@@ -923,8 +923,8 @@ static Item *create_comparator(MY_XPATH *xpath,
else if (a->type() == Item::XPATH_NODESET && else if (a->type() == Item::XPATH_NODESET &&
b->type() == Item::XPATH_NODESET) b->type() == Item::XPATH_NODESET)
{ {
uint len= context->end - context->beg; uint len= xpath->query.end - context->beg;
set_if_bigger(len, 32); set_if_smaller(len, 32);
my_printf_error(ER_UNKNOWN_ERROR, my_printf_error(ER_UNKNOWN_ERROR,
"XPATH error: " "XPATH error: "
"comparison of two nodesets is not supported: '%.*s'", "comparison of two nodesets is not supported: '%.*s'",
...@@ -2412,21 +2412,78 @@ my_xpath_parse_QName(MY_XPATH *xpath) ...@@ -2412,21 +2412,78 @@ my_xpath_parse_QName(MY_XPATH *xpath)
} }
/* /**
Scan Variable reference Scan Variable reference
SYNOPSYS @details Implements parsing of two syntax structures:
[36] VariableReference ::= '$' QName 1. Standard XPath syntax [36], for SP variables:
RETURN
1 - success VariableReference ::= '$' QName
0 - failure
Finds a SP variable with the given name.
If outside of a SP context, or variable with
the given name doesn't exists, then error is returned.
2. Non-standard syntax - MySQL extension for user variables:
VariableReference ::= '$' '@' QName
Item, corresponding to the variable, is returned
in xpath->item in both cases.
@param xpath pointer to XPath structure
@return Operation status
@retval 1 Success
@retval 0 Failure
*/ */
static int static int
my_xpath_parse_VariableReference(MY_XPATH *xpath) my_xpath_parse_VariableReference(MY_XPATH *xpath)
{ {
return my_xpath_parse_term(xpath, MY_XPATH_LEX_DOLLAR) && LEX_STRING name;
my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT); int user_var;
const char *dollar_pos;
if (!my_xpath_parse_term(xpath, MY_XPATH_LEX_DOLLAR) ||
(!(dollar_pos= xpath->prevtok.beg)) ||
(!((user_var= my_xpath_parse_term(xpath, MY_XPATH_LEX_AT) &&
my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT))) &&
!my_xpath_parse_term(xpath, MY_XPATH_LEX_IDENT)))
return 0;
name.length= xpath->prevtok.end - xpath->prevtok.beg;
name.str= (char*) xpath->prevtok.beg;
if (user_var)
xpath->item= new Item_func_get_user_var(name);
else
{
sp_variable_t *spv;
sp_pcontext *spc;
LEX *lex;
if ((lex= current_thd->lex) &&
(spc= lex->spcont) &&
(spv= spc->find_variable(&name)))
{
Item_splocal *splocal= new Item_splocal(name, spv->offset, spv->type, 0);
#ifndef DBUG_OFF
if (splocal)
splocal->m_sp= lex->sphead;
#endif
xpath->item= (Item*) splocal;
}
else
{
xpath->item= NULL;
DBUG_ASSERT(xpath->query.end > dollar_pos);
uint len= xpath->query.end - dollar_pos;
set_if_smaller(len, 32);
my_printf_error(ER_UNKNOWN_ERROR, "Unknown XPATH variable at: '%.*s'",
MYF(0), len, dollar_pos);
}
}
return xpath->item ? 1 : 0;
} }
...@@ -2534,12 +2591,10 @@ void Item_xml_str_func::fix_length_and_dec() ...@@ -2534,12 +2591,10 @@ void Item_xml_str_func::fix_length_and_dec()
if (!rc) if (!rc)
{ {
char context[32];
uint clen= xpath.query.end - xpath.lasttok.beg; uint clen= xpath.query.end - xpath.lasttok.beg;
set_if_bigger(clen, sizeof(context) - 1); set_if_smaller(clen, 32);
strmake(context, xpath.lasttok.beg, clen); my_printf_error(ER_UNKNOWN_ERROR, "XPATH syntax error: '%.*s'",
my_printf_error(ER_UNKNOWN_ERROR, "XPATH syntax error: '%s'", MYF(0), clen, xpath.lasttok.beg);
MYF(0), context);
return; return;
} }
...@@ -2768,6 +2823,16 @@ String *Item_func_xml_update::val_str(String *str) ...@@ -2768,6 +2823,16 @@ String *Item_func_xml_update::val_str(String *str)
nodebeg+= fltbeg->num; nodebeg+= fltbeg->num;
if (!nodebeg->level)
{
/*
Root element, without NameTest:
UpdateXML(xml, '/', 'replacement');
Just return the replacement string.
*/
return rep;
}
tmp_value.length(0); tmp_value.length(0);
tmp_value.set_charset(collation.collation); tmp_value.set_charset(collation.collation);
uint offs= nodebeg->type == MY_XML_NODE_TAG ? 1 : 0; uint offs= nodebeg->type == MY_XML_NODE_TAG ? 1 : 0;
......
...@@ -1462,20 +1462,31 @@ Query_log_event::Query_log_event() ...@@ -1462,20 +1462,31 @@ Query_log_event::Query_log_event()
/* /*
Query_log_event::Query_log_event() SYNOPSIS
Query_log_event::Query_log_event()
thd - thread handle
query_arg - array of char representing the query
query_length - size of the `query_arg' array
using_trans - there is a modified transactional table
suppress_use - suppress the generation of 'USE' statements
killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
if the value is different from the default, the arg
is set to the current thd->killed value.
A caller might need to masquerade thd->killed with
THD::NOT_KILLED.
DESCRIPTION
Creates an event for binlogging
The value for local `killed_status' can be supplied by caller.
*/ */
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans, ulong query_length, bool using_trans,
bool suppress_use) bool suppress_use, THD::killed_state killed_status_arg)
:Log_event(thd_arg, :Log_event(thd_arg,
((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) ((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0)
| (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)), | (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)),
using_trans), using_trans),
data_buf(0), query(query_arg), catalog(thd_arg->catalog), data_buf(0), query(query_arg), catalog(thd_arg->catalog),
db(thd_arg->db), q_len((uint32) query_length), db(thd_arg->db), q_len((uint32) query_length),
error_code((thd_arg->killed != THD::NOT_KILLED) ?
((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ?
0 : thd->killed_errno()) : thd_arg->net.last_errno),
thread_id(thd_arg->thread_id), thread_id(thd_arg->thread_id),
/* save the original thread id; we already know the server id */ /* save the original thread id; we already know the server id */
slave_proxy_id(thd_arg->variables.pseudo_thread_id), slave_proxy_id(thd_arg->variables.pseudo_thread_id),
...@@ -1487,6 +1498,14 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, ...@@ -1487,6 +1498,14 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
charset_database_number(0) charset_database_number(0)
{ {
time_t end_time; time_t end_time;
if (killed_status_arg == THD::KILLED_NO_VALUE)
killed_status_arg= thd_arg->killed;
error_code=
(killed_status_arg == THD::NOT_KILLED) ? thd_arg->net.last_errno :
((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 :
thd->killed_errno());
time(&end_time); time(&end_time);
exec_time = (ulong) (end_time - thd->start_time); exec_time = (ulong) (end_time - thd->start_time);
catalog_len = (catalog) ? (uint32) strlen(catalog) : 0; catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
...@@ -6737,10 +6756,23 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table) ...@@ -6737,10 +6756,23 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table)
lex->duplicates flag. lex->duplicates flag.
*/ */
thd->lex->sql_command= SQLCOM_REPLACE; thd->lex->sql_command= SQLCOM_REPLACE;
/*
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); // Needed for ndbcluster Do not raise the error flag in case of hitting to an unique attribute
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE); // Needed for ndbcluster */
table->file->extra(HA_EXTRA_IGNORE_NO_KEY); // Needed for ndbcluster table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
/*
NDB specific: update from ndb master wrapped as Write_rows
*/
/*
so that the event should be applied to replace slave's row
*/
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
/*
NDB specific: if update from ndb master wrapped as Write_rows
does not find the row it's assumed idempotent binlog applying
is taking place; don't raise the error.
*/
table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
/* /*
TODO: the cluster team (Tomas?) says that it's better if the engine knows TODO: the cluster team (Tomas?) says that it's better if the engine knows
how many rows are going to be inserted, then it can allocate needed memory how many rows are going to be inserted, then it can allocate needed memory
...@@ -6768,9 +6800,20 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table) ...@@ -6768,9 +6800,20 @@ int Write_rows_log_event::do_before_row_operations(TABLE *table)
int Write_rows_log_event::do_after_row_operations(TABLE *table, int error) int Write_rows_log_event::do_after_row_operations(TABLE *table, int error)
{ {
if (error == 0) int local_error= 0;
error= table->file->ha_end_bulk_insert(); table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
return error; table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
/*
reseting the extra with
table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
fires bug#27077
todo: explain or fix
*/
if ((local_error= table->file->ha_end_bulk_insert()))
{
table->file->print_error(local_error, MYF(0));
}
return error? error : local_error;
} }
int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli, int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli,
......
...@@ -1023,7 +1023,8 @@ public: ...@@ -1023,7 +1023,8 @@ public:
#ifndef MYSQL_CLIENT #ifndef MYSQL_CLIENT
Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
bool using_trans, bool suppress_use); bool using_trans, bool suppress_use,
THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE);
const char* get_db() { return db; } const char* get_db() { return db; }
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol); void pack_info(Protocol* protocol);
......
...@@ -3082,9 +3082,9 @@ void THD::binlog_delete_pending_rows_event() ...@@ -3082,9 +3082,9 @@ void THD::binlog_delete_pending_rows_event()
RETURN VALUE RETURN VALUE
Error code, or 0 if no error. Error code, or 0 if no error.
*/ */
int THD::binlog_query(THD::enum_binlog_query_type qtype, int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query,
char const *query, ulong query_len, ulong query_len, bool is_trans, bool suppress_use,
bool is_trans, bool suppress_use) THD::killed_state killed_status_arg)
{ {
DBUG_ENTER("THD::binlog_query"); DBUG_ENTER("THD::binlog_query");
DBUG_PRINT("enter", ("qtype=%d, query='%s'", qtype, query)); DBUG_PRINT("enter", ("qtype=%d, query='%s'", qtype, query));
...@@ -3123,7 +3123,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, ...@@ -3123,7 +3123,8 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
flush the pending rows event if necessary. flush the pending rows event if necessary.
*/ */
{ {
Query_log_event qinfo(this, query, query_len, is_trans, suppress_use); Query_log_event qinfo(this, query, query_len, is_trans, suppress_use,
killed_status_arg);
qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F; qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
/* /*
Binlog table maps will be irrelevant after a Query_log_event Binlog table maps will be irrelevant after a Query_log_event
......
...@@ -1116,32 +1116,6 @@ public: ...@@ -1116,32 +1116,6 @@ public:
} }
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
#ifndef MYSQL_CLIENT
public:
enum enum_binlog_query_type {
/*
The query can be logged row-based or statement-based
*/
ROW_QUERY_TYPE,
/*
The query has to be logged statement-based
*/
STMT_QUERY_TYPE,
/*
The query represents a change to a table in the "mysql"
database and is currently mapped to ROW_QUERY_TYPE.
*/
MYSQL_QUERY_TYPE,
QUERY_TYPE_COUNT
};
int binlog_query(enum_binlog_query_type qtype,
char const *query, ulong query_len,
bool is_trans, bool suppress_use);
#endif
public: public:
struct st_transactions { struct st_transactions {
...@@ -1396,7 +1370,14 @@ public: ...@@ -1396,7 +1370,14 @@ public:
DYNAMIC_ARRAY user_var_events; /* For user variables replication */ DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */ MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
enum killed_state { NOT_KILLED=0, KILL_BAD_DATA=1, KILL_CONNECTION=ER_SERVER_SHUTDOWN, KILL_QUERY=ER_QUERY_INTERRUPTED }; enum killed_state
{
NOT_KILLED=0,
KILL_BAD_DATA=1,
KILL_CONNECTION=ER_SERVER_SHUTDOWN,
KILL_QUERY=ER_QUERY_INTERRUPTED,
KILLED_NO_VALUE /* means neither of the states */
};
killed_state volatile killed; killed_state volatile killed;
/* scramble - random string sent to client on handshake */ /* scramble - random string sent to client on handshake */
...@@ -1521,6 +1502,33 @@ public: ...@@ -1521,6 +1502,33 @@ public:
void close_active_vio(); void close_active_vio();
#endif #endif
void awake(THD::killed_state state_to_set); void awake(THD::killed_state state_to_set);
#ifndef MYSQL_CLIENT
enum enum_binlog_query_type {
/*
The query can be logged row-based or statement-based
*/
ROW_QUERY_TYPE,
/*
The query has to be logged statement-based
*/
STMT_QUERY_TYPE,
/*
The query represents a change to a table in the "mysql"
database and is currently mapped to ROW_QUERY_TYPE.
*/
MYSQL_QUERY_TYPE,
QUERY_TYPE_COUNT
};
int binlog_query(enum_binlog_query_type qtype,
char const *query, ulong query_len,
bool is_trans, bool suppress_use,
THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE);
#endif
/* /*
For enter_cond() / exit_cond() to work the mutex must be got before For enter_cond() / exit_cond() to work the mutex must be got before
enter_cond(); this mutex is then released by exit_cond(). enter_cond(); this mutex is then released by exit_cond().
...@@ -1647,7 +1655,8 @@ public: ...@@ -1647,7 +1655,8 @@ public:
void end_statement(); void end_statement();
inline int killed_errno() const inline int killed_errno() const
{ {
return killed != KILL_BAD_DATA ? killed : 0; killed_state killed_val; /* to cache the volatile 'killed' */
return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
} }
inline void send_kill_message() const inline void send_kill_message() const
{ {
......
...@@ -843,10 +843,36 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -843,10 +843,36 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
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(); 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, if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query, thd->query_length, thd->query, thd->query_length,
transactional_table, FALSE) && transactional_table, FALSE,
(error>0) ? thd->killed : THD::NOT_KILLED) &&
transactional_table) transactional_table)
{ {
error=1; error=1;
...@@ -858,7 +884,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -858,7 +884,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
} }
if (transactional_table) if (transactional_table)
error=ha_autocommit_or_rollback(thd,error); error=ha_autocommit_or_rollback(thd,error);
if (thd->lock) if (thd->lock)
{ {
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
......
...@@ -413,9 +413,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -413,9 +413,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
if (error) if (error)
{ {
if (transactional_table)
ha_autocommit_or_rollback(thd,error);
if (read_file_from_client) if (read_file_from_client)
while (!read_info.next_line()) while (!read_info.next_line())
; ;
...@@ -463,6 +460,9 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -463,6 +460,9 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
} }
} }
#endif /*!EMBEDDED_LIBRARY*/ #endif /*!EMBEDDED_LIBRARY*/
if (transactional_table)
ha_autocommit_or_rollback(thd,error);
error= -1; // Error on read error= -1; // Error on read
goto err; goto err;
} }
......
...@@ -621,6 +621,37 @@ int mysql_update(THD *thd, ...@@ -621,6 +621,37 @@ int mysql_update(THD *thd,
thd->row_count++; thd->row_count++;
} }
dup_key_found= 0; dup_key_found= 0;
/*
todo bug#27571: to avoid asynchronization of `error' and
`error_code' of binlog event constructor
The concept, which is a bit different for insert(!), is to
replace `error' assignment with the following lines
killed_status= thd->killed; // get the status of the volatile
Notice: thd->killed is type of "state" whereas the lhs has
"status" the suffix which translates according to WordNet: a state
at a particular time - at the time of the end of per-row loop in
our case. Binlogging ops are conducted with the status.
error= (killed_status == THD::NOT_KILLED)? error : 1;
which applies to most mysql_$query functions.
Event's constructor will accept `killed_status' as an argument:
Query_log_event qinfo(..., killed_status);
thd->killed might be changed after killed_status had got cached and this
won't affect binlogging event but other effects remain.
Open issue: In a case the error happened not because of KILLED -
and then KILLED was caught later still within the loop - we shall
do something to avoid binlogging of incorrect ER_SERVER_SHUTDOWN
error_code.
*/
if (thd->killed && !error) if (thd->killed && !error)
error= 1; // Aborted error= 1; // Aborted
else if (will_batch && else if (will_batch &&
......
...@@ -379,7 +379,13 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) ...@@ -379,7 +379,13 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
{ {
register ulong nr=0; /*
Note, if a key consists of a combination of numeric and
a text columns, it most likely won't work well.
Making text columns work with NEW_HASH_FUNCTION
needs also changes in strings/ctype-xxx.c.
*/
ulong nr= 1, nr2= 4;
HA_KEYSEG *seg,*endseg; HA_KEYSEG *seg,*endseg;
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
...@@ -401,14 +407,15 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) ...@@ -401,14 +407,15 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
} }
if (seg->type == HA_KEYTYPE_TEXT) if (seg->type == HA_KEYTYPE_TEXT)
{ {
seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL); seg->charset->coll->hash_sort(seg->charset, pos, ((uchar*)key)-pos,
&nr, &nr2);
} }
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
{ {
uint pack_length= 2; /* Key packing is constant */ uint pack_length= 2; /* Key packing is constant */
uint length= uint2korr(pos); uint length= uint2korr(pos);
seg->charset->hash_sort(seg->charset, pos+pack_length, length, &nr, seg->charset->coll->hash_sort(seg->charset, pos+pack_length, length,
NULL); &nr, &nr2);
key+= pack_length; key+= pack_length;
} }
else else
...@@ -428,7 +435,7 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key) ...@@ -428,7 +435,7 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
{ {
register ulong nr=0; ulong nr= 1, nr2= 4;
HA_KEYSEG *seg,*endseg; HA_KEYSEG *seg,*endseg;
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++) for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
...@@ -444,14 +451,16 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec) ...@@ -444,14 +451,16 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
} }
if (seg->type == HA_KEYTYPE_TEXT) if (seg->type == HA_KEYTYPE_TEXT)
{ {
seg->charset->hash_sort(seg->charset,pos,((uchar*)key)-pos,&nr,NULL); uint char_length= seg->length; /* TODO: fix to use my_charpos() */
seg->charset->coll->hash_sort(seg->charset, pos, char_length,
&nr, &nr2);
} }
else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */ else if (seg->type == HA_KEYTYPE_VARTEXT1) /* Any VARCHAR segments */
{ {
uint pack_length= seg->bit_start; uint pack_length= seg->bit_start;
uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos)); uint length= (pack_length == 1 ? (uint) *(uchar*) pos : uint2korr(pos));
seg->charset->hash_sort(seg->charset, pos+pack_length, seg->charset->coll->hash_sort(seg->charset, pos+pack_length,
length, &nr, NULL); length, &nr, &nr2);
} }
else else
{ {
......
...@@ -24,4 +24,4 @@ ADD_LIBRARY(strings bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ...@@ -24,4 +24,4 @@ ADD_LIBRARY(strings bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c
is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c r_strinstr.c is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c r_strinstr.c
str2int.c str_alloc.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c str2int.c str_alloc.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c
strtod.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c xml.c strtod.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c xml.c
my_strchr.c strcont.c strinstr.c) my_strchr.c strcont.c strinstr.c strnlen.c)
...@@ -95,8 +95,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) ...@@ -95,8 +95,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
reg2 char *par = va_arg(ap, char *); reg2 char *par = va_arg(ap, char *);
uint plen,left_len = (uint)(end-to)+1; uint plen,left_len = (uint)(end-to)+1;
if (!par) par = (char*)"(null)"; if (!par) par = (char*)"(null)";
plen = (uint) strlen(par); plen= (uint) strnlen(par, width);
set_if_smaller(plen,width);
if (left_len <= plen) if (left_len <= plen)
plen = left_len - 1; plen = left_len - 1;
to=strnmov(to,par,plen); to=strnmov(to,par,plen);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment