Auto-merge from mysql-trunk-bugfixing.

This commit is contained in:
Alexander Nozdrin 2010-07-30 19:13:38 +04:00
commit 02a0787d8d
284 changed files with 7335 additions and 5154 deletions

View File

@ -6,6 +6,7 @@ configure="./configure $base_configs $extra_configs"
commands="\
$make -k maintainer-clean || true
/bin/rm -rf */.deps/*.P configure config.cache storage/*/configure storage/*/config.cache autom4te.cache storage/*/autom4te.cache;
/bin/rm -rf CMakeCache.txt CMakeFiles/
path=`dirname $0`
. \"$path/autorun.sh\""

View File

@ -20,7 +20,7 @@
EXTRA_DIST = FINISH.sh \
SETUP.sh \
autorun.sh \
choose_configure.sh \
cmake_configure.sh \
build_mccge.sh \
check-cpu \
cleanup \

View File

@ -21,18 +21,24 @@ done
IFS="$save_ifs"
rm -rf configure
aclocal || die "Can't execute aclocal"
autoheader || die "Can't execute autoheader"
# --force means overwrite ltmain.sh script if it already exists
$LIBTOOLIZE --automake --force --copy || die "Can't execute libtoolize"
# --add-missing instructs automake to install missing auxiliary files
# and --force to overwrite them if they already exist
automake --add-missing --force --copy || die "Can't execute automake"
autoconf || die "Can't execute autoconf"
# Do not use autotools generated configure directly. Instead, use a script
# that will either call CMake or original configure shell script at build
# time (CMake is preferred if installed).
mv configure configure.am
cp BUILD/choose_configure.sh configure
chmod a+x configure
# Ensure that cmake and perl are available. Required for cmake based builds.
cmake -P cmake/check_minimal_version.cmake >/dev/null 2>&1 || HAVE_CMAKE=no
perl --version >/dev/null 2>&1 || HAVE_CMAKE=no
# Whether to use the autotools configuration script or cmake.
if test "$HAVE_CMAKE" = "no"
then
aclocal || die "Can't execute aclocal"
autoheader || die "Can't execute autoheader"
# --force means overwrite ltmain.sh script if it already exists
$LIBTOOLIZE --automake --force --copy || die "Can't execute libtoolize"
# --add-missing instructs automake to install missing auxiliary files
# and --force to overwrite them if they already exist
automake --add-missing --force --copy || die "Can't execute automake"
autoconf || die "Can't execute autoconf"
else
path=`dirname $0`
cp $path/cmake_configure.sh $path/../configure
chmod +x $path/../configure
fi

View File

@ -148,6 +148,9 @@ OPTION(ENABLED_PROFILING "Enable profiling" ON)
OPTION(CYBOZU "" OFF)
OPTION(BACKUP_TEST "" OFF)
OPTION(WITHOUT_SERVER OFF)
IF(UNIX)
OPTION(WITH_VALGRIND "Valgrind instrumentation" OFF)
ENDIF()
OPTION (WITH_UNIT_TESTS "Compile MySQL with unit tests" ON)
MARK_AS_ADVANCED(CYBOZU BACKUP_TEST WITHOUT_SERVER DISABLE_SHARED)

View File

@ -65,7 +65,7 @@ dist-hook:
test ! -f $(top_srcdir)/configure.am || \
$(INSTALL_DATA) $(top_srcdir)/configure.am $(distdir)
all-local: @ABI_CHECK@
all-local: @ABI_CHECK@
tags:
support-files/build-tags
@ -314,7 +314,7 @@ abi_check_all: abi_check
do_abi_check:
set -ex; \
for file in $(abi_headers); do \
@CC@ -E -nostdinc -dI \
@CC@ -E -nostdinc -dI -DMYSQL_ABI_CHECK \
-I$(top_srcdir)/include \
-I$(top_srcdir)/include/mysql \
-I$(top_srcdir)/sql \

View File

@ -3652,7 +3652,7 @@ xmlencode_print(const char *src, uint length)
tee_fputs("NULL", PAGER);
else
{
for (const char *p = src; length; *p++, length--)
for (const char *p = src; length; p++, length--)
{
const char *t;
if ((t = array_value(xmlmeta, *p)))
@ -4740,7 +4740,7 @@ static const char* construct_prompt()
struct tm *t = localtime(&lclock);
/* parse thru the settings for the prompt */
for (char *c = current_prompt; *c ; *c++)
for (char *c = current_prompt; *c ; c++)
{
if (*c != PROMPT_CHAR)
processed_prompt.append(*c);

View File

@ -596,7 +596,10 @@ static int upgrade_already_done(void)
my_fclose(in, MYF(0));
return (strncmp(buf, MYSQL_SERVER_VERSION,
if (!res)
return 0; /* Could not read from file => not sure */
return (strncmp(res, MYSQL_SERVER_VERSION,
sizeof(MYSQL_SERVER_VERSION)-1)==0);
}

View File

@ -38,7 +38,7 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYSTEM_NAME MATCHES "Linux")
-DCOMPILER=${COMPILER}
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-DBINARY_DIR=${CMAKE_BINARY_DIR}
"-DABI_HEADERS=${API_PREPROCESSOR_HEADER}"
"-DDMYSQL_ABI_CHECK -DABI_HEADERS=${API_PREPROCESSOR_HEADER}"
-P ${CMAKE_SOURCE_DIR}/cmake/do_abi_check.cmake
VERBATIM
)
@ -48,7 +48,7 @@ IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_SYSTEM_NAME MATCHES "Linux")
-DCMAKE_C_COMPILER=${COMPILER}
-DCMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}
-DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}
"-DABI_HEADERS=${API_PREPROCESSOR_HEADER}"
"-DMYSQL_ABI_CHECK -DABI_HEADERS=${API_PREPROCESSOR_HEADER}"
-P ${CMAKE_SOURCE_DIR}/cmake/scripts/do_abi_check.cmake
VERBATIM
)

View File

@ -308,7 +308,7 @@
#define USE_MB 1
#define USE_MB_IDENT 1
#cmakedefine HAVE_VALGRIND
/* Types we may use */
#ifdef __APPLE__

View File

@ -805,7 +805,7 @@ ENDIF(NOT HAVE_POSIX_SIGNALS)
# Assume regular sprintf
SET(SPRINTFS_RETURNS_INT 1)
IF(CMAKE_COMPILER_IS_GNUXX AND HAVE_CXXABI_H)
IF(CMAKE_COMPILER_IS_GNUCXX AND HAVE_CXXABI_H)
CHECK_CXX_SOURCE_COMPILES("
#include <cxxabi.h>
int main(int argc, char **argv)
@ -994,6 +994,14 @@ configuration. By default gcc built-in sync functions are used,
if available and 'smp' configuration otherwise.")
MARK_AS_ADVANCED(WITH_ATOMIC_LOCKS MY_ATOMIC_MODE_RWLOCK MY_ATOMIC_MODE_DUMMY)
IF(WITH_VALGRIND)
CHECK_INCLUDE_FILES("valgrind/memcheck.h;valgrind/valgrind.h"
HAVE_VALGRIND_HEADERS)
IF(HAVE_VALGRIND_HEADERS)
SET(HAVE_VALGRIND 1)
ENDIF()
ENDIF()
#--------------------------------------------------------------------
# Check for IPv6 support
#--------------------------------------------------------------------

View File

@ -463,16 +463,7 @@ if test "$GCC" != "yes" || expr "$CC" : ".*icc.*"
then
ABI_CHECK=""
else
# Workaround GCC >= 4.5 - See Bug#52514
case `$CC -dumpversion` in
[[4-9]].[[5-9]]*)
AC_MSG_WARN([ABI check disabled (GCC >= 4.5)])
ABI_CHECK=""
;;
*)
ABI_CHECK="abi_check"
;;
esac
ABI_CHECK="abi_check"
fi
AC_SUBST(ABI_CHECK)
@ -3045,7 +3036,8 @@ fi
AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl
unittest/Makefile unittest/mytap/Makefile unittest/mytap/t/Makefile dnl
unittest/mysys/Makefile unittest/examples/Makefile dnl
unittest/mysys/Makefile unittest/strings/Makefile dnl
unittest/examples/Makefile dnl
strings/Makefile regex/Makefile storage/Makefile dnl
man/Makefile BUILD/Makefile vio/Makefile dnl
libmysql/Makefile libmysql_r/Makefile client/Makefile dnl

View File

