Browse Source

Merge main 5.1 and the 5.1 version of the fix for bug#40546

pull/374/head
Joerg Bruehe 17 years ago
parent
commit
e9be23fae6
  1. 33
      BUILD/compile-dist
  2. 66
      configure.in
  3. 99
      mysql-test/extra/rpl_tests/rpl_row_basic.test
  4. 12
      mysql-test/r/alter_table.result
  5. 3
      mysql-test/r/binlog_format_basic.result
  6. 9
      mysql-test/r/innodb_mysql.result
  7. 74
      mysql-test/r/partition.result
  8. 20
      mysql-test/r/xa.result
  9. 40
      mysql-test/suite/rpl/r/rpl_redirect.result
  10. 57
      mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result
  11. 57
      mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result
  12. 3
      mysql-test/suite/rpl/t/disabled.def
  13. 45
      mysql-test/suite/rpl/t/rpl_redirect.test
  14. 57
      mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result
  15. 12
      mysql-test/t/alter_table.test
  16. 7
      mysql-test/t/binlog_format_basic.test
  17. 14
      mysql-test/t/innodb_mysql.test
  18. 29
      mysql-test/t/partition.test
  19. 45
      mysql-test/t/xa.test
  20. 35
      sql/field.cc
  21. 2
      sql/field.h
  22. 2
      sql/ha_partition.cc
  23. 34
      sql/handler.cc
  24. 2
      sql/log.cc
  25. 38
      sql/log_event.cc
  26. 47
      sql/log_event_old.cc
  27. 6
      sql/share/errmsg.txt
  28. 7
      sql/sql_class.cc
  29. 4
      sql/sql_class.h
  30. 78
      sql/sql_parse.cc
  31. 5
      zlib/gzio.c

33
BUILD/compile-dist

@ -13,34 +13,51 @@ path=`dirname $0`
# Default to gcc for CC and CXX
if test -z "$CXX" ; then
export CXX=gcc
CXX=gcc
# Set some required compile options
if test -z "$CXXFLAGS" ; then
export CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti"
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti"
fi
fi
if test -z "$CC" ; then
export CC=gcc
CC=gcc
fi
# Use ccache, if available
if ccache -V > /dev/null 2>&1
then
if ! (echo "$CC" | grep "ccache" > /dev/null)
if echo "$CC" | grep "ccache" > /dev/null
then
export CC="ccache $CC"
:
else
CC="ccache $CC"
fi
if ! (echo "$CXX" | grep "ccache" > /dev/null)
if echo "$CXX" | grep "ccache" > /dev/null
then
export CXX="ccache $CXX"
:
else
CXX="ccache $CXX"
fi
fi
if test -z "$MAKE"
then
if gmake -v > /dev/null 2>&1
then
MAKE="gmake"
else
MAKE="make"
fi
fi
export CC CXX MAKE
# Make sure to enable all features that affect "make dist"
# Remember that configure restricts the man pages to the configured features !
./configure \
--with-embedded-server \
--with-ndbcluster
make
$MAKE

66
configure.in

