From: Date: June 20 2008 1:43pm Subject: bzr push into mysql-6.0 branch (davi:2675 to 2676) Bug#37076 List-Archive: http://lists.mysql.com/commits/48232 X-Bug: 37076 Message-Id: <20080620114332.A867124168@skynet> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 2676 Davi Arnaut 2008-06-20 [merge] Manual merge. renamed: sql/stacktrace.c => mysys/stacktrace.c sql/stacktrace.h => include/my_stacktrace.h modified: client/CMakeLists.txt client/Makefile.am client/mysqltest.c configure.in include/Makefile.am libmysqld/CMakeLists.txt libmysqld/Makefile.am libmysqld/lib_sql.cc mysql-test/include/mix1.inc mysql-test/r/alter_table.result mysql-test/r/innodb_mysql.result mysql-test/t/alter_table.test mysql-test/t/sql_low_priority_updates_func.test mysys/CMakeLists.txt mysys/Makefile.am sql/CMakeLists.txt sql/Makefile.am sql/mysqld.cc sql/sql_table.cc mysys/stacktrace.c include/my_stacktrace.h 2675 Gleb Shchepa 2008-06-19 [merge] auto merge with local tree (bug #37076) modified: mysql-test/extra/rpl_tests/rpl_row_basic.test mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result sql/field.h === modified file 'client/CMakeLists.txt' --- a/client/CMakeLists.txt 2008-04-02 17:52:11 +0000 +++ b/client/CMakeLists.txt 2008-06-20 11:40:01 +0000 @@ -15,7 +15,7 @@ INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") # We use the "mysqlclient_notls" library here just as safety, in case -# any of the clients here would go beond the client API and access the +# any of the clients here would go beyond the client API and access the # Thread Local Storage directly. SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") @@ -32,9 +32,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/ ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) TARGET_LINK_LIBRARIES(mysql mysqlclient_notls ws2_32) -ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c - ../mysys/my_copy.c ../mysys/my_mkdir.c) -TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex ws2_32) +ADD_EXECUTABLE(mysqltest mysqltest.c) +SET_SOURCE_FILES_PROPERTIES(mysqltest.c PROPERTIES COMPILE_FLAGS "-DTHREADS") +TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex ws2_32 dbug) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls ws2_32) === modified file 'client/Makefile.am' --- a/client/Makefile.am 2008-02-19 14:09:52 +0000 +++ b/client/Makefile.am 2008-06-20 11:40:01 +0000 @@ -86,11 +86,13 @@ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIEN $(LIBMYSQLCLIENT_LA) \ $(top_builddir)/mysys/libmysys.a -mysqltest_SOURCES= mysqltest.c \ - $(top_srcdir)/mysys/my_getsystime.c \ - $(top_srcdir)/mysys/my_copy.c \ - $(top_srcdir)/mysys/my_mkdir.c -mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) +mysqltest_SOURCES= mysqltest.c +mysqltest_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK +mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ + @CLIENT_EXTRA_LDFLAGS@ \ + $(LIBMYSQLCLIENT_LA) \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/regex/libregex.a mysql_upgrade_SOURCES= mysql_upgrade.c \ $(top_srcdir)/mysys/my_getpagesize.c === modified file 'client/mysqltest.c' --- a/client/mysqltest.c 2008-05-14 13:49:41 +0000 +++ b/client/mysqltest.c 2008-06-20 11:40:01 +0000 @@ -48,7 +48,15 @@ #ifdef __WIN__ #include #endif +#include +#include +#ifdef __WIN__ +#include +#define SIGNAL_FMT "exception 0x%x" +#else +#define SIGNAL_FMT "signal %d" +#endif /* Use cygwin for --exec and --system before 5.0 */ #if MYSQL_VERSION_ID < 50000 @@ -214,6 +222,7 @@ struct st_connection /* Used when creating views and sp, to avoid implicit commit */ MYSQL* util_mysql; char *name; + size_t name_len; MYSQL_STMT* stmt; #ifdef EMBEDDED_LIBRARY @@ -4395,6 +4404,7 @@ void do_connect(struct st_command *comma ds_connection_name.str)); if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) die("Out of memory"); + con_slot->name_len= strlen(con_slot->name); cur_con= con_slot; if (con_slot == next_con) @@ -6797,6 +6807,104 @@ void mark_progress(struct st_command* co } +#ifdef HAVE_STACKTRACE + +static void dump_backtrace(void) +{ + struct st_connection *conn= cur_con; + + my_safe_print_str("read_command_buf", read_command_buf, + sizeof(read_command_buf)); + if (conn) + { + my_safe_print_str("conn->name", conn->name, conn->name_len); +#ifdef EMBEDDED_LIBRARY + my_safe_print_str("conn->cur_query", conn->cur_query, conn->cur_query_len); +#endif + } + fputs("Attempting backtrace...\n", stderr); + my_print_stacktrace(NULL, my_thread_stack_size); +} + +#else + +static void dump_backtrace(void) +{ + fputs("Backtrace not available.\n", stderr); +} + +#endif + +static sig_handler signal_handler(int sig) +{ + fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig); + dump_backtrace(); +} + +#ifdef __WIN__ + +LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp) +{ + __try + { + my_set_exception_pointers(exp); + signal_handler(exp->ExceptionRecord->ExceptionCode); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + fputs("Got exception in exception handler!\n", stderr); + } + + return EXCEPTION_CONTINUE_SEARCH; +} + + +static void init_signal_handling(void) +{ + UINT mode; + + /* Set output destination of messages to the standard error stream. */ + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); + + /* Do not not display the a error message box. */ + mode= SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX; + SetErrorMode(mode); + + SetUnhandledExceptionFilter(exception_filter); +} + +#else /* __WIN__ */ + +static void init_signal_handling(void) +{ + struct sigaction sa; + DBUG_ENTER("init_signal_handling"); + +#ifdef HAVE_STACKTRACE + my_init_stacktrace(); +#endif + + sa.sa_flags = SA_RESETHAND | SA_NODEFER; + sigemptyset(&sa.sa_mask); + sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL); + + sa.sa_handler= signal_handler; + + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGABRT, &sa, NULL); +#ifdef SIGBUS + sigaction(SIGBUS, &sa, NULL); +#endif + sigaction(SIGILL, &sa, NULL); + sigaction(SIGFPE, &sa, NULL); +} + +#endif /* !__WIN__ */ int main(int argc, char **argv) { @@ -6810,6 +6918,8 @@ int main(int argc, char **argv) save_file[0]= 0; TMPDIR[0]= 0; + init_signal_handling(); + /* Init expected errors */ memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); === modified file 'configure.in' --- a/configure.in 2008-06-18 03:54:37 +0000 +++ b/configure.in 2008-06-20 11:40:01 +0000 @@ -2359,10 +2359,31 @@ then fi AC_MSG_RESULT("$netinet_inc") +AC_CACHE_CHECK([support for weak symbols], mysql_cv_weak_symbol, +[AC_TRY_LINK([],[ + extern void __attribute__((weak)) foo(void); +], [mysql_cv_weak_symbol=yes], [mysql_cv_weak_symbol=no])]) + +if test "x$mysql_cv_weak_symbol" = xyes; then + AC_DEFINE(HAVE_WEAK_SYMBOL, 1, + [Define to 1 if compiler supports weak symbol attribute.]) +fi + +AC_CACHE_CHECK([whether __bss_start is defined], mysql_cv_bss_start, +[AC_TRY_LINK([],[ + extern char *__bss_start; + return __bss_start ? 1 : 0; +], [mysql_cv_bss_start=yes], [mysql_cv_bss_start=no])]) + +if test "x$mysql_cv_bss_start" = xyes; then + AC_DEFINE(HAVE_BSS_START, 1, + [Define to 1 if compiler defines __bss_start.]) +fi + AC_LANG_SAVE AC_LANG_CPLUSPLUS AC_CHECK_HEADERS(cxxabi.h) -AC_CACHE_CHECK([checking for abi::__cxa_demangle], mysql_cv_cxa_demangle, +AC_CACHE_CHECK([for abi::__cxa_demangle], mysql_cv_cxa_demangle, [AC_TRY_LINK([#include ], [ char *foo= 0; int bar= 0; foo= abi::__cxa_demangle(foo, foo, 0, &bar); === modified file 'include/Makefile.am' --- a/include/Makefile.am 2008-04-01 15:13:57 +0000 +++ b/include/Makefile.am 2008-06-20 11:40:01 +0000 @@ -37,7 +37,7 @@ noinst_HEADERS = config-win.h config-net mysql_version.h.in my_handler.h my_time.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \ - atomic/gcc_builtins.h my_libwrap.h + atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h # Remove built files and the symlinked directories CLEANFILES = $(BUILT_SOURCES) readline openssl === renamed file 'sql/stacktrace.h' => 'include/my_stacktrace.h' --- a/sql/stacktrace.h 2008-02-21 13:23:13 +0000 +++ b/include/my_stacktrace.h 2008-06-20 11:40:01 +0000 @@ -13,57 +13,54 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef __cplusplus -extern "C" { -#endif +#ifndef _my_stacktrace_h_ +#define _my_stacktrace_h_ -#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE -#define BACKTRACE_DEMANGLE 1 -#endif +#include -#if BACKTRACE_DEMANGLE -char *my_demangle(const char *mangled_name, int *status); +#ifdef TARGET_OS_LINUX +#if defined (__x86_64__) || defined (__i386__) || \ + (defined(__alpha__) && defined(__GNUC__)) +#define HAVE_STACKTRACE 1 +#endif +#elif defined(__WIN__) +#define HAVE_STACKTRACE 1 #endif -#ifdef TARGET_OS_LINUX -#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) +#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) #undef HAVE_STACKTRACE -#define HAVE_STACKTRACE +#define HAVE_STACKTRACE 1 +#endif -extern char* __bss_start; -extern char* heap_start; +#if !defined(__NETWARE__) +#define HAVE_WRITE_CORE +#endif -#define init_stacktrace() do { \ - heap_start = (char*) &__bss_start; \ - } while(0); -void check_thread_lib(void); -#endif /* defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */ -#elif defined (__WIN__) -#define HAVE_STACKTRACE -extern void set_exception_pointers(EXCEPTION_POINTERS *ep); -#define init_stacktrace() {} -#endif - -#ifdef HAVE_STACKTRACE -void print_stacktrace(uchar* stack_bottom, ulong thread_stack); -void safe_print_str(const char* name, const char* val, int max_len); -#else -/* Define empty prototypes for functions that are not implemented */ -#define init_stacktrace() {} -#define print_stacktrace(A,B) {} -#define safe_print_str(A,B,C) {} -#endif /* HAVE_STACKTRACE */ +#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && \ + HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE && \ + HAVE_WEAK_SYMBOL +#define BACKTRACE_DEMANGLE 1 +#endif +C_MODE_START -#if !defined(__NETWARE__) -#define HAVE_WRITE_CORE +#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE) +void my_init_stacktrace(); +void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack); +void my_safe_print_str(const char* name, const char* val, int max_len); +void my_write_core(int sig); +#if BACKTRACE_DEMANGLE +char *my_demangle(const char *mangled_name, int *status); +#endif +#ifdef __WIN__ +void my_set_exception_pointers(EXCEPTION_POINTERS *ep); +#endif #endif #ifdef HAVE_WRITE_CORE -void write_core(int sig); +void my_write_core(int sig); #endif +C_MODE_END -#ifdef __cplusplus -} -#endif +#endif /* _my_stacktrace_h_ */ === modified file 'libmysqld/CMakeLists.txt' --- a/libmysqld/CMakeLists.txt 2008-05-21 10:17:29 +0000 +++ b/libmysqld/CMakeLists.txt 2008-06-20 11:40:01 +0000 @@ -193,7 +193,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libm ../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc ../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc ../sql/partition_info.cc ../sql/sql_connect.cc - ../sql/scheduler.cc ../sql/sql_audit.cc ../sql/stacktrace.c + ../sql/scheduler.cc ../sql/sql_audit.cc ../sql/ddl_blocker.cc ../sql/si_objects.cc ../sql/event_parse_data.cc ${GEN_SOURCES} === modified file 'libmysqld/Makefile.am' --- a/libmysqld/Makefile.am 2008-05-09 07:47:28 +0000 +++ b/libmysqld/Makefile.am 2008-06-20 11:40:01 +0000 @@ -73,7 +73,7 @@ sqlsources = derror.cc field.cc field_co sql_select.cc sql_do.cc sql_show.cc set_var.cc \ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ - unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ + unireg.cc uniques.cc sql_union.cc hash_filo.cc \ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ === modified file 'libmysqld/lib_sql.cc' --- a/libmysqld/lib_sql.cc 2008-06-02 15:47:07 +0000 +++ b/libmysqld/lib_sql.cc 2008-06-20 11:40:01 +0000 @@ -79,6 +79,15 @@ emb_advanced_command(MYSQL *mysql, enum my_bool result= 1; THD *thd=(THD *) mysql->thd; NET *net= &mysql->net; + my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE; + + if (!thd) + { + /* Do "reconnect" if possible */ + if (mysql_reconnect(mysql) || stmt_skip) + return 1; + thd= (THD *) mysql->thd; + } #if defined(ENABLED_PROFILING) thd->profiling.start_new_query(); === modified file 'mysql-test/include/mix1.inc' --- a/mysql-test/include/mix1.inc 2008-05-21 10:17:29 +0000 +++ b/mysql-test/include/mix1.inc 2008-06-20 11:40:01 +0000 @@ -1428,29 +1428,31 @@ DROP TABLE t1; # Bug#21704: Renaming column does not update FK definition. # ---disable_warnings -DROP TABLE IF EXISTS t1; -DROP TABLE IF EXISTS t2; ---enable_warnings - -CREATE TABLE t1(id INT PRIMARY KEY) - ENGINE=innodb; - -CREATE TABLE t2( - t1_id INT PRIMARY KEY, - CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id)) - ENGINE=innodb; - ---echo - ---disable_result_log ---error ER_ERROR_ON_RENAME -ALTER TABLE t1 CHANGE id id2 INT; ---enable_result_log - ---echo - -DROP TABLE t2; -DROP TABLE t1; +# +# --disable_warnings +# DROP TABLE IF EXISTS t1; +# DROP TABLE IF EXISTS t2; +# --enable_warnings +# +# CREATE TABLE t1(id INT PRIMARY KEY) +# ENGINE=innodb; +# +# CREATE TABLE t2( +# t1_id INT PRIMARY KEY, +# CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id)) +# ENGINE=innodb; +# +# --echo +# +# --disable_result_log +# --error ER_ERROR_ON_RENAME +# ALTER TABLE t1 CHANGE id id2 INT; +# --enable_result_log +# +# --echo +# +# DROP TABLE t2; +# DROP TABLE t1; +# --echo End of 5.1 tests === modified file 'mysql-test/r/alter_table.result' --- a/mysql-test/r/alter_table.result 2008-03-14 22:21:29 +0000 +++ b/mysql-test/r/alter_table.result 2008-06-20 11:40:01 +0000 @@ -1184,3 +1184,42 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (id int, c int) character set latin1; +INSERT INTO t1 VALUES (1,1); +ALTER TABLE t1 CHANGE c d int; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 CHANGE d c int; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 MODIFY c VARCHAR(10); +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 CHANGE c d varchar(10); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 CHANGE d c varchar(10); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +DROP TABLE t1; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (id int, c int) character set utf8; +INSERT INTO t1 VALUES (1,1); +ALTER TABLE t1 CHANGE c d int; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 CHANGE d c int; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 MODIFY c VARCHAR(10); +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 CHANGE c d varchar(10); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t1 CHANGE d c varchar(10); +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +DROP TABLE t1; +End of 5.1 tests === modified file 'mysql-test/r/innodb_mysql.result' --- a/mysql-test/r/innodb_mysql.result 2008-05-08 12:32:12 +0000 +++ b/mysql-test/r/innodb_mysql.result 2008-06-20 11:40:01 +0000 @@ -1641,19 +1641,6 @@ vid tid idx name type 3 1 2 c1 NULL 3 1 1 pk NULL DROP TABLE t1; -DROP TABLE IF EXISTS t1; -DROP TABLE IF EXISTS t2; -CREATE TABLE t1(id INT PRIMARY KEY) -ENGINE=innodb; -CREATE TABLE t2( -t1_id INT PRIMARY KEY, -CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id)) -ENGINE=innodb; - -ALTER TABLE t1 CHANGE id id2 INT; - -DROP TABLE t2; -DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; create table t1(a int); === modified file 'mysql-test/t/alter_table.test' --- a/mysql-test/t/alter_table.test 2007-07-27 09:44:31 +0000 +++ b/mysql-test/t/alter_table.test 2008-06-17 14:12:21 +0000 @@ -914,3 +914,37 @@ unlock tables; select * from t1; check table t1; drop table t1; + +# +# Bug#33873: Fast ALTER TABLE doesn't work with multibyte character sets +# + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (id int, c int) character set latin1; +INSERT INTO t1 VALUES (1,1); +--enable_info +ALTER TABLE t1 CHANGE c d int; +ALTER TABLE t1 CHANGE d c int; +ALTER TABLE t1 MODIFY c VARCHAR(10); +ALTER TABLE t1 CHANGE c d varchar(10); +ALTER TABLE t1 CHANGE d c varchar(10); +--disable_info +DROP TABLE t1; + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (id int, c int) character set utf8; +INSERT INTO t1 VALUES (1,1); +--enable_info +ALTER TABLE t1 CHANGE c d int; +ALTER TABLE t1 CHANGE d c int; +ALTER TABLE t1 MODIFY c VARCHAR(10); +ALTER TABLE t1 CHANGE c d varchar(10); +ALTER TABLE t1 CHANGE d c varchar(10); +--disable_info +DROP TABLE t1; + +--echo End of 5.1 tests === modified file 'mysql-test/t/sql_low_priority_updates_func.test' --- a/mysql-test/t/sql_low_priority_updates_func.test 2008-04-10 13:14:28 +0000 +++ b/mysql-test/t/sql_low_priority_updates_func.test 2008-06-18 16:17:15 +0000 @@ -19,6 +19,7 @@ # # ############################################################################### +--source include/not_embedded.inc ################################################################ # sql_low_priority_updates was renamed to low_priority_updates # === modified file 'mysys/CMakeLists.txt' --- a/mysys/CMakeLists.txt 2007-11-07 23:18:30 +0000 +++ b/mysys/CMakeLists.txt 2008-06-20 11:40:01 +0000 @@ -39,7 +39,7 @@ SET(MYSYS_SOURCES array.c charset-def.c my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c - my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c + my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c my_atomic.c my_getncpus.c lf_dynarray.c lf_alloc-pin.c lf_hash.c) === modified file 'mysys/Makefile.am' --- a/mysys/Makefile.am 2008-04-01 15:13:57 +0000 +++ b/mysys/Makefile.am 2008-06-20 11:40:01 +0000 @@ -52,7 +52,7 @@ libmysys_a_SOURCES = my_init.c my_get charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_handler.c my_netware.c my_largepage.c \ - my_memmem.c \ + my_memmem.c stacktrace.c \ my_windac.c my_access.c base64.c my_libwrap.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c \ === renamed file 'sql/stacktrace.c' => 'mysys/stacktrace.c' --- a/sql/stacktrace.c 2008-04-09 01:07:00 +0000 +++ b/mysys/stacktrace.c 2008-06-20 11:40:01 +0000 @@ -14,7 +14,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include "stacktrace.h" +#include #ifndef __WIN__ #include @@ -30,16 +30,27 @@ #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) -char *heap_start; +static char *heap_start; -void safe_print_str(const char* name, const char* val, int max_len) +#ifdef HAVE_BSS_START +extern char *__bss_start; +#endif + +void my_init_stacktrace() +{ +#ifdef HAVE_BSS_START + heap_start = (char*) &__bss_start; +#endif +} + +void my_safe_print_str(const char* name, const char* val, int max_len) { char *heap_end= (char*) sbrk(0); fprintf(stderr, "%s at %p ", name, val); if (!PTR_SANE(val)) { - fprintf(stderr, " is invalid pointer\n"); + fprintf(stderr, "is an invalid pointer\n"); return; } @@ -49,57 +60,15 @@ void safe_print_str(const char* name, co fputc('\n', stderr); } -#ifdef TARGET_OS_LINUX - -#ifdef __i386__ -#define SIGRETURN_FRAME_OFFSET 17 -#endif - -#ifdef __x86_64__ -#define SIGRETURN_FRAME_OFFSET 23 -#endif - -#if defined(__alpha__) && defined(__GNUC__) -/* - The only way to backtrace without a symbol table on alpha - is to find stq fp,N(sp), and the first byte - of the instruction opcode will give us the value of N. From this - we can find where the old value of fp is stored -*/ - -#define MAX_INSTR_IN_FUNC 10000 +#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD) -inline uchar** find_prev_fp(uint32* pc, uchar** fp) -{ - int i; - for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) - { - uchar* p = (uchar*)pc; - if (p[2] == 222 && p[3] == 35) - { - return (uchar**)((uchar*)fp - *(short int*)p); - } - } - return 0; -} +#if BACKTRACE_DEMANGLE -inline uint32* find_prev_pc(uint32* pc, uchar** fp) +char __attribute__ ((weak)) *my_demangle(const char *mangled_name, int *status) { - int i; - for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) - { - char* p = (char*)pc; - if (p[1] == 0 && p[2] == 94 && p[3] == -73) - { - uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp))); - return prev_pc; - } - } - return 0; + return NULL; } -#endif /* defined(__alpha__) && defined(__GNUC__) */ -#if BACKTRACE_DEMANGLE static void my_demangle_symbols(char **addrs, int n) { int status, i; @@ -129,15 +98,16 @@ static void my_demangle_symbols(char **a fprintf(stderr, "%s\n", addrs[i]); } } -#endif +#endif /* BACKTRACE_DEMANGLE */ -#if HAVE_BACKTRACE -static void backtrace_current_thread(void) +void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) { void *addrs[128]; char **strings= NULL; int n = backtrace(addrs, array_elements(addrs)); + fprintf(stderr, "stack_bottom = %p thread_stack 0x%lx\n", + stack_bottom, thread_stack); #if BACKTRACE_DEMANGLE if ((strings= backtrace_symbols(addrs, n))) { @@ -152,15 +122,59 @@ static void backtrace_current_thread(voi } #endif } + +#elif defined(TARGET_OS_LINUX) + +#ifdef __i386__ +#define SIGRETURN_FRAME_OFFSET 17 #endif +#ifdef __x86_64__ +#define SIGRETURN_FRAME_OFFSET 23 +#endif + +#if defined(__alpha__) && defined(__GNUC__) +/* + The only way to backtrace without a symbol table on alpha + is to find stq fp,N(sp), and the first byte + of the instruction opcode will give us the value of N. From this + we can find where the old value of fp is stored +*/ + +#define MAX_INSTR_IN_FUNC 10000 -void print_stacktrace(uchar* stack_bottom, ulong thread_stack) +inline uchar** find_prev_fp(uint32* pc, uchar** fp) +{ + int i; + for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) + { + uchar* p = (uchar*)pc; + if (p[2] == 222 && p[3] == 35) + { + return (uchar**)((uchar*)fp - *(short int*)p); + } + } + return 0; +} + +inline uint32* find_prev_pc(uint32* pc, uchar** fp) +{ + int i; + for (i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc) + { + char* p = (char*)pc; + if (p[1] == 0 && p[2] == 94 && p[3] == -73) + { + uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp))); + return prev_pc; + } + } + return 0; +} +#endif /* defined(__alpha__) && defined(__GNUC__) */ + +void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack) { -#if HAVE_BACKTRACE - backtrace_current_thread(); - return; -#endif uchar** fp; uint frame_count = 0, sigreturn_frame_count; #if defined(__alpha__) && defined(__GNUC__) @@ -278,16 +292,7 @@ end: #endif /* HAVE_STACKTRACE */ /* Produce a core for the thread */ - -#ifdef NOT_USED /* HAVE_LINUXTHREADS */ -void write_core(int sig) -{ - signal(sig, SIG_DFL); - if (fork() != 0) exit(1); /* Abort main program */ - /* Core will be written at exit */ -} -#else -void write_core(int sig) +void my_write_core(int sig) { signal(sig, SIG_DFL); #ifdef HAVE_gcov @@ -305,7 +310,7 @@ void write_core(int sig) sigsend(P_PID,P_MYID,sig); #endif } -#endif + #else /* __WIN__*/ #include @@ -353,6 +358,10 @@ static EXCEPTION_POINTERS *exception_ptr #define MODULE64_SIZE_WINXP 576 #define STACKWALK_MAX_FRAMES 64 +void my_init_stacktrace() +{ +} + /* Dynamically load dbghelp functions */ @@ -392,7 +401,7 @@ BOOL init_dbghelp_functions() return rc; } -void set_exception_pointers(EXCEPTION_POINTERS *ep) +void my_set_exception_pointers(EXCEPTION_POINTERS *ep) { exception_ptrs = ep; } @@ -402,7 +411,7 @@ void set_exception_pointers(EXCEPTION_PO #define SYMOPT_NO_PROMPTS 0 #endif -void print_stacktrace(uchar* unused1, ulong unused2) +void my_print_stacktrace(uchar* unused1, ulong unused2) { HANDLE hProcess= GetCurrentProcess(); HANDLE hThread= GetCurrentThread(); @@ -510,7 +519,7 @@ void print_stacktrace(uchar* unused1, ul file name is constructed from executable name plus ".dmp" extension */ -void write_core(int unused) +void my_write_core(int unused) { char path[MAX_PATH]; char dump_fname[MAX_PATH]= "core.dmp"; @@ -557,7 +566,7 @@ void write_core(int unused) } -void safe_print_str(const char *name, const char *val, int len) +void my_safe_print_str(const char *name, const char *val, int len) { fprintf(stderr,"%s at %p", name, val); __try === modified file 'sql/CMakeLists.txt' --- a/sql/CMakeLists.txt 2008-05-14 13:49:41 +0000 +++ b/sql/CMakeLists.txt 2008-06-20 11:40:01 +0000 @@ -44,9 +44,8 @@ ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOL ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc - discover.cc ../libmysql/errmsg.c field.cc stacktrace.c stacktrace.h field_conv.cc - filesort.cc gstream.cc sha2.cc - ha_partition.cc + discover.cc ../libmysql/errmsg.c field.cc field_conv.cc + filesort.cc gstream.cc sha2.cc ha_partition.cc handler.cc hash_filo.cc hash_filo.h hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc item_create.cc item_func.cc item_geofunc.cc item_row.cc === modified file 'sql/Makefile.am' --- a/sql/Makefile.am 2008-05-09 07:47:28 +0000 +++ b/sql/Makefile.am 2008-06-20 11:40:01 +0000 @@ -77,7 +77,7 @@ noinst_HEADERS = item.h item_func.h item sql_repl.h slave.h rpl_filter.h rpl_injector.h \ log_event.h rpl_record.h \ log_event_old.h rpl_record_old.h \ - stacktrace.h sql_sort.h sql_cache.h set_var.h \ + sql_sort.h sql_cache.h set_var.h \ spatial.h gstream.h client_settings.h tzfile.h \ tztime.h my_decimal.h\ sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \ @@ -122,7 +122,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler. rpl_reporting.cc \ sql_union.cc sql_derived.cc \ sql_client.cc \ - stacktrace.c repl_failsafe.h repl_failsafe.cc \ + repl_failsafe.h repl_failsafe.cc \ sql_olap.cc sql_view.cc \ gstream.cc spatial.cc sql_help.cc sql_cursor.cc \ tztime.cc my_decimal.cc\ === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2008-06-18 04:21:22 +0000 +++ b/sql/mysqld.cc 2008-06-20 11:40:01 +0000 @@ -22,7 +22,7 @@ #include "sql_repl.h" #include "rpl_filter.h" #include "repl_failsafe.h" -#include "stacktrace.h" +#include #include "mysqld_suffix.h" #include "mysys_err.h" #include "events.h" @@ -2176,7 +2176,7 @@ LONG WINAPI my_unhandler_exception_filte #endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */ __try { - set_exception_pointers(ex_pointers); + my_set_exception_pointers(ex_pointers); handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode); } __except(EXCEPTION_EXECUTE_HANDLER) @@ -2560,8 +2560,8 @@ the thread stack. Please read http://dev Attempting backtrace. You can use the following information to find out\n\ where mysqld died. If you see no messages after this, something went\n\ terribly wrong...\n"); - print_stacktrace(thd ? (uchar*) thd->thread_stack : (uchar*) 0, - my_thread_stack_size); + my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL, + my_thread_stack_size); } if (thd) { @@ -2585,7 +2585,7 @@ terribly wrong...\n"); } fprintf(stderr, "Trying to get some variables.\n\ Some pointers may be invalid and cause the dump to abort...\n"); - safe_print_str("thd->query", thd->query, 1024); + my_safe_print_str("thd->query", thd->query, 1024); fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id); fprintf(stderr, "thd->killed=%s\n", kreason); } @@ -2632,7 +2632,7 @@ bugs.\n"); { fprintf(stderr, "Writing a core file\n"); fflush(stderr); - write_core(sig); + my_write_core(sig); } #endif @@ -2666,7 +2666,9 @@ static void init_signals(void) sigemptyset(&sa.sa_mask); sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL); - init_stacktrace(); +#ifdef HAVE_STACKTRACE + my_init_stacktrace(); +#endif #if defined(__amiga__) sa.sa_handler=(void(*)())handle_segfault; #else === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2008-06-18 03:30:29 +0000 +++ b/sql/sql_table.cc 2008-06-20 11:40:01 +0000 @@ -5093,7 +5093,7 @@ bool compare_tables(THD *thd, TABLE *table, Alter_info *alter_info, - HA_CREATE_INFO *create_info, + HA_CREATE_INFO *create_info, uint order_num, HA_ALTER_FLAGS *alter_flags, HA_ALTER_INFO *ha_alter_info, @@ -5101,8 +5101,8 @@ compare_tables(THD *thd, { Field **f_ptr, *field; uint table_changes_local= 0; - List_iterator_fast new_field_it(alter_info->create_list); - Create_field *new_field; + List_iterator_fast new_field_it, tmp_new_field_it; + Create_field *new_field, *tmp_new_field; KEY_PART_INFO *key_part; KEY_PART_INFO *end; /* @@ -5110,45 +5110,44 @@ compare_tables(THD *thd, create_info->varchar will be reset in mysql_prepare_create_table. */ bool varchar= create_info->varchar; + /* + Create a copy of alter_info. + To compare the new and old table definitions, we need to "prepare" + the new definition - transform it from parser output to a format + that describes the final table layout (all column defaults are + initialized, duplicate columns are removed). This is done by + mysql_prepare_create_table. Unfortunately, + mysql_prepare_create_table performs its transformations + "in-place", that is, modifies the argument. Since we would + like to keep compare_tables() idempotent (not altering any + of the arguments) we create a copy of alter_info here and + pass it to mysql_prepare_create_table, then use the result + to evaluate possibility of fast ALTER TABLE, and then + destroy the copy. + */ + Alter_info tmp_alter_info(*alter_info, thd->mem_root); + uint db_options= 0; /* not used */ + DBUG_ENTER("compare_tables"); - { - /* - Create a copy of alter_info. - To compare the new and old table definitions, we need to "prepare" - the new definition - transform it from parser output to a format - that describes the final table layout (all column defaults are - initialized, duplicate columns are removed). This is done by - mysql_prepare_create_table. Unfortunately, - mysql_prepare_create_table performs its transformations - "in-place", that is, modifies the argument. Since we would - like to keep compare_tables() idempotent (not altering any - of the arguments) we create a copy of alter_info here and - pass it to mysql_prepare_create_table, then use the result - to evaluate possibility of fast ALTER TABLE, and then - destroy the copy. - */ - Alter_info tmp_alter_info(*alter_info, thd->mem_root); - THD *thd= table->in_use; - uint db_options= 0; /* not used */ - /* Create the prepared information. */ - if (mysql_prepare_create_table(thd, create_info, - &tmp_alter_info, - (table->s->tmp_table != NO_TMP_TABLE), - &db_options, - table->file, - &ha_alter_info->key_info_buffer, - &ha_alter_info->key_count, - /* select_field_count */ 0)) - DBUG_RETURN(TRUE); - /* Allocate result buffers. */ - if (! (ha_alter_info->index_drop_buffer= - (uint*) thd->alloc(sizeof(uint) * table->s->keys)) || - ! (ha_alter_info->index_add_buffer= - (uint*) thd->alloc(sizeof(uint) * - tmp_alter_info.key_list.elements))) - DBUG_RETURN(TRUE); - } + /* Create the prepared information. */ + if (mysql_prepare_create_table(thd, create_info, + &tmp_alter_info, + (table->s->tmp_table != NO_TMP_TABLE), + &db_options, + table->file, + &ha_alter_info->key_info_buffer, + &ha_alter_info->key_count, + /* select_field_count */ 0)) + DBUG_RETURN(TRUE); + /* Allocate result buffers. */ + if (! (ha_alter_info->index_drop_buffer= + (uint*) thd->alloc(sizeof(uint) * table->s->keys)) || + ! (ha_alter_info->index_add_buffer= + (uint*) thd->alloc(sizeof(uint) * + tmp_alter_info.key_list.elements))) + DBUG_RETURN(TRUE); + /* First we setup ha_alter_flags based on what was detected by parser @@ -5226,12 +5225,21 @@ compare_tables(THD *thd, *alter_flags|= HA_ALTER_COLUMN_TYPE; } /* + Use transformed info to evaluate possibility of fast ALTER TABLE + but use the preserved field to persist modifications. + */ + new_field_it.init(alter_info->create_list); + tmp_new_field_it.init(tmp_alter_info.create_list); + + /* Go through fields and check if the original ones are compatible with new table. */ - for (f_ptr= table->field, new_field= new_field_it++; + for (f_ptr= table->field, new_field= new_field_it++, + tmp_new_field= tmp_new_field_it++; (new_field && (field= *f_ptr)); - f_ptr++, new_field= new_field_it++) + f_ptr++, new_field= new_field_it++, + tmp_new_field= tmp_new_field_it++) { /* Make sure we have at least the default charset in use. */ if (!new_field->charset) @@ -5239,8 +5247,8 @@ compare_tables(THD *thd, /* Don't pack rows in old tables if the user has requested this. */ if (create_info->row_type == ROW_TYPE_DYNAMIC || - (new_field->flags & BLOB_FLAG) || - new_field->sql_type == MYSQL_TYPE_VARCHAR && + (tmp_new_field->flags & BLOB_FLAG) || + tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR && create_info->row_type != ROW_TYPE_FIXED) create_info->table_options|= HA_OPTION_PACK_RECORD; @@ -5248,14 +5256,14 @@ compare_tables(THD *thd, if (alter_info->flags & ALTER_CHANGE_COLUMN) { /* Evaluate changes bitmap and send to check_if_incompatible_data() */ - if (!(table_changes_local= field->is_equal(new_field))) + if (!(table_changes_local= field->is_equal(tmp_new_field))) *alter_flags|= HA_ALTER_COLUMN_TYPE; /* Check if field was renamed */ field->flags&= ~FIELD_IS_RENAMED; if (my_strcasecmp(system_charset_info, field->field_name, - new_field->field_name)) + tmp_new_field->field_name)) { field->flags|= FIELD_IS_RENAMED; *alter_flags|= HA_ALTER_COLUMN_NAME; @@ -5266,7 +5274,7 @@ compare_tables(THD *thd, *alter_flags|= HA_ALTER_COLUMN_TYPE; /* Check that NULL behavior is same for old and new fields */ - if ((new_field->flags & NOT_NULL_FLAG) != + if ((tmp_new_field->flags & NOT_NULL_FLAG) != (uint) (field->flags & NOT_NULL_FLAG)) { *table_changes= IS_EQUAL_NO;