@ -857,7 +857,6 @@ static struct message *parse_message_string(struct message *new_message,
static struct errors *parse_error_string(char *str, int er_count)
{
struct errors *new_error;
char *start;
DBUG_ENTER("parse_error_string");
DBUG_PRINT("enter", ("str: %s", str));
@ -868,7 +867,6 @@ static struct errors *parse_error_string(char *str, int er_count)
DBUG_RETURN(0); /* OOM: Fatal error */
/* getting the error name */
start= str;
str= skip_delimiters(str);
if (!(new_error->er_name= get_word(&str)))

View File

@ -884,21 +884,19 @@ void Alert::Process(input_buffer& input, SSL& ssl)
else
hmac(ssl, verify, data, aSz, alert, true);
// read mac and fill
// read mac and skip fill
int digestSz = ssl.getCrypto().get_digest().get_digestSize();
opaque mac[SHA_LEN];
input.read(mac, digestSz);
if (ssl.getSecurity().get_parms().cipher_type_ == block) {
int ivExtra = 0;
opaque fill;
if (ssl.isTLSv1_1())
ivExtra = ssl.getCrypto().get_cipher().get_blockSize();
int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra -
aSz - digestSz;
for (int i = 0; i < padSz; i++)
fill = input[AUTO];
input.set_current(input.get_current() + padSz);
}
// verify
@ -981,17 +979,17 @@ output_buffer& operator<<(output_buffer& output, const Data& data)
void Data::Process(input_buffer& input, SSL& ssl)
{
int msgSz = ssl.getSecurity().get_parms().encrypt_size_;
int pad = 0, padByte = 0;
int pad = 0, padSz = 0;
int ivExtra = 0;
if (ssl.getSecurity().get_parms().cipher_type_ == block) {
if (ssl.isTLSv1_1()) // IV
ivExtra = ssl.getCrypto().get_cipher().get_blockSize();
pad = *(input.get_buffer() + input.get_current() + msgSz -ivExtra - 1);
padByte = 1;
padSz = 1;
}
int digestSz = ssl.getCrypto().get_digest().get_digestSize();
int dataSz = msgSz - ivExtra - digestSz - pad - padByte;
int dataSz = msgSz - ivExtra - digestSz - pad - padSz;
opaque verify[SHA_LEN];
const byte* rawData = input.get_buffer() + input.get_current();
@ -1020,14 +1018,10 @@ void Data::Process(input_buffer& input, SSL& ssl)
hmac(ssl, verify, rawData, dataSz, application_data, true);
}
// read mac and fill
// read mac and skip fill
opaque mac[SHA_LEN];
opaque fill;
input.read(mac, digestSz);
for (int i = 0; i < pad; i++)
fill = input[AUTO];
if (padByte)
fill = input[AUTO];
input.set_current(input.get_current() + pad + padSz);
// verify
if (dataSz) {
@ -2073,11 +2067,9 @@ void Finished::Process(input_buffer& input, SSL& ssl)
if (ssl.isTLSv1_1())
ivExtra = ssl.getCrypto().get_cipher().get_blockSize();
opaque fill;
int padSz = ssl.getSecurity().get_parms().encrypt_size_ - ivExtra -
HANDSHAKE_HEADER - finishedSz - digestSz;
for (int i = 0; i < padSz; i++)
fill = input[AUTO];
input.set_current(input.get_current() + padSz);
// verify mac
if (memcmp(mac, verifyMAC, digestSz)) {

View File

@ -255,14 +255,13 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
we want to make sure that no such flags are set.
*/
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; int l_rc; \
#define my_sigset(A,B) do { struct sigaction l_s; sigset_t l_set; \
DBUG_ASSERT((A) != 0); \
sigemptyset(&l_set); \
l_s.sa_handler = (B); \
l_s.sa_mask = l_set; \
l_s.sa_flags = 0; \
l_rc= sigaction((A), &l_s, (struct sigaction *) NULL);\
DBUG_ASSERT(l_rc == 0); \
sigaction((A), &l_s, NULL); \
} while (0)
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
#define my_sigset(A,B) sigset((A),(B))

View File

@ -44,7 +44,9 @@ extern "C" {
#endif
#ifndef _global_h /* If not standard header */
#ifndef MYSQL_ABI_CHECK
#include <sys/types.h>
#endif
#ifdef __LCC__
#include <winsock2.h> /* For windows */
#endif

View File

@ -1,4 +1,3 @@
#include <sys/types.h>
typedef char my_bool;
typedef int my_socket;
#include "mysql_version.h"

View File

@ -1,7 +1,5 @@
#include <mysql/services.h>
#include <mysql/service_my_snprintf.h>
#include <stdarg.h>
#include <stdlib.h>
extern struct my_snprintf_service_st {
size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);
@ -9,7 +7,6 @@ extern struct my_snprintf_service_st {
size_t my_snprintf(char* to, size_t n, const char* fmt, ...);
size_t my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap);
#include <mysql/service_thd_alloc.h>
#include <stdlib.h>
struct st_mysql_lex_string
{
char *str;

View File

@ -70,8 +70,11 @@
extern "C" {
#endif
#ifndef MYSQL_ABI_CHECK
#include <stdarg.h>
#include <stdlib.h>
#endif
extern struct my_snprintf_service_st {
size_t (*my_snprintf_type)(char*, size_t, const char*, ...);
size_t (*my_vsnprintf_type)(char *, size_t, const char*, va_list);

View File

@ -27,7 +27,9 @@
allocations - they are better served with my_malloc.
*/
#ifndef MYSQL_ABI_CHECK
#include <stdlib.h>
#endif
#ifdef __cplusplus
extern "C" {

View File

@ -63,7 +63,9 @@ extern const char *globerrs[]; /* my_error_messages is here */
#define EE_UNKNOWN_COLLATION 28
#define EE_FILENOTFOUND 29
#define EE_FILE_NOT_CLOSED 30
#define EE_ERROR_LAST 30 /* Copy last error nr */
#define EE_CHANGE_OWNERSHIP 31
#define EE_CHANGE_PERMISSIONS 32
#define EE_ERROR_LAST 32 /* Copy last error nr */
/* Add error numbers before EE_ERROR_LAST and change it accordingly. */
/* exit codes for all MySQL programs */

View File

@ -89,23 +89,11 @@ typedef struct st_thr_lock_info
{
pthread_t thread;
my_thread_id thread_id;
ulong n_cursors;
} THR_LOCK_INFO;
/*
Lock owner identifier. Globally identifies the lock owner within the
thread and among all the threads. The address of an instance of this
structure is used as id.
*/
typedef struct st_thr_lock_owner
{
THR_LOCK_INFO *info;
} THR_LOCK_OWNER;
typedef struct st_thr_lock_data {
THR_LOCK_OWNER *owner;
THR_LOCK_INFO *owner;
struct st_thr_lock_data *next,**prev;
struct st_thr_lock *lock;
mysql_cond_t *cond;
@ -141,19 +129,18 @@ extern LIST *thr_lock_thread_list;
extern mysql_mutex_t THR_LOCK_lock;
my_bool init_thr_lock(void); /* Must be called once/thread */
#define thr_lock_owner_init(owner, info_arg) (owner)->info= (info_arg)
void thr_lock_info_init(THR_LOCK_INFO *info);
void thr_lock_init(THR_LOCK *lock);
void thr_lock_delete(THR_LOCK *lock);
void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data,
void *status_param);
enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data,
THR_LOCK_OWNER *owner,
THR_LOCK_INFO *owner,
enum thr_lock_type lock_type,
ulong lock_wait_timeout);
void thr_unlock(THR_LOCK_DATA *data);
enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data,
uint count, THR_LOCK_OWNER *owner,
uint count, THR_LOCK_INFO *owner,
ulong lock_wait_timeout);
void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
void

View File

@ -1757,3 +1757,35 @@ disconnect con51355;
--echo # Connection default
connection default;
--echo #
--echo # Bug#54401 assert in Diagnostics_area::set_eof_status , HANDLER
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
--enable_warnings
delimiter |;
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
SELECT 1 FROM t2 INTO @a;
RETURN 1;
END|
delimiter ;|
# Get f1() parsed and cached
--error ER_NO_SUCH_TABLE
SELECT f1();
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1);
HANDLER t1 OPEN;
# This used to cause the assert
--error ER_NO_SUCH_TABLE
HANDLER t1 READ FIRST WHERE f1() = 1;
HANDLER t1 CLOSE;
DROP FUNCTION f1;
DROP TABLE t1;

View File

@ -3113,7 +3113,6 @@ sub install_db ($$) {
mtr_add_arg($args, "--bootstrap");
mtr_add_arg($args, "--basedir=%s", $path_my_basedir);
mtr_add_arg($args, "--datadir=%s", $data_dir);
mtr_add_arg($args, "--loose-skip-innodb");
mtr_add_arg($args, "--loose-skip-ndbcluster");
mtr_add_arg($args, "--tmpdir=.");
mtr_add_arg($args, "--core-file");

View File

@ -1370,3 +1370,16 @@ CREATE TABLE t1 (id int);
INSERT INTO t1 VALUES (1), (2);
ALTER TABLE t1 ADD COLUMN (f1 INT), ADD COLUMN (f2 INT), ADD KEY f2k(f2);
DROP TABLE t1;
#
# Test for bug #53820 "ALTER a MEDIUMINT column table causes full
# table copy".
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b MEDIUMINT);
INSERT INTO t1 VALUES (1, 1), (2, 2);
# The below ALTER should not copy table and so no rows should
# be shown as affected.
ALTER TABLE t1 CHANGE a id INT;
affected rows: 0
info: Records: 0 Duplicates: 0 Warnings: 0
DROP TABLE t1;

View File

@ -12775,3 +12775,29 @@ a
1
2
DROP TABLE t1;
#
# Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a int) ENGINE=ARCHIVE;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES (1);
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
FLUSH TABLES;
INSERT INTO t1 VALUES (2);
SELECT * FROM t1 ORDER BY a;
a
1
2
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
DROP TABLE t1;

View File

@ -1710,3 +1710,23 @@ ERROR 42S02: Table 'test.t1' doesn't exist
HANDLER t1 CLOSE;
# Connection con51355
# Connection default
#
# Bug#54401 assert in Diagnostics_area::set_eof_status , HANDLER
#
DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
SELECT 1 FROM t2 INTO @a;
RETURN 1;
END|
SELECT f1();
ERROR 42S02: Table 'test.t2' doesn't exist
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1);
HANDLER t1 OPEN;
HANDLER t1 READ FIRST WHERE f1() = 1;
ERROR 42S02: Table 'test.t2' doesn't exist
HANDLER t1 CLOSE;
DROP FUNCTION f1;
DROP TABLE t1;

View File

@ -1707,6 +1707,26 @@ HANDLER t1 CLOSE;
# Connection con51355
# Connection default
#
# Bug#54401 assert in Diagnostics_area::set_eof_status , HANDLER
#
DROP TABLE IF EXISTS t1, t2;
DROP FUNCTION IF EXISTS f1;
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
SELECT 1 FROM t2 INTO @a;
RETURN 1;
END|
SELECT f1();
ERROR 42S02: Table 'test.t2' doesn't exist
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1);
HANDLER t1 OPEN;
HANDLER t1 READ FIRST WHERE f1() = 1;
ERROR 42S02: Table 'test.t2' doesn't exist
HANDLER t1 CLOSE;
DROP FUNCTION f1;
DROP TABLE t1;
#
# BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash
#
CREATE TABLE t1 AS SELECT 1 AS f1;

View File

@ -382,3 +382,14 @@ INSERT INTO t1 VALUES('A ', 'A ');
ERROR 23000: Duplicate entry 'A -A ' for key 'key1'
DROP TABLE t1;
End of 5.0 tests
#
# Bug #55472: Assertion failed in heap_rfirst function of hp_rfirst.c
# on DELETE statement
#
CREATE TABLE t1 (col_int_nokey INT,
col_int_key INT,
INDEX(col_int_key) USING HASH) ENGINE = HEAP;
INSERT INTO t1 (col_int_nokey, col_int_key) VALUES (3, 0), (4, 0), (3, 1);
DELETE FROM t1 WHERE col_int_nokey = 5 ORDER BY col_int_key LIMIT 2;
DROP TABLE t1;
End of 5.5 tests

View File

@ -116,3 +116,35 @@ Table Op Msg_type Msg_text
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
test.t1 optimize status OK
DROP TABLE t1;
#
# Bug#49891 View DDL breaks REPEATABLE READ
#
DROP TABLE IF EXISTS t1, t2;
DROP VIEW IF EXISTS v2;
CREATE TABLE t1 ( f1 INTEGER ) ENGINE = innodb;
CREATE TABLE t2 ( f1 INTEGER );
CREATE VIEW v1 AS SELECT 1 FROM t1;
# Connection con3
LOCK TABLE t1 WRITE;
# Connection default
START TRANSACTION;
# Sending:
SELECT * FROM v1;
# Connection con2
# Waiting for 'SELECT * FROM v1' to sync in.
# Sending:
ALTER VIEW v1 AS SELECT 2 FROM t2;
# Connection con3
# Waiting for 'ALTER VIEW v1 AS SELECT 2 FROM t2' to sync in.
UNLOCK TABLES;
# Connection default;
# Reaping: SELECT * FROM v1
1
SELECT * FROM v1;
1
COMMIT;
# Connection con2
# Reaping: ALTER VIEW v1 AS SELECT 2 FROM t2
# Connection default
DROP TABLE t1, t2;
DROP VIEW v1;

View File

@ -48,3 +48,21 @@ Warnings:
Error 1146 Table 'test.t1' doesn't exist
# Connection default
SET DEBUG_SYNC= "RESET";
#
# Bug#53757 assert in mysql_truncate_by_delete
#
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1(a INT) Engine=InnoDB;
CREATE TABLE t2(id INT);
INSERT INTO t1 VALUES (1), (2);
INSERT INTO t2 VALUES(connection_id());
SET DEBUG_SYNC= "open_and_process_table SIGNAL opening WAIT_FOR killed";
# Sending: (not reaped since connection is killed later)
TRUNCATE t1;
SET DEBUG_SYNC= "now WAIT_FOR opening";
SELECT ((@id := id) - id) FROM t2;
((@id := id) - id)
0
KILL @id;
SET DEBUG_SYNC= "now SIGNAL killed";
DROP TABLE t1, t2;

View File

@ -56,6 +56,7 @@ CREATE DATABASE `TEST_$1`;
SHOW DATABASES LIKE "TEST%";
Database (TEST%)
TEST_$1
test
DROP DATABASE `test_$1`;
CREATE TABLE T1 (a int) engine=innodb;
INSERT INTO T1 VALUES (1);
@ -171,7 +172,7 @@ create table myUC (i int);
select TABLE_SCHEMA,TABLE_NAME FROM information_schema.TABLES
where TABLE_SCHEMA ='mysqltest_LC2';
TABLE_SCHEMA TABLE_NAME
mysqltest_LC2 myUC
mysqltest_lc2 myUC
use test;
drop database mysqltest_LC2;
# End of 5.1 tests

View File

@ -2527,3 +2527,240 @@ SET DEBUG_SYNC= "now SIGNAL completed";
Field Type Collation Null Key Default Extra Privileges Comment
a char(255) latin1_swedish_ci YES NULL #
DROP TABLE t1;
#
# Tests for schema-scope locks
#
DROP DATABASE IF EXISTS db1;
DROP DATABASE IF EXISTS db2;
# Test 1:
# CREATE DATABASE blocks database DDL on the same database, but
# not database DDL on different databases. Tests X vs X lock.
#
# Connection default
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
CREATE DATABASE db1;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
CREATE DATABASE db1;
# Connection con3
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: CREATE DATABASE db1
# Connection con2
# Reaping: CREATE DATABASE db1
ERROR HY000: Can't create database 'db1'; database exists
# Test 2:
# ALTER DATABASE blocks database DDL on the same database, but
# not database DDL on different databases. Tests X vs X lock.
#
# Connection default
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
# Connection con3
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
# Connection con2
# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
# Connection default
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
DROP DATABASE db1;
# Connection con3
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
# Connection con2
# Reaping: DROP DATABASE db1
CREATE DATABASE db1;
# Test 3:
# Two ALTER..UPGRADE of the same database are mutually exclusive, but
# two ALTER..UPGRADE of different databases are not. Tests X vs X lock.
#
# Connection default
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
# Connection con3
ALTER DATABASE `#mysql50#a-b-c-d` UPGRADE DATA DIRECTORY NAME;
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
# Connection con2
# Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
ERROR 42000: Unknown database '#mysql50#a-b-c'
DROP DATABASE `a-b-c`;
DROP DATABASE `a-b-c-d`;
# Test 4:
# DROP DATABASE blocks database DDL on the same database, but
# not database DDL on different databases. Tests X vs X lock.
#
# Connection default
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
DROP DATABASE db1;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
DROP DATABASE db1;
# Connection con3
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: DROP DATABASE db1
# Connection con2
# Reaping: DROP DATABASE db1
ERROR HY000: Can't drop database 'db1'; database doesn't exist
# Connection default
CREATE DATABASE db1;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
DROP DATABASE db1;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
# Connection con3
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: DROP DATABASE db1
# Connection con2
# Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
Got one of the listed errors
# Test 5:
# Locked database name prevents CREATE of tables in that database.
# Tests X vs IX lock.
#
# Connection default
CREATE DATABASE db1;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
DROP DATABASE db1;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
CREATE TABLE db1.t1 (a INT);
# Connection con3
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: DROP DATABASE db1
# Connection con2
# Reaping: CREATE TABLE db1.t1 (a INT)
ERROR 42000: Unknown database 'db1'
# Test 6:
# Locked database name prevents RENAME of tables to/from that database.
# Tests X vs IX lock.
#
# Connection default
CREATE DATABASE db1;
CREATE TABLE db1.t1 (a INT);
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
DROP DATABASE db1;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
RENAME TABLE db1.t1 TO test.t1;
# Connection con3
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: DROP DATABASE db1
# Connection con2
# Reaping: RENAME TABLE db1.t1 TO test.t1
Got one of the listed errors
# Connection default
CREATE DATABASE db1;
CREATE TABLE test.t2 (a INT);
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
DROP DATABASE db1;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
RENAME TABLE test.t2 TO db1.t2;
# Connection con3
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: DROP DATABASE db1
# Connection con2
# Reaping: RENAME TABLE test.t2 TO db1.t2
Got one of the listed errors
DROP TABLE test.t2;
# Test 7:
# Locked database name prevents DROP of tables in that database.
# Tests X vs IX lock.
#
# Connection default
CREATE DATABASE db1;
CREATE TABLE db1.t1 (a INT);
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
# Sending:
DROP DATABASE db1;
# Connection con2
SET DEBUG_SYNC= 'now WAIT_FOR locked';
# Sending:
DROP TABLE db1.t1;
# Connection con3
SET DEBUG_SYNC= 'now SIGNAL blocked';
# Connection default
# Reaping: DROP DATABASE db1
# Connection con2
# Reaping: DROP TABLE db1.t1
ERROR 42S02: Unknown table 't1'
# Connection default
SET DEBUG_SYNC= 'RESET';
#
# End of tests for schema-scope locks
#
#
# Tests of granted global S lock (FLUSH TABLE WITH READ LOCK)
#
CREATE DATABASE db1;
CREATE TABLE db1.t1(a INT);
# Connection default
FLUSH TABLE WITH READ LOCK;
# Connection con2
CREATE TABLE db1.t2(a INT);
# Connection default
UNLOCK TABLES;
# Connection con2
# Reaping CREATE TABLE db1.t2(a INT)
# Connection default
FLUSH TABLE WITH READ LOCK;
# Connection con2
ALTER DATABASE db1 DEFAULT CHARACTER SET utf8;
# Connection default
UNLOCK TABLES;
# Connection con2
# Reaping ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
# Connection default
FLUSH TABLE WITH READ LOCK;
# Connection con2
FLUSH TABLE WITH READ LOCK;
UNLOCK TABLES;
# Connection default
UNLOCK TABLES;
DROP DATABASE db1;

View File

@ -1,3 +1,5 @@
set global storage_engine=myisam;
set session storage_engine=myisam;
drop table if exists t1,t2,t3,t4,t5,t6;
drop database if exists mysqltest;
create table t1 (a int not null primary key auto_increment, message char(20));
@ -584,7 +586,9 @@ INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
CREATE TEMPORARY TABLE t3 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t1,t2);
SELECT * FROM t3;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
c1
1
2
CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL);
CREATE TEMPORARY TABLE t5 (c1 INT NOT NULL);
INSERT INTO t4 VALUES (4);
@ -613,7 +617,9 @@ ERROR HY000: Unable to open underlying table which is differently defined or of
drop table t3;
create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
select * from t3;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
a
1
2
drop table t3, t2, t1;
# CREATE...SELECT is not implemented for MERGE tables.
CREATE TEMPORARY TABLE t1 (c1 INT NOT NULL);
@ -1196,12 +1202,13 @@ ERROR HY000: Table 't4' was not locked with LOCK TABLES
# it can even be used.
CREATE TEMPORARY TABLE t4 LIKE t3;
SHOW CREATE TABLE t4;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
Table Create Table
t4 CREATE TEMPORARY TABLE `t4` (
`c1` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
INSERT INTO t4 VALUES (4);
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
UNLOCK TABLES;
INSERT INTO t4 VALUES (4);
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
DROP TABLE t4;
#
# Rename child.
@ -1229,6 +1236,8 @@ c1
2
3
4
4
4
RENAME TABLE t2 TO t5;
SELECT * FROM t3 ORDER BY c1;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
@ -1239,6 +1248,8 @@ c1
2
3
4
4
4
#
# 3. Normal rename with locked tables.
LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
@ -1248,6 +1259,8 @@ c1
2
3
4
4
4
RENAME TABLE t2 TO t5;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@ -1256,6 +1269,8 @@ c1
2
3
4
4
4
RENAME TABLE t5 TO t2;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@ -1264,6 +1279,8 @@ c1
2
3
4
4
4
UNLOCK TABLES;
#
# 4. Alter table rename.
@ -1277,6 +1294,8 @@ c1
2
3
4
4
4
#
# 5. Alter table rename with locked tables.
LOCK TABLES t1 WRITE, t2 WRITE, t3 WRITE;
@ -1293,6 +1312,8 @@ c1
2
3
4
4
4
#
# Rename parent.
#
@ -1304,6 +1325,8 @@ c1
2
3
4
4
4
RENAME TABLE t3 TO t5;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@ -1312,6 +1335,8 @@ c1
2
3
4
4
4
RENAME TABLE t5 TO t3;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
SELECT * FROM t3 ORDER BY c1;
@ -1320,6 +1345,8 @@ c1
2
3
4
4
4
#
# 5. Alter table rename with locked tables.
ALTER TABLE t3 RENAME TO t5;
@ -1335,6 +1362,8 @@ c1
2
3
4
4
4
DROP TABLE t1, t2, t3;
#
# Drop locked tables.
@ -2650,6 +2679,705 @@ test.t1 optimize Error Unable to open underlying table which is differently defi
test.t1 optimize note The storage engine for the table doesn't support optimize
DROP TABLE t1;
#
# Bug#36171 - CREATE TEMPORARY TABLE and MERGE engine
# More tests with TEMPORARY MERGE table and permanent children.
# First without locked tables.
#
DROP TABLE IF EXISTS t1, t2, t3, t4, m1, m2;
#
CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m1;
c1 c2
INSERT INTO t1 VALUES (111, 121);
INSERT INTO m1 VALUES (211, 221);
SELECT * FROM m1;
c1 c2
111 121
211 221
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
#
ALTER TABLE m1 RENAME m2;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2;
c1 c2
111 121
211 221
#
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
ALTER TABLE m2 RENAME m1;
ERROR 42S01: Table 'm1' already exists
DROP TABLE m1;
ALTER TABLE m2 RENAME m1;
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m1;
c1 c2
111 121
211 221
#
ALTER TABLE m1 ADD COLUMN c3 INT;
INSERT INTO m1 VALUES (212, 222, 232);
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
SELECT * FROM m1;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
ALTER TABLE t1 ADD COLUMN c3 INT;
ALTER TABLE t2 ADD COLUMN c3 INT;
INSERT INTO m1 VALUES (212, 222, 232);
SELECT * FROM m1;
c1 c2 c3
111 121 NULL
211 221 NULL
212 222 232
#
ALTER TABLE m1 DROP COLUMN c3;
INSERT INTO m1 VALUES (213, 223);
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
SELECT * FROM m1;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
ALTER TABLE t1 DROP COLUMN c3;
ALTER TABLE t2 DROP COLUMN c3;
INSERT INTO m1 VALUES (213, 223);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
#
CREATE TABLE t3 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3);
INSERT INTO m1 VALUES (311, 321);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
311 321
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
212 222
213 223
SELECT * FROM t3;
c1 c2
311 321
#
CREATE TEMPORARY TABLE t4 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3,t4);
INSERT INTO m1 VALUES (411, 421);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
311 321
411 421
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
212 222
213 223
SELECT * FROM t3;
c1 c2
311 321
SELECT * FROM t4;
c1 c2
411 421
#
ALTER TABLE m1 ENGINE=MyISAM;
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO m1 VALUES (511, 521);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
311 321
411 421
511 521
#
ALTER TABLE m1 ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
212 222
213 223
#
CREATE TEMPORARY TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (611, 621);
SELECT * FROM m1;
c1 c2
611 621
211 221
212 222
213 223
DROP TABLE t1;
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
#
#
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
#
CREATE TABLE m2 SELECT * FROM m1;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
DROP TABLE m2;
#
CREATE TEMPORARY TABLE m2 SELECT * FROM m1;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
DROP TABLE m2;
#
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
SELECT * FROM m2;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
DROP TABLE m2;
#
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
ERROR HY000: 'test.m2' is not BASE TABLE
#
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
ERROR HY000: 'test.m2' is not BASE TABLE
#
CREATE TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
DROP TABLE m2;
#
CREATE TEMPORARY TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
DROP TABLE m2;
#
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1 c2
311 321
411 421
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
#
#
LOCK TABLE m1 WRITE, m2 WRITE;
SELECT * FROM m1,m2 WHERE m1.c1=m2.c1;
c1 c2 c1 c2
111 121 111 121
111 121 111 121
111 121 111 121
111 121 111 121
211 221 211 221
211 221 211 221
211 221 211 221
211 221 211 221
212 222 212 222
212 222 212 222
212 222 212 222
212 222 212 222
213 223 213 223
213 223 213 223
213 223 213 223
213 223 213 223
111 121 111 121
111 121 111 121
111 121 111 121
111 121 111 121
211 221 211 221
211 221 211 221
211 221 211 221
211 221 211 221
212 222 212 222
212 222 212 222
212 222 212 222
212 222 212 222
213 223 213 223
213 223 213 223
213 223 213 223
213 223 213 223
111 121 111 121
111 121 111 121
111 121 111 121
111 121 111 121
211 221 211 221
211 221 211 221
211 221 211 221
211 221 211 221
212 222 212 222
212 222 212 222
212 222 212 222
212 222 212 222
213 223 213 223
213 223 213 223
213 223 213 223
213 223 213 223
111 121 111 121
111 121 111 121
111 121 111 121
111 121 111 121
211 221 211 221
211 221 211 221
211 221 211 221
211 221 211 221
212 222 212 222
212 222 212 222
212 222 212 222
212 222 212 222
213 223 213 223
213 223 213 223
213 223 213 223
213 223 213 223
UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4, m1, m2;
#
# Bug#36171 - CREATE TEMPORARY TABLE and MERGE engine
# More tests with TEMPORARY MERGE table and permanent children.
# (continued) Now the same with locked table.
#
CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m1;
c1 c2
INSERT INTO t1 VALUES (111, 121);
INSERT INTO m1 VALUES (211, 221);
SELECT * FROM m1;
c1 c2
111 121
211 221
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
#
LOCK TABLE m1 WRITE, t1 WRITE, t2 WRITE;
#
ALTER TABLE m1 RENAME m2;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2;
c1 c2
111 121
211 221
#
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
ALTER TABLE m2 RENAME m1;
ERROR 42S01: Table 'm1' already exists
DROP TABLE m1;
ALTER TABLE m2 RENAME m1;
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m1;
c1 c2
111 121
211 221
#
ALTER TABLE m1 ADD COLUMN c3 INT;
INSERT INTO m1 VALUES (212, 222, 232);
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
SELECT * FROM m1;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
ALTER TABLE t1 ADD COLUMN c3 INT;
ALTER TABLE t2 ADD COLUMN c3 INT;
INSERT INTO m1 VALUES (212, 222, 232);
SELECT * FROM m1;
c1 c2 c3
111 121 NULL
211 221 NULL
212 222 232
#
ALTER TABLE m1 DROP COLUMN c3;
INSERT INTO m1 VALUES (213, 223);
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
SELECT * FROM m1;
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
ALTER TABLE t1 DROP COLUMN c3;
ALTER TABLE t2 DROP COLUMN c3;
INSERT INTO m1 VALUES (213, 223);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
#
UNLOCK TABLES;
CREATE TABLE t3 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3);
LOCK TABLE m1 WRITE;
INSERT INTO m1 VALUES (311, 321);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
311 321
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
212 222
213 223
SELECT * FROM t3;
c1 c2
311 321
#
CREATE TEMPORARY TABLE t4 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3,t4);
INSERT INTO m1 VALUES (411, 421);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
311 321
411 421
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
212 222
213 223
SELECT * FROM t3;
c1 c2
311 321
SELECT * FROM t4;
c1 c2
411 421
#
ALTER TABLE m1 ENGINE=MyISAM;
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO m1 VALUES (511, 521);
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
311 321
411 421
511 521
#
ALTER TABLE m1 ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
SELECT * FROM t1;
c1 c2
111 121
SELECT * FROM t2;
c1 c2
211 221
212 222
213 223
#
CREATE TEMPORARY TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (611, 621);
SELECT * FROM m1;
c1 c2
611 621
211 221
212 222
213 223
DROP TABLE t1;
SELECT * FROM m1;
c1 c2
111 121
211 221
212 222
213 223
#
#
SHOW CREATE TABLE m1;
Table Create Table
m1 CREATE TEMPORARY TABLE `m1` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
CREATE TABLE m2 SELECT * FROM m1;
ERROR HY000: Table 'm2' was not locked with LOCK TABLES
#
CREATE TEMPORARY TABLE m2 SELECT * FROM m1;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
DROP TABLE m2;
#
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
SELECT * FROM m2;
c1 c2
311 321
411 421
LOCK TABLE m1 WRITE, m2 WRITE;
UNLOCK TABLES;
DROP TABLE m2;
LOCK TABLE m1 WRITE;
#
# ER_TABLE_NOT_LOCKED is returned in ps-protocol
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
Got one of the listed errors
#
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
ERROR HY000: 'test.m2' is not BASE TABLE
#
CREATE TEMPORARY TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
LOCK TABLE m1 WRITE, m2 WRITE;
SHOW CREATE TABLE m2;
Table Create Table
m2 CREATE TEMPORARY TABLE `m2` (
`c1` int(11) DEFAULT NULL,
`c2` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1 c2
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
DROP TABLE m2;
#
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1 c2
311 321
411 421
111 121
211 221
212 222
213 223
111 121
211 221
212 222
213 223
#
UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4, m1, m2;
#
# Bug47098 assert in MDL_context::destroy on HANDLER
# <damaged merge table> OPEN
#
@ -2745,4 +3473,106 @@ m2 CREATE TABLE `m2` (
`i` int(11) DEFAULT NULL
) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`)
drop tables m1, m2, t1;
#
# Test case for Bug#54811 "Assert in mysql_lock_have_duplicate()"
# Check that unique_table() works correctly for merge tables.
#
drop table if exists t1, t2, t3, m1, m2;
create table t1 (a int);
create table t2 (a int);
create table t3 (b int);
create view v1 as select * from t3,t1;
create table m1 (a int) engine=merge union (t1, t2) insert_method=last;
create table m2 (a int) engine=merge union (t1, t2) insert_method=first;
create temporary table tmp (b int);
insert into tmp (b) values (1);
insert into t1 (a) values (1);
insert into t3 (b) values (1);
insert into m1 (a) values ((select max(a) from m1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from m2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from t1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from t2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from t3, m1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from t3, m2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from t3, t1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from t3, t2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from tmp, m1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from tmp, m2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from tmp, t1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from tmp, t2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
insert into m1 (a) values ((select max(a) from v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'.
insert into m1 (a) values ((select max(a) from tmp, v1));
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'.
update m1 set a = ((select max(a) from m1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from m2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from t1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from t2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from t3, m1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from t3, m2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from t3, t1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from t3, t2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from tmp, m1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from tmp, m2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from tmp, t1));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from tmp, t2));
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
update m1 set a = ((select max(a) from v1));
ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'm1'.
update m1 set a = ((select max(a) from tmp, v1));
ERROR HY000: The definition of table 'v1' prevents operation UPDATE on table 'm1'.
delete from m1 where a = (select max(a) from m1);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from m2);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from t1);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from t2);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from t3, m1);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from t3, m2);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from t3, t1);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from t3, t2);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from tmp, m1);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from tmp, m2);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from tmp, t1);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from tmp, t2);
ERROR HY000: You can't specify target table 'm1' for update in FROM clause
delete from m1 where a = (select max(a) from v1);
ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 'm1'.
delete from m1 where a = (select max(a) from tmp, v1);
ERROR HY000: The definition of table 'v1' prevents operation DELETE on table 'm1'.
drop view v1;
drop temporary table tmp;
drop table t1, t2, t3, m1, m2;
End of 6.0 tests

View File

@ -0,0 +1,190 @@
SET GLOBAL storage_engine = MyISAM;
SET SESSION storage_engine = MyISAM;
DROP TABLE IF EXISTS t1, t2, m1, m2;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
SELECT * FROM t2;
c1
2
3
4
1
2
3
4
DROP TABLE m2, m1, t2, t1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
DROP TABLE m2, m1, t2, t1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
DROP TABLE m2, m1, t2, t1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
DROP TABLE m2, m1, t2, t1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
SELECT * FROM t2;
c1
2
3
4
1
2
3
4
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
c1
1
2
3
4
1
2
3
4
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
End of 6.0 tests

View File

@ -47,7 +47,7 @@ ENGINE = MYISAM
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */;
SET DEBUG_SYNC= 'open_tables_acquire_upgradable_mdl SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_open_tables SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done';
ALTER TABLE t2 REMOVE PARTITIONING;
# Con default

View File

@ -16,19 +16,21 @@ drop schema foo;
# Bug #48940 MDL deadlocks against mysql_rm_db
#
DROP SCHEMA IF EXISTS schema1;
DROP SCHEMA IF EXISTS schema2;
# Connection default
CREATE SCHEMA schema1;
CREATE SCHEMA schema2;
CREATE TABLE schema1.t1 (a INT);
SET autocommit= FALSE;
INSERT INTO schema1.t1 VALUES (1);
# Connection 2
DROP SCHEMA schema1;
# Connection default
ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
Got one of the listed errors
ALTER SCHEMA schema2 DEFAULT CHARACTER SET utf8;
SET autocommit= TRUE;
# Connection 2
# Connection default
DROP SCHEMA schema2;
#
# Bug #49988 MDL deadlocks with mysql_create_db, reload_acl_and_cache
#
@ -48,3 +50,48 @@ ERROR HY000: Can't execute the given command because you have active locked tabl
UNLOCK TABLES;
# Connection con2
# Connection default
#
# Bug#54360 Deadlock DROP/ALTER/CREATE DATABASE with open HANDLER
#
CREATE DATABASE db1;
CREATE TABLE db1.t1 (a INT);
INSERT INTO db1.t1 VALUES (1), (2);
# Connection con1
HANDLER db1.t1 OPEN;
# Connection default
# Sending:
DROP DATABASE db1;
# Connection con2
# Connection con1
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
HANDLER t1 CLOSE;
# Connection default
# Reaping: DROP DATABASE db1
#
# Tests for increased CREATE/ALTER/DROP DATABASE concurrency with
# database name locks.
#
DROP DATABASE IF EXISTS db1;
DROP DATABASE IF EXISTS db2;
# Connection default
CREATE DATABASE db1;
CREATE TABLE db1.t1 (id INT);
START TRANSACTION;
INSERT INTO db1.t1 VALUES (1);
# Connection 2
# DROP DATABASE should block due to the active transaction
# Sending:
DROP DATABASE db1;
# Connection 3
# But it should still be possible to CREATE/ALTER/DROP other databases.
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
# Connection default
# End the transaction so DROP DATABASE db1 can continue
COMMIT;
# Connection 2
# Reaping: DROP DATABASE db1
# Connection default;

View File

@ -1466,3 +1466,51 @@ t1 CREATE TABLE `t1` (
# Switching to connection 'default'.
UNLOCK TABLES;
DROP TABLE t1;
#
# Bug#54905 Connection with WRITE lock cannot ALTER table due to
# concurrent SHOW CREATE
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INT);
# Connection con1
LOCK TABLE t1 WRITE;
# Connection default
START TRANSACTION;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
# Connection con1
ALTER TABLE t1 CHARACTER SET = utf8;
UNLOCK TABLES;
# Connection default
COMMIT;
DROP TABLE t1;
#
# Bug#55498 SHOW CREATE TRIGGER takes wrong type of metadata lock.
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT);
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1;
# Test 1: SHOW CREATE TRIGGER with WRITE locked table.
# Connection con1
LOCK TABLE t1 WRITE;
# Connection default
SHOW CREATE TRIGGER t1_bi;
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
t1_bi CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1 utf8 utf8_general_ci latin1_swedish_ci
# Connection con1
UNLOCK TABLES;
# Test 2: ALTER TABLE with SHOW CREATE TRIGGER in transaction
# Connection default
START TRANSACTION;
SHOW CREATE TRIGGER t1_bi;
Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation
t1_bi CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1 utf8 utf8_general_ci latin1_swedish_ci
# Connection con1
ALTER TABLE t1 CHARACTER SET = utf8;
# Connection default
COMMIT;
DROP TRIGGER t1_bi;
DROP TABLE t1;

View File

@ -210,4 +210,16 @@ UPDATE t1,t2 SET t1.a = t2.a;
INSERT INTO t2 SELECT f1();
DROP TABLE t1,t2,t3;
DROP FUNCTION f1;
#
# Bug #48067: A temp table with the same name as an existing table,
# makes drop database fail.
#
DROP TEMPORARY TABLE IF EXISTS bug48067.t1;
DROP DATABASE IF EXISTS bug48067;
CREATE DATABASE bug48067;
CREATE TABLE bug48067.t1 (c1 int);
INSERT INTO bug48067.t1 values (1);
CREATE TEMPORARY TABLE bug48067.t1 (c1 int);
DROP DATABASE bug48067;
DROP TEMPORARY table bug48067.t1;
End of 5.1 tests

View File

@ -1677,3 +1677,25 @@ SET @@sql_quote_show_create = @sql_quote_show_create_saved;
# End of Bug#34828.
# Make sure we can manipulate with autocommit in the
# along with other variables.
drop table if exists t1;
drop function if exists t1_max;
drop function if exists t1_min;
create table t1 (a int) engine=innodb;
insert into t1(a) values (0), (1);
create function t1_max() returns int return (select max(a) from t1);
create function t1_min() returns int return (select min(a) from t1);
select t1_min();
t1_min()
0
select t1_max();
t1_max()
1
set @@session.autocommit=t1_min(), @@session.autocommit=t1_max(),
@@session.autocommit=t1_min(), @@session.autocommit=t1_max(),
@@session.autocommit=t1_min(), @@session.autocommit=t1_max();
# Cleanup.
drop table t1;
drop function t1_min;
drop function t1_max;

View File

@ -1955,15 +1955,15 @@ CHECK TABLE v1, v2, v3, v4, v5, v6;
Table Op Msg_type Msg_text
test.v1 check Error FUNCTION test.f1 does not exist
test.v1 check Error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
test.v1 check status Operation failed
test.v1 check error Corrupt
test.v2 check status OK
test.v3 check Error FUNCTION test.f1 does not exist
test.v3 check Error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
test.v3 check status Operation failed
test.v3 check error Corrupt
test.v4 check status OK
test.v5 check Error FUNCTION test.f1 does not exist
test.v5 check Error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
test.v5 check status Operation failed
test.v5 check error Corrupt
test.v6 check status OK
create function f1 () returns int return (select max(col1) from t1);
DROP TABLE t1;

View File

@ -0,0 +1,5 @@
CREATE TABLE bug52199 (a INT NOT NULL,
b CHAR(125) CHARACTER SET utf32 COLLATE utf32_bin NOT NULL
)ENGINE=InnoDB;
CREATE UNIQUE INDEX idx ON bug52199(a);
DROP TABLE bug52199;

View File

@ -0,0 +1,88 @@
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
SET innodb_strict_mode=ON;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
TABLE_NAME ROW_FORMAT CREATE_OPTIONS
bug54679 Compressed row_format=COMPRESSED
ALTER TABLE bug54679 ADD COLUMN b INT;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
TABLE_NAME ROW_FORMAT CREATE_OPTIONS
bug54679 Compressed row_format=COMPRESSED
DROP TABLE bug54679;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
TABLE_NAME ROW_FORMAT CREATE_OPTIONS
bug54679 Compact
ALTER TABLE bug54679 KEY_BLOCK_SIZE=1;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
TABLE_NAME ROW_FORMAT CREATE_OPTIONS
bug54679 Compressed KEY_BLOCK_SIZE=1
ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT;
ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE.
Error 1005 Can't create table '#sql-temporary' (errno: 1478)
DROP TABLE bug54679;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
TABLE_NAME ROW_FORMAT CREATE_OPTIONS
bug54679 Redundant row_format=REDUNDANT
ALTER TABLE bug54679 KEY_BLOCK_SIZE=2;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
TABLE_NAME ROW_FORMAT CREATE_OPTIONS
bug54679 Compressed row_format=REDUNDANT KEY_BLOCK_SIZE=2
SET GLOBAL innodb_file_format=Antelope;
ALTER TABLE bug54679 KEY_BLOCK_SIZE=4;
ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Error 1005 Can't create table '#sql-temporary' (errno: 1478)
ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.
Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
Warning 1478 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.
Error 1005 Can't create table '#sql-temporary' (errno: 1478)
DROP TABLE bug54679;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ERROR HY000: Can't create table 'test.bug54679' (errno: 1478)
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope.
Error 1005 Can't create table 'test.bug54679' (errno: 1478)
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=OFF;
ALTER TABLE bug54679 KEY_BLOCK_SIZE=4;
ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.
Error 1005 Can't create table '#sql-temporary' (errno: 1478)
ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
ERROR HY000: Can't create table '#sql-temporary' (errno: 1478)
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
Error 1005 Can't create table '#sql-temporary' (errno: 1478)
DROP TABLE bug54679;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ERROR HY000: Can't create table 'test.bug54679' (errno: 1478)
SHOW WARNINGS;
Level Code Message
Warning 1478 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table.
Error 1005 Can't create table 'test.bug54679' (errno: 1478)
SET GLOBAL innodb_file_per_table=ON;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
DROP TABLE bug54679;

View File

@ -42,21 +42,7 @@ trx_isolation_level varchar(16) NO
trx_unique_checks int(1) NO 0
trx_foreign_key_checks int(1) NO 0
trx_last_foreign_key_error varchar(256) YES NULL
trx_apative_hash_latched int(1) NO 0
trx_adaptive_hash_timeout bigint(21) unsigned NO 0
trx_operation_state varchar(64) YES NULL
trx_tables_in_use bigint(21) unsigned NO 0
trx_tables_locked bigint(21) unsigned NO 0
trx_lock_structs bigint(21) unsigned NO 0
trx_lock_memory_bytes bigint(21) unsigned NO 0
trx_rows_locked bigint(21) unsigned NO 0
trx_rows_modified bigint(21) unsigned NO 0
trx_concurrency_tickets bigint(21) unsigned NO 0
trx_isolation_level varchar(16) NO
trx_unique_checks int(1) NO 0
trx_foreign_key_checks int(1) NO 0
trx_last_foreign_key_error varchar(256) YES NULL
trx_apative_hash_latched int(1) NO 0
trx_adaptive_hash_latched int(1) NO 0
trx_adaptive_hash_timeout bigint(21) unsigned NO 0
trx_state trx_weight trx_tables_in_use trx_tables_locked trx_rows_locked trx_rows_modified trx_concurrency_tickets trx_isolation_level trx_unique_checks trx_foreign_key_checks
RUNNING 4 0 0 7 1 0 REPEATABLE READ 1 1

View File

@ -0,0 +1,7 @@
-- source include/have_innodb.inc
CREATE TABLE bug52199 (a INT NOT NULL,
b CHAR(125) CHARACTER SET utf32 COLLATE utf32_bin NOT NULL
)ENGINE=InnoDB;
CREATE UNIQUE INDEX idx ON bug52199(a);
DROP TABLE bug52199;

View File

@ -0,0 +1,101 @@
# Test Bug #54679 alter table causes compressed row_format to revert to compact
--source include/have_innodb.inc
let $file_format=`select @@innodb_file_format`;
let $file_format_max=`select @@innodb_file_format_max`;
let $file_per_table=`select @@innodb_file_per_table`;
SET GLOBAL innodb_file_format='Barracuda';
SET GLOBAL innodb_file_per_table=ON;
SET innodb_strict_mode=ON;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
# The ROW_FORMAT of the table should be preserved when it is not specified
# in ALTER TABLE.
ALTER TABLE bug54679 ADD COLUMN b INT;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
DROP TABLE bug54679;
# Check that the ROW_FORMAT conversion to/from COMPRESSED works.
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
# KEY_BLOCK_SIZE implies COMPRESSED.
ALTER TABLE bug54679 KEY_BLOCK_SIZE=1;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
ALTER TABLE bug54679 ROW_FORMAT=REDUNDANT;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
SHOW WARNINGS;
DROP TABLE bug54679;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
ALTER TABLE bug54679 KEY_BLOCK_SIZE=2;
SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables
WHERE TABLE_NAME='bug54679';
# This prevents other than REDUNDANT or COMPACT ROW_FORMAT for new tables.
SET GLOBAL innodb_file_format=Antelope;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
ALTER TABLE bug54679 KEY_BLOCK_SIZE=4;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
SHOW WARNINGS;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
SHOW WARNINGS;
DROP TABLE bug54679;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
SHOW WARNINGS;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB;
SET GLOBAL innodb_file_format=Barracuda;
# This will prevent ROW_FORMAT=COMPRESSED, because the system tablespace
# cannot be compressed.
SET GLOBAL innodb_file_per_table=OFF;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
ALTER TABLE bug54679 KEY_BLOCK_SIZE=4;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
SHOW WARNINGS;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
ALTER TABLE bug54679 ROW_FORMAT=DYNAMIC;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
SHOW WARNINGS;
DROP TABLE bug54679;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_CANT_CREATE_TABLE
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
SHOW WARNINGS;
SET GLOBAL innodb_file_per_table=ON;
CREATE TABLE bug54679 (a INT) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
DROP TABLE bug54679;
# restore original values, quietly so the test does not fail if those
# defaults are changed
-- disable_query_log
EVAL SET GLOBAL innodb_file_format=$file_format;
EVAL SET GLOBAL innodb_file_format_max=$file_format_max;
EVAL SET GLOBAL innodb_file_per_table=$file_per_table;
-- enable_query_log

View File

@ -40,18 +40,10 @@ where name like "wait/synch/cond/mysys/THR_COND_threads";
count(name)
1
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_mysql_create_db";
count(name)
1
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_open";
count(name)
1
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_lock_db";
count(name)
1
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_thread_count";
count(name)
1

View File

@ -68,15 +68,9 @@ select count(name) from COND_INSTANCES
# Verify that these global mutexes have been properly initilized in sql
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_mysql_create_db";
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_open";
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_lock_db";
select count(name) from MUTEX_INSTANCES
where name like "wait/synch/mutex/sql/LOCK_thread_count";

View File

@ -0,0 +1,67 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE TABLE t1(c1 INT);
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
# Case 1:
# ------------------------------------------------------------------
# In a statement, some CCs are applied while others are not. The CCs
# which are not applied on master will be binlogged as common comments.
/*!99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /*!99999 ,(11)*/;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; /* 99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /* 99999 ,(11)*/
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
# Case 2:
# -----------------------------------------------------------------
# Verify whether it can be binlogged correctly when executing prepared
# statement.
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla*/ t1 VALUES(60) /*!99999 ,(61)*/';
EXECUTE stmt;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt;
Comparing tables master:test.t1 and slave:test.t1
SET @value=62;
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla */ t1 VALUES(?) /*!99999 ,(63)*/';
EXECUTE stmt USING @value;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt USING @value;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla*/ t1 VALUES(60) /* 99999 ,(61)*/
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1(c1 INT)
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO /* 99999 blabla */ t1 VALUES(62) /* 99999 ,(63)*/
master-bin.000001 # Query # # COMMIT
Comparing tables master:test.t1 and slave:test.t1
# Case 3:
# -----------------------------------------------------------------
# Verify it can restore the '!', if the it is an uncomplete conditional
# comments
SELECT c1 FROM /*!99999 t1 WHEREN;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '/*!99999 t1 WHEREN' at line 1
DROP TABLE t1;

View File

@ -49,6 +49,14 @@ Slave_IO_Running = No (expect No)
SELECT "Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master'" AS Last_IO_Error;
Last_IO_Error
Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master'
STOP SLAVE;
RESET SLAVE;
RESET MASTER;
SET @max_allowed_packet_0= @@session.max_allowed_packet;
SHOW BINLOG EVENTS;
SET @max_allowed_packet_1= @@session.max_allowed_packet;
SHOW BINLOG EVENTS;
SET @max_allowed_packet_2= @@session.max_allowed_packet;
==== clean up ====
DROP TABLE t1;
SET @@global.max_allowed_packet= 1024;

View File

@ -165,10 +165,6 @@ master-bin.000001 # Table_map # # table_id: # (test.tt_1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; SET PASSWORD FOR 'user'@'localhost'='*D8DECEC305209EEFEC43008E1D420E1AA06B19E0'
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (mysql.user)
master-bin.000001 # Update_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
-e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e-
-b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b-

View File

@ -0,0 +1,74 @@
###############################################################################
# After the patch for BUG#49124:
# - Use ' ' instead of '!' in the conditional comments which are not applied on
# master. So they become common comments and will not be applied on slave.
#
# - Example:
# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /*!99999 ,(3)*/
# will be binlogged as
# 'INSERT INTO t1 VALUES (1) /*!10000, (2)*/ /* 99999 ,(3)*/'.
###############################################################################
source include/master-slave.inc;
source include/have_binlog_format_statement.inc;
CREATE TABLE t1(c1 INT);
source include/show_binlog_events.inc;
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
--echo
--echo # Case 1:
--echo # ------------------------------------------------------------------
--echo # In a statement, some CCs are applied while others are not. The CCs
--echo # which are not applied on master will be binlogged as common comments.
/*!99999 --- */INSERT /*!INTO*/ /*!10000 t1 */ VALUES(10) /*!99999 ,(11)*/;
source include/show_binlog_events.inc;
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
--echo
--echo # Case 2:
--echo # -----------------------------------------------------------------
--echo # Verify whether it can be binlogged correctly when executing prepared
--echo # statement.
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla*/ t1 VALUES(60) /*!99999 ,(61)*/';
EXECUTE stmt;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt;
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
--echo
SET @value=62;
PREPARE stmt FROM 'INSERT INTO /*!99999 blabla */ t1 VALUES(?) /*!99999 ,(63)*/';
EXECUTE stmt USING @value;
DROP TABLE t1;
CREATE TABLE t1(c1 INT);
EXECUTE stmt USING @value;
source include/show_binlog_events.inc;
let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
--echo
--echo # Case 3:
--echo # -----------------------------------------------------------------
--echo # Verify it can restore the '!', if the it is an uncomplete conditional
--echo # comments
--error 1064
SELECT c1 FROM /*!99999 t1 WHEREN;
DROP TABLE t1;
source include/master-slave-end.inc;

View File

@ -1,7 +1,12 @@
# ==== Purpose ====
#
# Check replication protocol packet size handling
# Bug#19402 SQL close to the size of the max_allowed_packet fails on slave
#
# ==== Related bugs ====
# Bug#19402 SQL close to the size of the max_allowed_packet fails on slave
# BUG#23755: Replicated event larger that max_allowed_packet infinitely re-transmits
# BUG#42914: No LAST_IO_ERROR for max_allowed_packet errors
# BUG#55322: SHOW BINLOG EVENTS increases @@SESSION.MAX_ALLOWED_PACKET
# max-out size db name
source include/master-slave.inc;
@ -114,6 +119,38 @@ let $slave_io_running= query_get_value(SHOW SLAVE STATUS, Slave_IO_Running, 1);
let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
eval SELECT "$last_io_error" AS Last_IO_Error;
# Remove the bad binlog and clear error status on slave.
STOP SLAVE;
RESET SLAVE;
--connection master
RESET MASTER;
#
# BUG#55322: SHOW BINLOG EVENTS increases @@SESSION.MAX_ALLOWED_PACKET
#
# In BUG#55322, @@session.max_allowed_packet increased each time SHOW
# BINLOG EVENTS was issued. To verify that this bug is fixed, we
# execute SHOW BINLOG EVENTS twice and check that max_allowed_packet
# never changes. We turn off the result log because we don't care
# about the contents of the binlog.
--disable_result_log
SET @max_allowed_packet_0= @@session.max_allowed_packet;
SHOW BINLOG EVENTS;
SET @max_allowed_packet_1= @@session.max_allowed_packet;
SHOW BINLOG EVENTS;
SET @max_allowed_packet_2= @@session.max_allowed_packet;
--enable_result_log
if (`SELECT NOT(@max_allowed_packet_0 = @max_allowed_packet_1 AND @max_allowed_packet_1 = @max_allowed_packet_2)`)
{
--echo ERROR: max_allowed_packet changed after executing SHOW BINLOG EVENTS
--source include/show_rpl_debug_info.inc
SELECT @max_allowed_packet_0, @max_allowed_packet_1, @max_allowed_packet_2;
--die @max_allowed_packet changed after executing SHOW BINLOG EVENTS
}
--echo ==== clean up ====
connection master;
DROP TABLE t1;

View File

@ -1 +1 @@
--sync-relay-log-info=1 --relay-log-recovery=1 --innodb_file_format_check='ON' --default-storage-engine=MyISAM --innodb-file-per-table=0
--sync-relay-log-info=1 --relay-log-recovery=1 --innodb_file_format_check=1 --default-storage-engine=MyISAM --innodb-file-per-table=0

View File

@ -1128,3 +1128,19 @@ INSERT INTO t1 VALUES (1), (2);
ALTER TABLE t1 ADD COLUMN (f1 INT), ADD COLUMN (f2 INT), ADD KEY f2k(f2);
DROP TABLE t1;
--echo #
--echo # Test for bug #53820 "ALTER a MEDIUMINT column table causes full
--echo # table copy".
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a INT, b MEDIUMINT);
INSERT INTO t1 VALUES (1, 1), (2, 2);
--echo # The below ALTER should not copy table and so no rows should
--echo # be shown as affected.
--enable_info
ALTER TABLE t1 CHANGE a id INT;
--disable_info
DROP TABLE t1;

View File

@ -1701,3 +1701,24 @@ SELECT * FROM t1;
REPAIR TABLE t1 EXTENDED;
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # Bug#45377: ARCHIVE tables aren't discoverable after OPTIMIZE
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a int) ENGINE=ARCHIVE;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES (1);
OPTIMIZE TABLE t1;
let $MYSQLD_DATADIR= `select @@datadir`;
remove_file $MYSQLD_DATADIR/test/t1.frm;
FLUSH TABLES;
INSERT INTO t1 VALUES (2);
SELECT * FROM t1 ORDER BY a;
SHOW CREATE TABLE t1;
DROP TABLE t1;

View File

@ -284,3 +284,20 @@ INSERT INTO t1 VALUES('A ', 'A ');
DROP TABLE t1;
--echo End of 5.0 tests
--echo #
--echo # Bug #55472: Assertion failed in heap_rfirst function of hp_rfirst.c
--echo # on DELETE statement
--echo #
CREATE TABLE t1 (col_int_nokey INT,
col_int_key INT,
INDEX(col_int_key) USING HASH) ENGINE = HEAP;
INSERT INTO t1 (col_int_nokey, col_int_key) VALUES (3, 0), (4, 0), (3, 1);
DELETE FROM t1 WHERE col_int_nokey = 5 ORDER BY col_int_key LIMIT 2;
DROP TABLE t1;
--echo End of 5.5 tests

View File

@ -209,6 +209,74 @@ disconnect con1;
DROP TABLE t1;
--echo #
--echo # Bug#49891 View DDL breaks REPEATABLE READ
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
DROP VIEW IF EXISTS v2;
--enable_warnings
CREATE TABLE t1 ( f1 INTEGER ) ENGINE = innodb;
CREATE TABLE t2 ( f1 INTEGER );
CREATE VIEW v1 AS SELECT 1 FROM t1;
connect (con2, localhost, root);
connect (con3, localhost, root);
--echo # Connection con3
connection con3;
LOCK TABLE t1 WRITE;
--echo # Connection default
connection default;
START TRANSACTION;
# This should block due to t1 being locked.
--echo # Sending:
--send SELECT * FROM v1
--echo # Connection con2
connection con2;
--echo # Waiting for 'SELECT * FROM v1' to sync in.
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist
WHERE state = "Waiting for table" AND info = "SELECT * FROM v1";
--source include/wait_condition.inc
# This should block due to v1 being locked.
--echo # Sending:
--send ALTER VIEW v1 AS SELECT 2 FROM t2
--echo # Connection con3
connection con3;
--echo # Waiting for 'ALTER VIEW v1 AS SELECT 2 FROM t2' to sync in.
let $wait_condition=
SELECT COUNT(*) = 1 FROM information_schema.processlist
WHERE state = "Waiting for table" AND info = "ALTER VIEW v1 AS SELECT 2 FROM t2";
--source include/wait_condition.inc
# Unlock t1 allowing SELECT * FROM v1 to proceed.
UNLOCK TABLES;
--echo # Connection default;
connection default;
--echo # Reaping: SELECT * FROM v1
--reap
SELECT * FROM v1;
COMMIT;
--echo # Connection con2
connection con2;
--echo # Reaping: ALTER VIEW v1 AS SELECT 2 FROM t2
--reap
--echo # Connection default
connection default;
DROP TABLE t1, t2;
DROP VIEW v1;
disconnect con2;
disconnect con3;
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc

View File

@ -80,6 +80,32 @@ disconnect con1;
SET DEBUG_SYNC= "RESET";
--echo #
--echo # Bug#53757 assert in mysql_truncate_by_delete
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
CREATE TABLE t1(a INT) Engine=InnoDB;
CREATE TABLE t2(id INT);
INSERT INTO t1 VALUES (1), (2);
connect (con1, localhost, root);
INSERT INTO t2 VALUES(connection_id());
SET DEBUG_SYNC= "open_and_process_table SIGNAL opening WAIT_FOR killed";
--echo # Sending: (not reaped since connection is killed later)
--send TRUNCATE t1
connection default;
SET DEBUG_SYNC= "now WAIT_FOR opening";
SELECT ((@id := id) - id) FROM t2;
KILL @id;
SET DEBUG_SYNC= "now SIGNAL killed";
DROP TABLE t1, t2;
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc

View File

@ -3705,6 +3705,481 @@ DROP TABLE t1;
disconnect con1;
--echo #
--echo # Tests for schema-scope locks
--echo #
--disable_warnings
DROP DATABASE IF EXISTS db1;
DROP DATABASE IF EXISTS db2;
--enable_warnings
connect (con2, localhost, root);
connect (con3, localhost, root);
--echo # Test 1:
--echo # CREATE DATABASE blocks database DDL on the same database, but
--echo # not database DDL on different databases. Tests X vs X lock.
--echo #
--echo # Connection default
connection default;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send CREATE DATABASE db1
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send CREATE DATABASE db1
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='CREATE DATABASE db1';
--source include/wait_condition.inc
# This should not block.
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: CREATE DATABASE db1
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: CREATE DATABASE db1
--error ER_DB_CREATE_EXISTS
--reap
--echo # Test 2:
--echo # ALTER DATABASE blocks database DDL on the same database, but
--echo # not database DDL on different databases. Tests X vs X lock.
--echo #
--echo # Connection default
connection default;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table'
AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
--source include/wait_condition.inc
# This should not block.
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--reap
--echo # Connection default
connection default;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should also block.
--send DROP DATABASE db1
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='DROP DATABASE db1';
--source include/wait_condition.inc
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: DROP DATABASE db1
--reap
# Recreate the database
CREATE DATABASE db1;
--echo # Test 3:
--echo # Two ALTER..UPGRADE of the same database are mutually exclusive, but
--echo # two ALTER..UPGRADE of different databases are not. Tests X vs X lock.
--echo #
let $MYSQLD_DATADIR= `select @@datadir`;
# Manually make a 5.0 database from the template
--mkdir $MYSQLD_DATADIR/a-b-c
--copy_file $MYSQLD_DATADIR/db1/db.opt $MYSQLD_DATADIR/a-b-c/db.opt
--mkdir $MYSQLD_DATADIR/a-b-c-d
--copy_file $MYSQLD_DATADIR/db1/db.opt $MYSQLD_DATADIR/a-b-c-d/db.opt
--echo # Connection default
connection default;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table'
AND info='ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME';
--source include/wait_condition.inc
# This should not block.
ALTER DATABASE `#mysql50#a-b-c-d` UPGRADE DATA DIRECTORY NAME;
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: ALTER DATABASE '#mysql50#a-b-c' UPGRADE DATA DIRECTORY NAME
--error ER_BAD_DB_ERROR
--reap
DROP DATABASE `a-b-c`;
DROP DATABASE `a-b-c-d`;
--echo # Test 4:
--echo # DROP DATABASE blocks database DDL on the same database, but
--echo # not database DDL on different databases. Tests X vs X lock.
--echo #
--echo # Connection default
connection default;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send DROP DATABASE db1
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='DROP DATABASE db1';
--source include/wait_condition.inc
# This should not block.
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: DROP DATABASE db1
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: DROP DATABASE db1
--error ER_DB_DROP_EXISTS
--reap
--echo # Connection default
connection default;
CREATE DATABASE db1;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should also block.
--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table'
AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
--source include/wait_condition.inc
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: DROP DATABASE db1
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--error 1,1 # Wrong error pending followup patch for bug#54360
--reap
--echo # Test 5:
--echo # Locked database name prevents CREATE of tables in that database.
--echo # Tests X vs IX lock.
--echo #
--echo # Connection default
connection default;
CREATE DATABASE db1;
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send CREATE TABLE db1.t1 (a INT)
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='CREATE TABLE db1.t1 (a INT)';
--source include/wait_condition.inc
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: DROP DATABASE db1
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: CREATE TABLE db1.t1 (a INT)
--error ER_BAD_DB_ERROR
--reap
--echo # Test 6:
--echo # Locked database name prevents RENAME of tables to/from that database.
--echo # Tests X vs IX lock.
--echo #
--echo # Connection default
connection default;
CREATE DATABASE db1;
CREATE TABLE db1.t1 (a INT);
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send RENAME TABLE db1.t1 TO test.t1
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='RENAME TABLE db1.t1 TO test.t1';
--source include/wait_condition.inc
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: DROP DATABASE db1
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: RENAME TABLE db1.t1 TO test.t1
--error ER_FILE_NOT_FOUND, ER_FILE_NOT_FOUND
--reap
--echo # Connection default
connection default;
CREATE DATABASE db1;
CREATE TABLE test.t2 (a INT);
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send RENAME TABLE test.t2 TO db1.t2
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='RENAME TABLE test.t2 TO db1.t2';
--source include/wait_condition.inc
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: DROP DATABASE db1
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: RENAME TABLE test.t2 TO db1.t2
--error 7, 7 # Wrong error pending followup patch for bug#54360
--reap
DROP TABLE test.t2;
--echo # Test 7:
--echo # Locked database name prevents DROP of tables in that database.
--echo # Tests X vs IX lock.
--echo #
--echo # Connection default
connection default;
CREATE DATABASE db1;
CREATE TABLE db1.t1 (a INT);
SET DEBUG_SYNC= 'after_wait_locked_schema_name SIGNAL locked WAIT_FOR blocked';
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection con2
connection con2;
SET DEBUG_SYNC= 'now WAIT_FOR locked';
--echo # Sending:
# This should block.
--send DROP TABLE db1.t1
--echo # Connection con3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='DROP TABLE db1.t1';
--source include/wait_condition.inc
SET DEBUG_SYNC= 'now SIGNAL blocked';
--echo # Connection default
connection default;
--echo # Reaping: DROP DATABASE db1
--reap
--echo # Connection con2
connection con2;
--echo # Reaping: DROP TABLE db1.t1
--error ER_BAD_TABLE_ERROR
--reap
--echo # Connection default
connection default;
disconnect con2;
disconnect con3;
SET DEBUG_SYNC= 'RESET';
--echo #
--echo # End of tests for schema-scope locks
--echo #
--echo #
--echo # Tests of granted global S lock (FLUSH TABLE WITH READ LOCK)
--echo #
CREATE DATABASE db1;
CREATE TABLE db1.t1(a INT);
connect(con2, localhost, root);
connect(con3, localhost, root);
--echo # Connection default
connection default;
FLUSH TABLE WITH READ LOCK;
--echo # Connection con2
connection con2;
# IX global lock should block
--send CREATE TABLE db1.t2(a INT)
--echo # Connection default
connection default;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for release of readlock'
AND info='CREATE TABLE db1.t2(a INT)';
--source include/wait_condition.inc
UNLOCK TABLES;
--echo # Connection con2
connection con2;
--echo # Reaping CREATE TABLE db1.t2(a INT)
--reap
--echo # Connection default
connection default;
FLUSH TABLE WITH READ LOCK;
--echo # Connection con2
connection con2;
# X global lock should block
--send ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--echo # Connection default
connection default;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for release of readlock'
AND info='ALTER DATABASE db1 DEFAULT CHARACTER SET utf8';
--source include/wait_condition.inc
UNLOCK TABLES;
--echo # Connection con2
connection con2;
--echo # Reaping ALTER DATABASE db1 DEFAULT CHARACTER SET utf8
--reap
--echo # Connection default
connection default;
FLUSH TABLE WITH READ LOCK;
--echo # Connection con2
connection con2;
# S global lock should not block
FLUSH TABLE WITH READ LOCK;
UNLOCK TABLES;
--echo # Connection default
connection default;
UNLOCK TABLES;
DROP DATABASE db1;
disconnect con2;
disconnect con3;
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc

View File

@ -51,7 +51,7 @@ connection default;
#--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = $con1_id AND STATE = 'Table lock';
WHERE ID = $con1_id AND STATE = 'Waiting for table';
--source include/wait_condition.inc
#SELECT NOW();
--echo # Kick INSERT out of thr_multi_lock().
@ -61,7 +61,7 @@ FLUSH TABLES;
#--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = $con1_id AND STATE = 'Table lock';
WHERE ID = $con1_id AND STATE = 'Waiting for table';
--source include/wait_condition.inc
#SELECT NOW();
--echo # Unlock and close table and wait for con1 to close too.

View File

@ -2,6 +2,12 @@
# Test of MERGE TABLES
#
# MERGE tables require MyISAM tables
let $default=`select @@global.storage_engine`;
set global storage_engine=myisam;
set session storage_engine=myisam;
# Clean up resources used in this test case.
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6;
drop database if exists mysqltest;
@ -222,7 +228,6 @@ CREATE TABLE t2 (c1 INT NOT NULL);
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
CREATE TEMPORARY TABLE t3 (c1 INT NOT NULL) ENGINE=MRG_MYISAM UNION=(t1,t2);
--error ER_WRONG_MRG_TABLE
SELECT * FROM t3;
CREATE TEMPORARY TABLE t4 (c1 INT NOT NULL);
CREATE TEMPORARY TABLE t5 (c1 INT NOT NULL);
@ -254,7 +259,6 @@ create table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
select * from t3;
drop table t3;
create temporary table t3 (a int not null) ENGINE=MERGE UNION=(t1,t2);
--error ER_WRONG_MRG_TABLE
select * from t3;
drop table t3, t2, t1;
--echo # CREATE...SELECT is not implemented for MERGE tables.
@ -891,12 +895,9 @@ INSERT INTO t4 VALUES (4);
--echo # If the temporary MERGE table uses the locked children only,
--echo # it can even be used.
CREATE TEMPORARY TABLE t4 LIKE t3;
--error ER_WRONG_MRG_TABLE
SHOW CREATE TABLE t4;
--error ER_WRONG_MRG_TABLE
INSERT INTO t4 VALUES (4);
UNLOCK TABLES;
--error ER_WRONG_MRG_TABLE
INSERT INTO t4 VALUES (4);
DROP TABLE t4;
#
@ -2116,6 +2117,325 @@ ALTER TABLE t1 ENGINE=MERGE UNION(t_not_exists,t1);
OPTIMIZE TABLE t1;
DROP TABLE t1;
--echo #
--echo # Bug#36171 - CREATE TEMPORARY TABLE and MERGE engine
--echo # More tests with TEMPORARY MERGE table and permanent children.
--echo # First without locked tables.
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1, t2, t3, t4, m1, m2;
--enable_warnings
#
--echo #
CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SHOW CREATE TABLE t1;
SHOW CREATE TABLE m1;
SELECT * FROM m1;
INSERT INTO t1 VALUES (111, 121);
INSERT INTO m1 VALUES (211, 221);
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
#
--echo #
ALTER TABLE m1 RENAME m2;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
#
--echo #
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
--error ER_TABLE_EXISTS_ERROR
ALTER TABLE m2 RENAME m1;
DROP TABLE m1;
ALTER TABLE m2 RENAME m1;
SHOW CREATE TABLE m1;
SELECT * FROM m1;
#
--echo #
ALTER TABLE m1 ADD COLUMN c3 INT;
--error ER_WRONG_MRG_TABLE
INSERT INTO m1 VALUES (212, 222, 232);
--error ER_WRONG_MRG_TABLE
SELECT * FROM m1;
ALTER TABLE t1 ADD COLUMN c3 INT;
ALTER TABLE t2 ADD COLUMN c3 INT;
INSERT INTO m1 VALUES (212, 222, 232);
SELECT * FROM m1;
#
--echo #
ALTER TABLE m1 DROP COLUMN c3;
--error ER_WRONG_MRG_TABLE
INSERT INTO m1 VALUES (213, 223);
--error ER_WRONG_MRG_TABLE
SELECT * FROM m1;
ALTER TABLE t1 DROP COLUMN c3;
ALTER TABLE t2 DROP COLUMN c3;
INSERT INTO m1 VALUES (213, 223);
SELECT * FROM m1;
#
--echo #
CREATE TABLE t3 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3);
INSERT INTO m1 VALUES (311, 321);
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
#
--echo #
CREATE TEMPORARY TABLE t4 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3,t4);
INSERT INTO m1 VALUES (411, 421);
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
SELECT * FROM t4;
#
--echo #
ALTER TABLE m1 ENGINE=MyISAM;
SHOW CREATE TABLE m1;
INSERT INTO m1 VALUES (511, 521);
SELECT * FROM m1;
#
--echo #
ALTER TABLE m1 ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
#
--echo #
CREATE TEMPORARY TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (611, 621);
SELECT * FROM m1;
DROP TABLE t1;
SELECT * FROM m1;
#
#
--echo #
--echo #
SHOW CREATE TABLE m1;
#
--echo #
CREATE TABLE m2 SELECT * FROM m1;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
DROP TABLE m2;
#
--echo #
CREATE TEMPORARY TABLE m2 SELECT * FROM m1;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
DROP TABLE m2;
#
--echo #
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
--error ER_WRONG_MRG_TABLE
SELECT * FROM m2;
DROP TABLE m2;
#
--echo #
--error ER_WRONG_OBJECT
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
#
--echo #
--error ER_WRONG_OBJECT
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
#
--echo #
CREATE TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
DROP TABLE m2;
#
--echo #
CREATE TEMPORARY TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
DROP TABLE m2;
#
--echo #
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
#
#
--echo #
--echo #
LOCK TABLE m1 WRITE, m2 WRITE;
SELECT * FROM m1,m2 WHERE m1.c1=m2.c1;
UNLOCK TABLES;
#
DROP TABLE t1, t2, t3, t4, m1, m2;
#
#
#
--echo #
--echo # Bug#36171 - CREATE TEMPORARY TABLE and MERGE engine
--echo # More tests with TEMPORARY MERGE table and permanent children.
--echo # (continued) Now the same with locked table.
--echo #
CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c1 INT, c2 INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SHOW CREATE TABLE t1;
SHOW CREATE TABLE m1;
SELECT * FROM m1;
INSERT INTO t1 VALUES (111, 121);
INSERT INTO m1 VALUES (211, 221);
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
#
--echo #
LOCK TABLE m1 WRITE, t1 WRITE, t2 WRITE;
#
--echo #
ALTER TABLE m1 RENAME m2;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
#
--echo #
CREATE TEMPORARY TABLE m1 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
--error ER_TABLE_EXISTS_ERROR
ALTER TABLE m2 RENAME m1;
DROP TABLE m1;
ALTER TABLE m2 RENAME m1;
SHOW CREATE TABLE m1;
SELECT * FROM m1;
#
--echo #
ALTER TABLE m1 ADD COLUMN c3 INT;
--error ER_WRONG_MRG_TABLE
INSERT INTO m1 VALUES (212, 222, 232);
--error ER_WRONG_MRG_TABLE
SELECT * FROM m1;
ALTER TABLE t1 ADD COLUMN c3 INT;
ALTER TABLE t2 ADD COLUMN c3 INT;
INSERT INTO m1 VALUES (212, 222, 232);
SELECT * FROM m1;
#
--echo #
ALTER TABLE m1 DROP COLUMN c3;
--error ER_WRONG_MRG_TABLE
INSERT INTO m1 VALUES (213, 223);
--error ER_WRONG_MRG_TABLE
SELECT * FROM m1;
ALTER TABLE t1 DROP COLUMN c3;
ALTER TABLE t2 DROP COLUMN c3;
INSERT INTO m1 VALUES (213, 223);
SELECT * FROM m1;
#
--echo #
UNLOCK TABLES;
CREATE TABLE t3 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3);
LOCK TABLE m1 WRITE;
INSERT INTO m1 VALUES (311, 321);
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
#
--echo #
CREATE TEMPORARY TABLE t4 (c1 INT, c2 INT) ENGINE=MyISAM;
ALTER TABLE m1 UNION=(t1,t2,t3,t4);
INSERT INTO m1 VALUES (411, 421);
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
SELECT * FROM t3;
SELECT * FROM t4;
#
--echo #
ALTER TABLE m1 ENGINE=MyISAM;
SHOW CREATE TABLE m1;
INSERT INTO m1 VALUES (511, 521);
SELECT * FROM m1;
#
--echo #
ALTER TABLE m1 ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
SELECT * FROM m1;
SELECT * FROM t1;
SELECT * FROM t2;
#
--echo #
CREATE TEMPORARY TABLE t1 (c1 INT, c2 INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (611, 621);
SELECT * FROM m1;
DROP TABLE t1;
SELECT * FROM m1;
#
#
--echo #
--echo #
SHOW CREATE TABLE m1;
--error ER_TABLE_NOT_LOCKED
CREATE TABLE m2 SELECT * FROM m1;
#
--echo #
CREATE TEMPORARY TABLE m2 SELECT * FROM m1;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
DROP TABLE m2;
#
--echo #
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
SELECT * FROM m2;
LOCK TABLE m1 WRITE, m2 WRITE;
UNLOCK TABLES;
DROP TABLE m2;
LOCK TABLE m1 WRITE;
#
--echo #
--echo # ER_TABLE_NOT_LOCKED is returned in ps-protocol
--error ER_WRONG_OBJECT, ER_TABLE_NOT_LOCKED
CREATE TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
#
--echo #
--error ER_WRONG_OBJECT
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST SELECT * FROM m1;
#
--echo #
CREATE TEMPORARY TABLE m2 LIKE m1;
SHOW CREATE TABLE m2;
LOCK TABLE m1 WRITE, m2 WRITE;
SHOW CREATE TABLE m2;
SELECT * FROM m2;
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
DROP TABLE m2;
#
--echo #
CREATE TEMPORARY TABLE m2 (c1 INT, c2 INT) ENGINE=MRG_MyISAM UNION=(t3,t4)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
#
--echo #
UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4, m1, m2;
--echo #
--echo # Bug47098 assert in MDL_context::destroy on HANDLER
--echo # <damaged merge table> OPEN
@ -2225,6 +2545,130 @@ show create table m1;
show create table m2;
drop tables m1, m2, t1;
--echo #
--echo # Test case for Bug#54811 "Assert in mysql_lock_have_duplicate()"
--echo # Check that unique_table() works correctly for merge tables.
--echo #
--disable_warnings
drop table if exists t1, t2, t3, m1, m2;
--enable_warnings
create table t1 (a int);
create table t2 (a int);
create table t3 (b int);
create view v1 as select * from t3,t1;
create table m1 (a int) engine=merge union (t1, t2) insert_method=last;
create table m2 (a int) engine=merge union (t1, t2) insert_method=first;
create temporary table tmp (b int);
insert into tmp (b) values (1);
insert into t1 (a) values (1);
insert into t3 (b) values (1);
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from m1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from m2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, m1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, m2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, t1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from t3, t2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, m1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, m2));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, t1));
--error ER_UPDATE_TABLE_USED
insert into m1 (a) values ((select max(a) from tmp, t2));
--error ER_VIEW_PREVENT_UPDATE
insert into m1 (a) values ((select max(a) from v1));
--error ER_VIEW_PREVENT_UPDATE
insert into m1 (a) values ((select max(a) from tmp, v1));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from m1));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from m2));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from t1));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from t2));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from t3, m1));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from t3, m2));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from t3, t1));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from t3, t2));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from tmp, m1));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from tmp, m2));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from tmp, t1));
--error ER_UPDATE_TABLE_USED
update m1 set a = ((select max(a) from tmp, t2));
--error ER_VIEW_PREVENT_UPDATE
update m1 set a = ((select max(a) from v1));
--error ER_VIEW_PREVENT_UPDATE
update m1 set a = ((select max(a) from tmp, v1));
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from m1);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from m2);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from t1);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from t2);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from t3, m1);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from t3, m2);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from t3, t1);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from t3, t2);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from tmp, m1);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from tmp, m2);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from tmp, t1);
--error ER_UPDATE_TABLE_USED
delete from m1 where a = (select max(a) from tmp, t2);
--error ER_VIEW_PREVENT_UPDATE
delete from m1 where a = (select max(a) from v1);
--error ER_VIEW_PREVENT_UPDATE
delete from m1 where a = (select max(a) from tmp, v1);
drop view v1;
drop temporary table tmp;
drop table t1, t2, t3, m1, m2;
--echo End of 6.0 tests
--disable_result_log
--disable_query_log
eval set global storage_engine=$default;
--enable_result_log
--enable_query_log