@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM
#
# When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version().
AM_INIT_AUTOMAKE(mysql, 5.1.29)
AM_INIT_AUTOMAKE(mysql, 5.1.30)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
@ -405,12 +405,15 @@ dnl Find paths to some shell programs
AC_PATH_PROG(LN, ln, ln)
# This must be able to take a -f flag like normal unix ln.
AC_PATH_PROG(LN_CP_F, ln, ln)
if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then
# If ln -f does not exists use -s (AFS systems)
if test -n "$LN_CP_F"; then
LN_CP_F="$LN_CP_F -s"
fi
fi
case $SYSTEM_TYPE in
*netware*) ;;
*)
# If ln -f does not exists use -s (AFS systems)
if test -n "$LN_CP_F"; then
LN_CP_F="$LN_CP_F -s"
fi
;;
esac
AC_PATH_PROG(MV, mv, mv)
AC_PATH_PROG(RM, rm, rm)
@ -1642,14 +1645,16 @@ else
OPTIMIZE_CXXFLAGS="-O"
fi
if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then
DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4"
DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4"
DEBUG_OPTIMIZE_CC="-DDEBUG"
DEBUG_OPTIMIZE_CXX="-DDEBUG"
OPTIMIZE_CFLAGS="-O3 -DNDEBUG"
OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG"
fi
case $SYSTEM_TYPE in
*netware*)
DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4"
DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4"
DEBUG_OPTIMIZE_CC="-DDEBUG"
DEBUG_OPTIMIZE_CXX="-DDEBUG"
OPTIMIZE_CFLAGS="-O3 -DNDEBUG"
OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG"
;;
esac
# If the user specified CFLAGS, we won't add any optimizations
if test -n "$SAVE_CFLAGS"
@ -1915,15 +1920,18 @@ MYSQL_TZNAME
# Do the c++ compiler have a bool type
MYSQL_CXX_BOOL
# Check some common bugs with gcc 2.8.# on sparc
if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then
MYSQL_CHECK_LONGLONG_TO_FLOAT
if test "$ac_cv_conv_longlong_to_float" != "yes"
then
AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float!
If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try
again])
fi
fi
case $SYSTEM_TYPE in
*netware*) ;;
*)
MYSQL_CHECK_LONGLONG_TO_FLOAT
if test "$ac_cv_conv_longlong_to_float" != "yes"
then
AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float!
If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try
again])
fi
;;
esac
AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include <sys/types.h>])
AC_CHECK_TYPES([size_t], [], [], [#include <stdio.h>])
AC_CHECK_TYPES([u_int32_t])
@ -2549,11 +2557,12 @@ readline_h_ln_cmd=""
readline_link=""
want_to_use_readline="no"
if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null
then
case $SYSTEM_TYPE in
*netware*)
# For NetWare, do not need readline
echo "Skipping readline"
else
;;
*)
if [test "$with_libedit" = "yes"] || [test "$with_libedit" = "undefined"] && [test "$with_readline" = "undefined"]
then
readline_topdir="cmd-line-utils"
@ -2606,7 +2615,8 @@ else
be built with libreadline. Please use --with-libedit to use
the bundled version of libedit instead.])
fi
fi
;;
esac
AC_SUBST(readline_dir)
AC_SUBST(readline_topdir)

99
mysql-test/extra/rpl_tests/rpl_row_basic.test

@ -471,3 +471,102 @@ source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;
#
# BUG#40004: Replication failure with no PK + no indexes
#
# The test cases are taken from the bug report. It is difficult to
# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go
# with the test cases we have.
connection master;
eval CREATE TABLE t1 (a int) ENGINE=$type;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;
#
# Bug #39752: Replication failure on RBR + MyISAM + no PK
#
# The test cases are taken from the bug report. It is difficult to
# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go
# with the test cases we have.
connection master;
--disable_warnings
eval CREATE TABLE t1 (a bit) ENGINE=$type;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
--enable_warnings
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;

12
mysql-test/r/alter_table.result

@ -1222,4 +1222,16 @@ ALTER TABLE t1 CHANGE d c varchar(10);
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
DROP TABLE t1;
CREATE TABLE t1(a INT AUTO_INCREMENT PRIMARY KEY,
b ENUM('a', 'b', 'c') NOT NULL);
INSERT INTO t1 (b) VALUES ('a'), ('c'), ('b'), ('b'), ('a');
ALTER TABLE t1 MODIFY b ENUM('a', 'z', 'b', 'c') NOT NULL;
SELECT * FROM t1;
a b
1 a
2 c
3 b
4 b
5 a
DROP TABLE t1;
End of 5.1 tests

3
mysql-test/r/binlog_format_basic.result

@ -1,3 +1,6 @@
SELECT @@GLOBAL.binlog_format;
@@GLOBAL.binlog_format
STATEMENT
'#---------------------BS_STVARS_002_01----------------------#'
SELECT COUNT(@@GLOBAL.binlog_format);
COUNT(@@GLOBAL.binlog_format)

9
mysql-test/r/innodb_mysql.result

@ -1668,3 +1668,12 @@ explain select a from t2 where a=b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL a 10 NULL # Using where; Using index
drop table t1, t2;
SET SESSION BINLOG_FORMAT=STATEMENT;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
select @@session.sql_log_bin, @@session.binlog_format, @@session.tx_isolation;
@@session.sql_log_bin 1
@@session.binlog_format STATEMENT
@@session.tx_isolation READ-COMMITTED
CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
DROP TABLE t1;

74
mysql-test/r/partition.result

