Auto-merge from mysql-trunk-bugfixing.
This commit is contained in:
commit
02a0787d8d
@ -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\""
|
||||
|
@ -20,7 +20,7 @@
|
||||
EXTRA_DIST = FINISH.sh \
|
||||
SETUP.sh \
|
||||
autorun.sh \
|
||||
choose_configure.sh \
|
||||
cmake_configure.sh \
|
||||
build_mccge.sh \
|
||||
check-cpu \
|
||||
cleanup \
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -308,7 +308,7 @@
|
||||
#define USE_MB 1
|
||||
#define USE_MB_IDENT 1
|
||||
|
||||
|
||||
#cmakedefine HAVE_VALGRIND
|
||||
|
||||
/* Types we may use */
|
||||
#ifdef __APPLE__
|
||||
|
@ -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
|
||||
#--------------------------------------------------------------------
|
||||
|
14
configure.in
14
configure.in
@ -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
|
||||
|
@ -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)))
|
||||
|
@ -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)) {
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include <sys/types.h>
|
||||
typedef char my_bool;
|
||||
typedef int my_socket;
|
||||
#include "mysql_version.h"
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -27,7 +27,9 @@
|
||||
allocations - they are better served with my_malloc.
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_ABI_CHECK
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
190
mysql-test/r/merge_mmap.result
Normal file
190
mysql-test/r/merge_mmap.result
Normal 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
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
5
mysql-test/suite/innodb/r/innodb_bug52199.result
Normal file
5
mysql-test/suite/innodb/r/innodb_bug52199.result
Normal 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;
|
88
mysql-test/suite/innodb/r/innodb_bug54679.result
Normal file
88
mysql-test/suite/innodb/r/innodb_bug54679.result
Normal 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;
|
@ -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
|
||||
|
7
mysql-test/suite/innodb/t/innodb_bug52199.test
Normal file
7
mysql-test/suite/innodb/t/innodb_bug52199.test
Normal 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;
|
101
mysql-test/suite/innodb/t/innodb_bug54679.test
Normal file
101
mysql-test/suite/innodb/t/innodb_bug54679.test
Normal 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
|
@ -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
|
||||
|
@ -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";
|
||||
|
||||
|
67
mysql-test/suite/rpl/r/rpl_conditional_comments.result
Normal file
67
mysql-test/suite/rpl/r/rpl_conditional_comments.result
Normal 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;
|
@ -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;
|
||||
|
@ -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-
|
||||
|
74
mysql-test/suite/rpl/t/rpl_conditional_comments.test
Normal file
74
mysql-test/suite/rpl/t/rpl_conditional_comments.test
Normal 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;
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
1
mysql-test/t/merge_mmap-master.opt
Normal file
1
mysql-test/t/merge_mmap-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--myisam-use-mmap
|
151
mysql-test/t/merge_mmap.test
Normal file
151
mysql-test/t/merge_mmap.test
Normal 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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
###########################################################################
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
173
sql/lock.cc
173
sql/lock.cc
@ -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,
|
||||
|
@ -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);
|
||||
|
75
sql/log.cc
75
sql/log.cc
@ -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, ...)
|
||||
|
@ -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);
|
||||
|
227
sql/mdl.cc
227
sql/mdl.cc
@ -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.
|
||||
|
||||
|
21
sql/mdl.h
21
sql/mdl.h
@ -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
|
||||
|
@ -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},
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
16
sql/sp.cc
16
sql/sp.cc
@ -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;
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user