View File

@ -0,0 +1 @@
--myisam-use-mmap

View File

@ -0,0 +1,151 @@
#
# Test of MERGE TABLES with MyISAM memory mapping enabled (--myisam-use-mmap)
#
# MERGE tables require MyISAM tables
--let $default=`SELECT @@global.storage_engine`
SET GLOBAL storage_engine = MyISAM;
SET SESSION storage_engine = MyISAM;
# Clean up resources used in this test case.
--disable_warnings
DROP TABLE IF EXISTS t1, t2, m1, m2;
--enable_warnings
####################
## No locked tables.
####################
#
# INSERT-SELECT with no TEMPORARY table.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
SELECT * FROM t2;
DROP TABLE m2, m1, t2, t1;
#
# INSERT-SELECT with TEMPORARY select table.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
DROP TABLE m2, m1, t2, t1;
#
# INSERT-SELECT with TEMPORARY insert table.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
DROP TABLE m2, m1, t2, t1;
#
# INSERT-SELECT with TEMPORARY both tables.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
DROP TABLE m2, m1, t2, t1;
####################
## With LOCK TABLES.
####################
#
# INSERT-SELECT with no TEMPORARY table.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
SELECT * FROM t2;
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
#
# INSERT-SELECT with TEMPORARY select table.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
#
# INSERT-SELECT with TEMPORARY insert table.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
#
# INSERT-SELECT with TEMPORARY both tables.
#
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE TEMPORARY TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
CREATE TEMPORARY TABLE m2 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1,t2)
INSERT_METHOD=LAST;
LOCK TABLE m1 WRITE, m2 WRITE;
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2), (3), (4);
INSERT INTO m2 SELECT * FROM m1;
SELECT * FROM m2;
UNLOCK TABLES;
DROP TABLE m2, m1, t2, t1;
--echo End of 6.0 tests
--disable_result_log
--disable_query_log
eval SET GLOBAL storage_engine = $default;
--enable_result_log
--enable_query_log