@ -1,4 +1,78 @@
drop table if exists t1, t2;
CREATE TABLE t1 (a INT NOT NULL, KEY(a))
PARTITION BY RANGE(a)
(PARTITION p1 VALUES LESS THAN (200), PARTITION pmax VALUES LESS THAN MAXVALUE);
INSERT INTO t1 VALUES (2), (40), (40), (70), (60), (90), (199);
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC;
a
60
70
90
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95;
a
60
70
90
INSERT INTO t1 VALUES (200), (250), (210);
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC;
a
60
70
90
199
200
210
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a ASC;
a
200
210
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC;
a
90
70
60
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC;
a
210
200
199
90
70
60
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a DESC;
a
210
200
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220;
a
199
200
210
60
70
90
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220;
a
200
210
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95;
a
60
70
90
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220;
a
199
200
210
60
70
90
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220;
a
200
210
DROP TABLE t1;
CREATE TABLE t1 (
a INT NOT NULL,
b MEDIUMINT NOT NULL,

20
mysql-test/r/xa.result

@ -55,3 +55,23 @@ select * from t1;
a
20
drop table t1;
drop table if exists t1;
create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb;
insert into t1 values(1, 1, 'a');
insert into t1 values(2, 2, 'b');
xa start 'a','b';
update t1 set c = 'aa' where a = 1;
xa start 'a','c';
update t1 set c = 'bb' where a = 2;
update t1 set c = 'bb' where a = 2;
update t1 set c = 'aa' where a = 1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
select count(*) from t1;
count(*)
2
xa end 'a','c';
ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected
xa rollback 'a','c';
xa start 'a','c';
drop table t1;
End of 5.0 tests

40
mysql-test/suite/rpl/r/rpl_redirect.result

@ -1,40 +0,0 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
SHOW SLAVE STATUS;
SHOW SLAVE HOSTS;
Server_id Host Port Rpl_recovery_rank Master_id
2 127.0.0.1 SLAVE_PORT 2 1
create table t1 ( n int);
insert into t1 values (1),(2),(3),(4);
insert into t1 values(5);
SELECT * FROM t1 ORDER BY n;
n
1
2
3
4
5
SELECT * FROM t1 ORDER BY n;
n
1
2
3
4
SELECT * FROM t1 ORDER BY n;
n
1
2
3
4
SELECT * FROM t1 ORDER BY n;
n
1
2
3
4
5
drop table t1;

57
mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result

@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
INSERT INTO t1 VALUES (4);
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a int) ENGINE='MYISAM' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a bit) ENGINE='MYISAM' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;

57
mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result

@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
INSERT INTO t1 VALUES (4);
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a int) ENGINE='INNODB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a bit) ENGINE='INNODB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;

3
mysql-test/suite/rpl/t/disabled.def

@ -10,6 +10,3 @@
#
##############################################################################
rpl_redirect : Failure is sporadic and and the test is superfluous (mats)
rpl_innodb_bug28430 : Failure on Solaris Bug #36793
rpl_flushlog_loop : BUG#37733 2008-07-23 Sven disabled in 5.1-bugteam. the bug has been fixed in 5.1-rpl: please re-enable when that gets pushed to main

45
mysql-test/suite/rpl/t/rpl_redirect.test

@ -1,45 +0,0 @@
#
# Test of automatic redirection of queries to master/slave.
#
source include/master-slave.inc;
# We disable this for now as PS doesn't handle redirection
--disable_ps_protocol
#first, make sure the slave has had enough time to register
save_master_pos;
connection slave;
sync_with_master;
#discover slaves
connection master;
source include/show_slave_status.inc;
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW SLAVE HOSTS;
rpl_probe;
#turn on master/slave query direction auto-magic
enable_rpl_parse;
create table t1 ( n int);
insert into t1 values (1),(2),(3),(4);
disable_rpl_parse;
save_master_pos;
connection slave;
sync_with_master;
insert into t1 values(5);
connection master;
enable_rpl_parse;
# The first of the queries will be sent to the slave, the second to the master.
SELECT * FROM t1 ORDER BY n;
SELECT * FROM t1 ORDER BY n;
disable_rpl_parse;
SELECT * FROM t1 ORDER BY n;
connection slave;
SELECT * FROM t1 ORDER BY n;
# Cleanup
connection master;
drop table t1;
sync_slave_with_master;
# End of 4.1 tests

57
mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result

@ -527,3 +527,60 @@ ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
INSERT INTO t1 VALUES (4);
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a int) ENGINE='NDB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;
CREATE TABLE t1 (a bit) ENGINE='NDB' ;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
Comparing tables master:test.t1 and slave:test.t1
drop table t1;

