From b6b47f8824f57d434a51358017725ebc05e47535 Mon Sep 17 00:00:00 2001 From: Tatjana Azundris Nuernberg Date: Fri, 17 Feb 2012 19:02:17 +0000 Subject: [PATCH 01/13] BUG#13431369 - MAIN.VARIABLES-NOTEMBEDDED CRASHES THE SERVER SPORADICALLY ON WINDOWS On shutdown(), Windows can drop traffic still queued for sending even if that wasn't specifically requested. As a result, fatal errors (those after signaling which the server will drop the connection) were sometimes only seen as "connection lost" on the client side, because the server-side shutdown() erraneously discarded the correct error message before sending it. If on Windows, we now use the Windows API to access the (non-broken) equivalent of shutdown(). Backport from trunk include/violite.h: export mysql_socket_shutdown(). It lives in vio in the backport. sql/mysqld.cc: Go through our own shutdown() rather than straight to the POSIX one. vio/viosocket.c: Define mysql_socket_shutdown(). On UNIXoid systems, it's just a wrapper for shutdown(), but on Window, it uses DisconnectEx, which is magic. --- include/violite.h | 3 +++ sql/mysqld.cc | 16 ++++++++-------- vio/viosocket.c | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/include/violite.h b/include/violite.h index 32354938e13..5facd0911b7 100644 --- a/include/violite.h +++ b/include/violite.h @@ -61,6 +61,9 @@ int vio_close_pipe(Vio * vio); #define HANDLE void * #endif /* __WIN__ */ +/* backport from 5.6 where it is part of PSI, not vio_*() */ +int mysql_socket_shutdown(my_socket mysql_socket, int how); + void vio_delete(Vio* vio); int vio_close(Vio* vio); void vio_reset(Vio* vio, enum enum_vio_type type, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c47d39721b9..a37479dc4b4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -932,7 +932,7 @@ static void close_connections(void) { if (ip_sock != INVALID_SOCKET) { - (void) shutdown(ip_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(ip_sock, SHUT_RDWR); (void) closesocket(ip_sock); ip_sock= INVALID_SOCKET; } @@ -964,7 +964,7 @@ static void close_connections(void) #ifdef HAVE_SYS_UN_H if (unix_sock != INVALID_SOCKET) { - (void) shutdown(unix_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(unix_sock, SHUT_RDWR); (void) closesocket(unix_sock); (void) unlink(mysqld_unix_port); unix_sock= INVALID_SOCKET; @@ -1069,7 +1069,7 @@ static void close_server_sock() { ip_sock=INVALID_SOCKET; DBUG_PRINT("info",("calling shutdown on TCP/IP socket")); - VOID(shutdown(tmp_sock, SHUT_RDWR)); + VOID(mysql_socket_shutdown(tmp_sock, SHUT_RDWR)); #if defined(__NETWARE__) /* The following code is disabled for normal systems as it causes MySQL @@ -1084,7 +1084,7 @@ static void close_server_sock() { unix_sock=INVALID_SOCKET; DBUG_PRINT("info",("calling shutdown on unix socket")); - VOID(shutdown(tmp_sock, SHUT_RDWR)); + VOID(mysql_socket_shutdown(tmp_sock, SHUT_RDWR)); #if defined(__NETWARE__) /* The following code is disabled for normal systems as it may cause MySQL @@ -5091,7 +5091,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (req.sink) ((void (*)(int))req.sink)(req.fd); - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -5106,7 +5106,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (getsockname(new_sock,&dummy, &dummyLen) < 0) { sql_perror("Error on new connection socket"); - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -5118,7 +5118,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (!(thd= new THD)) { - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); VOID(closesocket(new_sock)); continue; } @@ -5137,7 +5137,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) vio_delete(vio_tmp); else { - (void) shutdown(new_sock, SHUT_RDWR); + (void) mysql_socket_shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); } delete thd; diff --git a/vio/viosocket.c b/vio/viosocket.c index 024aacc5db2..9633a01f689 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -23,8 +23,15 @@ the file descriptior. */ +#ifdef __WIN__ + #include + #include + #pragma comment(lib, "ws2_32.lib") +#endif #include "vio_priv.h" + + int vio_errno(Vio *vio __attribute__((unused))) { return socket_errno; /* On Win32 this mapped to WSAGetLastError() */ @@ -260,6 +267,37 @@ vio_was_interrupted(Vio *vio __attribute__((unused))) } +int +mysql_socket_shutdown(my_socket mysql_socket, int how) +{ + int result; + +#ifdef __WIN__ + static LPFN_DISCONNECTEX DisconnectEx = NULL; + if (DisconnectEx == NULL) + { + DWORD dwBytesReturned; + GUID guidDisconnectEx = WSAID_DISCONNECTEX; + WSAIoctl(mysql_socket, SIO_GET_EXTENSION_FUNCTION_POINTER, + &guidDisconnectEx, sizeof(GUID), + &DisconnectEx, sizeof(DisconnectEx), + &dwBytesReturned, NULL, NULL); + } +#endif + + /* Non instrumented code */ +#ifdef __WIN__ + if (DisconnectEx) + result= (DisconnectEx(mysql_socket, (LPOVERLAPPED) NULL, + (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1; + else +#endif + result= shutdown(mysql_socket, how); + + return result; +} + + int vio_close(Vio * vio) { int r=0; @@ -272,7 +310,7 @@ int vio_close(Vio * vio) vio->type == VIO_TYPE_SSL); DBUG_ASSERT(vio->sd >= 0); - if (shutdown(vio->sd, SHUT_RDWR)) + if (mysql_socket_shutdown(vio->sd, SHUT_RDWR)) r= -1; if (closesocket(vio->sd)) r= -1; From bd560bb7b68b14f1d439a91e58d689cb6064e123 Mon Sep 17 00:00:00 2001 From: Sunanda Menon Date: Mon, 20 Feb 2012 06:19:12 +0100 Subject: [PATCH 02/13] Raise version number after cloning 5.0.96 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 908171ca857..0f1968747c0 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.96) +AM_INIT_AUTOMAKE(mysql, 5.0.97) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=96 +NDB_VERSION_BUILD=97 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 457af3df74be62b8e17be0bb8cfc33a0e2c990b7 Mon Sep 17 00:00:00 2001 From: Karen Langford Date: Mon, 20 Feb 2012 17:03:24 +0100 Subject: [PATCH 03/13] Raise version number after cloning 5.1.62 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index fb6155aa0be..ccc2ac26570 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.62], [], [mysql]) +AC_INIT([MySQL Server], [5.1.63], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From f3eb021d5e0c09215b28bf82c10b2e3085ad7a38 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Wed, 22 Feb 2012 11:17:50 +0100 Subject: [PATCH 04/13] Bug#13519724 63793: CRASH IN DTCOLLATION::SET(DTCOLLATION &SET) Backport of fix for: Bug#53236 Segfault in DTCollation::set(DTCollation&) --- mysql-test/r/cast.result | 9 +++++++++ mysql-test/t/cast.test | 12 ++++++++++++ sql/sql_select.cc | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 44d57055e7f..d7a7503707b 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -468,4 +468,13 @@ NULL Warnings: Warning 1301 Result of cast_as_char() was larger than max_allowed_packet (2048) - truncated SET @@GLOBAL.max_allowed_packet=default; +# +# Bug#13519724 63793: CRASH IN DTCOLLATION::SET(DTCOLLATION &SET) +# +CREATE TABLE t1 (a VARCHAR(50)); +SELECT a FROM t1 +WHERE CAST(a as BINARY)=x'62736D697468' +AND CAST(a AS BINARY)=x'65736D697468'; +a +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index 426d7c7fdf2..4474736200c 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -297,4 +297,16 @@ connection default; disconnect newconn; SET @@GLOBAL.max_allowed_packet=default; +--echo # +--echo # Bug#13519724 63793: CRASH IN DTCOLLATION::SET(DTCOLLATION &SET) +--echo # + +CREATE TABLE t1 (a VARCHAR(50)); + +SELECT a FROM t1 +WHERE CAST(a as BINARY)=x'62736D697468' + AND CAST(a AS BINARY)=x'65736D697468'; + +DROP TABLE t1; + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5f1efabfc97..0d8dc740431 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8546,10 +8546,10 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, left_item->collation.collation == value->collation.collation)) { Item *tmp=value->clone_item(); - tmp->collation.set(right_item->collation); if (tmp) { + tmp->collation.set(right_item->collation); thd->change_item_tree(args + 1, tmp); func->update_used_tables(); if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) @@ -8570,10 +8570,10 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, right_item->collation.collation == value->collation.collation)) { Item *tmp= value->clone_item(); - tmp->collation.set(left_item->collation); if (tmp) { + tmp->collation.set(left_item->collation); thd->change_item_tree(args, tmp); value= tmp; func->update_used_tables(); From 7e36c4bdb0364158b63b4939838204b4f140b63e Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Thu, 1 Mar 2012 11:05:51 +0530 Subject: [PATCH 05/13] Bug#13635833: MULTIPLE CRASHES IN FOREIGN KEY CODE WITH CONCURRENT DDL/DML There are two threads. In one thread, dml operation is going on involving cascaded update operation. In another thread, alter table add foreign key constraint is happening. Under these circumstances, it is possible for the dml thread to access a dict_foreign_t object that has been freed by the ddl thread. The debug sync test case provides the sequence of operations. Without fix, the test case will crash the server (because of newly added assert). With fix, the alter table stmt will return an error message. Backporting the fix from MySQL 5.5 to 5.1 rb:961 rb:947 --- include/my_base.h | 7 +- .../suite/innodb/r/innodb_bug13635833.result | 45 +++++++++++++ .../suite/innodb/t/innodb_bug13635833.test | 64 +++++++++++++++++++ .../innodb_plugin/r/innodb_bug13635833.result | 45 +++++++++++++ .../innodb_plugin/t/innodb_bug13635833.test | 64 +++++++++++++++++++ mysys/my_handler_errors.h | 6 +- sql/handler.cc | 2 + storage/innobase/dict/dict0dict.c | 4 ++ storage/innobase/handler/ha_innodb.cc | 4 ++ storage/innobase/include/db0err.h | 2 + storage/innobase/row/row0ins.c | 3 + storage/innobase/row/row0mysql.c | 24 +++++++ storage/innodb_plugin/dict/dict0dict.c | 4 ++ storage/innodb_plugin/handler/ha_innodb.cc | 3 + storage/innodb_plugin/include/db0err.h | 2 + storage/innodb_plugin/row/row0ins.c | 3 + storage/innodb_plugin/row/row0mysql.c | 24 +++++++ 17 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug13635833.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug13635833.test create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug13635833.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test diff --git a/include/my_base.h b/include/my_base.h index 80ba4bcd004..ffd68046029 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -445,7 +445,12 @@ enum ha_base_keytype { #define HA_ERR_FILE_TOO_SHORT 175 /* File too short */ #define HA_ERR_WRONG_CRC 176 /* Wrong CRC on page */ #define HA_ERR_TOO_MANY_CONCURRENT_TRXS 177 /*Too many active concurrent transactions */ -#define HA_ERR_LAST 177 /* Copy of last error nr */ + +/* The error codes from 178 to 180 is not used, because we need to +maintain forward compatibility with higher versions. */ + +#define HA_ERR_TABLE_IN_FK_CHECK 181 /* Table being used in foreign key check */ +#define HA_ERR_LAST 181 /* Copy of last error nr */ /* Number of different errors */ #define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1) diff --git a/mysql-test/suite/innodb/r/innodb_bug13635833.result b/mysql-test/suite/innodb/r/innodb_bug13635833.result new file mode 100644 index 00000000000..e9107d5c125 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug13635833.result @@ -0,0 +1,45 @@ +SET DEBUG_SYNC='reset'; +create table t1 (f1 integer, key k1 (f1)) engine=innodb; +create table t2 (f1 int, f2 int, key(f1), key(f2)) engine=innodb; +create table t3 (f2 int, key(f2)) engine=innodb; +insert into t1 values (10); +insert into t2 values (10, 20); +insert into t3 values (20); +alter table t2 add constraint c1 foreign key (f1) +references t1(f1) on update cascade; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL, + KEY `k1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` int(11) DEFAULT NULL, + `f2` int(11) DEFAULT NULL, + KEY `f1` (`f1`), + KEY `f2` (`f2`), + CONSTRAINT `c1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f2` int(11) DEFAULT NULL, + KEY `f2` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SET DEBUG_SYNC='alter_table_before_rename_result_table + SIGNAL update_can_proceed WAIT_FOR dict_unfreeze'; +alter table t2 add constraint z1 foreign key (f2) +references t3(f2) on update cascade; +SET DEBUG_SYNC='innodb_row_update_for_mysql_begin + WAIT_FOR update_can_proceed'; +SET DEBUG_SYNC='innodb_dml_cascade_dict_unfreeze SIGNAL dict_unfreeze + WAIT_FOR foreign_free_cache'; +update ignore t1 set f1 = 20; +ERROR HY000: Error on rename of './test/t2' to '#sql2-temporary' (errno: 181) +SET DEBUG_SYNC='now SIGNAL foreign_free_cache'; +drop table t2; +drop table t1; +drop table t3; +SET DEBUG_SYNC='reset'; diff --git a/mysql-test/suite/innodb/t/innodb_bug13635833.test b/mysql-test/suite/innodb/t/innodb_bug13635833.test new file mode 100644 index 00000000000..b66b99b7681 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug13635833.test @@ -0,0 +1,64 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source include/not_embedded.inc + +SET DEBUG_SYNC='reset'; + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +create table t1 (f1 integer, key k1 (f1)) engine=innodb; +create table t2 (f1 int, f2 int, key(f1), key(f2)) engine=innodb; +create table t3 (f2 int, key(f2)) engine=innodb; + +insert into t1 values (10); +insert into t2 values (10, 20); +insert into t3 values (20); + +alter table t2 add constraint c1 foreign key (f1) + references t1(f1) on update cascade; + +show create table t1; +show create table t2; +show create table t3; + +SET DEBUG_SYNC='alter_table_before_rename_result_table + SIGNAL update_can_proceed WAIT_FOR dict_unfreeze'; + +--send +alter table t2 add constraint z1 foreign key (f2) + references t3(f2) on update cascade; + +connect (thr2,localhost,root,,); +connection thr2; + +SET DEBUG_SYNC='innodb_row_update_for_mysql_begin + WAIT_FOR update_can_proceed'; +SET DEBUG_SYNC='innodb_dml_cascade_dict_unfreeze SIGNAL dict_unfreeze + WAIT_FOR foreign_free_cache'; + +--send +update ignore t1 set f1 = 20; + +connection default; +--replace_regex /'[^']*test\/#sql2-[0-9a-f-]*'/'#sql2-temporary'/ +--error ER_ERROR_ON_RENAME +reap; + +SET DEBUG_SYNC='now SIGNAL foreign_free_cache'; + +connection thr2; +reap; +disconnect thr2; +--source include/wait_until_disconnected.inc + +connection default; + +drop table t2; +drop table t1; +drop table t3; + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc + +SET DEBUG_SYNC='reset'; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug13635833.result b/mysql-test/suite/innodb_plugin/r/innodb_bug13635833.result new file mode 100644 index 00000000000..e9107d5c125 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug13635833.result @@ -0,0 +1,45 @@ +SET DEBUG_SYNC='reset'; +create table t1 (f1 integer, key k1 (f1)) engine=innodb; +create table t2 (f1 int, f2 int, key(f1), key(f2)) engine=innodb; +create table t3 (f2 int, key(f2)) engine=innodb; +insert into t1 values (10); +insert into t2 values (10, 20); +insert into t3 values (20); +alter table t2 add constraint c1 foreign key (f1) +references t1(f1) on update cascade; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) DEFAULT NULL, + KEY `k1` (`f1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` int(11) DEFAULT NULL, + `f2` int(11) DEFAULT NULL, + KEY `f1` (`f1`), + KEY `f2` (`f2`), + CONSTRAINT `c1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `f2` int(11) DEFAULT NULL, + KEY `f2` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SET DEBUG_SYNC='alter_table_before_rename_result_table + SIGNAL update_can_proceed WAIT_FOR dict_unfreeze'; +alter table t2 add constraint z1 foreign key (f2) +references t3(f2) on update cascade; +SET DEBUG_SYNC='innodb_row_update_for_mysql_begin + WAIT_FOR update_can_proceed'; +SET DEBUG_SYNC='innodb_dml_cascade_dict_unfreeze SIGNAL dict_unfreeze + WAIT_FOR foreign_free_cache'; +update ignore t1 set f1 = 20; +ERROR HY000: Error on rename of './test/t2' to '#sql2-temporary' (errno: 181) +SET DEBUG_SYNC='now SIGNAL foreign_free_cache'; +drop table t2; +drop table t1; +drop table t3; +SET DEBUG_SYNC='reset'; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test b/mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test new file mode 100644 index 00000000000..90df623e8a0 --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test @@ -0,0 +1,64 @@ +--source include/have_innodb_plugin.inc +--source include/have_debug_sync.inc +--source include/not_embedded.inc + +SET DEBUG_SYNC='reset'; + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +create table t1 (f1 integer, key k1 (f1)) engine=innodb; +create table t2 (f1 int, f2 int, key(f1), key(f2)) engine=innodb; +create table t3 (f2 int, key(f2)) engine=innodb; + +insert into t1 values (10); +insert into t2 values (10, 20); +insert into t3 values (20); + +alter table t2 add constraint c1 foreign key (f1) + references t1(f1) on update cascade; + +show create table t1; +show create table t2; +show create table t3; + +SET DEBUG_SYNC='alter_table_before_rename_result_table + SIGNAL update_can_proceed WAIT_FOR dict_unfreeze'; + +--send +alter table t2 add constraint z1 foreign key (f2) + references t3(f2) on update cascade; + +connect (thr2,localhost,root,,); +connection thr2; + +SET DEBUG_SYNC='innodb_row_update_for_mysql_begin + WAIT_FOR update_can_proceed'; +SET DEBUG_SYNC='innodb_dml_cascade_dict_unfreeze SIGNAL dict_unfreeze + WAIT_FOR foreign_free_cache'; + +--send +update ignore t1 set f1 = 20; + +connection default; +--replace_regex /'[^']*test\/#sql2-[0-9a-f-]*'/'#sql2-temporary'/ +--error ER_ERROR_ON_RENAME +reap; + +SET DEBUG_SYNC='now SIGNAL foreign_free_cache'; + +connection thr2; +reap; +disconnect thr2; +--source include/wait_until_disconnected.inc + +connection default; + +drop table t2; +drop table t1; +drop table t3; + +# Wait till we reached the initial number of concurrent sessions +--source include/wait_until_count_sessions.inc + +SET DEBUG_SYNC='reset'; diff --git a/mysys/my_handler_errors.h b/mysys/my_handler_errors.h index 44c79466e84..1710ac81395 100644 --- a/mysys/my_handler_errors.h +++ b/mysys/my_handler_errors.h @@ -78,6 +78,10 @@ static const char *handler_error_messages[]= "Got a fatal error during initialzaction of handler", "File to short; Expected more data in file", "Read page with wrong checksum", - "Too many active concurrent transactions" + "Too many active concurrent transactions", + "", + "", + "", + "Table is being used in foreign key check" /* HA_ERR_TABLE_IN_FK_CHECK */ }; diff --git a/sql/handler.cc b/sql/handler.cc index 895e7cc4df0..d2eaab19ad8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -345,6 +345,7 @@ int ha_init_errors(void) SETMSG(HA_ERR_AUTOINC_READ_FAILED, ER(ER_AUTOINC_READ_FAILED)); SETMSG(HA_ERR_AUTOINC_ERANGE, ER(ER_WARN_DATA_OUT_OF_RANGE)); SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER(ER_TOO_MANY_CONCURRENT_TRXS)); + SETMSG(HA_ERR_TABLE_IN_FK_CHECK, "Table being used in foreign key check"); /* Register the error messages for use with my_error(). */ return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST); @@ -2820,6 +2821,7 @@ void handler::print_error(int error, myf errflag) case HA_ERR_TOO_MANY_CONCURRENT_TRXS: textno= ER_TOO_MANY_CONCURRENT_TRXS; break; + case HA_ERR_TABLE_IN_FK_CHECK: default: { /* The error was "unknown" to this function. diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index beea0a2f411..b2baa81b73f 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -26,6 +26,8 @@ Created 1/8/1996 Heikki Tuuri #include "pars0sym.h" #include "que0que.h" #include "rem0cmp.h" +#include "m_string.h" +#include "my_sys.h" #ifndef UNIV_HOTBACKUP # include "m_ctype.h" /* my_isspace() */ #endif /* !UNIV_HOTBACKUP */ @@ -1889,6 +1891,8 @@ dict_foreign_free( /*==============*/ dict_foreign_t* foreign) /* in, own: foreign key struct */ { + ut_a(foreign->foreign_table->n_foreign_key_checks_running == 0); + mem_heap_free(foreign->heap); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 20ab9c7a101..c59c02abe1b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -746,6 +746,10 @@ convert_error_code_to_mysql( return(HA_ERR_RECORD_FILE_FULL); + } else if (error == (int) DB_TABLE_IN_FK_CHECK) { + + return(HA_ERR_TABLE_IN_FK_CHECK); + } else if (error == (int) DB_TABLE_IS_BEING_USED) { return(HA_ERR_WRONG_COMMAND); diff --git a/storage/innobase/include/db0err.h b/storage/innobase/include/db0err.h index bab6fa46370..1514b19639c 100644 --- a/storage/innobase/include/db0err.h +++ b/storage/innobase/include/db0err.h @@ -82,6 +82,8 @@ Created 5/24/1996 Heikki Tuuri #define DB_REFERENCING_NO_INDEX 52 /* the parent (referencing) table does not have an index that contains the foreign keys as its prefix columns */ +#define DB_TABLE_IN_FK_CHECK 53 /* table is being used in foreign + key check */ /* The following are partial failure codes */ #define DB_FAIL 1000 diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index bb5c95a572b..785a0426195 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1074,6 +1074,9 @@ row_ins_foreign_check_on_constraint( release the latch. */ row_mysql_unfreeze_data_dictionary(thr_get_trx(thr)); + + DEBUG_SYNC_C("innodb_dml_cascade_dict_unfreeze"); + row_mysql_freeze_data_dictionary(thr_get_trx(thr)); mtr_start(mtr); diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 6148b01af9d..e8b3c485b0e 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -31,6 +31,8 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "fil0fil.h" #include "ibuf0ibuf.h" +#include "m_string.h" +#include "my_sys.h" /* A dummy variable used to fool the compiler */ ibool row_mysql_identically_false = FALSE; @@ -1373,6 +1375,8 @@ row_update_for_mysql( return(DB_ERROR); } + DEBUG_SYNC_C("innodb_row_update_for_mysql_begin"); + trx->op_info = "updating or deleting"; row_mysql_delay_if_needed(); @@ -3652,6 +3656,7 @@ row_rename_table_for_mysql( ulint n_constraints_to_drop = 0; ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; + ulint retry = 0; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(old_name != NULL); @@ -3750,6 +3755,25 @@ row_rename_table_for_mysql( } } + /* Is a foreign key check running on this table? */ + for (retry = 0; retry < 100 + && table->n_foreign_key_checks_running > 0; ++retry) { + row_mysql_unlock_data_dictionary(trx); + os_thread_yield(); + row_mysql_lock_data_dictionary(trx); + } + + if (table->n_foreign_key_checks_running > 0) { + ut_print_timestamp(stderr); + fputs(" InnoDB: Error: in ALTER TABLE ", stderr); + ut_print_name(stderr, trx, TRUE, old_name); + fprintf(stderr, "\n" + "InnoDB: a FOREIGN KEY check is running.\n" + "InnoDB: Cannot rename table.\n"); + err = DB_TABLE_IN_FK_CHECK; + goto funct_exit; + } + /* We use the private SQL parser of Innobase to generate the query graphs needed in deleting the dictionary data from system tables in Innobase. Deleting a row from SYS_INDEXES table also frees the file diff --git a/storage/innodb_plugin/dict/dict0dict.c b/storage/innodb_plugin/dict/dict0dict.c index 2d2262acf87..b70d5929f53 100644 --- a/storage/innodb_plugin/dict/dict0dict.c +++ b/storage/innodb_plugin/dict/dict0dict.c @@ -24,6 +24,8 @@ Created 1/8/1996 Heikki Tuuri ***********************************************************************/ #include "dict0dict.h" +#include "m_string.h" +#include "my_sys.h" #ifdef UNIV_NONINL #include "dict0dict.ic" @@ -2272,6 +2274,8 @@ dict_foreign_free( /*==============*/ dict_foreign_t* foreign) /*!< in, own: foreign key struct */ { + ut_a(foreign->foreign_table->n_foreign_key_checks_running == 0); + mem_heap_free(foreign->heap); } diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 09094c0146e..47d309f2360 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -868,6 +868,9 @@ convert_error_code_to_mysql( case DB_OUT_OF_FILE_SPACE: return(HA_ERR_RECORD_FILE_FULL); + case DB_TABLE_IN_FK_CHECK: + return(HA_ERR_TABLE_IN_FK_CHECK); + case DB_TABLE_IS_BEING_USED: return(HA_ERR_WRONG_COMMAND); diff --git a/storage/innodb_plugin/include/db0err.h b/storage/innodb_plugin/include/db0err.h index c7fa6d2a444..e4a3844cd22 100644 --- a/storage/innodb_plugin/include/db0err.h +++ b/storage/innodb_plugin/include/db0err.h @@ -97,6 +97,8 @@ enum db_err { DB_FOREIGN_EXCEED_MAX_CASCADE, /* Foreign key constraint related cascading delete/update exceeds maximum allowed depth */ + DB_TABLE_IN_FK_CHECK, /* table is being used in foreign + key check */ /* The following are partial failure codes */ DB_FAIL = 1000, diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index 9a603d5690f..2d4afa6c5ed 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -1102,6 +1102,9 @@ row_ins_foreign_check_on_constraint( release the latch. */ row_mysql_unfreeze_data_dictionary(thr_get_trx(thr)); + + DEBUG_SYNC_C("innodb_dml_cascade_dict_unfreeze"); + row_mysql_freeze_data_dictionary(thr_get_trx(thr)); mtr_start(mtr); diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 36aad4f8ca2..cd46244eb34 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -51,6 +51,8 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "fil0fil.h" #include "ibuf0ibuf.h" +#include "m_string.h" +#include "my_sys.h" /** Provide optional 4.x backwards compatibility for 5.0 and above */ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; @@ -1350,6 +1352,8 @@ row_update_for_mysql( return(DB_ERROR); } + DEBUG_SYNC_C("innodb_row_update_for_mysql_begin"); + trx->op_info = "updating or deleting"; row_mysql_delay_if_needed(); @@ -3741,6 +3745,7 @@ row_rename_table_for_mysql( ulint n_constraints_to_drop = 0; ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; + ulint retry = 0; ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(old_name != NULL); @@ -3824,6 +3829,25 @@ row_rename_table_for_mysql( } } + /* Is a foreign key check running on this table? */ + for (retry = 0; retry < 100 + && table->n_foreign_key_checks_running > 0; ++retry) { + row_mysql_unlock_data_dictionary(trx); + os_thread_yield(); + row_mysql_lock_data_dictionary(trx); + } + + if (table->n_foreign_key_checks_running > 0) { + ut_print_timestamp(stderr); + fputs(" InnoDB: Error: in ALTER TABLE ", stderr); + ut_print_name(stderr, trx, TRUE, old_name); + fprintf(stderr, "\n" + "InnoDB: a FOREIGN KEY check is running.\n" + "InnoDB: Cannot rename table.\n"); + err = DB_TABLE_IN_FK_CHECK; + goto funct_exit; + } + /* We use the private SQL parser of Innobase to generate the query graphs needed in updating the dictionary data from system tables. */ From 621db3d42ef19d8ff28da9968fcc47d952345a28 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Thu, 1 Mar 2012 15:44:23 +0530 Subject: [PATCH 06/13] The innodb plugin module cannot use DEBUG_SYNC_C facility on Windows. Taking care of it. --- .../suite/innodb_plugin/t/innodb_bug13635833.test | 2 ++ storage/innodb_plugin/row/row0mysql.c | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test b/mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test index 90df623e8a0..5db7a41e201 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug13635833.test @@ -1,6 +1,8 @@ --source include/have_innodb_plugin.inc --source include/have_debug_sync.inc --source include/not_embedded.inc +# InnoDB Plugin cannot use DEBUG_SYNC on Windows +--source include/not_windows.inc SET DEBUG_SYNC='reset'; diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index cd46244eb34..b7df3479a3c 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -51,8 +51,14 @@ Created 9/17/2000 Heikki Tuuri #include "btr0sea.h" #include "fil0fil.h" #include "ibuf0ibuf.h" -#include "m_string.h" -#include "my_sys.h" + +#ifdef __WIN__ +/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */ +# define DEBUG_SYNC_C(dummy) ((void) 0) +#else +# include "m_string.h" /* for my_sys.h */ +# include "my_sys.h" /* DEBUG_SYNC_C */ +#endif /** Provide optional 4.x backwards compatibility for 5.0 and above */ UNIV_INTERN ibool row_rollback_on_timeout = FALSE; From 8aea62fa8a4ac6b065322814d2dcc2c2a9a7ec7e Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Mon, 5 Mar 2012 21:58:07 +0400 Subject: [PATCH 07/13] Fix for BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS Problem: lack of incoming geometry data validation may lead to a server crash when ISCLOSED() function called. Solution: necessary incoming data check added. mysql-test/r/gis.result: Fix for BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS test result. mysql-test/t/gis.test: Fix for BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS test case. sql/spatial.cc: Fix for BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS check if a LINESTRING has at least one point as we rely on that further. --- mysql-test/r/gis.result | 6 ++++++ mysql-test/t/gis.test | 7 +++++++ sql/spatial.cc | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index acb55d225a7..9b901e0f93f 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -1075,4 +1075,10 @@ SPATIAL INDEX i1 (col1, col2) ); ERROR HY000: Incorrect arguments to SPATIAL INDEX DROP TABLE t0, t1, t2; +# +# BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS +# +SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); +ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))) +NULL End of 5.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index f8cec14d9ae..fbd4c87cb97 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -812,4 +812,11 @@ CREATE TABLE t3 ( # cleanup DROP TABLE t0, t1, t2; + +--echo # +--echo # BUG#12414917 - ISCLOSED() CRASHES ON 64-BIT BUILDS +--echo # +SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); + + --echo End of 5.1 tests diff --git a/sql/spatial.cc b/sql/spatial.cc index ed3d72b91ec..0d2dd81c71e 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -627,7 +627,8 @@ int Gis_line_string::is_closed(int *closed) const return 0; } data+= 4; - if (no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) + if (n_points == 0 || + no_data(data, SIZEOF_STORED_DOUBLE * 2 * n_points)) return 1; /* Get first point */ From 30d32207e724ebf9dca7c2ecdaec04b076cd902b Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Mon, 5 Mar 2012 22:15:23 +0400 Subject: [PATCH 08/13] BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN GEOMETRY FUNCTION ARGUMENTS A defect in the subquery substitution code may lead to a server crash: setting substitution's name should be followed by setting its length (to keep them in sync). mysql-test/r/gis.result: BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN GEOMETRY FUNCTION ARGUMENTS test result. mysql-test/t/gis.test: BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN GEOMETRY FUNCTION ARGUMENTS test case. sql/item_subselect.cc: BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN GEOMETRY FUNCTION ARGUMENTS set substitution's name length as well as the name itself (to keep them in sync). --- mysql-test/r/gis.result | 6 ++++++ mysql-test/t/gis.test | 7 +++++++ sql/item_subselect.cc | 1 + 3 files changed, 14 insertions(+) diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 9b901e0f93f..9af100e479c 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -1081,4 +1081,10 @@ DROP TABLE t0, t1, t2; SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))) NULL +# +# BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN +# GEOMETRY FUNCTION ARGUMENTS +# +SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); +ERROR 22007: Illegal non geometric '' value found during parsing End of 5.1 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index fbd4c87cb97..c2a1416f9a1 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -818,5 +818,12 @@ DROP TABLE t0, t1, t2; --echo # SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); +--echo # +--echo # BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN +--echo # GEOMETRY FUNCTION ARGUMENTS +--echo # +--error ER_ILLEGAL_VALUE_FOR_TYPE +SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); + --echo End of 5.1 tests diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index e9e2e8bacf9..8335ae2ca8d 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -173,6 +173,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) (*ref)= substitution; substitution->name= name; + substitution->name_length= name_length; if (have_to_be_excluded) engine->exclude(); substitution= 0; From b15a8bf8a7ec9d1181cf813a2662a0777dbcea89 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 6 Mar 2012 15:13:56 +0400 Subject: [PATCH 09/13] BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN GEOMETRY FUNCTION ARGUMENTS Fixed --ps-protocol gis test failure. --- mysql-test/t/gis.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index c2a1416f9a1..abda3e997bd 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -822,6 +822,7 @@ SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); --echo # BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN --echo # GEOMETRY FUNCTION ARGUMENTS --echo # +--replace_regex /non geometric .* value/non geometric '' value/ --error ER_ILLEGAL_VALUE_FOR_TYPE SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); From c48233c61e6ab3a45f554de4d975f5c91b914822 Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Sun, 11 Mar 2012 16:05:42 +0400 Subject: [PATCH 10/13] Fixed test case for bug #13105873 "valgrind warning:possible crash in foreign key handling on subsequent create table if not exists". Do not leave current database unassigned after the end of the test case. --- mysql-test/r/sp-bugs.result | 1 + mysql-test/t/sp-bugs.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/r/sp-bugs.result b/mysql-test/r/sp-bugs.result index 59588768d14..3b4e2855e46 100644 --- a/mysql-test/r/sp-bugs.result +++ b/mysql-test/r/sp-bugs.result @@ -128,4 +128,5 @@ CALL p1(); Warnings: Note 1050 Table 't2' already exists DROP DATABASE testdb; +USE test; End of 5.1 tests diff --git a/mysql-test/t/sp-bugs.test b/mysql-test/t/sp-bugs.test index a23ccea8189..2d143b6d86a 100644 --- a/mysql-test/t/sp-bugs.test +++ b/mysql-test/t/sp-bugs.test @@ -161,5 +161,6 @@ CALL p1(); --echo # below stmt should not return valgrind warnings CALL p1(); DROP DATABASE testdb; +USE test; --echo End of 5.1 tests From ad031d51100555dd1b77baaa075d2f7c8790571b Mon Sep 17 00:00:00 2001 From: "Norvald H. Ryeng" Date: Mon, 12 Mar 2012 08:56:56 +0100 Subject: [PATCH 11/13] Bug#13031606 VALUES() IN A SELECT STATEMENT CRASHES SERVER Problem: Grouping results by VALUES(alias for string literal) causes the server to crash. Item_insert_values is not constructed to handle other types of arguments than field and reference to field. In this case, the argument is an Item_string, and this causes Item_insert_values::fix_fields() to crash. Fix: Issue an error message when the argument to Item_insert_values is not a field or a reference to a field. This is slightly in breach with documentation, which states that VALUES should return NULL, but the error message is only issued in cases where the server otherwise would crash, so there is no change in behavior for queries that already work. Future versions will restrict syntax so that using VALUES in this way is illegal. mysql-test/r/errors.result: Add test case for bug #13031606. mysql-test/t/errors.test: Add test case for bug #13031606. sql/item.cc: Issue error message if argument is not field or reference to field. --- mysql-test/r/errors.result | 14 ++++++++++++++ mysql-test/t/errors.test | 18 ++++++++++++++++++ sql/item.cc | 16 ++++------------ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/errors.result b/mysql-test/r/errors.result index 022a32d9c9b..bcc92296945 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -55,3 +55,17 @@ Error 1054 Unknown column 'b' in 'field list' INSERT INTO t1 SELECT b FROM t1; ERROR 42S22: Unknown column 'b' in 'field list' DROP TABLE t1; +CREATE TABLE t1 (a INT); +CREATE TABLE t2(a INT PRIMARY KEY, b INT); +SELECT '' AS b FROM t1 GROUP BY VALUES(b); +ERROR 42S22: Unknown column '' in 'VALUES() function' +REPLACE t2(b) SELECT '' AS b FROM t1 GROUP BY VALUES(b); +ERROR 42S22: Unknown column '' in 'VALUES() function' +UPDATE t2 SET a=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +ERROR 42S22: Unknown column '' in 'VALUES() function' +INSERT INTO t2 VALUES (1,0) ON DUPLICATE KEY UPDATE +b=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +ERROR 42S22: Unknown column '' in 'VALUES() function' +INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE +b=(SELECT VALUES(a)+2 FROM t1); +DROP TABLE t1, t2; diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index 89579ec1739..b426d9fd5b0 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -67,3 +67,21 @@ SHOW ERRORS; INSERT INTO t1 SELECT b FROM t1; DROP TABLE t1; # End of 5.0 tests + +# +# Bug #13031606 VALUES() IN A SELECT STATEMENT CRASHES SERVER +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2(a INT PRIMARY KEY, b INT); +--error ER_BAD_FIELD_ERROR +SELECT '' AS b FROM t1 GROUP BY VALUES(b); +--error ER_BAD_FIELD_ERROR +REPLACE t2(b) SELECT '' AS b FROM t1 GROUP BY VALUES(b); +--error ER_BAD_FIELD_ERROR +UPDATE t2 SET a=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +--error ER_BAD_FIELD_ERROR +INSERT INTO t2 VALUES (1,0) ON DUPLICATE KEY UPDATE + b=(SELECT '' AS b FROM t1 GROUP BY VALUES(b)); +INSERT INTO t2(a,b) VALUES (1,0) ON DUPLICATE KEY UPDATE + b=(SELECT VALUES(a)+2 FROM t1); +DROP TABLE t1, t2; diff --git a/sql/item.cc b/sql/item.cc index 2a7d2453889..90bfb0d2852 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6657,20 +6657,12 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items) } if (arg->type() == REF_ITEM) + arg= static_cast(arg)->ref[0]; + if (arg->type() != FIELD_ITEM) { - Item_ref *ref= (Item_ref *)arg; - if (ref->ref[0]->type() != FIELD_ITEM) - { - my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function"); - return TRUE; - } - arg= ref->ref[0]; + my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function"); + return TRUE; } - /* - According to our SQL grammar, VALUES() function can reference - only to a column. - */ - DBUG_ASSERT(arg->type() == FIELD_ITEM); Item_field *field_arg= (Item_field *)arg; From b5c690aa548ce7796d25f9df3f8ae056dcda1703 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 4 Apr 2012 13:29:45 +0400 Subject: [PATCH 12/13] Bug#11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE Bug#13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE INDEX The crash happened due to wrong calculation of key length during creation of reference for sort order index. The problem is that keyuse->used_tables can have OUTER_REF_TABLE_BIT enabled but used_tables parameter(create_ref_for_key() func) does not have it. So key parts which have OUTER_REF_TABLE_BIT are ommited and it could lead to incorrect key length calculation(zero key length). mysql-test/r/subselect_innodb.result: test result mysql-test/t/subselect_innodb.test: test case sql/sql_select.cc: added OUTER_REF_TABLE_BIT to the used_tables parameter for create_ref_for_key() function. storage/innobase/handler/ha_innodb.cc: added assertion, request from Inno team storage/innodb_plugin/handler/ha_innodb.cc: added assertion, request from Inno team --- mysql-test/r/subselect_innodb.result | 60 ++++++++++++++++++++++ mysql-test/t/subselect_innodb.test | 56 ++++++++++++++++++++ sql/sql_select.cc | 7 ++- storage/innobase/handler/ha_innodb.cc | 1 + storage/innodb_plugin/handler/ha_innodb.cc | 1 + 5 files changed, 124 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result index 6c6d563e284..4069958267a 100644 --- a/mysql-test/r/subselect_innodb.result +++ b/mysql-test/r/subselect_innodb.result @@ -245,3 +245,63 @@ x NULL drop procedure p1; drop tables t1,t2,t3; +# +# Bug #11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE +# +CREATE TABLE t1 (a INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (0); +CREATE TABLE t2 (d BINARY(2), PRIMARY KEY (d(1)), UNIQUE KEY (d)) ENGINE=INNODB; +SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); +1 +1 +EXPLAIN SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where +2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY,d d 2 func 1 Using where +3 DEPENDENT SUBQUERY t2 index NULL d 2 NULL 1 Using where; Using index +DROP TABLE t2; +CREATE TABLE t2 (b INT, c INT, UNIQUE KEY (b), UNIQUE KEY (b, c )) ENGINE=INNODB; +INSERT INTO t2 VALUES (1, 1); +SELECT 1 FROM t1 +WHERE a != (SELECT 1 FROM t2 WHERE a <=> b OR a > '' AND 6 = 7 ORDER BY b, c); +1 +DROP TABLE t1, t2; +# +# Bug #13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE +# INDEX +# +CREATE TABLE t1 ( +id int +) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (11); +CREATE TABLE t2 ( +t1_id int, +position int, +KEY t1_id (t1_id), +KEY t1_id_position (t1_id,position) +) ENGINE=InnoDB; +EXPLAIN SELECT +(SELECT position FROM t2 +WHERE t2.t1_id = t1.id +ORDER BY t2.t1_id , t2.position +LIMIT 10,1 +) AS maxkey +FROM t1 +LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 1 +2 DEPENDENT SUBQUERY t2 ref t1_id,t1_id_position t1_id_position 5 test.t1.id 1 Using where +SELECT +(SELECT position FROM t2 +WHERE t2.t1_id = t1.id +ORDER BY t2.t1_id , t2.position +LIMIT 10,1 +) AS maxkey +FROM t1 +LIMIT 1; +maxkey +NULL +DROP TABLE t1,t2; +End of 5.1 tests diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test index 573fe0c1810..ce070b454c3 100644 --- a/mysql-test/t/subselect_innodb.test +++ b/mysql-test/t/subselect_innodb.test @@ -238,3 +238,59 @@ call p1(); call p1(); drop procedure p1; drop tables t1,t2,t3; + +--echo # +--echo # Bug #11766300 59387: FAILING ASSERTION: CURSOR->POS_STATE == 1997660512 (BTR_PCUR_IS_POSITIONE +--echo # + +CREATE TABLE t1 (a INT) ENGINE=INNODB; +INSERT INTO t1 VALUES (0); +CREATE TABLE t2 (d BINARY(2), PRIMARY KEY (d(1)), UNIQUE KEY (d)) ENGINE=INNODB; + +SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); + +EXPLAIN SELECT 1 FROM t1 WHERE NOT EXISTS +(SELECT 1 FROM t2 WHERE d = (SELECT d FROM t2 WHERE a >= 1) ORDER BY d); + +DROP TABLE t2; + +CREATE TABLE t2 (b INT, c INT, UNIQUE KEY (b), UNIQUE KEY (b, c )) ENGINE=INNODB; +INSERT INTO t2 VALUES (1, 1); + +SELECT 1 FROM t1 +WHERE a != (SELECT 1 FROM t2 WHERE a <=> b OR a > '' AND 6 = 7 ORDER BY b, c); + +DROP TABLE t1, t2; + +--echo # +--echo # Bug #13639204 64111: CRASH ON SELECT SUBQUERY WITH NON UNIQUE +--echo # INDEX +--echo # +CREATE TABLE t1 ( +id int +) ENGINE=InnoDB; +INSERT INTO t1 (id) VALUES (11); + +CREATE TABLE t2 ( +t1_id int, +position int, +KEY t1_id (t1_id), +KEY t1_id_position (t1_id,position) +) ENGINE=InnoDB; + +let $query=SELECT +(SELECT position FROM t2 +WHERE t2.t1_id = t1.id +ORDER BY t2.t1_id , t2.position +LIMIT 10,1 +) AS maxkey +FROM t1 +LIMIT 1; + +eval EXPLAIN $query; +eval $query; + +DROP TABLE t1,t2; + +--echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0d8dc740431..a0390baffaa 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5793,6 +5793,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, } keyuse++; } while (keyuse->table == table && keyuse->key == key); + DBUG_ASSERT(length > 0 && keyparts != 0); } /* not ftkey */ /* set up fieldref */ @@ -13426,6 +13427,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, DBUG_ENTER("test_if_skip_sort_order"); LINT_INIT(ref_key_parts); + /* Check that we are always called with first non-const table */ + DBUG_ASSERT(tab == tab->join->join_tab + tab->join->const_tables); + /* Keys disabled by ALTER TABLE ... DISABLE KEYS should have already been taken into account. @@ -13507,7 +13511,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, while (keyuse->key != new_ref_key && keyuse->table == tab->table) keyuse++; if (create_ref_for_key(tab->join, tab, keyuse, - tab->join->const_table_map)) + (tab->join->const_table_map | + OUTER_REF_TABLE_BIT))) DBUG_RETURN(0); pick_table_access_method(tab); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index c59c02abe1b..6576016501f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4871,6 +4871,7 @@ ha_innobase::index_read( DBUG_ENTER("index_read"); ut_a(prebuilt->trx == thd_to_trx(user_thd)); + ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT); ha_statistic_increment(&SSV::ha_read_key_count); diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index d1e9649be07..b8e9ccc72ef 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -5575,6 +5575,7 @@ ha_innobase::index_read( DBUG_ENTER("index_read"); ut_a(prebuilt->trx == thd_to_trx(user_thd)); + ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT); ha_statistic_increment(&SSV::ha_read_key_count); From 7dcf0a66fdcd098fb6f8700712595bbaeb4e3cbf Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 6 Apr 2012 12:04:07 +0300 Subject: [PATCH 13/13] Bug #13934049: 64884: LOGINS WITH INCORRECT PASSWORD ARE ALLOWED Fixed an improper type conversion on return that can make the server accept logins with a wrong password. --- sql/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/password.c b/sql/password.c index e9e81fb7bf3..e029ba51fc4 100644 --- a/sql/password.c +++ b/sql/password.c @@ -531,7 +531,7 @@ check_scramble(const char *scramble_arg, const char *message, mysql_sha1_reset(&sha1_context); mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE); mysql_sha1_result(&sha1_context, hash_stage2_reassured); - return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE); + return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE)); }