View File

@ -65,7 +65,7 @@ ENGINE = MYISAM
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */;
SET DEBUG_SYNC= 'open_tables_acquire_upgradable_mdl SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_open_tables SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done';
--send ALTER TABLE t2 REMOVE PARTITIONING
connection default;

View File

@ -23,6 +23,7 @@ drop schema foo;
--disable_warnings
DROP SCHEMA IF EXISTS schema1;
DROP SCHEMA IF EXISTS schema2;
--enable_warnings
connect(con2, localhost, root);
@ -31,6 +32,7 @@ connect(con2, localhost, root);
connection default;
CREATE SCHEMA schema1;
CREATE SCHEMA schema2;
CREATE TABLE schema1.t1 (a INT);
SET autocommit= FALSE;
@ -46,9 +48,7 @@ let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist
WHERE state= 'Waiting for table'
AND info='DROP SCHEMA schema1';
--source include/wait_condition.inc
# Listing the error twice to prevent result diffences based on filename
--error 1,1
ALTER SCHEMA schema1 DEFAULT CHARACTER SET utf8;
ALTER SCHEMA schema2 DEFAULT CHARACTER SET utf8;
SET autocommit= TRUE;
--echo # Connection 2
@ -57,6 +57,7 @@ connection con2;
--echo # Connection default
connection default;
DROP SCHEMA schema2;
disconnect con2;
@ -102,6 +103,98 @@ connection con2;
connection default;
disconnect con2;
--echo #
--echo # Bug#54360 Deadlock DROP/ALTER/CREATE DATABASE with open HANDLER
--echo #
CREATE DATABASE db1;
CREATE TABLE db1.t1 (a INT);
INSERT INTO db1.t1 VALUES (1), (2);
--echo # Connection con1
connect (con1, localhost, root);
HANDLER db1.t1 OPEN;
--echo # Connection default
connection default;
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection con2
connect (con2, localhost, root);
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' AND info='DROP DATABASE db1';
--source include/wait_condition.inc
--echo # Connection con1
connection con1;
# All these statements before resulted in deadlock.
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
HANDLER t1 CLOSE;
--echo # Connection default
connection default;
--echo # Reaping: DROP DATABASE db1
--reap
disconnect con1;
disconnect con2;
--echo #
--echo # Tests for increased CREATE/ALTER/DROP DATABASE concurrency with
--echo # database name locks.
--echo #
--disable_warnings
DROP DATABASE IF EXISTS db1;
DROP DATABASE IF EXISTS db2;
--enable_warnings
connect (con2, localhost, root);
connect (con3, localhost, root);
--echo # Connection default
connection default;
CREATE DATABASE db1;
CREATE TABLE db1.t1 (id INT);
START TRANSACTION;
INSERT INTO db1.t1 VALUES (1);
--echo # Connection 2
connection con2;
--echo # DROP DATABASE should block due to the active transaction
--echo # Sending:
--send DROP DATABASE db1
--echo # Connection 3
connection con3;
let $wait_condition=SELECT COUNT(*)=1 FROM information_schema.processlist
WHERE state='Waiting for table' and info='DROP DATABASE db1';
--source include/wait_condition.inc
--echo # But it should still be possible to CREATE/ALTER/DROP other databases.
CREATE DATABASE db2;
ALTER DATABASE db2 DEFAULT CHARACTER SET utf8;
DROP DATABASE db2;
--echo # Connection default
connection default;
--echo # End the transaction so DROP DATABASE db1 can continue
COMMIT;
--echo # Connection 2
connection con2;
--echo # Reaping: DROP DATABASE db1
--reap
--echo # Connection default;
connection default;
disconnect con2;
disconnect con3;
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc

View File

@ -1246,6 +1246,85 @@ UNLOCK TABLES;
DROP TABLE t1;
--echo #
--echo # Bug#54905 Connection with WRITE lock cannot ALTER table due to
--echo # concurrent SHOW CREATE
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1(a INT);
--echo # Connection con1
connect (con1,localhost,root);
LOCK TABLE t1 WRITE;
--echo # Connection default
connection default;
START TRANSACTION;
SHOW CREATE TABLE t1;
--echo # Connection con1
connection con1;
# Used to block
ALTER TABLE t1 CHARACTER SET = utf8;
UNLOCK TABLES;
--echo # Connection default
connection default;
COMMIT;
disconnect con1;
DROP TABLE t1;
--echo #
--echo # Bug#55498 SHOW CREATE TRIGGER takes wrong type of metadata lock.
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a INT);
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1;
--echo # Test 1: SHOW CREATE TRIGGER with WRITE locked table.
--echo # Connection con1
connect (con1, localhost, root);
LOCK TABLE t1 WRITE;
--echo # Connection default
connection default;
# Should not block.
SHOW CREATE TRIGGER t1_bi;
--echo # Connection con1
connection con1;
UNLOCK TABLES;
--echo # Test 2: ALTER TABLE with SHOW CREATE TRIGGER in transaction
--echo # Connection default
connection default;
START TRANSACTION;
SHOW CREATE TRIGGER t1_bi;
--echo # Connection con1
connection con1;
# Should not block.
ALTER TABLE t1 CHARACTER SET = utf8;
--echo # Connection default
connection default;
COMMIT;
DROP TRIGGER t1_bi;
DROP TABLE t1;
disconnect con1;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

View File

@ -235,4 +235,19 @@ INSERT INTO t2 SELECT f1();
DROP TABLE t1,t2,t3;
DROP FUNCTION f1;
--echo #
--echo # Bug #48067: A temp table with the same name as an existing table,
--echo # makes drop database fail.
--echo #
--disable_warnings
DROP TEMPORARY TABLE IF EXISTS bug48067.t1;
DROP DATABASE IF EXISTS bug48067;
--enable_warnings
CREATE DATABASE bug48067;
CREATE TABLE bug48067.t1 (c1 int);
INSERT INTO bug48067.t1 values (1);
CREATE TEMPORARY TABLE bug48067.t1 (c1 int);
DROP DATABASE bug48067;
DROP TEMPORARY table bug48067.t1;
--echo End of 5.1 tests

View File

@ -1405,4 +1405,30 @@ SET @@sql_quote_show_create = @sql_quote_show_create_saved;
--echo # End of Bug#34828.
--echo
--echo # Make sure we can manipulate with autocommit in the
--echo # along with other variables.
--disable_warnings
drop table if exists t1;
drop function if exists t1_max;
drop function if exists t1_min;
--enable_warnings
create table t1 (a int) engine=innodb;
insert into t1(a) values (0), (1);
create function t1_max() returns int return (select max(a) from t1);
create function t1_min() returns int return (select min(a) from t1);
select t1_min();
select t1_max();
set @@session.autocommit=t1_min(), @@session.autocommit=t1_max(),
@@session.autocommit=t1_min(), @@session.autocommit=t1_max(),
@@session.autocommit=t1_min(), @@session.autocommit=t1_max();
--echo # Cleanup.
drop table t1;
drop function t1_min;
drop function t1_max;
###########################################################################

View File

@ -49,7 +49,9 @@ const char *globerrs[GLOBERRS]=
"Can't sync file '%s' to disk (Errcode: %d)",
"Collation '%s' is not a compiled collation and is not specified in the '%s' file",
"File '%s' not found (Errcode: %d)",
"File '%s' (fileno: %d) was not closed"
"File '%s' (fileno: %d) was not closed",
"Can't change ownership of the file '%s' (Errcode: %d)",
"Can't change permissions of the file '%s' (Errcode: %d)",
};
void init_glob_errs(void)
@ -90,6 +92,8 @@ void init_glob_errs()
EE(EE_UNKNOWN_COLLATION)= "Collation '%s' is not a compiled collation and is not specified in the %s file";
EE(EE_FILENOTFOUND) = "File '%s' not found (Errcode: %d)";
EE(EE_FILE_NOT_CLOSED) = "File '%s' (fileno: %d) was not closed";
EE(EE_CHANGE_OWNERSHIP) = "Can't change ownership of the file '%s' (Errcode: %d)";
EE(EE_CHANGE_PERMISSIONS) = "Can't change permissions of the file '%s' (Errcode: %d)";
}
#endif

View File