12
mysql-test/t/alter_table.test

@ -947,4 +947,16 @@ ALTER TABLE t1 CHANGE d c varchar(10);
--disable_info
DROP TABLE t1;
#
# Bug #23113: Different behavior on altering ENUM fields between 5.0 and 5.1
#
CREATE TABLE t1(a INT AUTO_INCREMENT PRIMARY KEY,
b ENUM('a', 'b', 'c') NOT NULL);
INSERT INTO t1 (b) VALUES ('a'), ('c'), ('b'), ('b'), ('a');
ALTER TABLE t1 MODIFY b ENUM('a', 'z', 'b', 'c') NOT NULL;
SELECT * FROM t1;
DROP TABLE t1;
--echo End of 5.1 tests

7
mysql-test/t/binlog_format_basic.test

@ -22,6 +22,13 @@
# #
###############################################################################
###################################################################
# BUG#39812: Make statement replication default for 5.1 (to match 5.0)
# We just verify that the default binlog_format is STATEMENT in 5.1.
# In 6.0, it should be MIXED.
###################################################################
SELECT @@GLOBAL.binlog_format;
--echo '#---------------------BS_STVARS_002_01----------------------#'
####################################################################
# Displaying default value #

14
mysql-test/t/innodb_mysql.test

@ -29,3 +29,17 @@ insert into t2 select @a:=A.a+10*(B.a + 10*C.a),@a, @a from t1 A, t1 B, t1 C;
explain select a from t2 where a=b;
drop table t1, t2;
#
# Bug #40360: Binlog related errors with binlog off
#
# This bug is triggered when the binlog format is STATEMENT and the
# binary log is turned off. In this case, no error should be shown for
# the statement since there are no replication issues.
SET SESSION BINLOG_FORMAT=STATEMENT;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
query_vertical select @@session.sql_log_bin, @@session.binlog_format, @@session.tx_isolation;
CREATE TABLE t1 ( a INT ) ENGINE=InnoDB;
INSERT INTO t1 VALUES(1);
DROP TABLE t1;

29
mysql-test/t/partition.test

@ -14,6 +14,35 @@
drop table if exists t1, t2;
--enable_warnings
#
# Bug#40494: Crash MYSQL server crashes on range access with partitioning
# and order by
#
CREATE TABLE t1 (a INT NOT NULL, KEY(a))
PARTITION BY RANGE(a)
(PARTITION p1 VALUES LESS THAN (200), PARTITION pmax VALUES LESS THAN MAXVALUE);
INSERT INTO t1 VALUES (2), (40), (40), (70), (60), (90), (199);
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a ASC;
--sorted_result
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95;
INSERT INTO t1 VALUES (200), (250), (210);
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a ASC;
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a ASC;
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95 ORDER BY a DESC;
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220 ORDER BY a DESC;
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220 ORDER BY a DESC;
--sorted_result
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220;
--sorted_result
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220;
--sorted_result
SELECT a FROM t1 WHERE a BETWEEN 60 AND 95;
--sorted_result
SELECT a FROM t1 WHERE a BETWEEN 60 AND 220;
--sorted_result
SELECT a FROM t1 WHERE a BETWEEN 200 AND 220;
DROP TABLE t1;
#
# Bug35931: Index search may return duplicates
#

45
mysql-test/t/xa.test

@ -74,3 +74,48 @@ xa start 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
select * from t1;
drop table t1;
disconnect con1;
#
# Bug#28323: Server crashed in xid cache operations
#
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1(a int, b int, c varchar(20), primary key(a)) engine = innodb;
insert into t1 values(1, 1, 'a');
insert into t1 values(2, 2, 'b');
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
--connection con1
xa start 'a','b';
update t1 set c = 'aa' where a = 1;
--connection con2
xa start 'a','c';
update t1 set c = 'bb' where a = 2;
--connection con1
--send update t1 set c = 'bb' where a = 2
--connection con2
--sleep 1
--error ER_LOCK_DEADLOCK
update t1 set c = 'aa' where a = 1;
select count(*) from t1;
--error ER_XA_RBDEADLOCK
xa end 'a','c';
xa rollback 'a','c';
--disconnect con2
connect (con3,localhost,root,,);
--connection con3
xa start 'a','c';
--disconnect con1
--disconnect con3
--connection default
drop table t1;
--echo End of 5.0 tests

