From 5e0f4e53c5902a3f5f41ec2a4dda3f6691a80230 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@macbook.gmz" <> Date: Tue, 21 Nov 2006 10:11:43 +0200 Subject: [PATCH 01/30] Bug#23556: TRUNCATE TABLE still maps to DELETE This is the 5.0 part of the fix. Currently TRUNCATE command will not call delete_all_rows() in the handler (that implements the "fast" TRUNCATE for InnoDB) when there are triggers on the table. As decided by the architecture team TRUNCATE must use "fast" TRUNCATE even when there are triggers. Thus it must ignore the triggers. Made TRUNCATE to ignore the triggers and call delete_all_rows() for all storage engines to maintain engine consistency. --- mysql-test/r/trigger.result | 25 +++++++++++++++++++++++++ mysql-test/t/trigger.test | 25 +++++++++++++++++++++++++ sql/sql_delete.cc | 6 +++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 5d643057666..54534ea5930 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1241,4 +1241,29 @@ i j 2 2 13 13 drop table t1; +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW +INSERT INTO t2 VALUES (OLD.a); +FLUSH STATUS; +TRUNCATE t1; +SHOW STATUS LIKE 'handler_delete'; +Variable_name Value +Handler_delete 0 +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +DELETE FROM t2; +FLUSH STATUS; +DELETE FROM t1; +SHOW STATUS LIKE 'handler_delete'; +Variable_name Value +Handler_delete 8 +SELECT COUNT(*) FROM t2; +COUNT(*) +8 +DROP TRIGGER trg_t1; +DROP TABLE t1,t2; End of 5.0 tests diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 92320648033..dd3293b815f 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -1498,5 +1498,30 @@ update t1 set i= i+ 10 where j > 2; select * from t1; drop table t1; +# +# Bug#23556 TRUNCATE TABLE still maps to DELETE +# +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); + +CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW + INSERT INTO t2 VALUES (OLD.a); + +FLUSH STATUS; +TRUNCATE t1; +SHOW STATUS LIKE 'handler_delete'; +SELECT COUNT(*) FROM t2; + +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +DELETE FROM t2; + +FLUSH STATUS; +DELETE FROM t1; +SHOW STATUS LIKE 'handler_delete'; +SELECT COUNT(*) FROM t2; + +DROP TRIGGER trg_t1; +DROP TABLE t1,t2; --echo End of 5.0 tests diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index e13e7728708..0d47c2a2623 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -76,10 +76,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, Test if the user wants to delete all rows and deletion doesn't have any side-effects (because of triggers), so we can use optimized handler::delete_all_rows() method. + We implement fast TRUNCATE for InnoDB even if triggers are present. + TRUNCATE ignores triggers. */ if (!using_limit && const_cond && (!conds || conds->val_int()) && !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && - !(table->triggers && table->triggers->has_delete_triggers())) + (thd->lex->sql_command == SQLCOM_TRUNCATE || + !(table->triggers && table->triggers->has_delete_triggers())) + ) { deleted= table->file->records; if (!(error=table->file->delete_all_rows())) From ff58749b290dc8f5f8e78ce7b5a73d7efecc610a Mon Sep 17 00:00:00 2001 From: "jani@a88-113-38-195.elisa-laajakaista.fi" <> Date: Mon, 22 Jan 2007 02:32:07 +0200 Subject: [PATCH 02/30] Fix for configure to detect library correctly. Fix to check library in use during runtime. Fix for Bug#16995, "idle connections not being killed due to timeout when NPTL is used". --- BUILD/SETUP.sh | 4 +- configure.in | 161 ++++++++++++++++++++++++++----------------- include/my_global.h | 7 +- include/my_pthread.h | 41 ++++++++--- include/thr_alarm.h | 5 -- mysys/my_pthread.c | 4 +- mysys/thr_alarm.c | 93 +++++++++++-------------- sql/mysqld.cc | 53 +++++++++----- 8 files changed, 216 insertions(+), 152 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 150f9e28b41..779d0f1c660 100644 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -39,8 +39,8 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch c_warnings="$global_warnings -Wunused" cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" -alpha_cflags="-mcpu=ev6 -Wa,-mev6" # Not used yet -pentium_cflags="-mcpu=pentiumpro" +#alpha_cflags="-mcpu=ev6 -Wa,-mev6" # Not used yet +#pentium_cflags="-mcpu=pentiumpro" sparc_cflags="" # be as fast as we can be without losing our ability to backtrace diff --git a/configure.in b/configure.in index a59f1e30ab2..10f8ca37a4b 100644 --- a/configure.in +++ b/configure.in @@ -388,15 +388,16 @@ AC_MSG_CHECKING("if we should use 'skip-locking' as default for $target_os") if expr "$target_os" : "[[Ll]]inux.*" > /dev/null then MYSQLD_DEFAULT_SWITCHES="--skip-locking" - IS_LINUX="true" + TARGET_LINUX="true" AC_MSG_RESULT("yes"); + AC_DEFINE([TARGET_OS_LINUX], [1], [Whether we build for Linux]) else MYSQLD_DEFAULT_SWITCHES="" - IS_LINUX="false" + TARGET_LINUX="false" AC_MSG_RESULT("no"); fi AC_SUBST(MYSQLD_DEFAULT_SWITCHES) -AC_SUBST(IS_LINUX) +AC_SUBST(TARGET_LINUX) dnl Find paths to some shell programs AC_PATH_PROG(LN, ln, ln) @@ -576,7 +577,7 @@ AC_SUBST(NOINST_LDFLAGS) # (this is true on the MySQL build machines to avoid NSS problems) # -if test "$IS_LINUX" = "true" -a "$static_nss" = "" +if test "$TARGET_LINUX" = "true" -a "$static_nss" = "" then tmp=`nm /usr/lib/libc.a | grep _nss_files_getaliasent_r` if test -n "$tmp" @@ -827,7 +828,7 @@ struct request_info *req; ]) AC_SUBST(WRAPLIBS) -if test "$IS_LINUX" = "true"; then +if test "$TARGET_LINUX" = "true"; then AC_MSG_CHECKING([for atomic operations]) AC_LANG_SAVE @@ -870,7 +871,7 @@ int main() [ USE_PSTACK=no ]) pstack_libs= pstack_dirs= - if test "$USE_PSTACK" = yes -a "$IS_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" -a "$with_mit_threads" = "no" + if test "$USE_PSTACK" = yes -a "$TARGET_LINUX" = "true" -a "$BASE_MACHINE_TYPE" = "i386" -a "$with_mit_threads" = "no" then have_libiberty= have_libbfd= my_save_LIBS="$LIBS" @@ -1239,63 +1240,98 @@ with_posix_threads="no" # Hack for DEC-UNIX (OSF1) if test "$with_named_thread" = "no" -a "$with_mit_threads" = "no" then - # Look for LinuxThreads. - AC_MSG_CHECKING("LinuxThreads") - grepres=`grep Linuxthreads /usr/include/pthread.h 2>/dev/null | wc -l` - getconfres=`which getconf >/dev/null && getconf GNU_LIBPTHREAD_VERSION | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ |grep LINUXTHREADS | wc -l || echo 0` - if test "$grepres" -gt 0 -o "$getconfres" -gt 0 + AC_MSG_CHECKING("Linux threads") + if test "$TARGET_LINUX" = "true" then - AC_MSG_RESULT("Found") - AC_DEFINE(HAVE_LINUXTHREADS) - # Linux 2.0 sanity check - AC_TRY_COMPILE([#include ], [int a = sched_get_priority_min(1);], , - AC_MSG_ERROR([Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file. See the Installation chapter in the Reference Manual])) - # RedHat 5.0 does not work with dynamic linking of this. -static also - # gives a speed increase in linux so it does not hurt on other systems. - with_named_thread="-lpthread" - else - AC_MSG_RESULT("Not found") - # If this is a linux machine we should barf - AC_MSG_CHECKING("NPTL") - if test "$IS_LINUX" = "true" - then - getconfres=`which getconf >/dev/null && getconf GNU_LIBPTHREAD_VERSION | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ |grep NPTL | wc -l || echo 0` - if test "$getconfres" -gt 0 + AC_MSG_RESULT("starting") + # use getconf to check glibc contents + AC_MSG_CHECKING("getconf GNU_LIBPTHREAD_VERSION") + case `getconf GNU_LIBPTHREAD_VERSION | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` in + NPTL* ) + AC_MSG_RESULT("NPTL") + AC_DEFINE([HAVE_NPTL], [1], [NPTL threads implementation]) + with_named_thread="-lpthread" + ;; + LINUXTHREADS* ) + AC_MSG_RESULT("Linuxthreads") + AC_DEFINE([HAVE_LINUXTHREADS], [1], + [Whether we are using Xavier Leroy's LinuxThreads]) + with_named_thread="-lpthread" + ;; + * ) + AC_MSG_RESULT("unknown") + ;; + esac + if test "$with_named_thread" = "no" then - AC_DEFINE(HAVE_LINUXTHREADS) dnl All this code predates NPTL, so "have linuxthreads" is a poor name. - with_named_thread="-lpthread" - else - AC_MSG_ERROR([This is a Linux system and neither Linuxthreads nor NPTL were -found. Please install Linuxthreads or a new glibc and try -again. See the Installation chapter in the Reference Manual for -more information.]) - fi - else - AC_MSG_CHECKING("DEC threads") - if test -f /usr/shlib/libpthread.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a - then - with_named_thread="-lpthread -lmach -lexc" - CFLAGS="$CFLAGS -D_REENTRANT" - CXXFLAGS="$CXXFLAGS -D_REENTRANT" - AC_DEFINE(HAVE_DEC_THREADS) - AC_MSG_RESULT("yes") - else - AC_MSG_RESULT("no") - AC_MSG_CHECKING("DEC 3.2 threads") - if test -f /usr/shlib/libpthreads.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a - then - with_named_thread="-lpthreads -lmach -lc_r" - AC_DEFINE(HAVE_DEC_THREADS) - AC_DEFINE(HAVE_DEC_3_2_THREADS) - with_osf32_threads="yes" - MYSQLD_DEFAULT_SWITCHES="--skip-thread-priority" - AC_MSG_RESULT("yes") - else - AC_MSG_RESULT("no") + # old method, check headers + # Look for LinuxThreads. + AC_MSG_CHECKING("LinuxThreads in header file comment") + res=`grep Linuxthreads /usr/include/pthread.h 2>/dev/null | wc -l` + if test "$res" -gt 0 + then + AC_MSG_RESULT("Found") + AC_DEFINE([HAVE_LINUXTHREADS], [1], + [Whether we are using Xavier Leroy's LinuxThreads]) + # Linux 2.0 sanity check + AC_TRY_COMPILE([#include ], [int a = sched_get_priority_min(1);], , + AC_MSG_ERROR([Syntax error in sched.h. Change _P to __P in the /usr/include/sched.h file. See the Installation chapter in the Reference Manual])) + # RedHat 5.0 does not work with dynamic linking of this. -static also + # gives a speed increase in linux so it does not hurt on other systems. + with_named_thread="-lpthread" + else + AC_MSG_RESULT("Not found") + # If this is a linux machine we should barf + AC_MSG_ERROR([This is a Linux system without a working getconf, +and Linuxthreads was not found. Please install it (or a new glibc) and try again. +See the Installation chapter in the Reference Manual for more information.]) fi - fi - fi - fi + else + AC_MSG_RESULT("no need to check headers") + fi + AC_MSG_CHECKING("for pthread_create in -lpthread"); + ac_save_LIBS="$LIBS" + LIBS="$LIBS -lpthread" + AC_TRY_LINK( [#include ], + [ (void) pthread_create((pthread_t*) 0,(pthread_attr_t*) 0, 0, 0); ], + AC_MSG_RESULT("yes"), + [ AC_MSG_RESULT("no") + AC_MSG_ERROR([ +This is a Linux system claiming to support threads, either Linuxthreads or NPTL, but linking a test program failed. +Please install one of these (or a new glibc) and try again. +See the Installation chapter in the Reference Manual for more information.]) ] + ) + LIBS="$ac_save_LIBS" + else + AC_MSG_RESULT("no") + fi # "$TARGET_LINUX" +fi # "$with_named_thread" = "no" -a "$with_mit_threads" = "no" + +if test "$with_named_thread" = "no" -a "$with_mit_threads" = "no" +then + AC_MSG_CHECKING("DEC threads") + if test -f /usr/shlib/libpthread.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a + then + with_named_thread="-lpthread -lmach -lexc" + CFLAGS="$CFLAGS -D_REENTRANT" + CXXFLAGS="$CXXFLAGS -D_REENTRANT" + AC_DEFINE(HAVE_DEC_THREADS) + AC_MSG_RESULT("yes") + else + AC_MSG_RESULT("no") + AC_MSG_CHECKING("DEC 3.2 threads") + if test -f /usr/shlib/libpthreads.so -a -f /usr/lib/libmach.a -a -f /usr/ccs/lib/cmplrs/cc/libexc.a + then + with_named_thread="-lpthreads -lmach -lc_r" + AC_DEFINE(HAVE_DEC_THREADS) + AC_DEFINE(HAVE_DEC_3_2_THREADS) + with_osf32_threads="yes" + MYSQLD_DEFAULT_SWITCHES="--skip-thread-priority" + AC_MSG_RESULT("yes") + else + AC_MSG_RESULT("no") + fi + fi fi @@ -1720,7 +1756,7 @@ fi AC_SUBST(COMPILATION_COMMENT) AC_MSG_CHECKING("need of special linking flags") -if test "$IS_LINUX" = "true" -a "$ac_cv_prog_gcc" = "yes" -a "$all_is_static" != "yes" +if test "$TARGET_LINUX" = "true" -a "$ac_cv_prog_gcc" = "yes" -a "$all_is_static" != "yes" then LDFLAGS="$LDFLAGS -rdynamic" AC_MSG_RESULT("-rdynamic") @@ -1873,6 +1909,7 @@ AC_CHECK_FUNCS(alarm bmove \ tell atod memcpy memmove \ setupterm strcasecmp sighold vidattr lrand48 localtime_r \ sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \ + sigaction sigemptyset sigaddset \ pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \ pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \ pthread_attr_getstacksize pthread_key_delete \ @@ -1884,7 +1921,7 @@ CFLAGS="$ORG_CFLAGS" # Sanity check: We chould not have any fseeko symbol unless # large_file_support=yes AC_CHECK_FUNCS(fseeko, -[if test "$large_file_support" = no -a "$IS_LINUX" = "true"; +[if test "$large_file_support" = no -a "$TARGET_LINUX" = "true"; then AC_MSG_ERROR("Found fseeko symbol but large_file_support is not enabled!"); fi] diff --git a/include/my_global.h b/include/my_global.h index 37e53c65dec..e6bf9a9b840 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -97,7 +97,7 @@ /* Fix problem with S_ISLNK() on Linux */ -#if defined(HAVE_LINUXTHREADS) +#if defined(TARGET_OS_LINUX) || defined(__GLIBC__) #undef _GNU_SOURCE #define _GNU_SOURCE 1 #endif @@ -348,7 +348,10 @@ int __void__; #endif /* Define some useful general macros */ -#if !defined(max) +#if defined(__cplusplus) && defined(__GNUC__) +#define max(a, b) ((a) >? (b)) +#define min(a, b) ((a) (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) #endif diff --git a/include/my_pthread.h b/include/my_pthread.h index 7620b46e08b..e1a7ecab4ab 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -28,6 +28,14 @@ extern "C" { #endif /* __cplusplus */ +/* Thread library */ + +#define THD_LIB_OTHER 1 +#define THD_LIB_NPTL 2 +#define THD_LIB_LT 4 + +extern uint thd_lib_detected; + #if defined(__WIN__) || defined(OS2) #ifdef OS2 @@ -286,8 +294,8 @@ extern int my_pthread_create_detached; #undef HAVE_PTHREAD_RWLOCK_RDLOCK #undef HAVE_SNPRINTF -#define sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) -#define signal(A,B) pthread_signal((A),(void (*)(int)) (B)) +#define my_sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) +#define my_signal(A,B) pthread_signal((A),(void (*)(int)) (B)) #define my_pthread_attr_setprio(A,B) #endif /* defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) */ @@ -324,14 +332,27 @@ extern int my_pthread_cond_init(pthread_cond_t *mp, #if !defined(HAVE_SIGWAIT) && !defined(HAVE_mit_thread) && !defined(HAVE_rts_threads) && !defined(sigwait) && !defined(alpha_linux_port) && !defined(HAVE_NONPOSIX_SIGWAIT) && !defined(HAVE_DEC_3_2_THREADS) && !defined(_AIX) int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */ #endif -#if !defined(HAVE_SIGSET) && !defined(HAVE_mit_thread) && !defined(sigset) -#define sigset(A,B) do { struct sigaction s; sigset_t set; \ - sigemptyset(&set); \ - s.sa_handler = (B); \ - s.sa_mask = set; \ - s.sa_flags = 0; \ - sigaction((A), &s, (struct sigaction *) NULL); \ + +/* + We define my_sigset() and use that instead of the system sigset() so that + we can favor an implementation based on sigaction(). On some systems, such + as Mac OS X, sigset() results in flags such as SA_RESTART being set, and + 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 s; sigset_t set; int rc; \ + DBUG_ASSERT((A) != 0); \ + sigemptyset(&set); \ + s.sa_handler = (B); \ + s.sa_mask = set; \ + s.sa_flags = 0; \ + rc= sigaction((A), &s, (struct sigaction *) NULL); \ + DBUG_ASSERT(rc == 0); \ } while (0) +#elif defined(HAVE_SIGSET) && !defined(my_sigset) +#define my_sigset(A,B) sigset((A),(B)) +#elif !defined(my_sigset) +#define my_sigset(A,B) signal((A),(B)) #endif #ifndef my_pthread_setprio @@ -416,7 +437,7 @@ struct tm *localtime_r(const time_t *clock, struct tm *res); #undef pthread_detach_this_thread #define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); } #undef sigset -#define sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) +#define my_sigset(A,B) pthread_signal((A),(void (*)(int)) (B)) #endif #if ((defined(HAVE_PTHREAD_ATTR_CREATE) && !defined(HAVE_SIGWAIT)) || defined(HAVE_DEC_3_2_THREADS)) && !defined(HAVE_CTHREADS_WRAPPER) diff --git a/include/thr_alarm.h b/include/thr_alarm.h index 7a10d6886ce..0c26a67acf4 100644 --- a/include/thr_alarm.h +++ b/include/thr_alarm.h @@ -25,11 +25,6 @@ extern "C" { #ifndef USE_ALARM_THREAD #define USE_ONE_SIGNAL_HAND /* One must call process_alarm */ #endif -#ifdef HAVE_LINUXTHREADS -#define THR_CLIENT_ALARM SIGALRM -#else -#define THR_CLIENT_ALARM SIGUSR1 -#endif #ifdef HAVE_rts_threads #undef USE_ONE_SIGNAL_HAND #define USE_ALARM_THREAD diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index a8157cc2f91..3eaf27844b2 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -31,6 +31,8 @@ #define SCHED_POLICY SCHED_OTHER #endif +uint thd_lib_detected; + #ifndef my_pthread_setprio void my_pthread_setprio(pthread_t thread_id,int prior) { @@ -320,7 +322,7 @@ void *sigwait_thread(void *set_arg) sigaction(i, &sact, (struct sigaction*) 0); } } - sigaddset(set,THR_CLIENT_ALARM); + sigaddset(set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0); alarm_thread=pthread_self(); /* For thr_alarm */ diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 54aa4d421f6..54480b3908d 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -59,9 +59,7 @@ static void *alarm_handler(void *arg); #define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM) #endif -#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD) static sig_handler thread_alarm(int sig __attribute__((unused))); -#endif static int compare_ulong(void *not_used __attribute__((unused)), byte *a_ptr,byte* b_ptr) @@ -77,21 +75,16 @@ void init_thr_alarm(uint max_alarms) alarm_aborted=0; init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0, compare_ulong,NullS); - sigfillset(&full_signal_set); /* Neaded to block signals */ + sigfillset(&full_signal_set); /* Needed to block signals */ pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_alarm,NULL); -#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD) -#if defined(HAVE_mit_thread) - sigset(THR_CLIENT_ALARM,thread_alarm); /* int. thread system calls */ -#else +#ifndef USE_ALARM_THREAD + if (thd_lib_detected != THD_LIB_LT) +#endif { - struct sigaction sact; - sact.sa_flags = 0; - sact.sa_handler = thread_alarm; - sigaction(THR_CLIENT_ALARM, &sact, (struct sigaction*) 0); + my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, + thread_alarm); } -#endif -#endif sigemptyset(&s); sigaddset(&s, THR_SERVER_ALARM); alarm_thread=pthread_self(); @@ -109,13 +102,15 @@ void init_thr_alarm(uint max_alarms) } #elif defined(USE_ONE_SIGNAL_HAND) pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */ -#if THR_SERVER_ALARM == THR_CLIENT_ALARM - sigset(THR_CLIENT_ALARM,process_alarm); /* Linuxthreads */ - pthread_sigmask(SIG_UNBLOCK, &s, NULL); -#endif + if (thd_lib_detected == THD_LIB_LT) + { + my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, + process_alarm); /* Linuxthreads */ + pthread_sigmask(SIG_UNBLOCK, &s, NULL); + } #else + my_sigset(THR_SERVER_ALARM, process_alarm); pthread_sigmask(SIG_UNBLOCK, &s, NULL); - sigset(THR_SERVER_ALARM,process_alarm); #endif DBUG_VOID_RETURN; } @@ -163,7 +158,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) now=(ulong) time((time_t*) 0); pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); - pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */ + pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */ if (alarm_aborted > 0) { /* No signal thread */ DBUG_PRINT("info", ("alarm aborted")); @@ -249,7 +244,7 @@ void thr_end_alarm(thr_alarm_t *alarmed) if (alarm_data->malloced) my_free((gptr) alarm_data,MYF(0)); found++; -#ifndef DBUG_OFF +#ifdef DBUG_OFF break; #endif } @@ -258,10 +253,11 @@ void thr_end_alarm(thr_alarm_t *alarmed) if (!found) { if (*alarmed) - fprintf(stderr,"Warning: Didn't find alarm %lx in queue of %d alarms\n", - (long) *alarmed, alarm_queue.elements); - DBUG_PRINT("warning",("Didn't find alarm %lx in queue\n", - (long) *alarmed)); + fprintf(stderr, + "Warning: Didn't find alarm 0x%lx in queue of %d alarms\n", + (long) *alarmed, alarm_queue.elements); + DBUG_PRINT("warning",("Didn't find alarm 0x%lx in queue\n", + (long) *alarmed)); } pthread_mutex_unlock(&LOCK_alarm); pthread_sigmask(SIG_SETMASK,&old_mask,NULL); @@ -283,18 +279,18 @@ sig_handler process_alarm(int sig __attribute__((unused))) This must be first as we can't call DBUG inside an alarm for a normal thread */ -#if THR_SERVER_ALARM == THR_CLIENT_ALARM - if (!pthread_equal(pthread_self(),alarm_thread)) + if (thd_lib_detected == THD_LIB_LT && + !pthread_equal(pthread_self(),alarm_thread)) { #if defined(MAIN) && !defined(__bsdi__) - printf("thread_alarm\n"); fflush(stdout); + printf("thread_alarm in process_alarm\n"); fflush(stdout); #endif #ifdef DONT_REMEMBER_SIGNAL - sigset(THR_CLIENT_ALARM,process_alarm); /* int. thread system calls */ + my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, + process_alarm); /* int. thread system calls */ #endif return; } -#endif /* We have to do do the handling of the alarm in a sub function, @@ -310,7 +306,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) process_alarm_part2(sig); #ifndef USE_ALARM_THREAD #if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND) - sigset(THR_SERVER_ALARM,process_alarm); + my_sigset(THR_SERVER_ALARM, process_alarm); #endif pthread_mutex_unlock(&LOCK_alarm); pthread_sigmask(SIG_SETMASK,&old_mask,NULL); @@ -338,7 +334,8 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) alarm_data=(ALARM*) queue_element(&alarm_queue,i); alarm_data->alarmed=1; /* Info to thread */ if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, THR_CLIENT_ALARM)) + pthread_kill(alarm_data->thread, + thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) { #ifdef MAIN printf("Warning: pthread_kill couldn't find thread!!!\n"); @@ -362,7 +359,8 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) alarm_data->alarmed=1; /* Info to thread */ DBUG_PRINT("info",("sending signal to waiting thread")); if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, THR_CLIENT_ALARM)) + pthread_kill(alarm_data->thread, + thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) { #ifdef MAIN printf("Warning: pthread_kill couldn't find thread!!!\n"); @@ -439,16 +437,13 @@ void end_thr_alarm(my_bool free_structures) if (error == ETIME || error == ETIMEDOUT) break; /* Don't wait forever */ } - if (!alarm_queue.elements) + delete_queue(&alarm_queue); + alarm_aborted= 1; + pthread_mutex_unlock(&LOCK_alarm); + if (!alarm_thread_running) /* Safety */ { - delete_queue(&alarm_queue); - alarm_aborted= 1; - pthread_mutex_unlock(&LOCK_alarm); - if (!alarm_thread_running) /* Safety */ - { - pthread_mutex_destroy(&LOCK_alarm); - pthread_cond_destroy(&COND_alarm); - } + pthread_mutex_destroy(&LOCK_alarm); + pthread_cond_destroy(&COND_alarm); } } else @@ -505,17 +500,15 @@ void thr_alarm_info(ALARM_INFO *info) ARGSUSED */ -#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD) static sig_handler thread_alarm(int sig) { #ifdef MAIN printf("thread_alarm\n"); fflush(stdout); #endif #ifdef DONT_REMEMBER_SIGNAL - sigset(sig,thread_alarm); /* int. thread system calls */ + my_sigset(sig, thread_alarm); /* int. thread system calls */ #endif } -#endif #ifdef HAVE_TIMESPEC_TS_SEC @@ -916,7 +909,7 @@ static sig_handler print_signal_warning(int sig) printf("Warning: Got signal %d from thread %s\n",sig,my_thread_name()); fflush(stdout); #ifdef DONT_REMEMBER_SIGNAL - sigset(sig,print_signal_warning); /* int. thread system calls */ + my_sigset(sig, print_signal_warning); /* int. thread system calls */ #endif #ifndef OS2 if (sig == SIGALRM) @@ -943,9 +936,7 @@ static void *signal_hand(void *arg __attribute__((unused))) sigaddset(&set,SIGINT); sigaddset(&set,SIGQUIT); sigaddset(&set,SIGTERM); -#if THR_CLIENT_ALARM != SIGHUP sigaddset(&set,SIGHUP); -#endif #ifdef SIGTSTP sigaddset(&set,SIGTSTP); #endif @@ -957,7 +948,7 @@ static void *signal_hand(void *arg __attribute__((unused))) #endif #endif /* OS2 */ printf("server alarm: %d thread alarm: %d\n", - THR_SERVER_ALARM,THR_CLIENT_ALARM); + THR_SERVER_ALARM, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); DBUG_PRINT("info",("Starting signal and alarm handling thread")); for(;;) { @@ -1029,11 +1020,11 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) sigaddset(&set,SIGTSTP); #endif sigaddset(&set,THR_SERVER_ALARM); - sigdelset(&set,THR_CLIENT_ALARM); + sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); (void) pthread_sigmask(SIG_SETMASK,&set,NULL); #ifdef NOT_USED sigemptyset(&set); - sigaddset(&set,THR_CLIENT_ALARM); + sigaddset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0)); #endif #endif /* OS2 */ @@ -1083,8 +1074,8 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) } } pthread_mutex_unlock(&LOCK_thread_count); - end_thr_alarm(1); thr_alarm_info(&alarm_info); + end_thr_alarm(1); printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n", alarm_info.active_alarms, alarm_info.max_used_alarms, alarm_info.next_alarm_time); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 00bcdbf7132..d70fe9a1c32 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -177,12 +177,6 @@ inline void reset_floating_point_exceptions() } /* cplusplus */ -#if defined(HAVE_LINUXTHREADS) -#define THR_KILL_SIGNAL SIGINT -#else -#define THR_KILL_SIGNAL SIGUSR2 // Can't use this with LinuxThreads -#endif - #ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R #include #else @@ -505,6 +499,7 @@ static void clean_up(bool print_message); static void clean_up_mutexes(void); static int test_if_case_insensitive(const char *dir_name); static void create_pid_file(); +static uint get_thread_lib(void); /**************************************************************************** ** Code to end mysqld @@ -544,7 +539,8 @@ static void close_connections(void) DBUG_PRINT("info",("Waiting for select_thread")); #ifndef DONT_USE_THR_ALARM - if (pthread_kill(select_thread,THR_CLIENT_ALARM)) + if (pthread_kill(select_thread, + thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) break; // allready dead #endif set_timespec(abstime, 2); @@ -844,7 +840,7 @@ extern "C" sig_handler print_signal_warning(int sig) sig,my_thread_id()); } #ifdef DONT_REMEMBER_SIGNAL - sigset(sig,print_signal_warning); /* int. thread system calls */ + my_sigset(sig, print_signal_warning); /* int. thread system calls */ #endif #if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) if (sig == SIGALRM) @@ -1841,8 +1837,11 @@ static void init_signals(void) DBUG_ENTER("init_signals"); if (test_flags & TEST_SIGINT) - sigset(THR_KILL_SIGNAL,end_thread_signal); - sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called! + { + my_sigset(thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2, + end_thread_signal); + } + my_sigset(THR_SERVER_ALARM, print_signal_warning); // Should never be called! if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) { @@ -1877,7 +1876,7 @@ static void init_signals(void) #endif (void) sigemptyset(&set); #ifdef THREAD_SPECIFIC_SIGPIPE - sigset(SIGPIPE,abort_thread); + my_sigset(SIGPIPE, abort_thread); sigaddset(&set,SIGPIPE); #else (void) signal(SIGPIPE,SIG_IGN); // Can't know which thread @@ -1903,8 +1902,12 @@ static void init_signals(void) #endif sigaddset(&set,THR_SERVER_ALARM); if (test_flags & TEST_SIGINT) - sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT - sigdelset(&set,THR_CLIENT_ALARM); // For alarms + { + // May be SIGINT + sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2); + } + // For alarms + sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); sigprocmask(SIG_SETMASK,&set,NULL); pthread_sigmask(SIG_SETMASK,&set,NULL); DBUG_VOID_RETURN; @@ -1959,23 +1962,19 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) */ init_thr_alarm(max_connections + global_system_variables.max_insert_delayed_threads + 10); -#if SIGINT != THR_KILL_SIGNAL - if (test_flags & TEST_SIGINT) + if (thd_lib_detected != THD_LIB_LT && test_flags & TEST_SIGINT) { (void) sigemptyset(&set); // Setup up SIGINT for debug (void) sigaddset(&set,SIGINT); // For debugging (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); } -#endif (void) sigemptyset(&set); // Setup up SIGINT for debug #ifdef USE_ONE_SIGNAL_HAND (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms #endif #ifndef IGNORE_SIGHUP_SIGQUIT (void) sigaddset(&set,SIGQUIT); -#if THR_CLIENT_ALARM != SIGHUP (void) sigaddset(&set,SIGHUP); -#endif #endif (void) sigaddset(&set,SIGTERM); (void) sigaddset(&set,SIGTSTP); @@ -2236,8 +2235,8 @@ int main(int argc, char **argv) MY_INIT(argv[0]); // init my_sys library & pthreads tzset(); // Set tzname + thd_lib_detected= get_thread_lib(); start_time=time((time_t*) 0); - #ifdef OS2 { // fix timezone for daylight saving @@ -5549,6 +5548,22 @@ static void create_pid_file() } +static uint get_thread_lib(void) +{ + char buff[64]; + +#ifdef _CS_GNU_LIBPTHREAD_VERSION + confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff)); + + if (!strncasecmp(buff, "NPTL", 4)) + return THD_LIB_NPTL; + else if (!strncasecmp(buff, "linuxthreads", 12)) + return THD_LIB_LT; +#endif + return THD_LIB_OTHER; +} + + /***************************************************************************** Instantiate templates *****************************************************************************/ From 292ba83f409b2b0f407400c9f662ed79a13da180 Mon Sep 17 00:00:00 2001 From: "tomas@poseidon.mysql.com" <> Date: Wed, 24 Jan 2007 09:41:40 +0700 Subject: [PATCH 03/30] Bug#25668 mysqld may core if cluster disconnected - recommit in 4.1 --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index fd9a5720e3d..d16e00f4e52 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -5373,7 +5373,7 @@ ndb_get_table_statistics(ha_ndbcluster* file, bool report_error, Ndb* ndb, retry: if(report_error) { - if (file) + if (file && pTrans) { reterr= file->ndb_err(pTrans); } From fdd8410e59f5cfe8037cba321b9f9bbd3b3ea748 Mon Sep 17 00:00:00 2001 From: "df@kahlann.erinye.com" <> Date: Thu, 25 Jan 2007 08:46:07 +0100 Subject: [PATCH 04/30] BUG#25530 --with-readline fails with commercial source packages --- BUILD/SETUP.sh | 11 ++++++++++- configure.in | 17 +++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 6f3c4222ed2..7f979d765d3 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -84,7 +84,16 @@ debug_extra_cflags="-O1 -Wuninitialized" base_cxxflags="-felide-constructors -fno-exceptions -fno-rtti" amd64_cxxflags="" # If dropping '--with-big-tables', add here "-DBIG_TABLES" -base_configs="$prefix_configs --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-readline --with-big-tables" +base_configs="$prefix_configs --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-big-tables" + +if test -d "$path/../cmd-line-utils/readline" +then + base_configs="$base_configs --with-readline" +elif test -d "$path/../cmd-line-utils/libedit" +then + base_configs="$base_configs --with-libedit" +fi + static_link="--with-mysqld-ldflags=-all-static --with-client-ldflags=-all-static" amd64_configs="" alpha_configs="" # Not used yet diff --git a/configure.in b/configure.in index cf1b4b0cd32..c6a8e20fd2f 100644 --- a/configure.in +++ b/configure.in @@ -2439,6 +2439,7 @@ readline_basedir="" readline_dir="" readline_h_ln_cmd="" readline_link="" +want_to_use_readline="no" if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then # For NetWare, do not need readline @@ -2463,6 +2464,7 @@ then readline_link="\$(top_builddir)/cmd-line-utils/readline/libreadline.a" readline_h_ln_cmd="\$(LN) -s \$(top_srcdir)/cmd-line-utils/readline readline" compile_readline=yes + want_to_use_readline="yes" AC_DEFINE_UNQUOTED(USE_NEW_READLINE_INTERFACE, 1) else # Use system readline library @@ -2472,10 +2474,12 @@ else MYSQL_CHECK_NEW_RL_INTERFACE MYSQL_CHECK_READLINE_DECLARES_HIST_ENTRY AC_LANG_RESTORE - if [test "$mysql_cv_new_rl_interface" = "yes"] + if [test "$mysql_cv_new_rl_interface" = "yes"] && [test -d "./cmd-line-utils/readline"] then - # Use the new readline interface + # Use the new readline interface, but only if the package includes a bundled libreadline + # this way we avoid linking commercial source with GPL readline readline_link="-lreadline" + want_to_use_readline="yes" elif [test "$mysql_cv_libedit_interface" = "yes"]; then # Use libedit readline_link="-ledit" @@ -2485,6 +2489,15 @@ else versions of libedit or readline]) fi fi + +# if there is no readline, but we want to build with readline, we fail +if [test "$want_to_use_readline" = "yes"] && [test ! -d "./cmd-line-utils/readline"] +then + AC_MSG_ERROR([This commercially licensed MySQL source package can't + be built with libreadline. Please use --with-libedit to use + the bundled version of libedit instead.]) +fi + fi AC_SUBST(readline_dir) From 32e83a6c3d3ca07d5bac0d8b1fb4e421252488e0 Mon Sep 17 00:00:00 2001 From: "joerg@trift2." <> Date: Thu, 25 Jan 2007 17:51:21 +0100 Subject: [PATCH 05/30] For Linux systems running RHEL 4 (which includes SE-Linux), we need to provide additional files that specify some actions which are allowed to the MySQL binaries. Create a new subdirectory "supportfiles/RHEL4-SElinux" for them, and process it. This fixes bug#12676. --- configure.in | 3 +- support-files/Makefile.am | 4 +- support-files/RHEL4-SElinux/Makefile.am | 23 +++++ support-files/RHEL4-SElinux/mysql.fc | 25 +++++ support-files/RHEL4-SElinux/mysql.te | 132 ++++++++++++++++++++++++ 5 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 support-files/RHEL4-SElinux/Makefile.am create mode 100644 support-files/RHEL4-SElinux/mysql.fc create mode 100644 support-files/RHEL4-SElinux/mysql.te diff --git a/configure.in b/configure.in index e3bb541c9ec..80638e6ae98 100644 --- a/configure.in +++ b/configure.in @@ -2860,7 +2860,8 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl include/Makefile sql-bench/Makefile dnl server-tools/Makefile server-tools/instance-manager/Makefile dnl tests/Makefile Docs/Makefile support-files/Makefile dnl - support-files/MacOSX/Makefile mysql-test/Makefile dnl + support-files/MacOSX/Makefile support-files/RHEL4-SElinux/Makefile dnl + mysql-test/Makefile dnl netware/Makefile dnl include/mysql_version.h dnl cmd-line-utils/Makefile dnl diff --git a/support-files/Makefile.am b/support-files/Makefile.am index da8c25ccb1e..f2533100117 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -30,13 +30,13 @@ EXTRA_DIST = mysql.spec.sh \ MySQL-shared-compat.spec.sh \ ndb-config-2-node.ini.sh -SUBDIRS = MacOSX +SUBDIRS = MacOSX RHEL4-SElinux pkgdata_DATA = my-small.cnf \ my-medium.cnf \ my-large.cnf \ my-huge.cnf \ - my-innodb-heavy-4G.cnf \ + my-innodb-heavy-4G.cnf \ mysql-log-rotate \ binary-configure \ ndb-config-2-node.ini diff --git a/support-files/RHEL4-SElinux/Makefile.am b/support-files/RHEL4-SElinux/Makefile.am new file mode 100644 index 00000000000..52292136877 --- /dev/null +++ b/support-files/RHEL4-SElinux/Makefile.am @@ -0,0 +1,23 @@ +# Copyright (C) 2000-2001, 2003-2006 MySQL AB +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; version 2 +# of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free +# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +# MA 02111-1307, USA + +## Process this file with automake to create Makefile.in + +EXTRA_DIST = mysql.fc mysql.te + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/support-files/RHEL4-SElinux/mysql.fc b/support-files/RHEL4-SElinux/mysql.fc new file mode 100644 index 00000000000..0db0ccf6e68 --- /dev/null +++ b/support-files/RHEL4-SElinux/mysql.fc @@ -0,0 +1,25 @@ +# MySQL Database Server + +# +# /etc +# +/etc/my\.cnf -- gen_context(system_u:object_r:mysqld_etc_t,s0) +/etc/mysql(/.*)? gen_context(system_u:object_r:mysqld_etc_t,s0) + +# +# /usr +# Red Hat compatibility +/usr/libexec/mysqld -- gen_context(system_u:object_r:mysqld_exec_t,s0) + +# MySQL AB compatibility +/usr/sbin/mysqld(-max)? -- gen_context(system_u:object_r:mysqld_exec_t,s0) + +# +# /var +# +/var/lib/mysql(/.*)? gen_context(system_u:object_r:mysqld_db_t,s0) +/var/lib/mysql/mysql\.sock -s gen_context(system_u:object_r:mysqld_var_run_t,s0) + +/var/log/mysql.* -- gen_context(system_u:object_r:mysqld_log_t,s0) + +/var/run/mysqld(/.*)? gen_context(system_u:object_r:mysqld_var_run_t,s0) diff --git a/support-files/RHEL4-SElinux/mysql.te b/support-files/RHEL4-SElinux/mysql.te new file mode 100644 index 00000000000..b050fa7b1a6 --- /dev/null +++ b/support-files/RHEL4-SElinux/mysql.te @@ -0,0 +1,132 @@ + +policy_module(mysql,1.0.0) + +######################################## +# +# Declarations +# + +type mysqld_t; +type mysqld_exec_t; +init_daemon_domain(mysqld_t,mysqld_exec_t) + +type mysqld_var_run_t; +files_pid_file(mysqld_var_run_t) + +type mysqld_db_t; +files_type(mysqld_db_t) + +type mysqld_etc_t alias etc_mysqld_t; +files_config_file(mysqld_etc_t) + +type mysqld_log_t; +logging_log_file(mysqld_log_t) + +type mysqld_tmp_t; +files_tmp_file(mysqld_tmp_t) + +######################################## +# +# Local policy +# + +allow mysqld_t self:capability { dac_override setgid setuid sys_resource net_bind_service }; +dontaudit mysqld_t self:capability sys_tty_config; +allow mysqld_t self:process { setsched getsched setrlimit signal_perms rlimitinh }; +allow mysqld_t self:fifo_file { read write }; +allow mysqld_t self:unix_stream_socket create_stream_socket_perms; +allow mysqld_t self:tcp_socket create_stream_socket_perms; +allow mysqld_t self:udp_socket create_socket_perms; + +allow mysqld_t mysqld_db_t:dir create_dir_perms; +allow mysqld_t mysqld_db_t:file create_file_perms; +allow mysqld_t mysqld_db_t:lnk_file create_lnk_perms; +files_var_lib_filetrans(mysqld_t,mysqld_db_t,{ dir file }) + +allow mysqld_t mysqld_etc_t:file { getattr read }; +allow mysqld_t mysqld_etc_t:lnk_file { getattr read }; +allow mysqld_t mysqld_etc_t:dir list_dir_perms; + +allow mysqld_t mysqld_log_t:file create_file_perms; +logging_log_filetrans(mysqld_t,mysqld_log_t,file) + +allow mysqld_t mysqld_tmp_t:dir create_dir_perms; +allow mysqld_t mysqld_tmp_t:file create_file_perms; +files_tmp_filetrans(mysqld_t, mysqld_tmp_t, { file dir }) + +allow mysqld_t mysqld_var_run_t:dir rw_dir_perms; +allow mysqld_t mysqld_var_run_t:sock_file create_file_perms; +allow mysqld_t mysqld_var_run_t:file create_file_perms; +files_pid_filetrans(mysqld_t,mysqld_var_run_t,file) + +kernel_read_system_state(mysqld_t) +kernel_read_kernel_sysctls(mysqld_t) + +corenet_non_ipsec_sendrecv(mysqld_t) +corenet_tcp_sendrecv_all_if(mysqld_t) +corenet_udp_sendrecv_all_if(mysqld_t) +corenet_tcp_sendrecv_all_nodes(mysqld_t) +corenet_udp_sendrecv_all_nodes(mysqld_t) +corenet_tcp_sendrecv_all_ports(mysqld_t) +corenet_udp_sendrecv_all_ports(mysqld_t) +corenet_tcp_bind_all_nodes(mysqld_t) +corenet_tcp_bind_mysqld_port(mysqld_t) +corenet_tcp_connect_mysqld_port(mysqld_t) +corenet_sendrecv_mysqld_client_packets(mysqld_t) +corenet_sendrecv_mysqld_server_packets(mysqld_t) + +dev_read_sysfs(mysqld_t) + +fs_getattr_all_fs(mysqld_t) +fs_search_auto_mountpoints(mysqld_t) + +term_dontaudit_use_console(mysqld_t) + +domain_use_interactive_fds(mysqld_t) + +files_getattr_var_lib_dirs(mysqld_t) +files_read_etc_runtime_files(mysqld_t) +files_read_etc_files(mysqld_t) +files_read_usr_files(mysqld_t) +files_search_var_lib(mysqld_t) + +auth_use_nsswitch(mysqld_t) + +init_use_fds(mysqld_t) +init_use_script_ptys(mysqld_t) + +libs_use_ld_so(mysqld_t) +libs_use_shared_libs(mysqld_t) + +logging_send_syslog_msg(mysqld_t) + +miscfiles_read_localization(mysqld_t) + +sysnet_read_config(mysqld_t) + +userdom_dontaudit_use_unpriv_user_fds(mysqld_t) +# for /root/.my.cnf - should not be needed: +userdom_read_sysadm_home_content_files(mysqld_t) + +ifdef(`distro_redhat',` + # because Fedora has the sock_file in the database directory + type_transition mysqld_t mysqld_db_t:sock_file mysqld_var_run_t; +') + +ifdef(`targeted_policy',` + term_dontaudit_use_unallocated_ttys(mysqld_t) + term_dontaudit_use_generic_ptys(mysqld_t) + files_dontaudit_read_root_files(mysqld_t) +') + +optional_policy(` + daemontools_service_domain(mysqld_t, mysqld_exec_t) +') + +optional_policy(` + seutil_sigchld_newrole(mysqld_t) +') + +optional_policy(` + udev_read_db(mysqld_t) +') From 0b4ee9e5b8cee5af84295d76345d917788ebe294 Mon Sep 17 00:00:00 2001 From: "jani@ua141d10.elisa.omakaista.fi" <> Date: Thu, 25 Jan 2007 20:10:31 +0200 Subject: [PATCH 06/30] Cleanup of thread-type (linuxthread or NTPL) detection code Move get_thread_lib to mysys/my_pthread.c Set 'thr_client_alarm' to signal number used by thr_alarm to give alarms --- include/my_global.h | 5 +---- include/my_pthread.h | 16 ++++++++-------- include/thr_alarm.h | 2 ++ mysys/default.c | 4 ++-- mysys/my_pthread.c | 4 +++- mysys/my_thr_init.c | 20 ++++++++++++++++++++ mysys/thr_alarm.c | 26 +++++++++++++------------- sql/mysqld.cc | 34 +++++++++------------------------- 8 files changed, 58 insertions(+), 53 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index e6bf9a9b840..f0e600e386d 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -348,10 +348,7 @@ int __void__; #endif /* Define some useful general macros */ -#if defined(__cplusplus) && defined(__GNUC__) -#define max(a, b) ((a) >? (b)) -#define min(a, b) ((a) (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) #endif diff --git a/include/my_pthread.h b/include/my_pthread.h index e1a7ecab4ab..9d5e78bba44 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -28,14 +28,6 @@ extern "C" { #endif /* __cplusplus */ -/* Thread library */ - -#define THD_LIB_OTHER 1 -#define THD_LIB_NPTL 2 -#define THD_LIB_LT 4 - -extern uint thd_lib_detected; - #if defined(__WIN__) || defined(OS2) #ifdef OS2 @@ -684,6 +676,14 @@ extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); */ extern pthread_t shutdown_th, main_th, signal_th; +/* Which kind of thread library is in use */ + +#define THD_LIB_OTHER 1 +#define THD_LIB_NPTL 2 +#define THD_LIB_LT 4 + +extern uint thd_lib_detected; + /* statistics_xxx functions are for not essential statistic */ #ifndef thread_safe_increment diff --git a/include/thr_alarm.h b/include/thr_alarm.h index 0c26a67acf4..ef6aaf49f77 100644 --- a/include/thr_alarm.h +++ b/include/thr_alarm.h @@ -93,6 +93,8 @@ typedef struct st_alarm { my_bool malloced; } ALARM; +extern uint thr_client_alarm; + #define thr_alarm_init(A) (*(A))=0 #define thr_alarm_in_use(A) (*(A)!= 0) void init_thr_alarm(uint max_alarm); diff --git a/mysys/default.c b/mysys/default.c index 25e283a9650..911f516dad8 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -282,7 +282,7 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, { char **ext; - for (ext= (char**) f_extensions; *ext; *ext++) + for (ext= (char**) f_extensions; *ext; ext++) { int error; if ((error= search_default_file_with_ext(args, alloc, dir, *ext, @@ -543,7 +543,7 @@ void print_defaults(const char *conf_file, const char **groups) #endif for (dirs=default_directories ; *dirs; dirs++) { - for (ext= (char**) f_extensions; *ext; *ext++) + for (ext= (char**) f_extensions; *ext; ext++) { const char *pos; char *end; diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 3eaf27844b2..19766a2d195 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -322,7 +322,9 @@ void *sigwait_thread(void *set_arg) sigaction(i, &sact, (struct sigaction*) 0); } } - sigaddset(set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + /* Ensure that init_thr_alarm() is called */ + DBUG_ASSERT(thr_client_alarm); + sigaddset(set, thr_client_alarm); pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0); alarm_thread=pthread_self(); /* For thr_alarm */ diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 878a861bc94..51b31f78a1c 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -44,6 +44,8 @@ pthread_mutexattr_t my_fast_mutexattr; pthread_mutexattr_t my_errchk_mutexattr; #endif +static uint get_thread_lib(void); + /* initialize thread environment @@ -57,6 +59,8 @@ pthread_mutexattr_t my_errchk_mutexattr; my_bool my_thread_global_init(void) { + thd_lib_detected= get_thread_lib(); + if (pthread_key_create(&THR_KEY_mysys,0)) { fprintf(stderr,"Can't initialize threads: error %d\n",errno); @@ -276,4 +280,20 @@ const char *my_thread_name(void) } #endif /* DBUG_OFF */ + +static uint get_thread_lib(void) +{ + char buff[64]; + +#ifdef _CS_GNU_LIBPTHREAD_VERSION + confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff)); + + if (!strncasecmp(buff, "NPTL", 4)) + return THD_LIB_NPTL; + if (!strncasecmp(buff, "linuxthreads", 12)) + return THD_LIB_LT; +#endif + return THD_LIB_OTHER; +} + #endif /* THREAD */ diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 54480b3908d..8f342e269de 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -37,6 +37,7 @@ #define ETIME ETIMEDOUT #endif +uint thr_client_alarm; static int alarm_aborted=1; /* No alarm thread */ my_bool thr_alarm_inited= 0; volatile my_bool alarm_thread_running= 0; @@ -78,12 +79,15 @@ void init_thr_alarm(uint max_alarms) sigfillset(&full_signal_set); /* Needed to block signals */ pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_alarm,NULL); + if (thd_lib_detected == THD_LIB_LT) + thr_client_alarm= SIGALRM; + else + thr_client_alarm= SIGUSR1; #ifndef USE_ALARM_THREAD if (thd_lib_detected != THD_LIB_LT) #endif { - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, - thread_alarm); + my_sigset(thr_client_alarm, thread_alarm); } sigemptyset(&s); sigaddset(&s, THR_SERVER_ALARM); @@ -104,8 +108,7 @@ void init_thr_alarm(uint max_alarms) pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */ if (thd_lib_detected == THD_LIB_LT) { - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, - process_alarm); /* Linuxthreads */ + my_sigset(thr_client_alarm, process_alarm); /* Linuxthreads */ pthread_sigmask(SIG_UNBLOCK, &s, NULL); } #else @@ -286,8 +289,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) printf("thread_alarm in process_alarm\n"); fflush(stdout); #endif #ifdef DONT_REMEMBER_SIGNAL - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, - process_alarm); /* int. thread system calls */ + my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */ #endif return; } @@ -334,8 +336,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) alarm_data=(ALARM*) queue_element(&alarm_queue,i); alarm_data->alarmed=1; /* Info to thread */ if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, - thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) + pthread_kill(alarm_data->thread, thr_client_alarm)) { #ifdef MAIN printf("Warning: pthread_kill couldn't find thread!!!\n"); @@ -359,8 +360,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) alarm_data->alarmed=1; /* Info to thread */ DBUG_PRINT("info",("sending signal to waiting thread")); if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, - thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) + pthread_kill(alarm_data->thread, thr_client_alarm)) { #ifdef MAIN printf("Warning: pthread_kill couldn't find thread!!!\n"); @@ -948,7 +948,7 @@ static void *signal_hand(void *arg __attribute__((unused))) #endif #endif /* OS2 */ printf("server alarm: %d thread alarm: %d\n", - THR_SERVER_ALARM, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + THR_SERVER_ALARM, thr_client_alarm); DBUG_PRINT("info",("Starting signal and alarm handling thread")); for(;;) { @@ -1020,11 +1020,11 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) sigaddset(&set,SIGTSTP); #endif sigaddset(&set,THR_SERVER_ALARM); - sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + sigdelset(&set, thr_client_alarm); (void) pthread_sigmask(SIG_SETMASK,&set,NULL); #ifdef NOT_USED sigemptyset(&set); - sigaddset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + sigaddset(&set, thr_client_alarm); VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0)); #endif #endif /* OS2 */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d70fe9a1c32..43d76f28007 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -459,6 +459,7 @@ pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped, pthread_cond_t COND_thread_cache,COND_flush_thread_cache; pthread_t signal_thread; pthread_attr_t connection_attrib; +static uint thr_kill_signal; #ifdef __WIN__ #undef getpid @@ -499,7 +500,6 @@ static void clean_up(bool print_message); static void clean_up_mutexes(void); static int test_if_case_insensitive(const char *dir_name); static void create_pid_file(); -static uint get_thread_lib(void); /**************************************************************************** ** Code to end mysqld @@ -539,8 +539,7 @@ static void close_connections(void) DBUG_PRINT("info",("Waiting for select_thread")); #ifndef DONT_USE_THR_ALARM - if (pthread_kill(select_thread, - thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) + if (pthread_kill(select_thread, thr_client_alarm)) break; // allready dead #endif set_timespec(abstime, 2); @@ -1838,8 +1837,7 @@ static void init_signals(void) if (test_flags & TEST_SIGINT) { - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2, - end_thread_signal); + my_sigset(thr_kill_signal, end_thread_signal); } my_sigset(THR_SERVER_ALARM, print_signal_warning); // Should never be called! @@ -1904,10 +1902,10 @@ static void init_signals(void) if (test_flags & TEST_SIGINT) { // May be SIGINT - sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2); + sigdelset(&set, thr_kill_signal); } // For alarms - sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + sigdelset(&set, thr_client_alarm); sigprocmask(SIG_SETMASK,&set,NULL); pthread_sigmask(SIG_SETMASK,&set,NULL); DBUG_VOID_RETURN; @@ -1962,7 +1960,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) */ init_thr_alarm(max_connections + global_system_variables.max_insert_delayed_threads + 10); - if (thd_lib_detected != THD_LIB_LT && test_flags & TEST_SIGINT) + if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT)) { (void) sigemptyset(&set); // Setup up SIGINT for debug (void) sigaddset(&set,SIGINT); // For debugging @@ -2235,7 +2233,6 @@ int main(int argc, char **argv) MY_INIT(argv[0]); // init my_sys library & pthreads tzset(); // Set tzname - thd_lib_detected= get_thread_lib(); start_time=time((time_t*) 0); #ifdef OS2 { @@ -2253,6 +2250,9 @@ int main(int argc, char **argv) } #endif + /* Set signal used to kill MySQL */ + thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2; + /* Init mutexes for the global MYSQL_LOG objects. As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of @@ -5548,22 +5548,6 @@ static void create_pid_file() } -static uint get_thread_lib(void) -{ - char buff[64]; - -#ifdef _CS_GNU_LIBPTHREAD_VERSION - confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff)); - - if (!strncasecmp(buff, "NPTL", 4)) - return THD_LIB_NPTL; - else if (!strncasecmp(buff, "linuxthreads", 12)) - return THD_LIB_LT; -#endif - return THD_LIB_OTHER; -} - - /***************************************************************************** Instantiate templates *****************************************************************************/ From 36df33d80abb4ed946c7feee6b20205619ba3534 Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Thu, 25 Jan 2007 18:44:35 -0800 Subject: [PATCH 07/30] Fixed bug #24653. The bug report has demonstrated the following two problems. 1. If an ORDER/GROUP BY list includes a constant expression being optimized away and, at the same time, containing single-row subselects that return more that one row, no error is reported. Strictly speaking the standard allows to ignore error in this case. Yet, now a corresponding fatal error is reported in this case. 2. If a query requires sorting by expressions containing single-row subselects that, however, return more than one row, then the execution of the query may cause a server crash. To fix this some code has been added that blocks execution of a subselect item in case of a fatal error in the method Item_subselect::exec. --- mysql-test/r/subselect.result | 74 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 59 ++++++++++++++++++++++++++++ sql/filesort.cc | 6 ++- sql/item.cc | 1 + sql/item.h | 3 ++ sql/item_cmpfunc.cc | 7 ++-- sql/item_cmpfunc.h | 3 +- sql/item_func.cc | 1 + sql/item_subselect.cc | 4 ++ sql/sql_select.cc | 21 ++++++++++ 10 files changed, 174 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index a4ea8e21d61..a339a139687 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3026,3 +3026,77 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE DROP TABLE t1; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (2), (4), (1), (3); +CREATE TABLE t2 (b int, c int); +INSERT INTO t2 VALUES +(2,1), (1,3), (2,1), (4,4), (2,2), (1,4); +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 ); +a +2 +4 +1 +3 +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1); +ERROR 21000: Subquery returns more than 1 row +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a; +a +1 +2 +3 +4 +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a; +ERROR 21000: Subquery returns more than 1 row +SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2); +b MAX(c) +1 4 +2 2 +4 4 +SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1); +ERROR 21000: Subquery returns more than 1 row +SELECT a FROM t1 GROUP BY a +HAVING IFNULL((SELECT b FROM t2 WHERE b > 2), +(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; +a +1 +2 +3 +4 +SELECT a FROM t1 GROUP BY a +HAVING IFNULL((SELECT b FROM t2 WHERE b > 1), +(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; +ERROR 21000: Subquery returns more than 1 row +SELECT a FROM t1 GROUP BY a +HAVING IFNULL((SELECT b FROM t2 WHERE b > 4), +(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; +a +4 +SELECT a FROM t1 GROUP BY a +HAVING IFNULL((SELECT b FROM t2 WHERE b > 4), +(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3; +ERROR 21000: Subquery returns more than 1 row +SELECT a FROM t1 +ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2), +(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)); +a +2 +4 +1 +3 +SELECT a FROM t1 +ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1), +(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)); +ERROR 21000: Subquery returns more than 1 row +SELECT a FROM t1 +ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4), +(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)); +a +2 +1 +3 +4 +SELECT a FROM t1 +ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4), +(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)); +ERROR 21000: Subquery returns more than 1 row +DROP TABLE t1,t2; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index f816551e51f..67a18e7a30f 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1993,4 +1993,63 @@ SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL; EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL; DROP TABLE t1; + +# +# Bug 24653: sorting by expressions containing subselects +# that return more than one row +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (2), (4), (1), (3); + +CREATE TABLE t2 (b int, c int); +INSERT INTO t2 VALUES + (2,1), (1,3), (2,1), (4,4), (2,2), (1,4); + +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 ); +--error 1242 +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1); +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a; +--error 1242 +SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a; + +SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2); +--error 1242 +SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1); + + +SELECT a FROM t1 GROUP BY a + HAVING IFNULL((SELECT b FROM t2 WHERE b > 2), + (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; +--error 1242 +SELECT a FROM t1 GROUP BY a + HAVING IFNULL((SELECT b FROM t2 WHERE b > 1), + (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; + +SELECT a FROM t1 GROUP BY a + HAVING IFNULL((SELECT b FROM t2 WHERE b > 4), + (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3; +--error 1242 +SELECT a FROM t1 GROUP BY a + HAVING IFNULL((SELECT b FROM t2 WHERE b > 4), + (SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3; + +SELECT a FROM t1 + ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2), + (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)); +--error 1242 +SELECT a FROM t1 + ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1), + (SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)); + +SELECT a FROM t1 + ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4), + (SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)); +--error 1242 +SELECT a FROM t1 + ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4), + (SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)); + +DROP TABLE t1,t2; + # End of 4.1 tests diff --git a/sql/filesort.cc b/sql/filesort.cc index 63a8515020b..38a49e24263 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -387,7 +387,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, byte *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH]; my_off_t record; TABLE *sort_form; - volatile my_bool *killed= ¤t_thd->killed; + THD *thd= current_thd; + volatile my_bool *killed= &thd->killed; handler *file; DBUG_ENTER("find_all_keys"); DBUG_PRINT("info",("using: %s",(select?select->quick?"ranges":"where":"every row"))); @@ -474,6 +475,9 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, } else file->unlock_row(); + /* It does not make sense to read more keys in case of a fatal error */ + if (thd->net.report_error) + DBUG_RETURN(HA_POS_ERROR); } (void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */ if (!next_pos) diff --git a/sql/item.cc b/sql/item.cc index 1e8c70c6616..7d110ccdc25 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -47,6 +47,7 @@ Item::Item(): collation.set(&my_charset_bin, DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; + with_subselect= 0; /* Put item in free list so that we can free all items at end */ THD *thd= current_thd; diff --git a/sql/item.h b/sql/item.h index ad8bea663f1..f2136c4997a 100644 --- a/sql/item.h +++ b/sql/item.h @@ -142,6 +142,9 @@ public: my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ DTCollation collation; + my_bool with_subselect; /* If this item is a subselect or some + of its arguments is or contains a + subselect */ // alloc & destruct is done as start of select using sql_alloc Item(); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 859b4e0ecc1..91546c2282c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2139,6 +2139,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) and_tables_cache&= tmp_table_map; const_item_cache&= item->const_item(); with_sum_func= with_sum_func || item->with_sum_func; + with_subselect|= item->with_subselect; if (item->maybe_null) maybe_null=1; } @@ -2351,7 +2352,7 @@ longlong Item_func_isnull::val_int() Handle optimization if the argument can't be null This has to be here because of the test in update_used_tables(). */ - if (!used_tables_cache) + if (!used_tables_cache && !with_subselect) return cached_value; return args[0]->is_null() ? 1: 0; } @@ -2360,7 +2361,7 @@ longlong Item_is_not_null_test::val_int() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_is_not_null_test::val_int"); - if (!used_tables_cache) + if (!used_tables_cache && !with_subselect) { owner->was_null|= (!cached_value); DBUG_PRINT("info", ("cached :%d", cached_value)); @@ -2387,7 +2388,7 @@ void Item_is_not_null_test::update_used_tables() else { args[0]->update_used_tables(); - if (!(used_tables_cache=args[0]->used_tables())) + if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect) { /* Remember if the value is always NULL or never NULL */ cached_value= (longlong) !args[0]->is_null(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 0e157fd412c..4635a301c31 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -843,7 +843,8 @@ public: else { args[0]->update_used_tables(); - if ((const_item_cache= !(used_tables_cache= args[0]->used_tables()))) + if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) && + !with_subselect) { /* Remember if the value is always NULL or never NULL */ cached_value= (longlong) args[0]->is_null(); diff --git a/sql/item_func.cc b/sql/item_func.cc index 461998477b5..92ba7520642 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -177,6 +177,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) used_tables_cache|= item->used_tables(); not_null_tables_cache|= item->not_null_tables(); const_item_cache&= item->const_item(); + with_subselect|= item->with_subselect; } } fix_length_and_dec(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 20a092d7607..cdbcde8b56b 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -39,6 +39,7 @@ Item_subselect::Item_subselect(): engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1), engine_changed(0), changed(0) { + with_subselect= 1; reset(); /* item value is NULL if select_subselect not changed this value @@ -201,6 +202,9 @@ bool Item_subselect::exec() mem root */ thd->mem_root= &thd->main_mem_root; + if (thd->net.report_error) + /* Do not execute subselect in case of a fatal error */ + return 1; res= engine->exec(); thd->mem_root= old_root; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0254e8f56dc..97fa6bb7809 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -644,6 +644,13 @@ JOIN::optimize() { ORDER *org_order= order; order=remove_const(this, order,conds,1, &simple_order); + if (thd->net.report_error) + { + error= 1; + DBUG_PRINT("error",("Error from remove_const")); + DBUG_RETURN(1); + } + /* If we are using ORDER BY NULL or ORDER BY const_expression, return result in any order (even if we are using a GROUP BY) @@ -747,6 +754,12 @@ JOIN::optimize() group_list= remove_const(this, (old_group_list= group_list), conds, rollup.state == ROLLUP::STATE_NONE, &simple_group); + if (thd->net.report_error) + { + error= 1; + DBUG_PRINT("error",("Error from remove_const")); + DBUG_RETURN(1); + } if (old_group_list && !group_list) select_distinct= 0; } @@ -763,6 +776,12 @@ JOIN::optimize() { group_list= procedure->group= remove_const(this, procedure->group, conds, 1, &simple_group); + if (thd->net.report_error) + { + error= 1; + DBUG_PRINT("error",("Error from remove_const")); + DBUG_RETURN(1); + } calc_group_buffer(this, group_list); } @@ -4428,6 +4447,8 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, *simple_order=0; // Must do a temp table to sort else if (!(order_tables & not_const_tables)) { + if (order->item[0]->with_subselect) + order->item[0]->val_str(&order->item[0]->str_value); DBUG_PRINT("info",("removing: %s", order->item[0]->full_name())); continue; // skip const item } From 7740b0248e7147acdb741faa43d5dc52d3073ac7 Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Thu, 25 Jan 2007 22:50:48 -0800 Subject: [PATCH 08/30] Post merge fix --- sql/item_subselect.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 7a2d749524b..d61bb25e9b7 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -199,6 +199,8 @@ bool Item_subselect::exec() /* Do not execute subselect in case of a fatal error */ return 1; + res= engine->exec(); + if (engine_changed) { engine_changed= 0; From e897780919fff10981f123b3f4e1f754aa431518 Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Fri, 26 Jan 2007 17:10:45 -0800 Subject: [PATCH 09/30] Fixed bug #24420. Objects of the classes Item_func_is_not_null_test and Item_func_trig_cond must be transparent for the method Item::split_sum_func2 as these classes are pure helpers. It means that the method Item::split_sum_func2 should look at those objects as at pure wrappers. --- mysql-test/r/subselect3.result | 16 ++++++++++++++++ mysql-test/t/subselect3.test | 17 +++++++++++++++++ sql/item.cc | 5 ++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 07ff17c9df9..29143b9e504 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -629,3 +629,19 @@ cc NULL NULL aa 1 1 bb NULL NULL drop table t1,t2; +create table t1 (a int, b int); +insert into t1 values (0,0), (2,2), (3,3); +create table t2 (a int, b int); +insert into t2 values (1,1), (3,3); +select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1; +a b Z +0 0 0 +2 2 0 +3 3 1 +insert into t2 values (NULL,4); +select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1; +a b Z +0 0 0 +2 2 0 +3 3 1 +drop table t1,t2; diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test index 23d78721dbe..ed8480ba464 100644 --- a/mysql-test/t/subselect3.test +++ b/mysql-test/t/subselect3.test @@ -472,3 +472,20 @@ select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z drop table t1,t2; +# +# BUG#24420: row-based IN suqueries with aggregation when the left operand +# of the subquery predicate may contain NULL values +# + +create table t1 (a int, b int); +insert into t1 values (0,0), (2,2), (3,3); +create table t2 (a int, b int); +insert into t2 values (1,1), (3,3); + +select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1; + +insert into t2 values (NULL,4); +select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1; + +drop table t1,t2; + diff --git a/sql/item.cc b/sql/item.cc index 0017b64ba0d..9a55eb25e2c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1242,7 +1242,10 @@ void Item::split_sum_func2(THD *thd, Item **ref_pointer_array, if (type() == SUM_FUNC_ITEM && skip_registered && ((Item_sum *) this)->ref_by) return; - if (type() != SUM_FUNC_ITEM && with_sum_func) + if ((type() != SUM_FUNC_ITEM && with_sum_func) || + (type() == FUNC_ITEM && + (((Item_func *) this)->functype() == Item_func::ISNOTNULLTEST_FUNC || + ((Item_func *) this)->functype() == Item_func::TRIG_COND_FUNC))) { /* Will split complicated items and ignore simple ones */ split_sum_func(thd, ref_pointer_array, fields); From a7af53838aaa925cef23bb695512f399a89c8f95 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@macbook.gmz" <> Date: Tue, 30 Jan 2007 17:43:34 +0200 Subject: [PATCH 10/30] Bug #25643: SEC_TO_TIME function problem Checking for NULL before calling the val_xxx() methods only checks for such arguments that are known to be NULLs at compile time. The arguments that may or may not contain NULLs (e.g. function calls and possibly others) are not checked at all. Fixed by first calling the val_xxx() method and then checking for null in SEC_TO_TIME(). In addition QUARTER() was not returning 0 (as all the val_int() functions do when processing a NULL value). --- mysql-test/r/func_time.result | 14 ++++++++++++++ mysql-test/t/func_time.test | 12 ++++++++++++ sql/item_timefunc.cc | 9 ++++++--- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 45c05f0b5b5..32f930ca6ba 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1207,3 +1207,17 @@ SET NAMES DEFAULT; select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE NULL +CREATE TABLE t1 (a int, t1 time, t2 time, d date, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (1, '10:00:00', NULL, NULL), +(2, '11:00:00', '11:15:00', '1972-02-06'); +SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d) +FROM t1; +t1 t2 SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ) QUARTER(d) +10:00:00 NULL NULL NULL +11:00:00 11:15:00 00:15:00 1 +SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d) +FROM t1 ORDER BY a DESC; +t1 t2 SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ) QUARTER(d) +11:00:00 11:15:00 00:15:00 1 +10:00:00 NULL NULL NULL +DROP TABLE t1; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index a69cbb67c5b..1aa4b434a83 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -713,3 +713,15 @@ SET NAMES DEFAULT; # select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; + +# +# Bug #25643: SEC_TO_TIME function problem +# +CREATE TABLE t1 (a int, t1 time, t2 time, d date, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (1, '10:00:00', NULL, NULL), + (2, '11:00:00', '11:15:00', '1972-02-06'); +SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d) + FROM t1; +SELECT t1, t2, SEC_TO_TIME( TIME_TO_SEC( t2 ) - TIME_TO_SEC( t1 ) ), QUARTER(d) + FROM t1 ORDER BY a DESC; +DROP TABLE t1; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index e99db62068d..83b48645d1c 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1054,7 +1054,8 @@ longlong Item_func_quarter::val_int() { DBUG_ASSERT(fixed == 1); TIME ltime; - (void) get_arg0_date(<ime, TIME_FUZZY_DATE); + if (get_arg0_date(<ime, TIME_FUZZY_DATE)) + return 0; return (longlong) ((ltime.month+2)/3); } @@ -1668,6 +1669,7 @@ String *Item_func_sec_to_time::val_str(String *str) { DBUG_ASSERT(fixed == 1); TIME ltime; + longlong arg_val= args[0]->val_int(); if ((null_value=args[0]->null_value) || str->alloc(19)) { @@ -1675,7 +1677,7 @@ String *Item_func_sec_to_time::val_str(String *str) return (String*) 0; } - sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime); + sec_to_time(arg_val, args[0]->unsigned_flag, <ime); make_time((DATE_TIME_FORMAT *) 0, <ime, str); return str; @@ -1686,11 +1688,12 @@ longlong Item_func_sec_to_time::val_int() { DBUG_ASSERT(fixed == 1); TIME ltime; + longlong arg_val= args[0]->val_int(); if ((null_value=args[0]->null_value)) return 0; - sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime); + sec_to_time(arg_val, args[0]->unsigned_flag, <ime); return (ltime.neg ? -1 : 1) * ((ltime.hour)*10000 + ltime.minute*100 + ltime.second); From b3523e398cb3eb4b391d60183da6ce2ac959c212 Mon Sep 17 00:00:00 2001 From: "jani@ua141d10.elisa.omakaista.fi" <> Date: Tue, 30 Jan 2007 18:52:26 +0200 Subject: [PATCH 11/30] Cleanup of thread-type (linuxthread or NTPL) detection code Move get_thread_lib to mysys/my_pthread.c Set 'thr_client_alarm' to signal number used by thr_alarm to give alarms --- include/my_global.h | 5 +---- include/my_pthread.h | 17 +++++++++-------- mysys/default.c | 4 ++-- mysys/my_pthread.c | 5 ++++- mysys/my_thr_init.c | 25 +++++++++++++++++++++++++ mysys/thr_alarm.c | 21 ++++++++------------- sql/mysqld.cc | 34 +++++++++------------------------- 7 files changed, 58 insertions(+), 53 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index e6bf9a9b840..f0e600e386d 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -348,10 +348,7 @@ int __void__; #endif /* Define some useful general macros */ -#if defined(__cplusplus) && defined(__GNUC__) -#define max(a, b) ((a) >? (b)) -#define min(a, b) ((a) (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) #endif diff --git a/include/my_pthread.h b/include/my_pthread.h index e1a7ecab4ab..a336d4dc288 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -28,14 +28,6 @@ extern "C" { #endif /* __cplusplus */ -/* Thread library */ - -#define THD_LIB_OTHER 1 -#define THD_LIB_NPTL 2 -#define THD_LIB_LT 4 - -extern uint thd_lib_detected; - #if defined(__WIN__) || defined(OS2) #ifdef OS2 @@ -684,6 +676,15 @@ extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); */ extern pthread_t shutdown_th, main_th, signal_th; +/* Which kind of thread library is in use */ + +#define THD_LIB_OTHER 1 +#define THD_LIB_NPTL 2 +#define THD_LIB_LT 4 + +extern uint thd_lib_detected; +extern uint thr_client_alarm; + /* statistics_xxx functions are for not essential statistic */ #ifndef thread_safe_increment diff --git a/mysys/default.c b/mysys/default.c index 25e283a9650..911f516dad8 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -282,7 +282,7 @@ static int search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc, { char **ext; - for (ext= (char**) f_extensions; *ext; *ext++) + for (ext= (char**) f_extensions; *ext; ext++) { int error; if ((error= search_default_file_with_ext(args, alloc, dir, *ext, @@ -543,7 +543,7 @@ void print_defaults(const char *conf_file, const char **groups) #endif for (dirs=default_directories ; *dirs; dirs++) { - for (ext= (char**) f_extensions; *ext; *ext++) + for (ext= (char**) f_extensions; *ext; ext++) { const char *pos; char *end; diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 3eaf27844b2..fd716448e43 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -32,6 +32,7 @@ #endif uint thd_lib_detected; +uint thr_client_alarm; #ifndef my_pthread_setprio void my_pthread_setprio(pthread_t thread_id,int prior) @@ -322,7 +323,9 @@ void *sigwait_thread(void *set_arg) sigaction(i, &sact, (struct sigaction*) 0); } } - sigaddset(set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + /* Ensure that init_thr_alarm() is called */ + DBUG_ASSERT(thr_client_alarm); + sigaddset(set, thr_client_alarm); pthread_sigmask(SIG_UNBLOCK,(sigset_t*) set,(sigset_t*) 0); alarm_thread=pthread_self(); /* For thr_alarm */ diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 878a861bc94..5729f27b7a7 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -21,6 +21,7 @@ #include "mysys_priv.h" #include +#include #ifdef THREAD #ifdef USE_TLS @@ -44,6 +45,8 @@ pthread_mutexattr_t my_fast_mutexattr; pthread_mutexattr_t my_errchk_mutexattr; #endif +static uint get_thread_lib(void); + /* initialize thread environment @@ -57,6 +60,12 @@ pthread_mutexattr_t my_errchk_mutexattr; my_bool my_thread_global_init(void) { + thd_lib_detected= get_thread_lib(); + if (thd_lib_detected == THD_LIB_LT) + thr_client_alarm= SIGALRM; + else + thr_client_alarm= SIGUSR1; + if (pthread_key_create(&THR_KEY_mysys,0)) { fprintf(stderr,"Can't initialize threads: error %d\n",errno); @@ -276,4 +285,20 @@ const char *my_thread_name(void) } #endif /* DBUG_OFF */ + +static uint get_thread_lib(void) +{ + char buff[64]; + +#ifdef _CS_GNU_LIBPTHREAD_VERSION + confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff)); + + if (!strncasecmp(buff, "NPTL", 4)) + return THD_LIB_NPTL; + if (!strncasecmp(buff, "linuxthreads", 12)) + return THD_LIB_LT; +#endif + return THD_LIB_OTHER; +} + #endif /* THREAD */ diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 54480b3908d..fd1e48d730a 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -82,8 +82,7 @@ void init_thr_alarm(uint max_alarms) if (thd_lib_detected != THD_LIB_LT) #endif { - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, - thread_alarm); + my_sigset(thr_client_alarm, thread_alarm); } sigemptyset(&s); sigaddset(&s, THR_SERVER_ALARM); @@ -104,8 +103,7 @@ void init_thr_alarm(uint max_alarms) pthread_sigmask(SIG_BLOCK, &s, NULL); /* used with sigwait() */ if (thd_lib_detected == THD_LIB_LT) { - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, - process_alarm); /* Linuxthreads */ + my_sigset(thr_client_alarm, process_alarm); /* Linuxthreads */ pthread_sigmask(SIG_UNBLOCK, &s, NULL); } #else @@ -286,8 +284,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) printf("thread_alarm in process_alarm\n"); fflush(stdout); #endif #ifdef DONT_REMEMBER_SIGNAL - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1, - process_alarm); /* int. thread system calls */ + my_sigset(thr_client_alarm, process_alarm); /* int. thread system calls */ #endif return; } @@ -334,8 +331,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) alarm_data=(ALARM*) queue_element(&alarm_queue,i); alarm_data->alarmed=1; /* Info to thread */ if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, - thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) + pthread_kill(alarm_data->thread, thr_client_alarm)) { #ifdef MAIN printf("Warning: pthread_kill couldn't find thread!!!\n"); @@ -359,8 +355,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused))) alarm_data->alarmed=1; /* Info to thread */ DBUG_PRINT("info",("sending signal to waiting thread")); if (pthread_equal(alarm_data->thread,alarm_thread) || - pthread_kill(alarm_data->thread, - thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) + pthread_kill(alarm_data->thread, thr_client_alarm)) { #ifdef MAIN printf("Warning: pthread_kill couldn't find thread!!!\n"); @@ -948,7 +943,7 @@ static void *signal_hand(void *arg __attribute__((unused))) #endif #endif /* OS2 */ printf("server alarm: %d thread alarm: %d\n", - THR_SERVER_ALARM, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + THR_SERVER_ALARM, thr_client_alarm); DBUG_PRINT("info",("Starting signal and alarm handling thread")); for(;;) { @@ -1020,11 +1015,11 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) sigaddset(&set,SIGTSTP); #endif sigaddset(&set,THR_SERVER_ALARM); - sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + sigdelset(&set, thr_client_alarm); (void) pthread_sigmask(SIG_SETMASK,&set,NULL); #ifdef NOT_USED sigemptyset(&set); - sigaddset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + sigaddset(&set, thr_client_alarm); VOID(pthread_sigmask(SIG_UNBLOCK, &set, (sigset_t*) 0)); #endif #endif /* OS2 */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d70fe9a1c32..43d76f28007 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -459,6 +459,7 @@ pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped, pthread_cond_t COND_thread_cache,COND_flush_thread_cache; pthread_t signal_thread; pthread_attr_t connection_attrib; +static uint thr_kill_signal; #ifdef __WIN__ #undef getpid @@ -499,7 +500,6 @@ static void clean_up(bool print_message); static void clean_up_mutexes(void); static int test_if_case_insensitive(const char *dir_name); static void create_pid_file(); -static uint get_thread_lib(void); /**************************************************************************** ** Code to end mysqld @@ -539,8 +539,7 @@ static void close_connections(void) DBUG_PRINT("info",("Waiting for select_thread")); #ifndef DONT_USE_THR_ALARM - if (pthread_kill(select_thread, - thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1)) + if (pthread_kill(select_thread, thr_client_alarm)) break; // allready dead #endif set_timespec(abstime, 2); @@ -1838,8 +1837,7 @@ static void init_signals(void) if (test_flags & TEST_SIGINT) { - my_sigset(thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2, - end_thread_signal); + my_sigset(thr_kill_signal, end_thread_signal); } my_sigset(THR_SERVER_ALARM, print_signal_warning); // Should never be called! @@ -1904,10 +1902,10 @@ static void init_signals(void) if (test_flags & TEST_SIGINT) { // May be SIGINT - sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2); + sigdelset(&set, thr_kill_signal); } // For alarms - sigdelset(&set, thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1); + sigdelset(&set, thr_client_alarm); sigprocmask(SIG_SETMASK,&set,NULL); pthread_sigmask(SIG_SETMASK,&set,NULL); DBUG_VOID_RETURN; @@ -1962,7 +1960,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) */ init_thr_alarm(max_connections + global_system_variables.max_insert_delayed_threads + 10); - if (thd_lib_detected != THD_LIB_LT && test_flags & TEST_SIGINT) + if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT)) { (void) sigemptyset(&set); // Setup up SIGINT for debug (void) sigaddset(&set,SIGINT); // For debugging @@ -2235,7 +2233,6 @@ int main(int argc, char **argv) MY_INIT(argv[0]); // init my_sys library & pthreads tzset(); // Set tzname - thd_lib_detected= get_thread_lib(); start_time=time((time_t*) 0); #ifdef OS2 { @@ -2253,6 +2250,9 @@ int main(int argc, char **argv) } #endif + /* Set signal used to kill MySQL */ + thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2; + /* Init mutexes for the global MYSQL_LOG objects. As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of @@ -5548,22 +5548,6 @@ static void create_pid_file() } -static uint get_thread_lib(void) -{ - char buff[64]; - -#ifdef _CS_GNU_LIBPTHREAD_VERSION - confstr(_CS_GNU_LIBPTHREAD_VERSION, buff, sizeof(buff)); - - if (!strncasecmp(buff, "NPTL", 4)) - return THD_LIB_NPTL; - else if (!strncasecmp(buff, "linuxthreads", 12)) - return THD_LIB_LT; -#endif - return THD_LIB_OTHER; -} - - /***************************************************************************** Instantiate templates *****************************************************************************/ From 60ac1f1b785ced5c8e09d738da294a614e680188 Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Tue, 30 Jan 2007 13:06:36 -0800 Subject: [PATCH 12/30] Fixed bug #24987. Made the function opt_sum_query to return HA_ERR_KEY_NOT_FOUND when no matches were found (instead of -1 it returned prior this patch). This changes allow us to avoid possible conflicts with return values from user-defined handler methods which also may return -1. No particular test cases are provided with this fix. --- sql/opt_sum.cc | 10 +++++----- sql/sql_select.cc | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 412fc0dc037..f912d67fe06 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -68,9 +68,9 @@ static int maxmin_in_range(bool max_fl, Field* field, COND *cond); GROUP BY part. RETURN VALUES - 0 No errors - 1 if all items were resolved - -1 on impossible conditions + 0 no errors + 1 if all items were resolved + HA_ERR_KEY_NOT_FOUND on impossible conditions OR an error number from my_base.h HA_ERR_... if a deadlock or a lock wait timeout happens, for example */ @@ -216,7 +216,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) if (error) { if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) - return -1; // No rows matching WHERE + return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE /* HA_ERR_LOCK_DEADLOCK or some other error */ table->file->print_error(error, MYF(0)); return(error); @@ -303,7 +303,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) if (error) { if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE) - return -1; // No rows matching WHERE + return HA_ERR_KEY_NOT_FOUND; // No rows matching WHERE /* HA_ERR_LOCK_DEADLOCK or some other error */ table->file->print_error(error, MYF(0)); return(error); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 97fa6bb7809..0768e54c4da 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -531,23 +531,25 @@ JOIN::optimize() { int res; /* - opt_sum_query() returns -1 if no rows match to the WHERE conditions, - or 1 if all items were resolved, or 0, or an error number HA_ERR_... + opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match + to the WHERE conditions, + or 1 if all items were resolved, + or 0, or an error number HA_ERR_... */ if ((res=opt_sum_query(tables_list, all_fields, conds))) { + if (res == HA_ERR_KEY_NOT_FOUND) + { + zero_result_cause= "No matching min/max row"; + error=0; + DBUG_RETURN(0); + } if (res > 1) { thd->fatal_error(); error= res; DBUG_RETURN(1); } - if (res < 0) - { - zero_result_cause= "No matching min/max row"; - error=0; - DBUG_RETURN(0); - } zero_result_cause= "Select tables optimized away"; tables_list= 0; // All tables resolved /* From e580bd6c6f8e56dcc8566384b53990ffe3b48d2d Mon Sep 17 00:00:00 2001 From: "kent@mysql.com/kent-amd64.(none)" <> Date: Wed, 31 Jan 2007 00:06:42 +0100 Subject: [PATCH 13/30] gen_lex_hash.cc: If inserting a GPL header, include a complete one Makefile.am, mysql.dsw, mysql.sln: Removed C version of mysql-test-run mysql.spec.sh: Specify GPL license only in GPL sources .del-my_manage.h: Delete: mysql-test/my_manage.h mysql.spec.sh: Added GPL header .del-mysql_test_run_new.c: Delete: mysql-test/mysql_test_run_new.c .del-mysql_test_run_new.dsp: Delete: VC++Files/mysql-test/mysql_test_run_new.dsp .del-my_create_tables.c: Delete: mysql-test/my_create_tables.c .del-mysql_test_run_new_ia64.dsp: Delete: VC++Files/mysql-test/mysql_test_run_new_ia64.dsp msql2mysql.sh: Use up-to-date GPL header .del-mysql_test_run_new.vcproj: Delete: VC++Files/mysql-test/mysql_test_run_new.vcproj .del-my_manage.c: Delete: mysql-test/my_manage.c --- VC++Files/mysql-test/mysql_test_run_new.dsp | 106 - .../mysql-test/mysql_test_run_new.vcproj | 204 -- .../mysql-test/mysql_test_run_new_ia64.dsp | 142 -- VC++Files/mysql.dsw | 22 - VC++Files/mysql.sln | 34 - mysql-test/Makefile.am | 2 - mysql-test/my_create_tables.c | 688 ------ mysql-test/my_manage.c | 887 -------- mysql-test/my_manage.h | 137 -- mysql-test/mysql_test_run_new.c | 1941 ----------------- scripts/msql2mysql.sh | 24 +- sql/gen_lex_hash.cc | 22 +- support-files/mysql.spec.sh | 34 +- 13 files changed, 53 insertions(+), 4190 deletions(-) delete mode 100644 VC++Files/mysql-test/mysql_test_run_new.dsp delete mode 100644 VC++Files/mysql-test/mysql_test_run_new.vcproj delete mode 100644 VC++Files/mysql-test/mysql_test_run_new_ia64.dsp delete mode 100644 mysql-test/my_create_tables.c delete mode 100644 mysql-test/my_manage.c delete mode 100644 mysql-test/my_manage.h delete mode 100644 mysql-test/mysql_test_run_new.c diff --git a/VC++Files/mysql-test/mysql_test_run_new.dsp b/VC++Files/mysql-test/mysql_test_run_new.dsp deleted file mode 100644 index 5ff07f0994d..00000000000 --- a/VC++Files/mysql-test/mysql_test_run_new.dsp +++ /dev/null @@ -1,106 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mysql_test_run_new" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mysql_test_run_new - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mysql_test_run_new.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mysql_test_run_new.mak" CFG="mysql_test_run_new - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mysql_test_run_new - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE "mysql_test_run_new - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mysql_test_run_new - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\Debug" -# PROP BASE Intermediate_Dir ".\Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\Debug" -# PROP Intermediate_Dir ".\Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /I "../include" /I "../" /Z7 /W3 /Od /G6 /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /Fp".\Debug/mysql_test_run_new.pch" /Fo".\Debug/" /Fd".\Debug/" /GZ /FD /c /GX -# ADD CPP /nologo /MTd /I "../include" /I "../" /Z7 /W3 /Od /G6 /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /Fp".\Debug/mysql_test_run_new.pch" /Fo".\Debug/" /Fd".\Debug/" /GZ /FD /c /GX -# ADD BASE MTL /nologo /tlb".\Debug\mysql_test_run_new.tlb" /win32 -# ADD MTL /nologo /tlb".\Debug\mysql_test_run_new.tlb" /win32 -# ADD BASE RSC /l 1033 -# ADD RSC /l 1033 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /out:"..\mysql-test\mysql_test_run_new.exe" /incremental:yes /debug /pdb:".\Debug\mysql_test_run_new.pdb" /pdbtype:sept /map:".\Debug\mysql_test_run_new.map" /subsystem:console -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib zlib.lib /nologo /out:"..\mysql-test\mysql_test_run_new.exe" /incremental:yes /libpath:"..\lib_debug\" /debug /pdb:".\Debug\mysql_test_run_new.pdb" /pdbtype:sept /map:".\Debug\mysql_test_run_new.map" /subsystem:console - -!ELSEIF "$(CFG)" == "mysql_test_run_new - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Release" -# PROP Intermediate_Dir ".\Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /I "../include" /I "../" /W3 /Ob1 /G6 /D "DBUG_OFF" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /GF /Gy /Fp".\Release/mysql_test_run_new.pch" /Fo".\Release/" /Fd".\Release/" /FD /c /GX -# ADD CPP /nologo /MTd /I "../include" /I "../" /W3 /Ob1 /G6 /D "DBUG_OFF" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN32" /GF /Gy /Fp".\Release/mysql_test_run_new.pch" /Fo".\Release/" /Fd".\Release/" /FD /c /GX -# ADD BASE MTL /nologo /tlb".\Release\mysql_test_run_new.tlb" /win32 -# ADD MTL /nologo /tlb".\Release\mysql_test_run_new.tlb" /win32 -# ADD BASE RSC /l 1033 -# ADD RSC /l 1033 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /out:"..\mysql-test\mysql_test_run_new.exe" /incremental:no /pdb:".\Release\mysql_test_run_new.pdb" /pdbtype:sept /subsystem:console -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib zlib.lib /nologo /out:"..\mysql-test\mysql_test_run_new.exe" /incremental:no /libpath:"..\lib_release\" /pdb:".\Release\mysql_test_run_new.pdb" /pdbtype:sept /subsystem:console - -!ENDIF - -# Begin Target - -# Name "mysql_test_run_new - Win32 Debug" -# Name "mysql_test_run_new - Win32 Release" -# Begin Source File - -SOURCE=.\my_create_tables.c -# End Source File -# Begin Source File - -SOURCE=.\my_manage.c -# End Source File -# Begin Source File - -SOURCE=.\my_manage.h -# End Source File -# Begin Source File - -SOURCE=.\mysql_test_run_new.c -# End Source File -# End Target -# End Project - diff --git a/VC++Files/mysql-test/mysql_test_run_new.vcproj b/VC++Files/mysql-test/mysql_test_run_new.vcproj deleted file mode 100644 index 12d502e5768..00000000000 --- a/VC++Files/mysql-test/mysql_test_run_new.vcproj +++ /dev/null @@ -1,204 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/VC++Files/mysql-test/mysql_test_run_new_ia64.dsp b/VC++Files/mysql-test/mysql_test_run_new_ia64.dsp deleted file mode 100644 index 023b38bd3c6..00000000000 --- a/VC++Files/mysql-test/mysql_test_run_new_ia64.dsp +++ /dev/null @@ -1,142 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mysql_test_run_new" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mysql_test_run_new - WinIA64 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mysql_test_run_new_ia64.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mysql_test_run_new_ia64.mak" CFG="mysql_test_run_new - WinIA64 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mysql_test_run_new - WinIA64 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE "mysql_test_run_new - WinIA64 Release" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mysql_test_run_new - WinIA64 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\Debug" -# PROP BASE Intermediate_Dir ".\Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\Debug" -# PROP Intermediate_Dir ".\Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE MTL /nologo /tlb".\Debug\mysql_test_run_new.tlb" /WinIA64 -# ADD MTL /nologo /tlb".\Debug\mysql_test_run_new.tlb" /WinIA64 -# ADD BASE CPP /nologo /G6 /MTd /W3 /GX /Z7 /Od /I "../include" /I "../" /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN64" /GZ /c -# ADD CPP /nologo /MTd /W3 /Zi /Od /I "../include" /I "../" /D "_DEBUG" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN64" /D "_IA64_" /D "WIN64" /D "WIN32" /D "_AFX_NO_DAO_SUPPORT" /GZ /G2 /EHsc /Wp64 /Zm600 /c -# ADD BASE RSC /l 0x409 -# ADD RSC /l 0x409 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /map /debug /out:"..\mysql-test\mysql_test_run_new.exe" /machine:IA64 -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib bufferoverflowU.lib zlib.lib /nologo /subsystem:console /incremental:no /libpath:"..\lib_debug\" /map /debug /out:"..\mysql-test\mysql_test_run_new.exe" /machine:IA64 -# SUBTRACT LINK32 /pdb:none - -!ELSEIF "$(CFG)" == "mysql_test_run_new - WinIA64 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Release" -# PROP Intermediate_Dir ".\Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE MTL /nologo /tlb".\Release\mysql_test_run_new.tlb" /WinIA64 -# ADD MTL /nologo /tlb".\Release\mysql_test_run_new.tlb" /WinIA64 -# ADD BASE CPP /nologo /G6 /MTd /W3 /GX /Ob1 /Gy /I "../include" /I "../" /D "DBUG_OFF" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN64" /GF /c -# ADD CPP /nologo /MTd /W3 /Zi /O2 /I "../include" /I "../" /D "DBUG_OFF" /D "_WINDOWS" /D "SAFE_MUTEX" /D "USE_TLS" /D "MYSQL_CLIENT" /D "__WIN__" /D "_WIN64" /D "_IA64_" /D "WIN64" /D "WIN32" /D "_AFX_NO_DAO_SUPPORT" /GF /G2 /EHsc /Wp64 /Zm600 /c -# ADD BASE RSC /l 0x409 -# ADD RSC /l 0x409 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /out:"..\mysql-test\mysql_test_run_new.exe" /machine:IA64 -# SUBTRACT BASE LINK32 /pdb:none -# ADD LINK32 t kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib bufferoverflowU.lib zlib.lib /nologo /subsystem:console /libpath:"..\lib_release\" /out:"..\mysql-test\mysql_test_run_new.exe" /machine:IA64 -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "mysql_test_run_new - WinIA64 Debug" -# Name "mysql_test_run_new - WinIA64 Release" -# Begin Source File - -SOURCE=.\my_create_tables.c -DEP_CPP_MY_CR=\ - "..\include\config-netware.h"\ - "..\include\config-os2.h"\ - "..\include\config-win.h"\ - "..\include\m_string.h"\ - "..\include\my_config.h"\ - "..\include\my_dbug.h"\ - "..\include\my_global.h"\ - ".\my_manage.h"\ - -# End Source File -# Begin Source File - -SOURCE=.\my_manage.c -DEP_CPP_MY_MA=\ - "..\include\config-netware.h"\ - "..\include\config-os2.h"\ - "..\include\config-win.h"\ - "..\include\m_string.h"\ - "..\include\my_config.h"\ - "..\include\my_dbug.h"\ - "..\include\my_global.h"\ - ".\my_manage.h"\ - -# End Source File -# Begin Source File - -SOURCE=.\my_manage.h -# End Source File -# Begin Source File - -SOURCE=.\mysql_test_run_new.c -DEP_CPP_MYSQL=\ - "..\include\config-netware.h"\ - "..\include\config-os2.h"\ - "..\include\config-win.h"\ - "..\include\m_string.h"\ - "..\include\my_config.h"\ - "..\include\my_dbug.h"\ - "..\include\my_global.h"\ - ".\my_manage.h"\ - -# End Source File -# End Target -# End Project diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw index 911b895c1ad..f69719bf21e 100644 --- a/VC++Files/mysql.dsw +++ b/VC++Files/mysql.dsw @@ -808,28 +808,6 @@ Project: "mysql_client_test"=.\tests\mysql_client_test.dsp - Package Owner=<4> {{{ }}} - ############################################################################### - - -Project: "mysql_test_run_new"=".\mysql-test\mysql_test_run_new.dsp" - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ Begin Project Dependency - Project_Dep_Name mysqltest - End Project Dependency - Begin Project Dependency - Project_Dep_Name mysqladmin - End Project Dependency - Begin Project Dependency - Project_Dep_Name mysql_client_test - End Project Dependency -}}} - - ############################################################################### Global: diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln index 1e3a33b8eb4..0d4f22862a3 100644 --- a/VC++Files/mysql.sln +++ b/VC++Files/mysql.sln @@ -281,13 +281,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_client_test", "tests\ {44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_test_run_new", "mysql-test\mysql_test_run_new.vcproj", "{6189F838-21C6-42A1-B2D0-9146316573F7}" - ProjectSection(ProjectDependencies) = postProject - {8961F149-C68A-4154-A499-A2AB39E607E8} = {8961F149-C68A-4154-A499-A2AB39E607E8} - {DA224DAB-5006-42BE-BB77-16E8BE5326D5} = {DA224DAB-5006-42BE-BB77-16E8BE5326D5} - {D2B00DE0-F6E9-40AF-B90D-A257D014F098} = {D2B00DE0-F6E9-40AF-B90D-A257D014F098} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlmanager", "server-tools\instance-manager\mysqlmanager.vcproj", "{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}" ProjectSection(ProjectDependencies) = postProject {EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859} @@ -1467,33 +1460,6 @@ Global {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro nt.Build.0 = Release|Win32 {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Release.ActiveCfg = Release|Win32 {DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Release.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.classic.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.classic.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.classic nt.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.classic nt.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Debug.ActiveCfg = Debug|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Debug.Build.0 = Debug|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Embedded_Classic.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Embedded_Debug.ActiveCfg = Debug|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Embedded_Pro.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Embedded_ProGPL.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Embedded_Release.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Max.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Max.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Max nt.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Max nt.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.nt.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.nt.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl nt.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl nt.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro nt.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.pro nt.Build.0 = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Release.ActiveCfg = Release|Win32 - {6189F838-21C6-42A1-B2D0-9146316573F7}.Release.Build.0 = Release|Win32 {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic.ActiveCfg = Release|Win32 {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic.Build.0 = Release|Win32 {6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic nt.ActiveCfg = Release|Win32 diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index cd668950459..ed85f06fcc5 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -46,8 +46,6 @@ CLEANFILES = $(GENSCRIPTS) $(test_DATA) INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I.. -noinst_HEADERS = my_manage.h - dist-hook: mkdir -p $(distdir)/t $(distdir)/r $(distdir)/include \ $(distdir)/std_data $(distdir)/lib diff --git a/mysql-test/my_create_tables.c b/mysql-test/my_create_tables.c deleted file mode 100644 index 0f6691b91b7..00000000000 --- a/mysql-test/my_create_tables.c +++ /dev/null @@ -1,688 +0,0 @@ -/* Copyright (C) 2004-2005 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include -#include -#ifndef __WIN__ -#include -#endif -#include -#ifdef __NETWARE__ -#include -#include -#else -#include -#ifndef __WIN__ -#include -#include -#else -#include -#include -#include -#endif -#endif -#include -#include -#include -#include -#include "my_manage.h" - -/* - Synopsis: - This function testes a exist file - -Arguments: - mdata: path to data - file_name: name of file -Output: - A zero value indicates that file is exist. -*/ -bool test_sys_file(const char *mdata,const char *file_name) -{ - struct stat file; - char path_file_name[PATH_MAX]; - snprintf(path_file_name, PATH_MAX, "%s/%s", mdata, file_name); - return(stat(path_file_name,&file)); -} - -/* - Synopsis: - This function creates a file with sql requstes for creating - system data files. - -Arguments: - mdata: path to data - output_file: file name for output file - test: to create system files with test data -Output: - A zero value indicates a success. -*/ -bool create_system_files(const char *mdata,const char *output_file, bool test) -{ - FILE *out; - - out = fopen(output_file, "w+"); - - if (!out) - return 1; - - if (test_sys_file(mdata,"mysql")) - { - fprintf(out,"CREATE DATABASE mysql;\n"); - } - - if (test && test_sys_file(mdata,"test")) - { - fprintf(out,"CREATE DATABASE test;\n"); - } - - fprintf(out,"USE mysql;\n"); - - if (test_sys_file(mdata,"mysql/db.frm")) - { - fprintf(out, - "CREATE TABLE db (" - "Host char(60) binary DEFAULT '' NOT NULL," - "Db char(64) binary DEFAULT '' NOT NULL," - "User char(16) binary DEFAULT '' NOT NULL," - "Select_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Update_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Create_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "References_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "PRIMARY KEY Host (Host,Db,User)," - "KEY User (User))" - "engine=MyISAM " - "CHARACTER SET utf8 COLLATE utf8_bin " - "comment='Database privileges';\n"); - - if (test) - { - fprintf(out,"INSERT INTO db VALUES ('%%','test','','Y','Y','Y','Y'" - ",'Y','Y','N','Y','Y','Y','Y','Y');\n"); - fprintf(out,"INSERT INTO db VALUES ('%%','test\\_%%','','Y','Y','Y'" - ",'Y','Y','Y','N','Y','Y','Y','Y','Y');\n"); - } - } - - if (test_sys_file(mdata,"mysql/host.frm")) - { - fprintf(out, - "CREATE TABLE host (" - "Host char(60) binary DEFAULT '' NOT NULL," - "Db char(64) binary DEFAULT '' NOT NULL," - "Select_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Update_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Create_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "References_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "PRIMARY KEY Host (Host,Db))" - "engine=MyISAM " - "CHARACTER SET utf8 COLLATE utf8_bin " - "comment='Host privileges; Merged with database privileges';\n"); - } - - - if (test_sys_file(mdata,"mysql/user.frm")) - { -#ifdef __WIN__ - WSADATA wsa_data; -#endif - char hostname[FN_REFLEN]; - -#ifdef __WIN__ - if (WSAStartup(MAKEWORD( 2, 2 ),&wsa_data)) - return 1; -#endif - if (gethostname(hostname, FN_REFLEN)) - return 1; -#ifdef __WIN__ - WSACleanup( ); -#endif - - if (strchr(hostname, '.') == NULL) - strcat(hostname, "%"); - - fprintf(out, - "CREATE TABLE user (" - "Host char(60) binary DEFAULT '' NOT NULL," - "User char(16) binary DEFAULT '' NOT NULL," - "Password char(41) binary DEFAULT '' NOT NULL," - "Select_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Update_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Create_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Process_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "File_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "References_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Index_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Super_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL," - "ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL," - "ssl_cipher BLOB NOT NULL," - "x509_issuer BLOB NOT NULL," - "x509_subject BLOB NOT NULL," - "max_questions int(11) unsigned DEFAULT 0 NOT NULL," - "max_updates int(11) unsigned DEFAULT 0 NOT NULL," - "max_connections int(11) unsigned DEFAULT 0 NOT NULL," - "PRIMARY KEY Host (Host,User)" - ") engine=MyISAM " - "CHARACTER SET utf8 COLLATE utf8_bin " - "comment='Users and global privileges';\n"); - - - if (test) - { - fprintf(out, - "INSERT INTO user VALUES ('localhost','root',''" - ",'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'" - ",'Y','Y','Y','Y','Y','','','','',0,0,0);\n"); - fprintf(out, - "INSERT INTO user VALUES ('%s','root','','Y','Y'," - "'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'," - "'Y','Y','Y','Y','','','','',0,0,0);\n",hostname); - fprintf(out, - "REPLACE INTO user VALUES ('127.0.0.1','root',''," - "'Y','Y','Y','Y','Y','Y'," - "'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'" - ",'Y','','','','',0,0,0);\n"); - fprintf(out,"INSERT INTO user (host,user) values ('localhost','');\n"); - fprintf(out,"INSERT INTO user (host,user) values ('%s','');\n",hostname); - } - else - { - fprintf(out, - "INSERT INTO user VALUES ('localhost','root',''," - "'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'," - "'Y','Y','Y','Y','','','','',0,0,0);\n"); -#ifndef __WIN__ - fprintf(out, - "INSERT INTO user VALUES ('%s','root','','Y','Y'," - "'Y','Y','Y','Y','Y','Y'" - "'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','',''" - ",'','',0,0,0);\n",hostname); - fprintf(out,"INSERT INTO user (host,user) values ('%s','');\n",hostname); - fprintf(out,"INSERT INTO user (host,user) values ('localhost','');\n"); -#else - fprintf(out, - "INSERT INTO user VALUES ('localhost','','','Y','Y','Y'" - ",'Y','Y','Y','Y','Y','Y'" - ",'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','',''," - "'','',0,0,0);\n"); -#endif - } - } - - - if (test_sys_file(mdata,"mysql/func.frm")) - { - fprintf(out, - "CREATE TABLE func (" - "name char(64) binary DEFAULT '' NOT NULL," - "ret tinyint(1) DEFAULT '0' NOT NULL," - "dl char(128) DEFAULT '' NOT NULL," - "type enum ('function','aggregate') NOT NULL," - "PRIMARY KEY (name)" - ") engine=MyISAM " - "CHARACTER SET utf8 COLLATE utf8_bin " - "comment='User defined functions';\n"); - } - - if (test_sys_file(mdata,"mysql/tables_priv.frm")) - { - fprintf(out, - "CREATE TABLE tables_priv (" - "Host char(60) binary DEFAULT '' NOT NULL," - "Db char(64) binary DEFAULT '' NOT NULL," - "User char(16) binary DEFAULT '' NOT NULL," - "Table_name char(64) binary DEFAULT '' NOT NULL," - "Grantor char(77) DEFAULT '' NOT NULL," - "Timestamp timestamp(14)," - "Table_priv set('Select','Insert','Update','Delete'," - "'Create','Drop','Grant','References','Index','Alter')" - " DEFAULT '' NOT NULL," - "Column_priv set('Select','Insert','Update','References')" - " DEFAULT '' NOT NULL," - "PRIMARY KEY (Host,Db,User,Table_name)," - "KEY Grantor (Grantor)" - ") engine=MyISAM " - "CHARACTER SET utf8 COLLATE utf8_bin " - "comment='Table privileges';\n"); - } - - if (test_sys_file(mdata,"mysql/columns_priv.frm")) - { - fprintf(out, - "CREATE TABLE columns_priv (" - "Host char(60) binary DEFAULT '' NOT NULL," - "Db char(64) binary DEFAULT '' NOT NULL," - "User char(16) binary DEFAULT '' NOT NULL," - "Table_name char(64) binary DEFAULT '' NOT NULL," - "Column_name char(64) binary DEFAULT '' NOT NULL," - "Timestamp timestamp(14)," - "Column_priv set('Select','Insert','Update','References')" - " DEFAULT '' NOT NULL," - "PRIMARY KEY (Host,Db,User,Table_name,Column_name)" - ") engine=MyISAM " - "CHARACTER SET utf8 COLLATE utf8_bin " - "comment='Column privileges';\n"); - } - - if (test_sys_file(mdata,"mysql/help_topic.frm")) - { - fprintf(out, - "CREATE TABLE help_topic (" - "help_topic_id int unsigned not null," - "name varchar(64) not null," - "help_category_id smallint unsigned not null," - "description text not null," - "example text not null," - "url varchar(128) not null," - "primary key (help_topic_id)," - "unique index (name)" - ") engine=MyISAM " - "CHARACTER SET utf8 " - "comment='help topics';\n"); - } - - if (test_sys_file(mdata,"mysql/help_category.frm")) - { - fprintf(out, - "CREATE TABLE help_category (" - "help_category_id smallint unsigned not null," - "name varchar(64) not null," - "parent_category_id smallint unsigned null," - "url varchar(128) not null," - "primary key (help_category_id)," - "unique index (name)" - ") engine=MyISAM " - "CHARACTER SET utf8 " - "comment='help categories';\n"); - } - - if (test_sys_file(mdata,"mysql/help_keyword.frm")) - { - fprintf(out, - "CREATE TABLE help_keyword (" - "help_keyword_id int unsigned not null," - "name varchar(64) not null," - "primary key (help_keyword_id)," - "unique index (name)" - ") engine=MyISAM " - "CHARACTER SET utf8 " - "comment='help keywords';\n"); - } - - if (test_sys_file(mdata,"mysql/help_relation.frm")) - { - fprintf(out, - "CREATE TABLE help_relation (" - "help_topic_id int unsigned not null references help_topic," - "help_keyword_id int unsigned not null references help_keyword," - "primary key (help_keyword_id, help_topic_id)" - ") engine=MyISAM " - "CHARACTER SET utf8 " - "comment='keyword-topic relation';\n"); - } - - if (test_sys_file(mdata,"mysql/time_zone_name.frm")) - { - fprintf(out, - "CREATE TABLE time_zone_name (" - "Name char(64) NOT NULL," - "Time_zone_id int unsigned NOT NULL," - "PRIMARY KEY Name (Name)" - ") engine=MyISAM CHARACTER SET utf8 " - "comment='Time zone names';\n"); - - if (test) - { - fprintf(out, - "INSERT INTO time_zone_name (Name, Time_Zone_id) VALUES" - "('MET', 1), ('UTC', 2), ('Universal', 2), " - "('Europe/Moscow',3), ('leap/Europe/Moscow',4)," - "('Japan', 5);\n"); - - } - } - - - if (test_sys_file(mdata,"mysql/time_zone.frm")) - { - fprintf(out, - "CREATE TABLE time_zone (" - "Time_zone_id int unsigned NOT NULL auto_increment," - "Use_leap_seconds enum('Y','N') DEFAULT 'N' NOT NULL," - "PRIMARY KEY TzId (Time_zone_id)" - ") engine=MyISAM CHARACTER SET utf8 " - "comment='Time zones';\n"); - - if (test) - { - fprintf(out,"INSERT INTO time_zone (Time_zone_id, Use_leap_seconds)" - "VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y'), (5,'N');\n"); - } - } - - if (test_sys_file(mdata,"mysql/time_zone_transition.frm")) - { - fprintf(out, - "CREATE TABLE time_zone_transition (" - "Time_zone_id int unsigned NOT NULL," - "Transition_time bigint signed NOT NULL," - "Transition_type_id int unsigned NOT NULL," - "PRIMARY KEY TzIdTranTime (Time_zone_id, Transition_time)" - ") engine=MyISAM CHARACTER SET utf8 " - "comment='Time zone transitions';\n"); - - if (test) - { - fprintf(out, - "INSERT INTO time_zone_transition" - "(Time_zone_id, Transition_time, Transition_type_id)" - "VALUES" - " (1, -1693706400, 0) ,(1, -1680483600, 1)" - ",(1, -1663455600, 2) ,(1, -1650150000, 3)" - ",(1, -1632006000, 2) ,(1, -1618700400, 3)" - ",(1, -938905200, 2) ,(1, -857257200, 3)" - ",(1, -844556400, 2) ,(1, -828226800, 3)" - ",(1, -812502000, 2) ,(1, -796777200, 3)" - ",(1, 228877200, 2) ,(1, 243997200, 3)" - ",(1, 260326800, 2) ,(1, 276051600, 3)" - ",(1, 291776400, 2) ,(1, 307501200, 3)" - ",(1, 323830800, 2) ,(1, 338950800, 3)" - ",(1, 354675600, 2) ,(1, 370400400, 3)" - ",(1, 386125200, 2) ,(1, 401850000, 3)" - ",(1, 417574800, 2) ,(1, 433299600, 3)" - ",(1, 449024400, 2) ,(1, 465354000, 3)" - ",(1, 481078800, 2) ,(1, 496803600, 3)" - ",(1, 512528400, 2) ,(1, 528253200, 3)" - ",(1, 543978000, 2) ,(1, 559702800, 3)" - ",(1, 575427600, 2) ,(1, 591152400, 3)" - ",(1, 606877200, 2) ,(1, 622602000, 3)" - ",(1, 638326800, 2) ,(1, 654656400, 3)" - ",(1, 670381200, 2) ,(1, 686106000, 3)" - ",(1, 701830800, 2) ,(1, 717555600, 3)" - ",(1, 733280400, 2) ,(1, 749005200, 3)" - ",(1, 764730000, 2) ,(1, 780454800, 3)" - ",(1, 796179600, 2) ,(1, 811904400, 3)" - ",(1, 828234000, 2) ,(1, 846378000, 3)" - ",(1, 859683600, 2) ,(1, 877827600, 3)" - ",(1, 891133200, 2) ,(1, 909277200, 3)" - ",(1, 922582800, 2) ,(1, 941331600, 3)" - ",(1, 954032400, 2) ,(1, 972781200, 3)" - ",(1, 985482000, 2) ,(1, 1004230800, 3)" - ",(1, 1017536400, 2) ,(1, 1035680400, 3)" - ",(1, 1048986000, 2) ,(1, 1067130000, 3)" - ",(1, 1080435600, 2) ,(1, 1099184400, 3)" - ",(1, 1111885200, 2) ,(1, 1130634000, 3)" - ",(1, 1143334800, 2) ,(1, 1162083600, 3)" - ",(1, 1174784400, 2) ,(1, 1193533200, 3)" - ",(1, 1206838800, 2) ,(1, 1224982800, 3)" - ",(1, 1238288400, 2) ,(1, 1256432400, 3)" - ",(1, 1269738000, 2) ,(1, 1288486800, 3)" - ",(1, 1301187600, 2) ,(1, 1319936400, 3)" - ",(1, 1332637200, 2) ,(1, 1351386000, 3)" - ",(1, 1364691600, 2) ,(1, 1382835600, 3)" - ",(1, 1396141200, 2) ,(1, 1414285200, 3)" - ",(1, 1427590800, 2) ,(1, 1445734800, 3)" - ",(1, 1459040400, 2) ,(1, 1477789200, 3)" - ",(1, 1490490000, 2) ,(1, 1509238800, 3)" - ",(1, 1521939600, 2) ,(1, 1540688400, 3)" - ",(1, 1553994000, 2) ,(1, 1572138000, 3)" - ",(1, 1585443600, 2) ,(1, 1603587600, 3)" - ",(1, 1616893200, 2) ,(1, 1635642000, 3)" - ",(1, 1648342800, 2) ,(1, 1667091600, 3)" - ",(1, 1679792400, 2) ,(1, 1698541200, 3)" - ",(1, 1711846800, 2) ,(1, 1729990800, 3)" - ",(1, 1743296400, 2) ,(1, 1761440400, 3)" - ",(1, 1774746000, 2) ,(1, 1792890000, 3)" - ",(1, 1806195600, 2) ,(1, 1824944400, 3)" - ",(1, 1837645200, 2) ,(1, 1856394000, 3)" - ",(1, 1869094800, 2) ,(1, 1887843600, 3)" - ",(1, 1901149200, 2) ,(1, 1919293200, 3)" - ",(1, 1932598800, 2) ,(1, 1950742800, 3)" - ",(1, 1964048400, 2) ,(1, 1982797200, 3)" - ",(1, 1995498000, 2) ,(1, 2014246800, 3)" - ",(1, 2026947600, 2) ,(1, 2045696400, 3)" - ",(1, 2058397200, 2) ,(1, 2077146000, 3)" - ",(1, 2090451600, 2) ,(1, 2108595600, 3)" - ",(1, 2121901200, 2) ,(1, 2140045200, 3)" - ",(3, -1688265000, 2) ,(3, -1656819048, 1)" - ",(3, -1641353448, 2) ,(3, -1627965048, 3)" - ",(3, -1618716648, 1) ,(3, -1596429048, 3)" - ",(3, -1593829848, 5) ,(3, -1589860800, 4)" - ",(3, -1542427200, 5) ,(3, -1539493200, 6)" - ",(3, -1525323600, 5) ,(3, -1522728000, 4)" - ",(3, -1491188400, 7) ,(3, -1247536800, 4)" - ",(3, 354920400, 5) ,(3, 370728000, 4)" - ",(3, 386456400, 5) ,(3, 402264000, 4)" - ",(3, 417992400, 5) ,(3, 433800000, 4)" - ",(3, 449614800, 5) ,(3, 465346800, 8)" - ",(3, 481071600, 9) ,(3, 496796400, 8)" - ",(3, 512521200, 9) ,(3, 528246000, 8)" - ",(3, 543970800, 9) ,(3, 559695600, 8)" - ",(3, 575420400, 9) ,(3, 591145200, 8)" - ",(3, 606870000, 9) ,(3, 622594800, 8)" - ",(3, 638319600, 9) ,(3, 654649200, 8)" - ",(3, 670374000, 10) ,(3, 686102400, 11)" - ",(3, 695779200, 8) ,(3, 701812800, 5)" - ",(3, 717534000, 4) ,(3, 733273200, 9)" - ",(3, 748998000, 8) ,(3, 764722800, 9)" - ",(3, 780447600, 8) ,(3, 796172400, 9)" - ",(3, 811897200, 8) ,(3, 828226800, 9)" - ",(3, 846370800, 8) ,(3, 859676400, 9)" - ",(3, 877820400, 8) ,(3, 891126000, 9)" - ",(3, 909270000, 8) ,(3, 922575600, 9)" - ",(3, 941324400, 8) ,(3, 954025200, 9)" - ",(3, 972774000, 8) ,(3, 985474800, 9)" - ",(3, 1004223600, 8) ,(3, 1017529200, 9)" - ",(3, 1035673200, 8) ,(3, 1048978800, 9)" - ",(3, 1067122800, 8) ,(3, 1080428400, 9)" - ",(3, 1099177200, 8) ,(3, 1111878000, 9)" - ",(3, 1130626800, 8) ,(3, 1143327600, 9)" - ",(3, 1162076400, 8) ,(3, 1174777200, 9)" - ",(3, 1193526000, 8) ,(3, 1206831600, 9)" - ",(3, 1224975600, 8) ,(3, 1238281200, 9)" - ",(3, 1256425200, 8) ,(3, 1269730800, 9)" - ",(3, 1288479600, 8) ,(3, 1301180400, 9)" - ",(3, 1319929200, 8) ,(3, 1332630000, 9)" - ",(3, 1351378800, 8) ,(3, 1364684400, 9)" - ",(3, 1382828400, 8) ,(3, 1396134000, 9)" - ",(3, 1414278000, 8) ,(3, 1427583600, 9)" - ",(3, 1445727600, 8) ,(3, 1459033200, 9)" - ",(3, 1477782000, 8) ,(3, 1490482800, 9)" - ",(3, 1509231600, 8) ,(3, 1521932400, 9)" - ",(3, 1540681200, 8) ,(3, 1553986800, 9)" - ",(3, 1572130800, 8) ,(3, 1585436400, 9)" - ",(3, 1603580400, 8) ,(3, 1616886000, 9)" - ",(3, 1635634800, 8) ,(3, 1648335600, 9)" - ",(3, 1667084400, 8) ,(3, 1679785200, 9)" - ",(3, 1698534000, 8) ,(3, 1711839600, 9)" - ",(3, 1729983600, 8) ,(3, 1743289200, 9)" - ",(3, 1761433200, 8) ,(3, 1774738800, 9)" - ",(3, 1792882800, 8) ,(3, 1806188400, 9)" - ",(3, 1824937200, 8) ,(3, 1837638000, 9)" - ",(3, 1856386800, 8) ,(3, 1869087600, 9)" - ",(3, 1887836400, 8) ,(3, 1901142000, 9)" - ",(3, 1919286000, 8) ,(3, 1932591600, 9)" - ",(3, 1950735600, 8) ,(3, 1964041200, 9)" - ",(3, 1982790000, 8) ,(3, 1995490800, 9)" - ",(3, 2014239600, 8) ,(3, 2026940400, 9)" - ",(3, 2045689200, 8) ,(3, 2058390000, 9)" - ",(3, 2077138800, 8) ,(3, 2090444400, 9)" - ",(3, 2108588400, 8) ,(3, 2121894000, 9)" - ",(3, 2140038000, 8)" - ",(4, -1688265000, 2) ,(4, -1656819048, 1)" - ",(4, -1641353448, 2) ,(4, -1627965048, 3)" - ",(4, -1618716648, 1) ,(4, -1596429048, 3)" - ",(4, -1593829848, 5) ,(4, -1589860800, 4)" - ",(4, -1542427200, 5) ,(4, -1539493200, 6)" - ",(4, -1525323600, 5) ,(4, -1522728000, 4)" - ",(4, -1491188400, 7) ,(4, -1247536800, 4)" - ",(4, 354920409, 5) ,(4, 370728010, 4)" - ",(4, 386456410, 5) ,(4, 402264011, 4)" - ",(4, 417992411, 5) ,(4, 433800012, 4)" - ",(4, 449614812, 5) ,(4, 465346812, 8)" - ",(4, 481071612, 9) ,(4, 496796413, 8)" - ",(4, 512521213, 9) ,(4, 528246013, 8)" - ",(4, 543970813, 9) ,(4, 559695613, 8)" - ",(4, 575420414, 9) ,(4, 591145214, 8)" - ",(4, 606870014, 9) ,(4, 622594814, 8)" - ",(4, 638319615, 9) ,(4, 654649215, 8)" - ",(4, 670374016, 10) ,(4, 686102416, 11)" - ",(4, 695779216, 8) ,(4, 701812816, 5)" - ",(4, 717534017, 4) ,(4, 733273217, 9)" - ",(4, 748998018, 8) ,(4, 764722818, 9)" - ",(4, 780447619, 8) ,(4, 796172419, 9)" - ",(4, 811897219, 8) ,(4, 828226820, 9)" - ",(4, 846370820, 8) ,(4, 859676420, 9)" - ",(4, 877820421, 8) ,(4, 891126021, 9)" - ",(4, 909270021, 8) ,(4, 922575622, 9)" - ",(4, 941324422, 8) ,(4, 954025222, 9)" - ",(4, 972774022, 8) ,(4, 985474822, 9)" - ",(4, 1004223622, 8) ,(4, 1017529222, 9)" - ",(4, 1035673222, 8) ,(4, 1048978822, 9)" - ",(4, 1067122822, 8) ,(4, 1080428422, 9)" - ",(4, 1099177222, 8) ,(4, 1111878022, 9)" - ",(4, 1130626822, 8) ,(4, 1143327622, 9)" - ",(4, 1162076422, 8) ,(4, 1174777222, 9)" - ",(4, 1193526022, 8) ,(4, 1206831622, 9)" - ",(4, 1224975622, 8) ,(4, 1238281222, 9)" - ",(4, 1256425222, 8) ,(4, 1269730822, 9)" - ",(4, 1288479622, 8) ,(4, 1301180422, 9)" - ",(4, 1319929222, 8) ,(4, 1332630022, 9)" - ",(4, 1351378822, 8) ,(4, 1364684422, 9)" - ",(4, 1382828422, 8) ,(4, 1396134022, 9)" - ",(4, 1414278022, 8) ,(4, 1427583622, 9)" - ",(4, 1445727622, 8) ,(4, 1459033222, 9)" - ",(4, 1477782022, 8) ,(4, 1490482822, 9)" - ",(4, 1509231622, 8) ,(4, 1521932422, 9)" - ",(4, 1540681222, 8) ,(4, 1553986822, 9)" - ",(4, 1572130822, 8) ,(4, 1585436422, 9)" - ",(4, 1603580422, 8) ,(4, 1616886022, 9)" - ",(4, 1635634822, 8) ,(4, 1648335622, 9)" - ",(4, 1667084422, 8) ,(4, 1679785222, 9)" - ",(4, 1698534022, 8) ,(4, 1711839622, 9)" - ",(4, 1729983622, 8) ,(4, 1743289222, 9)" - ",(4, 1761433222, 8) ,(4, 1774738822, 9)" - ",(4, 1792882822, 8) ,(4, 1806188422, 9)" - ",(4, 1824937222, 8) ,(4, 1837638022, 9)" - ",(4, 1856386822, 8) ,(4, 1869087622, 9)" - ",(4, 1887836422, 8) ,(4, 1901142022, 9)" - ",(4, 1919286022, 8) ,(4, 1932591622, 9)" - ",(4, 1950735622, 8) ,(4, 1964041222, 9)" - ",(4, 1982790022, 8) ,(4, 1995490822, 9)" - ",(4, 2014239622, 8) ,(4, 2026940422, 9)" - ",(4, 2045689222, 8) ,(4, 2058390022, 9)" - ",(4, 2077138822, 8) ,(4, 2090444422, 9)" - ",(4, 2108588422, 8) ,(4, 2121894022, 9)" - ",(4, 2140038022, 8), (5, -1009875600, 1);\n"); - - - } - } - - if (test_sys_file(mdata,"mysql/time_zone_transition_type.frm")) - { - fprintf(out, - "CREATE TABLE time_zone_transition_type (" - "Time_zone_id int unsigned NOT NULL," - "Transition_type_id int unsigned NOT NULL," - "Offset int signed DEFAULT 0 NOT NULL," - "Is_DST tinyint unsigned DEFAULT 0 NOT NULL," - "Abbreviation char(8) DEFAULT '' NOT NULL," - "PRIMARY KEY TzIdTrTId (Time_zone_id, Transition_type_id)" - ") engine=MyISAM CHARACTER SET utf8 " - "comment='Time zone transition types';\n"); - - if (test) - { - fprintf(out, - "INSERT INTO time_zone_transition_type (Time_zone_id," - "Transition_type_id, Offset, Is_DST, Abbreviation) VALUES" - "(1, 0, 7200, 1, 'MEST') ,(1, 1, 3600, 0, 'MET')" - ",(1, 2, 7200, 1, 'MEST') ,(1, 3, 3600, 0, 'MET')" - ",(2, 0, 0, 0, 'UTC')" - ",(3, 0, 9000, 0, 'MMT') ,(3, 1, 12648, 1, 'MST')" - ",(3, 2, 9048, 0, 'MMT') ,(3, 3, 16248, 1, 'MDST')" - ",(3, 4, 10800, 0, 'MSK') ,(3, 5, 14400, 1, 'MSD')" - ",(3, 6, 18000, 1, 'MSD') ,(3, 7, 7200, 0, 'EET')" - ",(3, 8, 10800, 0, 'MSK') ,(3, 9, 14400, 1, 'MSD')" - ",(3, 10, 10800, 1, 'EEST') ,(3, 11, 7200, 0, 'EET')" - ",(4, 0, 9000, 0, 'MMT') ,(4, 1, 12648, 1, 'MST')" - ",(4, 2, 9048, 0, 'MMT') ,(4, 3, 16248, 1, 'MDST')" - ",(4, 4, 10800, 0, 'MSK') ,(4, 5, 14400, 1, 'MSD')" - ",(4, 6, 18000, 1, 'MSD') ,(4, 7, 7200, 0, 'EET')" - ",(4, 8, 10800, 0, 'MSK') ,(4, 9, 14400, 1, 'MSD')" - ",(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET')" - ",(5, 0, 32400, 0, 'CJT') ,(5, 1, 32400, 0, 'JST');\n"); - - } - } - - if (test_sys_file(mdata,"mysql/time_zone_leap_second.frm")) - { - fprintf(out, - "CREATE TABLE time_zone_leap_second (" - "Transition_time bigint signed NOT NULL," - "Correction int signed NOT NULL," - "PRIMARY KEY TranTime (Transition_time)" - ") engine=MyISAM CHARACTER SET utf8 " - "comment='Leap seconds information for time zones';\n"); - - if (test) - { - fprintf(out, - "INSERT INTO time_zone_leap_second " - "(Transition_time, Correction) VALUES " - "(78796800, 1) ,(94694401, 2) ,(126230402, 3)" - ",(157766403, 4) ,(189302404, 5) ,(220924805, 6)" - ",(252460806, 7) ,(283996807, 8) ,(315532808, 9)" - ",(362793609, 10) ,(394329610, 11) ,(425865611, 12)" - ",(489024012, 13) ,(567993613, 14) ,(631152014, 15)" - ",(662688015, 16) ,(709948816, 17) ,(741484817, 18)" - ",(773020818, 19) ,(820454419, 20) ,(867715220, 21)" - ",(915148821, 22);\n"); - } - } - - return fclose(out); -} diff --git a/mysql-test/my_manage.c b/mysql-test/my_manage.c deleted file mode 100644 index e5d1be42f95..00000000000 --- a/mysql-test/my_manage.c +++ /dev/null @@ -1,887 +0,0 @@ -/* - Copyright (c) 2003 Novell, Inc. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#ifndef __WIN__ -#include -#endif -#include -#ifdef __NETWARE__ -#include -#include -#else -#include -#ifndef __WIN__ -#include -#include -#include -#include /* FIXME HAVE_FNMATCH_H or something */ -#else -#include -#include -#include -#endif -#endif -#include -#include -#include -#include - -#include "my_manage.h" - -#ifndef __NETWARE__ -#define ASSERT assert -extern char **environ; -#endif - - - -/****************************************************************************** - - macros - -******************************************************************************/ - -/****************************************************************************** - - global variables - -******************************************************************************/ - -/****************************************************************************** - - functions - -******************************************************************************/ - -/****************************************************************************** - - init_args() - - Init an argument list. - -******************************************************************************/ - -void init_args(arg_list_t *al) -{ - ASSERT(al != NULL); - - al->argc= 0; - al->size= ARG_BUF; - al->argv= malloc(al->size * sizeof(char *)); - ASSERT(al->argv != NULL); - - return; -} - -/****************************************************************************** - - add_arg() - - Add an argument to a list. - -******************************************************************************/ - -void add_arg(arg_list_t *al, const char *format, ...) -{ - va_list ap; - char temp[FN_REFLEN]; - - ASSERT(al != NULL); - - /* increase size */ - if (al->argc >= (int)al->size) - { - al->size+= ARG_BUF; - al->argv= realloc(al->argv, al->size * sizeof(char *)); - ASSERT(al->argv != NULL); - } - - if (format) - { - va_start(ap, format); - vsprintf(temp, format, ap); - va_end(ap); - - al->argv[al->argc]= malloc(strlen(temp)+1); - ASSERT(al->argv[al->argc] != NULL); - strcpy(al->argv[al->argc], temp); - - ++(al->argc); - } - else - { - al->argv[al->argc]= NULL; - } - - return; -} - -/****************************************************************************** - - free_args() - - Free an argument list. - -******************************************************************************/ - -void free_args(arg_list_t *al) -{ - int i; - - ASSERT(al != NULL); - - for (i= 0; i < al->argc; i++) - { - ASSERT(al->argv[i] != NULL); - free(al->argv[i]); - al->argv[i]= NULL; - } - - free(al->argv); - al->argc= 0; - al->argv= NULL; - - return; -} - -/****************************************************************************** - - sleep_until_file_deleted() - - Sleep until the given file is no longer found. - -******************************************************************************/ - -#ifndef __WIN__ -int sleep_until_file_deleted(char *pid_file) -#else -int sleep_until_file_deleted(HANDLE pid_file) -#endif -{ - int err= 0; /* Initiate to supress warning */ -#ifndef __WIN__ - struct stat buf; - int i; - - for (i= 0; (i < TRY_MAX) && (err= !stat(pid_file, &buf)); i++) sleep(1); - - if (err != 0) err= errno; -#else - err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT); -#endif - return err; -} - -/****************************************************************************** - - sleep_until_file_exists() - - Sleep until the given file exists. - -******************************************************************************/ - -#ifndef __WIN__ -int sleep_until_file_exists(char *pid_file) -#else -int sleep_until_file_exists(HANDLE pid_file) -#endif -{ - int err= 0; /* Initiate to supress warning */ -#ifndef __WIN__ - struct stat buf; - int i; - - for (i= 0; (i < TRY_MAX) && (err= stat(pid_file, &buf)); i++) sleep(1); - - if (err != 0) err= errno; -#else - err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT); -#endif - return err; -} - -/****************************************************************************** - - wait_for_server_start() - - Wait for the server on the given port to start. - -******************************************************************************/ - -int wait_for_server_start(char *bin_dir __attribute__((unused)), - char *mysqladmin_file, - char *user, char *password, int port,char *tmp_dir) -{ - arg_list_t al; - int err= 0; - char trash[FN_REFLEN]; - - /* mysqladmin file */ - snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir); - - /* args */ - init_args(&al); - add_arg(&al, "%s", mysqladmin_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--port=%u", port); - add_arg(&al, "--user=%s", user); - add_arg(&al, "--password=%s", password); - add_arg(&al, "--silent"); - add_arg(&al, "--host=localhost"); - -#ifndef __NETWARE__ - add_arg(&al, "--connect_timeout=10"); - add_arg(&al, "-w"); - add_arg(&al, "--protocol=tcp"); -#endif - add_arg(&al, "ping"); - - /* - NetWare does not support the connect timeout in the TCP/IP stack - -- we will try the ping multiple times - */ -#ifndef __WIN__ - { - int i; - for (i= 0; - (i < TRY_MAX) && (err= spawn(mysqladmin_file, &al, TRUE, NULL, - trash, NULL, NULL)); - i++) - sleep(1); - } -#else - err= spawn(mysqladmin_file, &al, TRUE, NULL,trash, NULL, NULL); -#endif - - /* free args */ - free_args(&al); - - return err; -} - -/****************************************************************************** - - spawn() - - Spawn the given path with the given arguments. - -******************************************************************************/ - -#ifdef __NETWARE__ -int spawn(char *path, arg_list_t *al, int join, char *input, - char *output, char *error, char *pid_file) -{ - pid_t pid; - int result= 0; - wiring_t wiring= { FD_UNUSED, FD_UNUSED, FD_UNUSED }; - unsigned long flags= PROC_CURRENT_SPACE | PROC_INHERIT_CWD; - - /* open wiring */ - if (input) - wiring.infd= open(input, O_RDONLY); - - if (output) - wiring.outfd= open(output, O_WRONLY | O_CREAT | O_TRUNC); - - if (error) - wiring.errfd= open(error, O_WRONLY | O_CREAT | O_TRUNC); - - /* procve requires a NULL */ - add_arg(al, NULL); - - /* go */ - pid= procve(path, flags, NULL, &wiring, NULL, NULL, 0, - NULL, (const char **)al->argv); - - /* close wiring */ - if (wiring.infd != -1) - close(wiring.infd); - - if (wiring.outfd != -1) - close(wiring.outfd); - - if (wiring.errfd != -1) - close(wiring.errfd); - - return result; -} -#elif __WIN__ - -int spawn(char *path, arg_list_t *al, int join, char *input, - char *output, char *error, HANDLE *pid) -{ - bool result; - int i; - STARTUPINFO startup_info; - PROCESS_INFORMATION process_information; - DWORD exit_code; - char win_args[1024]= ""; - - /* Skip the first parameter */ - for (i= 1; i < al->argc; i++) - { - ASSERT(al->argv[i] != NULL); - strcat(win_args,al->argv[i]); - strcat(win_args," "); - } - - memset(&startup_info,0,sizeof(STARTUPINFO)); - startup_info.cb= sizeof(STARTUPINFO); - - if (input) - freopen(input, "rb", stdin); - - if (output) - freopen(output, "wb", stdout); - - if (error) - freopen(error, "wb", stderr); - - result= CreateProcess( - path, - (LPSTR)&win_args, - NULL, - NULL, - TRUE, - 0, - NULL, - NULL, - &startup_info, - &process_information - ); - - if (result && process_information.hProcess) - { - if (join) - { - if (WaitForSingleObject(process_information.hProcess, mysqld_timeout) - == WAIT_TIMEOUT) - { - exit_code= -1; - } - else - { - GetExitCodeProcess(process_information.hProcess, &exit_code); - } - CloseHandle(process_information.hProcess); - } - else - { - exit_code= 0; - } - if (pid != NULL) - *pid= process_information.hProcess; - } - else - { - exit_code= -1; - } - if (input) - freopen("CONIN$","rb",stdin); - if (output) - freopen("CONOUT$","wb",stdout); - if (error) - freopen("CONOUT$","wb",stderr); - - return exit_code; -} -#else -int spawn(char *path, arg_list_t *al, int join, char *input, - char *output, char *error, char *pid_file __attribute__((unused))) -{ - pid_t pid; - int res_exec= 0; - int result= 0; - - pid= fork(); - - if (pid == -1) - { - fprintf(stderr, "fork was't created\n"); - /* We can't create the fork...exit with error */ - return EXIT_FAILURE; - } - - if (pid > 0) - { - /* The parent process is waiting for child process if join is not zero */ - if (join) - { - waitpid(pid, &result, 0); - if (WIFEXITED(result) != 0) - { - result= WEXITSTATUS(result); - } - else - { - result= EXIT_FAILURE; - } - } - } - else - { - - /* Child process */ - add_arg(al, NULL); - - /* Reassign streams */ - if (input) - freopen(input, "r", stdin); - - if (output) - freopen(output, "w", stdout); - - if (error) - freopen(error, "w", stderr); - - /* Spawn the process */ - if ((res_exec= execve(path, al->argv, environ)) < 0) - exit(EXIT_FAILURE); - - /* Restore streams */ - if (input) - freopen("/dev/tty", "r", stdin); - - if (output) - freopen("/dev/tty", "w", stdout); - - if (error) - freopen("/dev/tty", "w", stderr); - - exit(0); - } - - return result; -} -#endif -/****************************************************************************** - - stop_server() - - Stop the server with the given port and pid file. - -******************************************************************************/ - -int stop_server(char *bin_dir __attribute__((unused)), char *mysqladmin_file, - char *user, char *password, int port, -#ifndef __WIN__ - char *pid_file, -#else - HANDLE pid_file, -#endif - char *tmp_dir) -{ - arg_list_t al; - int err= 0; - char trash[FN_REFLEN]; - - snprintf(trash, FN_REFLEN, "%s/trash.out",tmp_dir); - - /* args */ - init_args(&al); - add_arg(&al, "%s", mysqladmin_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--port=%u", port); - add_arg(&al, "--user=%s", user); - add_arg(&al, "--password=%s", password); - add_arg(&al, "-O"); - add_arg(&al, "shutdown_timeout=20"); -#ifndef __NETWARE__ - add_arg(&al, "--protocol=tcp"); -#endif - add_arg(&al, "shutdown"); - - /* spawn */ - if ((err= spawn(mysqladmin_file, &al, TRUE, NULL, - trash, NULL, NULL)) == 0) - { - sleep_until_file_deleted(pid_file); - } - else - { -#ifndef __WIN__ - pid_t pid= get_server_pid(pid_file); - - /* shutdown failed - kill server */ - kill_server(pid); - - sleep(TRY_MAX); - - /* remove pid file if possible */ - err= remove(pid_file); -#else - TerminateProcess(pid_file,err); -#endif - } - - /* free args */ - free_args(&al); - - return err; -} - -/****************************************************************************** - - get_server_pid() - - Get the VM id with the given pid file. - -******************************************************************************/ - -#ifndef __WIN__ -pid_t get_server_pid(char *pid_file) -{ - char buf[FN_REFLEN]; - int fd, err; - char *p; - pid_t id= 0; - - /* discover id */ - fd= open(pid_file, O_RDONLY); - - err= read(fd, buf, FN_REFLEN); - - close(fd); - - if (err > 0) - { - /* terminate string */ - if ((p= strchr(buf, '\n')) != NULL) - { - *p= '\0'; - - /* check for a '\r' */ - if ((p= strchr(buf, '\r')) != NULL) - { - *p= '\0'; - } - } - else - { - buf[err]= '\0'; - } - - id= strtol(buf, NULL, 0); - } - - return id; -} - -/****************************************************************************** - - kill_server() - - Force a kill of the server with the given pid. - -******************************************************************************/ - -void kill_server(pid_t pid) -{ - if (pid > 0) - { -#if !defined(__NETWARE__) - /* Send SIGTERM to pid */ - kill(pid, SIGTERM); -#else /* __NETWARE__ */ - /* destroy vm */ - NXVmDestroy(pid); -#endif - } -} -#endif -/****************************************************************************** - - del_tree() - - Delete the directory and subdirectories. - -******************************************************************************/ - -void del_tree(char *dir) -{ -#ifndef __WIN__ - DIR *parent= opendir(dir); - struct dirent *entry; - char temp[FN_REFLEN]; - - if (parent == NULL) - { - return; - } - - while ((entry= readdir(parent)) != NULL) - { - /* create long name */ - snprintf(temp, FN_REFLEN, "%s/%s", dir, entry->d_name); - - if (entry->d_name[0] == '.') - { - /* Skip */ - } - else - { -/* FIXME missing test in acinclude.m4 */ -#ifndef STRUCT_DIRENT_HAS_D_TYPE - struct stat st; - - if (lstat(entry->d_name, &st) == -1) - { - /* FIXME error */ - return; - } - if (S_ISDIR(st.st_mode)) -#else - if (S_ISDIR(entry->d_type)) -#endif - { - /* delete subdirectory */ - del_tree(temp); - } - else - { - /* remove file */ - remove(temp); - } - } - } - /* remove directory */ - rmdir(dir); -#else - struct _finddata_t parent; -#if defined(_MSC_VER) && _MSC_VER > 1200 - intptr_t handle; -#else - long handle; -#endif /* _MSC_VER && _MSC_VER > 1200 */ - char temp[FN_REFLEN]; - char mask[FN_REFLEN]; - - snprintf(mask,FN_REFLEN,"%s/*.*",dir); - - if ((handle=_findfirst(mask,&parent)) == -1L) - { - return; - } - - do - { - /* create long name */ - snprintf(temp, FN_REFLEN, "%s/%s", dir, parent.name); - if (parent.name[0] == '.') - { - /* Skip */ - } - else - if (parent.attrib & _A_SUBDIR) - { - /* delete subdirectory */ - del_tree(temp); - } - else - { - /* remove file */ - remove(temp); - } - } while (_findnext(handle,&parent) == 0); - - _findclose(handle); - - /* remove directory */ - _rmdir(dir); -#endif -} - -/****************************************************************************** - - removef() - -******************************************************************************/ - -int removef(const char *format, ...) -{ -#ifdef __NETWARE__ - va_list ap; - char path[FN_REFLEN]; - - va_start(ap, format); - - vsnprintf(path, FN_REFLEN, format, ap); - - va_end(ap); - return remove(path); - -#elif __WIN__ - { - va_list ap; - char path[FN_REFLEN]; - struct _finddata_t parent; -#if defined(_MSC_VER) && _MSC_VER > 1200 - intptr_t handle; -#else - long handle; -#endif /* _MSC_VER && _MSC_VER > 1200 */ - char temp[FN_REFLEN]; - char *p; - - va_start(ap, format); - - vsnprintf(path, FN_REFLEN, format, ap); - - va_end(ap); - - p= path + strlen(path); - while (*p != '\\' && *p != '/' && p > path) p--; - - if ((handle=_findfirst(path,&parent)) == -1L) - { - /* if there is not files....it's ok */ - return 0; - } - - *p= '\0'; - - do - { - if (! (parent.attrib & _A_SUBDIR)) - { - snprintf(temp, FN_REFLEN, "%s/%s", path, parent.name); - remove(temp); - } - }while (_findnext(handle,&parent) == 0); - - _findclose(handle); - } -#else - DIR *parent; - struct dirent *entry; - char temp[FN_REFLEN]; - va_list ap; - char path[FN_REFLEN]; - char *p; - /* Get path with mask */ - va_start(ap, format); - - vsnprintf(path, FN_REFLEN, format, ap); - - va_end(ap); - - p= path + strlen(path); - while (*p != '\\' && *p != '/' && p > path) p--; - *p= '\0'; - p++; - - parent= opendir(path); - - if (parent == NULL) - { - return 1; /* Error, directory missing */ - } - - while ((entry= readdir(parent)) != NULL) - { - /* entry is not directory and entry matches with mask */ -#ifndef STRUCT_DIRENT_HAS_D_TYPE - struct stat st; - - /* create long name */ - snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name); - - if (lstat(temp, &st) == -1) - { - return 1; /* Error couldn't lstat file */ - } - - if (!S_ISDIR(st.st_mode) && !fnmatch(p, entry->d_name,0)) -#else - if (!S_ISDIR(entry->d_type) && !fnmatch(p, entry->d_name,0)) -#endif - { - /* create long name */ - snprintf(temp, FN_REFLEN, "%s/%s", path, entry->d_name); - /* Delete only files */ - remove(temp); - } - } -#endif - return 0; -} - -/****************************************************************************** - - get_basedir() - -******************************************************************************/ - -void get_basedir(char *argv0, char *basedir) -{ - char temp[FN_REFLEN]; - char *p; - int position; - - ASSERT(argv0 != NULL); - ASSERT(basedir != NULL); - - strcpy(temp, strlwr(argv0)); - while ((p= strchr(temp, '\\')) != NULL) *p= '/'; - - if ((position= strinstr(temp, "/bin/")) != 0) - { - p= temp + position; - *p= '\0'; - strcpy(basedir, temp); - } -} - -uint strinstr(reg1 const char *str,reg4 const char *search) -{ - reg2 my_string i,j; - my_string start= (my_string) str; - - skipp: - while (*str != '\0') - { - if (*str++ == *search) - { - i=(my_string) str; - j= (my_string) search+1; - while (*j) - if (*i++ != *j++) goto skipp; - return ((uint) (str - start)); - } - } - return (0); -} - -/****************************************************************************** - - remove_empty_file() - -******************************************************************************/ - -void remove_empty_file(const char *file_name) -{ - struct stat file; - - if (!stat(file_name,&file)) - { - if (!file.st_size) - remove(file_name); - } -} diff --git a/mysql-test/my_manage.h b/mysql-test/my_manage.h deleted file mode 100644 index 5df77b01af8..00000000000 --- a/mysql-test/my_manage.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - Copyright (c) 2002 Novell, Inc. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef _MY_MANAGE -#define _MY_MANAGE - -/****************************************************************************** - - includes - -******************************************************************************/ - -#include -#ifndef __WIN__ -#include -#endif -#ifndef __NETWARE__ -#include -#include -#include - -#ifndef __WIN__ -#define strnicmp strncasecmp -#define strlwr(STRARG) (STRARG) -#else -int my_vsnprintf_(char *to, size_t n, const char* value, ...); -#endif -#endif - -/****************************************************************************** - - macros - -******************************************************************************/ - -#define ARG_BUF 10 -#define TRY_MAX 5 - -#ifdef __WIN__ -#define PATH_MAX _MAX_PATH -#define NAME_MAX _MAX_FNAME -#define kill(A,B) TerminateProcess((HANDLE)A,0) -#define NOT_NEED_PID 0 -#define MASTER_PID 1 -#define SLAVE_PID 2 -#define mysqld_timeout 60000 - -int pid_mode; -bool run_server; -bool skip_first_param; - -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#endif - - -/****************************************************************************** - - structures - -******************************************************************************/ - -typedef struct -{ - - int argc; - char **argv; - - size_t size; - -} arg_list_t; - -#ifdef __WIN__ -typedef int pid_t; -#endif -/****************************************************************************** - - global variables - -******************************************************************************/ - -/****************************************************************************** - - prototypes - -******************************************************************************/ - -void init_args(arg_list_t *); -void add_arg(arg_list_t *, const char *, ...); -void free_args(arg_list_t *); - -#ifndef __WIN__ -int sleep_until_file_exists(char *); -int sleep_until_file_deleted(char *); -#else -int sleep_until_file_exists(HANDLE); -int sleep_until_file_deleted(HANDLE); -#endif -int wait_for_server_start(char *, char *, char *, char *, int,char *); - -#ifndef __WIN__ -int spawn(char *, arg_list_t *, int, char *, char *, char *, char *); -#else -int spawn(char *, arg_list_t *, int , char *, char *, char *, HANDLE *); -#endif - -#ifndef __WIN__ -int stop_server(char *, char *, char *, char *, int, char *,char *); -pid_t get_server_pid(char *); -void kill_server(pid_t pid); -#else -int stop_server(char *, char *, char *, char *, int, HANDLE,char *); -#endif -void del_tree(char *); -int removef(const char *, ...); - -void get_basedir(char *, char *); -void remove_empty_file(const char *file_name); - -bool create_system_files(const char *mdata,const char *output_file, bool test); - -#endif /* _MY_MANAGE */ diff --git a/mysql-test/mysql_test_run_new.c b/mysql-test/mysql_test_run_new.c deleted file mode 100644 index f9c0045472d..00000000000 --- a/mysql-test/mysql_test_run_new.c +++ /dev/null @@ -1,1941 +0,0 @@ -/* - Copyright (c) 2002, 2003 Novell, Inc. All Rights Reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#ifndef __WIN__ -#include -#endif -#include -#ifdef __NETWARE__ -#include -#include -#endif -#include -#include -#ifndef __WIN__ -#include -#endif -#include -#ifdef __NETWARE__ -#include -#endif -#ifdef __WIN__ -#include -#include -#include -#endif - -#include "my_manage.h" - -/****************************************************************************** - - macros - -******************************************************************************/ - -#define HEADER "TEST RESULT \n" -#define DASH "-------------------------------------------------------\n" - -#define NW_TEST_SUFFIX ".nw-test" -#define NW_RESULT_SUFFIX ".nw-result" -#define TEST_SUFFIX ".test" -#define RESULT_SUFFIX ".result" -#define REJECT_SUFFIX ".reject" -#define OUT_SUFFIX ".out" -#define ERR_SUFFIX ".err" - -const char *TEST_PASS= "[ pass ]"; -const char *TEST_SKIP= "[ skip ]"; -const char *TEST_FAIL= "[ fail ]"; -const char *TEST_BAD= "[ bad ]"; -const char *TEST_IGNORE= "[ignore]"; - -/****************************************************************************** - - global variables - -******************************************************************************/ - -#ifdef __NETWARE__ -static char base_dir[FN_REFLEN]= "sys:/mysql"; -#else -static char base_dir[FN_REFLEN]= ".."; -#endif -static char db[FN_LEN]= "test"; -static char user[FN_LEN]= "root"; -static char password[FN_LEN]= ""; - -int master_port= 9306; -int slave_port= 9307; - -#if !defined(__NETWARE__) && !defined(__WIN__) -static char master_socket[FN_REFLEN]= "./var/tmp/master.sock"; -static char slave_socket[FN_REFLEN]= "./var/tmp/slave.sock"; -#endif - -#define MAX_COUNT_TESTES 1024 - -#ifdef __WIN__ -# define sting_compare_func _stricmp -#else -# ifdef HAVE_STRCASECMP -# define sting_compare_func strcasecmp -# else -# define sting_compare_func strcmp -# endif -#endif - -/* comma delimited list of tests to skip or empty string */ -#ifndef __WIN__ -static char skip_test[FN_REFLEN]= " lowercase_table3 , system_mysql_db_fix "; -#else -/* - The most ignore testes contain the calls of system command - - lowercase_table3 is disabled by Gerg - system_mysql_db_fix is disabled by Gerg - sp contains a command system - rpl_EE_error contains a command system - rpl_loaddatalocal contains a command system - ndb_autodiscover contains a command system - rpl_rotate_logs contains a command system - repair contains a command system - rpl_trunc_binlog contains a command system - mysqldump contains a command system - rpl000001 makes non-exit loop...temporary skiped -*/ -static char skip_test[FN_REFLEN]= -" lowercase_table3 ," -" system_mysql_db_fix ," -" sp ," -" rpl_EE_error ," -" rpl_loaddatalocal ," -" ndb_autodiscover ," -" rpl_rotate_logs ," -" repair ," -" rpl_trunc_binlog ," -" mysqldump ," -" rpl000001 ," - -" derived ," -" group_by ," -" select ," -" rpl000015 ," -" subselect "; -#endif -static char ignore_test[FN_REFLEN]= ""; - -static char bin_dir[FN_REFLEN]; -static char mysql_test_dir[FN_REFLEN]; -static char test_dir[FN_REFLEN]; -static char mysql_tmp_dir[FN_REFLEN]; -static char result_dir[FN_REFLEN]; -static char master_dir[FN_REFLEN]; -static char slave_dir[FN_REFLEN]; -static char slave1_dir[FN_REFLEN]; -static char slave2_dir[FN_REFLEN]; -static char lang_dir[FN_REFLEN]; -static char char_dir[FN_REFLEN]; - -static char mysqladmin_file[FN_REFLEN]; -static char mysqld_file[FN_REFLEN]; -static char mysqltest_file[FN_REFLEN]; -#ifndef __WIN__ -static char master_pid[FN_REFLEN]; -static char slave_pid[FN_REFLEN]; -static char sh_file[FN_REFLEN]= "/bin/sh"; -#else -static HANDLE master_pid; -static HANDLE slave_pid; -#endif - -static char master_opt[FN_REFLEN]= ""; -static char slave_opt[FN_REFLEN]= ""; - -static char slave_master_info[FN_REFLEN]= ""; - -static char master_init_script[FN_REFLEN]= ""; -static char slave_init_script[FN_REFLEN]= ""; - -/* OpenSSL */ -static char ca_cert[FN_REFLEN]; -static char server_cert[FN_REFLEN]; -static char server_key[FN_REFLEN]; -static char client_cert[FN_REFLEN]; -static char client_key[FN_REFLEN]; - -int total_skip= 0; -int total_pass= 0; -int total_fail= 0; -int total_test= 0; - -int total_ignore= 0; - -int use_openssl= FALSE; -int master_running= FALSE; -int slave_running= FALSE; -int skip_slave= TRUE; -int single_test= TRUE; - -int restarts= 0; - -FILE *log_fd= NULL; - -static char argument[FN_REFLEN]; - -/****************************************************************************** - - functions - -******************************************************************************/ - -/****************************************************************************** - - prototypes - -******************************************************************************/ - -void report_stats(); -void install_db(char *); -void mysql_install_db(); -void start_master(); -void start_slave(); -void mysql_start(); -void stop_slave(); -void stop_master(); -void mysql_stop(); -void mysql_restart(); -int read_option(char *, char *); -void run_test(char *); -void setup(char *); -void vlog(const char *, va_list); -void mlog(const char *, ...); -void log_info(const char *, ...); -void log_error(const char *, ...); -void log_errno(const char *, ...); -void die(const char *); -char *str_tok(char* dest, char *string, const char *delim); -#ifndef __WIN__ -void run_init_script(const char *script_name); -#endif -/****************************************************************************** - - report_stats() - - Report the gathered statistics. - -******************************************************************************/ - -void report_stats() -{ - if (total_fail == 0) - { - mlog("\nAll %d test(s) were successful.\n", total_test); - } - else - { - double percent= ((double)total_pass / total_test) * 100; - - mlog("\nFailed %u/%u test(s), %.02f%% successful.\n", - total_fail, total_test, percent); - mlog("\nThe .out and .err files in %s may give you some\n", result_dir); - mlog("hint of what when wrong.\n"); - mlog("\nIf you want to report this error, please first read " - "the documentation\n"); - mlog("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n"); - } -} - -/****************************************************************************** - - install_db() - - Install the a database. - -******************************************************************************/ - -void install_db(char *datadir) -{ - arg_list_t al; - int err; - char input[FN_REFLEN]; - char output[FN_REFLEN]; - char error[FN_REFLEN]; - - /* input file */ -#ifdef __NETWARE__ - snprintf(input, FN_REFLEN, "%s/bin/init_db.sql", base_dir); -#else - snprintf(input, FN_REFLEN, "%s/mysql-test/init_db.sql", base_dir); -#endif - snprintf(output, FN_REFLEN, "%s/install.out", datadir); - snprintf(error, FN_REFLEN, "%s/install.err", datadir); - - if (create_system_files(datadir,input, TRUE)) - die("Unable to create init_db.sql."); - /* args */ - init_args(&al); - /* - XXX: If mysqld is compiled with DISABLE_GRANT_OPTIONS defined, it - will not recognize the --bootstrap, --init-file or --skip-grant- - tables options. If this is needed here, please check - MYSQLD_BOOTSTRAP in the environment, and use its value instead of - mysqld_file if it is set. See mysql-test-run.pl and - mysql_install_db. - */ - add_arg(&al, mysqld_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--bootstrap"); - add_arg(&al, "--skip-grant-tables"); - add_arg(&al, "--basedir=%s", base_dir); - add_arg(&al, "--datadir=%s", datadir); - add_arg(&al, "--skip-innodb"); - add_arg(&al, "--skip-ndbcluster"); - add_arg(&al, "--skip-bdb"); -#ifndef __NETWARE__ - add_arg(&al, "--character-sets-dir=%s", char_dir); - add_arg(&al, "--language=%s", lang_dir); -#endif -// added - add_arg(&al, "--default-character-set=latin1"); - add_arg(&al, "--innodb_data_file_path=ibdata1:50M"); - - /* spawn */ - if ((err= spawn(mysqld_file, &al, TRUE, input, output, error, NULL)) != 0) - { - die("Unable to create database."); - } - - /* free args */ - free_args(&al); -} - -/****************************************************************************** - - mysql_install_db() - - Install the test databases. - -******************************************************************************/ - -void mysql_install_db() -{ - char temp[FN_REFLEN]; - - /* var directory */ - snprintf(temp, FN_REFLEN, "%s/var", mysql_test_dir); - - /* create var directory */ -#ifndef __WIN__ - mkdir(temp, S_IRWXU); - /* create subdirectories */ - mlog("Creating test-suite folders...\n"); - snprintf(temp, FN_REFLEN, "%s/var/run", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/tmp", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/master-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/master-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/master-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); - - snprintf(temp, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/slave-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/slave-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); - - snprintf(temp, FN_REFLEN, "%s/var/slave1-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/slave1-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/slave1-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); - - snprintf(temp, FN_REFLEN, "%s/var/slave2-data", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/slave2-data/mysql", mysql_test_dir); - mkdir(temp, S_IRWXU); - snprintf(temp, FN_REFLEN, "%s/var/slave2-data/test", mysql_test_dir); - mkdir(temp, S_IRWXU); -#else - mkdir(temp); - /* create subdirectories */ - mlog("Creating test-suite folders...\n"); - snprintf(temp, FN_REFLEN, "%s/var/run", mysql_test_dir); - mkdir(temp); - snprintf(temp, FN_REFLEN, "%s/var/tmp", mysql_test_dir); - mkdir(temp); - snprintf(temp, FN_REFLEN, "%s/var/master-data", mysql_test_dir); - mkdir(temp); - snprintf(temp, FN_REFLEN, "%s/var/master-data/mysql", mysql_test_dir); - mkdir(temp); - snprintf(temp, FN_REFLEN, "%s/var/master-data/test", mysql_test_dir); - mkdir(temp); - snprintf(temp, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); - mkdir(temp); - snprintf(temp, FN_REFLEN, "%s/var/slave-data/mysql", mysql_test_dir); - mkdir(temp); - snprintf(temp, FN_REFLEN, "%s/var/slave-data/test", mysql_test_dir); - mkdir(temp); -#endif - - /* install databases */ - mlog("Creating test databases for master... \n"); - install_db(master_dir); - mlog("Creating test databases for slave... \n"); - install_db(slave_dir); - install_db(slave1_dir); - install_db(slave2_dir); -} - -/****************************************************************************** - - start_master() - - Start the master server. - -******************************************************************************/ - -void start_master() -{ - arg_list_t al; - int err; - char master_out[FN_REFLEN]; - char master_err[FN_REFLEN]; - char temp2[FN_REFLEN]; - - /* remove old berkeley db log files that can confuse the server */ - removef("%s/log.*", master_dir); - - /* remove stale binary logs */ - removef("%s/var/log/*-bin.*", mysql_test_dir); - - /* remove stale binary logs */ - removef("%s/var/log/*.index", mysql_test_dir); - - /* remove master.info file */ - removef("%s/master.info", master_dir); - - /* remove relay files */ - removef("%s/var/log/*relay*", mysql_test_dir); - - /* remove relay-log.info file */ - removef("%s/relay-log.info", master_dir); - - /* init script */ - if (master_init_script[0] != 0) - { -#ifdef __NETWARE__ - /* TODO: use the scripts */ - if (strinstr(master_init_script, "repair_part2-master.sh") != 0) - { - FILE *fp; - - /* create an empty index file */ - snprintf(temp, FN_REFLEN, "%s/test/t1.MYI", master_dir); - fp= fopen(temp, "wb+"); - - fputs("1", fp); - - fclose(fp); - } -#elif !defined(__WIN__) - run_init_script(master_init_script); -#endif - } - - /* redirection files */ - snprintf(master_out, FN_REFLEN, "%s/var/run/master%u.out", - mysql_test_dir, restarts); - snprintf(master_err, FN_REFLEN, "%s/var/run/master%u.err", - mysql_test_dir, restarts); -#ifndef __WIN__ - snprintf(temp2,FN_REFLEN,"%s/var",mysql_test_dir); - mkdir(temp2,S_IRWXU); - snprintf(temp2,FN_REFLEN,"%s/var/log",mysql_test_dir); - mkdir(temp2,S_IRWXU); -#else - snprintf(temp2,FN_REFLEN,"%s/var",mysql_test_dir); - mkdir(temp2); - snprintf(temp2,FN_REFLEN,"%s/var/log",mysql_test_dir); - mkdir(temp2); -#endif - /* args */ - init_args(&al); - add_arg(&al, "%s", mysqld_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--log-bin=%s/var/log/master-bin",mysql_test_dir); - add_arg(&al, "--server-id=1"); - add_arg(&al, "--basedir=%s", base_dir); - add_arg(&al, "--port=%u", master_port); -#if !defined(__NETWARE__) && !defined(__WIN__) - add_arg(&al, "--socket=%s",master_socket); -#endif - add_arg(&al, "--local-infile"); - add_arg(&al, "--core"); - add_arg(&al, "--log-bin-trust-function-creators"); - add_arg(&al, "--datadir=%s", master_dir); -#ifndef __WIN__ - add_arg(&al, "--pid-file=%s", master_pid); -#endif - add_arg(&al, "--character-sets-dir=%s", char_dir); - add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); - add_arg(&al, "--language=%s", lang_dir); - - add_arg(&al, "--rpl-recovery-rank=1"); - add_arg(&al, "--init-rpl-role=master"); - add_arg(&al, "--default-character-set=latin1"); -// add_arg(&al, "--innodb_data_file_path=ibdata1:50M"); -#ifdef DEBUG /* only for debug builds */ - add_arg(&al, "--debug"); -#endif - - if (use_openssl) - { - add_arg(&al, "--ssl-ca=%s", ca_cert); - add_arg(&al, "--ssl-cert=%s", server_cert); - add_arg(&al, "--ssl-key=%s", server_key); - } - - /* $MASTER_40_ARGS */ - add_arg(&al, "--rpl-recovery-rank=1"); - add_arg(&al, "--init-rpl-role=master"); - - /* $SMALL_SERVER */ - add_arg(&al, "-O"); - add_arg(&al, "key_buffer_size=1M"); - add_arg(&al, "-O"); - add_arg(&al, "sort_buffer=256K"); - add_arg(&al, "-O"); - add_arg(&al, "max_heap_table_size=1M"); - - /* $EXTRA_MASTER_OPT */ - if (master_opt[0] != 0) - { - char *p; - - p= (char *)str_tok(argument, master_opt, " \t"); - if (!strstr(master_opt, "timezone")) - { - while (p) - { - add_arg(&al, "%s", p); - p= (char *)str_tok(argument, NULL, " \t"); - } - } - } - - /* remove the pid file if it exists */ -#ifndef __WIN__ - remove(master_pid); -#endif - - /* spawn */ -#ifdef __WIN__ - if ((err= spawn(mysqld_file, &al, FALSE, NULL, - master_out, master_err, &master_pid)) == 0) -#else - if ((err= spawn(mysqld_file, &al, FALSE, NULL, - master_out, master_err, master_pid)) == 0) -#endif - { - sleep_until_file_exists(master_pid); - - if ((err= wait_for_server_start(bin_dir, mysqladmin_file, user, password, - master_port, mysql_tmp_dir)) == 0) - { - master_running= TRUE; - } - else - { - log_error("The master server went down early."); - } - } - else - { - log_error("Unable to start master server."); - } - - /* free_args */ - free_args(&al); -} - -/****************************************************************************** - - start_slave() - - Start the slave server. - -******************************************************************************/ - -void start_slave() -{ - arg_list_t al; - int err; - char slave_out[FN_REFLEN]; - char slave_err[FN_REFLEN]; - - /* skip? */ - if (skip_slave) return; - - /* remove stale binary logs */ - removef("%s/*-bin.*", slave_dir); - - /* remove stale binary logs */ - removef("%s/*.index", slave_dir); - - /* remove master.info file */ - removef("%s/master.info", slave_dir); - - /* remove relay files */ - removef("%s/var/log/*relay*", mysql_test_dir); - - /* remove relay-log.info file */ - removef("%s/relay-log.info", slave_dir); - - /* init script */ - if (slave_init_script[0] != 0) - { -#ifdef __NETWARE__ - /* TODO: use the scripts */ - if (strinstr(slave_init_script, "rpl000016-slave.sh") != 0) - { - /* create empty master.info file */ - snprintf(temp, FN_REFLEN, "%s/master.info", slave_dir); - close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO)); - } - else if (strinstr(slave_init_script, "rpl000017-slave.sh") != 0) - { - FILE *fp; - - /* create a master.info file */ - snprintf(temp, FN_REFLEN, "%s/master.info", slave_dir); - fp= fopen(temp, "wb+"); - - fputs("master-bin.000001\n", fp); - fputs("4\n", fp); - fputs("127.0.0.1\n", fp); - fputs("replicate\n", fp); - fputs("aaaaaaaaaaaaaaab\n", fp); - fputs("9306\n", fp); - fputs("1\n", fp); - fputs("0\n", fp); - - fclose(fp); - } - else if (strinstr(slave_init_script, "rpl_rotate_logs-slave.sh") != 0) - { - /* create empty master.info file */ - snprintf(temp, FN_REFLEN, "%s/master.info", slave_dir); - close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO)); - } -#elif !defined(__WIN__) - run_init_script(slave_init_script); -#endif - } - - /* redirection files */ - snprintf(slave_out, FN_REFLEN, "%s/var/run/slave%u.out", - mysql_test_dir, restarts); - snprintf(slave_err, FN_REFLEN, "%s/var/run/slave%u.err", - mysql_test_dir, restarts); - - /* args */ - init_args(&al); - add_arg(&al, "%s", mysqld_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--log-bin=slave-bin"); - add_arg(&al, "--relay_log=slave-relay-bin"); - add_arg(&al, "--basedir=%s", base_dir); -#if !defined(__NETWARE__) && !defined(__WIN__) - add_arg(&al, "--socket=%s",slave_socket); -#endif - add_arg(&al, "--port=%u", slave_port); - add_arg(&al, "--datadir=%s", slave_dir); -#ifndef __WIN__ - add_arg(&al, "--pid-file=%s", slave_pid); -#endif - add_arg(&al, "--character-sets-dir=%s", char_dir); - add_arg(&al, "--core"); - add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); - add_arg(&al, "--language=%s", lang_dir); - - add_arg(&al, "--exit-info=256"); - add_arg(&al, "--log-slave-updates"); - add_arg(&al, "--init-rpl-role=slave"); - add_arg(&al, "--skip-innodb"); - add_arg(&al, "--skip-slave-start"); - add_arg(&al, "--slave-load-tmpdir=../../var/tmp"); - - add_arg(&al, "--report-user=%s", user); - add_arg(&al, "--report-host=127.0.0.1"); - add_arg(&al, "--report-port=%u", slave_port); - - add_arg(&al, "--master-retry-count=10"); - add_arg(&al, "-O"); - add_arg(&al, "slave_net_timeout=10"); - add_arg(&al, "--log-slave-updates"); - add_arg(&al, "--log=%s/var/log/slave.log", mysql_test_dir); - add_arg(&al, "--default-character-set=latin1"); - add_arg(&al, "--skip-ndbcluster"); - -#ifdef DEBUG /* only for debug builds */ - add_arg(&al, "--debug"); -#endif - - if (use_openssl) - { - add_arg(&al, "--ssl-ca=%s", ca_cert); - add_arg(&al, "--ssl-cert=%s", server_cert); - add_arg(&al, "--ssl-key=%s", server_key); - } - - /* slave master info */ - if (slave_master_info[0] != 0) - { - char *p; - - p= (char *)str_tok(argument, slave_master_info, " \t"); - - while (p) - { - add_arg(&al, "%s", p); - p= (char *)str_tok(argument, NULL, " \t"); - } - } - else - { - add_arg(&al, "--master-user=%s", user); - add_arg(&al, "--master-password=%s", password); - add_arg(&al, "--master-host=127.0.0.1"); - add_arg(&al, "--master-port=%u", master_port); - add_arg(&al, "--master-connect-retry=1"); - add_arg(&al, "--server-id=2"); - add_arg(&al, "--rpl-recovery-rank=2"); - } - - /* small server */ - add_arg(&al, "-O"); - add_arg(&al, "key_buffer_size=1M"); - add_arg(&al, "-O"); - add_arg(&al, "sort_buffer=256K"); - add_arg(&al, "-O"); - add_arg(&al, "max_heap_table_size=1M"); - - - /* opt args */ - if (slave_opt[0] != 0) - { - char *p; - - p= (char *)str_tok(argument, slave_opt, " \t"); - - while (p) - { - add_arg(&al, "%s", p); - p= (char *)str_tok(argument, NULL, " \t"); - } - } - - /* remove the pid file if it exists */ -#ifndef __WIN__ - remove(slave_pid); -#endif - /* spawn */ -#ifdef __WIN__ - if ((err= spawn(mysqld_file, &al, FALSE, NULL, - slave_out, slave_err, &slave_pid)) == 0) -#else - if ((err= spawn(mysqld_file, &al, FALSE, NULL, - slave_out, slave_err, slave_pid)) == 0) -#endif - { - sleep_until_file_exists(slave_pid); - - if ((err= wait_for_server_start(bin_dir, mysqladmin_file, user, password, - slave_port, mysql_tmp_dir)) == 0) - { - slave_running= TRUE; - } - else - { - log_error("The slave server went down early."); - } - } - else - { - log_error("Unable to start slave server."); - } - - /* free args */ - free_args(&al); -} - -/****************************************************************************** - - mysql_start() - - Start the mysql servers. - -******************************************************************************/ - -void mysql_start() -{ - - - printf("loading master...\r"); - start_master(); - - printf("loading slave...\r"); - start_slave(); - - /* activate the test screen */ -#ifdef __NETWARE__ - ActivateScreen(getscreenhandle()); -#endif -} - -/****************************************************************************** - - stop_slave() - - Stop the slave server. - -******************************************************************************/ - -void stop_slave() -{ - int err; - - /* running? */ - if (!slave_running) return; - - /* stop */ - if ((err= stop_server(bin_dir, mysqladmin_file, user, password, - slave_port, slave_pid, mysql_tmp_dir)) == 0) - { - slave_running= FALSE; - } - else - { - log_error("Unable to stop slave server."); - } -} - -/****************************************************************************** - - stop_master() - - Stop the master server. - -******************************************************************************/ - -void stop_master() -{ - int err; - - /* running? */ - if (!master_running) return; - - if ((err= stop_server(bin_dir, mysqladmin_file, user, password, - master_port, master_pid, mysql_tmp_dir)) == 0) - { - master_running= FALSE; - } - else - { - log_error("Unable to stop master server."); - } -} - -/****************************************************************************** - - mysql_stop() - - Stop the mysql servers. - -******************************************************************************/ - -void mysql_stop() -{ - - stop_master(); - - stop_slave(); - - /* activate the test screen */ -#ifdef __NETWARE__ - ActivateScreen(getscreenhandle()); -#endif -} - -/****************************************************************************** - - mysql_restart() - - Restart the mysql servers. - -******************************************************************************/ - -void mysql_restart() -{ -/* log_info("Restarting the MySQL server(s): %u", ++restarts); */ - - mysql_stop(); - - mlog(DASH); - sleep(1); - - mysql_start(); -} - -/****************************************************************************** - - read_option() - - Read the option file. - -******************************************************************************/ - -int read_option(char *opt_file, char *opt) -{ - int fd, err; - char *p; - char buf[FN_REFLEN]; - - /* copy current option */ - strncpy(buf, opt, FN_REFLEN); - - /* open options file */ - fd= open(opt_file, O_RDONLY); - err= read(fd, opt, FN_REFLEN); - close(fd); - - if (err > 0) - { - /* terminate string */ - if ((p= strchr(opt, '\n')) != NULL) - { - *p= 0; - - /* check for a '\r' */ - if ((p= strchr(opt, '\r')) != NULL) - { - *p= 0; - } - } - else - { - opt[err]= 0; - } - - /* check for $MYSQL_TEST_DIR */ - if ((p= strstr(opt, "$MYSQL_TEST_DIR")) != NULL) - { - char temp[FN_REFLEN]; - - *p= 0; - - strcpy(temp, p + strlen("$MYSQL_TEST_DIR")); - strcat(opt, mysql_test_dir); - strcat(opt, temp); - } - /* Check for double backslash and replace it with single bakslash */ - if ((p= strstr(opt, "\\\\")) != NULL) - { - /* bmove is guranteed to work byte by byte */ - bmove(p, p+1, strlen(p)+1); - } - } - else - { - /* clear option */ - *opt= 0; - } - - /* compare current option with previous */ - return strcmp(opt, buf); -} - -/****************************************************************************** - - run_test() - - Run the given test case. - -******************************************************************************/ - -void run_test(char *test) -{ - char temp[FN_REFLEN]; - const char *rstr; - int skip= FALSE, ignore=FALSE; - int restart= FALSE; - int flag= FALSE; - struct stat info; - - /* skip tests in the skip list */ - snprintf(temp, FN_REFLEN, " %s ", test); - skip= (strinstr(skip_test, temp) != 0); - if (skip == FALSE) - ignore= (strinstr(ignore_test, temp) != 0); - - snprintf(master_init_script, FN_REFLEN, "%s/%s-master.sh", test_dir, test); - snprintf(slave_init_script, FN_REFLEN, "%s/%s-slave.sh", test_dir, test); -#ifdef __WIN__ - if (! stat(master_init_script, &info)) - skip= TRUE; - if (!stat(slave_init_script, &info)) - skip= TRUE; -#endif - if (ignore) - { - /* show test */ - mlog("%-46s ", test); - - /* ignore */ - rstr= TEST_IGNORE; - ++total_ignore; - } - else if (!skip) /* skip test? */ - { - char test_file[FN_REFLEN]; - char master_opt_file[FN_REFLEN]; - char slave_opt_file[FN_REFLEN]; - char slave_master_info_file[FN_REFLEN]; - char result_file[FN_REFLEN]; - char reject_file[FN_REFLEN]; - char out_file[FN_REFLEN]; - char err_file[FN_REFLEN]; - int err; - arg_list_t al; - /* skip slave? */ - flag= skip_slave; - skip_slave= (strncmp(test, "rpl", 3) != 0); - if (flag != skip_slave) restart= TRUE; - - /* create files */ - snprintf(master_opt_file, FN_REFLEN, "%s/%s-master.opt", test_dir, test); - snprintf(slave_opt_file, FN_REFLEN, "%s/%s-slave.opt", test_dir, test); - snprintf(slave_master_info_file, FN_REFLEN, "%s/%s.slave-mi", - test_dir, test); - snprintf(reject_file, FN_REFLEN, "%s/%s%s", - result_dir, test, REJECT_SUFFIX); - snprintf(out_file, FN_REFLEN, "%s/%s%s", result_dir, test, OUT_SUFFIX); - snprintf(err_file, FN_REFLEN, "%s/%s%s", result_dir, test, ERR_SUFFIX); - - /* netware specific files */ - snprintf(test_file, FN_REFLEN, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX); - if (stat(test_file, &info)) - { - snprintf(test_file, FN_REFLEN, "%s/%s%s", test_dir, test, TEST_SUFFIX); - if (access(test_file,0)) - { - printf("Invalid test name %s, %s file not found\n",test,test_file); - return; - } - } - - snprintf(result_file, FN_REFLEN, "%s/%s%s", - result_dir, test, NW_RESULT_SUFFIX); - if (stat(result_file, &info)) - { - snprintf(result_file, FN_REFLEN, "%s/%s%s", - result_dir, test, RESULT_SUFFIX); - } - - /* init scripts */ - if (stat(master_init_script, &info)) - master_init_script[0]= 0; - else - restart= TRUE; - - if (stat(slave_init_script, &info)) - slave_init_script[0]= 0; - else - restart= TRUE; - - /* read options */ - if (read_option(master_opt_file, master_opt)) restart= TRUE; - if (read_option(slave_opt_file, slave_opt)) restart= TRUE; - if (read_option(slave_master_info_file, slave_master_info)) restart= TRUE; - - /* cleanup previous run */ - remove(reject_file); - remove(out_file); - remove(err_file); - - /* start or restart? */ - if (!master_running) mysql_start(); - else if (restart) mysql_restart(); - - /* show test */ - mlog("%-46s ", test); - - /* args */ - init_args(&al); - add_arg(&al, "%s", mysqltest_file); - add_arg(&al, "--no-defaults"); - add_arg(&al, "--port=%u", master_port); -#if !defined(__NETWARE__) && !defined(__WIN__) - add_arg(&al, "--socket=%s", master_socket); - add_arg(&al, "--tmpdir=%s", mysql_tmp_dir); -#endif - add_arg(&al, "--database=%s", db); - add_arg(&al, "--user=%s", user); - add_arg(&al, "--password=%s", password); - add_arg(&al, "--silent"); - add_arg(&al, "--basedir=%s/", mysql_test_dir); - add_arg(&al, "--host=127.0.0.1"); - add_arg(&al, "--skip-safemalloc"); - add_arg(&al, "-v"); - add_arg(&al, "-R"); - add_arg(&al, "%s", result_file); - - - if (use_openssl) - { - add_arg(&al, "--ssl-ca=%s", ca_cert); - add_arg(&al, "--ssl-cert=%s", client_cert); - add_arg(&al, "--ssl-key=%s", client_key); - } - - /* spawn */ - err= spawn(mysqltest_file, &al, TRUE, test_file, out_file, err_file, NULL); - /* free args */ - free_args(&al); - - remove_empty_file(out_file); - remove_empty_file(err_file); - - if (err == 0) - { - /* pass */ - rstr= TEST_PASS; - ++total_pass; - - /* increment total */ - ++total_test; - } - else if (err == 2) - { - /* skip */ - rstr= TEST_SKIP; - ++total_skip; - } - else if (err == 1) - { - /* fail */ - rstr= TEST_FAIL; - ++total_fail; - - /* increment total */ - ++total_test; - } - else - { - rstr= TEST_BAD; - } - } - else /* early skips */ - { - /* show test */ - mlog("%-46s ", test); - - /* skip */ - rstr= TEST_SKIP; - ++total_skip; - } - - /* result */ - mlog("%-14s\n", rstr); -} - -/****************************************************************************** - - vlog() - - Log the message. - -******************************************************************************/ - -void vlog(const char *format, va_list ap) -{ - vfprintf(stdout, format, ap); - fflush(stdout); - - if (log_fd) - { - vfprintf(log_fd, format, ap); - fflush(log_fd); - } -} - -/****************************************************************************** - - log() - - Log the message. - -******************************************************************************/ - -void mlog(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - vlog(format, ap); - - va_end(ap); -} - -/****************************************************************************** - - log_info() - - Log the given information. - -******************************************************************************/ - -void log_info(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - mlog("-- INFO : "); - vlog(format, ap); - mlog("\n"); - - va_end(ap); -} - -/****************************************************************************** - - log_error() - - Log the given error. - -******************************************************************************/ - -void log_error(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - mlog("-- ERROR: "); - vlog(format, ap); - mlog("\n"); - - va_end(ap); -} - -/****************************************************************************** - - log_errno() - - Log the given error and errno. - -******************************************************************************/ - -void log_errno(const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - - mlog("-- ERROR: (%003u) ", errno); - vlog(format, ap); - mlog("\n"); - - va_end(ap); -} - -/****************************************************************************** - - die() - - Exit the application. - -******************************************************************************/ - -void die(const char *msg) -{ - log_error(msg); -#ifdef __NETWARE__ - pressanykey(); -#endif - exit(-1); -} - -/****************************************************************************** - - setup() - - Setup the mysql test enviornment. - -******************************************************************************/ - -void setup(char *file __attribute__((unused))) -{ - char temp[FN_REFLEN]; -#if defined(__WIN__) || defined(__NETWARE__) - char file_path[FN_REFLEN*2]; -#endif - char *p; - int position; - - /* set the timezone for the timestamp test */ -#ifdef __WIN__ - _putenv( "TZ=GMT-3" ); -#else - putenv((char *)"TZ=GMT-3"); -#endif - /* find base dir */ -#ifdef __NETWARE__ - strcpy(temp, strlwr(file)); - while ((p= strchr(temp, '\\')) != NULL) *p= '/'; -#else - getcwd(temp, FN_REFLEN); - position= strlen(temp); - temp[position]= '/'; - temp[position+1]= 0; -#ifdef __WIN__ - while ((p= strchr(temp, '\\')) != NULL) *p= '/'; -#endif -#endif - - if ((position= strinstr(temp, "/mysql-test/")) != 0) - { - p= temp + position - 1; - *p= 0; - strcpy(base_dir, temp); - } - - log_info("Currect directory: %s",base_dir); - -#ifdef __NETWARE__ - /* setup paths */ - snprintf(bin_dir, FN_REFLEN, "%s/bin", base_dir); - snprintf(mysql_test_dir, FN_REFLEN, "%s/mysql-test", base_dir); - snprintf(test_dir, FN_REFLEN, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, FN_REFLEN, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, FN_REFLEN, "%s/r", mysql_test_dir); - snprintf(master_dir, FN_REFLEN, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, FN_REFLEN, "%s/share/english", base_dir); - snprintf(char_dir, FN_REFLEN, "%s/share/charsets", base_dir); - -#ifdef HAVE_OPENSSL - use_openssl= TRUE; -#endif /* HAVE_OPENSSL */ - - /* OpenSSL paths */ - snprintf(ca_cert, FN_REFLEN, "%s/std_data/cacert.pem", mysql_test_dir); - snprintf(server_cert, FN_REFLEN, "%s/std_data/server-cert.pem", mysql_test_dir); - snprintf(server_key, FN_REFLEN, "%s/std_data/server-key.pem", mysql_test_dir); - snprintf(client_cert, FN_REFLEN, "%s/std_data/client-cert.pem", mysql_test_dir); - snprintf(client_key, FN_REFLEN, "%s/std_data/client-key.pem", mysql_test_dir); - - /* setup files */ - snprintf(mysqld_file, FN_REFLEN, "%s/mysqld", bin_dir); - snprintf(mysqltest_file, FN_REFLEN, "%s/mysqltest", bin_dir); - snprintf(mysqladmin_file, FN_REFLEN, "%s/mysqladmin", bin_dir); - snprintf(master_pid, FN_REFLEN, "%s/var/run/master.pid", mysql_test_dir); - snprintf(slave_pid, FN_REFLEN, "%s/var/run/slave.pid", mysql_test_dir); -#elif __WIN__ - /* setup paths */ -#ifdef _DEBUG - snprintf(bin_dir, FN_REFLEN, "%s/client_debug", base_dir); -#else - snprintf(bin_dir, FN_REFLEN, "%s/client_release", base_dir); -#endif - snprintf(mysql_test_dir, FN_REFLEN, "%s/mysql-test", base_dir); - snprintf(test_dir, FN_REFLEN, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, FN_REFLEN, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, FN_REFLEN, "%s/r", mysql_test_dir); - snprintf(master_dir, FN_REFLEN, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); - snprintf(lang_dir, FN_REFLEN, "%s/share/english", base_dir); - snprintf(char_dir, FN_REFLEN, "%s/share/charsets", base_dir); - -#ifdef HAVE_OPENSSL - use_openssl= TRUE; -#endif /* HAVE_OPENSSL */ - - /* OpenSSL paths */ - snprintf(ca_cert, FN_REFLEN, "%s/std_data/cacert.pem", mysql_test_dir); - snprintf(server_cert, FN_REFLEN, "%s/std_data/server-cert.pem", mysql_test_dir); - snprintf(server_key, FN_REFLEN, "%s/std_data/server-key.pem", mysql_test_dir); - snprintf(client_cert, FN_REFLEN, "%s/std_data/client-cert.pem", mysql_test_dir); - snprintf(client_key, FN_REFLEN, "%s/std_data/client-key.pem", mysql_test_dir); - - /* setup files */ -#ifdef _DEBUG - snprintf(mysqld_file, FN_REFLEN, "%s/mysqld-debug.exe", bin_dir); -#else - snprintf(mysqld_file, FN_REFLEN, "%s/mysqld.exe", bin_dir); -#endif - snprintf(mysqltest_file, FN_REFLEN, "%s/mysqltest.exe", bin_dir); - snprintf(mysqladmin_file, FN_REFLEN, "%s/mysqladmin.exe", bin_dir); -#else - /* setup paths */ - snprintf(bin_dir, FN_REFLEN, "%s/client", base_dir); - snprintf(mysql_test_dir, FN_REFLEN, "%s/mysql-test", base_dir); - snprintf(test_dir, FN_REFLEN, "%s/t", mysql_test_dir); - snprintf(mysql_tmp_dir, FN_REFLEN, "%s/var/tmp", mysql_test_dir); - snprintf(result_dir, FN_REFLEN, "%s/r", mysql_test_dir); - snprintf(master_dir, FN_REFLEN, "%s/var/master-data", mysql_test_dir); - snprintf(slave_dir, FN_REFLEN, "%s/var/slave-data", mysql_test_dir); - snprintf(slave1_dir, FN_REFLEN, "%s/var/slave1-data", mysql_test_dir); - snprintf(slave2_dir, FN_REFLEN, "%s/var/slave2-data", mysql_test_dir); - snprintf(lang_dir, FN_REFLEN, "%s/sql/share/english", base_dir); - snprintf(char_dir, FN_REFLEN, "%s/sql/share/charsets", base_dir); - -#ifdef HAVE_OPENSSL - use_openssl= TRUE; -#endif /* HAVE_OPENSSL */ - - /* OpenSSL paths */ - snprintf(ca_cert, FN_REFLEN, "%s/std_data/cacert.pem", mysql_test_dir); - snprintf(server_cert, FN_REFLEN, "%s/std_data/server-cert.pem", mysql_test_dir); - snprintf(server_key, FN_REFLEN, "%s/std_data/server-key.pem", mysql_test_dir); - snprintf(client_cert, FN_REFLEN, "%s/std_data/client-cert.pem", mysql_test_dir); - snprintf(client_key, FN_REFLEN, "%s/std_data/client-key.pem", mysql_test_dir); - - /* setup files */ - snprintf(mysqld_file, FN_REFLEN, "%s/sql/mysqld", base_dir); - snprintf(mysqltest_file, FN_REFLEN, "%s/mysqltest", bin_dir); - snprintf(mysqladmin_file, FN_REFLEN, "%s/mysqladmin", bin_dir); - snprintf(master_pid, FN_REFLEN, "%s/var/run/master.pid", mysql_test_dir); - snprintf(slave_pid, FN_REFLEN, "%s/var/run/slave.pid", mysql_test_dir); - - snprintf(master_socket,FN_REFLEN, "%s/var/tmp/master.sock", mysql_test_dir); - snprintf(slave_socket,FN_REFLEN, "%s/var/tmp/slave.sock", mysql_test_dir); - -#endif - /* create log file */ - snprintf(temp, FN_REFLEN, "%s/mysql-test-run.log", mysql_test_dir); - if ((log_fd= fopen(temp, "w+")) == NULL) - { - log_errno("Unable to create log file."); - } - - /* prepare skip test list */ - while ((p= strchr(skip_test, ',')) != NULL) *p= ' '; - strcpy(temp, strlwr(skip_test)); - snprintf(skip_test, FN_REFLEN, " %s ", temp); - - /* environment */ -#ifdef __NETWARE__ - setenv("MYSQL_TEST_DIR", mysql_test_dir, 1); - snprintf(file_path, FN_REFLEN*2, - "%s/client/mysqldump --no-defaults -u root --port=%u", - bin_dir, master_port); - setenv("MYSQL_DUMP", file_path, 1); - snprintf(file_path, FN_REFLEN*2, - "%s/client/mysqlbinlog --no-defaults --local-load=%s", - bin_dir, mysql_tmp_dir); - setenv("MYSQL_BINLOG", file_path, 1); -#elif __WIN__ - snprintf(file_path,FN_REFLEN,"MYSQL_TEST_DIR=%s",mysql_test_dir); - _putenv(file_path); - snprintf(file_path, FN_REFLEN*2, - "MYSQL_DUMP=%s/mysqldump.exe --no-defaults -uroot --port=%u", - bin_dir, master_port); - _putenv(file_path); - snprintf(file_path, FN_REFLEN*2, - "MYSQL_BINLOG=%s/mysqlbinlog.exe --no-defaults --local-load=%s", - bin_dir, mysql_tmp_dir); - _putenv(file_path); - - snprintf(file_path, FN_REFLEN*2, - "TESTS_BINDIR=%s/tests", base_dir); - _putenv(file_path); - - snprintf(file_path, FN_REFLEN*2, - "CHARSETSDIR=%s/sql/share/charsets", base_dir); - _putenv(file_path); - - snprintf(file_path, FN_REFLEN*2, - "MYSQL=%s/mysql --port=%u ", - bin_dir, master_port); - _putenv(file_path); - - snprintf(file_path, FN_REFLEN*2, - "MYSQL_FIX_SYSTEM_TABLES=%s/scripts/mysql_fix_privilege_tables --no-defaults " - "--host=localhost --port=%u " - "--basedir=%s --bindir=%s --verbose", - base_dir,master_port, base_dir, bin_dir); - _putenv(file_path); - - snprintf(file_path, FN_REFLEN*2, - "NDB_TOOLS_DIR=%s/ndb/tools", base_dir); - _putenv(file_path); - - snprintf(file_path, FN_REFLEN*2, - "CLIENT_BINDIR=%s", bin_dir); - _putenv(file_path); - - snprintf(file_path, FN_REFLEN*2, - "MYSQL_CLIENT_TEST=%s/tests/mysql_client_test --no-defaults --testcase " - "--user=root --port=%u --silent", - base_dir, master_port); - _putenv(file_path); - -#else - { - static char env_MYSQL_TEST_DIR[FN_REFLEN*2]; - static char env_MYSQL_DUMP[FN_REFLEN*2]; - static char env_MYSQL_BINLOG[FN_REFLEN*2]; - static char env_MASTER_MYSOCK[FN_REFLEN*2]; - static char env_TESTS_BINDIR[FN_REFLEN*2]; - static char env_CHARSETSDIR[FN_REFLEN*2]; - static char env_MYSQL[FN_REFLEN*2]; - static char env_MYSQL_FIX_SYSTEM_TABLES[FN_REFLEN*2]; - static char env_CLIENT_BINDIR[FN_REFLEN*2]; - static char env_MYSQL_CLIENT_TEST[FN_REFLEN*2]; - static char env_NDB_TOOLS_DIR[FN_REFLEN*2]; - static char env_NDB_MGM[FN_REFLEN*2]; - static char env_NDB_BACKUP_DIR[FN_REFLEN*2]; - static char env_NDB_TOOLS_OUTPUT[FN_REFLEN*2]; - - snprintf(env_MYSQL_TEST_DIR,FN_REFLEN*2, - "MYSQL_TEST_DIR=%s",mysql_test_dir); - putenv(env_MYSQL_TEST_DIR); - - snprintf(env_MYSQL_DUMP, FN_REFLEN*2,"MYSQL_DUMP=%s/mysqldump --no-defaults " - "-uroot --port=%u --socket=%s ", - bin_dir, master_port, master_socket); - putenv(env_MYSQL_DUMP); - - snprintf(env_MYSQL_BINLOG, FN_REFLEN*2, - "MYSQL_BINLOG=%s/mysqlbinlog --no-defaults --local-load=%s -uroot ", - bin_dir, mysql_tmp_dir); - putenv(env_MYSQL_BINLOG); - - snprintf(env_MASTER_MYSOCK, FN_REFLEN*2, - "MASTER_MYSOCK=%s", master_socket); - putenv(env_MASTER_MYSOCK); - - snprintf(env_TESTS_BINDIR, FN_REFLEN*2, - "TESTS_BINDIR=%s/tests", base_dir); - putenv(env_TESTS_BINDIR); - - snprintf(env_CHARSETSDIR, FN_REFLEN*2, - "CHARSETSDIR=%s/sql/share/charsets", base_dir); - putenv(env_CHARSETSDIR); - - snprintf(env_MYSQL, FN_REFLEN*2, - "MYSQL=%s/mysql --port=%u --socket=%s -uroot ", - bin_dir, master_port, master_socket); - putenv(env_MYSQL); - - snprintf(env_MYSQL_FIX_SYSTEM_TABLES, FN_REFLEN*2, - "MYSQL_FIX_SYSTEM_TABLES=%s/scripts/mysql_fix_privilege_tables --no-defaults " - "--host=localhost --port=%u --socket=%s " - "--basedir=%s --bindir=%s --verbose -uroot ", - base_dir,master_port, master_socket, base_dir, bin_dir); - putenv(env_MYSQL_FIX_SYSTEM_TABLES); - - - snprintf(env_CLIENT_BINDIR, FN_REFLEN*2, - "CLIENT_BINDIR=%s", bin_dir); - putenv(env_CLIENT_BINDIR); - - snprintf(env_MYSQL_CLIENT_TEST, FN_REFLEN*2, - "MYSQL_CLIENT_TEST=%s/tests/mysql_client_test --no-defaults --testcase " - "--user=root --socket=%s --port=%u --silent", - base_dir, master_socket, master_port); - putenv(env_MYSQL_CLIENT_TEST); - - // NDB - - snprintf(env_NDB_TOOLS_DIR, FN_REFLEN*2, - "NDB_TOOLS_DIR=%s/ndb/tools", base_dir); - putenv(env_NDB_TOOLS_DIR); - - snprintf(env_NDB_MGM, FN_REFLEN*2, - "NDB_MGM=%s/ndb/src/mgmclient/ndb_mgm", base_dir); - putenv(env_NDB_MGM); - - //NDBCLUSTER_PORT=9350 - snprintf(env_NDB_BACKUP_DIR, FN_REFLEN*2, - "NDB_BACKUP_DIR=%s/var/ndbcluster-%i", mysql_test_dir, 9350); - putenv(env_NDB_BACKUP_DIR); - - snprintf(env_NDB_TOOLS_OUTPUT, FN_REFLEN*2, - "NDB_TOOLS_OUTPUT=%s/var/log/ndb_tools.log", mysql_test_dir); - putenv(env_NDB_TOOLS_OUTPUT); - - putenv((char *)"NDB_STATUS_OK=1"); - -// NDB_MGM="$BASEDIR/ndb/src/mgmclient/ndb_mgm" -// NDB_BACKUP_DIR=$MYSQL_TEST_DIR/var/ndbcluster-$NDBCLUSTER_PORT -// NDB_TOOLS_OUTPUT=$MYSQL_TEST_DIR/var/log/ndb_tools.log - } - -#endif - -#ifndef __WIN__ - putenv((char *)"MASTER_MYPORT=9306"); - putenv((char *)"SLAVE_MYPORT=9307"); - putenv((char *)"MYSQL_TCP_PORT=3306"); - -#else - _putenv("MASTER_MYPORT=9306"); - _putenv("SLAVE_MYPORT=9307"); - _putenv("MYSQL_TCP_PORT=3306"); -#endif - -} - -/* - Compare names of testes for right order -*/ -int compare( const void *arg1, const void *arg2 ) -{ - return sting_compare_func( * ( char** ) arg1, * ( char** ) arg2 ); -} - - - -/****************************************************************************** - - main() - -******************************************************************************/ - -int main(int argc, char **argv) -{ - int is_ignore_list= 0; - char **names= 0; - char **testes= 0; - int name_index; - int index; - char var_dir[FN_REFLEN]; - /* setup */ - setup(argv[0]); - - /* delete all file in var */ - snprintf(var_dir,FN_REFLEN,"%s/var",mysql_test_dir); - del_tree(var_dir); - - /* - The --ignore option is comma saperated list of test cases to skip and - should be very first command line option to the test suite. - - The usage is now: - mysql_test_run --ignore=test1,test2 test3 test4 - where test1 and test2 are test cases to ignore - and test3 and test4 are test cases to run. - */ - if (argc >= 2 && !strnicmp(argv[1], "--ignore=", sizeof("--ignore=")-1)) - { - char *temp, *token; - temp= strdup(strchr(argv[1],'=') + 1); - for (token=str_tok(argument, temp, ","); token != NULL; - token=str_tok(argument, NULL, ",")) - { - if (strlen(ignore_test) + strlen(token) + 2 <= FN_REFLEN-1) - sprintf(ignore_test+strlen(ignore_test), " %s ", token); - else - { - free(temp); - die("ignore list too long."); - } - } - free(temp); - is_ignore_list= 1; - } - /* header */ -#ifndef __WIN__ - mlog("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE); -#else - mlog("MySQL Server ---, for %s (%s)\n\n", SYSTEM_TYPE, MACHINE_TYPE); -#endif - - mlog("Initializing Tests...\n"); - - /* install test databases */ - mysql_install_db(); - - mlog("Starting Tests...\n"); - - mlog("\n"); - mlog(HEADER); - mlog(DASH); - - if ( argc > 1 + is_ignore_list ) - { - int i; - - /* single test */ - single_test= TRUE; - - for (i= 1 + is_ignore_list; i < argc; i++) - { - /* run given test */ - run_test(argv[i]); - } - } - else - { - /* run all tests */ - testes= malloc(MAX_COUNT_TESTES*sizeof(void*)); - if (!testes) - die("can not allcate memory for sorting"); - names= testes; - name_index= 0; -#ifndef __WIN__ - struct dirent *entry; - DIR *parent; - char test[FN_LEN]; - int position; - - /* FIXME are we sure the list is sorted if using readdir()? */ - if ((parent= opendir(test_dir)) == NULL) /* Not thread safe */ - die("Unable to open tests directory."); - else - { - while ((entry= readdir(parent)) != NULL) /* Not thread safe */ - { - strcpy(test, strlwr(entry->d_name)); - /* find the test suffix */ - if ((position= strinstr(test, TEST_SUFFIX)) != 0) - { - if (name_index < MAX_COUNT_TESTES) - { - /* null terminate at the suffix */ - *(test + position - 1)= '\0'; - /* insert test */ - *names= malloc(FN_REFLEN); - strcpy(*names,test); - names++; - name_index++; - } - else - die("can not sort files, array is overloaded"); - } - } - closedir(parent); - } -#else - { - struct _finddata_t dir; - int* handle; - char test[FN_LEN]; - char mask[FN_REFLEN]; - int position; - - /* single test */ - single_test= FALSE; - - snprintf(mask,FN_REFLEN,"%s/*.test",test_dir); - - if ((handle=_findfirst(mask,&dir)) == -1L) - { - die("Unable to open tests directory."); - } - - - do - { - if (!(dir.attrib & _A_SUBDIR)) - { - strcpy(test, strlwr(dir.name)); - - /* find the test suffix */ - if ((position= strinstr(test, TEST_SUFFIX)) != 0) - { - if (name_index < MAX_COUNT_TESTES) - { - /* null terminate at the suffix */ - *(test + position - 1)= '\0'; - /* insert test */ - *names= malloc(FN_REFLEN); - strcpy(*names,test); - names++; - name_index++; - } - else - die("can not sort files, array is overloaded"); - } - } - }while (_findnext(handle,&dir) == 0); - - _findclose(handle); - } -#endif - qsort( (void *)testes, name_index, sizeof( char * ), compare ); - - for (index= 0; index < name_index; index++) - { - run_test(testes[index]); - free(testes[index]); - } - - free(testes); - } - - /* stop server */ - mysql_stop(); - - mlog(DASH); - mlog("\n"); - - mlog("Ending Tests...\n"); - - /* report stats */ - report_stats(); - - /* close log */ - if (log_fd) fclose(log_fd); - - /* keep results up */ -#ifdef __NETWARE__ - pressanykey(); -#endif - return 0; -} - - -/* - Synopsis: - This function breaks the string into a sequence of tokens. The difference - between this function and strtok is that it respects the quoted string i.e. - it skips any delimiter character within the quoted part of the string. - It return tokens by eliminating quote character. It modifies the input string - passed. It will work with whitespace delimeter but may not work properly with - other delimeter. If the delimeter will contain any quote character, then - function will not tokenize and will return null string. - e.g. if input string is - --init-slave="set global max_connections=500" --skip-external-locking - then the output will two string i.e. - --init-slave=set global max_connections=500 - --skip-external-locking - -Arguments: - string: input string - delim: set of delimiter character -Output: - return the null terminated token of NULL. -*/ -char *str_tok(char* dest, char *string, const char *delim) -{ - char *token; - char *ptr_end_token= NULL; - char *ptr_quote= NULL; - char *ptr_token= NULL; - int count_quotes= 0; - - *dest = '\0'; - if (strchr(delim,'\'') || strchr(delim,'\"')) - return NULL; - - token= (char*)strtok(string, delim); - if (token) - { - /* double quote is found */ - if (strchr(token,'\"')) - { - do - { - if (count_quotes & 1) - { - if (*dest == '\0') - sprintf(dest,"%s", ptr_token); - else - sprintf(dest,"%s %s", dest, ptr_token); - ptr_token= (char*)strtok(NULL, delim); - if (!ptr_token) - break; - } - else - { - ptr_token= token; - } - if (ptr_quote = strchr(ptr_token,'\"')) - { - ptr_end_token= ptr_token + strlen(ptr_token); - do - { -#ifndef __WIN__ - bmove(ptr_quote, ptr_quote+1, ptr_end_token - ptr_quote); -#endif - count_quotes++; - } while (ptr_quote != NULL && (ptr_quote = strchr(ptr_quote+1,'\"'))); - } - /* there are unpair quotes we have to search next quote*/ - } while (count_quotes & 1); - if (ptr_token != NULL) - { - if (*dest == '\0') - sprintf(dest,"%s", ptr_token); - else - sprintf(dest,"%s %s",dest,ptr_token); - } - } - else - { - sprintf(dest,"%s",token); - } - } - return token ? dest : NULL; -} - -#ifndef __WIN__ -/* - Synopsis: - This function run scripts files on Linux and Netware - -Arguments: - script_name: name of script file - -Output: - nothing -*/ - -void run_init_script(const char *script_name) -{ - arg_list_t al; - int err; - - /* args */ - init_args(&al); - add_arg(&al, sh_file); - add_arg(&al, script_name); - - /* spawn */ - if ((err= spawn(sh_file, &al, TRUE, NULL, NULL, NULL, NULL)) != 0) - { - die("Unable to run script."); - } - - /* free args */ - free_args(&al); -} -#endif diff --git a/scripts/msql2mysql.sh b/scripts/msql2mysql.sh index 89a1fcea959..3c802d63705 100644 --- a/scripts/msql2mysql.sh +++ b/scripts/msql2mysql.sh @@ -1,16 +1,18 @@ #!/bin/sh -# Copyright (C) 1979-1996 TcX AB & Monty Program KB & Detron HB +# Copyright (C) 1979-2007 MySQL AB # -# This software is distributed with NO WARRANTY OF ANY KIND. No author or -# distributor accepts any responsibility for the consequences of using it, or -# for whether it serves any particular purpose or works at all, unless he or -# she says so in writing. Refer to the Free Public License (the "License") -# for full details. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. # -# Every copy of this file must include a copy of the License, normally in a -# plain ASCII text file named PUBLIC. The License grants you the right to -# copy, modify and redistribute this file, but only under certain conditions -# described in the License. Among other things, the License requires that -# the copyright notice and this notice be preserved on all copies. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston +# MA 02110-1301 USA. @bindir@/replace msqlConnect mysql_connect msqlListDBs mysql_list_dbs msqlNumRows mysql_num_rows msqlFetchRow mysql_fetch_row msqlFetchField mysql_fetch_field msqlFreeResult mysql_free_result msqlListFields mysql_list_fields msqlListTables mysql_list_tables msqlErrMsg 'mysql_error(mysql)' msqlStoreResult mysql_store_result msqlQuery mysql_query msqlField mysql_field msqlSelect mysql_select msqlSelectDB mysql_select_db msqlNumFields mysql_num_fields msqlClose mysql_close msqlDataSeek mysql_data_seek m_field MYSQL_FIELD m_result MYSQL_RES m_row MYSQL_ROW msql mysql mSQL mySQL MSQL MYSQL msqlCreateDB mysql_create_db msqlDropDB mysql_drop_db msqlFieldSeek mysql_field_seek -- $* diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 7abdb5f488c..2d78999017a 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -445,10 +445,24 @@ int main(int argc,char **argv) /* Broken up to indicate that it's not advice to you, gentle reader. */ printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n"); - printf("/* Copyright (C) 2001-2004 MySQL AB\n\ - This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ - and you are welcome to modify and redistribute it under the GPL license\n\ - \n*/\n\n"); + printf("\ +/* Copyright (C) 2001-2004 MySQL AB\n\ +\n\ + This program is free software; you can redistribute it and/or modify\n\ + it under the terms of the GNU General Public License as published by\n\ + the Free Software Foundation; version 2 of the License.\n\ +\n\ + This program is distributed in the hope that it will be useful,\n\ + but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ + GNU General Public License for more details.\n\ +\n\ + You should have received a copy of the GNU General Public License\n\ + along with this program; see the file COPYING. If not, write to the\n\ + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston\n\ + MA 02110-1301 USA. */\n\ +\n\ +"); /* Broken up to indicate that it's not advice to you, gentle reader. */ printf("/* Do " "not " "edit " "this " "file! This is generated by " diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 528b1f2746b..cbd74cf557e 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,3 +1,19 @@ +# Copyright (C) 2000-2007 MySQL AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; see the file COPYING. If not, write to the +# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston +# MA 02110-1301 USA. + %define mysql_version @VERSION@ # use "rpmbuild --with static" or "rpm --define '_with_static 1'" (for RPM 3.x) @@ -70,12 +86,9 @@ is intended for mission-critical, heavy-load production systems as well as for embedding into mass-deployed software. MySQL is a trademark of MySQL AB. -The MySQL software has Dual Licensing, which means you can use the MySQL -software free of charge under the GNU General Public License -(http://www.gnu.org/licenses/). You can also purchase commercial MySQL -licenses from MySQL AB if you do not wish to be bound by the terms of -the GPL. See the chapter "Licensing and Support" in the manual for -further info. +Copyright (C) 2000-2007 MySQL AB +This software comes with ABSOLUTELY NO WARRANTY. This is free software, +and you are welcome to modify and redistribute it under the GPL license. The MySQL web site (http://www.mysql.com/) provides the latest news and information about the MySQL software. Also please see the @@ -95,12 +108,9 @@ is intended for mission-critical, heavy-load production systems as well as for embedding into mass-deployed software. MySQL is a trademark of MySQL AB. -The MySQL software has Dual Licensing, which means you can use the MySQL -software free of charge under the GNU General Public License -(http://www.gnu.org/licenses/). You can also purchase commercial MySQL -licenses from MySQL AB if you do not wish to be bound by the terms of -the GPL. See the chapter "Licensing and Support" in the manual for -further info. +Copyright (C) 2000-2007 MySQL AB +This software comes with ABSOLUTELY NO WARRANTY. This is free software, +and you are welcome to modify and redistribute it under the GPL license. The MySQL web site (http://www.mysql.com/) provides the latest news and information about the MySQL software. Also please see the From 2ba683f2eeef8eb13462c5e46ca625d669e48463 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@macbook.gmz" <> Date: Wed, 31 Jan 2007 10:18:26 +0200 Subject: [PATCH 14/30] Bug #25551: inconsistent behaviour in grouping NULL, depending on index type The optimizer takes away columns from GROUP BY/DISTINCT if they constitute all the parts of an unique index. However if some of the columns can contain NULLs this cannot be done (because an UNIQUE index can have multiple rows with NULL values). Fixed by not using UNIQUE indexes with nullable columns to remove grouping columns from GROUP BY/DISTINCT. --- mysql-test/r/distinct.result | 26 +++++++++++++++++++++++++- mysql-test/t/distinct.test | 17 ++++++++++++++++- sql/sql_select.cc | 19 +++++++++++-------- 3 files changed, 52 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 32151305698..3508a83a810 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -530,7 +530,8 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT DISTINCT a,b FROM t1 GROUP BY a,b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 -CREATE TABLE t2(a INT, b INT, c INT, d INT, PRIMARY KEY (a,b)); +CREATE TABLE t2(a INT, b INT NOT NULL, c INT NOT NULL, d INT, +PRIMARY KEY (a,b)); INSERT INTO t2 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4); EXPLAIN SELECT DISTINCT a FROM t2; id select_type table type possible_keys key key_len ref rows Extra @@ -644,3 +645,26 @@ SELECT COUNT(*) FROM COUNT(*) 2 DROP TABLE t1, t2; +CREATE TABLE t1 (a INT, UNIQUE (a)); +INSERT INTO t1 VALUES (4),(null),(2),(1),(null),(3); +EXPLAIN SELECT DISTINCT a FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 6 Using index +SELECT DISTINCT a FROM t1; +a +NULL +1 +2 +3 +4 +EXPLAIN SELECT a FROM t1 GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 6 Using index +SELECT a FROM t1 GROUP BY a; +a +NULL +1 +2 +3 +4 +DROP TABLE t1; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 8734b940241..476e4ce7735 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -364,7 +364,8 @@ EXPLAIN SELECT a FROM t1 GROUP BY a; EXPLAIN SELECT a,b FROM t1 GROUP BY a,b; EXPLAIN SELECT DISTINCT a,b FROM t1 GROUP BY a,b; -CREATE TABLE t2(a INT, b INT, c INT, d INT, PRIMARY KEY (a,b)); +CREATE TABLE t2(a INT, b INT NOT NULL, c INT NOT NULL, d INT, + PRIMARY KEY (a,b)); INSERT INTO t2 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4); EXPLAIN SELECT DISTINCT a FROM t2; EXPLAIN SELECT DISTINCT a,a FROM t2; @@ -525,3 +526,17 @@ SELECT COUNT(*) FROM (SELECT DISTINCT a FROM t2 WHERE a='oe' COLLATE latin1_german2_ci) dt; DROP TABLE t1, t2; + +# +# Bug #25551: inconsistent behaviour in grouping NULL, depending on index type +# +CREATE TABLE t1 (a INT, UNIQUE (a)); +INSERT INTO t1 VALUES (4),(null),(2),(1),(null),(3); +EXPLAIN SELECT DISTINCT a FROM t1; +#result must have one row with NULL +SELECT DISTINCT a FROM t1; +EXPLAIN SELECT a FROM t1 GROUP BY a; +#result must have one row with NULL +SELECT a FROM t1 GROUP BY a; + +DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b03c4556279..1486cf521a5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -848,10 +848,11 @@ JOIN::optimize() } /* Check if we can optimize away GROUP BY/DISTINCT. - We can do that if there are no aggregate functions and the + We can do that if there are no aggregate functions, the fields in DISTINCT clause (if present) and/or columns in GROUP BY (if present) contain direct references to all key parts of - an unique index (in whatever order). + an unique index (in whatever order) and if the key parts of the + unique index cannot contain NULLs. Note that the unique keys for DISTINCT and GROUP BY should not be the same (as long as they are unique). @@ -11856,7 +11857,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts, /* - Check if GROUP BY/DISTINCT can be optimized away because the set is + Check if GROUP BY/DISTINCT can be optimized away because the set is already known to be distinct. SYNOPSIS @@ -11864,7 +11865,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts, table The table to operate on. find_func function to iterate over the list and search for a field - + DESCRIPTION Used in removing the GROUP BY/DISTINCT of the following types of statements: @@ -11875,12 +11876,13 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts, then ,{whatever} is also distinct This function checks if all the key parts of any of the unique keys - of the table are referenced by a list : either the select list + of the table are referenced by a list : either the select list through find_field_in_item_list or GROUP BY list through find_field_in_order_list. - If the above holds then we can safely remove the GROUP BY/DISTINCT, + If the above holds and the key parts cannot contain NULLs then we + can safely remove the GROUP BY/DISTINCT, as no result set can be more distinct than an unique key. - + RETURN VALUE 1 found 0 not found. @@ -11903,7 +11905,8 @@ list_contains_unique_index(TABLE *table, key_part < key_part_end; key_part++) { - if (!find_func(key_part->field, data)) + if (key_part->field->maybe_null() || + !find_func(key_part->field, data)) break; } if (key_part == key_part_end) From a51aae601d82261e9b30d394c8f022e3740aa788 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Wed, 31 Jan 2007 16:15:20 +0400 Subject: [PATCH 15/30] WL#3567 - MERGE engine: a check for underlying table conformance When a merge table is opened compare column and key definition of underlying tables against column and key definition of merge table. If any of underlying tables have different column/key definition refuse to open merge table. --- mysql-test/r/merge.result | 22 +- mysql-test/t/merge.test | 29 ++- sql/ha_myisam.cc | 491 ++++++++++++++++++++++++-------------- sql/ha_myisammrg.cc | 42 +++- 4 files changed, 404 insertions(+), 180 deletions(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index a1ef7597143..eb333cdadb7 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -770,7 +770,7 @@ CREATE TABLE t1(a INT); INSERT INTO t1 VALUES(2),(1); CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1); SELECT * FROM t2 WHERE a=2; -ERROR HY000: Got error 124 from storage engine +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist DROP TABLE t1, t2; CREATE TABLE t1(a INT) ENGINE=MEMORY; CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1); @@ -781,3 +781,23 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3); SELECT * FROM t2; ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist DROP TABLE t2; +CREATE TABLE t1(a INT, b TEXT); +CREATE TABLE tm1(a TEXT, b INT) ENGINE=MERGE UNION=(t1); +SELECT * FROM tm1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +DROP TABLE t1, tm1; +CREATE TABLE t1(a SMALLINT, b SMALLINT); +CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1); +SELECT * FROM tm1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +DROP TABLE t1, tm1; +CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(a, b)); +CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1); +SELECT * FROM tm1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +DROP TABLE t1, tm1; +CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(b)); +CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1); +SELECT * FROM tm1; +ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +DROP TABLE t1, tm1; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index bb03b7b8d62..700a807e62c 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -383,7 +383,7 @@ drop table t1, t2, t3; CREATE TABLE t1(a INT); INSERT INTO t1 VALUES(2),(1); CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1); ---error 1030 +--error 1168 SELECT * FROM t2 WHERE a=2; DROP TABLE t1, t2; @@ -401,4 +401,31 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3); SELECT * FROM t2; DROP TABLE t2; +# +# Underlying table definition conformance tests. +# +CREATE TABLE t1(a INT, b TEXT); +CREATE TABLE tm1(a TEXT, b INT) ENGINE=MERGE UNION=(t1); +--error 1168 +SELECT * FROM tm1; +DROP TABLE t1, tm1; + +CREATE TABLE t1(a SMALLINT, b SMALLINT); +CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1); +--error 1168 +SELECT * FROM tm1; +DROP TABLE t1, tm1; + +CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(a, b)); +CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1); +--error 1168 +SELECT * FROM tm1; +DROP TABLE t1, tm1; + +CREATE TABLE t1(a SMALLINT, b SMALLINT, KEY(b)); +CREATE TABLE tm1(a SMALLINT, b SMALLINT, KEY(a)) ENGINE=MERGE UNION=(t1); +--error 1168 +SELECT * FROM tm1; +DROP TABLE t1, tm1; + # End of 4.1 tests diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 2e29d929352..2cec03a51db 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -91,6 +91,296 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, return; } + +/* + Convert TABLE object to MyISAM key and column definition + + SYNOPSIS + table2myisam() + table_arg in TABLE object. + keydef_out out MyISAM key definition. + recinfo_out out MyISAM column definition. + records_out out Number of fields. + + DESCRIPTION + This function will allocate and initialize MyISAM key and column + definition for further use in mi_create or for a check for underlying + table conformance in merge engine. + + RETURN VALUE + 0 OK + !0 error code +*/ + +int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, + MI_COLUMNDEF **recinfo_out, uint *records_out) +{ + uint i, j, recpos, minpos, fieldpos, temp_length, length; + uint options= table_arg->db_options_in_use; + enum ha_base_keytype type= HA_KEYTYPE_BINARY; + KEY *pos; + MI_KEYDEF *keydef; + MI_COLUMNDEF *recinfo, *recinfo_pos; + HA_KEYSEG *keyseg; + + DBUG_ENTER("table2myisam"); + if (!(my_multi_malloc(MYF(MY_WME), + recinfo_out, (table_arg->fields * 2 + 2) * sizeof(MI_COLUMNDEF), + keydef_out, table_arg->keys * sizeof(MI_KEYDEF), + &keyseg, + (table_arg->key_parts + table_arg->keys) * sizeof(HA_KEYSEG), + NullS))) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */ + keydef= *keydef_out; + recinfo= *recinfo_out; + pos= table_arg->key_info; + for (i= 0; i < table_arg->keys; i++, pos++) + { + keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL)); + keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ? + (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) : + pos->algorithm; + keydef[i].seg= keyseg; + keydef[i].keysegs= pos->key_parts; + for (j= 0; j < pos->key_parts; j++) + { + keydef[i].seg[j].flag= pos->key_part[j].key_part_flag; + Field *field= pos->key_part[j].field; + type= field->key_type(); + + if (options & HA_OPTION_PACK_KEYS || + (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY | + HA_SPACE_PACK_USED))) + { + if (pos->key_part[j].length > 8 && + (type == HA_KEYTYPE_TEXT || + type == HA_KEYTYPE_NUM || + (type == HA_KEYTYPE_BINARY && !field->zero_pack()))) + { + /* No blobs here */ + if (j == 0) + keydef[i].flag|= HA_PACK_KEY; + if (!(field->flags & ZEROFILL_FLAG) && + (field->type() == FIELD_TYPE_STRING || + field->type() == FIELD_TYPE_VAR_STRING || + ((int) (pos->key_part[j].length - field->decimals())) >= 4)) + keydef[i].seg[j].flag|= HA_SPACE_PACK; + } + else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16)) + keydef[i].flag|= HA_BINARY_PACK_KEY; + } + keydef[i].seg[j].type= (int) type; + keydef[i].seg[j].start= pos->key_part[j].offset; + keydef[i].seg[j].length= pos->key_part[j].length; + keydef[i].seg[j].bit_start= keydef[i].seg[j].bit_end= 0; + keydef[i].seg[j].language= field->charset()->number; + + if (field->null_ptr) + { + keydef[i].seg[j].null_bit= field->null_bit; + keydef[i].seg[j].null_pos= (uint) (field->null_ptr- + (uchar*) table_arg->record[0]); + } + else + { + keydef[i].seg[j].null_bit= 0; + keydef[i].seg[j].null_pos= 0; + } + if (field->type() == FIELD_TYPE_BLOB || + field->type() == FIELD_TYPE_GEOMETRY) + { + keydef[i].seg[j].flag|= HA_BLOB_PART; + /* save number of bytes used to pack length */ + keydef[i].seg[j].bit_start= (uint) (field->pack_length() - + table_arg->blob_ptr_size); + } + } + keyseg+= pos->key_parts; + } + if (table_arg->found_next_number_field) + keydef[table_arg->next_number_index].flag|= HA_AUTO_KEY; + recpos= 0; + recinfo_pos= recinfo; + while (recpos < (uint) table_arg->reclength) + { + Field **field, *found= 0; + minpos= table_arg->reclength; + length= 0; + + for (field= table_arg->field; *field; field++) + { + if ((fieldpos= (*field)->offset()) >= recpos && + fieldpos <= minpos) + { + /* skip null fields */ + if (!(temp_length= (*field)->pack_length())) + continue; /* Skip null-fields */ + if (! found || fieldpos < minpos || + (fieldpos == minpos && temp_length < length)) + { + minpos= fieldpos; + found= *field; + length= temp_length; + } + } + } + DBUG_PRINT("loop", ("found: %lx recpos: %d minpos: %d length: %d", + (long) found, recpos, minpos, length)); + if (recpos != minpos) + { // Reserved space (Null bits?) + bzero((char*) recinfo_pos, sizeof(*recinfo_pos)); + recinfo_pos->type= (int) FIELD_NORMAL; + recinfo_pos++->length= (uint16) (minpos - recpos); + } + if (!found) + break; + + if (found->flags & BLOB_FLAG) + { + recinfo_pos->type= (int) FIELD_BLOB; + } + else if (!(options & HA_OPTION_PACK_RECORD)) + recinfo_pos->type= (int) FIELD_NORMAL; + else if (found->zero_pack()) + recinfo_pos->type= (int) FIELD_SKIP_ZERO; + else + recinfo_pos->type= (int) ((length <= 3 || + (found->flags & ZEROFILL_FLAG)) ? + FIELD_NORMAL : + found->type() == FIELD_TYPE_STRING || + found->type() == FIELD_TYPE_VAR_STRING ? + FIELD_SKIP_ENDSPACE : + FIELD_SKIP_PRESPACE); + if (found->null_ptr) + { + recinfo_pos->null_bit= found->null_bit; + recinfo_pos->null_pos= (uint) (found->null_ptr - + (uchar*) table_arg->record[0]); + } + else + { + recinfo_pos->null_bit= 0; + recinfo_pos->null_pos= 0; + } + (recinfo_pos++)->length= (uint16) length; + recpos= minpos + length; + DBUG_PRINT("loop", ("length: %d type: %d", + recinfo_pos[-1].length,recinfo_pos[-1].type)); + } + *records_out= (uint) (recinfo_pos - recinfo); + DBUG_RETURN(0); +} + + +/* + Check for underlying table conformance + + SYNOPSIS + check_definition() + t1_keyinfo in First table key definition + t1_recinfo in First table record definition + t1_keys in Number of keys in first table + t1_recs in Number of records in first table + t2_keyinfo in Second table key definition + t2_recinfo in Second table record definition + t2_keys in Number of keys in second table + t2_recs in Number of records in second table + strict in Strict check switch + + DESCRIPTION + This function compares two MyISAM definitions. By intention it was done + to compare merge table definition against underlying table definition. + It may also be used to compare dot-frm and MYI definitions of MyISAM + table as well to compare different MyISAM table definitions. + + For merge table it is not required that number of keys in merge table + must exactly match number of keys in underlying table. When calling this + function for underlying table conformance check, 'strict' flag must be + set to false, and converted merge definition must be passed as t1_*. + + Otherwise 'strict' flag must be set to 1 and it is not required to pass + converted dot-frm definition as t1_*. + + RETURN VALUE + 0 - Equal definitions. + 1 - Different definitions. +*/ + +int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, + uint t1_keys, uint t1_recs, + MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo, + uint t2_keys, uint t2_recs, bool strict) +{ + uint i, j; + DBUG_ENTER("check_definition"); + if ((strict ? t1_keys != t2_keys : t1_keys > t2_keys)) + { + DBUG_PRINT("error", ("Number of keys differs: t1_keys=%u, t2_keys=%u", + t1_keys, t2_keys)); + DBUG_RETURN(1); + } + if (t1_recs != t2_recs) + { + DBUG_PRINT("error", ("Number of recs differs: t1_recs=%u, t2_recs=%u", + t1_recs, t2_recs)); + DBUG_RETURN(1); + } + for (i= 0; i < t1_keys; i++) + { + HA_KEYSEG *t1_keysegs= t1_keyinfo[i].seg; + HA_KEYSEG *t2_keysegs= t2_keyinfo[i].seg; + if (t1_keyinfo[i].keysegs != t2_keyinfo[i].keysegs || + t1_keyinfo[i].key_alg != t2_keyinfo[i].key_alg) + { + DBUG_PRINT("error", ("Key %d has different definition", i)); + DBUG_PRINT("error", ("t1_keysegs=%d, t1_key_alg=%d", + t1_keyinfo[i].keysegs, t1_keyinfo[i].key_alg)); + DBUG_PRINT("error", ("t2_keysegs=%d, t2_key_alg=%d", + t2_keyinfo[i].keysegs, t2_keyinfo[i].key_alg)); + DBUG_RETURN(1); + } + for (j= t1_keyinfo[i].keysegs; j--;) + { + if (t1_keysegs[j].type != t2_keysegs[j].type || + t1_keysegs[j].language != t2_keysegs[j].language || + t1_keysegs[j].null_bit != t2_keysegs[j].null_bit || + t1_keysegs[j].length != t2_keysegs[j].length) + { + DBUG_PRINT("error", ("Key segment %d (key %d) has different " + "definition", j, i)); + DBUG_PRINT("error", ("t1_type=%d, t1_language=%d, t1_null_bit=%d, " + "t1_length=%d", + t1_keysegs[j].type, t1_keysegs[j].language, + t1_keysegs[j].null_bit, t1_keysegs[j].length)); + DBUG_PRINT("error", ("t2_type=%d, t2_language=%d, t2_null_bit=%d, " + "t2_length=%d", + t2_keysegs[j].type, t2_keysegs[j].language, + t2_keysegs[j].null_bit, t2_keysegs[j].length)); + + DBUG_RETURN(1); + } + } + } + for (i= 0; i < t1_recs; i++) + { + MI_COLUMNDEF *t1_rec= &t1_recinfo[i]; + MI_COLUMNDEF *t2_rec= &t2_recinfo[i]; + if (t1_rec->type != t2_rec->type || + t1_rec->length != t2_rec->length || + t1_rec->null_bit != t2_rec->null_bit) + { + DBUG_PRINT("error", ("Field %d has different definition", i)); + DBUG_PRINT("error", ("t1_type=%d, t1_length=%d, t1_null_bit=%d", + t1_rec->type, t1_rec->length, t1_rec->null_bit)); + DBUG_PRINT("error", ("t2_type=%d, t2_length=%d, t2_null_bit=%d", + t2_rec->type, t2_rec->length, t2_rec->null_bit)); + DBUG_RETURN(1); + } + } + DBUG_RETURN(0); +} + + extern "C" { volatile my_bool *killed_ptr(MI_CHECK *param) @@ -1345,181 +1635,30 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, HA_CREATE_INFO *info) { int error; - uint i,j,recpos,minpos,fieldpos,temp_length,length, create_flags= 0; - bool found_real_auto_increment=0; - enum ha_base_keytype type; + uint create_flags= 0, options= table_arg->db_options_in_use, records; char buff[FN_REFLEN]; - KEY *pos; MI_KEYDEF *keydef; - MI_COLUMNDEF *recinfo,*recinfo_pos; - HA_KEYSEG *keyseg; - uint options=table_arg->db_options_in_use; - DBUG_ENTER("ha_myisam::create"); - - type=HA_KEYTYPE_BINARY; // Keep compiler happy - if (!(my_multi_malloc(MYF(MY_WME), - &recinfo,(table_arg->fields*2+2)*sizeof(MI_COLUMNDEF), - &keydef, table_arg->keys*sizeof(MI_KEYDEF), - &keyseg, - ((table_arg->key_parts + table_arg->keys) * - sizeof(HA_KEYSEG)), - NullS))) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - - pos=table_arg->key_info; - for (i=0; i < table_arg->keys ; i++, pos++) - { - keydef[i].flag= (pos->flags & (HA_NOSAME | HA_FULLTEXT | HA_SPATIAL)); - keydef[i].key_alg= pos->algorithm == HA_KEY_ALG_UNDEF ? - (pos->flags & HA_SPATIAL ? HA_KEY_ALG_RTREE : HA_KEY_ALG_BTREE) : - pos->algorithm; - keydef[i].seg=keyseg; - keydef[i].keysegs=pos->key_parts; - for (j=0 ; j < pos->key_parts ; j++) - { - keydef[i].seg[j].flag=pos->key_part[j].key_part_flag; - Field *field=pos->key_part[j].field; - type=field->key_type(); - - if (options & HA_OPTION_PACK_KEYS || - (pos->flags & (HA_PACK_KEY | HA_BINARY_PACK_KEY | - HA_SPACE_PACK_USED))) - { - if (pos->key_part[j].length > 8 && - (type == HA_KEYTYPE_TEXT || - type == HA_KEYTYPE_NUM || - (type == HA_KEYTYPE_BINARY && !field->zero_pack()))) - { - /* No blobs here */ - if (j == 0) - keydef[i].flag|=HA_PACK_KEY; - if (!(field->flags & ZEROFILL_FLAG) && - (field->type() == FIELD_TYPE_STRING || - field->type() == FIELD_TYPE_VAR_STRING || - ((int) (pos->key_part[j].length - field->decimals())) - >= 4)) - keydef[i].seg[j].flag|=HA_SPACE_PACK; - } - else if (j == 0 && (!(pos->flags & HA_NOSAME) || pos->key_length > 16)) - keydef[i].flag|= HA_BINARY_PACK_KEY; - } - keydef[i].seg[j].type= (int) type; - keydef[i].seg[j].start= pos->key_part[j].offset; - keydef[i].seg[j].length= pos->key_part[j].length; - keydef[i].seg[j].bit_start=keydef[i].seg[j].bit_end=0; - keydef[i].seg[j].language = field->charset()->number; - - if (field->null_ptr) - { - keydef[i].seg[j].null_bit=field->null_bit; - keydef[i].seg[j].null_pos= (uint) (field->null_ptr- - (uchar*) table_arg->record[0]); - } - else - { - keydef[i].seg[j].null_bit=0; - keydef[i].seg[j].null_pos=0; - } - if (field->type() == FIELD_TYPE_BLOB || - field->type() == FIELD_TYPE_GEOMETRY) - { - keydef[i].seg[j].flag|=HA_BLOB_PART; - /* save number of bytes used to pack length */ - keydef[i].seg[j].bit_start= (uint) (field->pack_length() - - table_arg->blob_ptr_size); - } - } - keyseg+=pos->key_parts; - } - - if (table_arg->found_next_number_field) - { - keydef[table_arg->next_number_index].flag|= HA_AUTO_KEY; - found_real_auto_increment= table_arg->next_number_key_offset == 0; - } - - recpos=0; recinfo_pos=recinfo; - while (recpos < (uint) table_arg->reclength) - { - Field **field,*found=0; - minpos=table_arg->reclength; length=0; - - for (field=table_arg->field ; *field ; field++) - { - if ((fieldpos=(*field)->offset()) >= recpos && - fieldpos <= minpos) - { - /* skip null fields */ - if (!(temp_length= (*field)->pack_length())) - continue; /* Skip null-fields */ - if (! found || fieldpos < minpos || - (fieldpos == minpos && temp_length < length)) - { - minpos=fieldpos; found= *field; length=temp_length; - } - } - } - DBUG_PRINT("loop",("found: %lx recpos: %d minpos: %d length: %d", - found,recpos,minpos,length)); - if (recpos != minpos) - { // Reserved space (Null bits?) - bzero((char*) recinfo_pos,sizeof(*recinfo_pos)); - recinfo_pos->type=(int) FIELD_NORMAL; - recinfo_pos++->length= (uint16) (minpos-recpos); - } - if (! found) - break; - - if (found->flags & BLOB_FLAG) - { - recinfo_pos->type= (int) FIELD_BLOB; - } - else if (!(options & HA_OPTION_PACK_RECORD)) - recinfo_pos->type= (int) FIELD_NORMAL; - else if (found->zero_pack()) - recinfo_pos->type= (int) FIELD_SKIP_ZERO; - else - recinfo_pos->type= (int) ((length <= 3 || - (found->flags & ZEROFILL_FLAG)) ? - FIELD_NORMAL : - found->type() == FIELD_TYPE_STRING || - found->type() == FIELD_TYPE_VAR_STRING ? - FIELD_SKIP_ENDSPACE : - FIELD_SKIP_PRESPACE); - if (found->null_ptr) - { - recinfo_pos->null_bit=found->null_bit; - recinfo_pos->null_pos= (uint) (found->null_ptr- - (uchar*) table_arg->record[0]); - } - else - { - recinfo_pos->null_bit=0; - recinfo_pos->null_pos=0; - } - (recinfo_pos++) ->length=(uint16) length; - recpos=minpos+length; - DBUG_PRINT("loop",("length: %d type: %d", - recinfo_pos[-1].length,recinfo_pos[-1].type)); - - } + MI_COLUMNDEF *recinfo; MI_CREATE_INFO create_info; - bzero((char*) &create_info,sizeof(create_info)); - create_info.max_rows=table_arg->max_rows; - create_info.reloc_rows=table_arg->min_rows; - create_info.with_auto_increment=found_real_auto_increment; - create_info.auto_increment=(info->auto_increment_value ? - info->auto_increment_value -1 : - (ulonglong) 0); + DBUG_ENTER("ha_myisam::create"); + if ((error= table2myisam(table_arg, &keydef, &recinfo, &records))) + DBUG_RETURN(error); /* purecov: inspected */ + bzero((char*) &create_info, sizeof(create_info)); + create_info.max_rows= table_arg->max_rows; + create_info.reloc_rows= table_arg->min_rows; + create_info.with_auto_increment= table_arg->next_number_key_offset == 0; + create_info.auto_increment= (info->auto_increment_value ? + info->auto_increment_value -1 : + (ulonglong) 0); create_info.data_file_length= ((ulonglong) table_arg->max_rows * - table_arg->avg_row_length); - create_info.raid_type=info->raid_type; + table_arg->avg_row_length); + create_info.raid_type= info->raid_type; create_info.raid_chunks= (info->raid_chunks ? info->raid_chunks : - RAID_DEFAULT_CHUNKS); - create_info.raid_chunksize=(info->raid_chunksize ? info->raid_chunksize : - RAID_DEFAULT_CHUNKSIZE); + RAID_DEFAULT_CHUNKS); + create_info.raid_chunksize= (info->raid_chunksize ? info->raid_chunksize : + RAID_DEFAULT_CHUNKSIZE); create_info.data_file_name= info->data_file_name; - create_info.index_file_name=info->index_file_name; + create_info.index_file_name= info->index_file_name; if (info->options & HA_LEX_CREATE_TMP_TABLE) create_flags|= HA_CREATE_TMP_TABLE; @@ -1531,13 +1670,13 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, create_flags|= HA_CREATE_DELAY_KEY_WRITE; /* TODO: Check that the following fn_format is really needed */ - error=mi_create(fn_format(buff,name,"","",2+4), - table_arg->keys,keydef, - (uint) (recinfo_pos-recinfo), recinfo, - 0, (MI_UNIQUEDEF*) 0, - &create_info, create_flags); - - my_free((gptr) recinfo,MYF(0)); + error= mi_create(fn_format(buff, name, "", "", + MY_UNPACK_FILENAME|MY_REPLACE_EXT), + table_arg->keys, keydef, + records, recinfo, + 0, (MI_UNIQUEDEF*) 0, + &create_info, create_flags); + my_free((gptr) recinfo, MYF(0)); DBUG_RETURN(error); } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 1fed5cc35f0..53923add49a 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -32,6 +32,13 @@ ** MyISAM MERGE tables *****************************************************************************/ +extern int table2myisam(TABLE *table_arg, MI_KEYDEF **keydef_out, + MI_COLUMNDEF **recinfo_out, uint *records_out); +extern int check_definition(MI_KEYDEF *t1_keyinfo, MI_COLUMNDEF *t1_recinfo, + uint t1_keys, uint t1_recs, + MI_KEYDEF *t2_keyinfo, MI_COLUMNDEF *t2_recinfo, + uint t2_keys, uint t2_recs, bool strict); + const char **ha_myisammrg::bas_ext() const { static const char *ext[]= { ".MRG", NullS }; return ext; } @@ -49,6 +56,12 @@ const char *ha_myisammrg::index_type(uint key_number) int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) { + MI_KEYDEF *keyinfo; + MI_COLUMNDEF *recinfo; + MYRG_TABLE *u_table; + uint recs; + uint keys= table->keys; + int error; char name_buff[FN_REFLEN]; DBUG_PRINT("info", ("ha_myisammrg::open")); @@ -69,20 +82,45 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) if (table->reclength != mean_rec_length && mean_rec_length) { - DBUG_PRINT("error",("reclength: %d mean_rec_length: %d", + DBUG_PRINT("error",("reclength: %d mean_rec_length: %lu", table->reclength, mean_rec_length)); + error= HA_ERR_WRONG_MRG_TABLE_DEF; goto err; } + if ((error= table2myisam(table, &keyinfo, &recinfo, &recs))) + { + /* purecov: begin inspected */ + DBUG_PRINT("error", ("Failed to convert TABLE object to MyISAM " + "key and column definition")); + goto err; + /* purecov: end */ + } + for (u_table= file->open_tables; u_table < file->end_table; u_table++) + { + if (check_definition(keyinfo, recinfo, keys, recs, + u_table->table->s->keyinfo, u_table->table->s->rec, + u_table->table->s->base.keys, + u_table->table->s->base.fields, false)) + { + my_free((gptr) recinfo, MYF(0)); + error= HA_ERR_WRONG_MRG_TABLE_DEF; + goto err; + } + } + my_free((gptr) recinfo, MYF(0)); #if !defined(BIG_TABLES) || SIZEOF_OFF_T == 4 /* Merge table has more than 2G rows */ if (table->crashed) + { + error= HA_ERR_WRONG_MRG_TABLE_DEF; goto err; + } #endif return (0); err: myrg_close(file); file=0; - return (my_errno= HA_ERR_WRONG_MRG_TABLE_DEF); + return (my_errno= error); } int ha_myisammrg::close(void) From 91f6883758c68132433b2335a8294f6ac7471109 Mon Sep 17 00:00:00 2001 From: "holyfoot/hf@mysql.com/hfmain.(none)" <> Date: Wed, 31 Jan 2007 16:45:33 +0400 Subject: [PATCH 16/30] bug #25973 (ps_1general.test fails in embedded server) --- mysql-test/t/ps_1general.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 33b86dde9ed..d4e6a62c09e 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -588,7 +588,7 @@ prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ; create table t5 (a int) ; # rename must fail, t7 does not exist # Clean up the filename here because embedded server reports whole path ---replace_result \\ / $MYSQL_TEST_DIR . /var/master-data/ / t7.frm t7 +--replace_result \\ / $MYSQLTEST_VARDIR . /master-data/ / t7.frm t7 --error 1017 execute stmt1 ; create table t7 (a int) ; From 16d2d68257ab131f53cf8fc8c2d9abf871b5a1b0 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@macbook.gmz" <> Date: Wed, 31 Jan 2007 16:04:38 +0200 Subject: [PATCH 17/30] BUG#25575: ERROR 1052 (Column in from clause is ambiguous) with sub-join Two problems here: Problem 1: While constructing the join columns list the optimizer does as follows: 1. Sets the join_using_fields/natural_join members of the right JOIN operand. 2. Makes a "table reference" (TABLE_LIST) to parent the two tables. 3. Assigns the join_using_fields/is_natural_join of the wrapper table using join_using_fields/natural_join of the rightmost table 4. Sets join_using_fields to NULL for the right JOIN operand. 5. Passes the parent table up to the same procedure on the upper level. Step 1 overrides the the join_using_fields that are set for a nested join wrapping table in step 4. Fixed by making a designated variable SELECT_LEX::prev_join_using to pass the data from step 1 to step 4 without destroying the wrapping table data. Problem 2: The optimizer checks for ambiguous columns while transforming NATURAL JOIN/JOIN USING to JOIN ON. While doing that there was no distinction between columns that are used in the generated join condition (where ambiguity can be checked) and the other columns (where ambiguity can be checked only when resolving references coming from outside the JOIN construct itself). Fixed by allowing the non-USING columns to be present in multiple copies in both sides of the join and moving the ambiguity check to the place where unqualified references to the join columns are resolved (find_field_in_natural_join()). --- mysql-test/r/join_nested.result | 28 ++++++++++++++++++ mysql-test/t/join_nested.test | 39 +++++++++++++++++++++++++ sql/mysql_priv.h | 3 +- sql/sql_base.cc | 51 ++++++++++++++++++++++++++------- sql/sql_lex.h | 14 +++++++++ sql/sql_parse.cc | 13 ++++----- sql/sql_yacc.yy | 16 +++++++---- sql/table.cc | 1 + 8 files changed, 140 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result index f5c98f383b7..006488f9d43 100644 --- a/mysql-test/r/join_nested.result +++ b/mysql-test/r/join_nested.result @@ -1605,3 +1605,31 @@ WHERE t1.id='5'; id ct pc nm 5 NULL NULL NULL DROP TABLE t1,t2,t3,t4; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, c INT); +CREATE TABLE t4 (a INT, c INT); +CREATE TABLE t5 (a INT, c INT); +SELECT b FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +b +SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +ERROR 23000: Column 'c' in field list is ambiguous +SELECT b FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a) +JOIN t5 USING (a)) USING (a); +b +SELECT c FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a) +JOIN t5 USING (a)) USING (a); +ERROR 23000: Column 'c' in field list is ambiguous +DROP TABLE t1,t2,t3,t4,t5; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT, b INT); +CREATE TABLE t3 (a INT, b INT); +INSERT INTO t1 VALUES (1,1); +INSERT INTO t2 VALUES (1,1); +INSERT INTO t3 VALUES (1,1); +SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a); +ERROR 23000: Column 'a' in from clause is ambiguous +DROP TABLE t1,t2,t3; +End of 5.0 tests diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test index e7405418be7..f29366797f6 100644 --- a/mysql-test/t/join_nested.test +++ b/mysql-test/t/join_nested.test @@ -1045,3 +1045,42 @@ SELECT t1.*, t4.nm WHERE t1.id='5'; DROP TABLE t1,t2,t3,t4; + +# +# BUG#25575: ERROR 1052 (Column in from clause is ambiguous) with sub-join +# +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, c INT); +CREATE TABLE t4 (a INT, c INT); +CREATE TABLE t5 (a INT, c INT); + +SELECT b FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); + +--error ER_NON_UNIQ_ERROR +SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); + +SELECT b FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a) +JOIN t5 USING (a)) USING (a); + +--error ER_NON_UNIQ_ERROR +SELECT c FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a) +JOIN t5 USING (a)) USING (a); + +DROP TABLE t1,t2,t3,t4,t5; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT, b INT); +CREATE TABLE t3 (a INT, b INT); + +INSERT INTO t1 VALUES (1,1); +INSERT INTO t2 VALUES (1,1); +INSERT INTO t3 VALUES (1,1); + +--error ER_NON_UNIQ_ERROR +SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a); + +DROP TABLE t1,t2,t3; + +--echo End of 5.0 tests diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index caf3e6479f9..b4f2e712f33 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -982,7 +982,8 @@ bool push_new_name_resolution_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op); void add_join_on(TABLE_LIST *b,Item *expr); -void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List *using_fields); +void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List *using_fields, + SELECT_LEX *lex); bool add_proc_to_list(THD *thd, Item *item); TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find); void update_non_unique_table_error(TABLE_LIST *update, diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0949d4aa331..ad9cd5985d1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2945,7 +2945,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, { List_iterator_fast field_it(*(table_ref->join_columns)); - Natural_join_column *nj_col; + Natural_join_column *nj_col, *curr_nj_col; Field *found_field; Query_arena *arena, backup; DBUG_ENTER("find_field_in_natural_join"); @@ -2956,14 +2956,21 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, LINT_INIT(found_field); - for (;;) + for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col; + curr_nj_col= field_it++) { - if (!(nj_col= field_it++)) - DBUG_RETURN(NULL); - - if (!my_strcasecmp(system_charset_info, nj_col->name(), name)) - break; + if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name)) + { + if (nj_col) + { + my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where); + DBUG_RETURN(NULL); + } + nj_col= curr_nj_col; + } } + if (!nj_col) + DBUG_RETURN(NULL); if (nj_col->view_field) { @@ -3774,9 +3781,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, { bool found= FALSE; const char *field_name_1; + /* true if field_name_1 is a member of using_fields */ + bool is_using_column_1; if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1))) goto err; field_name_1= nj_col_1->name(); + is_using_column_1= using_fields && + test_if_string_in_list(field_name_1, using_fields); + DBUG_PRINT ("info", ("field_name_1=%s.%s", + nj_col_1->table_name() ? nj_col_1->table_name() : "", + field_name_1)); /* Find a field with the same name in table_ref_2. @@ -3793,6 +3807,10 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2))) goto err; cur_field_name_2= cur_nj_col_2->name(); + DBUG_PRINT ("info", ("cur_field_name_2=%s.%s", + cur_nj_col_2->table_name() ? + cur_nj_col_2->table_name() : "", + cur_field_name_2)); /* Compare the two columns and check for duplicate common fields. @@ -3800,10 +3818,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, table_ref_2 (then found == TRUE), or if a field in table_ref_2 was already matched by some previous field in table_ref_1 (then cur_nj_col_2->is_common == TRUE). + Note that it is too early to check the columns outside of the + USING list for ambiguity because they are not actually "referenced" + here. These columns must be checked only on unqualified reference + by name (e.g. in SELECT list). */ if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2)) { - if (found || cur_nj_col_2->is_common) + DBUG_PRINT ("info", ("match c1.is_common=%d", nj_col_1->is_common)); + if (cur_nj_col_2->is_common || + (found && (!using_fields || is_using_column_1))) { my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where); goto err; @@ -3829,9 +3853,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, clause (if present), mark them as common fields, and add a new equi-join condition to the ON clause. */ - if (nj_col_2 && - (!using_fields || - test_if_string_in_list(field_name_1, using_fields))) + if (nj_col_2 && (!using_fields ||is_using_column_1)) { Item *item_1= nj_col_1->create_item(thd); Item *item_2= nj_col_2->create_item(thd); @@ -3886,6 +3908,13 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, eq_cond); nj_col_1->is_common= nj_col_2->is_common= TRUE; + DBUG_PRINT ("info", ("%s.%s and %s.%s are common", + nj_col_1->table_name() ? + nj_col_1->table_name() : "", + nj_col_1->name(), + nj_col_2->table_name() ? + nj_col_2->table_name() : "", + nj_col_2->name())); if (field_1) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 1bf37c92b85..83daec89a50 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -587,6 +587,20 @@ public: int cur_pos_in_select_list; List udf_list; /* udf function calls stack */ + /* + This is a copy of the original JOIN USING list that comes from + the parser. The parser : + 1. Sets the natural_join of the second TABLE_LIST in the join + and the st_select_lex::prev_join_using. + 2. Makes a parent TABLE_LIST and sets its is_natural_join/ + join_using_fields members. + 3. Uses the wrapper TABLE_LIST as a table in the upper level. + We cannot assign directly to join_using_fields in the parser because + at stage (1.) the parent TABLE_LIST is not constructed yet and + the assignment will override the JOIN USING fields of the lower level + joins on the right. + */ + List *prev_join_using; void init_query(); void init_select(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 007c5edd673..5c307a7260e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6365,11 +6365,8 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) If this is a JOIN ... USING, move the list of joined fields to the table reference that describes the join. */ - if (table->join_using_fields) - { - ptr->join_using_fields= table->join_using_fields; - table->join_using_fields= NULL; - } + if (prev_join_using) + ptr->join_using_fields= prev_join_using; } } join_list->push_front(ptr); @@ -6625,6 +6622,7 @@ void add_join_on(TABLE_LIST *b, Item *expr) a Left join argument b Right join argument using_fields Field names from USING clause + lex The current st_select_lex IMPLEMENTATION This function marks that table b should be joined with a either via @@ -6653,10 +6651,11 @@ void add_join_on(TABLE_LIST *b, Item *expr) None */ -void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List *using_fields) +void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List *using_fields, + SELECT_LEX *lex) { b->natural_join= a; - b->join_using_fields= using_fields; + lex->prev_join_using= using_fields; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 90dc6d54fe1..bc58a14a9f9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5280,11 +5280,11 @@ join_table: YYERROR_UNLESS($1 && $3); } '(' using_list ')' - { add_join_natural($1,$3,$7); $$=$3; } + { add_join_natural($1,$3,$7,Select); $$=$3; } | table_ref NATURAL JOIN_SYM table_factor { YYERROR_UNLESS($1 && ($$=$4)); - add_join_natural($1,$4,NULL); + add_join_natural($1,$4,NULL,Select); } /* LEFT JOIN variants */ @@ -5311,11 +5311,15 @@ join_table: YYERROR_UNLESS($1 && $5); } USING '(' using_list ')' - { add_join_natural($1,$5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } + { + add_join_natural($1,$5,$9,Select); + $5->outer_join|=JOIN_TYPE_LEFT; + $$=$5; + } | table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor { YYERROR_UNLESS($1 && $6); - add_join_natural($1,$6,NULL); + add_join_natural($1,$6,NULL,Select); $6->outer_join|=JOIN_TYPE_LEFT; $$=$6; } @@ -5349,12 +5353,12 @@ join_table: LEX *lex= Lex; if (!($$= lex->current_select->convert_right_join())) YYABORT; - add_join_natural($$,$5,$9); + add_join_natural($$,$5,$9,Select); } | table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor { YYERROR_UNLESS($1 && $6); - add_join_natural($6,$1,NULL); + add_join_natural($6,$1,NULL,Select); LEX *lex= Lex; if (!($$= lex->current_select->convert_right_join())) YYABORT; diff --git a/sql/table.cc b/sql/table.cc index 2a492a15722..d8aeed6f54b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -2628,6 +2628,7 @@ Field *Natural_join_column::field() const char *Natural_join_column::table_name() { + DBUG_ASSERT(table_ref); return table_ref->alias; } From e56eb2288cc31a8a0d0cbf478aeb99f62be95ec3 Mon Sep 17 00:00:00 2001 From: "joerg@trift2." <> Date: Wed, 31 Jan 2007 15:25:56 +0100 Subject: [PATCH 18/30] Fix bug#23293 "readline detection broken on NetBSD": Its root cause is a difference between the "readline" and "libedit" (header files) definitions of "rl_completion_entry_function", where the "libedit" one is wrong anyway: This variable is used as a pointer to a function returning "char *", but "libedit" declares it as returning "int" and then adds casts on usage. Change it to "CPFunction *" and get rid of the casts. --- client/mysql.cc | 6 +++--- cmd-line-utils/libedit/readline.c | 11 +++++------ cmd-line-utils/libedit/readline/readline.h | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 4e479f3ff70..75dae284b61 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1420,7 +1420,7 @@ static char **new_mysql_completion (const char *text, int start, int end); #if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE) char *no_completion(const char*,int) #else -int no_completion() +char *no_completion() #endif { return 0; /* No filename completion */ @@ -1508,10 +1508,10 @@ static void initialize_readline (char *name) setlocale(LC_ALL,""); /* so as libedit use isprint */ #endif rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion; - rl_completion_entry_function= (Function*)&no_completion; + rl_completion_entry_function= &no_completion; #else rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion; - rl_completion_entry_function= (Function*)&no_completion; + rl_completion_entry_function= &no_completion; #endif } diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 8c09a6f39d5..004fcf7d183 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -112,7 +112,7 @@ int rl_attempted_completion_over = 0; char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; -Function *rl_completion_entry_function = NULL; +CPFunction *rl_completion_entry_function = NULL; CPPFunction *rl_attempted_completion_function = NULL; Function *rl_pre_input_hook = NULL; Function *rl_startup1_hook = NULL; @@ -1724,7 +1724,7 @@ rl_display_match_list (matches, len, max) static int _rl_complete_internal(int what_to_do) { - Function *complet_func; + CPFunction *complet_func; const LineInfo *li; char *temp, **matches; const char *ctemp; @@ -1737,7 +1737,7 @@ _rl_complete_internal(int what_to_do) complet_func = rl_completion_entry_function; if (!complet_func) - complet_func = (Function *)(void *)filename_completion_function; + complet_func = filename_completion_function; /* We now look backwards for the start of a filename/variable word */ li = el_line(e); @@ -1764,7 +1764,7 @@ _rl_complete_internal(int what_to_do) } else matches = 0; if (!rl_attempted_completion_function || !matches) - matches = completion_matches(temp, (CPFunction *)complet_func); + matches = completion_matches(temp, complet_func); if (matches) { int i, retval = CC_REFRESH; @@ -1789,8 +1789,7 @@ _rl_complete_internal(int what_to_do) * object is a directory. */ size_t alen = strlen(matches[0]); - if ((complet_func != - (Function *)filename_completion_function + if ((complet_func != filename_completion_function || (alen > 0 && (matches[0])[alen - 1] != '/')) && rl_completion_append_character) { char buf[2]; diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h index c43f71fb51d..6b1fa186512 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/readline/readline.h @@ -102,7 +102,7 @@ extern int max_input_history; extern char *rl_basic_word_break_characters; extern char *rl_completer_word_break_characters; extern char *rl_completer_quote_characters; -extern Function *rl_completion_entry_function; +extern CPFunction *rl_completion_entry_function; extern CPPFunction *rl_attempted_completion_function; extern int rl_completion_type; extern int rl_completion_query_items; From 11322bfaf154fc263f76b905022d39decb568e72 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/june.mysql.com" <> Date: Wed, 31 Jan 2007 18:32:53 +0400 Subject: [PATCH 19/30] After merge fix (WL#3567). --- sql/ha_myisam.cc | 3 ++- sql/ha_myisammrg.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 18e621142f7..39f8894ae89 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1728,12 +1728,13 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, HA_CREATE_INFO *info) { int error; - uint create_flags= 0, options= table_arg->db_options_in_use, records; + uint create_flags= 0, records; char buff[FN_REFLEN]; MI_KEYDEF *keydef; MI_COLUMNDEF *recinfo; MI_CREATE_INFO create_info; TABLE_SHARE *share= table->s; + uint options= share->db_options_in_use; DBUG_ENTER("ha_myisam::create"); if ((error= table2myisam(table_arg, &keydef, &recinfo, &records))) DBUG_RETURN(error); /* purecov: inspected */ diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 97823e2cf47..8e24164abc9 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -97,7 +97,7 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) MI_COLUMNDEF *recinfo; MYRG_TABLE *u_table; uint recs; - uint keys= table->keys; + uint keys= table->s->keys; int error; char name_buff[FN_REFLEN]; From beb265b2fe82857a43d34ef4d67faf7822e14313 Mon Sep 17 00:00:00 2001 From: "df@kahlann.erinye.com" <> Date: Wed, 31 Jan 2007 18:18:44 +0100 Subject: [PATCH 20/30] MTR_BUILD_THREAD=auto for test runs during RPM build --- support-files/mysql.spec.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 528b1f2746b..0dbe59a8831 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -345,6 +345,8 @@ then fi ( cd mysql-test + MTR_BUILD_THREAD=auto + export MTR_BUILD_THREAD perl ./mysql-test-run.pl --force --report-features perl ./mysql-test-run.pl --force --ps-protocol true ) @@ -407,6 +409,8 @@ then fi ( cd mysql-test + MTR_BUILD_THREAD=auto + export MTR_BUILD_THREAD perl ./mysql-test-run.pl --force --report-features perl ./mysql-test-run.pl --force --ps-protocol true ) @@ -755,6 +759,10 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Wed Jan 31 2007 Daniel Fischer + +- add MTR_BUILD_THREAD=auto to test runs. + * Fri Jan 05 2007 Kent Boortz - Add CFLAGS to gcc call with --print-libgcc-file, to make sure the From 710136217bfadb3d2c418b4f04bcfa71e8193b6c Mon Sep 17 00:00:00 2001 From: "igor@olga.mysql.com" <> Date: Wed, 31 Jan 2007 19:31:36 -0800 Subject: [PATCH 21/30] Fixed bug #25407. The bug could cause choosing a sub-optimal execution plan for a single-table query if a unique index with many null keys were defined for the table. It happened because the code of the check_quick_keys function made an assumption that any key may occur in an unique index only once. Yet this is not true for keys with nulls that may have multiple occurrences in the index. --- mysql-test/r/null_key.result | 4 +- mysql-test/r/select.result | 86 ++++++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 74 +++++++++++++++++++++++++++++++ sql/opt_range.cc | 12 ++++- 4 files changed, 173 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index 6eb3cf312a0..0b4ed15f659 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -30,7 +30,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a,b a 5 const 3 Using where; Using index explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a,b a 5 const 2 Using where; Using index +1 SIMPLE t1 range a,b a 9 NULL 3 Using where; Using index explain select * from t1 where a > 1 and a < 3 limit 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index @@ -258,7 +258,7 @@ INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4 INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL); explain select id from t1 where uniq_id is null; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref idx1 idx1 5 const 1 Using where +1 SIMPLE t1 ref idx1 idx1 5 const 5 Using where explain select id from t1 where uniq_id =1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const idx1 idx1 5 const 1 diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 5dcf830ca97..f3938fd6413 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3642,3 +3642,89 @@ INSERT into t1 values (1), (2), (3); SELECT * FROM t1 LIMIT 2, -1; 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 '-1' at line 1 DROP TABLE t1; +CREATE TABLE t1 ( +ID_with_null int NULL, +ID_better int NOT NULL, +INDEX idx1 (ID_with_null), +INDEX idx2 (ID_better) +); +INSERT INTO t1 VALUES (1,1), (2,1), (null,3), (null,3), (null,3), (null,3); +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +SELECT COUNT(*) FROM t1 WHERE ID_with_null IS NULL; +COUNT(*) +128 +SELECT COUNT(*) FROM t1 WHERE ID_better=1; +COUNT(*) +2 +EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP INDEX idx1 ON t1; +CREATE UNIQUE INDEX idx1 ON t1(ID_with_null); +EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP TABLE t1; +CREATE TABLE t1 ( +ID1_with_null int NULL, +ID2_with_null int NULL, +ID_better int NOT NULL, +INDEX idx1 (ID1_with_null, ID2_with_null), +INDEX idx2 (ID_better) +); +INSERT INTO t1 VALUES (1,1,1), (2,2,1), (3,null,3), (null,3,3), (null,null,3), +(3,null,3), (null,3,3), (null,null,3), (3,null,3), (null,3,3), (null,null,3); +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3; +COUNT(*) +24 +SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL; +COUNT(*) +24 +SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL; +COUNT(*) +192 +SELECT COUNT(*) FROM t1 WHERE ID_better=1; +COUNT(*) +2 +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP INDEX idx1 ON t1; +CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null); +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +EXPLAIN SELECT * FROM t1 +WHERE ID_better=1 AND ID1_with_null IS NULL AND +(ID2_with_null=1 OR ID2_with_null=2); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref idx1,idx2 idx2 4 const 1 Using where +DROP TABLE t1; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 19b625451d4..19c7d742f5b 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3133,3 +3133,77 @@ SELECT * FROM t1 LIMIT 2, -1; DROP TABLE t1; +# +# 25407: wrong estimate of NULL keys for unique indexes +# + +CREATE TABLE t1 ( + ID_with_null int NULL, + ID_better int NOT NULL, + INDEX idx1 (ID_with_null), + INDEX idx2 (ID_better) +); + +INSERT INTO t1 VALUES (1,1), (2,1), (null,3), (null,3), (null,3), (null,3); +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID_with_null IS NULL; + +SELECT COUNT(*) FROM t1 WHERE ID_with_null IS NULL; +SELECT COUNT(*) FROM t1 WHERE ID_better=1; + +EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL; + +DROP INDEX idx1 ON t1; +CREATE UNIQUE INDEX idx1 ON t1(ID_with_null); + +EXPLAIN SELECT * FROM t1 WHERE ID_better=1 AND ID_with_null IS NULL; + +DROP TABLE t1; + +CREATE TABLE t1 ( + ID1_with_null int NULL, + ID2_with_null int NULL, + ID_better int NOT NULL, + INDEX idx1 (ID1_with_null, ID2_with_null), + INDEX idx2 (ID_better) +); + +INSERT INTO t1 VALUES (1,1,1), (2,2,1), (3,null,3), (null,3,3), (null,null,3), + (3,null,3), (null,3,3), (null,null,3), (3,null,3), (null,3,3), (null,null,3); + +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID1_with_null IS NULL; +INSERT INTO t1 SELECT * FROM t1 WHERE ID2_with_null IS NULL; + +SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null=3; +SELECT COUNT(*) FROM t1 WHERE ID1_with_null=3 AND ID2_with_null IS NULL; +SELECT COUNT(*) FROM t1 WHERE ID1_with_null IS NULL AND ID2_with_null IS NULL; +SELECT COUNT(*) FROM t1 WHERE ID_better=1; + +EXPLAIN SELECT * FROM t1 + WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; +EXPLAIN SELECT * FROM t1 + WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null=3 IS NULL ; +EXPLAIN SELECT * FROM t1 + WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; + +DROP INDEX idx1 ON t1; +CREATE UNIQUE INDEX idx1 ON t1(ID1_with_null,ID2_with_null); + +EXPLAIN SELECT * FROM t1 + WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null=3 ; +EXPLAIN SELECT * FROM t1 + WHERE ID_better=1 AND ID1_with_null=3 AND ID2_with_null IS NULL ; +EXPLAIN SELECT * FROM t1 + WHERE ID_better=1 AND ID1_with_null IS NULL AND ID2_with_null IS NULL; +EXPLAIN SELECT * FROM t1 + WHERE ID_better=1 AND ID1_with_null IS NULL AND + (ID2_with_null=1 OR ID2_with_null=2); + +DROP TABLE t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 04bc24b718a..f0af4b7db2a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -193,6 +193,8 @@ public: } inline void merge_flags(SEL_ARG *arg) { maybe_flag|=arg->maybe_flag; } inline void maybe_smaller() { maybe_flag=1; } + /* Return true iff it's a single-point null interval */ + inline bool is_null_interval() { return maybe_null && max_value[0] == 1; } inline int cmp_min_to_min(SEL_ARG* arg) { return sel_cmp(field,min_value, arg->min_value, min_flag, arg->min_flag); @@ -452,6 +454,7 @@ typedef struct st_qsel_param { bool is_ror_scan; /* Number of ranges in the last checked tree->key */ uint n_ranges; + uint8 first_null_comp; /* first null component if any, 0 - otherwise */ } PARAM; class TABLE_READ_PLAN; @@ -5619,6 +5622,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree) DBUG_ENTER("check_quick_select"); param->is_ror_scan= FALSE; + param->first_null_comp= 0; if (!tree) DBUG_RETURN(HA_POS_ERROR); // Can't use it @@ -5710,6 +5714,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, ha_rows records=0, tmp; uint tmp_min_flag, tmp_max_flag, keynr, min_key_length, max_key_length; char *tmp_min_key, *tmp_max_key; + uint8 save_first_null_comp= param->first_null_comp; param->max_key_part=max(param->max_key_part,key_tree->part); if (key_tree->left != &null_element) @@ -5747,6 +5752,9 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, param->is_ror_scan= FALSE; } + if (!param->first_null_comp && key_tree->is_null_interval()) + param->first_null_comp= key_tree->part+1; + if (key_tree->next_key_part && key_tree->next_key_part->part == key_tree->part+1 && key_tree->next_key_part->type == SEL_ARG::KEY_RANGE) @@ -5790,7 +5798,8 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, (param->table->key_info[keynr].flags & (HA_NOSAME | HA_END_SPACE_KEY)) == HA_NOSAME && min_key_length == max_key_length && - !memcmp(param->min_key,param->max_key,min_key_length)) + !memcmp(param->min_key,param->max_key,min_key_length) && + !param->first_null_comp) { tmp=1; // Max one record param->n_ranges++; @@ -5865,6 +5874,7 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, return tmp; records+=tmp; } + param->first_null_comp= save_first_null_comp; return records; } From 95154f86b52be53c525def99c661e87a3c98e6f2 Mon Sep 17 00:00:00 2001 From: "gkodinov/kgeorge@rakia.gmz" <> Date: Thu, 1 Feb 2007 13:25:50 +0200 Subject: [PATCH 22/30] trigger.result: merge of the 5.0-opt tree --- mysql-test/r/trigger.result | 50 ++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 340b775cb85..fe0e444f87d 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -1241,6 +1241,31 @@ i j 2 2 13 13 drop table t1; +CREATE TABLE t1 (a INT PRIMARY KEY); +CREATE TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW +INSERT INTO t2 VALUES (OLD.a); +FLUSH STATUS; +TRUNCATE t1; +SHOW STATUS LIKE 'handler_delete'; +Variable_name Value +Handler_delete 0 +SELECT COUNT(*) FROM t2; +COUNT(*) +0 +INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); +DELETE FROM t2; +FLUSH STATUS; +DELETE FROM t1; +SHOW STATUS LIKE 'handler_delete'; +Variable_name Value +Handler_delete 8 +SELECT COUNT(*) FROM t2; +COUNT(*) +8 +DROP TRIGGER trg_t1; +DROP TABLE t1,t2; drop table if exists t1; drop function if exists f1; create table t1 (i int); @@ -1310,29 +1335,4 @@ SELECT fubar_id FROM t2; fubar_id 1 DROP TABLE t1,t2; -CREATE TABLE t1 (a INT PRIMARY KEY); -CREATE TABLE t2 (a INT PRIMARY KEY); -INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); -CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW -INSERT INTO t2 VALUES (OLD.a); -FLUSH STATUS; -TRUNCATE t1; -SHOW STATUS LIKE 'handler_delete'; -Variable_name Value -Handler_delete 0 -SELECT COUNT(*) FROM t2; -COUNT(*) -0 -INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8); -DELETE FROM t2; -FLUSH STATUS; -DELETE FROM t1; -SHOW STATUS LIKE 'handler_delete'; -Variable_name Value -Handler_delete 8 -SELECT COUNT(*) FROM t2; -COUNT(*) -8 -DROP TRIGGER trg_t1; -DROP TABLE t1,t2; End of 5.0 tests From 010dc0b55c1255b75ca6ddd1bd058c157624b9df Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/eagle.(none)" <> Date: Thu, 1 Feb 2007 18:00:24 +0400 Subject: [PATCH 23/30] Valgrind error fixes Notes: This patch doesn't fix all issues in the tree and we need jani's fix for that This patch shoud not be merged into 5.0 --- mysql-test/r/ps.result | 15 -- mysql-test/r/symlink.result | 15 ++ mysql-test/t/ps.test | 18 -- mysql-test/t/symlink.test | 19 ++ mysql-test/valgrind.supp | 437 ++++++++++++++++++++++++++++++++++++ sql/field_conv.cc | 4 + sql/mysqld.cc | 3 + vio/viosslfactories.c | 4 + 8 files changed, 482 insertions(+), 33 deletions(-) create mode 100644 mysql-test/valgrind.supp diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 0d6b01f3481..d8a75737efc 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1087,19 +1087,4 @@ t2 CREATE TABLE `t2` ( drop database mysqltest; deallocate prepare stmt1; deallocate prepare stmt2; -execute stmt; -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `c` char(10) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' -drop table t1; -execute stmt; -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `c` char(10) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' -drop table t1; -deallocate prepare stmt; End of 4.1 tests. diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index bc7d3275754..9b21dc7e952 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -123,4 +123,19 @@ select * from t1; a 42 drop table t1; +execute stmt; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(10) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' +drop table t1; +execute stmt; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c` char(10) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' +drop table t1; +deallocate prepare stmt; End of 4.1 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index c963e59110f..a0133897f50 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1128,22 +1128,4 @@ drop database mysqltest; deallocate prepare stmt1; deallocate prepare stmt2; # -# CREATE TABLE with DATA DIRECTORY option -# -# Protect ourselves from data left in tmp/ by a previos possibly failed -# test ---system rm -f $MYSQLTEST_VARDIR/tmp/t1.* ---disable_query_log -eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'"; ---enable_query_log -execute stmt; ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -show create table t1; -drop table t1; -execute stmt; ---replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -show create table t1; -drop table t1; -deallocate prepare stmt; -# --echo End of 4.1 tests. diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 23fd779ee13..010ef496399 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -170,4 +170,23 @@ connection default; select * from t1; drop table t1; +# +# CREATE TABLE with DATA DIRECTORY option +# +# Protect ourselves from data left in tmp/ by a previos possibly failed +# test +--system rm -f $MYSQLTEST_VARDIR/tmp/t1.* +--disable_query_log +eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'"; +--enable_query_log +execute stmt; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +show create table t1; +drop table t1; +execute stmt; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +show create table t1; +drop table t1; +deallocate prepare stmt; + --echo End of 4.1 tests diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp new file mode 100644 index 00000000000..716dca491ce --- /dev/null +++ b/mysql-test/valgrind.supp @@ -0,0 +1,437 @@ +# +# Suppress some common (not fatal) errors in system libraries found by valgrind +# + +# +# Pthread doesn't free all thread specific memory before program exists +# +{ + pthread allocate_tls memory loss + Memcheck:Leak + fun:calloc + fun:_dl_allocate_tls + fun:allocate_stack + fun:pthread_create* +} + +{ + pthread allocate_tls memory loss + Memcheck:Leak + fun:calloc + fun:_dl_allocate_tls + fun:pthread_create* +} + +{ + pthread allocate_dtv memory loss + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls_storage + fun:__GI__dl_allocate_tls + fun:pthread_create +} + +{ + pthread allocate_dtv memory loss second + Memcheck:Leak + fun:calloc + fun:allocate_dtv + fun:_dl_allocate_tls + fun:pthread_create* +} + +{ + pthread memalign memory loss + Memcheck:Leak + fun:memalign + fun:_dl_allocate_tls_storage + fun:__GI__dl_allocate_tls + fun:pthread_create +} + +{ + pthread pthread_key_create + Memcheck:Leak + fun:malloc + fun:* + fun:* + fun:pthread_key_create + fun:my_thread_global_init +} + +{ + pthread strstr uninit + Memcheck:Cond + fun:strstr + obj:/lib/tls/libpthread.so.* + obj:/lib/tls/libpthread.so.* + fun:call_init + fun:_dl_init + obj:/lib/ld-*.so +} + +{ + pthread errno + Memcheck:Leak + fun:calloc + fun:_dlerror_run + fun:dlsym + fun:__errno_location +} + + +# +# Warnings in libz becasue it works with aligned memory(?) +# + +{ + libz tr_flush_block + Memcheck:Cond + fun:_tr_flush_block + fun:deflate_slow + fun:deflate + fun:do_flush + fun:gzclose +} + +{ + libz tr_flush_block2 + Memcheck:Cond + fun:_tr_flush_block + fun:deflate_slow + fun:deflate + fun:compress2 +} + +{ + libz longest_match + Memcheck:Cond + fun:longest_match + fun:deflate_slow + fun:deflate + fun:do_flush +} + +{ + libz longest_match2 + Memcheck:Cond + fun:longest_match + fun:deflate_slow + fun:deflate + fun:compress2 +} + +{ + libz longest_match 3 + Memcheck:Cond + fun:longest_match + fun:deflate_slow + fun:deflate + fun:gzclose +} + +{ + libz longest_match 4 + Memcheck:Cond + fun:longest_match + fun:deflate_slow + fun:deflate + fun:gzflush +} + +{ + libz deflate + Memcheck:Cond + obj:*/libz.so.* + obj:*/libz.so.* + fun:deflate + fun:compress2 +} + +{ + libz deflate2 + Memcheck:Cond + obj:*/libz.so.* + obj:*/libz.so.* + fun:deflate + obj:*/libz.so.* + fun:gzflush +} + + +# +# Warning from my_thread_init becasue mysqld dies before kill thread exists +# + +{ + my_thread_init kill thread memory loss second + Memcheck:Leak + fun:calloc + fun:my_thread_init + fun:kill_server_thread +} + +# +# Leaks reported in _dl_* internal functions on Linux amd64 / glibc2.3.2. +# + +{ + _dl_start invalid write8 + Memcheck:Addr8 + fun:_dl_start +} + +{ + _dl_start invalid write4 + Memcheck:Addr4 + fun:_dl_start +} + +{ + _dl_start/_dl_setup_hash invalid read8 + Memcheck:Addr8 + fun:_dl_setup_hash + fun:_dl_start +} + +{ + _dl_sysdep_start invalid write8 + Memcheck:Addr8 + fun:_dl_sysdep_start +} + +{ + _dl_init invalid write8 + Memcheck:Addr8 + fun:_dl_init +} + +{ + _dl_init invalid write4 + Memcheck:Addr4 + fun:_dl_init +} + +{ + _dl_init/_dl_init invalid read8 + Memcheck:Addr8 + fun:_dl_debug_initialize + fun:_dl_init +} + +{ + _dl_init/_dl_debug_state invalid read8 + Memcheck:Addr8 + fun:_dl_debug_state + fun:_dl_init +} + +{ + init invalid write8 + Memcheck:Addr8 + fun:init +} + +{ + fixup invalid write8 + Memcheck:Addr8 + fun:fixup +} + +{ + fixup/_dl_lookup_versioned_symbol invalid read8 + Memcheck:Addr8 + fun:_dl_lookup_versioned_symbol + fun:fixup +} + +{ + _dl_runtime_resolve invalid read8 + Memcheck:Addr8 + fun:_dl_runtime_resolve +} + +{ + __libc_start_main invalid write8 + Memcheck:Addr8 + fun:__libc_start_main +} + +{ + __libc_start_main/__sigjmp_save invalid write4 + Memcheck:Addr4 + fun:__sigjmp_save + fun:__libc_start_main +} + +# +# These seem to be libc threading stuff, not related to MySQL code (allocations +# during pthread_exit()). Googling shows other projects also using these +# suppressions. +# +# Note that these all stem from pthread_exit() deeper in the call stack, but +# Valgrind only allows the top four calls in the suppressions. +# + +{ + libc pthread_exit 1 + Memcheck:Leak + fun:malloc + fun:_dl_new_object + fun:_dl_map_object_from_fd + fun:_dl_map_object +} + +{ + libc pthread_exit 2 + Memcheck:Leak + fun:malloc + fun:_dl_map_object + fun:dl_open_worker + fun:_dl_catch_error +} + +{ + libc pthread_exit 3 + Memcheck:Leak + fun:malloc + fun:_dl_map_object_deps + fun:dl_open_worker + fun:_dl_catch_error +} + +{ + libc pthread_exit 4 + Memcheck:Leak + fun:calloc + fun:_dl_check_map_versions + fun:dl_open_worker + fun:_dl_catch_error +} + +{ + libc pthread_exit 5 + Memcheck:Leak + fun:calloc + fun:_dl_new_object + fun:_dl_map_object_from_fd + fun:_dl_map_object +} + + + +# +# This is seen internally in the system libraries on 64-bit RHAS3. +# + +{ + __lll_mutex_unlock_wake uninitialized + Memcheck:Param + futex(utime) + fun:__lll_mutex_unlock_wake +} + +# +# BUG#19940: NDB sends uninitialized parts of field buffers across the wire. +# This is "works as designed"; the uninitialized part is not used at the +# other end (but Valgrind cannot see this). +# +{ + bug19940 + Memcheck:Param + socketcall.sendto(msg) + fun:send + fun:_ZN15TCP_Transporter6doSendEv + fun:_ZN19TransporterRegistry11performSendEv + fun:_ZN19TransporterRegistry14forceSendCheckEi +} + +{ + OpenSSL_1 + Memcheck:Cond + fun:BN_num_bits_word + fun:BN_num_bits + fun:BN_mod_exp_mont_consttime + fun:BN_mod_exp_mont + obj:*libcrypto.so.* + obj:*libcrypto.so.* + fun:DH_generate_key + fun:ssl3_ctx_ctrl + fun:SSL_CTX_ctrl + fun:new_VioSSLAcceptorFd + fun:main +} + +{ + OpenSSL_2 + Memcheck:Value4 + fun:BN_num_bits_word + fun:BN_num_bits + fun:BN_mod_exp_mont_consttime + fun:BN_mod_exp_mont + obj:*libcrypto.so.* + obj:*libcrypto.so.* + fun:DH_generate_key + fun:ssl3_ctx_ctrl + fun:SSL_CTX_ctrl + fun:new_VioSSLAcceptorFd + fun:main +} + +{ + OpenSSL_3 + Memcheck:Value4 + fun:BN_mod_exp_mont_consttime + fun:BN_mod_exp_mont + obj:*libcrypto.so.* + obj:*libcrypto.so.* + fun:DH_generate_key + fun:ssl3_ctx_ctrl + fun:SSL_CTX_ctrl + fun:new_VioSSLAcceptorFd + fun:main +} + +{ + OpenSSL_4 + Memcheck:Cond + fun:BN_bin2bn + obj:*libcrypto.so.* + obj:*libcrypto.so.* + fun:DH_generate_key + fun:ssl3_ctx_ctrl + fun:SSL_CTX_ctrl + fun:new_VioSSLAcceptorFd + fun:main +} + +{ + OpenSSL_5 + Memcheck:Leak + fun:realloc + obj:*libcrypto.so.* + fun:CRYPTO_realloc + fun:lh_insert + fun:OBJ_NAME_add + fun:EVP_add_cipher + fun:OpenSSL_add_all_ciphers + fun:OPENSSL_add_all_algorithms_noconf + fun:new_VioSSLAcceptorFd + fun:main +} + +{ + OpenSSL_6 + Memcheck:Leak + fun:malloc + obj:*libcrypto.so.* + fun:CRYPTO_malloc + fun:lh_new + fun:OBJ_NAME_init + fun:OBJ_NAME_add + fun:EVP_add_cipher + fun:SSL_library_init + fun:new_VioSSLAcceptorFd + fun:main +} diff --git a/sql/field_conv.cc b/sql/field_conv.cc index d61b3735c91..59b550572c3 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -605,6 +605,10 @@ void field_conv(Field *to,Field *from) from->charset() == to->charset() && to->table->db_low_byte_first == from->table->db_low_byte_first) { // Identical fields +#ifdef HAVE_purify + /* This may happen if one does 'UPDATE ... SET x=x' */ + if (to->ptr != from->ptr) +#endif memcpy(to->ptr,from->ptr,to->pack_length()); return; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d9962eec4c1..0cccf097132 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1070,7 +1070,10 @@ void clean_up(bool print_message) #endif #ifdef HAVE_OPENSSL if (ssl_acceptor_fd) + { + SSL_CTX_free(ssl_acceptor_fd->ssl_context); my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); + } #endif /* HAVE_OPENSSL */ #ifdef USE_REGEX my_regex_end(); diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 46306cf48bb..1ac5d96d158 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -289,6 +289,8 @@ new_VioSSLConnectorFd(const char* key_file, DBUG_RETURN(ptr); ctor_failure: DBUG_PRINT("exit", ("there was an error")); + if (ptr->ssl_context) + SSL_CTX_free(ptr->ssl_context); my_free((gptr)ptr,MYF(0)); DBUG_RETURN(0); } @@ -390,6 +392,8 @@ new_VioSSLAcceptorFd(const char *key_file, ctor_failure: DBUG_PRINT("exit", ("there was an error")); + if (ptr->ssl_context) + SSL_CTX_free(ptr->ssl_context); my_free((gptr) ptr,MYF(0)); DBUG_RETURN(0); } From b0e8f2b534d0314e41fa3005a584b6d3574216cc Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Thu, 1 Feb 2007 15:59:51 +0100 Subject: [PATCH 24/30] Bug#25844: "make test" does not find mysql-test-run.pl Need to change directory before calling mysql-test-run.pl --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 798d1944fd0..04d50ccfbaf 100644 --- a/Makefile.am +++ b/Makefile.am @@ -123,6 +123,7 @@ tags: # making sure each user use different ports. test-ps: + cd mysql-test ; \ @PERL@ ./mysql-test-run.pl $(force) --ps-protocol test-ns: From d1185aaeafb9b34729db600160760a5dd7c59511 Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/eagle.(none)" <> Date: Thu, 1 Feb 2007 19:12:45 +0400 Subject: [PATCH 25/30] Bug#23299 Some queries against INFORMATION_SCHEMA with subqueries fail additional call of file->extra() method with HA_EXTRA_NO_CACHE parameter --- mysql-test/r/information_schema.result | 10 ++++++++++ mysql-test/t/information_schema.test | 12 ++++++++++++ sql/sql_show.cc | 1 + 3 files changed, 23 insertions(+) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 21d7bfb1b21..b93a4c28849 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1269,3 +1269,13 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 0 const row not found 2 DERIVED tables ALL NULL NULL NULL NULL 2 drop view v1; +create table t1 (f1 int(11)); +create table t2 (f1 int(11), f2 int(11)); +select table_name from information_schema.tables +where table_schema = 'test' and table_name not in +(select table_name from information_schema.columns +where table_schema = 'test' and column_name = 'f3'); +table_name +t1 +t2 +drop table t1,t2; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 623ccee49e4..d1dd485e21c 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -987,4 +987,16 @@ explain select * from v1; explain select * from (select table_name from information_schema.tables) as a; drop view v1; +# +# Bug#23299 Some queries against INFORMATION_SCHEMA with subqueries fail +# +create table t1 (f1 int(11)); +create table t2 (f1 int(11), f2 int(11)); + +select table_name from information_schema.tables +where table_schema = 'test' and table_name not in +(select table_name from information_schema.columns + where table_schema = 'test' and column_name = 'f3'); +drop table t1,t2; + # End of 5.0 tests. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 21a5ead90af..23059ac545a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3973,6 +3973,7 @@ bool get_schema_tables_result(JOIN *join) if (is_subselect) // is subselect { + table_list->table->file->extra(HA_EXTRA_NO_CACHE); table_list->table->file->extra(HA_EXTRA_RESET_STATE); table_list->table->file->delete_all_rows(); free_io_cache(table_list->table); From 3a664472de14322bb635baeec59d9c8bec0026c2 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Fri, 2 Feb 2007 10:01:44 +0100 Subject: [PATCH 26/30] After merge fix --- include/my_pthread.h | 1 - include/thr_alarm.h | 1 + mysys/my_pthread.c | 3 --- mysys/my_thr_init.c | 4 ---- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index 3bcb30cd1f1..14dbc9825d4 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -683,7 +683,6 @@ extern pthread_t shutdown_th, main_th, signal_th; #define THD_LIB_LT 4 extern uint thd_lib_detected; -extern uint thr_client_alarm; /* statistics_xxx functions are for not essential statistic */ diff --git a/include/thr_alarm.h b/include/thr_alarm.h index ef6aaf49f77..1d7ebbcb9f5 100644 --- a/include/thr_alarm.h +++ b/include/thr_alarm.h @@ -94,6 +94,7 @@ typedef struct st_alarm { } ALARM; extern uint thr_client_alarm; +extern pthread_t alarm_thread; #define thr_alarm_init(A) (*(A))=0 #define thr_alarm_in_use(A) (*(A)!= 0) diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index 09685ba3e12..14ba6aabf0e 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -31,7 +31,6 @@ #endif uint thd_lib_detected; -uint thr_client_alarm; #ifndef my_pthread_setprio void my_pthread_setprio(pthread_t thread_id,int prior) @@ -319,8 +318,6 @@ void sigwait_handle_sig(int sig) pthread_mutex_unlock(&LOCK_sigwait); } -extern pthread_t alarm_thread; - void *sigwait_thread(void *set_arg) { sigset_t *set=(sigset_t*) set_arg; diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 34fa2e8aa7e..42f025c39f3 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -61,10 +61,6 @@ static uint get_thread_lib(void); my_bool my_thread_global_init(void) { thd_lib_detected= get_thread_lib(); - if (thd_lib_detected == THD_LIB_LT) - thr_client_alarm= SIGALRM; - else - thr_client_alarm= SIGUSR1; if (pthread_key_create(&THR_KEY_mysys,0)) { From 31c3059ae9d8fdf0e1127ebed8bf276b0fbcc2cf Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/eagle.(none)" <> Date: Fri, 2 Feb 2007 15:01:11 +0400 Subject: [PATCH 27/30] Valgrind errors added valgrind.supp to EXTRA_SCRIPTS(for pushbuild) --- mysql-test/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index f8bf5c490f0..5b0a8afe98e 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -33,7 +33,7 @@ endif benchdir_root= $(prefix) testdir = $(benchdir_root)/mysql-test EXTRA_SCRIPTS = mysql-test-run-shell.sh install_test_db.sh \ - $(PRESCRIPTS) + valgrind.supp $(PRESCRIPTS) EXTRA_DIST = $(EXTRA_SCRIPTS) GENSCRIPTS = mysql-test-run-shell mysql-test-run install_test_db mtr PRESCRIPTS = mysql-test-run.pl From 938de5eee42df8284a11f1ed1eaeb012bd26042b Mon Sep 17 00:00:00 2001 From: "gluh@mysql.com/eagle.(none)" <> Date: Fri, 2 Feb 2007 17:18:42 +0400 Subject: [PATCH 28/30] another valgrind error fix for 4.1(backport from 5.0) --- sql/examples/ha_tina.cc | 12 ++++++++++++ sql/examples/ha_tina.h | 2 ++ sql/handler.cc | 4 ++++ 3 files changed, 18 insertions(+) diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 0091e1f40a0..a3b05d298c2 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -220,6 +220,18 @@ static int free_share(TINA_SHARE *share) } +bool tina_end() +{ + if (tina_init) + { + hash_free(&tina_open_tables); + VOID(pthread_mutex_destroy(&tina_mutex)); + } + tina_init= 0; + return FALSE; +} + + /* Finds the end of a line. Currently only supports files written on a UNIX OS. diff --git a/sql/examples/ha_tina.h b/sql/examples/ha_tina.h index d8cd0fa9cfe..266db1bc1fe 100644 --- a/sql/examples/ha_tina.h +++ b/sql/examples/ha_tina.h @@ -136,3 +136,5 @@ class ha_tina: public handler int find_current_row(byte *buf); int chain_append(); }; + +bool tina_end(); diff --git a/sql/handler.cc b/sql/handler.cc index 0476b855e3c..82fff72f0da 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -340,6 +340,10 @@ int ha_panic(enum ha_panic_function flag) #ifdef HAVE_ARCHIVE_DB if (have_archive_db == SHOW_OPTION_YES) error|= archive_db_end(); +#endif +#ifdef HAVE_CSV_DB + if (have_csv_db == SHOW_OPTION_YES) + error|= tina_end(); #endif return error; } /* ha_panic */ From 177a366e538860ebe6378c925d6edc26ce2ceb02 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Fri, 2 Feb 2007 20:19:13 +0100 Subject: [PATCH 29/30] After merge fix --- sql/mysqld.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a3263b50951..2c84ca94c3c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3141,7 +3141,11 @@ int main(int argc, char **argv) MY_INIT(argv[0]); // init my_sys library & pthreads /* Set signal used to kill MySQL */ +#if defined(SIGUSR2) thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2; +#else + thr_kill_signal= SIGINT; +#endif #ifdef _CUSTOMSTARTUPCONFIG_ if (_cust_check_startup()) From b4445664121219789c994d01fe9adf277404b245 Mon Sep 17 00:00:00 2001 From: "istruewing@chilla.local" <> Date: Sat, 3 Feb 2007 09:26:11 +0100 Subject: [PATCH 30/30] After merge fix --- sql/examples/ha_tina.cc | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 383feb60050..00f927aa7b7 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -276,17 +276,6 @@ bool tina_end() return FALSE; } -bool tina_end() -{ - if (tina_init) - { - hash_free(&tina_open_tables); - VOID(pthread_mutex_destroy(&tina_mutex)); - } - tina_init= 0; - return FALSE; -} - /* Finds the end of a line.