@ -454,7 +454,9 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
RETURN
0 we succeeded in reading all data
1 Error: can't read requested characters
1 Error: couldn't read requested characters. In this case:
If info->error == -1, we got a read error.
Otherwise info->error contains the number of bytes in Buffer.
*/
int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
@ -463,6 +465,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
my_off_t pos_in_file;
DBUG_ENTER("_my_b_read");
/* If the buffer is not empty yet, copy what is available. */
if ((left_length= (size_t) (info->read_end-info->read_pos)))
{
DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
@ -474,7 +477,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
/* pos_in_file always point on where info->buffer was read */
pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
/*
/*
Whenever a function which operates on IO_CACHE flushes/writes
some part of the IO_CACHE to disk it will set the property
"seek_not_done" to indicate this to other functions operating
@ -501,19 +504,38 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
}
}
/*
Calculate, how much we are within a IO_SIZE block. Ideally this
should be zero.
*/
diff_length= (size_t) (pos_in_file & (IO_SIZE-1));
/*
If more than a block plus the rest of the current block is wanted,
we do read directly, without filling the buffer.
*/
if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
{ /* Fill first intern buffer */
size_t read_length;
if (info->end_of_file <= pos_in_file)
{ /* End of file */
{
/* End of file. Return, what we did copy from the buffer. */
info->error= (int) left_length;
DBUG_RETURN(1);
}
/*
Crop the wanted count to a multiple of IO_SIZE and subtract,
what we did already read from a block. That way, the read will
end aligned with a block.
*/
length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
if ((read_length= my_read(info->file,Buffer, length, info->myflags))
!= length)
{
/*
If we didn't get, what we wanted, we either return -1 for a read
error, or (it's end of file), how much we got in total.
*/
info->error= (read_length == (size_t) -1 ? -1 :
(int) (read_length+left_length));
DBUG_RETURN(1);
@ -525,15 +547,27 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
diff_length=0;
}
/*
At this point, we want less than one and a partial block.
We will read a full cache, minus the number of bytes, we are
within a block already. So we will reach new alignment.
*/
max_length= info->read_length-diff_length;
/* We will not read past end of file. */
if (info->type != READ_FIFO &&
max_length > (info->end_of_file - pos_in_file))
max_length= (size_t) (info->end_of_file - pos_in_file);
/*
If there is nothing left to read,
we either are done, or we failed to fulfill the request.
Otherwise, we read max_length into the cache.
*/
if (!max_length)
{
if (Count)
{
info->error= left_length; /* We only got this many char */
/* We couldn't fulfil the request. Return, how much we got. */
info->error= left_length;
DBUG_RETURN(1);
}
length=0; /* Didn't read any chars */
@ -542,13 +576,23 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
info->myflags)) < Count ||
length == (size_t) -1)
{
/*
We got an read error, or less than requested (end of file).
If not a read error, copy, what we got.
*/
if (length != (size_t) -1)
memcpy(Buffer, info->buffer, length);
info->pos_in_file= pos_in_file;
/* For a read error, return -1, otherwise, what we got in total. */
info->error= length == (size_t) -1 ? -1 : (int) (length+left_length);
info->read_pos=info->read_end=info->buffer;
DBUG_RETURN(1);
}
/*
Count is the remaining number of bytes requested.
length is the amount of data in the cache.
Read Count bytes from the cache.
*/
info->read_pos=info->buffer+Count;
info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
@ -1702,16 +1746,19 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
#endif
int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
int my_b_flush_io_cache(IO_CACHE *info,
int need_append_buffer_lock __attribute__((unused)))
{
size_t length;
my_bool append_cache;
my_off_t pos_in_file;
my_bool append_cache= (info->type == SEQ_READ_APPEND);
DBUG_ENTER("my_b_flush_io_cache");
DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
if (!(append_cache = (info->type == SEQ_READ_APPEND)))
need_append_buffer_lock=0;
#ifdef THREAD
if (!append_cache)
need_append_buffer_lock= 0;
#endif
if (info->type == WRITE_CACHE || append_cache)
{

View File

@ -16,6 +16,7 @@
#include "mysys_priv.h"
#include <my_dir.h> /* for stat */
#include <m_string.h>
#include "mysys_err.h"
#if defined(HAVE_UTIME_H)
#include <utime.h>
#elif defined(HAVE_SYS_UTIME_H)
@ -56,7 +57,6 @@ int my_copy(const char *from, const char *to, myf MyFlags)
File from_file,to_file;
uchar buff[IO_SIZE];
MY_STAT stat_buff,new_stat_buff;
int res;
DBUG_ENTER("my_copy");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
@ -102,9 +102,23 @@ int my_copy(const char *from, const char *to, myf MyFlags)
if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
DBUG_RETURN(0); /* File copyed but not stat */
res= chmod(to, stat_buff.st_mode & 07777); /* Copy modes */
/* Copy modes */
if (chmod(to, stat_buff.st_mode & 07777))
{
my_errno= errno;
if (MyFlags & (MY_FAE+MY_WME))
my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
goto err;
}
#if !defined(__WIN__)
res= chown(to, stat_buff.st_uid,stat_buff.st_gid); /* Copy ownership */
/* Copy ownership */
if (chown(to, stat_buff.st_uid, stat_buff.st_gid))
{
my_errno= errno;
if (MyFlags & (MY_FAE+MY_WME))
my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno);
goto err;
}
#endif
if (MyFlags & MY_COPYTIME)

View File

@ -76,11 +76,8 @@ end:
int my_copystat(const char *from, const char *to, int MyFlags)
{
struct stat statbuf;
#if !defined(__WIN__)
int res;
#endif
if (stat((char*) from, &statbuf))
if (stat(from, &statbuf))
{
my_errno=errno;
if (MyFlags & (MY_FAE+MY_WME))
@ -89,7 +86,15 @@ int my_copystat(const char *from, const char *to, int MyFlags)
}
if ((statbuf.st_mode & S_IFMT) != S_IFREG)
return 1;
(void) chmod(to, statbuf.st_mode & 07777); /* Copy modes */
/* Copy modes */
if (chmod(to, statbuf.st_mode & 07777))
{
my_errno= errno;
if (MyFlags & (MY_FAE+MY_WME))
my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno);
return -1;
}
#if !defined(__WIN__)
if (statbuf.st_nlink > 1 && MyFlags & MY_LINK_WARNING)
@ -97,7 +102,14 @@ int my_copystat(const char *from, const char *to, int MyFlags)
if (MyFlags & MY_LINK_WARNING)
my_error(EE_LINK_WARNING,MYF(ME_BELL+ME_WAITTANG),from,statbuf.st_nlink);
}
res= chown(to, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
/* Copy ownership */
if (chown(to, statbuf.st_uid, statbuf.st_gid))
{
my_errno= errno;
if (MyFlags & (MY_FAE+MY_WME))
my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno);
return -1;
}
#endif /* !__WIN__ */
if (MyFlags & MY_COPYTIME)

View File

@ -107,7 +107,7 @@ my_bool init_thr_lock()
}
static inline my_bool
thr_lock_owner_equal(THR_LOCK_OWNER *rhs, THR_LOCK_OWNER *lhs)
thr_lock_owner_equal(THR_LOCK_INFO *rhs, THR_LOCK_INFO *lhs)
{
return rhs == lhs;
}
@ -122,7 +122,7 @@ static int check_lock(struct st_lock_list *list, const char* lock_type,
{
THR_LOCK_DATA *data,**prev;
uint count=0;
THR_LOCK_OWNER *UNINIT_VAR(first_owner);
THR_LOCK_INFO *UNINIT_VAR(first_owner);
prev= &list->data;
if (list->data)
@ -341,7 +341,6 @@ void thr_lock_info_init(THR_LOCK_INFO *info)
struct st_my_thread_var *tmp= my_thread_var;
info->thread= tmp->pthread_self;
info->thread_id= tmp->id;
info->n_cursors= 0;
}
/* Initialize a lock instance */
@ -357,7 +356,7 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param)
static inline my_bool
has_old_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner)
has_old_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner)
{
for ( ; data ; data=data->next)
{
@ -506,13 +505,12 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
enum enum_thr_lock_result
thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
thr_lock(THR_LOCK_DATA *data, THR_LOCK_INFO *owner,
enum thr_lock_type lock_type, ulong lock_wait_timeout)
{
THR_LOCK *lock=data->lock;
enum enum_thr_lock_result result= THR_LOCK_SUCCESS;
struct st_lock_list *wait_queue;
THR_LOCK_DATA *lock_owner;
DBUG_ENTER("thr_lock");
data->next=0;
@ -521,7 +519,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
data->owner= owner; /* Must be reset ! */
mysql_mutex_lock(&lock->mutex);
DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d",
(long) data, data->owner->info->thread_id,
(long) data, data->owner->thread_id,
(long) lock, (int) lock_type));
check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
"enter read_lock" : "enter write_lock",0);
@ -558,7 +556,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
*/
DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx",
lock->write.data->owner->info->thread_id));
lock->write.data->owner->thread_id));
if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
(lock->write.data->type <= TL_WRITE_DELAYED &&
(((int) lock_type <= (int) TL_READ_HIGH_PRIORITY) ||
@ -707,7 +705,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
goto end;
}
DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx",
lock->write.data->owner->info->thread_id));
lock->write.data->owner->thread_id));
}
else
{
@ -743,23 +741,10 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
}
}
DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx type: %d",
lock->read.data->owner->info->thread_id, data->type));
lock->read.data->owner->thread_id, data->type));
}
wait_queue= &lock->write_wait;
}
/*
Try to detect a trivial deadlock when using cursors: attempt to
lock a table that is already locked by an open cursor within the
same connection. lock_owner can be zero if we succumbed to a high
priority writer in the write_wait queue.
*/
lock_owner= lock->read.data ? lock->read.data : lock->write.data;
if (lock_owner && lock_owner->owner->info == owner->info)
{
DBUG_PRINT("lock",("deadlock"));
result= THR_LOCK_DEADLOCK;
goto end;
}
/* Can't get lock yet; Wait for it */
DBUG_RETURN(wait_for_lock(wait_queue, data, 0, lock_wait_timeout));
end:
@ -807,7 +792,7 @@ static inline void free_all_read_locks(THR_LOCK *lock,
}
/* purecov: begin inspected */
DBUG_PRINT("lock",("giving read lock to thread: 0x%lx",
data->owner->info->thread_id));
data->owner->thread_id));
/* purecov: end */
data->cond=0; /* Mark thread free */
mysql_cond_signal(cond);
@ -826,7 +811,7 @@ void thr_unlock(THR_LOCK_DATA *data)
enum thr_lock_type lock_type=data->type;
DBUG_ENTER("thr_unlock");
DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx",
(long) data, data->owner->info->thread_id, (long) lock));
(long) data, data->owner->thread_id, (long) lock));
mysql_mutex_lock(&lock->mutex);
check_locks(lock,"start of release lock",0);
@ -915,7 +900,7 @@ static void wake_up_waiters(THR_LOCK *lock)
data->type=TL_WRITE; /* Upgrade lock */
/* purecov: begin inspected */
DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx",
data->type, data->owner->info->thread_id));
data->type, data->owner->thread_id));
/* purecov: end */
{
mysql_cond_t *cond= data->cond;
@ -1020,7 +1005,7 @@ static void sort_locks(THR_LOCK_DATA **data,uint count)
enum enum_thr_lock_result
thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner,
thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_INFO *owner,
ulong lock_wait_timeout)
{
THR_LOCK_DATA **pos,**end;
@ -1144,7 +1129,7 @@ void thr_multi_unlock(THR_LOCK_DATA **data,uint count)
else
{
DBUG_PRINT("lock",("Free lock: data: 0x%lx thread: 0x%lx lock: 0x%lx",
(long) *pos, (*pos)->owner->info->thread_id,
(long) *pos, (*pos)->owner->thread_id,
(long) (*pos)->lock));
}
}
@ -1200,7 +1185,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
mysql_mutex_lock(&lock->mutex);
for (data= lock->read_wait.data; data ; data= data->next)
{
if (data->owner->info->thread_id == thread_id) /* purecov: tested */
if (data->owner->thread_id == thread_id) /* purecov: tested */
{
DBUG_PRINT("info",("Aborting read-wait lock"));
data->type= TL_UNLOCK; /* Mark killed */
@ -1217,7 +1202,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id)
}
for (data= lock->write_wait.data; data ; data= data->next)
{
if (data->owner->info->thread_id == thread_id) /* purecov: tested */
if (data->owner->thread_id == thread_id) /* purecov: tested */
{
DBUG_PRINT("info",("Aborting write-wait lock"));
data->type= TL_UNLOCK;
@ -1387,7 +1372,7 @@ static void thr_print_lock(const char* name,struct st_lock_list *list)
prev= &list->data;
for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
{
printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->info->thread_id,
printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->thread_id,
(int) data->type);
if (data->prev != prev)
printf("\nWarning: prev didn't point at previous lock\n");
@ -1525,7 +1510,6 @@ static void *test_thread(void *arg)
{
int i,j,param=*((int*) arg);
THR_LOCK_DATA data[MAX_LOCK_COUNT];
THR_LOCK_OWNER owner;
THR_LOCK_INFO lock_info;
THR_LOCK_DATA *multi_locks[MAX_LOCK_COUNT];
my_thread_init();
@ -1534,7 +1518,6 @@ static void *test_thread(void *arg)
thr_lock_info_init(&lock_info);
thr_lock_owner_init(&owner, &lock_info);
for (i=0; i < lock_counts[param] ; i++)
thr_lock_data_init(locks+tests[param][i].lock_nr,data+i,NULL);
for (j=1 ; j < 10 ; j++) /* try locking 10 times */
@ -1544,7 +1527,7 @@ static void *test_thread(void *arg)
multi_locks[i]= &data[i];
data[i].type= tests[param][i].lock_type;
}
thr_multi_lock(multi_locks, lock_counts[param], &owner, TEST_TIMEOUT);
thr_multi_lock(multi_locks, lock_counts[param], &lock_info, TEST_TIMEOUT);
mysql_mutex_lock(&LOCK_thread_count);
{
int tmp=rand() & 7; /* Do something from 0-2 sec */

View File

@ -256,7 +256,6 @@ sopno stopst;
register char *ssp; /* start of string matched by subsubRE */
register char *sep; /* end of string matched by subsubRE */
register char *oldssp; /* previous ssp */
register char *dp; /* used in debug mode to check asserts */
AT("diss", start, stop, startst, stopst);
sp = start;
@ -314,11 +313,9 @@ sopno stopst;
ssub = ss + 1;
esub = es - 1;
/* did innards match? */
if (slow(charset, m, sp, rest, ssub, esub) != NULL) {
dp = dissect(charset, m, sp, rest, ssub, esub);
assert(dp == rest);
} else /* no */
assert(sp == rest);
if (slow(charset, m, sp, rest, ssub, esub) != NULL)
sp = dissect(charset, m, sp, rest, ssub, esub);
assert(sp == rest);
sp = rest;
break;
case OPLUS_:
@ -353,8 +350,8 @@ sopno stopst;
}
assert(sep == rest); /* must exhaust substring */
assert(slow(charset, m, ssp, sep, ssub, esub) == rest);
dp = dissect(charset, m, ssp, sep, ssub, esub);
assert(dp == sep);
sp = dissect(charset, m, ssp, sep, ssub, esub);
assert(sp == sep);
sp = rest;
break;
case OCH_:
@ -388,8 +385,8 @@ sopno stopst;
else
assert(OP(m->g->strip[esub]) == O_CH);
}
dp = dissect(charset, m, sp, rest, ssub, esub);
assert(dp == rest);
sp = dissect(charset, m, sp, rest, ssub, esub);
assert(sp == rest);
sp = rest;
break;
case O_PLUS:

View File

@ -1402,6 +1402,8 @@ Event_job_data::execute(THD *thd, bool drop)
*/
thd->set_db(dbname.str, dbname.length);
lex_start(thd);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (event_sctx.change_security_context(thd,
&definer_user, &definer_host,
@ -1411,7 +1413,7 @@ Event_job_data::execute(THD *thd, bool drop)
"[%s].[%s.%s] execution failed, "
"failed to authenticate the user.",
definer.str, dbname.str, name.str);
goto end_no_lex_start;
goto end;
}
#endif
@ -1427,11 +1429,11 @@ Event_job_data::execute(THD *thd, bool drop)
"[%s].[%s.%s] execution failed, "
"user no longer has EVENT privilege.",
definer.str, dbname.str, name.str);
goto end_no_lex_start;
goto end;
}
if (construct_sp_sql(thd, &sp_sql))
goto end_no_lex_start;
goto end;
/*
Set up global thread attributes to reflect the properties of
@ -1451,8 +1453,6 @@ Event_job_data::execute(THD *thd, bool drop)
if (parser_state.init(thd, thd->query(), thd->query_length()))
goto end;
lex_start(thd);
if (parse_sql(thd, & parser_state, creation_ctx))
{
sql_print_error("Event Scheduler: "
@ -1484,13 +1484,6 @@ Event_job_data::execute(THD *thd, bool drop)
}
end:
if (thd->lex->sphead) /* NULL only if a parse error */
{
delete thd->lex->sphead;
thd->lex->sphead= NULL;
}
end_no_lex_start:
if (drop && !thd->is_fatal_error)
{
/*
@ -1529,7 +1522,6 @@ end_no_lex_start:
if (save_sctx)
event_sctx.restore_security_context(thd, save_sctx);
#endif
lex_end(thd->lex);
thd->lex->unit.cleanup();
thd->end_statement();
thd->cleanup_after_query();

View File

@ -518,17 +518,20 @@ Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table,
*/
bool
Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables,
Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *i_s_table,
const char *db)
{
TABLE *schema_table= tables->table;
TABLE *event_table= NULL;
TABLE *schema_table= i_s_table->table;
Open_tables_backup open_tables_backup;
TABLE_LIST event_table;
int ret= 0;
DBUG_ENTER("Event_db_repository::fill_schema_events");
DBUG_PRINT("info",("db=%s", db? db:"(null)"));
if (open_event_table(thd, TL_READ, &event_table))
event_table.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
if (open_system_tables_for_read(thd, &event_table, &open_tables_backup))
DBUG_RETURN(TRUE);
/*
@ -541,11 +544,11 @@ Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables,
every single row's `db` with the schema which we show.
*/
if (db)
ret= index_read_for_db_for_i_s(thd, schema_table, event_table, db);
ret= index_read_for_db_for_i_s(thd, schema_table, event_table.table, db);
else
ret= table_scan_all_for_i_s(thd, schema_table, event_table);
ret= table_scan_all_for_i_s(thd, schema_table, event_table.table);
close_thread_tables(thd);
close_system_tables(thd, &open_tables_backup);
DBUG_PRINT("info", ("Return code=%d", ret));
DBUG_RETURN(ret);
@ -584,10 +587,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
tables.init_one_table("mysql", 5, "event", 5, "event", lock_type);
if (open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
{
close_thread_tables(thd);
DBUG_RETURN(TRUE);
}
*table= tables.table;
tables.table->use_all_columns();
@ -700,7 +700,8 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
end:
if (table)
close_thread_tables(thd);
close_mysql_tables(thd);
thd->variables.sql_mode= saved_mode;
DBUG_RETURN(test(ret));
}
@ -811,7 +812,8 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
end:
if (table)
close_thread_tables(thd);
close_mysql_tables(thd);
thd->variables.sql_mode= saved_mode;
DBUG_RETURN(test(ret));
}
@ -865,7 +867,7 @@ Event_db_repository::drop_event(THD *thd, LEX_STRING db, LEX_STRING name,
end:
if (table)
close_thread_tables(thd);
close_mysql_tables(thd);
DBUG_RETURN(test(ret));
}
@ -933,34 +935,14 @@ Event_db_repository::find_named_event(LEX_STRING db, LEX_STRING name,
void
Event_db_repository::drop_schema_events(THD *thd, LEX_STRING schema)
{
DBUG_ENTER("Event_db_repository::drop_schema_events");
drop_events_by_field(thd, ET_FIELD_DB, schema);
DBUG_VOID_RETURN;
}
/**
Drops all events which have a specific value of a field.
@pre The thread handle has no open tables.
@param[in,out] thd Thread
@param[in,out] table mysql.event TABLE
@param[in] field Which field of the row to use for matching
@param[in] field_value The value that should match
*/
void
Event_db_repository::drop_events_by_field(THD *thd,
enum enum_events_table_field field,
LEX_STRING field_value)
{
int ret= 0;
TABLE *table= NULL;
READ_RECORD read_record_info;
DBUG_ENTER("Event_db_repository::drop_events_by_field");
DBUG_PRINT("enter", ("field=%d field_value=%s", field, field_value.str));
enum enum_events_table_field field= ET_FIELD_DB;
MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("Event_db_repository::drop_schema_events");
DBUG_PRINT("enter", ("field=%d schema=%s", field, schema.str));
if (open_event_table(thd, TL_WRITE, &table))
DBUG_VOID_RETURN;
@ -979,7 +961,7 @@ Event_db_repository::drop_events_by_field(THD *thd,
get_field(thd->mem_root,
table->field[ET_FIELD_NAME])));
if (!sortcmp_lex_string(et_field_lex, field_value, system_charset_info))
if (!sortcmp_lex_string(et_field_lex, schema, system_charset_info))
{
DBUG_PRINT("info", ("Dropping"));
if ((ret= table->file->ha_delete_row(table->record[0])))
@ -989,6 +971,11 @@ Event_db_repository::drop_events_by_field(THD *thd,
}
end_read_record(&read_record_info);
close_thread_tables(thd);
/*
Make sure to only release the MDL lock on mysql.event, not other
metadata locks DROP DATABASE might have acquired.
*/
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
DBUG_VOID_RETURN;
}
@ -1026,7 +1013,7 @@ Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname,
else if ((ret= etn->load_from_row(thd, table)))
my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "event");
close_thread_tables(thd);
close_mysql_tables(thd);
}
thd->variables.sql_mode= saved_mode;
@ -1104,7 +1091,8 @@ update_timing_fields_for_event(THD *thd,
end:
if (table)
close_thread_tables(thd);
close_mysql_tables(thd);
/* Restore the state of binlog format */
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (save_binlog_row_based)
@ -1151,7 +1139,7 @@ Event_db_repository::check_system_tables(THD *thd)
if (table_intact.check(tables.table, &mysql_db_table_def))
ret= 1;
close_thread_tables(thd);
close_mysql_tables(thd);
}
/* Check mysql.user */
tables.init_one_table("mysql", 5, "user", 4, "user", TL_READ);
@ -1171,7 +1159,7 @@ Event_db_repository::check_system_tables(THD *thd)
event_priv_column_position);
ret= 1;
}
close_thread_tables(thd);
close_mysql_tables(thd);
}
/* Check mysql.event */
tables.init_one_table("mysql", 5, "event", 5, "event", TL_READ);
@ -1185,7 +1173,7 @@ Event_db_repository::check_system_tables(THD *thd)
{
if (table_intact.check(tables.table, &event_table_def))
ret= 1;
close_thread_tables(thd);
close_mysql_tables(thd);
}
DBUG_RETURN(test(ret));

View File

@ -91,7 +91,7 @@ public:
bool
load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_basic *et);
bool
static bool
open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
bool
@ -109,9 +109,6 @@ public:
static bool
check_system_tables(THD *thd);
private:
void
drop_events_by_field(THD *thd, enum enum_events_table_field field,
LEX_STRING field_value);
bool
index_read_for_db_for_i_s(THD *thd, TABLE *schema_table, TABLE *event_table,
const char *db);

View File

@ -16,7 +16,7 @@
#include "sql_priv.h"
#include "unireg.h"
#include "sql_parse.h" // check_access
#include "sql_base.h" // close_thread_tables
#include "sql_base.h" // close_mysql_tables
#include "sql_show.h" // append_definer
#include "events.h"
#include "sql_db.h" // check_db_dir_existence
@ -754,7 +754,6 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
{
char *db= NULL;
int ret;
Open_tables_backup open_tables_backup;
DBUG_ENTER("Events::fill_schema_events");
if (check_if_system_tables_error())
@ -773,15 +772,7 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
DBUG_RETURN(1);
db= thd->lex->select_lex.db;
}
/*
Reset and backup of the currently open tables in this thread
is a way to allow SELECTs from INFORMATION_SCHEMA.events under
LOCK TABLES and in pre-locked mode. See also
Events::show_create_event for additional comments.
*/
thd->reset_n_backup_open_tables_state(&open_tables_backup);
ret= db_repository->fill_schema_events(thd, tables, db);
thd->restore_backup_open_tables_state(&open_tables_backup);
DBUG_RETURN(ret);
}
@ -1161,8 +1152,7 @@ Events::load_events_from_db(THD *thd)
end:
end_read_record(&read_record_info);
close_thread_tables(thd);
close_mysql_tables(thd);
DBUG_RETURN(ret);
}

View File

@ -5446,7 +5446,6 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
int Field_date::store(double nr)
{
longlong tmp;
int error= 0;
if (nr >= 19000000000000.0 && nr <= 99991231235959.0)
nr=floor(nr/1000000.0); // Timestamp to date
if (nr < 0.0 || nr > 99991231.0)
@ -5455,7 +5454,6 @@ int Field_date::store(double nr)
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
nr, MYSQL_TIMESTAMP_DATE);
error= 1;
}
else
tmp= (longlong) rint(nr);

View File

@ -36,6 +36,7 @@
#include "discover.h" // readfrm
#include "sql_acl.h" // wild_case_compare
#include "rpl_mi.h"
#include "transaction.h"
/*
There is an incompatibility between GNU ar and the Solaris linker
@ -7417,7 +7418,8 @@ int ndbcluster_find_files(handlerton *hton, THD *thd,
FALSE, /* drop_temporary */
FALSE, /* drop_view */
TRUE /* dont_log_query*/);
trans_commit_implicit(thd); /* Safety, should be unnecessary. */
thd->mdl_context.release_transactional_locks();
/* Clear error message that is returned when table is deleted */
thd->clear_error();
}

View File

@ -36,6 +36,7 @@
#include "lock.h" // MYSQL_LOCK_IGNORE_FLUSH,
// mysql_unlock_tables
#include "sql_parse.h" // mysql_parse
#include "transaction.h"
#ifdef ndb_dynamite
#undef assert
@ -298,13 +299,6 @@ static void run_query(THD *thd, char *buf, char *end,
thd_ndb->m_error_code,
(int) thd->is_error(), thd->is_slave_error);
}
/*
After executing statement we should unlock and close tables open
by it as well as release meta-data locks obtained by it.
*/
close_thread_tables(thd);
/*
XXX: this code is broken. mysql_parse()/mysql_reset_thd_for_next_command()
can not be called from within a statement, and
@ -2422,7 +2416,11 @@ int ndb_add_ndb_binlog_index(THD *thd, void *_row)
}
add_ndb_binlog_index_err:
thd->stmt_da->can_overwrite_status= TRUE;
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
thd->stmt_da->can_overwrite_status= FALSE;
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
ndb_binlog_index= 0;
thd->variables.option_bits= saved_options;
return error;
@ -3969,7 +3967,9 @@ restart:
{
if (ndb_binlog_index->s->needs_reopen())
{
trans_commit_stmt(thd);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
ndb_binlog_index= 0;
}
}
@ -4280,7 +4280,9 @@ restart:
if (do_ndbcluster_binlog_close_connection == BCCC_restart)
{
ndb_binlog_tables_inited= FALSE;
trans_commit_stmt(thd);
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
ndb_binlog_index= 0;
goto restart;
}
@ -4288,7 +4290,11 @@ err:
sql_print_information("Stopping Cluster Binlog");
DBUG_PRINT("info",("Shutting down cluster binlog thread"));
thd->proc_info= "Shutting down";
thd->stmt_da->can_overwrite_status= TRUE;
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
thd->stmt_da->can_overwrite_status= FALSE;
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
mysql_mutex_lock(&injector_mutex);
/* don't mess with the injector_ndb anymore from other threads */
injector_thd= 0;

View File

@ -1132,6 +1132,7 @@ int ha_commit_trans(THD *thd, bool all)
if (thd->in_sub_stmt)
{
DBUG_ASSERT(0);
/*
Since we don't support nested statement transactions in 5.0,
we can't commit or rollback stmt transactions while we are inside
@ -1146,7 +1147,6 @@ int ha_commit_trans(THD *thd, bool all)
bail out with error even before ha_commit_trans() call. To be 100% safe
let us throw error in non-debug builds.
*/
DBUG_ASSERT(0);
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
DBUG_RETURN(2);
}
@ -1329,6 +1329,7 @@ int ha_rollback_trans(THD *thd, bool all)
if (thd->in_sub_stmt)
{
DBUG_ASSERT(0);
/*
If we are inside stored function or trigger we should not commit or
rollback current statement transaction. See comment in ha_commit_trans()
@ -1336,7 +1337,6 @@ int ha_rollback_trans(THD *thd, bool all)
*/
if (!all)
DBUG_RETURN(0);
DBUG_ASSERT(0);
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
DBUG_RETURN(1);
}

View File

@ -842,6 +842,7 @@ struct THD_TRANS
bool modified_non_trans_table;
void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
bool is_empty() const { return ha_list == NULL; }
};

View File

@ -301,11 +301,10 @@ my_decimal *Item::val_decimal_from_int(my_decimal *decimal_value)
my_decimal *Item::val_decimal_from_string(my_decimal *decimal_value)
{
String *res;
char *end_ptr;
if (!(res= val_str(&str_value)))
return 0; // NULL or EOM
end_ptr= (char*) res->ptr()+ res->length();
if (!(res= val_str(&str_value)))
return NULL;
if (str2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_BAD_NUM,
res->ptr(), res->length(), res->charset(),
decimal_value) & E_DEC_BAD_NUM)

View File