35
sql/field.cc

@ -8783,28 +8783,43 @@ bool Field::eq_def(Field *field)
return 1;
}
/**
@return
returns 1 if the fields are equally defined
*/
bool Field_enum::eq_def(Field *field)
{
if (!Field::eq_def(field))
return 0;
TYPELIB *from_lib=((Field_enum*) field)->typelib;
return compare_enum_values(((Field_enum*) field)->typelib);
}
if (typelib->count < from_lib->count)
return 0;
for (uint i=0 ; i < from_lib->count ; i++)
bool Field_enum::compare_enum_values(TYPELIB *values)
{
if (typelib->count != values->count)
return FALSE;
for (uint i= 0; i < typelib->count; i++)
if (my_strnncoll(field_charset,
(const uchar*)typelib->type_names[i],
strlen(typelib->type_names[i]),
(const uchar*)from_lib->type_names[i],
strlen(from_lib->type_names[i])))
return 0;
return 1;
(const uchar*) typelib->type_names[i],
typelib->type_lengths[i],
(const uchar*) values->type_names[i],
values->type_lengths[i]))
return FALSE;
return TRUE;
}
uint Field_enum::is_equal(Create_field *new_field)
{
if (!Field_str::is_equal(new_field))
return 0;
return compare_enum_values(new_field->interval);
}
/**
@return
returns 1 if the fields are equally defined

2
sql/field.h

@ -1853,6 +1853,8 @@ public:
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
private:
int do_save_field_metadata(uchar *first_byte);
bool compare_enum_values(TYPELIB *values);
uint is_equal(Create_field *new_field);
};

2
sql/ha_partition.cc

@ -4084,7 +4084,7 @@ int ha_partition::read_range_next()
{
DBUG_ENTER("ha_partition::read_range_next");
if (m_ordered)
if (m_ordered_scan_ongoing)
{
DBUG_RETURN(handle_ordered_next(table->record[0], eq_range));
}

34
sql/handler.cc

@ -1278,7 +1278,12 @@ int ha_rollback_trans(THD *thd, bool all)
trans->ha_list= 0;
trans->no_2pc=0;
if (is_real_trans)
thd->transaction.xid_state.xid.null();
{
if (thd->transaction_rollback_request)
thd->transaction.xid_state.rm_error= thd->main_da.sql_errno();
else
thd->transaction.xid_state.xid.null();
}
if (all)
{
thd->variables.tx_isolation=thd->session_tx_isolation;
@ -2765,7 +2770,7 @@ int handler::check_collation_compatibility()
{
ulong mysql_version= table->s->mysql_version;
if (mysql_version < 50048)
if (mysql_version < 50124)
{
KEY *key= table->key_info;
KEY *key_end= key + table->s->keys;
@ -2779,15 +2784,18 @@ int handler::check_collation_compatibility()
continue;
Field *field= table->field[key_part->fieldnr - 1];
uint cs_number= field->charset()->number;
if (mysql_version < 50048 &&
(cs_number == 11 || /* ascii_general_ci - bug #29499, bug #27562 */
cs_number == 41 || /* latin7_general_ci - bug #29461 */
cs_number == 42 || /* latin7_general_cs - bug #29461 */
cs_number == 20 || /* latin7_estonian_cs - bug #29461 */
cs_number == 21 || /* latin2_hungarian_ci - bug #29461 */
cs_number == 22 || /* koi8u_general_ci - bug #29461 */
cs_number == 23 || /* cp1251_ukrainian_ci - bug #29461 */
cs_number == 26)) /* cp1250_general_ci - bug #29461 */
if ((mysql_version < 50048 &&
(cs_number == 11 || /* ascii_general_ci - bug #29499, bug #27562 */
cs_number == 41 || /* latin7_general_ci - bug #29461 */
cs_number == 42 || /* latin7_general_cs - bug #29461 */
cs_number == 20 || /* latin7_estonian_cs - bug #29461 */
cs_number == 21 || /* latin2_hungarian_ci - bug #29461 */
cs_number == 22 || /* koi8u_general_ci - bug #29461 */
cs_number == 23 || /* cp1251_ukrainian_ci - bug #29461 */
cs_number == 26)) || /* cp1250_general_ci - bug #29461 */
(mysql_version < 50124 &&
(cs_number == 33 || /* utf8_general_ci - bug #27877 */
cs_number == 35))) /* ucs2_general_ci - bug #27877 */
return HA_ADMIN_NEEDS_UPGRADE;
}
}
@ -3333,8 +3341,8 @@ handler::ha_create_handler_files(const char *name, const char *old_name,
int
handler::ha_change_partitions(HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
ulonglong * const copied,
ulonglong * const deleted,
const uchar *pack_frm_data,
size_t pack_frm_len)
{

2
sql/log.cc

@ -3779,7 +3779,7 @@ THD::binlog_set_pending_rows_event(Rows_log_event* ev)
int
MYSQL_BIN_LOG::remove_pending_rows_event(THD *thd)
{
DBUG_ENTER(__FUNCTION__);
DBUG_ENTER("MYSQL_BIN_LOG::remove_pending_rows_event");
binlog_trx_data *const trx_data=
(binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);

38
sql/log_event.cc

@ -7203,6 +7203,9 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
error= do_exec_row(rli);
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
table->in_use = old_thd;
switch (error)
{
@ -7218,11 +7221,13 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
case HA_ERR_TABLE_DEF_CHANGED:
case HA_ERR_CANNOT_ADD_FOREIGN:
which are not included into to the list.
Note that HA_ERR_RECORD_DELETED is not in the list since
do_exec_row() should not return that error code.
*/
case HA_ERR_RECORD_CHANGED:
case HA_ERR_RECORD_DELETED:
case HA_ERR_KEY_NOT_FOUND:
case HA_ERR_END_OF_FILE:
case HA_ERR_FOUND_DUPP_KEY:
@ -7231,7 +7236,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
case HA_ERR_NO_REFERENCED_ROW:
case HA_ERR_ROW_IS_REFERENCED:
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
{
if (global_system_variables.log_warnings)
@ -7254,7 +7258,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
m_curr_row_end.
*/
DBUG_PRINT("info", ("error: %d", error));
DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
(ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
@ -8269,6 +8272,8 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
if (error)
{
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
@ -8301,7 +8306,9 @@ Rows_log_event::write_row(const Relay_log_info *const rli,
HA_READ_KEY_EXACT);
if (error)
{
DBUG_PRINT("info",("index_read_idx() returns error %d",error));
DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error)));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
@ -8574,6 +8581,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
if (error)
{
DBUG_PRINT("info",("rnd_pos returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
}
DBUG_RETURN(error);
@ -8633,6 +8642,8 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
HA_READ_KEY_EXACT)))
{
DBUG_PRINT("info",("no record matching the key found in the table"));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
table->file->ha_index_end();
goto err;
@ -8690,8 +8701,11 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
256U - (1U << table->s->last_null_bit_pos);
}
if ((error= table->file->index_next(table->record[0])))
while ((error= table->file->index_next(table->record[0])))
{
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
continue;
DBUG_PRINT("info",("no record matching the given row found"));
table->file->print_error(error, MYF(0));
table->file->ha_index_end();
@ -8722,14 +8736,22 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
/* Continue until we find the right record or have made a full loop */
do
{
restart_rnd_next:
error= table->file->rnd_next(table->record[0]);
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
switch (error) {
case 0:
case HA_ERR_RECORD_DELETED:
break;
/*
If the record was deleted, we pick the next one without doing
any comparisons.
*/
case HA_ERR_RECORD_DELETED:
goto restart_rnd_next;
case HA_ERR_END_OF_FILE:
if (++restart_count < 2)
table->file->ha_rnd_init(1);
@ -8759,7 +8781,7 @@ int Rows_log_event::find_row(const Relay_log_info *rli)
DBUG_DUMP("record found", table->record[0], table->s->reclength);
table->file->ha_rnd_end();
DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0);
DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0);
goto err;
}
ok:

47
sql/log_event_old.cc

@ -556,6 +556,9 @@ replace_record(THD *thd, TABLE *table,
error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
if (error)
{
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
@ -582,6 +585,9 @@ replace_record(THD *thd, TABLE *table,
HA_READ_KEY_EXACT);
if (error)
{
DBUG_PRINT("info", ("index_read_idx() returns error %d", error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
@ -787,11 +793,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
256U - (1U << table->s->last_null_bit_pos);
}
if ((error= table->file->index_next(table->record[1])))
while ((error= table->file->index_next(table->record[1])))
{
table->file->print_error(error, MYF(0));
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
continue;
table->file->print_error(error, MYF(0));
table->file->ha_index_end();
DBUG_RETURN(error);
DBUG_RETURN(error);
}
}
@ -812,6 +821,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
/* Continue until we find the right record or have made a full loop */
do
{
restart_rnd_next:
error= table->file->rnd_next(table->record[1]);
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
@ -819,8 +829,14 @@ static int find_and_fetch_row(TABLE *table, uchar *key)
switch (error) {
case 0:
break;
/*
If the record was deleted, we pick the next one without doing
any comparisons.
*/
case HA_ERR_RECORD_DELETED:
break;
goto restart_rnd_next;
case HA_ERR_END_OF_FILE:
if (++restart_count < 2)
@ -1680,6 +1696,9 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli)
error= do_exec_row(rli);
DBUG_PRINT("info", ("error: %d", error));
DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
table->in_use = old_thd;
switch (error)
{
@ -2100,6 +2119,8 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli,
if (error)
{
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
@ -2132,7 +2153,9 @@ Old_rows_log_event::write_row(const Relay_log_info *const rli,
HA_READ_KEY_EXACT);
if (error)
{
DBUG_PRINT("info",("index_read_idx() returns error %d",error));
DBUG_PRINT("info",("index_read_idx() returns error %d", error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
@ -2288,6 +2311,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
if (error)
{
DBUG_PRINT("info",("rnd_pos returns error %d",error));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
}
DBUG_RETURN(error);
@ -2347,6 +2372,8 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
HA_READ_KEY_EXACT)))
{
DBUG_PRINT("info",("no record matching the key found in the table"));
if (error == HA_ERR_RECORD_DELETED)
error= HA_ERR_KEY_NOT_FOUND;
table->file->print_error(error, MYF(0));
table->file->ha_index_end();
DBUG_RETURN(error);
@ -2404,8 +2431,11 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
256U - (1U << table->s->last_null_bit_pos);
}
if ((error= table->file->index_next(table->record[0])))
while ((error= table->file->index_next(table->record[0])))
{
/* We just skip records that has already been deleted */
if (error == HA_ERR_RECORD_DELETED)
continue;
DBUG_PRINT("info",("no record matching the given row found"));
table->file->print_error(error, MYF(0));
table->file->ha_index_end();
@ -2436,14 +2466,17 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli)
/* Continue until we find the right record or have made a full loop */
do
{
restart_rnd_next:
error= table->file->rnd_next(table->record[0]);
switch (error) {
case 0:
case HA_ERR_RECORD_DELETED:
break;
case HA_ERR_RECORD_DELETED:
goto restart_rnd_next;
case HA_ERR_END_OF_FILE:
if (++restart_count < 2)
table->file->ha_rnd_init(1);

6
sql/share/errmsg.txt

@ -6128,6 +6128,12 @@ ER_LOAD_DATA_INVALID_COLUMN
ER_LOG_PURGE_NO_FILE
eng "Being purged log %s was not found"
ER_XA_RBTIMEOUT XA106
eng "XA_RBTIMEOUT: Transaction branch was rolled back: took too long"
ER_XA_RBDEADLOCK XA102
eng "XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected"
ER_NEED_REPREPARE
eng "Prepared statement needs to be re-prepared"

7
sql/sql_class.cc

@ -2852,7 +2852,10 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd)
extern "C" int thd_binlog_format(const MYSQL_THD thd)
{
return (int) thd->variables.binlog_format;
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
return (int) thd->variables.binlog_format;
else
return BINLOG_FORMAT_UNSPEC;
}
extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all)
@ -3513,7 +3516,7 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
int THD::binlog_remove_pending_rows_event(bool clear_maps)
{
DBUG_ENTER(__FUNCTION__);
DBUG_ENTER("THD::binlog_remove_pending_rows_event");
if (!mysql_bin_log.is_open())
DBUG_RETURN(0);

4
sql/sql_class.h

@ -739,7 +739,7 @@ struct st_savepoint {
Ha_trx_info *ha_list;
};
enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED};
enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED, XA_ROLLBACK_ONLY};
extern const char *xa_state_names[];
typedef struct st_xid_state {
@ -747,6 +747,8 @@ typedef struct st_xid_state {
XID xid; // transaction identifier
enum xa_states xa_state; // used by external XA only
bool in_thd;
/* Error reported by the Resource Manager (RM) to the Transaction Manager. */
uint rm_error;
} XID_STATE;
extern pthread_mutex_t LOCK_xid_cache;

78
sql/sql_parse.cc

@ -83,9 +83,57 @@ const LEX_STRING command_name[]={
};
const char *xa_state_names[]={
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED", "ROLLBACK ONLY"
};
/**
Mark a XA transaction as rollback-only if the RM unilaterally
rolled back the transaction branch.
@note If a rollback was requested by the RM, this function sets
the appropriate rollback error code and transits the state
to XA_ROLLBACK_ONLY.
@return TRUE if transaction was rolled back or if the transaction
state is XA_ROLLBACK_ONLY. FALSE otherwise.
*/
static bool xa_trans_rolled_back(XID_STATE *xid_state)
{
if (xid_state->rm_error)
{
switch (xid_state->rm_error) {
case ER_LOCK_WAIT_TIMEOUT:
my_error(ER_XA_RBTIMEOUT, MYF(0));
break;
case ER_LOCK_DEADLOCK:
my_error(ER_XA_RBDEADLOCK, MYF(0));
break;
default:
my_error(ER_XA_RBROLLBACK, MYF(0));
}
xid_state->xa_state= XA_ROLLBACK_ONLY;
}
return (xid_state->xa_state == XA_ROLLBACK_ONLY);
}
/**
Rollback work done on behalf of at ransaction branch.
*/
static bool xa_trans_rollback(THD *thd)
{
bool status= test(ha_rollback(thd));
thd->options&= ~(ulong) OPTION_BEGIN;
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state= XA_NOTR;
thd->transaction.xid_state.rm_error= 0;
return status;
}
static void unlock_locked_tables(THD *thd)
{
if (thd->locked_tables)
@ -4505,6 +4553,7 @@ create_sp_error:
}
DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
thd->transaction.xid_state.xa_state=XA_ACTIVE;
thd->transaction.xid_state.rm_error= 0;
thd->transaction.xid_state.xid.set(thd->lex->xid);
xid_cache_insert(&thd->transaction.xid_state);
thd->transaction.all.modified_non_trans_table= FALSE;
@ -4530,6 +4579,8 @@ create_sp_error:
my_error(ER_XAER_NOTA, MYF(0));
break;
}
if (xa_trans_rolled_back(&thd->transaction.xid_state))
break;
thd->transaction.xid_state.xa_state=XA_IDLE;
my_ok(thd);
break;
@ -4561,6 +4612,12 @@ create_sp_error:
XID_STATE *xs=xid_cache_search(thd->lex->xid);
if (!xs || xs->in_thd)
my_error(ER_XAER_NOTA, MYF(0));
else if (xa_trans_rolled_back(xs))
{
ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
xid_cache_delete(xs);
break;
}
else
{
ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
@ -4569,6 +4626,11 @@ create_sp_error:
}
break;
}
if (xa_trans_rolled_back(&thd->transaction.xid_state))
{
xa_trans_rollback(thd);
break;
}
if (thd->transaction.xid_state.xa_state == XA_IDLE &&
thd->lex->xa_opt == XA_ONE_PHASE)
{
@ -4615,28 +4677,26 @@ create_sp_error:
my_error(ER_XAER_NOTA, MYF(0));
else
{
bool ok= !xa_trans_rolled_back(xs);
ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
xid_cache_delete(xs);
my_ok(thd);
if (ok)
my_ok(thd);
}
break;
}
if (thd->transaction.xid_state.xa_state != XA_IDLE &&
thd->transaction.xid_state.xa_state != XA_PREPARED)
thd->transaction.xid_state.xa_state != XA_PREPARED &&
thd->transaction.xid_state.xa_state != XA_ROLLBACK_ONLY)
{
my_error(ER_XAER_RMFAIL, MYF(0),
xa_state_names[thd->transaction.xid_state.xa_state]);
break;
}
if (ha_rollback(thd))
if (xa_trans_rollback(thd))
my_error(ER_XAER_RMERR, MYF(0));
else
my_ok(thd);
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state=XA_NOTR;
break;
case SQLCOM_XA_RECOVER:
res= mysql_xa_recover(thd);

5
zlib/gzio.c

@ -7,6 +7,11 @@
/* @(#) $Id$ */
/* Need to be included "early" to control other headers */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include "zutil.h"

Loading…
Cancel
Save