@ -313,7 +313,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, uint flags)
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks +
sql_lock->lock_count,
sql_lock->lock_count,
thd->lock_id, timeout)];
&thd->lock_info, timeout)];
if (rc)
{
if (sql_lock->table_count)
@ -627,110 +627,6 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
}
/**
Find duplicate lock in tables.
Temporary tables are ignored here like they are ignored in
get_lock_data(). If we allow two opens on temporary tables later,
both functions should be checked.
@param thd The current thread.
@param needle The table to check for duplicate lock.
@param haystack The list of tables to search for the dup lock.
@note
This is mainly meant for MERGE tables in INSERT ... SELECT
situations. The 'real', underlying tables can be found only after
the MERGE tables are opened. This function assumes that the tables are
already locked.
@retval
NULL No duplicate lock found.
@retval
!NULL First table from 'haystack' that matches a lock on 'needle'.
*/
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
TABLE_LIST *haystack)
{
MYSQL_LOCK *mylock;
TABLE **lock_tables;
TABLE *table;
TABLE *table2;
THR_LOCK_DATA **lock_locks;
THR_LOCK_DATA **table_lock_data;
THR_LOCK_DATA **end_data;
THR_LOCK_DATA **lock_data2;
THR_LOCK_DATA **end_data2;
DBUG_ENTER("mysql_lock_have_duplicate");
/*
Table may not be defined for derived or view tables.
Table may not be part of a lock for delayed operations.
*/
if (! (table= needle->table) || ! table->lock_count)
goto end;
/* A temporary table does not have locks. */
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
goto end;
/* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
if (! (mylock= thd->lock))
goto end;
/* If we have less than two tables, we cannot have duplicates. */
if (mylock->table_count < 2)
goto end;
lock_locks= mylock->locks;
lock_tables= mylock->table;
/* Prepare table related variables that don't change in loop. */
DBUG_ASSERT((table->lock_position < mylock->table_count) &&
(table == lock_tables[table->lock_position]));
table_lock_data= lock_locks + table->lock_data_start;
end_data= table_lock_data + table->lock_count;
for (; haystack; haystack= haystack->next_global)
{
if (haystack->placeholder())
continue;
table2= haystack->table;
if (table2->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
continue;
/* All tables in list must be in lock. */
DBUG_ASSERT((table2->lock_position < mylock->table_count) &&
(table2 == lock_tables[table2->lock_position]));
for (lock_data2= lock_locks + table2->lock_data_start,
end_data2= lock_data2 + table2->lock_count;
lock_data2 < end_data2;
lock_data2++)
{
THR_LOCK_DATA **lock_data;
THR_LOCK *lock2= (*lock_data2)->lock;
for (lock_data= table_lock_data;
lock_data < end_data;
lock_data++)
{
if ((*lock_data)->lock == lock2)
{
DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name));
DBUG_RETURN(haystack);
}
}
}
}
end:
DBUG_PRINT("info", ("no duplicate found"));
DBUG_RETURN(NULL);
}
/** Unlock a set of external. */
static int unlock_external(THD *thd, TABLE **table,uint count)
@ -851,62 +747,48 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
}
/*****************************************************************************
Lock table based on the name.
This is used when we need total access to a closed, not open table
*****************************************************************************/
/**
Obtain exclusive metadata locks on the list of tables.
Obtain an exclusive metadata lock on a schema name.
@param thd Thread handle
@param table_list List of tables to lock
@param thd Thread handle.
@param db The database name.
@note This function assumes that no metadata locks were acquired
before calling it. Also it cannot be called while holding
LOCK_open mutex. Both these invariants are enforced by asserts
in MDL_context::acquire_locks().
@note Initialization of MDL_request members of TABLE_LIST elements
is a responsibility of the caller.
This function cannot be called while holding LOCK_open mutex.
To avoid deadlocks, we do not try to obtain exclusive metadata
locks in LOCK TABLES mode, since in this mode there may be
other metadata locks already taken by the current connection,
and we must not wait for MDL locks while holding locks.
@retval FALSE Success.
@retval TRUE Failure (OOM or thread was killed).
@retval FALSE Success.
@retval TRUE Failure: we're in LOCK TABLES mode, or out of memory,
or this connection was killed.
*/
bool lock_table_names(THD *thd, TABLE_LIST *table_list)
bool lock_schema_name(THD *thd, const char *db)
{
MDL_request_list mdl_requests;
MDL_request global_request;
TABLE_LIST *lock_table;
MDL_request mdl_request;
if (thd->locked_tables_mode)
{
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
return TRUE;
}
global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE);
mdl_request.init(MDL_key::SCHEMA, db, "", MDL_EXCLUSIVE);
for (lock_table= table_list; lock_table; lock_table= lock_table->next_local)
mdl_requests.push_front(&lock_table->mdl_request);
mdl_requests.push_front(&mdl_request);
mdl_requests.push_front(&global_request);
if (thd->mdl_context.acquire_locks(&mdl_requests,
thd->variables.lock_wait_timeout))
return 1;
return TRUE;
return 0;
}
/**
Release all metadata locks previously obtained by lock_table_names().
@param thd Thread handle.
@note Cannot be called while holding LOCK_open mutex.
*/
void unlock_table_names(THD *thd)
{
DBUG_ENTER("unlock_table_names");
thd->mdl_context.release_transactional_locks();
DBUG_VOID_RETURN;
DEBUG_SYNC(thd, "after_wait_locked_schema_name");
return FALSE;
}
@ -941,6 +823,7 @@ bool lock_routine_name(THD *thd, bool is_function,
MDL_key::PROCEDURE);
MDL_request_list mdl_requests;
MDL_request global_request;
MDL_request schema_request;
MDL_request mdl_request;
if (thd->locked_tables_mode)
@ -954,9 +837,11 @@ bool lock_routine_name(THD *thd, bool is_function,
DEBUG_SYNC(thd, "before_wait_locked_pname");
global_request.init(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE);
schema_request.init(MDL_key::SCHEMA, db, "", MDL_INTENTION_EXCLUSIVE);
mdl_request.init(mdl_type, db, name, MDL_EXCLUSIVE);
mdl_requests.push_front(&mdl_request);
mdl_requests.push_front(&schema_request);
mdl_requests.push_front(&global_request);
if (thd->mdl_context.acquire_locks(&mdl_requests,

View File

@ -60,12 +60,9 @@ void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock);
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
TABLE_LIST *haystack);
void broadcast_refresh(void);
/* Lock based on name */
bool lock_table_names(THD *thd, TABLE_LIST *table_list);
void unlock_table_names(THD *thd);
bool lock_schema_name(THD *thd, const char *db);
/* Lock based on stored routine name */
bool lock_routine_name(THD *thd, bool is_function, const char *db,
const char *name);

View File

@ -27,7 +27,7 @@
#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
#include "sql_priv.h"
#include "log.h"
#include "sql_base.h" // close_thread_tables
#include "sql_base.h" // open_log_table
#include "sql_repl.h"
#include "sql_delete.h" // mysql_truncate
#include "sql_parse.h" // command_name
@ -5447,6 +5447,22 @@ void sql_perror(const char *message)
}
/*
Unfortunately, there seems to be no good way
to restore the original streams upon failure.
*/
static bool redirect_std_streams(const char *file)
{
if (freopen(file, "a+", stdout) && freopen(file, "a+", stderr))
{
setbuf(stderr, NULL);
return FALSE;
}
return TRUE;
}
bool flush_error_log()
{
bool result=0;
@ -5474,11 +5490,7 @@ bool flush_error_log()
setbuf(stderr, NULL);
my_delete(err_renamed, MYF(0));
my_rename(log_error_file, err_renamed, MYF(0));
if (freopen(log_error_file,"a+",stdout))
{
freopen(log_error_file,"a+",stderr);
setbuf(stderr, NULL);
}
redirect_std_streams(log_error_file);
if ((fd= my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
{
@ -5493,13 +5505,7 @@ bool flush_error_log()
result= 1;
#else
my_rename(log_error_file, err_renamed, MYF(0));
if (freopen(log_error_file,"a+",stdout))
{
FILE *reopen;
reopen= freopen(log_error_file,"a+",stderr);
setbuf(stderr, NULL);
}
else
if (redirect_std_streams(log_error_file))
result= 1;
#endif
mysql_mutex_unlock(&LOCK_error_log);
@ -5551,25 +5557,9 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
#endif /* _WIN32 */
/**
Prints a printf style message to the error log and, under NT, to the
Windows event log.
This function prints the message into a buffer and then sends that buffer
to other functions to write that message to other logging sources.
@param event_type Type of event to write (Error, Warning, or Info)
@param format Printf style format of message
@param args va_list list of arguments for the message
@returns
The function always returns 0. The return value is present in the
signature to be compatible with other logging routines, which could
return an error (e.g. logging to the log tables)
*/
#ifndef EMBEDDED_LIBRARY
static void print_buffer_to_file(enum loglevel level, const char *buffer)
static void print_buffer_to_file(enum loglevel level, const char *buffer,
size_t length)
{
time_t skr;
struct tm tm_tmp;
@ -5583,7 +5573,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer)
localtime_r(&skr, &tm_tmp);
start=&tm_tmp;
fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n",
fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %.*s\n",
start->tm_year % 100,
start->tm_mon+1,
start->tm_mday,
@ -5592,7 +5582,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer)
start->tm_sec,
(level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ?
"Warning" : "Note"),
buffer);
(int) length, buffer);
fflush(stderr);
@ -5600,7 +5590,22 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer)
DBUG_VOID_RETURN;
}
/**
Prints a printf style message to the error log and, under NT, to the
Windows event log.
This function prints the message into a buffer and then sends that buffer
to other functions to write that message to other logging sources.
@param level The level of the msg significance
@param format Printf style format of message
@param args va_list list of arguments for the message
@returns
The function always returns 0. The return value is present in the
signature to be compatible with other logging routines, which could
return an error (e.g. logging to the log tables)
*/
int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
{
char buff[1024];
@ -5608,7 +5613,7 @@ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
DBUG_ENTER("vprint_msg_to_log");
length= my_vsnprintf(buff, sizeof(buff), format, args);
print_buffer_to_file(level, buff);
print_buffer_to_file(level, buff, length);
#ifdef _WIN32
print_buffer_to_nt_eventlog(level, buff, length, sizeof(buff));
@ -5616,7 +5621,7 @@ int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
DBUG_RETURN(0);
}
#endif /*EMBEDDED_LIBRARY*/
#endif /* EMBEDDED_LIBRARY */
void sql_print_error(const char *format, ...)

View File

@ -3332,6 +3332,19 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
thd->table_map_for_update= (table_map)table_map_for_update;
thd->set_invoker(&user, &host);
/*
Flag if we need to rollback the statement transaction on
slave if it by chance succeeds.
If we expected a non-zero error code and get nothing and,
it is a concurrency issue or ignorable issue, effects
of the statement should be rolled back.
*/
if (expected_error &&
(ignored_error_code(expected_error) ||
concurrency_error_code(expected_error)))
{
thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
}
/* Execute the query (note that we bypass dispatch_command()) */
Parser_state parser_state;
if (!parser_state.init(thd, thd->query(), thd->query_length()))
@ -3340,6 +3353,8 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
log_slow_statement(thd);
}
thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
/*
Resetting the enable_slow_log thd variable.
@ -3382,7 +3397,6 @@ START SLAVE; . Query: '%s'", expected_error, thd->query());
general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
compare_errors:
/*
In the slave thread, we may sometimes execute some DROP / * 40005
TEMPORARY * / TABLE that come from parts of binlogs (likely if we
@ -3430,25 +3444,7 @@ Default database: '%s'. Query: '%s'",
DBUG_PRINT("info",("error ignored"));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
thd->killed= THD::NOT_KILLED;
/*
When an error is expected and matches the actual error the
slave does not report any error and by consequence changes
on transactional tables are not rolled back in the function
close_thread_tables(). For that reason, we explicitly roll
them back here.
*/
if (expected_error && expected_error == actual_error)
trans_rollback_stmt(thd);
}
/*
If we expected a non-zero error code and get nothing and, it is a concurrency
issue or should be ignored.
*/
else if (expected_error && !actual_error &&
(concurrency_error_code(expected_error) ||
ignored_error_code(expected_error)))
trans_rollback_stmt(thd);
/*
Other cases: mostly we expected no error and get one.
*/
@ -3516,7 +3512,6 @@ end:
thd->set_db(NULL, 0); /* will free the current database */
thd->set_query(NULL, 0);
DBUG_PRINT("info", ("end: query= 0"));
close_thread_tables(thd);
/*
As a disk space optimization, future masters will not log an event for
LAST_INSERT_ID() if that function returned 0 (and thus they will be able
@ -3719,6 +3714,7 @@ bool Start_log_event_v3::write(IO_CACHE* file)
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
{
DBUG_ENTER("Start_log_event_v3::do_apply_event");
int error= 0;
switch (binlog_version)
{
case 3:
@ -3731,7 +3727,7 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
*/
if (created)
{
close_temporary_tables(thd);
error= close_temporary_tables(thd);
cleanup_load_tmpdir();
}
else
@ -3759,7 +3755,7 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
Can distinguish, based on the value of 'created': this event was
generated at master startup.
*/
close_temporary_tables(thd);
error= close_temporary_tables(thd);
}
/*
Otherwise, can't distinguish a Start_log_event generated at
@ -3771,7 +3767,7 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
/* this case is impossible */
DBUG_RETURN(1);
}
DBUG_RETURN(0);
DBUG_RETURN(error);
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@ -4946,7 +4942,22 @@ error:
thd->catalog= 0;
thd->set_db(NULL, 0); /* will free the current database */
thd->set_query(NULL, 0);
thd->stmt_da->can_overwrite_status= TRUE;
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
thd->stmt_da->can_overwrite_status= FALSE;
close_thread_tables(thd);
/*
- If inside a multi-statement transaction,
defer the release of metadata locks until the current
transaction is either committed or rolled back. This prevents
other statements from modifying the table for the entire
duration of this transaction. This provides commit ordering
and guarantees serializability across multiple transactions.
- If in autocommit mode, or outside a transactional context,
automatically release metadata locks of the current statement.
*/
if (! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
thd->is_slave_error= 0; thd->is_fatal_error= 1;);
@ -5531,11 +5542,9 @@ int Xid_log_event::do_apply_event(Relay_log_info const *rli)
/* For a slave Xid_log_event is COMMIT */
general_log_print(thd, COM_QUERY,
"COMMIT /* implicit, from Xid_log_event */");
if (!(res= trans_commit(thd)))
{
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
}
res= trans_commit(thd); /* Automatically rolls back on error. */
thd->mdl_context.release_transactional_locks();
return res;
}
@ -7610,8 +7619,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
We should not honour --slave-skip-errors at this point as we are
having severe errors which should not be skiped.
*/
mysql_unlock_tables(thd, thd->lock);
thd->lock= 0;
thd->is_slave_error= 1;
const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
DBUG_RETURN(ERR_BAD_TABLE_DEF);

View File

@ -284,8 +284,6 @@ public:
public:
/** The key of the object (data) being protected. */
MDL_key key;
void *cached_object;
mdl_cached_object_release_hook cached_object_release_hook;
/**
Read-write lock protecting this lock context.
@ -362,8 +360,6 @@ public:
MDL_lock(const MDL_key *key_arg)
: key(key_arg),
cached_object(NULL),
cached_object_release_hook(NULL),
m_ref_usage(0),
m_ref_release(0),
m_is_destroyed(FALSE)
@ -405,14 +401,15 @@ public:
/**
An implementation of the global metadata lock. The only locking modes
which are supported at the moment are SHARED and INTENTION EXCLUSIVE.
An implementation of the scoped metadata lock. The only locking modes
which are supported at the moment are SHARED and INTENTION EXCLUSIVE
and EXCLUSIVE
*/
class MDL_global_lock : public MDL_lock
class MDL_scoped_lock : public MDL_lock
{
public:
MDL_global_lock(const MDL_key *key_arg)
MDL_scoped_lock(const MDL_key *key_arg)
: MDL_lock(key_arg)
{ }
@ -674,9 +671,6 @@ void MDL_map::remove(MDL_lock *lock)
{
uint ref_usage, ref_release;
if (lock->cached_object)
(*lock->cached_object_release_hook)(lock->cached_object);
/*
Destroy the MDL_lock object, but ensure that anyone that is
holding a reference to the object is not remaining, if so he
@ -838,7 +832,8 @@ inline MDL_lock *MDL_lock::create(const MDL_key *mdl_key)
switch (mdl_key->mdl_namespace())
{
case MDL_key::GLOBAL:
return new MDL_global_lock(mdl_key);
case MDL_key::SCHEMA:
return new MDL_scoped_lock(mdl_key);
default:
return new MDL_object_lock(mdl_key);
}
@ -886,67 +881,6 @@ uint MDL_ticket::get_deadlock_weight() const
}
/**
Helper functions and macros to be used for killable waiting in metadata
locking subsystem.
@sa THD::enter_cond()/exit_cond()/killed.
@note We can't use THD::enter_cond()/exit_cond()/killed directly here
since this will make metadata subsystem dependent on THD class
and thus prevent us from writing unit tests for it. And usage of
wrapper functions to access THD::killed/enter_cond()/exit_cond()
will probably introduce too much overhead.
*/
#define MDL_ENTER_COND(A, B, C, D) \
mdl_enter_cond(A, B, C, D, __func__, __FILE__, __LINE__)
static inline const char *mdl_enter_cond(THD *thd,
st_my_thread_var *mysys_var,
mysql_cond_t *cond,
mysql_mutex_t *mutex,
const char *calling_func,
const char *calling_file,
const unsigned int calling_line)
{
mysql_mutex_assert_owner(mutex);
mysys_var->current_mutex= mutex;
mysys_var->current_cond= cond;
DEBUG_SYNC(thd, "mdl_enter_cond");
return set_thd_proc_info(thd, "Waiting for table",
calling_func, calling_file, calling_line);
}
#define MDL_EXIT_COND(A, B, C, D) \
mdl_exit_cond(A, B, C, D, __func__, __FILE__, __LINE__)
static inline void mdl_exit_cond(THD *thd,
st_my_thread_var *mysys_var,
mysql_mutex_t *mutex,
const char* old_msg,
const char *calling_func,
const char *calling_file,
const unsigned int calling_line)
{
DBUG_ASSERT(mutex == mysys_var->current_mutex);
mysql_mutex_unlock(mutex);
mysql_mutex_lock(&mysys_var->mutex);
mysys_var->current_mutex= NULL;
mysys_var->current_cond= NULL;
mysql_mutex_unlock(&mysys_var->mutex);
DEBUG_SYNC(thd, "mdl_exit_cond");
(void) set_thd_proc_info(thd, old_msg, calling_func,
calling_file, calling_line);
}
/** Construct an empty wait slot. */
MDL_wait::MDL_wait()
@ -1026,15 +960,14 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout,
{
const char *old_msg;
enum_wait_status result;
st_my_thread_var *mysys_var= my_thread_var;
int wait_result= 0;
mysql_mutex_lock(&m_LOCK_wait_status);
old_msg= MDL_ENTER_COND(thd, mysys_var, &m_COND_wait_status,
&m_LOCK_wait_status);
old_msg= thd_enter_cond(thd, &m_COND_wait_status, &m_LOCK_wait_status,
"Waiting for table");
while (!m_wait_status && !mysys_var->abort &&
while (!m_wait_status && !thd_killed(thd) &&
wait_result != ETIMEDOUT && wait_result != ETIME)
wait_result= mysql_cond_timedwait(&m_COND_wait_status, &m_LOCK_wait_status,
abs_timeout);
@ -1053,14 +986,14 @@ MDL_wait::timed_wait(THD *thd, struct timespec *abs_timeout,
false, which means that the caller intends to restart the
wait.
*/
if (mysys_var->abort)
if (thd_killed(thd))
m_wait_status= KILLED;
else if (set_status_on_timeout)
m_wait_status= TIMEOUT;
}
result= m_wait_status;
MDL_EXIT_COND(thd, mysys_var, &m_LOCK_wait_status, old_msg);
thd_exit_cond(thd, old_msg);
return result;
}
@ -1181,11 +1114,6 @@ void MDL_lock::reschedule_waiters()
*/
m_waiting.remove_ticket(ticket);
m_granted.add_ticket(ticket);
/* If we are granting an X lock, release the cached object. */
if (ticket->get_type() == MDL_EXCLUSIVE && cached_object)
(*cached_object_release_hook)(cached_object);
cached_object= NULL;
}
/*
If we could not update the wait slot of the waiter,
@ -1201,61 +1129,66 @@ void MDL_lock::reschedule_waiters()
/**
Compatibility (or rather "incompatibility") matrices for global metadata
Compatibility (or rather "incompatibility") matrices for scoped metadata
lock. Arrays of bitmaps which elements specify which granted/waiting locks
are incompatible with type of lock being requested.
Here is how types of individual locks are translated to type of global lock:
Here is how types of individual locks are translated to type of scoped lock:
----------------+-------------+
Type of request | Correspond. |
for indiv. lock | global lock |
for indiv. lock | scoped lock |
----------------+-------------+
S, SH, SR, SW | IS |
SNW, SNRW, X | IX |
SNW, SNRW -> X | IX (*) |
The first array specifies if particular type of request can be satisfied
if there is granted global lock of certain type.
if there is granted scoped lock of certain type.
| Type of active |
Request | global lock |
type | IS(**) IX S |
---------+----------------+
IS | + + + |
IX | + + - |
S | + - + |
| Type of active |
Request | scoped lock |
type | IS(**) IX S X |
---------+------------------+
IS | + + + + |
IX | + + - - |
S | + - + - |
X | + - - - |
The second array specifies if particular type of request can be satisfied
if there is already waiting request for the global lock of certain type.
if there is already waiting request for the scoped lock of certain type.
I.e. it specifies what is the priority of different lock types.
| Pending |
Request | global lock |
type | IS(**) IX S |
---------+--------------+
IS | + + + |
IX | + + - |
S | + + + |
| Pending |
Request | scoped lock |
type | IS(**) IX S X |
---------+-----------------+
IS | + + + + |
IX | + + - - |
S | + + + - |
X | + + + + |
Here: "+" -- means that request can be satisfied
"-" -- means that request can't be satisfied and should wait
(*) Since for upgradable locks we always take intention exclusive global
(*) Since for upgradable locks we always take intention exclusive scoped
lock at the same time when obtaining the shared lock, there is no
need to obtain such lock during the upgrade itself.
(**) Since intention shared global locks are compatible with all other
(**) Since intention shared scoped locks are compatible with all other
type of locks we don't even have any accounting for them.
*/
const MDL_lock::bitmap_t MDL_global_lock::m_granted_incompatible[MDL_TYPE_END] =
const MDL_lock::bitmap_t MDL_scoped_lock::m_granted_incompatible[MDL_TYPE_END] =
{
MDL_BIT(MDL_SHARED), MDL_BIT(MDL_INTENTION_EXCLUSIVE), 0, 0, 0, 0, 0, 0
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_INTENTION_EXCLUSIVE), 0, 0, 0, 0, 0,
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED) | MDL_BIT(MDL_INTENTION_EXCLUSIVE)
};
const MDL_lock::bitmap_t MDL_global_lock::m_waiting_incompatible[MDL_TYPE_END] =
const MDL_lock::bitmap_t MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END] =
{
MDL_BIT(MDL_SHARED), 0, 0, 0, 0, 0, 0, 0
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
MDL_BIT(MDL_EXCLUSIVE), 0, 0, 0, 0, 0, 0
};
@ -1655,10 +1588,6 @@ MDL_context::try_acquire_lock_impl(MDL_request *mdl_request,
{
lock->m_granted.add_ticket(ticket);
if (mdl_request->type == MDL_EXCLUSIVE && lock->cached_object)
(*lock->cached_object_release_hook)(lock->cached_object);
lock->cached_object= NULL;
mysql_prlock_unlock(&lock->m_rwlock);
m_tickets.push_front(ticket);
@ -1894,7 +1823,7 @@ extern "C" int mdl_request_ptr_cmp(const void* ptr1, const void* ptr2)
@note The list of requests should not contain non-exclusive lock requests.
There should not be any acquired locks in the context.
@note Assumes that one already owns global intention exclusive lock.
@note Assumes that one already owns scoped intention exclusive lock.
@retval FALSE Success
@retval TRUE Failure
@ -1911,13 +1840,6 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests,
if (req_count == 0)
return FALSE;
/*
To reduce deadlocks, the server acquires all exclusive
locks at once. For shared locks, try_acquire_lock() is
used instead.
*/
DBUG_ASSERT(m_tickets.is_empty() || m_tickets.front() == m_trans_sentinel);
/* Sort requests according to MDL_key. */
if (! (sort_buf= (MDL_request **)my_malloc(req_count *
sizeof(MDL_request*),
@ -2433,69 +2355,6 @@ bool MDL_ticket::has_pending_conflicting_lock() const
}
/**
Associate pointer to an opaque object with a lock.
@param cached_object Pointer to the object
@param release_hook Cleanup function to be called when MDL subsystem
decides to remove lock or associate another object.
This is used to cache a pointer to TABLE_SHARE in the lock
structure. Such caching can save one acquisition of LOCK_open
and one table definition cache lookup for every table.
Since the pointer may be stored only inside an acquired lock,
the caching is only effective when there is more than one lock
granted on a given table.
This function has the following usage pattern:
- try to acquire an MDL lock
- when done, call for mdl_get_cached_object(). If it returns NULL, our
thread has the only lock on this table.
- look up TABLE_SHARE in the table definition cache
- call mdl_set_cache_object() to assign the share to the opaque pointer.
The release hook is invoked when the last shared metadata
lock on this name is released.
*/
void
MDL_ticket::set_cached_object(void *cached_object,
mdl_cached_object_release_hook release_hook)
{
DBUG_ENTER("mdl_set_cached_object");
DBUG_PRINT("enter", ("db=%s name=%s cached_object=%p",
m_lock->key.db_name(), m_lock->key.name(),
cached_object));
/*
TODO: This assumption works now since we do get_cached_object()
and set_cached_object() in the same critical section. Once
this becomes false we will have to call release_hook here and
use additional mutex protecting 'cached_object' member.
*/
DBUG_ASSERT(!m_lock->cached_object);
m_lock->cached_object= cached_object;
m_lock->cached_object_release_hook= release_hook;
DBUG_VOID_RETURN;
}
/**
Get a pointer to an opaque object that associated with the lock.
@param ticket Lock ticket for the lock which the object is associated to.
@return Pointer to an opaque object associated with the lock.
*/
void *MDL_ticket::get_cached_object()
{
return m_lock->cached_object;
}
/**
Releases metadata locks that were acquired after a specific savepoint.

View File

@ -40,15 +40,16 @@ class Deadlock_detection_visitor;
Type of metadata lock request.
@sa Comments for MDL_object_lock::can_grant_lock() and
MDL_global_lock::can_grant_lock() for details.
MDL_scoped_lock::can_grant_lock() for details.
*/
enum enum_mdl_type {
/*
An intention exclusive metadata lock. Used only for global locks.
An intention exclusive metadata lock. Used only for scoped locks.
Owner of this type of lock can acquire upgradable exclusive locks on
individual objects.
Compatible with other IX locks, but is incompatible with global S lock.
Compatible with other IX locks, but is incompatible with scoped S and
X locks.
*/
MDL_INTENTION_EXCLUSIVE= 0,
/*
@ -179,6 +180,7 @@ public:
MDL_key is also used outside of the MDL subsystem.
*/
enum enum_mdl_namespace { GLOBAL=0,
SCHEMA,
TABLE,
FUNCTION,
PROCEDURE,
@ -396,9 +398,6 @@ public:
public:
bool has_pending_conflicting_lock() const;
void *get_cached_object();
void set_cached_object(void *cached_object,
mdl_cached_object_release_hook release_hook);
MDL_context *get_ctx() const { return m_ctx; }
bool is_upgradable_or_exclusive() const
{
@ -646,6 +645,8 @@ private:
closes all open HANDLERs.
However, one can open a few HANDLERs after entering the
read only mode.
* LOCK TABLES locks include intention exclusive locks on
involved schemas.
*/
Ticket_list m_tickets;
/**
@ -720,10 +721,10 @@ void mdl_destroy();
extern bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use,
bool needs_thr_lock_abort);
extern "C" const char *set_thd_proc_info(void *thd_arg, const char *info,
const char *calling_function,
const char *calling_file,
const unsigned int calling_line);
extern "C" const char* thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond,
mysql_mutex_t *mutex, const char *msg);
extern "C" void thd_exit_cond(MYSQL_THD thd, const char *old_msg);
#ifndef DBUG_OFF
extern mysql_mutex_t LOCK_open;
#endif

View File

@ -27,8 +27,8 @@
// reset_status_vars
#include "strfunc.h" // find_set_from_flags
#include "parse_file.h" // File_parser_dummy_hook
#include "sql_db.h" // my_database_names_free,
// my_database_names_init
#include "sql_db.h" // my_dboptions_cache_free
// my_dboptions_cache_init
#include "sql_table.h" // release_ddl_log, execute_ddl_log_recovery
#include "sql_connect.h" // free_max_user_conn, init_max_user_conn,
// handle_one_connection
@ -183,7 +183,7 @@ typedef fp_except fp_except_t;
# define fpu_control_t unsigned int
# define _FPU_EXTENDED 0x300
# define _FPU_DOUBLE 0x200
# if defined(__GNUC__) || defined(__SUNPRO_CC)
# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
# define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
# define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
# else
@ -601,7 +601,7 @@ SHOW_COMP_OPTION have_profiling;
pthread_key(MEM_ROOT**,THR_MALLOC);
pthread_key(THD*, THR_THD);
mysql_mutex_t LOCK_thread_count;
mysql_mutex_t LOCK_mysql_create_db, LOCK_open,
mysql_mutex_t LOCK_open,
LOCK_status, LOCK_global_read_lock,
LOCK_error_log, LOCK_uuid_generator,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
@ -1420,7 +1420,7 @@ void clean_up(bool print_message)
bitmap_free(&slave_error_mask);
#endif
my_tz_free();
my_database_names_free();
my_dboptions_cache_free();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
servers_free(1);
acl_free(1);
@ -1525,8 +1525,6 @@ static void wait_for_signal_thread_to_end()
static void clean_up_mutexes()
{
mysql_mutex_destroy(&LOCK_mysql_create_db);
mysql_mutex_destroy(&LOCK_lock_db);
mysql_rwlock_destroy(&LOCK_grant);
mysql_mutex_destroy(&LOCK_open);
mysql_mutex_destroy(&LOCK_thread_count);
@ -3445,7 +3443,7 @@ static int init_common_variables()
use_temp_pool= 0;
#endif
if (my_database_names_init())
if (my_dboptions_cache_init())
return 1;
/*
@ -3502,9 +3500,6 @@ You should consider changing lower_case_table_names to 1 or 2",
static int init_thread_environment()
{
mysql_mutex_init(key_LOCK_mysql_create_db,
&LOCK_mysql_create_db, MY_MUTEX_INIT_SLOW);
mysql_mutex_init(key_LOCK_lock_db, &LOCK_lock_db, MY_MUTEX_INIT_SLOW);
mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_thread_count, &LOCK_thread_count, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST);
@ -3703,7 +3698,6 @@ static void end_ssl()
static int init_server_components()
{
FILE *reopen;
DBUG_ENTER("init_server_components");
/*
We need to call each of these following functions to ensure that
@ -3751,8 +3745,8 @@ static int init_server_components()
if (freopen(log_error_file, "a+", stdout))
#endif
{
reopen= freopen(log_error_file, "a+", stderr);
setbuf(stderr, NULL);
if (freopen(log_error_file, "a+", stderr))
setbuf(stderr, NULL);
}
}
}
@ -6967,7 +6961,7 @@ mysqld_get_one_option(int optid,
*val= 0;
val+= 2;
while (*val && my_isspace(mysqld_charset, *val))
*val++;
val++;
if (!*val)
{
sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
@ -7685,8 +7679,8 @@ PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
key_LOCK_gdl, key_LOCK_global_read_lock, key_LOCK_global_system_variables,
key_LOCK_lock_db, key_LOCK_manager,
key_LOCK_mysql_create_db, key_LOCK_open, key_LOCK_prepared_stmt_count,
key_LOCK_manager,
key_LOCK_open, key_LOCK_prepared_stmt_count,
key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status,
key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data,
key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log,
@ -7724,9 +7718,7 @@ static PSI_mutex_info all_server_mutexes[]=
{ &key_LOCK_gdl, "LOCK_gdl", PSI_FLAG_GLOBAL},
{ &key_LOCK_global_read_lock, "LOCK_global_read_lock", PSI_FLAG_GLOBAL},
{ &key_LOCK_global_system_variables, "LOCK_global_system_variables", PSI_FLAG_GLOBAL},
{ &key_LOCK_lock_db, "LOCK_lock_db", PSI_FLAG_GLOBAL},
{ &key_LOCK_manager, "LOCK_manager", PSI_FLAG_GLOBAL},
{ &key_LOCK_mysql_create_db, "LOCK_mysql_create_db", PSI_FLAG_GLOBAL},
{ &key_LOCK_open, "LOCK_open", PSI_FLAG_GLOBAL},
{ &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL},
{ &key_LOCK_rpl_status, "LOCK_rpl_status", PSI_FLAG_GLOBAL},

View File

@ -228,8 +228,8 @@ extern PSI_mutex_key key_BINLOG_LOCK_index, key_BINLOG_LOCK_prep_xids,
key_LOCK_connection_count, key_LOCK_crypt, key_LOCK_delayed_create,
key_LOCK_delayed_insert, key_LOCK_delayed_status, key_LOCK_error_log,
key_LOCK_gdl, key_LOCK_global_read_lock, key_LOCK_global_system_variables,
key_LOCK_lock_db, key_LOCK_logger, key_LOCK_manager,
key_LOCK_mysql_create_db, key_LOCK_open, key_LOCK_prepared_stmt_count,
key_LOCK_logger, key_LOCK_manager,
key_LOCK_open, key_LOCK_prepared_stmt_count,
key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status,
key_LOCK_table_share, key_LOCK_thd_data,
key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log,
@ -316,7 +316,7 @@ extern MYSQL_PLUGIN_IMPORT key_map key_map_full; /* Should be threaded
/*
Server mutex locks and condition variables.
*/
extern mysql_mutex_t LOCK_mysql_create_db, LOCK_open, LOCK_lock_db,
extern mysql_mutex_t LOCK_open,
LOCK_user_locks, LOCK_status,
LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,

View File

@ -1535,13 +1535,11 @@ bool partition_info::set_up_charset_field_preps()
i= 0;
while ((field= *(ptr++)))
{
CHARSET_INFO *cs;
uchar *field_buf;
LINT_INIT(field_buf);
if (!field_is_partition_charset(field))
continue;
cs= ((Field_str*)field)->charset();
size= field->pack_length();
if (!(field_buf= (uchar*) sql_calloc(size)))
goto error;

View File

@ -658,7 +658,11 @@ void Protocol::end_partial_result_set(THD *thd_arg)
bool Protocol::flush()
{
#ifndef EMBEDDED_LIBRARY
return net_flush(&thd->net);
bool error;
thd->stmt_da->can_overwrite_status= TRUE;
error= net_flush(&thd->net);
thd->stmt_da->can_overwrite_status= FALSE;
return error;
#else
return 0;
#endif
@ -698,7 +702,8 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
if (flags & SEND_NUM_ROWS)
{ // Packet with number of elements
uchar *pos= net_store_length(buff, list->elements);
(void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
if (my_net_write(&thd->net, buff, (size_t) (pos-buff)))
DBUG_RETURN(1);
}
#ifndef DBUG_OFF
@ -803,7 +808,7 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
if (flags & SEND_DEFAULTS)
item->send(&prot, &tmp); // Send default value
if (prot.write())
break; /* purecov: inspected */
DBUG_RETURN(1);
#ifndef DBUG_OFF
field_types[count++]= field.type;
#endif
@ -816,8 +821,9 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags)
to show that there is no cursor.
Send no warning information, as it will be sent at statement end.
*/
write_eof_packet(thd, &thd->net, thd->server_status,
thd->warning_info->statement_warn_count());
if (write_eof_packet(thd, &thd->net, thd->server_status,
thd->warning_info->statement_warn_count()))
DBUG_RETURN(1);
}
DBUG_RETURN(prepare_for_send(list->elements));

View File

@ -1257,7 +1257,23 @@ void Relay_log_info::clear_tables_to_lock()
void Relay_log_info::slave_close_thread_tables(THD *thd)
{
thd->stmt_da->can_overwrite_status= TRUE;
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
thd->stmt_da->can_overwrite_status= FALSE;
close_thread_tables(thd);
/*
- If inside a multi-statement transaction,
defer the release of metadata locks until the current
transaction is either committed or rolled back. This prevents
other statements from modifying the table for the entire
duration of this transaction. This provides commit ordering
and guarantees serializability across multiple transactions.
- If in autocommit mode, or outside a transactional context,
automatically release metadata locks of the current statement.
*/
if (! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
clear_tables_to_lock();
}
#endif

View File

@ -27,7 +27,6 @@
#include "mysqld.h" // lc_messages_dir
#include "sys_vars_shared.h"
#include "transaction.h"
#include "sql_base.h" // close_thread_tables
#include "sql_locale.h" // my_locale_by_number,
// my_locale_by_name
#include "strfunc.h" // find_set_from_flags, find_set

View File

@ -3032,7 +3032,6 @@ err:
change_rpl_status(RPL_ACTIVE_SLAVE,RPL_IDLE_SLAVE);
DBUG_ASSERT(thd->net.buff != 0);
net_end(&thd->net); // destructor will not free it, because net.vio is 0
close_thread_tables(thd);
mysql_mutex_lock(&LOCK_thread_count);
THD_CHECK_SENTRY(thd);
delete thd;
@ -3263,11 +3262,8 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
mysql_mutex_lock(&rli->data_lock);
if (rli->slave_skip_counter)
{
char *pos;
pos= strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1);
pos= '\0';
pos= strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1);
pos= '\0';
strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1);
strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1);
saved_log_pos= rli->group_relay_log_pos;
saved_master_log_pos= rli->group_master_log_pos;
saved_skip= rli->slave_skip_counter;

View File

@ -450,10 +450,7 @@ static TABLE *open_proc_table_for_update(THD *thd)
if (!proc_table_intact.check(table, &proc_table_def))
DBUG_RETURN(table);
close_thread_tables(thd);
DBUG_RETURN(NULL);
}
@ -856,6 +853,7 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
}
end:
thd->lex->sphead= NULL;
lex_end(thd->lex);
thd->lex= old_lex;
return ret;
@ -1159,8 +1157,6 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
done:
thd->count_cuted_fields= saved_count_cuted_fields;
thd->variables.sql_mode= saved_mode;
close_thread_tables(thd);
/* Restore the state of binlog format */
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (save_binlog_row_based)
@ -1239,8 +1235,6 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
sp_cache_flush_obsolete(spc, &sp);
}
}
close_thread_tables(thd);
/* Restore the state of binlog format */
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (save_binlog_row_based)
@ -1348,7 +1342,6 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
sp_cache_invalidate();
}
err:
close_thread_tables(thd);
/* Restore the state of binlog format */
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
if (save_binlog_row_based)
@ -1370,6 +1363,7 @@ sp_drop_db_routines(THD *thd, char *db)
TABLE *table;
int ret;
uint key_len;
MDL_ticket *mdl_savepoint= thd->mdl_context.mdl_savepoint();
DBUG_ENTER("sp_drop_db_routines");
DBUG_PRINT("enter", ("db: %s", db));
@ -1410,6 +1404,11 @@ sp_drop_db_routines(THD *thd, char *db)
table->file->ha_index_end();
close_thread_tables(thd);
/*
Make sure to only release the MDL lock on mysql.proc, not other
metadata locks DROP DATABASE might have acquired.
*/
thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
err:
DBUG_RETURN(ret);
@ -2142,6 +2141,7 @@ sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db,
newlex.current_select= NULL;
sp= sp_compile(thd, &defstr, sql_mode, creation_ctx);
*free_sp_head= 1;
thd->lex->sphead= NULL;
lex_end(thd->lex);
thd->lex= old_lex;
return sp;

View File

@ -38,6 +38,7 @@
#include "set_var.h"
#include "sql_parse.h" // cleanup_items
#include "sql_base.h" // close_thread_tables
#include "transaction.h" // trans_commit_stmt
/*
Sufficient max length of printed destinations and frame offsets (all uints).
@ -795,6 +796,7 @@ sp_head::~sp_head()
while ((lex= (LEX *)m_lex.pop()))
{
THD *thd= lex->thd;
thd->lex->sphead= NULL;
lex_end(thd->lex);
delete thd->lex;
thd->lex= lex;
@ -1995,17 +1997,24 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
arguments evaluation. If arguments evaluation required prelocking mode,
we'll leave it here.
*/
thd->lex->unit.cleanup();
if (!thd->in_sub_stmt)
{
thd->lex->unit.cleanup();
thd_proc_info(thd, "closing tables");
close_thread_tables(thd);
thd_proc_info(thd, 0);
thd->rollback_item_tree_changes();
thd->stmt_da->can_overwrite_status= TRUE;
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
thd->stmt_da->can_overwrite_status= FALSE;
}
thd_proc_info(thd, "closing tables");
close_thread_tables(thd);
thd_proc_info(thd, 0);
if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
thd->rollback_item_tree_changes();
DBUG_PRINT("info",(" %.*s: eval args done", (int) m_name.length,
m_name.str));
}
@ -2197,6 +2206,7 @@ sp_head::restore_lex(THD *thd)
merge_table_list(thd, sublex->query_tables, sublex);
if (! sublex->sp_lex_in_use)
{
sublex->sphead= NULL;
lex_end(sublex);
delete sublex;
}
@ -2806,12 +2816,27 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
DBUG_PRINT("info",("exec_core returned: %d", res));
}
m_lex->unit.cleanup();
/*
Call after unit->cleanup() to close open table
key read.
*/
if (open_tables)
{
m_lex->unit.cleanup();
/* Here we also commit or rollback the current statement. */
if (! thd->in_sub_stmt)
{
thd->stmt_da->can_overwrite_status= TRUE;
thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
thd->stmt_da->can_overwrite_status= FALSE;
}
thd_proc_info(thd, "closing tables");
close_thread_tables(thd);
thd_proc_info(thd, 0);
thd_proc_info(thd, "closing tables");
/* Here we also commit or rollback the current statement. */
close_thread_tables(thd);
thd_proc_info(thd, 0);
if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
thd->mdl_context.release_transactional_locks();
}
if (m_lex->query_tables_own_last)
{

Some files were not shown because too many files have changed in this diff Show More